summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/ec/ecdh_kdf.c64
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--crypto/evp/c_allkdf.c1
-rw-r--r--crypto/evp/kdf_lib.c8
-rw-r--r--crypto/include/internal/evp_int.h1
-rw-r--r--crypto/kdf/kdf_err.c2
-rw-r--r--crypto/kdf/sskdf.c43
-rw-r--r--crypto/objects/obj_dat.h9
-rw-r--r--crypto/objects/obj_mac.num1
-rw-r--r--crypto/objects/objects.txt3
-rw-r--r--doc/man3/EVP_KDF_CTX.pod1
-rw-r--r--doc/man7/EVP_KDF_X963.pod136
-rw-r--r--include/openssl/kdf.h2
-rw-r--r--include/openssl/kdferr.h2
-rw-r--r--include/openssl/obj_mac.h4
-rw-r--r--test/evp_kdf_test.c94
-rw-r--r--test/recipes/30-test_evp_data/evpkdf.txt98
17 files changed, 391 insertions, 80 deletions
diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c
index f2af38a245..f556dc66a0 100644
--- a/crypto/ec/ecdh_kdf.c
+++ b/crypto/ec/ecdh_kdf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -10,62 +10,28 @@
#include <string.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
+#include <openssl/kdf.h>
#include "ec_lcl.h"
/* Key derivation function from X9.63/SECG */
-/* Way more than we will ever need */
-#define ECDH_KDF_MAX (1 << 30)
-
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
{
- EVP_MD_CTX *mctx = NULL;
- int rv = 0;
- unsigned int i;
- size_t mdlen;
- unsigned char ctr[4];
- if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
- || Zlen > ECDH_KDF_MAX)
- return 0;
- mctx = EVP_MD_CTX_new();
- if (mctx == NULL)
- return 0;
- mdlen = EVP_MD_size(md);
- for (i = 1;; i++) {
- unsigned char mtmp[EVP_MAX_MD_SIZE];
- if (!EVP_DigestInit_ex(mctx, md, NULL))
- goto err;
- ctr[3] = i & 0xFF;
- ctr[2] = (i >> 8) & 0xFF;
- ctr[1] = (i >> 16) & 0xFF;
- ctr[0] = (i >> 24) & 0xFF;
- if (!EVP_DigestUpdate(mctx, Z, Zlen))
- goto err;
- if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
- goto err;
- if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
- goto err;
- if (outlen >= mdlen) {
- if (!EVP_DigestFinal(mctx, out, NULL))
- goto err;
- outlen -= mdlen;
- if (outlen == 0)
- break;
- out += mdlen;
- } else {
- if (!EVP_DigestFinal(mctx, mtmp, NULL))
- goto err;
- memcpy(out, mtmp, outlen);
- OPENSSL_cleanse(mtmp, mdlen);
- break;
- }
- }
- rv = 1;
- err:
- EVP_MD_CTX_free(mctx);
- return rv;
+ int ret;
+ EVP_KDF_CTX *kctx = NULL;
+
+ kctx = EVP_KDF_CTX_new(EVP_get_kdfbyname(SN_x963kdf));
+ ret =
+ kctx != NULL
+ && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, md) > 0
+ && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, Z, Zlen) > 0
+ && EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, sinfo, sinfolen) > 0
+ && EVP_KDF_derive(kctx, out, outlen) > 0;
+
+ EVP_KDF_CTX_free(kctx);
+ return ret;
}
/*-
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 4b9f27be30..eee3092385 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -925,6 +925,7 @@ KDF_F_SSKDF_MAC2CTRL:136:sskdf_mac2ctrl
KDF_F_SSKDF_NEW:137:sskdf_new
KDF_F_SSKDF_SIZE:138:sskdf_size
KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg
+KDF_F_X963KDF_DERIVE:139:x963kdf_derive
OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object
OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid
OBJ_F_OBJ_CREATE:100:OBJ_create
@@ -2464,6 +2465,7 @@ KDF_R_MISSING_SEED:106:missing seed
KDF_R_MISSING_SESSION_ID:113:missing session id
KDF_R_MISSING_TYPE:114:missing type
KDF_R_MISSING_XCGHASH:115:missing xcghash
+KDF_R_NOT_SUPPORTED:118:not supported
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
KDF_R_UNSUPPORTED_MAC_TYPE:117:unsupported mac type
KDF_R_VALUE_ERROR:108:value error
diff --git a/crypto/evp/c_allkdf.c b/crypto/evp/c_allkdf.c
index 34109ca987..2233fd9cac 100644
--- a/crypto/evp/c_allkdf.c
+++ b/crypto/evp/c_allkdf.c
@@ -20,4 +20,5 @@ void openssl_add_all_kdfs_int(void)
EVP_add_kdf(&hkdf_kdf_meth);
EVP_add_kdf(&sshkdf_kdf_meth);
EVP_add_kdf(&ss_kdf_meth);
+ EVP_add_kdf(&x963_kdf_meth);
}
diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c
index be5d7c6061..6131d8ef77 100644
--- a/crypto/evp/kdf_lib.c
+++ b/crypto/evp/kdf_lib.c
@@ -22,8 +22,12 @@
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
{
- EVP_KDF_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
+ EVP_KDF_CTX *ctx = NULL;
+ if (kdf == NULL)
+ return NULL;
+
+ ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) {
EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
@@ -38,8 +42,6 @@ EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
{
const EVP_KDF *kdf = EVP_get_kdfbynid(id);
- if (kdf == NULL)
- return NULL;
return EVP_KDF_CTX_new(kdf);
}
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index c5d82e6257..43932a4149 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -172,6 +172,7 @@ extern const EVP_KDF tls1_prf_kdf_meth;
extern const EVP_KDF hkdf_kdf_meth;
extern const EVP_KDF sshkdf_kdf_meth;
extern const EVP_KDF ss_kdf_meth;
+extern const EVP_KDF x963_kdf_meth;
struct evp_md_st {
/* nid */
diff --git a/crypto/kdf/kdf_err.c b/crypto/kdf/kdf_err.c
index 84c330fafb..49028ab32f 100644
--- a/crypto/kdf/kdf_err.c
+++ b/crypto/kdf/kdf_err.c
@@ -65,6 +65,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_NEW, 0), "sskdf_new"},
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_SIZE, 0), "sskdf_size"},
{ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"},
+ {ERR_PACK(ERR_LIB_KDF, KDF_F_X963KDF_DERIVE, 0), "x963kdf_derive"},
{0, NULL}
};
@@ -84,6 +85,7 @@ static const ERR_STRING_DATA KDF_str_reasons[] = {
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SESSION_ID), "missing session id"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_TYPE), "missing type"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_XCGHASH), "missing xcghash"},
+ {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_NOT_SUPPORTED), "not supported"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE),
"unknown parameter type"},
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNSUPPORTED_MAC_TYPE),
diff --git a/crypto/kdf/sskdf.c b/crypto/kdf/sskdf.c
index 3dd5b78d26..92bf995425 100644
--- a/crypto/kdf/sskdf.c
+++ b/crypto/kdf/sskdf.c
@@ -66,10 +66,16 @@ static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
/*
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
* Section 4. One-Step Key Derivation using H(x) = hash(x)
+ * Note: X9.63 also uses this code with the only difference being that the
+ * counter is appended to the secret 'z'.
+ * i.e.
+ * result[i] = Hash(counter || z || info) for One Step OR
+ * result[i] = Hash(z || counter || info) for X9.63.
*/
static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
const unsigned char *z, size_t z_len,
const unsigned char *info, size_t info_len,
+ unsigned int append_ctr,
unsigned char *derived_key, size_t derived_key_len)
{
int ret = 0, hlen;
@@ -104,8 +110,9 @@ static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
c[3] = (unsigned char)(counter & 0xff);
if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
- && EVP_DigestUpdate(ctx, c, sizeof(c))
+ && (append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
&& EVP_DigestUpdate(ctx, z, z_len)
+ && (!append_ctr || EVP_DigestUpdate(ctx, c, sizeof(c)))
&& EVP_DigestUpdate(ctx, info, info_len)))
goto end;
if (len >= out_len) {
@@ -468,7 +475,28 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
return 0;
}
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
- impl->info, impl->info_len, key, keylen);
+ impl->info, impl->info_len, 0, key, keylen);
+ }
+}
+
+static int x963kdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
+{
+ if (impl->secret == NULL) {
+ KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_SECRET);
+ return 0;
+ }
+
+ if (impl->mac != NULL) {
+ KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_NOT_SUPPORTED);
+ return 0;
+ } else {
+ /* H(x) = hash */
+ if (impl->md == NULL) {
+ KDFerr(KDF_F_X963KDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
+ return 0;
+ }
+ return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
+ impl->info, impl->info_len, 1, key, keylen);
}
}
@@ -482,3 +510,14 @@ const EVP_KDF ss_kdf_meth = {
sskdf_size,
sskdf_derive
};
+
+const EVP_KDF x963_kdf_meth = {
+ EVP_KDF_X963,
+ sskdf_new,
+ sskdf_free,
+ sskdf_reset,
+ sskdf_ctrl,
+ sskdf_ctrl_str,
+ sskdf_size,
+ x963kdf_derive
+};
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index c778d45aa9..6bad09058a 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -1080,7 +1080,7 @@ static const unsigned char so[7775] = {
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7766] OBJ_SM2_with_SM3 */
};
-#define NUM_NID 1206
+#define NUM_NID 1207
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2288,9 +2288,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"SSHKDF", "sshkdf", NID_sshkdf},
{"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7766]},
{"SSKDF", "sskdf", NID_sskdf},
+ {"X963KDF", "x963kdf", NID_x963kdf},
};
-#define NUM_SN 1197
+#define NUM_SN 1198
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@@ -2591,6 +2592,7 @@ static const unsigned int sn_objs[NUM_SN] = {
378, /* "X500algorithms" */
12, /* "X509" */
184, /* "X9-57" */
+ 1206, /* "X963KDF" */
185, /* "X9cm" */
125, /* "ZLIB" */
478, /* "aRecord" */
@@ -3491,7 +3493,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1093, /* "x509ExtAdmission" */
};
-#define NUM_LN 1197
+#define NUM_LN 1198
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@@ -4689,6 +4691,7 @@ static const unsigned int ln_objs[NUM_LN] = {
503, /* "x500UniqueIdentifier" */
158, /* "x509Certificate" */
160, /* "x509Crl" */
+ 1206, /* "x963kdf" */
125, /* "zlib compression" */
};
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 44820a7c8d..e0969fe1fd 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -1203,3 +1203,4 @@ blake2smac 1202
sshkdf 1203
SM2_with_SM3 1204
sskdf 1205
+x963kdf 1206
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index 2240916ff4..a84b532247 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -1617,6 +1617,9 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
# NID for SSKDF
: SSKDF : sskdf
+# NID for X963-2001 KDF
+ : X963KDF : x963kdf
+
# RFC 4556
1 3 6 1 5 2 3 : id-pkinit
id-pkinit 4 : pkInitClientAuth : PKINIT Client Auth
diff --git a/doc/man3/EVP_KDF_CTX.pod b/doc/man3/EVP_KDF_CTX.pod
index 2bdefc668a..342807fa14 100644
--- a/doc/man3/EVP_KDF_CTX.pod
+++ b/doc/man3/EVP_KDF_CTX.pod
@@ -277,6 +277,7 @@ L<EVP_KDF_PBKDF2(7)>
L<EVP_KDF_HKDF(7)>
L<EVP_KDF_SS(7)>
L<EVP_KDF_SSHKDF(7)>
+L<EVP_KDF_X963(7)>
=head1 HISTORY
diff --git a/doc/man7/EVP_KDF_X963.pod b/doc/man7/EVP_KDF_X963.pod
new file mode 100644
index 0000000000..11789ae5aa
--- /dev/null
+++ b/doc/man7/EVP_KDF_X963.pod
@@ -0,0 +1,136 @@
+=pod
+
+=head1 NAME
+
+EVP_KDF_X963 - The X9.63-2001 EVP_KDF implementation
+
+=head1 DESCRIPTION
+
+The EVP_KDF_X963 algorithm implements the key derivation function (X963KDF).
+X963KDF is used by Cryptographic Message Syntax (CMS) for EC KeyAgreement, to
+derive a key using input such as a shared secret key and shared info.
+
+=head2 Numeric identity
+
+B<EVP_KDF_X963> is the numeric identity for this implementation; it
+can be used with the EVP_KDF_CTX_new_id() function.
+
+=head2 Supported controls
+
+The supported controls are:
+
+=over 4
+
+=item B<EVP_KDF_CTRL_SET_MD>
+
+This control works as described in L<EVP_KDF_CTX(3)/CONTROLS>.
+
+=item B<EVP_KDF_CTRL_SET_KEY>
+
+This control expects two arguments: C<unsigned char *secret>, C<size_t secretlen>
+
+The shared secret used for key derivation. This control sets the secret.
+
+EVP_KDF_ctrl_str() takes two type strings for this control:
+
+=over 4
+
+=item "secret"
+
+The value string is used as is.
+
+=item "hexsecret"
+
+The value string is expected to be a hexadecimal number, which will be
+decoded before being passed on as the control value.
+
+=back
+
+=item B<EVP_KDF_CTRL_SET_SHARED_INFO>
+
+This control expects two arguments: C<unsigned char *info>, C<size_t infolen>
+
+An optional value for shared info. This control sets the shared info.
+
+EVP_KDF_ctrl_str() takes two type strings for this control:
+
+=over 4
+
+=item "info"
+
+The value string is used as is.
+
+=item "hexinfo"
+
+The value string is expected to be a hexadecimal number, which will be
+decoded before being passed on as the control value.
+
+=back
+
+=back
+
+=head1 NOTES
+
+X963KDF is very similar to the SSKDF that uses a digest as the auxilary function,
+X963KDF appends the counter to the secret, whereas SSKDF prepends the counter.
+
+A context for X963KDF can be obtained by calling:
+
+EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_X963);
+
+The output length of an X963KDF is specified via the C<keylen>
+parameter to the L<EVP_KDF_derive(3)> function.
+
+=head1 EXAMPLE
+
+This example derives 10 bytes, with the secret key "secret" and sharedinfo
+value "label":
+
+ EVP_KDF_CTX *kctx;
+ unsigned char out[10];
+
+ kctx = EVP_KDF_CTX_new_id(EVP_KDF_X963);
+
+ if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
+ error("EVP_KDF_CTRL_SET_MD");
+ }
+ if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) {
+ error("EVP_KDF_CTRL_SET_KEY");
+ }
+ if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, "label", (size_t)5) <= 0) {
+ error("EVP_KDF_CTRL_SET_SHARED_INFO");
+ }
+ if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
+ error("EVP_KDF_derive");
+ }
+
+ EVP_KDF_CTX_free(kctx);
+
+=head1 CONFORMING TO
+
+"SEC 1: Elliptic Curve Cryptography"
+
+=head1 SEE ALSO
+
+L<EVP_KDF_CTX>,
+L<EVP_KDF_CTX_new_id(3)>,
+L<EVP_KDF_CTX_free(3)>,
+L<EVP_KDF_ctrl(3)>,
+L<EVP_KDF_size(3)>,
+L<EVP_KDF_derive(3)>,
+L<EVP_KDF_CTX(3)/CONTROLS>
+
+=head1 HISTORY
+
+This functionality was added to OpenSSL 3.0.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
index 6f38066743..b13b54cfc9 100644
--- a/include/openssl/kdf.h
+++ b/include/openssl/kdf.h
@@ -24,6 +24,7 @@ extern "C" {
# define EVP_KDF_HKDF NID_hkdf
# define EVP_KDF_SSHKDF NID_sshkdf
# define EVP_KDF_SS NID_sskdf
+# define EVP_KDF_X963 NID_x963kdf
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id);
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf);
@@ -64,6 +65,7 @@ const EVP_KDF *EVP_get_kdfbyname(const char *name);
# define EVP_KDF_CTRL_SET_MAC 0x13 /* EVP_MAC * */
# define EVP_KDF_CTRL_SET_MAC_SIZE 0x14 /* size_t */
# define EVP_KDF_CTRL_SET_SSKDF_INFO 0x15 /* unsigned char *, size_t */
+# define EVP_KDF_CTRL_SET_SHARED_INFO EVP_KDF_CTRL_SET_SSKDF_INFO
# define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 0
# define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1
diff --git a/include/openssl/kdferr.h b/include/openssl/kdferr.h
index bad8f13c42..db87f69ed2 100644
--- a/include/openssl/kdferr.h
+++ b/include/openssl/kdferr.h
@@ -62,6 +62,7 @@ int ERR_load_KDF_strings(void);
# define KDF_F_SSKDF_NEW 137
# define KDF_F_SSKDF_SIZE 138
# define KDF_F_TLS1_PRF_ALG 111
+# define KDF_F_X963KDF_DERIVE 139
/*
* KDF reason codes.
@@ -79,6 +80,7 @@ int ERR_load_KDF_strings(void);
# define KDF_R_MISSING_SESSION_ID 113
# define KDF_R_MISSING_TYPE 114
# define KDF_R_MISSING_XCGHASH 115
+# define KDF_R_NOT_SUPPORTED 118
# define KDF_R_UNKNOWN_PARAMETER_TYPE 103
# define KDF_R_UNSUPPORTED_MAC_TYPE 117
# define KDF_R_VALUE_ERROR 108
diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
index a0d4eed358..48d201d3d6 100644
--- a/include/openssl/obj_mac.h
+++ b/include/openssl/obj_mac.h
@@ -5004,6 +5004,10 @@
#define LN_sskdf "sskdf"
#define NID_sskdf 1205
+#define SN_x963kdf "X963KDF"
+#define LN_x963kdf "x963kdf"
+#define NID_x963kdf 1206
+
#define SN_id_pkinit "id-pkinit"
#define NID_id_pkinit 1031
#define OBJ_id_pkinit 1L,3L,6L,1L,5L,2L,3L
diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c
index 51f601eb24..79177f98ec 100644
--- a/test/evp_kdf_test.c
+++ b/test/evp_kdf_test.c
@@ -23,7 +23,7 @@ static int test_kdf_tls1_prf(void)
EVP_KDF_CTX *kctx = NULL;
const EVP_KDF *kdf;
unsigned char out[16];
- const unsigned char expected[sizeof(out)] = {
+ static const unsigned char expected[sizeof(out)] = {
0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc
};
@@ -50,7 +50,7 @@ static int test_kdf_hkdf(void)
int ret;
EVP_KDF_CTX *kctx;
unsigned char out[10];
- const unsigned char expected[sizeof(out)] = {
+ static const unsigned char expected[sizeof(out)] = {
0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
};
@@ -75,7 +75,7 @@ static int test_kdf_pbkdf2(void)
int ret;
EVP_KDF_CTX *kctx;
unsigned char out[32];
- const unsigned char expected[sizeof(out)] = {
+ static const unsigned char expected[sizeof(out)] = {
0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
@@ -103,7 +103,7 @@ static int test_kdf_scrypt(void)
int ret;
EVP_KDF_CTX *kctx;
unsigned char out[64];
- const unsigned char expected[sizeof(out)] = {
+ static const unsigned char expected[sizeof(out)] = {
0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
@@ -144,22 +144,22 @@ static int test_kdf_ss_hash(void)
{
int ret;
EVP_KDF_CTX *kctx = NULL;
- const unsigned char z[] = {
+ unsigned char out[14];
+ static const unsigned char z[] = {
0x6d,0xbd,0xc2,0x3f,0x04,0x54,0x88,0xe4,0x06,0x27,0x57,0xb0,0x6b,0x9e,
0xba,0xe1,0x83,0xfc,0x5a,0x59,0x46,0xd8,0x0d,0xb9,0x3f,0xec,0x6f,0x62,
0xec,0x07,0xe3,0x72,0x7f,0x01,0x26,0xae,0xd1,0x2c,0xe4,0xb2,0x62,0xf4,
0x7d,0x48,0xd5,0x42,0x87,0xf8,0x1d,0x47,0x4c,0x7c,0x3b,0x18,0x50,0xe9
};
- const unsigned char other[] = {
+ static const unsigned char other[] = {
0xa1,0xb2,0xc3,0xd4,0xe5,0x43,0x41,0x56,0x53,0x69,0x64,0x3c,0x83,0x2e,
0x98,0x49,0xdc,0xdb,0xa7,0x1e,0x9a,0x31,0x39,0xe6,0x06,0xe0,0x95,0xde,
0x3c,0x26,0x4a,0x66,0xe9,0x8a,0x16,0x58,0x54,0xcd,0x07,0x98,0x9b,0x1e,
0xe0,0xec,0x3f,0x8d,0xbe
};
- const unsigned char expected[] = {
+ static const unsigned char expected[sizeof(out)] = {
0xa4,0x62,0xde,0x16,0xa8,0x9d,0xe8,0x46,0x6e,0xf5,0x46,0x0b,0x47,0xb8
};
- unsigned char out[14];
ret =
TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS))
@@ -174,27 +174,75 @@ static int test_kdf_ss_hash(void)
return ret;
}
+static int test_kdf_x963(void)
+{
+ int ret;
+ EVP_KDF_CTX *kctx = NULL;
+ unsigned char out[1024 / 8];
+ /*
+ * Test data from https://csrc.nist.gov/CSRC/media/Projects/
+ * Cryptographic-Algorithm-Validation-Program/documents/components/
+ * 800-135testvectors/ansx963_2001.zip
+ */
+ static const unsigned char z[] = {
+ 0x00, 0xaa, 0x5b, 0xb7, 0x9b, 0x33, 0xe3, 0x89, 0xfa, 0x58, 0xce, 0xad,
+ 0xc0, 0x47, 0x19, 0x7f, 0x14, 0xe7, 0x37, 0x12, 0xf4, 0x52, 0xca, 0xa9,
+ 0xfc, 0x4c, 0x9a, 0xdb, 0x36, 0x93, 0x48, 0xb8, 0x15, 0x07, 0x39, 0x2f,
+ 0x1a, 0x86, 0xdd, 0xfd, 0xb7, 0xc4, 0xff, 0x82, 0x31, 0xc4, 0xbd, 0x0f,
+ 0x44, 0xe4, 0x4a, 0x1b, 0x55, 0xb1, 0x40, 0x47, 0x47, 0xa9, 0xe2, 0xe7,
+ 0x53, 0xf5, 0x5e, 0xf0, 0x5a, 0x2d
+ };
+ static const unsigned char shared[] = {
+ 0xe3, 0xb5, 0xb4, 0xc1, 0xb0, 0xd5, 0xcf, 0x1d, 0x2b, 0x3a, 0x2f, 0x99,
+ 0x37, 0x89, 0x5d, 0x31
+ };
+ static const unsigned char expected[sizeof(out)] = {
+ 0x44, 0x63, 0xf8, 0x69, 0xf3, 0xcc, 0x18, 0x76, 0x9b, 0x52, 0x26, 0x4b,
+ 0x01, 0x12, 0xb5, 0x85, 0x8f, 0x7a, 0xd3, 0x2a, 0x5a, 0x2d, 0x96, 0xd8,
+ 0xcf, 0xfa, 0xbf, 0x7f, 0xa7, 0x33, 0x63, 0x3d, 0x6e, 0x4d, 0xd2, 0xa5,
+ 0x99, 0xac, 0xce, 0xb3, 0xea, 0x54, 0xa6, 0x21, 0x7c, 0xe0, 0xb5, 0x0e,
+ 0xef, 0x4f, 0x6b, 0x40, 0xa5, 0xc3, 0x02, 0x50, 0xa5, 0xa8, 0xee, 0xee,
+ 0x20, 0x80, 0x02, 0x26, 0x70, 0x89, 0xdb, 0xf3, 0x51, 0xf3, 0xf5, 0x02,
+ 0x2a, 0xa9, 0x63, 0x8b, 0xf1, 0xee, 0x41, 0x9d, 0xea, 0x9c, 0x4f, 0xf7,
+ 0x45, 0xa2, 0x5a, 0xc2, 0x7b, 0xda, 0x33, 0xca, 0x08, 0xbd, 0x56, 0xdd,
+ 0x1a, 0x59, 0xb4, 0x10, 0x6c, 0xf2, 0xdb, 0xbc, 0x0a, 0xb2, 0xaa, 0x8e,
+ 0x2e, 0xfa, 0x7b, 0x17, 0x90, 0x2d, 0x34, 0x27, 0x69, 0x51, 0xce, 0xcc,
+ 0xab, 0x87, 0xf9, 0x66, 0x1c, 0x3e, 0x88, 0x16
+ };
+
+ ret =
+ TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_X963))
+ && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha512()), 0)
+ && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)), 0)
+ && TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SHARED_INFO, shared,
+ sizeof(shared)), 0)
+ && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0)
+ && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
+
+ EVP_KDF_CTX_free(kctx);
+ return ret;
+}
+
static int test_kdf_ss_hmac(void)
{
int ret;
EVP_KDF_CTX *kctx;
const EVP_MAC *mac;
-
- const unsigned char z[] = {
+ unsigned char out[16];
+ static const unsigned char z[] = {
0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
};
- const unsigned char other[] = {
+ static const unsigned char other[] = {
0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
};
- const unsigned char salt[] = {
+ static const unsigned char salt[] = {
0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
0x3f,0x89
};
- const unsigned char expected[] = {
+ static const unsigned char expected[sizeof(out)] = {
0x44,0xf6,0x76,0xe8,0x5c,0x1b,0x1a,0x8b,0xbc,0x3d,0x31,0x92,0x18,0x63,
0x1c,0xa3
};
- unsigned char out[16];
ret =
TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS))
@@ -219,18 +267,17 @@ static int test_kdf_ss_kmac(void)
EVP_KDF_CTX *kctx;
unsigned char out[64];
const EVP_MAC *mac;
-
- const unsigned char z[] = {
+ static const unsigned char z[] = {
0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
};
- const unsigned char other[] = {
+ static const unsigned char other[] = {
0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
};
- const unsigned char salt[] = {
+ static const unsigned char salt[] = {
0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
0x3f,0x89
};
- const unsigned char expected[] = {
+ static const unsigned char expected[sizeof(out)] = {
0xe9,0xc1,0x84,0x53,0xa0,0x62,0xb5,0x3b,0xdb,0xfc,0xbb,0x5a,0x34,0xbd,
0xb8,0xe5,0xe7,0x07,0xee,0xbb,0x5d,0xd1,0x34,0x42,0x43,0xd8,0xcf,0xc2,
0xc2,0xe6,0x33,0x2f,0x91,0xbd,0xa5,0x86,0xf3,0x7d,0xe4,0x8a,0x65,0xd4,
@@ -263,7 +310,7 @@ static int test_kdf_sshkdf(void)
EVP_KDF_CTX *kctx;
unsigned char out[8];
/* Test data from NIST CAVS 14.1 test vectors */
- const unsigned char key[] = {
+ static const unsigned char key[] = {
0x00, 0x00, 0x00, 0x81, 0x00, 0x87, 0x5c, 0x55, 0x1c, 0xef, 0x52, 0x6a,
0x4a, 0x8b, 0xe1, 0xa7, 0xdf, 0x27, 0xe9, 0xed, 0x35, 0x4b, 0xac, 0x9a,
0xfb, 0x71, 0xf5, 0x3d, 0xba, 0xe9, 0x05, 0x67, 0x9d, 0x14, 0xf9, 0xfa,
@@ -277,17 +324,17 @@ static int test_kdf_sshkdf(void)
0xaa, 0x22, 0x76, 0x93, 0xe1, 0x41, 0xad, 0x16, 0x30, 0xce, 0x13, 0x14,
0x4e
};
- const unsigned char xcghash[] = {
+ static const unsigned char xcghash[] = {
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
- const unsigned char sessid[] = {
+ static const unsigned char sessid[] = {
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
- const unsigned char expected[sizeof(out)] = {
+ static const unsigned char expected[sizeof(out)] = {
0x41, 0xff, 0x2e, 0xad, 0x16, 0x83, 0xf1, 0xe6
};
@@ -340,5 +387,6 @@ int setup_tests(void)
ADD_TEST(test_kdf_ss_hmac);
ADD_TEST(test_kdf_ss_kmac);
ADD_TEST(test_kdf_sshkdf);
+ ADD_TEST(test_kdf_x963);
return 1;
}
diff --git a/test/recipes/30-test_evp_data/evpkdf.txt b/test/recipes/30-test_evp_data/evpkdf.txt
index c66b6da901..7100c21f49 100644
--- a/test/recipes/30-test_evp_data/evpkdf.txt
+++ b/test/recipes/30-test_evp_data/evpkdf.txt
@@ -6375,3 +6375,101 @@ Ctrl.digest = digest:SHA512
Ctrl.hexsecret = hexsecret:abb7d7554c0de41cada5826a1f79d76f
Ctrl.hexinfo = hexinfo:a80b9061879365b1669c87a8
Output = 71e29fff69198eca92f5180bcb281fbdaf409ec7c99ca704b1f56e782d3c4db10cb4158e6634d793a46c13bffb6bdb71a01101936ea9b20f7dbe302558b1356c
+
+# Test vectors extracted from
+# https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/components/800-135testvectors/ansx963_2001.zip
+Title = X963 KDF tests (from NIST test vectors)
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA1
+Ctrl.hexsecret = hexsecret:fd17198b89ab39c4ab5d7cca363b82f9fd7e23c3984dc8a2
+Ctrl.hexinfo = hexinfo:856a53f3e36a26bbc5792879f307cce2
+Output = 6e5fad865cb4a51c95209b16df0cc490bc2c9064405c5bccd4ee4832a531fbe7f10cb79e2eab6ab1149fbd5a23cfdabc41242269c9df22f628c4424333855b64e95e2d4fb8469c669f17176c07d103376b10b384ec5763d8b8c610409f19aca8eb31f9d85cc61a8d6d4a03d03e5a506b78d6847e93d295ee548c65afedd2efec
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA224
+Ctrl.hexsecret = hexsecret:da67a73072d521a8272c69023573012ddf9b46bff65b3900
+Ctrl.hexinfo = hexinfo:727997aed53e78f74b1d66743a4ea4d2
+Output = dfc3126c5eebf9a58d89730e8d8ff7cc772592f28c10b349b437d9d068698a22e532eae975dfaf9c5c6a9f2935eafb05353013c253444e61f07bc9ddd15948e614bdc7e445ba3b1893f42f87f18fb352d49956009a642c362d45410b43a9ab376e9261210739174759511d1f9e52f6ec73dfed446dbafaf7fd1a57113abc2e8d
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA256
+Ctrl.hexsecret = hexsecret:22518b10e70f2a3f243810ae3254139efbee04aa57c7af7d
+Ctrl.hexinfo = hexinfo:75eef81aa3041e33b80971203d2c0c52
+Output = c498af77161cc59f2962b9a713e2b215152d139766ce34a776df11866a69bf2e52a13d9c7c6fc878c50c5ea0bc7b00e0da2447cfd874f6cf92f30d0097111485500c90c3af8b487872d04685d14c8d1dc8d7fa08beb0ce0ababc11f0bd496269142d43525a78e5bc79a17f59676a5706dc54d54d4d1f0bd7e386128ec26afc21
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA384
+Ctrl.hexsecret = hexsecret:d8554db1b392cd55c3fe957bed76af09c13ac2a9392f88f6
+Output = 671a46aada145162f8ddf1ca586a1cda
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA384
+Ctrl.hexsecret = hexsecret:c051fd22539c9de791d6c43a854b8f80a6bf70190050854a
+Ctrl.hexinfo = hexinfo:1317504aa34759bb4c931e3b78201945
+Output = cf6a84434734ac6949e1d7976743277be789906908ad3ca3a8923da7f476abbeb574306d7243031a85566914bfd247d2519c479953d9d55b6b831e56260806c39af21b74e3ecf470e3bd8332791c8a23c13352514fdef00c2d1a408ba31b2d3f9fdcb373895484649a645d1845eec91b5bfdc5ad28c7824984482002dd4a8677
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:87fc0d8c4477485bb574f5fcea264b30885dc8d90ad82782
+Output = 947665fbb9152153ef460238506a0245
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:00aa5bb79b33e389fa58ceadc047197f14e73712f452caa9fc4c9adb369348b81507392f1a86ddfdb7c4ff8231c4bd0f44e44a1b55b1404747a9e2e753f55ef05a2d
+Ctrl.hexinfo = hexinfo:e3b5b4c1b0d5cf1d2b3a2f9937895d31
+Output = 4463f869f3cc18769b52264b0112b5858f7ad32a5a2d96d8cffabf7fa733633d6e4dd2a599acceb3ea54a6217ce0b50eef4f6b40a5c30250a5a8eeee208002267089dbf351f3f5022aa9638bf1ee419dea9c4ff745a25ac27bda33ca08bd56dd1a59b4106cf2dbbc0ab2aa8e2efa7b17902d34276951ceccab87f9661c3e8816
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:009dcd6ba5c8c803ca21f9996ca5dd86047d4ddc150fddace1b1ebe996c2007e3ee907c8ff03b9ef766e8ceb4dedf7489e5162e2278c0185e4be381bec17dd992cf8
+Ctrl.hexinfo = hexinfo:1e60e51c11a538b0ea8990d69a4c6358
+Output = 4e55036a32f32fc965046fdfbf686c108e43a69f8fc1a64ff1bd77763f2eedc8bf277d78b4ce31243e1adbe2c2d5dd59b47503b5b90b54f9d7a9a5aea49c7f0283cb64c3849a1d157000fd41ef6c1d1a5b62734e7c9a20dcfb57f2da974933f57ee619d72898d0e93d9a4254aaddf73941d6269298b4d49c0ac64a33802fe8f2
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:01bbc44314f24db4d67a2a7fb5ca3f7a5022790f5875895d448050eda5611a2f39de48e394c5a3df26208eb01f804d0a1d68eece6b6fa96d6db895e133e129094f78
+Ctrl.hexinfo = hexinfo:433e3ee77d00e4a9634efd677e2ff21b
+Output = f1255002293d5fbcf35ad0e532ae872171d11014616a2c52d7e5cb861b0251b9e505a77161c777bafc052b6525a6ecf34590605de72f13a1aff0a61a8a4a3364ebbe2f99224c13e043e497af8a26de749cd257e475b2f0e60e3b594901320a692a4af422f9636e4814b33f67d181a086265013b0d4efd9e1a94ea8a576afde66
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:01a33032a2bf6f8e9d6972dd339536c9e248ae9881844ff1bd04af48085be4ca1834f2a94ce1019dd9620d1e3a68203a5b291f40b5f8e3238a2a036312b89061cc60
+Ctrl.hexinfo = hexinfo:d3297ad6b9757d1f5a9d5b0e72176d74
+Output = 63565d1d3443620fba4218c97887ff40d6d68bf56b429c22018be5d91c318187ebe8a9399c5cc6c4a849288ab784d4340714ae3fdb426c4a83db9ce2ba8aea80d448e50ad543749b47bcaae519f7f00badd8d48296e81069104dcd293c605b08159ef2ef14c7833739d0414274136ae4db05ba4fa31b29c59de46d9be539525f
+
+KDF = X963KDF
+Ctrl.digest = digest:SHA512
+Ctrl.hexsecret = hexsecret:004b20a501776ea54cbdabffec2a664b7a93f8d67b17405a82bd9cbf3685a4659beb2deff1b6ecaa7ab187b6d4fd407f10db6992c65308410deb133be31a0de0c1c9
+Ctrl.hexinfo = hexinfo:fd5462cb37aa298e95f8e34bb49d85ca
+Output = cafc