diff --git a/tests/api.c b/tests/api.c index b3e3eee4a..2d3979269 100644 --- a/tests/api.c +++ b/tests/api.c @@ -33295,6 +33295,36 @@ static int test_wolfSSL_EVP_PKEY_new_mac_key(void) return 0; } + + +static int test_wolfSSL_EVP_PKEY_new_CMAC_key(void) +{ +#ifdef OPENSSL_EXTRA +#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) + + const char *priv = "ABCDEFGHIJKLMNOP"; + const WOLFSSL_EVP_CIPHER* cipher = EVP_aes_128_cbc(); + WOLFSSL_EVP_PKEY* key = NULL; + printf(testingFmt, "wolfSSL_EVP_PKEY_new_CMAC_key()"); + + AssertNull(key = wolfSSL_EVP_PKEY_new_CMAC_key( + NULL, NULL, AES_128_KEY_SIZE, cipher)); + AssertNull(key = wolfSSL_EVP_PKEY_new_CMAC_key( + NULL, (const unsigned char *)priv, 0, cipher)); + AssertNull(key = wolfSSL_EVP_PKEY_new_CMAC_key( + NULL, (const unsigned char *)priv, AES_128_KEY_SIZE, NULL)); + + AssertNotNull(key = wolfSSL_EVP_PKEY_new_CMAC_key( + NULL, (const unsigned char *)priv, AES_128_KEY_SIZE, cipher)); + wolfSSL_EVP_PKEY_free(key); + + printf(resultFmt, passed); +#endif /* defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) */ +#endif /* OPENSSL_EXTRA */ + + return 0; +} + static int test_wolfSSL_EVP_Digest(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && !defined(NO_PWDBASED) @@ -58701,6 +58731,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_EVP_Digest), TEST_DECL(test_wolfSSL_EVP_Digest_all), TEST_DECL(test_wolfSSL_EVP_PKEY_new_mac_key), + TEST_DECL(test_wolfSSL_EVP_PKEY_new_CMAC_key), TEST_DECL(test_wolfSSL_EVP_MD_hmac_signing), TEST_DECL(test_wolfSSL_EVP_MD_rsa_signing), TEST_DECL(test_wolfSSL_EVP_MD_ecc_signing), diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 3a6e0963d..f1231fb81 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3428,6 +3428,60 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, WOLFSSL_ENGINE* e, } +#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) +WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_CMAC_key(WOLFSSL_ENGINE* e, + const unsigned char* priv, size_t len, const WOLFSSL_EVP_CIPHER *cipher) +{ + WOLFSSL_EVP_PKEY* pkey; + WOLFSSL_CMAC_CTX* ctx; + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_new_CMAC_key"); + + if (priv == NULL || len == 0 || cipher == NULL) { + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_new_CMAC_key", BAD_FUNC_ARG); + return NULL; + } + + ctx = wolfSSL_CMAC_CTX_new(); + if (ctx == NULL) { + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_new_CMAC_key", 0); + return NULL; + } + + ret = wolfSSL_CMAC_Init(ctx, priv, len, cipher, e); + if (ret == WOLFSSL_FAILURE) { + wolfSSL_CMAC_CTX_free(ctx); + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_new_CMAC_key", 0); + return NULL; + } + + pkey = wolfSSL_EVP_PKEY_new(); + if (pkey != NULL) { + pkey->pkey.ptr = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_PUBLIC_KEY); + if (pkey->pkey.ptr == NULL && len > 0) { + wolfSSL_EVP_PKEY_free(pkey); + pkey = NULL; + wolfSSL_CMAC_CTX_free(ctx); + } + else { + if (len) { + XMEMCPY(pkey->pkey.ptr, priv, len); + } + pkey->pkey_sz = (int)len; + pkey->type = pkey->save_type = EVP_PKEY_CMAC; + pkey->cmacCtx = ctx; + } + } + else { + wolfSSL_CMAC_CTX_free(ctx); + } + + WOLFSSL_LEAVE("wolfSSL_EVP_PKEY_new_CMAC_key", 0); + return pkey; +} +#endif /* defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) */ + const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, size_t* len) { @@ -8952,6 +9006,16 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) break; #endif /* HAVE_HKDF */ + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && \ + defined(WOLFSSL_AES_DIRECT) + case EVP_PKEY_CMAC: + if (key->cmacCtx != NULL) { + wolfSSL_CMAC_CTX_free(key->cmacCtx); + key->cmacCtx = NULL; + } + break; + #endif /* defined(WOLFSSL_CMAC) ... */ + default: break; } diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 6ddf9f558..32f7f461f 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -273,6 +273,7 @@ enum { NID_cast5_ofb64 = 111, EVP_PKEY_DH = NID_dhKeyAgreement, EVP_PKEY_HMAC = NID_hmac, + EVP_PKEY_CMAC = NID_cmac, EVP_PKEY_HKDF = NID_hkdf, EVP_PKEY_FALCON = 300, /* Randomly picked value. */ EVP_PKEY_DILITHIUM= 301, /* Randomly picked value. */ @@ -789,6 +790,11 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_hkdf_mode(WOLFSSL_EVP_PKEY_CTX* ctx, /* EVP ENGINE API's */ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, WOLFSSL_ENGINE* e, const unsigned char* key, int keylen); + +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_CMAC_key(WOLFSSL_ENGINE* e, + const unsigned char* priv, size_t len, + const WOLFSSL_EVP_CIPHER* cipher); + WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx, const WOLFSSL_EVP_MD* type, WOLFSSL_ENGINE *impl); @@ -1004,6 +1010,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_PKEY_get0_EC_KEY wolfSSL_EVP_PKEY_get0_EC_KEY #define EVP_PKEY_get0_hmac wolfSSL_EVP_PKEY_get0_hmac #define EVP_PKEY_new_mac_key wolfSSL_EVP_PKEY_new_mac_key +#define EVP_PKEY_new_CMAC_key wolfSSL_EVP_PKEY_new_CMAC_key #define EVP_MD_CTX_copy wolfSSL_EVP_MD_CTX_copy #define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex #define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index bb3a63390..9e6682588 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -89,6 +89,9 @@ #ifndef WOLFCRYPT_ONLY #include #endif + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) + #include + #endif /* We need the old SSL names */ #ifdef NO_OLD_SSL_NAMES @@ -411,6 +414,9 @@ struct WOLFSSL_EVP_PKEY { word32 hkdfInfoSz; int hkdfMode; #endif + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) + WOLFSSL_CMAC_CTX* cmacCtx; + #endif #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #ifdef HAVE_ECC int pkey_curve;