diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2021-02-05 17:45:39 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2021-02-10 10:28:32 +1000 |
commit | 8a686bdb3ac7d61b6d5f02b9132c4878ae80a7e5 (patch) | |
tree | c82f6f791129ae7cff64d7031544eaefaaaff3c9 /providers/implementations/kdfs | |
parent | 7e365d51a1ac7f092b7c2e459332051126f76d72 (diff) |
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)
Diffstat (limited to 'providers/implementations/kdfs')
-rw-r--r-- | providers/implementations/kdfs/x942kdf.c | 69 |
1 files changed, 50 insertions, 19 deletions
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), |