From 0ef743558060d0b74127fbc9c2b7ce6e0097cca6 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Thu, 17 Feb 2022 08:30:44 -0800 Subject: [PATCH] Make changes to compatibility layer to support libspdm. - Add support for ASN1_TIME_compare, DH_new_by_nid, OBJ_length, OBJ_get0_data, and ChaCha20-Poly1305 and HKDF in the EVP layer. - Map EC_POINT_get_affine_coordinates to wolfSSL_EC_POINT_get_affine_coordinates_GFp and EC_POINT_set_affine_coordinates to wolfSSL_EC_POINT_set_affine_coordinates_GFp. - Add kdf.h compatibility header. --- src/ssl.c | 253 ++++++++++++++++++++- tests/api.c | 248 ++++++++++++++++++++- wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/evp.c | 417 ++++++++++++++++++++++++++++++++--- wolfssl/openssl/asn1.h | 1 + wolfssl/openssl/dh.h | 11 +- wolfssl/openssl/ec.h | 4 + wolfssl/openssl/evp.h | 124 +++++++---- wolfssl/openssl/include.am | 1 + wolfssl/openssl/kdf.h | 37 ++++ wolfssl/openssl/objects.h | 30 +-- wolfssl/ssl.h | 15 ++ wolfssl/wolfcrypt/hmac.h | 2 +- wolfssl/wolfcrypt/settings.h | 2 +- 14 files changed, 1045 insertions(+), 104 deletions(-) create mode 100644 wolfssl/openssl/kdf.h diff --git a/src/ssl.c b/src/ssl.c index ded081f10..5c4578527 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24443,6 +24443,43 @@ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, return WOLFSSL_SUCCESS; } + +int wolfSSL_ASN1_TIME_compare(const WOLFSSL_ASN1_TIME *a, + const WOLFSSL_ASN1_TIME *b) +{ + int ret; + int days; + int secs; + + WOLFSSL_ENTER("wolfSSL_ASN1_TIME_compare"); + + if (wolfSSL_ASN1_TIME_diff(&days, &secs, a, b) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to get time difference."); + ret = -2; + } + else { + if (days == 0 && secs == 0) { + /* a and b are the same time. */ + ret = 0; + } + else if (days >= 0 && secs >= 0) { + /* a is before b. */ + ret = -1; + } + else if (days <= 0 && secs <= 0) { + /* a is after b. */ + ret = 1; + } + else { + WOLFSSL_MSG("Incoherent time difference."); + ret = -2; + } + } + + WOLFSSL_LEAVE("wolfSSL_ASN1_TIME_compare", ret); + + return ret; +} #endif /* !NO_ASN_TIME */ #ifndef NO_WOLFSSL_STUB @@ -26276,6 +26313,152 @@ WOLFSSL_DH* wolfSSL_DH_new(void) return external; } +WOLFSSL_DH* wolSSL_DH_new_by_nid(int nid) +{ + WOLFSSL_DH* dh; + int err = 0; +#if defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && FIPS_VERSION_EQ(2,0)) + const DhParams* params = NULL; + WOLFSSL_BIGNUM* pBn = NULL; + WOLFSSL_BIGNUM* gBn = NULL; + WOLFSSL_BIGNUM* qBn = NULL; +#elif !defined(HAVE_PUBLIC_FFDHE) && (!defined(HAVE_FIPS) || \ + FIPS_VERSION_GT(2,0)) + int name = 0; +#ifdef HAVE_FFDHE_Q + int elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q; +#else + int elements = ELEMENT_P | ELEMENT_G; +#endif /* HAVE_FFDHE_Q */ +#endif /* HAVE_PUBLIC_FFDHE || (HAVE_FIPS && HAVE_FIPS_VERSION == 2) */ + + WOLFSSL_ENTER("wolfSSL_DH_new_by_nid"); + + dh = wolfSSL_DH_new(); + if (dh == NULL) { + WOLFSSL_MSG("Failed to create WOLFSSL_DH."); + err = 1; + } + +/* HAVE_PUBLIC_FFDHE not required to expose wc_Dh_ffdhe* functions in FIPS v2 + * module */ +#if defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && FIPS_VERSION_EQ(2,0)) + if (err == 0) { + switch (nid) { +#ifdef HAVE_FFDHE_2048 + case NID_ffdhe2048: + params = wc_Dh_ffdhe2048_Get(); + break; +#endif /* HAVE_FFDHE_2048 */ +#ifdef HAVE_FFDHE_3072 + case NID_ffdhe3072: + params = wc_Dh_ffdhe3072_Get(); + break; +#endif /* HAVE_FFDHE_3072 */ +#ifdef HAVE_FFDHE_4096 + case NID_ffdhe4096: + params = wc_Dh_ffdhe4096_Get(); + break; +#endif /* HAVE_FFDHE_4096 */ + default: + break; + } + } + if (err == 0 && params == NULL) { + WOLFSSL_MSG("Unable to find DH params for nid."); + err = 1; + } + if (err == 0) { + pBn = wolfSSL_BN_bin2bn(params->p, params->p_len, NULL); + if (pBn == NULL) { + WOLFSSL_MSG("Error converting p hex to WOLFSSL_BIGNUM."); + err = 1; + } + } + if (err == 0) { + gBn = wolfSSL_BN_bin2bn(params->g, params->g_len, NULL); + if (gBn == NULL) { + WOLFSSL_MSG("Error converting g hex to WOLFSSL_BIGNUM."); + err = 1; + } + } +#ifdef HAVE_FFDHE_Q + if (err == 0) { + qBn = wolfSSL_BN_bin2bn(params->q, params->q_len, NULL); + if (qBn == NULL) { + WOLFSSL_MSG("Error converting q hex to WOLFSSL_BIGNUM."); + err = 1; + } + } +#endif +#if defined(OPENSSL_ALL) || defined(OPENSSL_VERSION_NUMBER) && \ + OPENSSL_VERSION_NUMBER >= 0x10100000L + if (err == 0 && wolfSSL_DH_set0_pqg(dh, pBn, qBn, gBn) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to set DH params."); + err = 1; + } +#else + dh->p = pBn; + dh->q = qBn; + dh->g = gBn; + if (err == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to set internal DH params."); + err = 1; + } +#endif /* OPENSSL_ALL || OPENSSL_VERSION_NUMBER >= 0x10100000L */ + + if (err == 1) { + wolfSSL_BN_free(pBn); + wolfSSL_BN_free(gBn); + wolfSSL_BN_free(qBn); + } +/* FIPS v2 and lower doesn't support wc_DhSetNamedKey. */ +#elif !defined(HAVE_PUBLIC_FFDHE) && (!defined(HAVE_FIPS) || \ + FIPS_VERSION_GT(2,0)) + if (err == 0) { + switch (nid) { +#ifdef HAVE_FFDHE_2048 + case NID_ffdhe2048: + name = WC_FFDHE_2048; + break; +#endif /* HAVE_FFDHE_2048 */ +#ifdef HAVE_FFDHE_3072 + case NID_ffdhe3072: + name = WC_FFDHE_3072; + break; +#endif /* HAVE_FFDHE_3072 */ +#ifdef HAVE_FFDHE_4096 + case NID_ffdhe4096: + name = WC_FFDHE_4096; + break; +#endif /* HAVE_FFDHE_4096 */ + default: + err = 1; + WOLFSSL_MSG("Unable to find DH params for nid."); + break; + } + } + if (err == 0 && wc_DhSetNamedKey((DhKey*)dh->internal, name) != 0) { + WOLFSSL_MSG("wc_DhSetNamedKey failed."); + err = 1; + } + if (err == 0 && SetDhExternal_ex(dh, elements) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to set external DH params."); + err = 1; + } +#else + /* Unsupported configuration. */ + err = 1; +#endif /* HAVE_PUBLIC_FFDHE || (HAVE_FIPS && HAVE_FIPS_VERSION == 2) */ + + if (err == 1 && dh != NULL) { + wolfSSL_DH_free(dh); + dh = NULL; + } + + return dh; +} + void wolfSSL_DH_free(WOLFSSL_DH* dh) { int doFree = 0; @@ -35044,9 +35227,9 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *EM, goto cleanup; } - hashType = wolfSSL_EVP_md2macType(hashAlg); + hashType = EvpMd2MacType(hashAlg); if (hashType > WC_HASH_TYPE_MAX) { - WOLFSSL_MSG("wolfSSL_EVP_md2macType error"); + WOLFSSL_MSG("EvpMd2MacType error"); goto cleanup; } @@ -35151,9 +35334,9 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash, return WOLFSSL_FAILURE; } - hashType = wolfSSL_EVP_md2macType(hashAlg); + hashType = EvpMd2MacType(hashAlg); if (hashType > WC_HASH_TYPE_MAX) { - WOLFSSL_MSG("wolfSSL_EVP_md2macType error"); + WOLFSSL_MSG("EvpMd2MacType error"); return WOLFSSL_FAILURE; } @@ -37342,6 +37525,58 @@ int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out, } #endif + size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o) + { + size_t ret = 0; + int err = 0; + word32 idx = 0; + int len = 0; + + WOLFSSL_ENTER("wolfSSL_OBJ_length"); + + if (o == NULL || o->obj == NULL) { + WOLFSSL_MSG("Bad argument."); + err = 1; + } + + if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) { + WOLFSSL_MSG("Error parsing ASN.1 header."); + err = 1; + } + if (err == 0) { + ret = len; + } + + WOLFSSL_LEAVE("wolfSSL_OBJ_length", ret); + + return ret; + } + + const unsigned char* wolfSSL_OBJ_get0_data(const WOLFSSL_ASN1_OBJECT* o) + { + const unsigned char* ret = NULL; + int err = 0; + word32 idx = 0; + int len = 0; + + WOLFSSL_ENTER("wolfSSL_OBJ_get0_data"); + + if (o == NULL || o->obj == NULL) { + WOLFSSL_MSG("Bad argument."); + err = 1; + } + + if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) { + WOLFSSL_MSG("Error parsing ASN.1 header."); + err = 1; + } + if (err == 0) { + ret = o->obj + idx; + } + + return ret; + } + /* Gets the NID value that corresponds with the ASN1 object. * @@ -47375,6 +47610,11 @@ int wolfSSL_RAND_poll(void) WOLFSSL_MSG("ARC4"); break; +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case CHACHA20_POLY1305_TYPE: + break; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); break; @@ -47459,6 +47699,11 @@ int wolfSSL_RAND_poll(void) WOLFSSL_MSG("ARC4"); break; +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case CHACHA20_POLY1305_TYPE: + break; +#endif + case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); break; diff --git a/tests/api.c b/tests/api.c index f59f61364..2b1f285f8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -305,6 +305,7 @@ #include #include #include + #include #ifdef OPENSSL_ALL #include #include @@ -30949,7 +30950,7 @@ static void test_wolfSSL_ASN1_UTCTIME_print(void) #endif /* OPENSSL_EXTRA && !NO_ASN_TIME && !NO_BIO */ } -static void test_wolfSSL_ASN1_TIME_diff(void) +static void test_wolfSSL_ASN1_TIME_diff_compare(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) ASN1_TIME* fromTime; @@ -30967,8 +30968,46 @@ static void test_wolfSSL_ASN1_TIME_diff(void) AssertIntEQ(ASN1_TIME_set_string(toTime, "101219181011Z"), WOLFSSL_SUCCESS); AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), WOLFSSL_SUCCESS); + /* Error conditions. */ + AssertIntEQ(ASN1_TIME_diff(NULL, &secsDiff, fromTime, toTime), + WOLFSSL_FAILURE); + AssertIntEQ(ASN1_TIME_diff(&daysDiff, NULL, fromTime, toTime), + WOLFSSL_FAILURE); + + /* If both times are NULL, difference is 0. */ + AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, NULL, NULL), + WOLFSSL_SUCCESS); + AssertIntEQ(daysDiff, 0); + AssertIntEQ(secsDiff, 0); + + /* If one time is NULL, it defaults to the current time. */ + AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, NULL, toTime), + WOLFSSL_SUCCESS); + AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, NULL), + WOLFSSL_SUCCESS); + + /* Normal operation. Both times non-NULL. */ + AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, fromTime, toTime), + WOLFSSL_SUCCESS); AssertIntEQ(daysDiff, 2856); AssertIntEQ(secsDiff, 75296); + /* Swapping the times should return negative values. */ + AssertIntEQ(ASN1_TIME_diff(&daysDiff, &secsDiff, toTime, fromTime), + WOLFSSL_SUCCESS); + AssertIntEQ(daysDiff, -2856); + AssertIntEQ(secsDiff, -75296); + + AssertIntEQ(ASN1_TIME_compare(fromTime, toTime), -1); + AssertIntEQ(ASN1_TIME_compare(toTime, fromTime), 1); + AssertIntEQ(ASN1_TIME_compare(fromTime, fromTime), 0); + + /* Compare regression test: No seconds difference, just difference in days. + */ + ASN1_TIME_set_string(fromTime, "19700101000000Z"); + ASN1_TIME_set_string(toTime, "19800101000000Z"); + AssertIntEQ(ASN1_TIME_compare(fromTime, toTime), -1); + AssertIntEQ(ASN1_TIME_compare(toTime, fromTime), 1); + AssertIntEQ(ASN1_TIME_compare(fromTime, fromTime), 0); /* Edge case with Unix epoch. */ AssertNotNull(ASN1_TIME_set_string(fromTime, "19700101000000Z")); @@ -46112,7 +46151,7 @@ static void test_wolfSSL_OCSP_resp_get0(void) static void test_wolfSSL_EVP_PKEY_derive(void) { #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_OPENSSH) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2, 0) #if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC) EVP_PKEY_CTX *ctx; @@ -49992,6 +50031,188 @@ static void test_wolfssl_EVP_aes_gcm(void) #endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ } +static void test_wolfssl_EVP_chacha20_poly1305(void) +{ +#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; + byte iv [CHACHA20_POLY1305_AEAD_IV_SIZE]; + byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF}; + byte aad[] = {0xAA, 0XBB, 0xCC, 0xDD, 0xEE, 0xFF}; + byte cipherText[sizeof(plainText)]; + byte decryptedText[sizeof(plainText)]; + byte tag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; + EVP_CIPHER_CTX* ctx; + int outSz; + + printf(testingFmt, "test_wolfssl_EVP_chacha20_poly1305"); + + /* Encrypt. */ + AssertNotNull((ctx = EVP_CIPHER_CTX_new())); + AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + /* Invalid IV length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE-1, NULL), WOLFSSL_FAILURE); + /* Valid IV length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS); + /* Invalid tag length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, NULL), WOLFSSL_FAILURE); + /* Valid tag length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, NULL), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText, + sizeof(plainText)), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS); + /* Invalid tag length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE-1, tag), WOLFSSL_FAILURE); + /* Valid tag length. */ + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS); + EVP_CIPHER_CTX_free(ctx); + + /* Decrypt. */ + AssertNotNull((ctx = EVP_CIPHER_CTX_new())); + AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL, + NULL), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + CHACHA20_POLY1305_AEAD_IV_SIZE, NULL), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, tag), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_DecryptUpdate(ctx, NULL, &outSz, aad, sizeof(aad)), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText, + sizeof(cipherText)), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz), + WOLFSSL_SUCCESS); + EVP_CIPHER_CTX_free(ctx); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_EVP_PKEY_hkdf(void) +{ +#if defined(OPENSSL_EXTRA) && defined(HAVE_HKDF) && (!defined(HAVE_FIPS) || \ + FIPS_VERSION_GT(2,0)) + EVP_PKEY_CTX* ctx; + byte salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + byte key[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; + byte info[] = {0X01, 0x02, 0x03, 0x04, 0x05}; + byte info2[] = {0X06, 0x07, 0x08, 0x09, 0x0A}; + byte outKey[34]; + size_t outKeySz = sizeof(outKey); + /* These expected outputs were gathered by running the same test below using + * OpenSSL. */ + const byte extractAndExpand[] = { + 0x8B, 0xEB, 0x90, 0xA9, 0x04, 0xFF, 0x05, 0x10, 0xE4, 0xB5, 0xB1, 0x10, + 0x31, 0x34, 0xFF, 0x07, 0x5B, 0xE3, 0xC6, 0x93, 0xD4, 0xF8, 0xC7, 0xEE, + 0x96, 0xDA, 0x78, 0x7A, 0xE2, 0x9A, 0x2D, 0x05, 0x4B, 0xF6 + }; + const byte extractOnly[] = { + 0xE7, 0x6B, 0x9E, 0x0F, 0xE4, 0x02, 0x1D, 0x62, 0xEA, 0x97, 0x74, 0x5E, + 0xF4, 0x3C, 0x65, 0x4D, 0xC1, 0x46, 0x98, 0xAA, 0x79, 0x9A, 0xCB, 0x9C, + 0xCC, 0x3E, 0x7F, 0x2A, 0x2B, 0x41, 0xA1, 0x9E + }; + const byte expandOnly[] = { + 0xFF, 0x29, 0x29, 0x56, 0x9E, 0xA7, 0x66, 0x02, 0xDB, 0x4F, 0xDB, 0x53, + 0x7D, 0x21, 0x67, 0x52, 0xC3, 0x0E, 0xF3, 0xFC, 0x71, 0xCE, 0x67, 0x2B, + 0xEA, 0x3B, 0xE9, 0xFC, 0xDD, 0xC8, 0xCC, 0xB7, 0x42, 0x74 + }; + const byte extractAndExpandAddInfo[] = { + 0x5A, 0x74, 0x79, 0x83, 0xA3, 0xA4, 0x2E, 0xB7, 0xD4, 0x08, 0xC2, 0x6A, + 0x2F, 0xA5, 0xE3, 0x4E, 0xF1, 0xF4, 0x87, 0x3E, 0xA6, 0xC7, 0x88, 0x45, + 0xD7, 0xE2, 0x15, 0xBC, 0xB8, 0x10, 0xEF, 0x6C, 0x4D, 0x7A + }; + + printf(testingFmt, "test_wolfSSL_EVP_PKEY_hkdf"); + + AssertNotNull((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL))); + AssertIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + /* NULL ctx. */ + AssertIntEQ(EVP_PKEY_CTX_set_hkdf_md(NULL, EVP_sha256()), WOLFSSL_FAILURE); + /* NULL md. */ + AssertIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, NULL), WOLFSSL_FAILURE); + AssertIntEQ(EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()), WOLFSSL_SUCCESS); + /* NULL ctx. */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(NULL, salt, sizeof(salt)), + WOLFSSL_FAILURE); + /* NULL salt is ok. */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, NULL, sizeof(salt)), + WOLFSSL_SUCCESS); + /* Salt length <= 0. */ + /* Length 0 salt is ok. */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, 0), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, -1), WOLFSSL_FAILURE); + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_key(NULL, key, sizeof(key)), + WOLFSSL_FAILURE); + /* NULL key. */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, NULL, sizeof(key)), + WOLFSSL_FAILURE); + /* Key length <= 0 */ + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, 0), WOLFSSL_FAILURE); + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, -1), WOLFSSL_FAILURE); + AssertIntEQ(EVP_PKEY_CTX_set1_hkdf_key(ctx, key, sizeof(key)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(NULL, info, sizeof(info)), + WOLFSSL_FAILURE); + /* NULL info is ok. */ + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, NULL, sizeof(info)), + WOLFSSL_SUCCESS); + /* Info length <= 0 */ + /* Length 0 info is ok. */ + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, 0), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, -1), WOLFSSL_FAILURE); + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info, sizeof(info)), + WOLFSSL_SUCCESS); + /* NULL ctx. */ + AssertIntEQ(EVP_PKEY_CTX_hkdf_mode(NULL, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY), + WOLFSSL_FAILURE); + /* Extract and expand (default). */ + AssertIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + AssertIntEQ(outKeySz, sizeof(extractAndExpand)); + AssertIntEQ(XMEMCMP(outKey, extractAndExpand, outKeySz), 0); + /* Extract only. */ + AssertIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + AssertIntEQ(outKeySz, sizeof(extractOnly)); + AssertIntEQ(XMEMCMP(outKey, extractOnly, outKeySz), 0); + outKeySz = sizeof(outKey); + /* Expand only. */ + AssertIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + AssertIntEQ(outKeySz, sizeof(expandOnly)); + AssertIntEQ(XMEMCMP(outKey, expandOnly, outKeySz), 0); + outKeySz = sizeof(outKey); + /* Extract and expand with appended additional info. */ + AssertIntEQ(EVP_PKEY_CTX_add1_hkdf_info(ctx, info2, sizeof(info2)), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_hkdf_mode(ctx, + EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_derive(ctx, outKey, &outKeySz), WOLFSSL_SUCCESS); + AssertIntEQ(outKeySz, sizeof(extractAndExpandAddInfo)); + AssertIntEQ(XMEMCMP(outKey, extractAndExpandAddInfo, outKeySz), 0); + + EVP_PKEY_CTX_free(ctx); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA && HAVE_HKDF && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2) */ +} + #ifndef NO_BIO static void test_wolfSSL_PEM_X509_INFO_read_bio(void) { @@ -52439,6 +52660,25 @@ static void test_wolfSSL_DH(void) DH_free(dh); /* decrease ref count */ DH_free(dh); /* free WOLFSSL_DH */ +#if (defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && \ + FIPS_VERSION_EQ(2,0))) || (!defined(HAVE_PUBLIC_FFDHE) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))) +#ifdef HAVE_FFDHE_2048 + AssertNotNull((dh = DH_new_by_nid(NID_ffdhe2048))); + DH_free(dh); +#endif +#ifdef HAVE_FFDHE_3072 + AssertNotNull((dh = DH_new_by_nid(NID_ffdhe3072))); + DH_free(dh); +#endif +#ifdef HAVE_FFDHE_4096 + AssertNotNull((dh = DH_new_by_nid(NID_ffdhe4096))); + DH_free(dh); +#endif +#else + AssertNull((dh = DH_new_by_nid(NID_ffdhe2048))); +#endif /* (HAVE_PUBLIC_FFDHE || (HAVE_FIPS && HAVE_FIPS_VERSION == 2)) || + * (!HAVE_PUBLIC_FFDHE && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2))*/ printf(resultFmt, passed); #endif /* OPENSSL_EXTRA && !NO_DH */ } @@ -53549,7 +53789,7 @@ void ApiTest(void) test_wolfSSL_X509_check_private_key(); test_wolfSSL_ASN1_TIME_print(); test_wolfSSL_ASN1_UTCTIME_print(); - test_wolfSSL_ASN1_TIME_diff(); + test_wolfSSL_ASN1_TIME_diff_compare(); test_wolfSSL_ASN1_GENERALIZEDTIME_free(); test_wolfSSL_private_keys(); test_wolfSSL_PEM_read_PrivateKey(); @@ -53756,6 +53996,8 @@ void ApiTest(void) test_wolfSSL_CRYPTO_cts128(); test_wolfssl_EVP_aes_gcm_AAD_2_parts(); test_wolfssl_EVP_aes_gcm(); + test_wolfssl_EVP_chacha20_poly1305(); + test_wolfSSL_EVP_PKEY_hkdf(); test_wolfSSL_PKEY_up_ref(); test_wolfSSL_EVP_Cipher_extra(); test_wolfSSL_d2i_and_i2d_PublicKey(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 314a8bec0..762811956 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2035,7 +2035,7 @@ static int GetASN_BitString_Int16Bit(ASNGetData* dataASN, word16* val) * On out, end of parsed length. * @param [out] len Length value decoded. * @param [in] maxIdx Maximum index of input data. - * @return 0 on success. + * @return Length on success. * @return ASN_PARSE_E if the encoding is invalid. * @return BUFFER_E when not enough data to complete decode. */ @@ -2060,7 +2060,7 @@ int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx) * @param [in] maxIdx Maximum index of input data. * @param [in] check Whether to check the buffer has at least the * decoded length of bytes remaining. - * @return 0 on success. + * @return Length on success. * @return ASN_PARSE_E if the encoding is invalid. * @return BUFFER_E when not enough data to complete decode. */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 11311c701..bb172a886 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -44,6 +44,7 @@ #include #include +#include #include #ifndef NO_AES @@ -161,6 +162,10 @@ static const char EVP_ARC4[] = "ARC4"; #endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + static const char EVP_CHACHA20_POLY1305[] = "CHACHA20-POLY1305"; +#endif + static const char EVP_NULL[] = "NULL"; #define EVP_CIPHER_TYPE_MATCHES(x, y) (XSTRCMP(x,y) == 0) @@ -170,6 +175,7 @@ static const char EVP_NULL[] = "NULL"; static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher); +static enum wc_HashType EvpMd2MacType(const WOLFSSL_EVP_MD *md); /* Getter function for cipher key length * @@ -657,25 +663,48 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, return WOLFSSL_SUCCESS; } - if ((ctx == NULL) || (inl < 0) || (outl == NULL)|| (in == NULL)) { + if ((ctx == NULL) || (inl < 0) || (outl == NULL) || (in == NULL)) { WOLFSSL_MSG("Bad argument"); return WOLFSSL_FAILURE; } *outl = 0; -#if !defined(NO_AES) && defined(HAVE_AESGCM) switch (ctx->cipherType) { +#if !defined(NO_AES) && defined(HAVE_AESGCM) case AES_128_GCM_TYPE: case AES_192_GCM_TYPE: case AES_256_GCM_TYPE: /* if out == NULL, in/inl contains the additional authenticated data * for GCM */ return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl); +#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case CHACHA20_POLY1305_TYPE: + if (out == NULL) { + if (wc_ChaCha20Poly1305_UpdateAad(&ctx->cipher.chachaPoly, in, + inl) != 0) { + WOLFSSL_MSG("wc_ChaCha20Poly1305_UpdateAad failed"); + return WOLFSSL_FAILURE; + } + else { + return WOLFSSL_SUCCESS; + } + } + else { + if (wc_ChaCha20Poly1305_UpdateData(&ctx->cipher.chachaPoly, in, + out, inl) != 0) { + WOLFSSL_MSG("wc_ChaCha20Poly1305_UpdateData failed"); + return WOLFSSL_FAILURE; + } + else { + return WOLFSSL_SUCCESS; + } + } +#endif default: /* fall-through */ break; } -#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */ if (out == NULL) { return WOLFSSL_FAILURE; @@ -861,6 +890,17 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); break; #endif /* !NO_AES && HAVE_AESGCM */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case CHACHA20_POLY1305_TYPE: + if (wc_ChaCha20Poly1305_Final(&ctx->cipher.chachaPoly, + ctx->authTag) != 0) { + WOLFSSL_MSG("wc_ChaCha20Poly1305_Final failed"); + return WOLFSSL_FAILURE; + } + else { + return WOLFSSL_SUCCESS; + } +#endif default: if (!out) return WOLFSSL_FAILURE; @@ -1446,7 +1486,7 @@ int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding) return WOLFSSL_SUCCESS; } -/* create a PKEY contxt and return it */ +/* create a PKEY context and return it */ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e) { WOLFSSL_EVP_PKEY* pkey; @@ -1520,16 +1560,22 @@ int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx, } #endif /* NO_WOLFSSL_STUB */ -#if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || 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) || \ + defined(HAVE_HKDF) +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int len; +#ifdef HAVE_HKDF + enum wc_HashType hkdfHashType; + int hkdfHashSz; +#endif WOLFSSL_ENTER("wolfSSL_EVP_PKEY_derive"); - if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE || !ctx->pkey || !ctx->peerKey || !keylen - || ctx->pkey->type != ctx->peerKey->type) { + if (!ctx || ctx->op != EVP_PKEY_OP_DERIVE || !ctx->pkey || (!ctx->peerKey + && ctx->pkey->type != EVP_PKEY_HKDF) || !keylen || (ctx->pkey->type + != EVP_PKEY_HKDF && ctx->pkey->type != ctx->peerKey->type)) { return WOLFSSL_FAILURE; } switch (ctx->pkey->type) { @@ -1634,6 +1680,56 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ *keylen = (size_t)len; break; #endif +#ifdef HAVE_HKDF + case EVP_PKEY_HKDF: + (void)len; + + hkdfHashType = EvpMd2MacType(ctx->pkey->hkdfMd); + if (hkdfHashType == WC_HASH_TYPE_NONE) { + WOLFSSL_MSG("Invalid hash type for HKDF."); + return WOLFSSL_FAILURE; + } + if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) { + if (wc_HKDF(hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, + ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz, + ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key, + (word32)*keylen) != 0) { + WOLFSSL_MSG("wc_HKDF failed."); + return WOLFSSL_FAILURE; + } + } + else if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) { + if (wc_HKDF_Extract(hkdfHashType, ctx->pkey->hkdfSalt, + ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfKey, + ctx->pkey->hkdfKeySz, key) != 0) { + WOLFSSL_MSG("wc_HKDF_Extract failed."); + return WOLFSSL_FAILURE; + } + else { + hkdfHashSz = wolfSSL_EVP_MD_size(ctx->pkey->hkdfMd); + if (hkdfHashSz <= 0) { + WOLFSSL_MSG("Failed to get block size for HKDF hash."); + return WOLFSSL_FAILURE; + } + /* Length of extract only is always the length of the hash. */ + *keylen = hkdfHashSz; + } + } + else if (ctx->pkey->hkdfMode == EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { + if (wc_HKDF_Expand(hkdfHashType, ctx->pkey->hkdfKey, + ctx->pkey->hkdfKeySz, ctx->pkey->hkdfInfo, + ctx->pkey->hkdfInfoSz, key, + (word32)*keylen) != 0) { + WOLFSSL_MSG("wc_HKDF_Expand failed."); + return WOLFSSL_FAILURE; + } + } + else { + WOLFSSL_MSG("Invalid HKDF mode."); + return WOLFSSL_FAILURE; + } + break; +#endif /* HAVE_HKDF */ default: WOLFSSL_MSG("Unknown key type"); return WOLFSSL_FAILURE; @@ -1641,7 +1737,166 @@ 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 && WOLFSSL_DH_EXTRA) || HAVE_ECC */ +#endif /* (!NO_DH && WOLFSSL_DH_EXTRA) || HAVE_ECC || HAVE_HKDF */ + +#ifdef HAVE_HKDF +int wolfSSL_EVP_PKEY_CTX_set_hkdf_md(WOLFSSL_EVP_PKEY_CTX* ctx, + const WOLFSSL_EVP_MD* md) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set_hkdf_md"); + + if (ctx == NULL || ctx->pkey == NULL || md == NULL) { + WOLFSSL_MSG("Bad argument."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ctx->pkey->hkdfMd = md; + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set_hkdf_md", ret); + + return ret; +} + +int wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt(WOLFSSL_EVP_PKEY_CTX* ctx, byte* salt, + int saltSz) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt"); + + if (ctx == NULL || ctx->pkey == NULL || saltSz < 0) { + WOLFSSL_MSG("Bad argument."); + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) { + WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && salt != NULL && saltSz > 0) { + if (ctx->pkey->hkdfSalt != NULL) { + XFREE(ctx->pkey->hkdfSalt, NULL, DYNAMIC_TYPE_SALT); + } + ctx->pkey->hkdfSalt = (byte*)XMALLOC(saltSz, NULL, DYNAMIC_TYPE_SALT); + if (ctx->pkey->hkdfSalt == NULL) { + WOLFSSL_MSG("Failed to allocate HKDF salt buffer."); + ret = WOLFSSL_FAILURE; + } + else { + XMEMCPY(ctx->pkey->hkdfSalt, salt, saltSz); + ctx->pkey->hkdfSaltSz = saltSz; + } + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt", ret); + + return ret; +} + +int wolfSSL_EVP_PKEY_CTX_set1_hkdf_key(WOLFSSL_EVP_PKEY_CTX* ctx, byte* key, + int keySz) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set1_hkdf_key"); + + if (ctx == NULL || ctx->pkey == NULL || key == NULL || keySz <= 0) { + WOLFSSL_MSG("Bad argument."); + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) { + WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + if (ctx->pkey->hkdfKey != NULL) { + XFREE(ctx->pkey->hkdfKey, NULL, DYNAMIC_TYPE_KEY); + } + ctx->pkey->hkdfKey = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_KEY); + if (ctx->pkey->hkdfKey == NULL) { + WOLFSSL_MSG("Failed to allocate HKDF key buffer."); + ret = WOLFSSL_FAILURE; + } + else { + XMEMCPY(ctx->pkey->hkdfKey, key, keySz); + ctx->pkey->hkdfKeySz = keySz; + } + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_set1_hkdf_key", ret); + + return ret; +} + +int wolfSSL_EVP_PKEY_CTX_add1_hkdf_info(WOLFSSL_EVP_PKEY_CTX* ctx, byte* info, + int infoSz) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_add1_hkdf_info"); + + if (ctx == NULL || ctx->pkey == NULL || infoSz < 0) { + WOLFSSL_MSG("Bad argument."); + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS && ctx->pkey->type != EVP_PKEY_HKDF) { + WOLFSSL_MSG("WOLFSSL_EVP_PKEY type is not HKDF."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && info != NULL && infoSz > 0) { + /* If there's already info in the buffer, append. */ + ctx->pkey->hkdfInfo = (byte*)XREALLOC(ctx->pkey->hkdfInfo, + ctx->pkey->hkdfInfoSz + infoSz, NULL, DYNAMIC_TYPE_INFO); + if (ctx->pkey->hkdfInfo == NULL) { + WOLFSSL_MSG("Failed to reallocate larger HKDF info buffer."); + ret = WOLFSSL_FAILURE; + } + else { + XMEMCPY(ctx->pkey->hkdfInfo + ctx->pkey->hkdfInfoSz, info, + infoSz); + ctx->pkey->hkdfInfoSz += infoSz; + } + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_add1_hkdf_info", ret); + + return ret; +} + +int wolfSSL_EVP_PKEY_CTX_hkdf_mode(WOLFSSL_EVP_PKEY_CTX* ctx, int mode) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_hkdf_mode"); + + if (ctx == NULL || ctx->pkey == NULL) { + WOLFSSL_MSG("Bad argument."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS && + mode != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND && + mode != EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY && + mode != EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { + WOLFSSL_MSG("Invalid HKDF mode."); + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + ctx->pkey->hkdfMode = mode; + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_CTX_hkdf_mode", ret); + + return ret; +} +#endif /* HAVE_HKDF */ /* Uses the WOLFSSL_EVP_PKEY_CTX to decrypt a buffer. * @@ -2641,7 +2896,7 @@ static const struct s_ent { {WC_HASH_TYPE_NONE, 0, NULL} }; -static enum wc_HashType wolfSSL_EVP_md2macType(const WOLFSSL_EVP_MD *md) +static enum wc_HashType EvpMd2MacType(const WOLFSSL_EVP_MD *md) { const struct s_ent *ent ; @@ -3421,7 +3676,7 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, } ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen, - iter, keylen, wolfSSL_EVP_md2macType(digest)); + iter, keylen, EvpMd2MacType(digest)); if (ret == 0) return WOLFSSL_SUCCESS; else @@ -4719,6 +4974,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } #endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20_poly1305(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_chacha20_poly1305"); + return EVP_CHACHA20_POLY1305; + } +#endif + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void) { WOLFSSL_ENTER("wolfSSL_EVP_enc_null"); @@ -4854,7 +5117,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) int arg, void *ptr) { int ret = WOLFSSL_FAILURE; -#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) && !defined(WC_NO_RNG) +#ifndef WC_NO_RNG WC_RNG rng; #endif if (ctx == NULL) @@ -4874,21 +5137,34 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) case EVP_CTRL_SET_KEY_LENGTH: ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg); break; -#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) && !defined(WC_NO_RNG) - case EVP_CTRL_GCM_SET_IVLEN: +#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) + case EVP_CTRL_AEAD_SET_IVLEN: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; - if(arg <= 0 || arg > 16) - break; + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + if (ctx->cipherType == CHACHA20_POLY1305_TYPE) { + if (arg != CHACHA20_POLY1305_AEAD_IV_SIZE) { + break; + } + } + else + #endif /* HAVE_CHACHA && HAVE_POLY1305 */ + { + if (arg <= 0 || arg > AES_BLOCK_SIZE) + break; + } ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); break; + case EVP_CTRL_AEAD_SET_IV_FIXED: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; if (arg == -1) { /* arg == -1 copies ctx->ivSz from ptr */ ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, (byte*)ptr, ctx->ivSz); - } else { + } +#ifndef WC_NO_RNG + else { /* * Fixed field must be at least 4 bytes and invocation * field at least 8. @@ -4918,9 +5194,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) break; } } +#endif /* !WC_NO_RNG */ break; -#if !defined(_WIN32) && (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION >= 2))) +#if defined(HAVE_AESGCM) && !defined(_WIN32) && !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(2,0)) case EVP_CTRL_GCM_IV_GEN: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; @@ -4948,27 +5225,57 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) ctx->gcmAuthInSz = 0; ret = WOLFSSL_SUCCESS; break; -#endif +#endif /* HAVE_AESGCM && !_WIN32 && !HAVE_SELFTEST && (!HAVE_FIPS || + * FIPS_VERSION >= 2)*/ case EVP_CTRL_AEAD_SET_TAG: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; - if(arg <= 0 || arg > 16 || (ptr == NULL)) +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + if (ctx->cipherType == CHACHA20_POLY1305_TYPE) { + if (arg != CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) { + break; + } + ctx->authTagSz = arg; + ret = WOLFSSL_SUCCESS; + if (ptr != NULL) { + XMEMCPY(ctx->authTag, ptr, arg); + } break; + } + else +#endif /* HAVE_CHACHA && HAVE_POLY1305 */ + { + if(arg <= 0 || arg > 16 || (ptr == NULL)) + break; - XMEMCPY(ctx->authTag, ptr, arg); - ctx->authTagSz = arg; - ret = WOLFSSL_SUCCESS; - break; + XMEMCPY(ctx->authTag, ptr, arg); + ctx->authTagSz = arg; + ret = WOLFSSL_SUCCESS; + break; + } case EVP_CTRL_AEAD_GET_TAG: if ((ctx->flags & WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER) == 0) break; - if(arg <= 0 || arg > 16) - break; - XMEMCPY(ptr, ctx->authTag, arg); - ret = WOLFSSL_SUCCESS; +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + if (ctx->cipherType == CHACHA20_POLY1305_TYPE) { + if (arg != CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) { + break; + } + } + else +#endif /* HAVE_CHACHA && HAVE_POLY1305 */ + { + if (arg <= 0 || arg > AES_BLOCK_SIZE) + break; + } + + if (ptr != NULL) { + XMEMCPY(ptr, ctx->authTag, arg); + ret = WOLFSSL_SUCCESS; + } break; -#endif /* HAVE_AESGCM && !HAVE_SELFTEST && !WC_NO_RNG */ +#endif /* HAVE_AESGCM || (HAVE_CHACHA && HAVE_POLY1305) */ default: WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); break; @@ -5873,7 +6180,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_XTS */ #endif /* NO_AES */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + if (ctx->cipherType == CHACHA20_POLY1305_TYPE || + (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_CHACHA20_POLY1305))) { + WOLFSSL_MSG("EVP_CHACHA20_POLY1305"); + ctx->cipherType = CHACHA20_POLY1305_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER; + ctx->keyLen = CHACHA20_POLY1305_AEAD_KEYSIZE; + ctx->block_size = CHACHA_CHUNK_BYTES; + ctx->authTagSz = CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE; + ctx->ivSz = CHACHA20_POLY1305_AEAD_IV_SIZE; + if (enc == 0 || enc == 1) { + ctx->enc = enc; + } + if (key != NULL && iv != NULL && wc_ChaCha20Poly1305_Init( + &ctx->cipher.chachaPoly, key, iv, enc) != 0) { + WOLFSSL_MSG("wc_ChaCha20Poly1305_Init() failed"); + return WOLFSSL_FAILURE; + } + } +#endif #ifndef NO_DES3 if (ctx->cipherType == DES_CBC_TYPE || (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_CBC))) { @@ -6030,7 +6358,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } #endif -#if defined(HAVE_AESGCM) +#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) /* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */ int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv, int ivLen) @@ -6377,7 +6705,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) #endif /* Set to 0 if no match */ - ctx->macType = wolfSSL_EVP_md2macType(md); + ctx->macType = EvpMd2MacType(md); if (md == NULL) { XMEMSET(&ctx->hash.digest, 0, sizeof(WOLFSSL_Hasher)); } @@ -6466,7 +6794,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) WOLFSSL_ENTER("EVP_DigestUpdate"); - macType = wolfSSL_EVP_md2macType(EVP_MD_CTX_md(ctx)); + macType = EvpMd2MacType(EVP_MD_CTX_md(ctx)); switch (macType) { case WC_HASH_TYPE_MD4: #ifndef NO_MD4 @@ -6580,7 +6908,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) enum wc_HashType macType; WOLFSSL_ENTER("EVP_DigestFinal"); - macType = wolfSSL_EVP_md2macType(EVP_MD_CTX_md(ctx)); + macType = EvpMd2MacType(EVP_MD_CTX_md(ctx)); switch (macType) { case WC_HASH_TYPE_MD4: #ifndef NO_MD4 @@ -8074,8 +8402,27 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) break; #endif /* ! NO_DH ... */ + #ifdef HAVE_HKDF + case EVP_PKEY_HKDF: + if (key->hkdfSalt != NULL) { + XFREE(key->hkdfSalt, NULL, DYNAMIC_TYPE_SALT); + key->hkdfSalt = NULL; + } + if (key->hkdfKey != NULL) { + XFREE(key->hkdfKey, NULL, DYNAMIC_TYPE_KEY); + key->hkdfKey = NULL; + } + if (key->hkdfInfo != NULL) { + XFREE(key->hkdfInfo, NULL, DYNAMIC_TYPE_INFO); + key->hkdfInfo = NULL; + } + key->hkdfSaltSz = 0; + key->hkdfKeySz = 0; + key->hkdfInfoSz = 0; + #endif /* HAVE_HKDF */ + default: - break; + break; } #ifndef SINGLE_THREADED diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 362383bbf..fc7345308 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -69,6 +69,7 @@ #define ASN1_UTCTIME_print wolfSSL_ASN1_UTCTIME_print #define ASN1_TIME_check wolfSSL_ASN1_TIME_check #define ASN1_TIME_diff wolfSSL_ASN1_TIME_diff +#define ASN1_TIME_compare wolfSSL_ASN1_TIME_compare #define ASN1_TIME_set wolfSSL_ASN1_TIME_set #define V_ASN1_EOC 0 diff --git a/wolfssl/openssl/dh.h b/wolfssl/openssl/dh.h index fe4b3fc2d..fdf54359c 100644 --- a/wolfssl/openssl/dh.h +++ b/wolfssl/openssl/dh.h @@ -60,6 +60,7 @@ WOLFSSL_API WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, long length); WOLFSSL_API int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out); WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_new(void); +WOLFSSL_API WOLFSSL_DH* wolSSL_DH_new_by_nid(int nid); WOLFSSL_API void wolfSSL_DH_free(WOLFSSL_DH* dh); WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh); WOLFSSL_API int wolfSSL_DH_up_ref(WOLFSSL_DH* dh); @@ -81,9 +82,10 @@ WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_get_2048_256(void); typedef WOLFSSL_DH DH; -#define DH_new wolfSSL_DH_new -#define DH_free wolfSSL_DH_free -#define DH_up_ref wolfSSL_DH_up_ref +#define DH_new wolfSSL_DH_new +#define DH_free wolfSSL_DH_free +#define DH_up_ref wolfSSL_DH_up_ref +#define DH_new_by_nid wolSSL_DH_new_by_nid #define d2i_DHparams wolfSSL_d2i_DHparams #define i2d_DHparams wolfSSL_i2d_DHparams @@ -126,6 +128,9 @@ typedef WOLFSSL_DH DH; #define DH_generate_parameters_ex wolfSSL_DH_generate_parameters_ex #endif /* OPENSSL_ALL || HAVE_STUNNEL */ +#define DH_GENERATOR_2 2 +#define DH_GENERATOR_5 5 + #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #ifdef __cplusplus diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 2d79a5925..049801609 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -354,8 +354,12 @@ typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; #define EC_POINT_free wolfSSL_EC_POINT_free #define EC_POINT_get_affine_coordinates_GFp \ wolfSSL_EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_get_affine_coordinates \ + wolfSSL_EC_POINT_get_affine_coordinates_GFp #define EC_POINT_set_affine_coordinates_GFp \ wolfSSL_EC_POINT_set_affine_coordinates_GFp +#define EC_POINT_set_affine_coordinates \ + wolfSSL_EC_POINT_set_affine_coordinates_GFp #define EC_POINT_add wolfSSL_EC_POINT_add #define EC_POINT_mul wolfSSL_EC_POINT_mul #define EC_POINT_invert wolfSSL_EC_POINT_invert diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 18e04097f..1cd7d6061 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -135,6 +136,9 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc2_cbc(void); +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20_poly1305(void); +#endif typedef union { @@ -205,6 +209,9 @@ typedef union { #ifdef WOLFSSL_QT int (*ctrl) (WOLFSSL_EVP_CIPHER_CTX *, int type, int arg, void *ptr); #endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + ChaChaPoly_Aead chachaPoly; +#endif } WOLFSSL_Cipher; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -241,8 +248,12 @@ enum { NID_hmacWithSHA256 = 799, NID_hmacWithSHA384 = 800, NID_hmacWithSHA512 = 801, + NID_hkdf = 1036, NID_cmac = 894, NID_dhKeyAgreement= 28, + NID_ffdhe2048 = 1126, + NID_ffdhe3072 = 1127, + NID_ffdhe4096 = 1128, NID_rc4 = 5, NID_bf_cbc = 91, NID_bf_ecb = 92, @@ -254,6 +265,7 @@ enum { NID_cast5_ofb64 = 111, EVP_PKEY_DH = NID_dhKeyAgreement, EVP_PKEY_HMAC = NID_hmac, + EVP_PKEY_HKDF = NID_hkdf, EVP_PKEY_FALCON = 300, /* Randomly picked value. */ AES_128_CFB1_TYPE = 24, AES_192_CFB1_TYPE = 25, @@ -268,7 +280,8 @@ enum { AES_192_OFB_TYPE = 34, AES_256_OFB_TYPE = 35, AES_128_XTS_TYPE = 36, - AES_256_XTS_TYPE = 37 + AES_256_XTS_TYPE = 37, + CHACHA20_POLY1305_TYPE = 38 }; enum { @@ -392,11 +405,12 @@ struct WOLFSSL_EVP_CIPHER_CTX { unsigned long flags; unsigned char enc; /* if encrypt side, then true */ unsigned char cipherType; -#ifndef NO_AES +#if !defined(NO_AES) /* working iv pointer into cipher */ ALIGN16 unsigned char iv[AES_BLOCK_SIZE]; +#elif defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + ALIGN16 unsigned char iv[CHACHA20_POLY1305_AEAD_IV_SIZE]; #elif !defined(NO_DES3) - /* working iv pointer into cipher */ ALIGN16 unsigned char iv[DES_BLOCK_SIZE]; #endif WOLFSSL_Cipher cipher; @@ -405,17 +419,24 @@ struct WOLFSSL_EVP_CIPHER_CTX { ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; int lastUsed; #if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_AESGCM) || \ - defined (WOLFSSL_AES_XTS) + defined (WOLFSSL_AES_XTS) || (defined(HAVE_CHACHA) || \ + defined(HAVE_POLY1305)) #define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV int ivSz; #ifdef HAVE_AESGCM byte* gcmBuffer; int gcmBufferLen; - ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; - int authTagSz; byte* gcmAuthIn; int gcmAuthInSz; #endif +#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) +#ifdef HAVE_AESGCM + ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; +#else + ALIGN16 unsigned char authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; +#endif + int authTagSz; +#endif #endif }; @@ -707,6 +728,18 @@ WOLFSSL_API void wolfSSL_EVP_MD_do_all(void (*fn) (const WOLFSSL_EVP_MD *md, const char* from, const char* to, void* xx), void* args); +#ifdef HAVE_HKDF +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_hkdf_md(WOLFSSL_EVP_PKEY_CTX* ctx, + const WOLFSSL_EVP_MD* md); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt(WOLFSSL_EVP_PKEY_CTX* ctx, + byte* salt, int saltSz); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set1_hkdf_key(WOLFSSL_EVP_PKEY_CTX* ctx, + byte* key, int keySz); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_add1_hkdf_info(WOLFSSL_EVP_PKEY_CTX* ctx, + byte* info, int infoSz); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_hkdf_mode(WOLFSSL_EVP_PKEY_CTX* ctx, + int mode); +#endif #define WOLFSSL_EVP_CIPH_MODE 0x0007 #define WOLFSSL_EVP_CIPH_STREAM_CIPHER 0x0 @@ -814,41 +847,42 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_sha3_384 wolfSSL_EVP_sha3_384 #define EVP_sha3_512 wolfSSL_EVP_sha3_512 -#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc -#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc -#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc -#define EVP_aes_128_cfb1 wolfSSL_EVP_aes_128_cfb1 -#define EVP_aes_192_cfb1 wolfSSL_EVP_aes_192_cfb1 -#define EVP_aes_256_cfb1 wolfSSL_EVP_aes_256_cfb1 -#define EVP_aes_128_cfb8 wolfSSL_EVP_aes_128_cfb8 -#define EVP_aes_192_cfb8 wolfSSL_EVP_aes_192_cfb8 -#define EVP_aes_256_cfb8 wolfSSL_EVP_aes_256_cfb8 -#define EVP_aes_128_cfb128 wolfSSL_EVP_aes_128_cfb128 -#define EVP_aes_192_cfb128 wolfSSL_EVP_aes_192_cfb128 -#define EVP_aes_256_cfb128 wolfSSL_EVP_aes_256_cfb128 -#define EVP_aes_128_cfb wolfSSL_EVP_aes_128_cfb128 -#define EVP_aes_192_cfb wolfSSL_EVP_aes_192_cfb128 -#define EVP_aes_256_cfb wolfSSL_EVP_aes_256_cfb128 -#define EVP_aes_128_ofb wolfSSL_EVP_aes_128_ofb -#define EVP_aes_192_ofb wolfSSL_EVP_aes_192_ofb -#define EVP_aes_256_ofb wolfSSL_EVP_aes_256_ofb -#define EVP_aes_128_xts wolfSSL_EVP_aes_128_xts -#define EVP_aes_256_xts wolfSSL_EVP_aes_256_xts -#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm -#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm -#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm -#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb -#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb -#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb -#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr -#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr -#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr -#define EVP_des_cbc wolfSSL_EVP_des_cbc -#define EVP_des_ecb wolfSSL_EVP_des_ecb -#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc -#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb -#define EVP_rc4 wolfSSL_EVP_rc4 -#define EVP_enc_null wolfSSL_EVP_enc_null +#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc +#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc +#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_cfb1 wolfSSL_EVP_aes_128_cfb1 +#define EVP_aes_192_cfb1 wolfSSL_EVP_aes_192_cfb1 +#define EVP_aes_256_cfb1 wolfSSL_EVP_aes_256_cfb1 +#define EVP_aes_128_cfb8 wolfSSL_EVP_aes_128_cfb8 +#define EVP_aes_192_cfb8 wolfSSL_EVP_aes_192_cfb8 +#define EVP_aes_256_cfb8 wolfSSL_EVP_aes_256_cfb8 +#define EVP_aes_128_cfb128 wolfSSL_EVP_aes_128_cfb128 +#define EVP_aes_192_cfb128 wolfSSL_EVP_aes_192_cfb128 +#define EVP_aes_256_cfb128 wolfSSL_EVP_aes_256_cfb128 +#define EVP_aes_128_cfb wolfSSL_EVP_aes_128_cfb128 +#define EVP_aes_192_cfb wolfSSL_EVP_aes_192_cfb128 +#define EVP_aes_256_cfb wolfSSL_EVP_aes_256_cfb128 +#define EVP_aes_128_ofb wolfSSL_EVP_aes_128_ofb +#define EVP_aes_192_ofb wolfSSL_EVP_aes_192_ofb +#define EVP_aes_256_ofb wolfSSL_EVP_aes_256_ofb +#define EVP_aes_128_xts wolfSSL_EVP_aes_128_xts +#define EVP_aes_256_xts wolfSSL_EVP_aes_256_xts +#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm +#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm +#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm +#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb +#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb +#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb +#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr +#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr +#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr +#define EVP_des_cbc wolfSSL_EVP_des_cbc +#define EVP_des_ecb wolfSSL_EVP_des_ecb +#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc +#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb +#define EVP_rc4 wolfSSL_EVP_rc4 +#define EVP_chacha20_poly1305 wolfSSL_EVP_chacha20_poly1305 +#define EVP_enc_null wolfSSL_EVP_enc_null #define EVP_MD_size wolfSSL_EVP_MD_size #define EVP_MD_pkey_type wolfSSL_EVP_MD_pkey_type @@ -1103,6 +1137,14 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_blake2s256 wolfSSL_EVP_blake2s256 #define EVP_MD_do_all wolfSSL_EVP_MD_do_all +#ifdef HAVE_HKDF +#define EVP_PKEY_CTX_set_hkdf_md wolfSSL_EVP_PKEY_CTX_set_hkdf_md +#define EVP_PKEY_CTX_set1_hkdf_salt wolfSSL_EVP_PKEY_CTX_set1_hkdf_salt +#define EVP_PKEY_CTX_set1_hkdf_key wolfSSL_EVP_PKEY_CTX_set1_hkdf_key +#define EVP_PKEY_CTX_add1_hkdf_info wolfSSL_EVP_PKEY_CTX_add1_hkdf_info +#define EVP_PKEY_CTX_hkdf_mode wolfSSL_EVP_PKEY_CTX_hkdf_mode +#endif + WOLFSSL_API void printPKEY(WOLFSSL_EVP_PKEY *k); #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 8f224e323..dee416cd5 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -29,6 +29,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/evp.h \ wolfssl/openssl/fips_rand.h \ wolfssl/openssl/hmac.h \ + wolfssl/openssl/kdf.h \ wolfssl/openssl/lhash.h \ wolfssl/openssl/md4.h \ wolfssl/openssl/md5.h \ diff --git a/wolfssl/openssl/kdf.h b/wolfssl/openssl/kdf.h new file mode 100644 index 000000000..b25052d83 --- /dev/null +++ b/wolfssl/openssl/kdf.h @@ -0,0 +1,37 @@ +/* kdf.h + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_KDF_H_ +#define WOLFSSL_KDF_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +#define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +#define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_KDF_H_ */ diff --git a/wolfssl/openssl/objects.h b/wolfssl/openssl/objects.h index ab08fdba2..4e088d4b7 100644 --- a/wolfssl/openssl/objects.h +++ b/wolfssl/openssl/objects.h @@ -43,21 +43,23 @@ #define OBJ_NAME_TYPE_NUM WOLFSSL_OBJ_NAME_TYPE_NUM #define OBJ_NAME_ALIAS WOLFSSL_OBJ_NAME_ALIAS -#define OBJ_nid2sn wolfSSL_OBJ_nid2sn -#define OBJ_obj2nid wolfSSL_OBJ_obj2nid -#define OBJ_sn2nid wolfSSL_OBJ_sn2nid -#define OBJ_nid2ln wolfSSL_OBJ_nid2ln -#define OBJ_ln2nid wolfSSL_OBJ_ln2nid -#define OBJ_txt2nid wolfSSL_OBJ_txt2nid -#define OBJ_txt2obj wolfSSL_OBJ_txt2obj -#define OBJ_nid2obj wolfSSL_OBJ_nid2obj -#define OBJ_obj2txt wolfSSL_OBJ_obj2txt -#define OBJ_cleanup wolfSSL_OBJ_cleanup -#define OBJ_cmp wolfSSL_OBJ_cmp -#define OBJ_create wolfSSL_OBJ_create +#define OBJ_nid2sn wolfSSL_OBJ_nid2sn +#define OBJ_obj2nid wolfSSL_OBJ_obj2nid +#define OBJ_sn2nid wolfSSL_OBJ_sn2nid +#define OBJ_length wolfSSL_OBJ_length +#define OBJ_get0_data wolfSSL_OBJ_get0_data +#define OBJ_nid2ln wolfSSL_OBJ_nid2ln +#define OBJ_ln2nid wolfSSL_OBJ_ln2nid +#define OBJ_txt2nid wolfSSL_OBJ_txt2nid +#define OBJ_txt2obj wolfSSL_OBJ_txt2obj +#define OBJ_nid2obj wolfSSL_OBJ_nid2obj +#define OBJ_obj2txt wolfSSL_OBJ_obj2txt +#define OBJ_cleanup wolfSSL_OBJ_cleanup +#define OBJ_cmp wolfSSL_OBJ_cmp +#define OBJ_create wolfSSL_OBJ_create #define ASN1_OBJECT_free wolfSSL_ASN1_OBJECT_free -#define OBJ_NAME_do_all wolfSSL_OBJ_NAME_do_all -#define i2t_ASN1_OBJECT wolfSSL_i2t_ASN1_OBJECT +#define OBJ_NAME_do_all wolfSSL_OBJ_NAME_do_all +#define i2t_ASN1_OBJECT wolfSSL_i2t_ASN1_OBJECT /* not required for wolfSSL */ #define OPENSSL_load_builtin_modules() diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 502ce76d5..746126083 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -399,6 +399,16 @@ struct WOLFSSL_EVP_PKEY { WOLFSSL_DH* dh; #endif WC_RNG rng; + #ifdef HAVE_HKDF + const WOLFSSL_EVP_MD* hkdfMd; + byte* hkdfSalt; + word32 hkdfSaltSz; + byte* hkdfKey; + word32 hkdfKeySz; + byte* hkdfInfo; + word32 hkdfInfoSz; + int hkdfMode; + #endif #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #ifdef HAVE_ECC int pkey_curve; @@ -2611,6 +2621,8 @@ WOLFSSL_API void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_GENERALIZEDTIME* WOLFSSL_API int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a); WOLFSSL_API int wolfSSL_ASN1_TIME_diff(int* days, int* secs, const WOLFSSL_ASN1_TIME* from, const WOLFSSL_ASN1_TIME* to); +WOLFSSL_API int wolfSSL_ASN1_TIME_compare(const WOLFSSL_ASN1_TIME *a, + const WOLFSSL_ASN1_TIME *b); #ifdef OPENSSL_EXTRA WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t); WOLFSSL_API int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str); @@ -4000,6 +4012,9 @@ WOLFSSL_API const char* wolfSSL_OBJ_nid2sn(int n); WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); WOLFSSL_API int wolfSSL_OBJ_get_type(const WOLFSSL_ASN1_OBJECT *o); WOLFSSL_API int wolfSSL_OBJ_sn2nid(const char *sn); +WOLFSSL_API size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o); +WOLFSSL_API const unsigned char* wolfSSL_OBJ_get0_data( + const WOLFSSL_ASN1_OBJECT* o); WOLFSSL_API const char* wolfSSL_OBJ_nid2ln(int n); WOLFSSL_API int wolfSSL_OBJ_ln2nid(const char *ln); diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 99ca2a4b1..d2992d207 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -210,7 +210,7 @@ WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, const byte* inKey, word32 inKeySz, byte* out); WOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, const byte* info, word32 infoSz, - byte* out, word32 outSz); + byte* out, word32 outSz); WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt, word32 saltSz, diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index cef354b81..d513d7f8a 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2027,7 +2027,7 @@ extern void uITRON4_free(void *p) ; #if !defined(HAVE_PUBLIC_FFDHE) && !defined(NO_DH) && \ !defined(WOLFSSL_NO_PUBLIC_FFDHE) && \ - (defined(HAVE_SELFTEST) || FIPS_VERSION_EQ(2,0)) + (defined(HAVE_SELFTEST) || FIPS_VERSION_GE(2,0)) #define HAVE_PUBLIC_FFDHE #endif