summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-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
10 files changed, 77 insertions, 57 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