diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2021-02-05 08:45:39 +0100 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2021-02-10 01:28:32 +0100 |
commit | 8a686bdb3ac7d61b6d5f02b9132c4878ae80a7e5 (patch) | |
tree | c82f6f791129ae7cff64d7031544eaefaaaff3c9 | |
parent | x509_vfy.c: Sort out return values 0 vs. -1 (failure/internal error) (diff) | |
download | openssl-8a686bdb3ac7d61b6d5f02b9132c4878ae80a7e5.tar.xz openssl-8a686bdb3ac7d61b6d5f02b9132c4878ae80a7e5.zip |
Change the ASN1 variant of x942kdf so that it can test acvp data.
This 'special' way of specifying the data should only be used for testing
purposes. It should not be used in production environments.
ACVP passes a blob of DER encoded data for some of the fields rather
than passing them as separate fields that need to be DER encoded.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14077)
-rw-r--r-- | doc/man7/EVP_KDF-X942-ASN1.pod | 8 | ||||
-rw-r--r-- | include/openssl/core_names.h | 1 | ||||
-rw-r--r-- | providers/implementations/kdfs/x942kdf.c | 69 | ||||
-rw-r--r-- | test/recipes/30-test_evp_data/evpkdf_x942.txt | 32 |
4 files changed, 91 insertions, 19 deletions
diff --git a/doc/man7/EVP_KDF-X942-ASN1.pod b/doc/man7/EVP_KDF-X942-ASN1.pod index 3c5c3077ca..bc19b27508 100644 --- a/doc/man7/EVP_KDF-X942-ASN1.pod +++ b/doc/man7/EVP_KDF-X942-ASN1.pod @@ -34,6 +34,14 @@ These parameters work as described in L<EVP_KDF(3)/PARAMETERS>. The shared secret used for key derivation. This parameter sets the secret. +=item "acvp-info" (B<OSSL_KDF_PARAM_X942_ACVPINFO>) <octet string> + +This value should not be used in production and should only be used for ACVP +testing. It is an optional octet string containing a combined DER encoded blob +of any of the optional fields related to "partyu-info", "partyv-info", +"supp-pubinfo" and "supp-privinfo". If it is specified then none of these other +fields should be used. + =item "partyu-info" (B<OSSL_KDF_PARAM_X942_PARTYUINFO>) <octet string> An optional octet string containing public info contributed by the initiator. diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 07b95e043b..221d67b823 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -203,6 +203,7 @@ extern "C" { #define OSSL_KDF_PARAM_PKCS12_ID "id" /* int */ #define OSSL_KDF_PARAM_KBKDF_USE_L "use-l" /* int */ #define OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR "use-separator" /* int */ +#define OSSL_KDF_PARAM_X942_ACVPINFO "acvp-info" #define OSSL_KDF_PARAM_X942_PARTYUINFO "partyu-info" #define OSSL_KDF_PARAM_X942_PARTYVINFO "partyv-info" #define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo" diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c index 31a69a096e..ae3ed69201 100644 --- a/providers/implementations/kdfs/x942kdf.c +++ b/providers/implementations/kdfs/x942kdf.c @@ -39,6 +39,8 @@ typedef struct { PROV_DIGEST digest; unsigned char *secret; size_t secret_len; + unsigned char *acvpinfo; + size_t acvpinfo_len; unsigned char *partyuinfo, *partyvinfo, *supp_pubinfo, *supp_privinfo; size_t partyuinfo_len, partyvinfo_len, supp_pubinfo_len, supp_privinfo_len; size_t dkm_len; @@ -110,6 +112,7 @@ static int DER_w_keyinfo(WPACKET *pkt, static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen, const unsigned char *der_oid, size_t der_oidlen, + const unsigned char *acvp, size_t acvplen, const unsigned char *partyu, size_t partyulen, const unsigned char *partyv, size_t partyvlen, const unsigned char *supp_pub, size_t supp_publen, @@ -127,6 +130,7 @@ static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen || ossl_DER_w_octet_string_uint32(pkt, 2, keylen_bits)) && (partyv == NULL || ossl_DER_w_octet_string(pkt, 1, partyv, partyvlen)) && (partyu == NULL || ossl_DER_w_octet_string(pkt, 0, partyu, partyulen)) + && (acvp == NULL || ossl_DER_w_precompiled(pkt, -1, acvp, acvplen)) && DER_w_keyinfo(pkt, der_oid, der_oidlen, pcounter) && ossl_DER_w_end_sequence(pkt, -1) && WPACKET_finish(pkt); @@ -159,35 +163,40 @@ static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen * } * Where suppPubInfo is the key length (in bits) (stored into 4 bytes) * -} - * * |keylen| is the length (in bytes) of the generated KEK. It is stored into - * suppPubInfo (in bits). It is ignored if the value is 0. + * suppPubInfo (in bits). It is ignored if the value is 0. * |cek_oid| The oid of the key wrapping algorithm. * |cek_oidlen| The length (in bytes) of the key wrapping algorithm oid, - * |partyu| is the optional public info contributed by the initiator. It - * can be NULL. (It is also used as the ukm by CMS). + * |acvp| is the optional blob of DER data representing one or more of the + * OtherInfo fields related to |partyu|, |partyv|, |supp_pub| and |supp_priv|. + * This field should noramlly be NULL. If |acvp| is non NULL then |partyu|, + * |partyv|, |supp_pub| and |supp_priv| should all be NULL. + * |acvp_len| is the |acvp| length (in bytes). + * |partyu| is the optional public info contributed by the initiator. + * It can be NULL. (It is also used as the ukm by CMS). * |partyu_len| is the |partyu| length (in bytes). - * |partyv| is the optional public info contributed by the responder. It - * can be NULL. + * |partyv| is the optional public info contributed by the responder. + * It can be NULL. * |partyv_len| is the |partyv| length (in bytes). - * |supp_pub| is the optional additional, mutually-known public information. It - * can be NULL. |keylen| should be 0 if this is not NULL. + * |supp_pub| is the optional additional, mutually-known public information. + * It can be NULL. |keylen| should be 0 if this is not NULL. * |supp_pub_len| is the |supp_pub| length (in bytes). - * |supp_priv| is the optional additional, mutually-known private information. It - * can be NULL. + * |supp_priv| is the optional additional, mutually-known private information. + * It can be NULL. * |supp_priv_len| is the |supp_priv| length (in bytes). * |der| is the returned encoded data. It must be freed by the caller. * |der_len| is the returned size of the encoded data. * |out_ctr| returns a pointer to the counter data which is embedded inside the - * encoded data. This allows the counter bytes to be updated without re-encoding. + * encoded data. This allows the counter bytes to be updated without + * re-encoding. * * Returns: 1 if successfully encoded, or 0 otherwise. * Assumptions: |der|, |der_len| & |out_ctr| are not NULL. */ static int x942_encode_otherinfo(size_t keylen, - const unsigned char *cek_oid, size_t cek_oidlen, + const unsigned char *cek_oid, size_t cek_oid_len, + const unsigned char *acvp, size_t acvp_len, const unsigned char *partyu, size_t partyu_len, const unsigned char *partyv, size_t partyv_len, const unsigned char *supp_pub, size_t supp_pub_len, @@ -207,7 +216,8 @@ x942_encode_otherinfo(size_t keylen, keylen_bits = 8 * keylen; /* Calculate the size of the buffer */ - if (!der_encode_sharedinfo(&pkt, NULL, 0, cek_oid, cek_oidlen, + if (!der_encode_sharedinfo(&pkt, NULL, 0, cek_oid, cek_oid_len, + acvp, acvp_len, partyu, partyu_len, partyv, partyv_len, supp_pub, supp_pub_len, supp_priv, supp_priv_len, keylen_bits, NULL) @@ -219,7 +229,8 @@ x942_encode_otherinfo(size_t keylen, if (der_buf == NULL) goto err; /* Encode into the buffer */ - if (!der_encode_sharedinfo(&pkt, der_buf, der_buflen, cek_oid, cek_oidlen, + if (!der_encode_sharedinfo(&pkt, der_buf, der_buflen, cek_oid, cek_oid_len, + acvp, acvp_len, partyu, partyu_len, partyv, partyv_len, supp_pub, supp_pub_len, supp_priv, supp_priv_len, keylen_bits, &pcounter)) @@ -262,9 +273,10 @@ static int x942kdf_hash_kdm(const EVP_MD *kdf_md, unsigned char *out = derived_key; EVP_MD_CTX *ctx = NULL, *ctx_init = NULL; - if (z_len > X942KDF_MAX_INLEN || other_len > X942KDF_MAX_INLEN - || derived_key_len > X942KDF_MAX_INLEN - || derived_key_len == 0) { + if (z_len > X942KDF_MAX_INLEN + || other_len > X942KDF_MAX_INLEN + || derived_key_len > X942KDF_MAX_INLEN + || derived_key_len == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); return 0; } @@ -336,6 +348,7 @@ static void x942kdf_reset(void *vctx) ossl_prov_digest_reset(&ctx->digest); OPENSSL_clear_free(ctx->secret, ctx->secret_len); + OPENSSL_clear_free(ctx->acvpinfo, ctx->acvpinfo_len); OPENSSL_clear_free(ctx->partyuinfo, ctx->partyuinfo_len); OPENSSL_clear_free(ctx->partyvinfo, ctx->partyvinfo_len); OPENSSL_clear_free(ctx->supp_pubinfo, ctx->supp_pubinfo_len); @@ -399,7 +412,18 @@ static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen) ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PUBINFO); return 0; } - + /* + * If the blob of acvp data is used then the individual info fields that it + * replaces should not also be defined. + */ + if (ctx->acvpinfo != NULL + && (ctx->partyuinfo != NULL + || ctx->partyvinfo != NULL + || ctx->supp_pubinfo != NULL + || ctx->supp_privinfo != NULL)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA); + return 0; + } if (ctx->secret == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET); return 0; @@ -424,6 +448,7 @@ static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen) /* generate the otherinfo der */ if (!x942_encode_otherinfo(ctx->use_keybits ? ctx->dkm_len : 0, ctx->cek_oid, ctx->cek_oid_len, + ctx->acvpinfo, ctx->acvpinfo_len, ctx->partyuinfo, ctx->partyuinfo_len, ctx->partyvinfo, ctx->partyvinfo_len, ctx->supp_pubinfo, ctx->supp_pubinfo_len, @@ -455,6 +480,11 @@ static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (p != NULL && !x942kdf_set_buffer(&ctx->secret, &ctx->secret_len, p)) return 0; + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_ACVPINFO); + if (p != NULL + && !x942kdf_set_buffer(&ctx->acvpinfo, &ctx->acvpinfo_len, p)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_X942_PARTYUINFO); if (p == NULL) p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_UKM); @@ -511,6 +541,7 @@ static const OSSL_PARAM *x942kdf_settable_ctx_params(ossl_unused void *provctx) OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_UKM, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_ACVPINFO, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYUINFO, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_PARTYVINFO, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_X942_SUPP_PUBINFO, NULL, 0), diff --git a/test/recipes/30-test_evp_data/evpkdf_x942.txt b/test/recipes/30-test_evp_data/evpkdf_x942.txt index 88f9dd379d..b695c64f5b 100644 --- a/test/recipes/30-test_evp_data/evpkdf_x942.txt +++ b/test/recipes/30-test_evp_data/evpkdf_x942.txt @@ -83,3 +83,35 @@ Ctrl.hexpartyv-info = hexpartyv-info:fedcba9876543210 Ctrl.hexsupp-pubinfo = hexsupp-pubinfo:12345678 Ctrl.hexsupp-privinfo = hexsupp-privinfo:87654321 Output = 2c5c1f028c6d1fc9ba752e41fdb9edb2ea936f1b2449f214acd56d31 + +Title = X9.42 KDF tests (ACVP test vectors) + +Availablein = default +KDF = X942KDF-ASN1 +Ctrl.digest = digest:SHA256 +Ctrl.hexsecret = hexsecret:6B +Ctrl.use-keybits = use-keybits:0 +Ctrl.cekalg = cekalg:id-smime-alg-CMS3DESwrap +Ctrl.hexacvp-info = hexacvp-info:a020299D468D60BC6A257E0B6523D691A3FC1602453B35F308C762FBBAC6069A88BCa12080D49BFE5BE01C7D56489AB017663C22B8CBB34C3174D1D71F00CB7505AC759Aa2203C21A5EA5988562C007986E0503D039E7231D9F152FE72A231A1FD98C59BCA6Aa320FD47477542989B51E4A0845DFABD6EEAA465F69B3D75349B2520051782C7F3FC +Output = A7758EC5DA5373C736F1E4CF18A4B6349B23ED86227234185B44638C69EBB222 + +KDF = X942KDF-ASN1 +Ctrl.digest = digest:SHA256 +Ctrl.hexsecret = hexsecret:6B +Ctrl.use-keybits = use-keybits:0 +Ctrl.cekalg = cekalg:id-aes128-wrap +Ctrl.hexacvp-info = hexacvp-info:a020299D468D60BC6A257E0B6523D691A3FC1602453B35F308C762FBBAC6069A88BCa12080D49BFE5BE01C7D56489AB017663C22B8CBB34C3174D1D71F00CB7505AC759Aa2203C21A5EA5988562C007986E0503D039E7231D9F152FE72A231A1FD98C59BCA6Aa320FD47477542989B51E4A0845DFABD6EEAA465F69B3D75349B2520051782C7F3FC +Output = C2E6A0978C24AF3932F478583ADBFB5F57D491822592EAD3C538875F46EB057A + +# Negative tests + +# Fail if both acvp and ukm values are specified. +KDF = X942KDF-ASN1 +Ctrl.digest = digest:SHA256 +Ctrl.hexsecret = hexsecret:6B +Ctrl.use-keybits = use-keybits:0 +Ctrl.cekalg = cekalg:id-aes128-wrap +Ctrl.hexacvp-info = hexacvp-info:a020299D468D60BC6A257E0B6523D691A3FC1602453B35F308C762FBBAC6069A88BCa12080D49BFE5BE01C7D56489AB017663C22B8CBB34C3174D1D71F00CB7505AC759Aa2203C21A5EA5988562C007986E0503D039E7231D9F152FE72A231A1FD98C59BCA6Aa320FD47477542989B51E4A0845DFABD6EEAA465F69B3D75349B2520051782C7F3FC +Ctrl.hexukm = hexukm:012345 +Output = C2E6A0978C24AF3932F478583ADBFB5F57D491822592EAD3C538875F46EB057A +Result = KDF_DERIVE_ERROR |