diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-01-12 11:32:12 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-01-12 11:32:12 +1000 |
commit | e683582bf37de45a9512aea7ff33b9a3ebdf07f4 (patch) | |
tree | 3a8c7e4f3ae908816ef57c15e56b619daa1430ac /providers | |
parent | e0e68f9e34585084038fba768fb2eecb5dd1ddf3 (diff) |
Add dsa signature alg to fips provider
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10615)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/fips/fipsprov.c | 178 | ||||
-rw-r--r-- | providers/implementations/keymgmt/dsa_kmgmt.c | 9 | ||||
-rw-r--r-- | providers/implementations/signature/dsa.c | 5 |
3 files changed, 181 insertions, 11 deletions
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 7afab78063..788963911b 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -121,6 +121,49 @@ static OSSL_PARAM core_params[] = OSSL_PARAM_END }; +/* + * This routine is currently necessary as bn params are currently processed + * using BN_native2bn when raw data is received. This means we need to do + * magic to reverse the order of the bytes to match native format. + * The array of hexdata is to get around compilers that dont like + * strings longer than 509 bytes, + */ +static int rawnative_fromhex(const char *hex_data[], + unsigned char **native, size_t *nativelen) +{ + int ret = 0; + unsigned char *data = NULL; + BIGNUM *bn = NULL; + int i, slen, datalen, sz; + char *str = NULL; + + for (slen = 0, i = 0; hex_data[i] != NULL; ++i) + slen += strlen(hex_data[i]); + str = OPENSSL_zalloc(slen + 1); + if (str == NULL) + return 0; + for (i = 0; hex_data[i] != NULL; ++i) + strcat(str, hex_data[i]); + + if (BN_hex2bn(&bn, str) <= 0) + return 0; + + datalen = slen / 2; + data = (unsigned char *)str; /* reuse the str buffer */ + + sz = BN_bn2nativepad(bn, data, datalen); + if (sz <= 0) + goto err; + ret = 1; + *native = data; + *nativelen = datalen; + data = NULL; /* so it does not get freed */ +err: + BN_free(bn); + OPENSSL_free(data); + return ret; +} + /* TODO(3.0): To be removed */ static int dummy_evp_call(void *provctx) { @@ -128,6 +171,58 @@ static int dummy_evp_call(void *provctx) EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL); EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, NULL); + EVP_PKEY_CTX *sctx = NULL, *kctx = NULL; + EVP_PKEY *pkey = NULL; + OSSL_PARAM *p; + OSSL_PARAM params[16]; + unsigned char sig[64]; + size_t siglen, sigdgstlen; + unsigned char *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL; + unsigned char *dsa_pub = NULL, *dsa_priv = NULL; + size_t dsa_p_len, dsa_q_len, dsa_g_len, dsa_pub_len, dsa_priv_len; + + /* dsa 2048 */ + static const char *dsa_p_hex[] = { + "a29b8872ce8b8423b7d5d21d4b02f57e03e9e6b8a258dc16611ba098ab543415" + "e415f156997a3ee236658fa093260de3ad422e05e046f9ec29161a375f0eb4ef" + "fcef58285c5d39ed425d7a62ca12896c4a92cb1946f2952a48133f07da364d1b" + "df6b0f7139983e693c80059b0eacd1479ba9f2857754ede75f112b07ebbf3534", + "8bbf3e01e02f2d473de39453f99dd2367541caca3ba01166343d7b5b58a37bd1" + "b7521db2f13b86707132fe09f4cd09dc1618fa3401ebf9cc7b19fa94aa472088" + "133d6cb2d35c1179c8c8ff368758d507d9f9a17d46c110fe3144ce9b022b42e4" + "19eb4f5388613bfc3e26241a432e8706bc58ef76117278deab6cf692618291b7", + NULL + }; + static const char *dsa_q_hex[] = { + "a3bfd9ab7884794e383450d5891dc18b65157bdcfcdac51518902867", + NULL + }; + static const char *dsa_g_hex[] = { + "6819278869c7fd3d2d7b77f77e8150d9ad433bea3ba85efc80415aa3545f78f7" + "2296f06cb19ceda06c94b0551cfe6e6f863e31d1de6eed7dab8b0c9df231e084" + "34d1184f91d033696bb382f8455e9888f5d31d4784ec40120246f4bea61794bb" + "a5866f09746463bdf8e9e108cd9529c3d0f6df80316e2e70aaeb1b26cdb8ad97", + "bc3d287e0b8d616c42e65b87db20deb7005bc416747a6470147a68a7820388eb" + "f44d52e0628af9cf1b7166d03465f35acc31b6110c43dabc7c5d591e671eaf7c" + "252c1c145336a1a4ddf13244d55e835680cab2533b82df2efe55ec18c1e6cd00" + "7bb089758bb17c2cbe14441bd093ae66e5976d53733f4fa3269701d31d23d467", + NULL + }; + static const char *dsa_pub_hex[] = { + "a012b3b170b307227957b7ca2061a816ac7a2b3d9ae995a5119c385b603bf6f6" + "c5de4dc5ecb5dfa4a41c68662eb25b638b7e2620ba898d07da6c4991e76cc0ec" + "d1ad3421077067e47c18f58a92a72ad43199ecb7bd84e7d3afb9019f0e9dd0fb" + "aa487300b13081e33c902876436f7b03c345528481d362815e24fe59dac5ac34", + "660d4c8a76cb99a7c7de93eb956cd6bc88e58d901034944a094b01803a43c672" + "b9688c0e01d8f4fc91c62a3f88021f7bd6a651b1a88f43aa4ef27653d12bf8b7" + "099fdf6b461082f8e939107bfd2f7210087d326c375200f1f51e7e74a3413190" + "1bcd0863521ff8d676c48581868736c5e51b16a4e39215ea0b17c4735974c516", + NULL + }; + static const char *dsa_priv_hex[] = { + "6ccaeef6d73b4e80f11c17b8e9627c036635bac39423505e407e5cb7", + NULL + }; char msg[] = "Hello World!"; const unsigned char exptd[] = { 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, @@ -186,7 +281,54 @@ static int dummy_evp_call(void *provctx) if (!EC_KEY_generate_key(key)) goto err; #endif + if (!rawnative_fromhex(dsa_p_hex, &dsa_p, &dsa_p_len) + || !rawnative_fromhex(dsa_q_hex, &dsa_q, &dsa_q_len) + || !rawnative_fromhex(dsa_g_hex, &dsa_g, &dsa_g_len) + || !rawnative_fromhex(dsa_pub_hex, &dsa_pub, &dsa_pub_len) + || !rawnative_fromhex(dsa_priv_hex, &dsa_priv, &dsa_priv_len)) + goto err; + + p = params; + *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, dsa_p, dsa_p_len); + *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, dsa_q, dsa_q_len); + *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, dsa_g, dsa_g_len); + *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PUB_KEY, + dsa_pub, dsa_pub_len); + *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PRIV_KEY, + dsa_priv, dsa_priv_len); + *p = OSSL_PARAM_construct_end(); + + kctx = EVP_PKEY_CTX_new_from_name(libctx, SN_dsa, ""); + if (kctx == NULL) + goto err; + if (EVP_PKEY_key_fromdata_init(kctx) <= 0 + || EVP_PKEY_fromdata(kctx, &pkey, params) <= 0) + goto err; + + sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey); + if (sctx == NULL) + goto err;; + if (EVP_PKEY_sign_init(sctx) <= 0) + goto err; + + /* set signature parameters */ + sigdgstlen = SHA256_DIGEST_LENGTH; + p = params; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + SN_sha256, + strlen(SN_sha256) + 1); + + *p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, + &sigdgstlen); + *p = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_set_params(sctx, params) <= 0) + goto err; + + if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0 + || EVP_PKEY_verify_init(sctx) <= 0 + || EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0) + goto err; ret = 1; err: BN_CTX_end(bnctx); @@ -199,6 +341,14 @@ static int dummy_evp_call(void *provctx) #ifndef OPENSSL_NO_EC EC_KEY_free(key); #endif + OPENSSL_free(dsa_p); + OPENSSL_free(dsa_q); + OPENSSL_free(dsa_g); + OPENSSL_free(dsa_pub); + OPENSSL_free(dsa_priv); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(kctx); + EVP_PKEY_CTX_free(sctx); return ret; } @@ -435,6 +585,19 @@ static const OSSL_ALGORITHM fips_kdfs[] = { { NULL, NULL, NULL } }; +static const OSSL_ALGORITHM fips_signature[] = { +#ifndef OPENSSL_NO_DSA + { "DSA:dsaEncryption", "fips=yes", dsa_signature_functions }, +#endif + { NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM fips_keymgmt[] = { +#ifndef OPENSSL_NO_DSA + { "DSA", "fips=yes", dsa_keymgmt_functions }, +#endif + { NULL, NULL, NULL } +}; static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov, int operation_id, @@ -451,6 +614,10 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov, return fips_macs; case OSSL_OP_KDF: return fips_kdfs; + case OSSL_OP_KEYMGMT: + return fips_keymgmt; + case OSSL_OP_SIGNATURE: + return fips_signature; } return NULL; } @@ -574,19 +741,18 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, return 0; } - *out = fips_dispatch_table; - *provctx = ctx; - /* * TODO(3.0): Remove me. This is just a dummy call to demonstrate making * EVP calls from within the FIPS module. */ - if (!dummy_evp_call(*provctx)) { - OPENSSL_CTX_free(*provctx); - *provctx = NULL; + if (!dummy_evp_call(ctx)) { + OPENSSL_CTX_free(ctx); return 0; } + *out = fips_dispatch_table; + *provctx = ctx; + return 1; } diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index ca4354af59..c3ab48b4eb 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -10,11 +10,12 @@ #include <openssl/core_numbers.h> #include <openssl/core_names.h> #include <openssl/bn.h> -#include <openssl/dsa.h> #include <openssl/params.h> #include "internal/param_build.h" #include "prov/implementations.h" #include "prov/providercommon.h" +#include "prov/provider_ctx.h" +#include "crypto/dsa.h" static OSSL_OP_keymgmt_importdomparams_fn dsa_importdomparams; static OSSL_OP_keymgmt_exportdomparams_fn dsa_exportdomparams; @@ -134,8 +135,9 @@ static int key_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl) static void *dsa_importdomparams(void *provctx, const OSSL_PARAM params[]) { DSA *dsa; + OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); - if ((dsa = DSA_new()) == NULL + if ((dsa = dsa_new(libctx)) == NULL || !params_to_domparams(dsa, params)) { DSA_free(dsa); dsa = NULL; @@ -164,8 +166,9 @@ static int dsa_exportdomparams(void *domparams, static void *dsa_importkey(void *provctx, const OSSL_PARAM params[]) { DSA *dsa; + OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); - if ((dsa = DSA_new()) == NULL + if ((dsa = dsa_new(libctx)) == NULL || !params_to_key(dsa, params)) { DSA_free(dsa); dsa = NULL; diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index 1eef3c9165..c656a45fd7 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -15,6 +15,7 @@ #include <openssl/evp.h> #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "crypto/dsa.h" static OSSL_OP_signature_newctx_fn dsa_newctx; static OSSL_OP_signature_sign_init_fn dsa_signature_init; @@ -95,8 +96,8 @@ static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize) return 0; - ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa); - + ret = dsa_sign_int(pdsactx->libctx, 0, tbs, tbslen, sig, &sltmp, + pdsactx->dsa); if (ret <= 0) return 0; |