diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2019-05-16 11:43:41 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2019-05-16 11:43:41 +1000 |
commit | 8bbeaaa4fc12f8b00fbea4dc649ef74b59f73b17 (patch) | |
tree | bf043355836767d39f96bd2a67b9bc3b7798dd9d /crypto/kdf | |
parent | 0211740fcc47a954be19cceb65fb57a6f7deb797 (diff) |
Added X963KDF API
X963 KDF is used for CMS ec keyagree Recipient Info.
The X963 KDF that is used by CMS EC Key Agreement has been moved
into a EVP_KDF object. This KDF is almost identical to the the SSKDF
hash variant, so it has been implemented inside the SSKDF code with
its own method table.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8902)
Diffstat (limited to 'crypto/kdf')
-rw-r--r-- | crypto/kdf/kdf_err.c | 2 | ||||
-rw-r--r-- | crypto/kdf/sskdf.c | 43 |
2 files changed, 43 insertions, 2 deletions
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 +}; |