Files
wolfssl/tests/api/test_ossl_mac.c
T
Tobias Frauenschläger cb73424c31 Zeroize the saved HMAC pads on cleanup
WOLFSSL_HMAC_CTX keeps a copy of the inner and outer pads outside the
embedded wolfCrypt HMAC object so that a later init with a NULL key can
restore the key. Those pads are the key combined with the fixed padding, so
for any key no longer than the hash block size the key falls out of a single
exclusive or. Cleanup only called wc_HmacFree on the embedded object, which
zeroes what it is given but cannot reach the enclosing context, so the saved
pads survived. HMAC_CTX_free then returned that heap block to the allocator
with the key material still in it, where it stayed until some later
allocation happened to overwrite it.

Wipe both saved pads in wolfSSL_HMAC_cleanup, which HMAC_CTX_cleanup,
HMAC_CTX_reset and HMAC_CTX_free all reach. Do the same on the set key
failure path in the init function, since the context is reported as unkeyed
there while the previous key's pads would otherwise remain.

The session ticket key callback had the same leak for the same reason. It
holds a WOLFSSL_HMAC_CTX on the stack, hands it to the application to be
keyed with the long lived ticket HMAC key, and then only freed the embedded
object, leaving the pads on the stack after every ticket encrypt and every
ticket decrypt including the error paths. Have it clean up through
wolfSSL_HMAC_CTX_cleanup so it picks up the wipe.

Add a regression test that keys a context, checks the pads were populated,
runs cleanup and requires both arrays to be zero.

Fixes F-7256 and F-7257.
2026-08-01 11:54:40 +02:00

575 lines
22 KiB
C

/* test_ossl_mac.c
*
* Copyright (C) 2006-2026 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 3 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
*/
#include <tests/unit.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#include <wolfssl/openssl/hmac.h>
#include <wolfssl/openssl/cmac.h>
#include <wolfssl/wolfcrypt/types.h>
#include <tests/api/api.h>
#include <tests/api/test_ossl_mac.h>
/*******************************************************************************
* MAC OpenSSL compatibility API Testing
******************************************************************************/
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC)
/* helper function for test_wolfSSL_HMAC_CTX, digest size is expected to be a
* buffer of 64 bytes.
*
* returns the size of the digest buffer on success and a negative value on
* failure.
*/
static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest,
int* sz)
{
EXPECT_DECLS;
HMAC_CTX ctx1;
HMAC_CTX ctx2;
unsigned char key[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
unsigned char long_key[] =
"0123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789"
"0123456789012345678901234567890123456789";
unsigned char msg[] = "message to hash";
unsigned int digestSz = 64;
int keySz = sizeof(key);
int long_keySz = sizeof(long_key);
int msgSz = sizeof(msg);
unsigned char digest2[64];
unsigned int digestSz2 = 64;
HMAC_CTX_init(&ctx1);
HMAC_CTX_init(&ctx2);
ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx1);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz2), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx2);
ExpectIntEQ(digestSz, digestSz2);
ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);
/* test HMAC_Init with NULL key */
/* init after copy */
HMAC_CTX_init(&ctx1);
ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);
ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx1);
ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx2);
ExpectIntEQ(digestSz, digestSz2);
ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);
/* long key */
HMAC_CTX_init(&ctx1);
ExpectIntEQ(HMAC_Init(&ctx1, (const void*)long_key, long_keySz, type),
SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);
ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx1);
ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx2);
ExpectIntEQ(digestSz, digestSz2);
ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);
/* init before copy */
HMAC_CTX_init(&ctx1);
ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS);
ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx1);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS);
ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS);
HMAC_CTX_cleanup(&ctx2);
ExpectIntEQ(digestSz, digestSz2);
ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0);
*sz = (int)digestSz;
return EXPECT_RESULT();
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_HMAC) */
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) && !defined(NO_SHA256)
/* Returns 1 when every byte of the buffer is zero. */
static int test_mac_all_zero(const void* buf, size_t len)
{
const byte* p = (const byte*)buf;
size_t i;
for (i = 0; i < len; i++) {
if (p[i] != 0) {
return 0;
}
}
return 1;
}
#endif
int test_wolfSSL_HMAC_CTX_cleanup_zeroize(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) && !defined(NO_SHA256)
/* The saved pads are the key combined with the fixed inner and outer
* padding, so cleanup has to wipe them along with the HMAC object. */
WOLFSSL_HMAC_CTX ctx;
unsigned char key[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
ExpectIntEQ(HMAC_CTX_init(&ctx), 1);
ExpectIntEQ(HMAC_Init_ex(&ctx, key, (int)sizeof(key) - 1, EVP_sha256(),
NULL), 1);
/* Keying the context must have filled the saved pads. */
ExpectIntEQ(test_mac_all_zero(ctx.save_ipad, sizeof(ctx.save_ipad)), 0);
ExpectIntEQ(test_mac_all_zero(ctx.save_opad, sizeof(ctx.save_opad)), 0);
HMAC_CTX_cleanup(&ctx);
ExpectIntEQ(test_mac_all_zero(ctx.save_ipad, sizeof(ctx.save_ipad)), 1);
ExpectIntEQ(test_mac_all_zero(ctx.save_opad, sizeof(ctx.save_opad)), 1);
/* Re-initializing without a key must now be rejected. Recovering from
* the wiped pads would silently MAC with an all zero key. */
ExpectIntEQ(HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL), 0);
HMAC_CTX_cleanup(&ctx);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_HMAC_CTX(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC)
unsigned char digest[64];
int digestSz;
WOLFSSL_HMAC_CTX* hmac_ctx = NULL;
WOLFSSL_HMAC_CTX ctx1;
WOLFSSL_HMAC_CTX ctx2;
ExpectNotNull(hmac_ctx = wolfSSL_HMAC_CTX_new());
ExpectIntEQ(wolfSSL_HMAC_CTX_Init(NULL), 1);
ExpectIntEQ(wolfSSL_HMAC_CTX_Init(hmac_ctx), 1);
wolfSSL_HMAC_CTX_free(NULL);
wolfSSL_HMAC_CTX_free(hmac_ctx);
XMEMSET(&ctx2, 0, sizeof(WOLFSSL_HMAC_CTX));
ExpectIntEQ(HMAC_CTX_init(NULL), 1);
ExpectIntEQ(HMAC_CTX_init(&ctx2), 1);
ExpectIntEQ(HMAC_CTX_copy(NULL, NULL), 0);
ExpectIntEQ(HMAC_CTX_copy(NULL, &ctx2), 0);
ExpectIntEQ(HMAC_CTX_copy(&ctx2, NULL), 0);
#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
((! defined(HAVE_FIPS_VERSION)) || \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2)))
/* Copy object that hasn't had a digest set - MD5. */
ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 1);
#else
/* Copy object that hasn't had a digest set. */
ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 0);
#endif
HMAC_CTX_cleanup(NULL);
HMAC_CTX_cleanup(&ctx2);
ExpectNull(HMAC_CTX_get_md(NULL));
#ifndef NO_SHA
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha1(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 20);
ExpectIntEQ(XMEMCMP("\xD9\x68\x77\x23\x70\xFB\x53\x70\x53\xBA\x0E\xDC\xDA"
"\xBF\x03\x98\x31\x19\xB2\xCC", digest, digestSz), 0);
#endif /* !NO_SHA */
#ifdef WOLFSSL_SHA224
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha224(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 28);
ExpectIntEQ(XMEMCMP("\x57\xFD\xF4\xE1\x2D\xB0\x79\xD7\x4B\x25\x7E\xB1\x95"
"\x9C\x11\xAC\x2D\x1E\x78\x94\x4F\x3A\x0F\xED\xF8\xAD"
"\x02\x0E", digest, digestSz), 0);
#endif /* WOLFSSL_SHA224 */
#ifndef NO_SHA256
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha256(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 32);
ExpectIntEQ(XMEMCMP("\x13\xAB\x76\x91\x0C\x37\x86\x8D\xB3\x7E\x30\x0C\xFC"
"\xB0\x2E\x8E\x4A\xD7\xD4\x25\xCC\x3A\xA9\x0F\xA2\xF2"
"\x47\x1E\x62\x6F\x5D\xF2", digest, digestSz), 0);
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha384(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 48);
ExpectIntEQ(XMEMCMP("\x9E\xCB\x07\x0C\x11\x76\x3F\x23\xC3\x25\x0E\xC4\xB7"
"\x28\x77\x95\x99\xD5\x9D\x7A\xBB\x1A\x9F\xB7\xFD\x25"
"\xC9\x72\x47\x9F\x8F\x86\x76\xD6\x20\x57\x87\xB7\xE7"
"\xCD\xFB\xC2\xCC\x9F\x2B\xC5\x41\xAB",
digest, digestSz), 0);
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha512(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 64);
ExpectIntEQ(XMEMCMP("\xD4\x21\x0C\x8B\x60\x6F\xF4\xBF\x07\x2F\x26\xCC\xAD"
"\xBC\x06\x0B\x34\x78\x8B\x4F\xD6\xC0\x42\xF1\x33\x10"
"\x6C\x4F\x1E\x55\x59\xDD\x2A\x9F\x15\x88\x62\xF8\x60"
"\xA3\x99\x91\xE2\x08\x7B\xF7\x95\x3A\xB0\x92\x48\x60"
"\x88\x8B\x5B\xB8\x5F\xE9\xB6\xB1\x96\xE3\xB5\xF0",
digest, digestSz), 0);
#endif /* WOLFSSL_SHA512 */
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_224(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 28);
ExpectIntEQ(XMEMCMP("\xdc\x53\x25\x3f\xc0\x9d\x2b\x0c\x7f\x59\x11\x17\x08"
"\x5c\xe8\x43\x31\x01\x5a\xb3\xe3\x08\x37\x71\x26\x0b"
"\x29\x0f", digest, digestSz), 0);
#endif
#ifndef WOLFSSL_NOSHA3_256
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_256(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 32);
ExpectIntEQ(XMEMCMP("\x0f\x00\x89\x82\x15\xce\xd6\x45\x01\x83\xce\xc8\x35"
"\xab\x71\x07\xc9\xfe\x61\x22\x38\xf9\x09\xad\x35\x65"
"\x43\x77\x24\xd4\x1e\xf4", digest, digestSz), 0);
#endif
#ifndef WOLFSSL_NOSHA3_384
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_384(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 48);
ExpectIntEQ(XMEMCMP("\x0f\x6a\xc0\xfb\xc3\xf2\x80\xb1\xb4\x04\xb6\xc8\x45"
"\x23\x3b\xb4\xbe\xc6\xea\x85\x07\xca\x8c\x71\xbb\x6e"
"\x79\xf6\xf9\x2b\x98\xf5\xef\x11\x39\xd4\x5d\xd3\xca"
"\xc0\xe6\x81\xf7\x73\xf9\x85\x5d\x4f",
digest, digestSz), 0);
#endif
#ifndef WOLFSSL_NOSHA3_512
ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_512(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 64);
ExpectIntEQ(XMEMCMP("\x3e\x77\xe3\x59\x42\x89\xed\xc3\xa4\x26\x3d\xa4\x75"
"\xd2\x84\x8c\xb2\xf3\x25\x04\x47\x61\xce\x1c\x42\x86"
"\xcd\xf4\x56\xaa\x2f\x84\xb1\x3b\x18\xed\xe6\xd6\x48"
"\x15\xb0\x29\xc5\x9d\x32\xef\xdd\x3e\x09\xf6\xed\x9e"
"\x70\xbc\x1c\x63\xf7\x3b\x3e\xe1\xdc\x84\x9c\x1c",
digest, digestSz), 0);
#endif
#endif
#if !defined(NO_MD5) && (!defined(HAVE_FIPS_VERSION) || \
HAVE_FIPS_VERSION <= 2)
ExpectIntEQ((test_HMAC_CTX_helper(EVP_md5(), digest, &digestSz)),
TEST_SUCCESS);
ExpectIntEQ(digestSz, 16);
ExpectIntEQ(XMEMCMP("\xB7\x27\xC4\x41\xE5\x2E\x62\xBA\x54\xED\x72\x70\x9F"
"\xE4\x98\xDD", digest, digestSz), 0);
#endif /* !NO_MD5 */
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && (!defined(NO_SHA256) || \
defined(WOLFSSL_SHA224) || defined(WOLFSSL_SHA384) || \
defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3))
static int test_openssl_hmac(const WOLFSSL_EVP_MD* md, int md_len)
{
EXPECT_DECLS;
static const unsigned char key[] = "simple test key";
HMAC_CTX* hmac = NULL;
ENGINE* e = NULL;
unsigned char hash[WC_MAX_DIGEST_SIZE];
unsigned int len;
ExpectNotNull(hmac = HMAC_CTX_new());
HMAC_CTX_init(hmac);
#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
((! defined(HAVE_FIPS_VERSION)) || \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2)))
/* Get size on object that hasn't had a digest set - MD5. */
ExpectIntEQ(HMAC_size(hmac), 16);
ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 1);
ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 1);
ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 1);
#else
ExpectIntEQ(HMAC_size(hmac), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 0);
ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 0);
ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 0);
#endif
ExpectIntEQ(HMAC_Init_ex(NULL, (void*)key, (int)sizeof(key), md, e), 0);
ExpectIntEQ(HMAC_Init_ex(hmac, (void*)key, (int)sizeof(key), md, e), 1);
/* reusing test key as data to hash */
ExpectIntEQ(HMAC_Update(NULL, key, (int)sizeof(key)), 0);
ExpectIntEQ(HMAC_Update(hmac, key, (int)sizeof(key)), 1);
ExpectIntEQ(HMAC_Update(hmac, key, 0), 1);
ExpectIntEQ(HMAC_Update(hmac, NULL, 0), 1);
ExpectIntEQ(HMAC_Update(hmac, NULL, (int)sizeof(key)), 1);
ExpectIntEQ(HMAC_Final(NULL, NULL, &len), 0);
ExpectIntEQ(HMAC_Final(hmac, NULL, &len), 0);
ExpectIntEQ(HMAC_Final(NULL, hash, &len), 0);
ExpectIntEQ(HMAC_Final(hmac, hash, &len), 1);
ExpectIntEQ(HMAC_Final(hmac, hash, NULL), 1);
ExpectIntEQ(len, md_len);
ExpectIntEQ(HMAC_size(NULL), 0);
ExpectIntEQ(HMAC_size(hmac), md_len);
ExpectStrEQ(HMAC_CTX_get_md(hmac), md);
HMAC_cleanup(NULL);
HMAC_cleanup(hmac);
HMAC_CTX_free(hmac);
len = 0;
ExpectNull(HMAC(NULL, key, (int)sizeof(key), NULL, 0, hash, &len));
ExpectNull(HMAC(md, NULL, (int)sizeof(key), NULL, 0, hash, &len));
ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, 0, NULL, &len));
ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, &len));
ExpectIntEQ(len, md_len);
ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, NULL));
/* With data. */
ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, (int)sizeof(key), hash,
&len));
/* With NULL data. */
ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, (int)sizeof(key), hash,
&len));
/* With zero length data. */
ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, 0, hash, &len));
return EXPECT_RESULT();
}
#endif
int test_wolfSSL_HMAC(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && (!defined(NO_SHA256) || \
defined(WOLFSSL_SHA224) || defined(WOLFSSL_SHA384) || \
defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3))
#ifndef NO_SHA256
ExpectIntEQ(test_openssl_hmac(EVP_sha256(), (int)WC_SHA256_DIGEST_SIZE),
TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA224
ExpectIntEQ(test_openssl_hmac(EVP_sha224(), (int)WC_SHA224_DIGEST_SIZE),
TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA384
ExpectIntEQ(test_openssl_hmac(EVP_sha384(), (int)WC_SHA384_DIGEST_SIZE),
TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA512
ExpectIntEQ(test_openssl_hmac(EVP_sha512(), (int)WC_SHA512_DIGEST_SIZE),
TEST_SUCCESS);
#endif
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
ExpectIntEQ(test_openssl_hmac(EVP_sha3_224(),
(int)WC_SHA3_224_DIGEST_SIZE), TEST_SUCCESS);
#endif
#ifndef WOLFSSL_NOSHA3_256
ExpectIntEQ(test_openssl_hmac(EVP_sha3_256(),
(int)WC_SHA3_256_DIGEST_SIZE), TEST_SUCCESS);
#endif
#ifndef WOLFSSL_NOSHA3_384
ExpectIntEQ(test_openssl_hmac(EVP_sha3_384(),
(int)WC_SHA3_384_DIGEST_SIZE), TEST_SUCCESS);
#endif
#ifndef WOLFSSL_NOSHA3_512
ExpectIntEQ(test_openssl_hmac(EVP_sha3_512(),
(int)WC_SHA3_512_DIGEST_SIZE), TEST_SUCCESS);
#endif
#endif
#ifndef NO_SHA
ExpectIntEQ(test_openssl_hmac(EVP_sha1(), (int)WC_SHA_DIGEST_SIZE),
TEST_SUCCESS);
#endif
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_CMAC(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_AES_DIRECT)
int i;
byte key[AES_256_KEY_SIZE];
CMAC_CTX* cmacCtx = NULL;
byte out[AES_BLOCK_SIZE];
#if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192)
size_t outLen = AES_BLOCK_SIZE;
#endif
for (i=0; i < AES_256_KEY_SIZE; ++i) {
key[i] = i;
}
#ifdef WOLFSSL_AES_128
ExpectNotNull(cmacCtx = CMAC_CTX_new());
/* Check CMAC_CTX_get0_cipher_ctx; return value not used. */
ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx));
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
NULL), 1);
/* reusing test key as data to hash */
ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 1);
ExpectIntEQ(outLen, AES_BLOCK_SIZE);
/* No Update works. */
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
NULL), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(),
NULL), 1);
/* Test parameters with CMAC_Update. */
ExpectIntEQ(CMAC_Update(NULL, NULL, 0), 0);
ExpectIntEQ(CMAC_Update(NULL, key, 0), 0);
ExpectIntEQ(CMAC_Update(NULL, NULL, AES_128_KEY_SIZE), 0);
ExpectIntEQ(CMAC_Update(NULL, key, AES_128_KEY_SIZE), 0);
ExpectIntEQ(CMAC_Update(cmacCtx, key, 0), 1);
ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1);
ExpectIntEQ(CMAC_Update(cmacCtx, NULL, AES_128_KEY_SIZE), 1);
/* Test parameters with CMAC_Final. */
ExpectIntEQ(CMAC_Final(NULL, NULL, NULL), 0);
ExpectIntEQ(CMAC_Final(NULL, out, NULL), 0);
ExpectIntEQ(CMAC_Final(NULL, NULL, &outLen), 0);
ExpectIntEQ(CMAC_Final(NULL, out, &outLen), 0);
ExpectIntEQ(CMAC_Final(cmacCtx, NULL, NULL), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, NULL, &outLen), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
CMAC_CTX_free(cmacCtx);
#endif
#ifdef WOLFSSL_AES_192
/* Test parameters with CMAC Init. */
cmacCtx = NULL;
ExpectNotNull(cmacCtx = CMAC_CTX_new());
ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx));
ExpectIntEQ(CMAC_Init(NULL, NULL, 0, NULL, NULL), 0);
ExpectIntEQ(CMAC_Init(NULL, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
NULL), 0);
ExpectIntEQ(CMAC_Init(cmacCtx, NULL, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
NULL), 0);
/* give a key too small for the cipher, verify we get failure */
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_192_cbc(),
NULL), 0);
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, NULL, NULL), 0);
#if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_128)
/* Only AES-CBC supported. */
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_gcm(),
NULL), 0);
#endif
CMAC_CTX_free(cmacCtx);
ExpectNull(CMAC_CTX_get0_cipher_ctx(NULL));
cmacCtx = NULL;
ExpectNotNull(cmacCtx = CMAC_CTX_new());
/* No Init. */
ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 0);
CMAC_CTX_free(cmacCtx);
#endif
/* Test AES-256-CBC */
#ifdef WOLFSSL_AES_256
cmacCtx = NULL;
ExpectNotNull(cmacCtx = CMAC_CTX_new());
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_256_KEY_SIZE, EVP_aes_256_cbc(),
NULL), 1);
ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
CMAC_CTX_free(cmacCtx);
#endif
/* Test AES-192-CBC */
#ifdef WOLFSSL_AES_192
cmacCtx = NULL;
ExpectNotNull(cmacCtx = CMAC_CTX_new());
ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(),
NULL), 1);
ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1);
ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1);
CMAC_CTX_free(cmacCtx);
#endif
cmacCtx = NULL;
ExpectNotNull(cmacCtx = CMAC_CTX_new());
CMAC_CTX_free(cmacCtx);
#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
return EXPECT_RESULT();
}