[openssl-commits] [openssl] master update
Dr. Stephen Henson
steve at openssl.org
Tue Jan 19 14:17:06 UTC 2016
The branch master has been updated
via 6ada465fb258ae2c29668c59f3ec9b69dc38f8b3 (commit)
via 53a3a545c3c1ce35a2e9af50e0f868c6878603b5 (commit)
via 44a284d292d7bc76edd6a7e3acbd70889daa25cf (commit)
via b7d60e7662f903fc2e5a137bf1fce9a6b431776a (commit)
via 1eff3485b63f84956b5f212aa4d853783bf6c8b5 (commit)
from 8957728772824c1efd1c5e479d8b60fe6f88e6f5 (commit)
- Log -----------------------------------------------------------------
commit 6ada465fb258ae2c29668c59f3ec9b69dc38f8b3
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Tue Jan 19 13:59:09 2016 +0000
Add documentation for EVP_PKEY_TLS1_PRF
Reviewed-by: Matt Caswell <matt at openssl.org>
commit 53a3a545c3c1ce35a2e9af50e0f868c6878603b5
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Tue Jan 19 13:59:05 2016 +0000
add TLS1-PRF tests
Reviewed-by: Matt Caswell <matt at openssl.org>
commit 44a284d292d7bc76edd6a7e3acbd70889daa25cf
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Tue Jan 19 13:59:00 2016 +0000
Add TLS1-PRF test support to evp_test
Reviewed-by: Matt Caswell <matt at openssl.org>
commit b7d60e7662f903fc2e5a137bf1fce9a6b431776a
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Tue Jan 19 13:58:51 2016 +0000
use TLS PRF
Modify libssl to use EVP_PKEY TLS PRF.
Reviewed-by: Matt Caswell <matt at openssl.org>
commit 1eff3485b63f84956b5f212aa4d853783bf6c8b5
Author: Dr. Stephen Henson <steve at openssl.org>
Date: Tue Jan 19 13:57:19 2016 +0000
Add TLS PRF method.
Add EVP_PKEY algorithm for TLS1 PRF.
Reviewed-by: Matt Caswell <matt at openssl.org>
-----------------------------------------------------------------------
Summary of changes:
Makefile.in | 2 +-
crypto/evp/pmeth_lib.c | 3 +-
crypto/include/internal/evp_int.h | 1 +
crypto/{cmac => kdf}/Makefile.in | 18 ++-
crypto/kdf/tls1_prf.c | 283 ++++++++++++++++++++++++++++++++++++++
crypto/objects/obj_dat.h | 9 +-
crypto/objects/obj_mac.num | 1 +
crypto/objects/objects.txt | 3 +
doc/crypto/EVP_PKEY_TLS1_PRF.pod | 87 ++++++++++++
include/openssl/evp.h | 1 +
include/openssl/{cmac.h => kdf.h} | 33 +++--
include/openssl/obj_mac.h | 4 +
ssl/t1_enc.c | 188 ++++++-------------------
test/evp_test.c | 115 ++++++++++++++++
test/evptests.txt | 48 +++++++
15 files changed, 625 insertions(+), 171 deletions(-)
copy crypto/{cmac => kdf}/Makefile.in (81%)
create mode 100644 crypto/kdf/tls1_prf.c
create mode 100644 doc/crypto/EVP_PKEY_TLS1_PRF.pod
copy include/openssl/{cmac.h => kdf.h} (74%)
diff --git a/Makefile.in b/Makefile.in
index 496f118..8dd7f1a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -144,7 +144,7 @@ SDIRS= \
bn ec rsa dsa dh dso engine \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui \
- cms pqueue ts jpake srp store cmac ct async
+ cms pqueue ts jpake srp store cmac ct async kdf
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index f5d558f..1d7d576 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -87,8 +87,9 @@ static const EVP_PKEY_METHOD *standard_methods[] = {
&hmac_pkey_meth,
&cmac_pkey_meth,
#ifndef OPENSSL_NO_DH
- &dhx_pkey_meth
+ &dhx_pkey_meth,
#endif
+ &tls1_prf_pkey_meth
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index e6be432..da73e70 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -131,6 +131,7 @@ extern const EVP_PKEY_METHOD dsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
extern const EVP_PKEY_METHOD hmac_pkey_meth;
extern const EVP_PKEY_METHOD rsa_pkey_meth;
+extern const EVP_PKEY_METHOD tls1_prf_pkey_meth;
struct evp_md_st {
int type;
diff --git a/crypto/cmac/Makefile.in b/crypto/kdf/Makefile.in
similarity index 81%
copy from crypto/cmac/Makefile.in
copy to crypto/kdf/Makefile.in
index d9cc9c5..25798af 100644
--- a/crypto/cmac/Makefile.in
+++ b/crypto/kdf/Makefile.in
@@ -1,8 +1,8 @@
#
-# OpenSSL/crypto/cmac/Makefile
+# OpenSSL/crypto/kdf/Makefile
#
-DIR= cmac
+DIR= kdf
TOP= ../..
CC= cc
INCLUDES=
@@ -15,12 +15,12 @@ CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile
LIB=$(TOP)/libcrypto.a
-LIBSRC=cmac.c cm_ameth.c cm_pmeth.c
-LIBOBJ=cmac.o cm_ameth.o cm_pmeth.o
+LIBSRC=tls1_prf.c
+LIBOBJ=tls1_prf.o
SRC= $(LIBSRC)
-HEADER=
+HEADER=
ALL= $(GENERAL) $(SRC) $(HEADER)
@@ -37,6 +37,14 @@ lib: $(LIBOBJ)
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
update: depend
depend:
diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c
new file mode 100644
index 0000000..3c14b90
--- /dev/null
+++ b/crypto/kdf/tls1_prf.c
@@ -0,0 +1,283 @@
+/*
+ * Written by Dr Stephen N Henson (steve at openssl.org) for the OpenSSL project
+ * 2016.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing at OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay at cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh at cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/kdf.h>
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+
+static int tls1_prf_alg(const EVP_MD *md,
+ const unsigned char *sec, size_t slen,
+ const unsigned char *seed, size_t seed_len,
+ unsigned char *out, size_t olen);
+
+#define TLS1_PRF_MAXBUF 1024
+
+/* TLS KDF pkey context structure */
+
+typedef struct {
+ /* Digest to use for PRF */
+ const EVP_MD *md;
+ /* Secret value to use for PRF */
+ unsigned char *sec;
+ size_t seclen;
+ /* Buffer of concatenated seed data */
+ unsigned char seed[TLS1_PRF_MAXBUF];
+ size_t seedlen;
+} TLS1_PRF_PKEY_CTX;
+
+static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
+{
+ TLS1_PRF_PKEY_CTX *kctx;
+
+ kctx = OPENSSL_zalloc(sizeof(*kctx));
+ if (kctx == NULL)
+ return 0;
+ ctx->data = kctx;
+
+ return 1;
+}
+
+static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
+{
+ TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+ OPENSSL_clear_free(kctx->sec, kctx->seclen);
+ OPENSSL_cleanse(kctx->seed, kctx->seedlen);
+ OPENSSL_free(kctx);
+}
+
+static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+ switch (type) {
+ case EVP_PKEY_CTRL_TLS_MD:
+ kctx->md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_TLS_SECRET:
+ if (p1 < 0)
+ return 0;
+ if (kctx->sec != NULL)
+ OPENSSL_clear_free(kctx->sec, kctx->seclen);
+ OPENSSL_cleanse(kctx->seed, kctx->seedlen);
+ kctx->seedlen = 0;
+ kctx->sec = OPENSSL_memdup(p2, p1);
+ if (kctx->sec == NULL)
+ return 0;
+ kctx->seclen = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_TLS_SEED:
+ if (p1 == 0 || p2 == NULL)
+ return 1;
+ if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
+ return 0;
+ memcpy(kctx->seed + kctx->seedlen, p2, p1);
+ kctx->seedlen += p1;
+ return 1;
+
+ default:
+ return -2;
+
+ }
+}
+
+static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+ size_t *keylen)
+{
+ TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+ if (kctx->md == NULL || kctx->sec == NULL || kctx->seed == NULL)
+ return 0;
+ return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
+ kctx->seed, kctx->seedlen,
+ key, *keylen);
+}
+
+const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
+ EVP_PKEY_TLS1_PRF,
+ 0,
+ pkey_tls1_prf_init,
+ 0,
+ pkey_tls1_prf_cleanup,
+
+ 0, 0,
+ 0, 0,
+
+ 0,
+ 0,
+
+ 0,
+ 0,
+
+ 0, 0,
+
+ 0, 0, 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0,
+ pkey_tls1_prf_derive,
+ pkey_tls1_prf_ctrl,
+ 0
+};
+
+static int tls1_prf_P_hash(const EVP_MD *md,
+ const unsigned char *sec, size_t sec_len,
+ const unsigned char *seed, size_t seed_len,
+ unsigned char *out, size_t olen)
+{
+ int chunk;
+ EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
+ EVP_PKEY *mac_key = NULL;
+ unsigned char A1[EVP_MAX_MD_SIZE];
+ size_t A1_len;
+ int ret = 0;
+
+ chunk = EVP_MD_size(md);
+ OPENSSL_assert(chunk >= 0);
+
+ ctx = EVP_MD_CTX_new();
+ ctx_tmp = EVP_MD_CTX_new();
+ ctx_init = EVP_MD_CTX_new();
+ if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
+ goto err;
+ EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
+ if (mac_key == NULL)
+ goto err;
+ if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
+ goto err;
+ if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
+ goto err;
+ if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
+ goto err;
+ if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
+ goto err;
+
+ for (;;) {
+ /* Reinit mac contexts */
+ if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
+ goto err;
+ if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
+ goto err;
+ if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
+ goto err;
+ if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
+ goto err;
+
+ if (olen > (size_t)chunk) {
+ size_t mac_len;
+ if (!EVP_DigestSignFinal(ctx, out, &mac_len))
+ goto err;
+ out += mac_len;
+ olen -= mac_len;
+ /* calc the next A1 value */
+ if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
+ goto err;
+ } else { /* last one */
+
+ if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
+ goto err;
+ memcpy(out, A1, olen);
+ break;
+ }
+ }
+ ret = 1;
+ err:
+ EVP_PKEY_free(mac_key);
+ EVP_MD_CTX_free(ctx);
+ EVP_MD_CTX_free(ctx_tmp);
+ EVP_MD_CTX_free(ctx_init);
+ OPENSSL_cleanse(A1, sizeof(A1));
+ return ret;
+}
+
+static int tls1_prf_alg(const EVP_MD *md,
+ const unsigned char *sec, size_t slen,
+ const unsigned char *seed, size_t seed_len,
+ unsigned char *out, size_t olen)
+{
+
+ if (EVP_MD_type(md) == NID_md5_sha1) {
+ size_t i;
+ unsigned char *tmp;
+ if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
+ seed, seed_len, out, olen))
+ return 0;
+
+ tmp = OPENSSL_malloc(olen);
+ if (tmp == NULL)
+ return 0;
+ if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
+ seed, seed_len, tmp, olen)) {
+ OPENSSL_clear_free(tmp, olen);
+ return 0;
+ }
+ for (i = 0; i < olen; i++)
+ out[i] ^= tmp[i];
+ OPENSSL_clear_free(tmp, olen);
+ return 1;
+ }
+ if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
+ return 0;
+
+ return 1;
+}
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index debf8cc..1f13992 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -62,9 +62,9 @@
* [including the GNU Public Licence.]
*/
-#define NUM_NID 1021
-#define NUM_SN 1014
-#define NUM_LN 1014
+#define NUM_NID 1022
+#define NUM_SN 1015
+#define NUM_LN 1015
#define NUM_OBJ 937
static const unsigned char lvalues[6612]={
@@ -2671,6 +2671,7 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
{"ChaCha20-Poly1305","chacha20-poly1305",NID_chacha20_poly1305,0,NULL,0},
{"ChaCha20","chacha20",NID_chacha20,0,NULL,0},
{"tlsfeature","TLS Feature",NID_tlsfeature,8,&(lvalues[6603]),0},
+{"TLS1-PRF","tls1-prf",NID_tls1_prf,0,NULL,0},
};
static const unsigned int sn_objs[NUM_SN]={
@@ -2878,6 +2879,7 @@ static const unsigned int sn_objs[NUM_SN]={
1006, /* "SNILS" */
16, /* "ST" */
143, /* "SXNetID" */
+1021, /* "TLS1-PRF" */
458, /* "UID" */
0, /* "UNDEF" */
11, /* "X500" */
@@ -4674,6 +4676,7 @@ static const unsigned int ln_objs[NUM_LN]={
459, /* "textEncodedORAddress" */
293, /* "textNotice" */
106, /* "title" */
+1021, /* "tls1-prf" */
682, /* "tpBasis" */
436, /* "ucl" */
0, /* "undefined" */
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 5c6ffd4..663e86c 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -1018,3 +1018,4 @@ grasshopper_mac 1017
chacha20_poly1305 1018
chacha20 1019
tlsfeature 1020
+tls1_prf 1021
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index f34609d..1de8e79 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -1428,3 +1428,6 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
# SCRYPT algorithm
1 3 6 1 4 1 11591 4 11 : id-scrypt
+
+# NID for TLS1 PRF
+ : TLS1-PRF : tls1-prf
diff --git a/doc/crypto/EVP_PKEY_TLS1_PRF.pod b/doc/crypto/EVP_PKEY_TLS1_PRF.pod
new file mode 100644
index 0000000..8e9ff5a
--- /dev/null
+++ b/doc/crypto/EVP_PKEY_TLS1_PRF.pod
@@ -0,0 +1,87 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_TLS1_PRF, EVP_PKEY_CTX_set_tls1_prf_md,
+EVP_PKEY_CTX_set1_tls1_prf_secret, EVP_PKEY_CTX_add1_tls1_prf_seed -
+TLS PRF key derivation algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/kdf.h>
+
+ int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *pctx, const EVP_MD *md);
+ int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx,
+ unsigned char *sec, int seclen);
+ int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *pctx, seed, seedlen)
+ unsigned char *seed, int seedlen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_TLS1_PRF algorithm implements the PRF key derivation function for
+TLS. It has no associated private key and only implements key derivation
+using EVP_PKEY_derive().
+
+EVP_PKEY_set_tls1_prf_md() sets the message digest associated with the
+TLS PRF. EVP_md5_sha1() is treated as a special case which uses the PRF
+algorithm using both B<MD5> and B<SHA1> as used in TLS 1.0 and 1.1.
+
+EVP_PKEY_CTX_set_tls1_prf_secret() sets the secret value of the TLS PRF
+to B<seclen> bytes of the buffer B<sec>. Any existing secret value is replaced
+and any seed is reset.
+
+EVP_PKEY_CTX_add1_tls1_prf_seed() sets the seed to B<seedlen> bytes of B<seed>.
+If a seed is already set it is appended to the existing value.
+
+=head1 NOTES
+
+All these functions are implemented as macros.
+
+A context for the TLS PRF can be obtained by calling:
+
+ EVP_PKEY_CTX *pctx = EVP_PKEY_new_id(EVP_PKEY_TLS1_PRF, NULL);
+
+The digest, secret value and seed must be set before a key is derived or an
+error occurs.
+
+The total length of all seeds cannot exceed 1024 bytes in length: this should
+be more than enough for any normal use of the TLS PRF.
+
+The output length of the PRF is specified by the length parameter in the
+EVP_PKEY_derive() function. Since the output length is variable, setting
+the buffer to B<NULL> is not meaningful for the TLS PRF.
+
+Optimised versions of the TLS PRF can be implemented in an ENGINE.
+
+=head1 RETURN VALUES
+
+All these functions return 1 for success and 0 or a negative value for failure.
+In particular a return value of -2 indicates the operation is not supported by
+the public key algorithm.
+
+=head1 EXAMPLE
+
+This example derives 10 bytes using SHA-256 with the secret key "secret"
+and seed value "seed":
+
+ EVP_PKEY_CTX *pctx;
+ unsigned char out[10];
+ size_t outlen = sizeof(out);
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
+ if (EVP_PKEY_derive_init(pctx) <= 0)
+ /* Error */
+ if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0)
+ /* Error */
+ if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0)
+ /* Error */
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0)
+ /* Error */
+ if (EVP_PKEY_derive(pctx, out, &outlen) <= 0)
+ /* Error */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_derive(3)>,
+
+=cut
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 8001182..2ed9faa 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -108,6 +108,7 @@
# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
# define EVP_PKEY_HMAC NID_hmac
# define EVP_PKEY_CMAC NID_cmac
+# define EVP_PKEY_TLS1_PRF NID_tls1_prf
#ifdef __cplusplus
extern "C" {
diff --git a/include/openssl/cmac.h b/include/openssl/kdf.h
similarity index 74%
copy from include/openssl/cmac.h
copy to include/openssl/kdf.h
index 175be83..96ccf92 100644
--- a/include/openssl/cmac.h
+++ b/include/openssl/kdf.h
@@ -1,10 +1,10 @@
-/* crypto/cmac/cmac.h */
+/* kdf.h */
/*
* Written by Dr Stephen N Henson (steve at openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
- * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,29 +52,28 @@
* ====================================================================
*/
-#ifndef HEADER_CMAC_H
-# define HEADER_CMAC_H
+#ifndef HEADER_KDF_H
+# define HEADER_KDF_H
#ifdef __cplusplus
extern "C" {
#endif
-# include <openssl/evp.h>
+# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL)
+# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2)
-/* Opaque */
-typedef struct CMAC_CTX_st CMAC_CTX;
+# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \
+ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+ EVP_PKEY_CTRL_TLS_MD, 0, (void *)md)
-CMAC_CTX *CMAC_CTX_new(void);
-void CMAC_CTX_cleanup(CMAC_CTX *ctx);
-void CMAC_CTX_free(CMAC_CTX *ctx);
-EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
-int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
+# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \
+ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+ EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)sec)
-int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
- const EVP_CIPHER *cipher, ENGINE *impl);
-int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
-int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
-int CMAC_resume(CMAC_CTX *ctx);
+# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \
+ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+ EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)seed)
#ifdef __cplusplus
}
diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
index 5f21fd5..04605e0 100644
--- a/include/openssl/obj_mac.h
+++ b/include/openssl/obj_mac.h
@@ -4463,3 +4463,7 @@
#define SN_id_scrypt "id-scrypt"
#define NID_id_scrypt 973
#define OBJ_id_scrypt 1L,3L,6L,1L,4L,1L,11591L,4L,11L
+
+#define SN_tls1_prf "TLS1-PRF"
+#define LN_tls1_prf "tls1-prf"
+#define NID_tls1_prf 1021
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 9885f24..23b3640 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -141,103 +141,10 @@
# include <openssl/comp.h>
#endif
#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/md5.h>
+#include <openssl/kdf.h>
#include <openssl/rand.h>
-/* seed1 through seed5 are virtually concatenated */
-static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
- int sec_len,
- const void *seed1, int seed1_len,
- const void *seed2, int seed2_len,
- const void *seed3, int seed3_len,
- const void *seed4, int seed4_len,
- const void *seed5, int seed5_len,
- unsigned char *out, int olen)
-{
- int chunk;
- size_t j;
- EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
- EVP_PKEY *mac_key = NULL;
- unsigned char A1[EVP_MAX_MD_SIZE];
- size_t A1_len;
- int ret = 0;
-
- chunk = EVP_MD_size(md);
- OPENSSL_assert(chunk >= 0);
-
- ctx = EVP_MD_CTX_new();
- ctx_tmp = EVP_MD_CTX_new();
- ctx_init = EVP_MD_CTX_new();
- if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
- goto err;
- EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
- if (!mac_key)
- goto err;
- if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
- goto err;
- if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
- goto err;
- if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
- goto err;
- if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
- goto err;
- if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
- goto err;
- if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
- goto err;
- if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
- goto err;
- if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
- goto err;
-
- for (;;) {
- /* Reinit mac contexts */
- if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
- goto err;
- if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
- goto err;
- if (olen > chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
- goto err;
- if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
- goto err;
- if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
- goto err;
- if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
- goto err;
- if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
- goto err;
- if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
- goto err;
-
- if (olen > chunk) {
- if (!EVP_DigestSignFinal(ctx, out, &j))
- goto err;
- out += j;
- olen -= j;
- /* calc the next A1 value */
- if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
- goto err;
- } else { /* last one */
-
- if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
- goto err;
- memcpy(out, A1, olen);
- break;
- }
- }
- ret = 1;
- err:
- EVP_PKEY_free(mac_key);
- EVP_MD_CTX_free(ctx);
- EVP_MD_CTX_free(ctx_tmp);
- EVP_MD_CTX_free(ctx_init);
- OPENSSL_cleanse(A1, sizeof(A1));
- return ret;
-}
-
-/* seed1 through seed5 are virtually concatenated */
+/* seed1 through seed5 are concatenated */
static int tls1_PRF(SSL *s,
const void *seed1, int seed1_len,
const void *seed2, int seed2_len,
@@ -245,43 +152,46 @@ static int tls1_PRF(SSL *s,
const void *seed4, int seed4_len,
const void *seed5, int seed5_len,
const unsigned char *sec, int slen,
- unsigned char *out1, unsigned char *out2, int olen)
+ unsigned char *out, int olen)
{
const EVP_MD *md = ssl_prf_md(s);
+ EVP_PKEY_CTX *pctx = NULL;
+
+ int ret = 0;
+ size_t outlen = olen;
if (md == NULL) {
/* Should never happen */
SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
return 0;
}
- if (EVP_MD_type(md) == NID_md5_sha1) {
- int i;
- if (!tls1_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
- seed1, seed1_len, seed2, seed2_len, seed3,
- seed3_len, seed4, seed4_len, seed5, seed5_len,
- out1, olen))
- return 0;
- if (!tls1_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
- seed1, seed1_len, seed2, seed2_len, seed3,
- seed3_len, seed4, seed4_len, seed5, seed5_len,
- out2, olen))
- return 0;
- for (i = 0; i < olen; i++)
- out1[i] ^= out2[i];
- return 1;
- }
- memset(out2, 0, olen);
- if (!tls1_P_hash(md, sec, slen,
- seed1, seed1_len, seed2, seed2_len, seed3,
- seed3_len, seed4, seed4_len, seed5, seed5_len,
- out1, olen))
- return 0;
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
+ if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0
+ || EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) <= 0
+ || EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, slen) <= 0)
+ goto err;
- return 1;
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, seed4_len) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, seed5_len) <= 0)
+ goto err;
+
+ if (EVP_PKEY_derive(pctx, out, &outlen) <= 0)
+ goto err;
+ ret = 1;
+
+ err:
+ EVP_PKEY_CTX_free(pctx);
+ return ret;
}
-static int tls1_generate_key_block(SSL *s, unsigned char *km,
- unsigned char *tmp, int num)
+static int tls1_generate_key_block(SSL *s, unsigned char *km, int num)
{
int ret;
ret = tls1_PRF(s,
@@ -289,7 +199,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random,
SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
NULL, 0, NULL, 0, s->session->master_key,
- s->session->master_key_length, km, tmp, num);
+ s->session->master_key_length, km, num);
return ret;
}
@@ -550,7 +460,7 @@ int tls1_change_cipher_state(SSL *s, int which)
int tls1_setup_key_block(SSL *s)
{
- unsigned char *p1, *p2 = NULL;
+ unsigned char *p;
const EVP_CIPHER *c;
const EVP_MD *hash;
int num;
@@ -578,19 +488,14 @@ int tls1_setup_key_block(SSL *s)
ssl3_cleanup_key_block(s);
- if ((p1 = OPENSSL_malloc(num)) == NULL) {
+ if ((p = OPENSSL_malloc(num)) == NULL) {
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
goto err;
}
s->s3->tmp.key_block_length = num;
- s->s3->tmp.key_block = p1;
+ s->s3->tmp.key_block = p;
- if ((p2 = OPENSSL_malloc(num)) == NULL) {
- SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(p1);
- goto err;
- }
#ifdef TLS_DEBUG
printf("client random\n");
{
@@ -614,7 +519,7 @@ int tls1_setup_key_block(SSL *s)
((z + 1) % 16) ? ' ' : '\n');
}
#endif
- if (!tls1_generate_key_block(s, p1, p2, num))
+ if (!tls1_generate_key_block(s, p, num))
goto err;
#ifdef TLS_DEBUG
printf("\nkey block\n");
@@ -646,7 +551,6 @@ int tls1_setup_key_block(SSL *s)
ret = 1;
err:
- OPENSSL_clear_free(p2, num);
return (ret);
}
@@ -655,7 +559,6 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen,
{
int hashlen;
unsigned char hash[EVP_MAX_MD_SIZE];
- unsigned char buf2[12];
if (!ssl3_digest_cached_records(s, 0))
return 0;
@@ -665,21 +568,17 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen,
if (hashlen == 0)
return 0;
- if (!tls1_PRF(s,
- str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
+ if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
s->session->master_key, s->session->master_key_length,
- out, buf2, sizeof buf2))
+ out, TLS1_FINISH_MAC_LENGTH))
return 0;
OPENSSL_cleanse(hash, hashlen);
- OPENSSL_cleanse(buf2, sizeof(buf2));
- return sizeof(buf2);
+ return TLS1_FINISH_MAC_LENGTH;
}
int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
int len)
{
- unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
-
if (s->session->flags & SSL_SESS_FLAG_EXTMS) {
unsigned char hash[EVP_MAX_MD_SIZE * 2];
int hashlen;
@@ -701,7 +600,8 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
hash, hashlen,
NULL, 0,
NULL, 0,
- NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+ NULL, 0, p, len, s->session->master_key,
+ SSL3_MASTER_SECRET_SIZE);
OPENSSL_cleanse(hash, hashlen);
} else {
tls1_PRF(s,
@@ -710,9 +610,9 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
s->s3->client_random, SSL3_RANDOM_SIZE,
NULL, 0,
s->s3->server_random, SSL3_RANDOM_SIZE,
- NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+ NULL, 0, p, len, s->session->master_key,
+ SSL3_MASTER_SECRET_SIZE);
}
- OPENSSL_cleanse(buff, sizeof buff);
#ifdef SSL_DEBUG
fprintf(stderr, "Premaster Secret:\n");
BIO_dump_fp(stderr, (char *)p, len);
@@ -817,7 +717,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
NULL, 0,
NULL, 0,
s->session->master_key, s->session->master_key_length,
- out, buff, olen);
+ out, olen);
goto ret;
err1:
diff --git a/test/evp_test.c b/test/evp_test.c
index c8d1f60..bc3e6dd 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -61,6 +61,7 @@
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
+#include <openssl/kdf.h>
#include "internal/numbers.h"
/* Remove spaces from beginning and end of a string */
@@ -293,6 +294,7 @@ static const struct evp_test_method pdecrypt_test_method;
static const struct evp_test_method pverify_recover_test_method;
static const struct evp_test_method pbe_test_method;
static const struct evp_test_method encode_test_method;
+static const struct evp_test_method kdf_test_method;
static const struct evp_test_method *evp_test_list[] = {
&digest_test_method,
@@ -304,6 +306,7 @@ static const struct evp_test_method *evp_test_list[] = {
&pverify_recover_test_method,
&pbe_test_method,
&encode_test_method,
+ &kdf_test_method,
NULL
};
@@ -1664,3 +1667,115 @@ static const struct evp_test_method encode_test_method = {
encode_test_parse,
encode_test_run,
};
+
+/*
+ * KDF operations: initially just TLS1 PRF but can be adapted.
+ */
+
+struct kdf_data {
+ /* Context for this operation */
+ EVP_PKEY_CTX *ctx;
+ /* Expected output */
+ unsigned char *output;
+ size_t output_len;
+};
+
+/*
+ * Perform public key operation setup: lookup key, allocated ctx and call
+ * the appropriate initialisation function
+ */
+static int kdf_test_init(struct evp_test *t, const char *name)
+{
+ struct kdf_data *kdata;
+
+ kdata = OPENSSL_malloc(sizeof(*kdata));
+ if (kdata == NULL)
+ return 0;
+ kdata->ctx = NULL;
+ kdata->output = NULL;
+ t->data = kdata;
+ kdata->ctx = EVP_PKEY_CTX_new_id(OBJ_sn2nid(name), NULL);
+ if (kdata->ctx == NULL)
+ return 0;
+ if (EVP_PKEY_derive_init(kdata->ctx) <= 0)
+ return 0;
+ return 1;
+}
+
+static void kdf_test_cleanup(struct evp_test *t)
+{
+ struct kdf_data *kdata = t->data;
+ OPENSSL_free(kdata->output);
+ EVP_PKEY_CTX_free(kdata->ctx);
+}
+
+static int kdf_ctrl(EVP_PKEY_CTX *ctx, int op, const char *value)
+{
+ unsigned char *buf = NULL;
+ size_t buf_len;
+ int rv = 0;
+ if (test_bin(value, &buf, &buf_len) == 0)
+ return 0;
+ if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, op, buf_len, buf) <= 0)
+ goto err;
+ rv = 1;
+ err:
+ OPENSSL_free(buf);
+ return rv;
+}
+
+static int kdf_test_parse(struct evp_test *t,
+ const char *keyword, const char *value)
+{
+ struct kdf_data *kdata = t->data;
+ if (strcmp(keyword, "Output") == 0)
+ return test_bin(value, &kdata->output, &kdata->output_len);
+ else if (strcmp(keyword, "MD") == 0) {
+ const EVP_MD *md = EVP_get_digestbyname(value);
+ if (md == NULL)
+ return 0;
+ if (EVP_PKEY_CTX_set_tls1_prf_md(kdata->ctx, md) <= 0)
+ return 0;
+ return 1;
+ } else if (strcmp(keyword, "Secret") == 0) {
+ return kdf_ctrl(kdata->ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
+ } else if (strncmp("Seed", keyword, 4) == 0) {
+ return kdf_ctrl(kdata->ctx, EVP_PKEY_CTRL_TLS_SEED, value);
+ }
+ return 0;
+}
+
+static int kdf_test_run(struct evp_test *t)
+{
+ struct kdf_data *kdata = t->data;
+ unsigned char *out = NULL;
+ size_t out_len = kdata->output_len;
+ const char *err = "INTERNAL_ERROR";
+ out = OPENSSL_malloc(out_len);
+ if (!out) {
+ fprintf(stderr, "Error allocating output buffer!\n");
+ exit(1);
+ }
+ err = "KDF_DERIVE_ERROR";
+ if (EVP_PKEY_derive(kdata->ctx, out, &out_len) <= 0)
+ goto err;
+ err = "KDF_LENGTH_MISMATCH";
+ if (out_len != kdata->output_len)
+ goto err;
+ err = "KDF_MISMATCH";
+ if (check_output(t, kdata->output, out, out_len))
+ goto err;
+ err = NULL;
+ err:
+ OPENSSL_free(out);
+ t->err = err;
+ return 1;
+}
+
+static const struct evp_test_method kdf_test_method = {
+ "KDF",
+ kdf_test_init,
+ kdf_test_cleanup,
+ kdf_test_parse,
+ kdf_test_run
+};
diff --git a/test/evptests.txt b/test/evptests.txt
index 99ffe60..83452b4 100644
--- a/test/evptests.txt
+++ b/test/evptests.txt
@@ -2908,3 +2908,51 @@ AAD = f33388860000000000004e91
Tag = eead9d67890cbb22392336fea1851f38
Plaintext = 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d
Ciphertext = 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b
+
+# TLS1 PRF tests, from NIST test vectors
+
+KDF=TLS1-PRF
+MD=MD5-SHA1
+Secret = bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0
+Seed.label = "master secret"
+Seed.client_random = e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693
+Seed.server_random = 135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2
+Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62
+
+KDF=TLS1-PRF
+MD=MD5-SHA1
+Secret = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62
+Seed.label = "key expansion"
+Seed.server_random = 67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be
+Seed.client_random = d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b62990440931f6
+Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d
+
+KDF=TLS1-PRF
+MD=SHA256
+Secret = f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc
+Seed.label = "master secret"
+Seed.client_random = 36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c
+Seed.server_random = f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce
+Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf
+
+KDF=TLS1-PRF
+MD=SHA256
+Secret = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf
+Seed.label = "key expansion"
+Seed.server_random = ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868
+Seed.client_random = 62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616
+Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928
+
+# Missing digest.
+KDF=TLS1-PRF
+Secret = 01
+Seed = 02
+Output = 03
+Result = KDF_DERIVE_ERROR
+
+# Missing secret.
+KDF=TLS1-PRF
+MD=MD5-SHA1
+Seed = 02
+Output = 03
+Result = KDF_DERIVE_ERROR
More information about the openssl-commits
mailing list