diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ec/ecdh_kdf.c | 64 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 2 | ||||
-rw-r--r-- | crypto/evp/c_allkdf.c | 1 | ||||
-rw-r--r-- | crypto/evp/kdf_lib.c | 8 | ||||
-rw-r--r-- | crypto/include/internal/evp_int.h | 1 | ||||
-rw-r--r-- | crypto/kdf/kdf_err.c | 2 | ||||
-rw-r--r-- | crypto/kdf/sskdf.c | 43 | ||||
-rw-r--r-- | crypto/objects/obj_dat.h | 9 | ||||
-rw-r--r-- | crypto/objects/obj_mac.num | 1 | ||||
-rw-r--r-- | crypto/objects/objects.txt | 3 |
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 |