diff --git a/src/ssl.c b/src/ssl.c index 56c58cb04..c98978e0b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -45705,274 +45705,7 @@ end: } #endif /* !NO_BIO */ -#ifndef NO_FILESYSTEM -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) -/* Convert DH key parameters to DER format, write to output (outSz) - * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is - * returned. - * - * Note : static function due to redefinition complications with DhKey and FIPS - * version 2 build. - * - * return bytes written on success */ -int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz) -{ - word32 sz = 0, idx = 0; - int pSz = 0, gSz = 0, ret; - byte scratch[MAX_LENGTH_SZ]; - - if (key == NULL || outSz == NULL) { - return BAD_FUNC_ARG; - } - - pSz = mp_unsigned_bin_size(&key->p); - if (pSz < 0) { - return pSz; - } - if (mp_leading_bit(&key->p)) { - pSz++; - } - - gSz = mp_unsigned_bin_size(&key->g); - if (gSz < 0) { - return gSz; - } - if (mp_leading_bit(&key->g)) { - gSz++; - } - - sz = ASN_TAG_SZ; /* Integer */ - sz += SetLength(pSz, scratch); - sz += ASN_TAG_SZ; /* Integer */ - sz += SetLength(gSz, scratch); - sz += gSz + pSz; - - if (out == NULL) { - byte seqScratch[MAX_SEQ_SZ]; - - *outSz = sz + SetSequence(sz, seqScratch); - return LENGTH_ONLY_E; - } - - if (*outSz < MAX_SEQ_SZ || *outSz < sz) { - return BUFFER_E; - } - - idx += SetSequence(sz, out); - if (*outSz < idx + sz) { - return BUFFER_E; - } - - out[idx++] = ASN_INTEGER; - idx += SetLength(pSz, out + idx); - if (mp_leading_bit(&key->p)) { - out[idx++] = 0x00; - pSz -= 1; /* subtract 1 from size to account for leading 0 */ - } - ret = mp_to_unsigned_bin(&key->p, out + idx); - if (ret != MP_OKAY) { - return BUFFER_E; - } - idx += pSz; - - out[idx++] = ASN_INTEGER; - idx += SetLength(gSz, out + idx); - if (mp_leading_bit(&key->g)) { - out[idx++] = 0x00; - gSz -= 1; /* subtract 1 from size to account for leading 0 */ - } - ret = mp_to_unsigned_bin(&key->g, out + idx); - if (ret != MP_OKAY) { - return BUFFER_E; - } - idx += gSz; - return idx; -} - -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) -int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz) -{ - word32 sz = 0; - word32 paramSz = 0; - int ret; - int pubSz = 0; - int idx = 0; - byte scratch[MAX_ALGO_SZ]; - - /* Get size of entire key */ - - /* SEQUENCE <--| SetAlgoId - * OBJECT IDENTIFIER <--| - * SEQUENCE <-- - * INTEGER | wc_DhParamsToDer - * INTEGER <-- - */ - ret = wc_DhParamsToDer(key, NULL, ¶mSz); - if (ret != LENGTH_ONLY_E) - return ASN_PARSE_E; - sz += paramSz; - sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz); - - /* BIT STRING - * INTEGER - */ - pubSz = mp_unsigned_bin_size(&key->pub); - if (pubSz < 0) - return pubSz; - - if (mp_leading_bit(&key->pub)) - pubSz++; - - sz += ASN_TAG_SZ; /* Integer */ - sz += SetLength(pubSz, scratch); - sz += pubSz; - - sz += SetBitString(pubSz, 0, scratch); - - if (out == NULL) { - /* Uppermost SEQUENCE */ - *outSz = sz + SetSequence(sz, scratch); - return LENGTH_ONLY_E; - } - /* end get size of entire key */ - - /* Check for indexing errors */ - if (*outSz < MAX_SEQ_SZ || *outSz < sz) { - return BUFFER_E; - } - - /* Build Up Entire Key */ - - idx += SetSequence(sz, out); - - idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz); - ret = wc_DhParamsToDer(key, out+idx, ¶mSz); - if (ret < 0) - return ret; - idx += ret; - - /* BIT STRING - * INTEGER - */ - idx += SetBitString(pubSz, 0, out+idx); - - out[idx++] = ASN_INTEGER; - idx += SetLength(pubSz, out + idx); - if (mp_leading_bit(&key->pub)) { - out[idx++] = 0x00; - pubSz -= 1; /* subtract 1 from size to account for leading 0 */ - } - ret = mp_to_unsigned_bin(&key->pub, out + idx); - if (ret != MP_OKAY) { - return BUFFER_E; - } - idx += pubSz; - - return idx; -} - -int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz) -{ - word32 sz = 0; - word32 paramSz = 0; - int ret; - int privSz = 0; - int idx = 0; - byte scratch[MAX_ALGO_SZ]; - - /* Get size of entire key */ - - /* INTEGER 0 */ - sz += ASN_TAG_SZ; /* Integer */ - sz += SetLength(1, scratch); - sz += 1; - - /* SEQUENCE <--| SetAlgoId - * OBJECT IDENTIFIER <--| - * SEQUENCE <-- - * INTEGER | wc_DhParamsToDer - * INTEGER <-- - */ - ret = wc_DhParamsToDer(key, NULL, ¶mSz); - if (ret != LENGTH_ONLY_E) - return ASN_PARSE_E; - sz += paramSz; - sz += SetAlgoID(DHk, scratch, oidKeyType, paramSz); - - /* OCTET STRING - * INTEGER - */ - privSz = mp_unsigned_bin_size(&key->priv); - if (privSz < 0) - return privSz; - else if (privSz > 256) /* Key is larger than 2048 */ - return ASN_VERSION_E; - - if (mp_leading_bit(&key->priv)) - privSz++; - - sz += ASN_TAG_SZ; /* Integer */ - sz += SetLength(privSz, scratch); - sz += privSz; - - sz += SetOctetString(privSz + ASN_OCTET_STRING, scratch); - - if (out == NULL) { - /* Uppermost SEQUENCE */ - *outSz = sz + SetSequence(sz, scratch); - return LENGTH_ONLY_E; - } - /* end get size of entire key */ - - /* Check for indexing errors */ - if (*outSz < MAX_SEQ_SZ || *outSz < sz) { - return BUFFER_E; - } - - /* Build Up Entire Key */ - - idx += SetSequence(sz, out); - - /* INTEGER 0 */ - out[idx++] = ASN_INTEGER; - idx += SetLength(1, out+idx); - out[idx++] = 0; - - idx += SetAlgoID(DHk, out+idx, oidKeyType, paramSz); - ret = wc_DhParamsToDer(key, out+idx, ¶mSz); - if (ret < 0) - return ret; - idx += ret; - - /* OCTET STRING - * INTEGER - */ - if (privSz == 256) { - idx += SetOctetString(privSz + ASN_OCTET_STRING, out+idx); - } else if (privSz == 128) { - idx += SetOctetString(privSz + ASN_OCTET_STRING-1, out+idx); - } else if (privSz == 64) { - idx += SetOctetString(privSz + ASN_OCTET_STRING-2, out+idx); - } else { - WOLFSSL_MSG("Unsupported key size"); - return ASN_VERSION_E; - } - - out[idx++] = ASN_INTEGER; - idx += SetLength(privSz, out + idx); - if (mp_leading_bit(&key->priv)) { - out[idx++] = 0x00; - privSz -= 1; /* subtract 1 from size to account for leading 0 */ - } - ret = mp_to_unsigned_bin(&key->priv, out + idx); - if (ret != MP_OKAY) { - return BUFFER_E; - } - idx += privSz; - - return idx; -} - +#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) /* Writes the DH parameters in PEM format from "dh" out to the file pointer * passed in. * @@ -46055,9 +45788,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh) WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", WOLFSSL_SUCCESS); return WOLFSSL_SUCCESS; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* WOLFSSL_QT || OPENSSL_ALL */ -#endif /* !NO_FILESYSTEM */ +#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */ #endif /* !NO_DH */ #ifndef NO_BIO diff --git a/tests/api.c b/tests/api.c index 0ad8e9b11..9a563cc83 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27717,7 +27717,8 @@ static void test_wolfSSL_tmp_dh(void) int bytes; DSA* dsa; DH* dh; -#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) +#if defined(WOLFSSL_DH_EXTRA) && \ + (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) DH* dh2; #endif BIO* bio; @@ -27748,7 +27749,8 @@ static void test_wolfSSL_tmp_dh(void) dh = wolfSSL_DSA_dup_DH(dsa); AssertNotNull(dh); -#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) +#if defined(WOLFSSL_DH_EXTRA) && \ + (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) AssertNotNull(dh2 = wolfSSL_DH_dup(dh)); #endif @@ -27762,7 +27764,8 @@ static void test_wolfSSL_tmp_dh(void) BIO_free(bio); DSA_free(dsa); DH_free(dh); -#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) +#if defined(WOLFSSL_DH_EXTRA) && \ + (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) DH_free(dh2); #endif SSL_free(ssl); @@ -34493,10 +34496,8 @@ static void test_wolfSSL_DH_1536_prime(void) static void test_wolfSSL_PEM_write_DHparams(void) { -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) -#if defined(OPENSSL_EXTRA) && !defined(NO_DH) && !defined(NO_FILESYSTEM) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) -#ifndef NO_BIO +#if defined(OPENSSL_EXTRA) && !defined(NO_BIO) && \ + !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) DH* dh; BIO* bio; XFILE fp; @@ -34536,9 +34537,6 @@ tgZl96bcAGdru8OpQYP7x/rI4h5+rwA/kwIBAg==\n\ XFCLOSE(fp); printf(resultFmt, passed); -#endif /* !NO_BIO */ -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* OPENSSL_ALL || OPENSSL_QT */ #endif } @@ -36247,8 +36245,9 @@ static void test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY (void) static void test_wolfSSL_EVP_PKEY_set1_get1_DH (void) { -#if !defined(NO_DH) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) DH *dh = NULL; DH *setDh = NULL; EVP_PKEY *pkey = NULL; @@ -36291,8 +36290,9 @@ static void test_wolfSSL_EVP_PKEY_set1_get1_DH (void) DH_free(setDh); DH_free(dh); printf(resultFmt, passed); +#endif /* !NO_DH && WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */ #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* NO_DH */ +#endif /* OPENSSL_ALL || WOLFSSL_QT || WOLFSSL_OPENSSH */ } /* END test_EVP_PKEY_set1_get1_DH */ static void test_wolfSSL_CTX_ctrl(void) @@ -37366,9 +37366,8 @@ static void test_wolfSSL_QT_EVP_PKEY_CTX_free(void) static void test_wolfSSL_EVP_PKEY_param_check(void) { #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) -#if !defined(NO_DH) && !defined(NO_FILESYSTEM) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) \ - && (HAVE_FIPS_VERSION>2)) +#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) + DH *dh = NULL; DH *setDh = NULL; EVP_PKEY *pkey = NULL; @@ -37415,7 +37414,6 @@ static void test_wolfSSL_EVP_PKEY_param_check(void) printf(resultFmt, passed); #endif #endif -#endif } static void test_wolfSSL_EVP_BytesToKey(void) { @@ -38408,16 +38406,18 @@ static void test_wolfSSL_OCSP_resp_get0(void) static void test_wolfSSL_EVP_PKEY_derive(void) { -#if defined(OPENSSL_ALL) && !defined(NO_DH) - printf(testingFmt, "wolfSSL_EVP_PKEY_derive()"); +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC) + + printf(testingFmt, "wolfSSL_EVP_PKEY_derive()"); EVP_PKEY_CTX *ctx; unsigned char *skey; size_t skeylen; EVP_PKEY *pkey, *peerkey; const unsigned char* key; -#ifndef NO_DH +#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) /* DH */ key = dh_key_der_2048; AssertNotNull((pkey = d2i_PrivateKey(EVP_PKEY_DH, NULL, &key, @@ -38460,9 +38460,11 @@ static void test_wolfSSL_EVP_PKEY_derive(void) EVP_PKEY_free(pkey); XFREE(skey, NULL, DYNAMIC_TYPE_OPENSSL); #endif /* HAVE_ECC */ -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ + printf(resultFmt, "passed"); -#endif /* OPENSSL_ALL */ +#endif /* (!NO_DH && WOLFSSL_DH_EXTRA) || HAVE_ECC */ +#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* OPENSSL_ALL || WOLFSSL_QT || WOLFSSL_OPENSSH */ } #ifndef NO_RSA diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 00dfbb702..880d1fb8a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -684,6 +684,7 @@ int SetASNInt(int len, byte firstByte, byte* output) #if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \ !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \ + (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \ defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int. * The number is assumed to be positive. @@ -4790,6 +4791,183 @@ int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz) return ret; } +#ifdef WOLFSSL_DH_EXTRA + +/* Export DH Key (private or public) */ +int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv) +{ + int privSz = 0, pubSz = 0, keySz; + word32 idx, total; + + if (key == NULL || outSz == NULL) { + return BAD_FUNC_ARG; + } + + /* determine size */ + if (exportPriv) { + /* octect string: priv */ + privSz = SetASNIntMP(&key->priv, -1, NULL); + idx = 1 + SetLength(privSz, NULL) + privSz; /* +1 for ASN_OCTET_STRING */ + } + else { + /* bit string: public */ + pubSz = SetASNIntMP(&key->pub, -1, NULL); + idx = 1 + SetLength(pubSz, NULL) + pubSz; /* +1 for ASN_BIT_STRING */ + } + keySz = idx; + /* integer - g */ + idx += SetASNIntMP(&key->g, -1, NULL); + /* integer - p */ + idx += SetASNIntMP(&key->p, -1, NULL); + /* sequence */ + idx += SetSequence(idx, NULL); + /* object dhKeyAgreement 1.2.840.113549.1.3.1 */ + idx += SetObjectId(sizeof(keyDhOid), NULL); + idx += sizeof(keyDhOid); + /* sequence */ + idx += SetSequence(idx, NULL); + /* version: 0 (ASN_INTEGER, 0x01, 0x00) */ + idx += 3; + /* sequence */ + total = idx + SetSequence(idx, NULL); + + /* if no output, then just getting size */ + if (output == NULL) { + *outSz = total; + return LENGTH_ONLY_E; + } + + /* make sure output fits in buffer */ + if (total > *outSz) { + return BUFFER_E; + } + total = idx; + + /* sequence */ + idx = SetSequence(total, output); + /* version: 0 */ + idx += SetMyVersion(0, output + idx, 0); + /* sequence - all but pub/priv */ + idx += SetSequence(total - keySz - idx, output + idx); + /* object dhKeyAgreement 1.2.840.113549.1.3.1 */ + idx += SetObjectId(sizeof(keyDhOid), output + idx); + XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid)); + idx += sizeof(keyDhOid); + /* sequence */ + idx += SetSequence(total - keySz - idx, output + idx); + /* integer - p */ + idx += SetASNIntMP(&key->p, -1, output + idx); + /* integer - g */ + idx += SetASNIntMP(&key->g, -1, output + idx); + /* octect string: priv */ + if (exportPriv) { + idx += SetOctetString(privSz, output + idx); + idx += SetASNIntMP(&key->priv, -1, output + idx); + } + else { + /* bit string: public */ + idx += SetBitString(pubSz, 0, output + idx); + idx += SetASNIntMP(&key->pub, -1, output + idx); + } + *outSz = idx; + + return idx; +} + +int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz) +{ + return wc_DhKeyToDer(key, out, outSz, 0); +} +int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz) +{ + return wc_DhKeyToDer(key, out, outSz, 1); +} + + +/* Convert DH key parameters to DER format, write to output (outSz) + * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is + * returned. + * + * Note : static function due to redefinition complications with DhKey and FIPS + * version 2 build. + * + * return bytes written on success */ +int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz) +{ + word32 sz = 0, idx = 0; + int pSz = 0, gSz = 0, ret; + byte scratch[MAX_LENGTH_SZ]; + + if (key == NULL || outSz == NULL) { + return BAD_FUNC_ARG; + } + + pSz = mp_unsigned_bin_size(&key->p); + if (pSz < 0) { + return pSz; + } + if (mp_leading_bit(&key->p)) { + pSz++; + } + + gSz = mp_unsigned_bin_size(&key->g); + if (gSz < 0) { + return gSz; + } + if (mp_leading_bit(&key->g)) { + gSz++; + } + + sz = ASN_TAG_SZ; /* Integer */ + sz += SetLength(pSz, scratch); + sz += ASN_TAG_SZ; /* Integer */ + sz += SetLength(gSz, scratch); + sz += gSz + pSz; + + if (out == NULL) { + byte seqScratch[MAX_SEQ_SZ]; + + *outSz = sz + SetSequence(sz, seqScratch); + return LENGTH_ONLY_E; + } + + if (*outSz < MAX_SEQ_SZ || *outSz < sz) { + return BUFFER_E; + } + + idx += SetSequence(sz, out); + if (*outSz < idx + sz) { + return BUFFER_E; + } + + out[idx++] = ASN_INTEGER; + idx += SetLength(pSz, out + idx); + if (mp_leading_bit(&key->p)) { + out[idx++] = 0x00; + pSz -= 1; /* subtract 1 from size to account for leading 0 */ + } + ret = mp_to_unsigned_bin(&key->p, out + idx); + if (ret != MP_OKAY) { + return BUFFER_E; + } + idx += pSz; + + out[idx++] = ASN_INTEGER; + idx += SetLength(gSz, out + idx); + if (mp_leading_bit(&key->g)) { + out[idx++] = 0x00; + gSz -= 1; /* subtract 1 from size to account for leading 0 */ + } + ret = mp_to_unsigned_bin(&key->g, out + idx); + if (ret != MP_OKAY) { + return BUFFER_E; + } + idx += gSz; + return idx; +} + +#endif /* WOLFSSL_DH_EXTRA */ + int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, byte* g, word32* gInOutSz) { diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 1a878a16a..76e5a8df6 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1509,8 +1509,8 @@ int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx, } #endif /* NO_WOLFSSL_STUB */ -#if !defined(NO_DH) && defined(HAVE_ECC) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION!=2)) +#if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC) +#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int len; @@ -1619,7 +1619,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ return WOLFSSL_SUCCESS; } #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* !NO_DH || HAVE_ECC */ +#endif /* (!NO_DH && WOLFSSL_DH_EXTRA) || HAVE_ECC */ /* Uses the WOLFSSL_EVP_PKEY_CTX to decrypt a buffer. * @@ -2206,16 +2206,13 @@ int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx) int ret; WOLFSSL_DH* dh_key = NULL; - (void)dh_key; - /* sanity check */ if (ctx == NULL) { return WOLFSSL_FAILURE; } type = wolfSSL_EVP_PKEY_type(wolfSSL_EVP_PKEY_base_id(ctx->pkey)); - - switch(type) { + switch (type) { #if !defined(NO_RSA) case EVP_PKEY_RSA: WOLFSSL_MSG("EVP_PKEY_RSA not yet implemented"); @@ -2231,10 +2228,8 @@ int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx) WOLFSSL_MSG("EVP_PKEY_DSA not yet implemented"); return WOLFSSL_FAILURE; #endif - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - #if !defined(NO_DH) && !defined(NO_FILESYSTEM) - #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) \ - && (HAVE_FIPS_VERSION>2)) + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH) + #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) case EVP_PKEY_DH: dh_key = wolfSSL_EVP_PKEY_get1_DH(ctx->pkey); if (dh_key != NULL) { @@ -2246,13 +2241,15 @@ int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx) return ret; #endif #endif - #endif default: WOLFSSL_MSG("Unknown PKEY type"); - return WOLFSSL_FAILURE; + break; } + (void)ret; (void)DH_param_check; + (void)dh_key; + return WOLFSSL_FAILURE; } /* Initialize structure for signing @@ -6334,9 +6331,8 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) } #endif /* HAVE_ECC */ -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) -#if !defined(NO_DH) && !defined(NO_FILESYSTEM) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH) +#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM) /* with set1 functions the pkey struct does not own the DH structure * Build the following DH Key format from the passed in WOLFSSL_DH * then store in WOLFSSL_EVP_PKEY in DER format. @@ -6415,7 +6411,6 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key) return WOLFSSL_SUCCESS; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ WOLFSSL_DH* wolfSSL_EVP_PKEY_get0_DH(WOLFSSL_EVP_PKEY* key) { @@ -6425,7 +6420,6 @@ WOLFSSL_DH* wolfSSL_EVP_PKEY_get0_DH(WOLFSSL_EVP_PKEY* key) return key->dh; } -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) WOLFSSL_DH* wolfSSL_EVP_PKEY_get1_DH(WOLFSSL_EVP_PKEY* key) { WOLFSSL_DH* local = NULL; @@ -6459,8 +6453,7 @@ WOLFSSL_DH* wolfSSL_EVP_PKEY_get1_DH(WOLFSSL_EVP_PKEY* key) return local; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* NO_DH && NO_FILESYSTEM */ +#endif /* NO_DH && WOLFSSL_DH_EXTRA && NO_FILESYSTEM */ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index efa3c430f..8036ece17 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -16271,10 +16271,15 @@ static int dh_test_check_pubvalue(void) #if defined(HAVE_FFDHE) -#ifdef HAVE_FFDHE_3072 - #define FFDHE_KEY_SIZE (3072/8) +#if defined(HAVE_FFDHE_4096) + #define MAX_DH_PRIV_SZ 39 + #define MAX_DH_KEY_SZ 512 +#elif defined(HAVE_FFDHE_3072) + #define MAX_DH_PRIV_SZ 34 + #define MAX_DH_KEY_SZ 384 #else - #define FFDHE_KEY_SIZE (2048/8) + #define MAX_DH_PRIV_SZ 29 + #define MAX_DH_KEY_SZ 256 #endif #ifndef WC_NO_RNG @@ -16283,26 +16288,26 @@ static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params) int ret; word32 privSz, pubSz, privSz2, pubSz2; #ifdef WOLFSSL_SMALL_STACK - byte *priv = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - byte *pub = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - byte *priv2 = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - byte *pub2 = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - byte *agree = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - byte *agree2 = (byte *)XMALLOC(FFDHE_KEY_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - DhKey *key = (DhKey *)XMALLOC(sizeof *key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - DhKey *key2 = (DhKey *)XMALLOC(sizeof *key2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *priv = (byte*)XMALLOC(MAX_DH_PRIV_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *pub = (byte*)XMALLOC(MAX_DH_KEY_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *priv2 = (byte*)XMALLOC(MAX_DH_PRIV_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *pub2 = (byte*)XMALLOC(MAX_DH_KEY_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *agree = (byte*)XMALLOC(MAX_DH_KEY_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + byte *agree2 = (byte*)XMALLOC(MAX_DH_KEY_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + DhKey *key = (DhKey*)XMALLOC(sizeof(*key), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + DhKey *key2 = (DhKey*)XMALLOC(sizeof(*key2), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #else - byte priv[FFDHE_KEY_SIZE]; - byte pub[FFDHE_KEY_SIZE]; - byte priv2[FFDHE_KEY_SIZE]; - byte pub2[FFDHE_KEY_SIZE]; - byte agree[FFDHE_KEY_SIZE]; - byte agree2[FFDHE_KEY_SIZE]; + byte priv[MAX_DH_PRIV_SZ]; + byte pub[MAX_DH_KEY_SZ]; + byte priv2[MAX_DH_PRIV_SZ]; + byte pub2[MAX_DH_KEY_SZ]; + byte agree[MAX_DH_KEY_SZ]; + byte agree2[MAX_DH_KEY_SZ]; DhKey key[1]; DhKey key2[1]; #endif - word32 agreeSz = FFDHE_KEY_SIZE; - word32 agreeSz2 = FFDHE_KEY_SIZE; + word32 agreeSz = MAX_DH_KEY_SZ; + word32 agreeSz2 = MAX_DH_KEY_SZ; #ifdef WOLFSSL_SMALL_STACK if ((priv == NULL) || @@ -16316,13 +16321,13 @@ static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params) ERROR_OUT(-8050, done); #endif - pubSz = FFDHE_KEY_SIZE; - pubSz2 = FFDHE_KEY_SIZE; - privSz = FFDHE_KEY_SIZE; - privSz2 = FFDHE_KEY_SIZE; + pubSz = MAX_DH_KEY_SZ; + pubSz2 = MAX_DH_KEY_SZ; + privSz = MAX_DH_PRIV_SZ; + privSz2 = MAX_DH_PRIV_SZ; - XMEMSET(key, 0, sizeof *key); - XMEMSET(key2, 0, sizeof *key2); + XMEMSET(key, 0, sizeof(*key)); + XMEMSET(key2, 0, sizeof(*key2)); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) { @@ -16410,17 +16415,17 @@ done: #ifdef WOLFSSL_SMALL_STACK if (priv) - XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pub) - XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (priv2) - XFREE(priv2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(priv2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pub2) - XFREE(pub2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(pub2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (agree) - XFREE(agree, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(agree, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (agree2) - XFREE(agree2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(agree2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key) { wc_FreeDhKey(key); XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -16654,17 +16659,41 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void) #if !defined(NO_ASN) && !defined(NO_FILESYSTEM) { + #ifdef WOLFSSL_SMALL_STACK + byte *tmp2; + #else + byte tmp2[DH_TEST_TMP_SIZE]; + #endif XFILE file = XFOPEN(dhKeyFile, "rb"); if (!file) ERROR_OUT(-8121, done); bytes = (word32)XFREAD(tmp, 1, DH_TEST_TMP_SIZE, file); XFCLOSE(file); - } - idx = 0; - ret = wc_DhKeyDecode(tmp, &idx, key, bytes); - if (ret != 0) { - ERROR_OUT(-8122, done); + #ifdef WOLFSSL_SMALL_STACK + tmp2 = (byte*)XMALLOC(DH_TEST_TMP_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp2 == NULL) + ERROR_OUT(-8122, done); + #endif + idx = 0; + XMEMSET(tmp2, 0, DH_TEST_TMP_SIZE); + + /* Import DH key as DER */ + ret = wc_DhKeyDecode(tmp, &idx, key, bytes); + if (ret == 0) { + /* Export as DER */ + idx = DH_TEST_TMP_SIZE; + ret = wc_DhPrivKeyToDer(key, tmp2, &idx); + } + + /* Verify export matches original */ + if (ret <= 0 || bytes != idx || XMEMCMP(tmp, tmp2, bytes) != 0) { + ERROR_OUT(-8123, done); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(tmp2, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + #endif } #else ret = wc_DhSetKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); @@ -16703,7 +16732,7 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void) #endif #ifndef WC_NO_RNG - /* Specialized code for key gen when using FFDHE-2048 and FFDHE-3072. */ + /* Specialized code for key gen when using FFDHE-2048, FFDHE-3072 and FFDHE-4096 */ #ifdef HAVE_FFDHE_2048 ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe2048_Get()); if (ret != 0) @@ -16714,6 +16743,11 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void) if (ret != 0) ERROR_OUT(-8130, done); #endif + #ifdef HAVE_FFDHE_4096 + ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe4096_Get()); + if (ret != 0) + ERROR_OUT(-8131, done); + #endif #endif /* !WC_NO_RNG */ wc_FreeDhKey(key); @@ -16725,7 +16759,7 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void) ret = wc_DhSetCheckKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g), NULL, 0, 0, &rng); if (ret != 0) - ERROR_OUT(-8131, done); + ERROR_OUT(-8132, done); keyInit = 1; /* DhSetCheckKey also initializes the key, free it */ #endif diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index a2b1d651d..660155302 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1157,11 +1157,13 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define DTLS1_2_VERSION 0xFEFD #define DTLS_MAX_VERSION DTLS1_2_VERSION +#ifndef WOLFSSL_APACHE_HTTPD /* apache uses SSL_CONF_FLAG_FILE to enable conf support */ #define SSL_CONF_FLAG_CMDLINE WOLFSSL_CONF_FLAG_CMDLINE #define SSL_CONF_FLAG_FILE WOLFSSL_CONF_FLAG_FILE #define SSL_CONF_FLAG_CERTIFICATE WOLFSSL_CONF_FLAG_CERTIFICATE #define SSL_CONF_TYPE_STRING WOLFSSL_CONF_TYPE_STRING #define SSL_CONF_TYPE_FILE WOLFSSL_CONF_TYPE_FILE +#endif #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(OPENSSL_EXTRA) \ || defined(OPENSSL_ALL) diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index f84c4e74e..3457b435a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1233,12 +1233,6 @@ WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag, WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); -#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_DH) \ - || defined(WOLFSSL_OPENSSH) -WOLFSSL_LOCAL int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz); -WOLFSSL_LOCAL int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz); -WOLFSSL_LOCAL int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); -#endif WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 289f3620e..4c4479b44 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -59,6 +59,10 @@ This library defines the interface APIs for X509 certificates. typedef struct WC_RNG WC_RNG; #define WC_RNG_TYPE_DEFINED #endif +#ifndef WC_DH_TYPE_DEFINED + typedef struct DhKey DhKey; + #define WC_DH_TYPE_DEFINED +#endif enum Ecc_Sum { ECC_SECP112R1_OID = 182, @@ -517,6 +521,13 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); WOLFSSL_API int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen); #endif +#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) +WOLFSSL_LOCAL int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv); +WOLFSSL_API int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz); +WOLFSSL_API int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz); +WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); +#endif + #ifdef HAVE_ECC /* private key helpers */ WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*, diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 4c5ea8abd..64650403a 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -46,13 +46,6 @@ #include #endif -/* Optional support extended DH public / private keys */ -#if !defined(WOLFSSL_DH_EXTRA) && (defined(WOLFSSL_QT) || \ - defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \ - defined(WOLFSSL_STATIC_EPHEMERAL)) - #define WOLFSSL_DH_EXTRA -#endif - typedef struct DhParams { #ifdef HAVE_FFDHE_Q const byte* q; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 116d4b07e..e1a92d0aa 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2450,6 +2450,20 @@ extern void uITRON4_free(void *p) ; #error Small stack cannot be used with no malloc (WOLFSSL_NO_MALLOC) #endif +/* Enable DH Extra for QT, openssl all, openssh and static ephemeral */ +/* Allows export/import of DH key and params as DER */ +#if !defined(WOLFSSL_DH_EXTRA) && \ + (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \ + defined(WOLFSSL_STATIC_EPHEMERAL)) + #define WOLFSSL_DH_EXTRA +#endif + +/* DH Extra is not supported on FIPS v1 or v2 (is missing DhKey .pub/.priv) */ +#if defined(WOLFSSL_DH_EXTRA) && defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || HAVE_FIPS_VERSION <= 2) + #undef WOLFSSL_DH_EXTRA +#endif + #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index fd75cd3b2..09724c474 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -889,8 +889,9 @@ decouple library dependencies with standard string, memory and so on. WC_PK_TYPE_EC_KEYGEN = 9, WC_PK_TYPE_RSA_CHECK_PRIV_KEY = 10, WC_PK_TYPE_EC_CHECK_PRIV_KEY = 11, - - WC_PK_TYPE_MAX = WC_PK_TYPE_EC_CHECK_PRIV_KEY + WC_PK_TYPE_ED448 = 12, + WC_PK_TYPE_CURVE448 = 13, + WC_PK_TYPE_MAX = WC_PK_TYPE_CURVE448 };