mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-08-24 05:13:28 +02:00
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.
575 lines
22 KiB
C
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();
|
|
}
|
|
|