Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,7 @@ WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
WOLFSSL_NO_ETM_ALERT
WOLFSSL_NO_FCHMOD
WOLFSSL_NO_FENCE
WOLFSSL_NO_HMAC_KEY_LOCATION
WOLFSSL_NO_ISSUERHASH_TDPEER
WOLFSSL_NO_KCAPI_AES_CBC
WOLFSSL_NO_KCAPI_HMAC_SHA1
Expand Down
177 changes: 177 additions & 0 deletions tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -12524,6 +12524,183 @@ int test_wc_CryptoCb_AesDirect(void)

#endif /* WC_AES_DIRECT_CRYPTO_CB && WOLFSSL_AES_128 && HAVE_AES_DECRYPT */

/*----------------------------------------------------------------------------*
| CryptoCB SetKey location API
*----------------------------------------------------------------------------*/

#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) && \
!defined(NO_AES)

#include <wolfssl/wolfcrypt/cryptocb.h>

int test_wc_CryptoCb_SetKeyLocation(void)
{
EXPECT_DECLS;
Aes aes;
wc_CryptoInfo info;

XMEMSET(&aes, 0, sizeof(aes));
XMEMSET(&info, 0, sizeof(info));
info.setkey.type = WC_SETKEY_AES;
info.setkey.obj = &aes;

/* Bad arguments */
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(NULL, WC_KEY_HW_STORED),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, WC_KEY_HW_STORED),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
info.algo_type = WC_ALGO_TYPE_SETKEY;
info.setkey.obj = NULL;
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, WC_KEY_HW_STORED),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
info.setkey.obj = &aes;
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, 2),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* AES accepts both locations */
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, WC_KEY_HW_STORED), 0);
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, WC_KEY_SW_STORED), 0);

/* A key type with no location support */
info.setkey.type = WC_SETKEY_NONE;
ExpectIntEQ(wc_CryptoCb_SetKeyLocation(&info, WC_KEY_HW_STORED),
WC_NO_ERR_TRACE(NOT_COMPILED_IN));

return EXPECT_RESULT();
}

#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY && !NO_AES */

/*----------------------------------------------------------------------------*
| CryptoCB AES SetKey: device-only key
*----------------------------------------------------------------------------*/

#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) && \
defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) && \
defined(WOLFSSL_AES_128) && defined(WOLFSSL_AES_REQUIRE_KEY_SET)

#include <wolfssl/wolfcrypt/cryptocb.h>

#define TEST_CRYPTOCB_AES_NOSW_DEVID 16

/* Set to make the mock decline SetKey, so software keeps the key. */
static int test_CryptoCb_AesNoSw_Decline = 0;

/* Mock device that keeps the key in hardware: the generic SetKey succeeds and
* marks the key HW stored. Every other request is declined,
* including the AES-specific SetKey, so the generic one is used. */
static int test_CryptoCb_AesNoSw_Cb(int devId, wc_CryptoInfo* info,
void* ctx)
{
(void)ctx;
if (devId != TEST_CRYPTOCB_AES_NOSW_DEVID || info == NULL)
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
if (info->algo_type == WC_ALGO_TYPE_SETKEY &&
info->setkey.type == WC_SETKEY_AES &&
!test_CryptoCb_AesNoSw_Decline) {
return wc_CryptoCb_SetKeyLocation(info, WC_KEY_HW_STORED);
}
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
}

int test_wc_CryptoCb_AesNoSwKey(void)
{
EXPECT_DECLS;
Aes aes;
WOLFSSL_SMALL_STACK_STATIC const byte key[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
byte iv[WC_AES_BLOCK_SIZE];
byte in[WC_AES_BLOCK_SIZE];
byte out[WC_AES_BLOCK_SIZE];
#ifdef WOLFSSL_AES_XTS
XtsAes xts;
WOLFSSL_SMALL_STACK_STATIC const byte xtsKey[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
#endif

XMEMSET(iv, 0, sizeof(iv));
XMEMSET(in, 0, sizeof(in));

ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_CRYPTOCB_AES_NOSW_DEVID,
test_CryptoCb_AesNoSw_Cb, NULL), 0);
XMEMSET(&aes, 0, sizeof(aes));
ExpectIntEQ(wc_AesInit(&aes, NULL, TEST_CRYPTOCB_AES_NOSW_DEVID), 0);

/* The device took the key; software has none to fall back on */
ExpectIntEQ(wc_AesSetKey(&aes, key, (word32)sizeof(key), iv,
AES_ENCRYPTION), 0);
ExpectIntEQ(wc_AesCbcEncrypt(&aes, out, in, sizeof(in)),
WC_NO_ERR_TRACE(MISSING_KEY));

ExpectIntEQ(wc_AesSetKey(&aes, key, (word32)sizeof(key), iv,
AES_DECRYPTION), 0);
ExpectIntEQ(wc_AesCbcDecrypt(&aes, out, in, sizeof(in)),
WC_NO_ERR_TRACE(MISSING_KEY));

#if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)
/* Streaming GCM has no device path, so a HW-stored key must not pass */
ExpectIntEQ(wc_AesGcmSetKey(&aes, key, (word32)sizeof(key)), 0);
ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0),
WC_NO_ERR_TRACE(MISSING_KEY));
/* Init caches the IV until a usable key is set; data still fails */
ExpectIntEQ(wc_AesGcmInit(&aes, NULL, 0, iv, GCM_NONCE_MID_SZ), 0);
ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0),
WC_NO_ERR_TRACE(MISSING_KEY));
ExpectIntEQ(wc_AesGcmInit(&aes, key, (word32)sizeof(key), iv,
GCM_NONCE_MID_SZ), 0);
ExpectIntEQ(wc_AesGcmEncryptUpdate(&aes, out, in, sizeof(in), NULL, 0),
WC_NO_ERR_TRACE(MISSING_KEY));

/* A HW-stored rekey must also stop a streaming GCM started in software */
test_CryptoCb_AesNoSw_Decline = 1;
ExpectIntEQ(wc_AesGcmInit(&aes, key, (word32)sizeof(key), iv,
GCM_NONCE_MID_SZ), 0);
test_CryptoCb_AesNoSw_Decline = 0;
ExpectIntEQ(wc_AesSetKey(&aes, key, (word32)sizeof(key), iv,
AES_ENCRYPTION), 0);
ExpectIntEQ(wc_AesGcmEncryptFinal(&aes, out, sizeof(out)),
WC_NO_ERR_TRACE(MISSING_KEY));
#endif

/* A new key the device declines is kept in software and must work */
test_CryptoCb_AesNoSw_Decline = 1;
ExpectIntEQ(wc_AesSetKey(&aes, key, (word32)sizeof(key), iv,
AES_ENCRYPTION), 0);
ExpectIntEQ(wc_AesCbcEncrypt(&aes, out, in, sizeof(in)), 0);
test_CryptoCb_AesNoSw_Decline = 0;

#ifdef WOLFSSL_AES_XTS
/* A HW-stored key replacing a software one must not leave the old
* schedule usable: XTS only checks rounds */
XMEMSET(&xts, 0, sizeof(xts));
ExpectIntEQ(wc_AesXtsInit(&xts, NULL, TEST_CRYPTOCB_AES_NOSW_DEVID), 0);
test_CryptoCb_AesNoSw_Decline = 1;
ExpectIntEQ(wc_AesXtsSetKeyNoInit(&xts, xtsKey, (word32)sizeof(xtsKey),
AES_ENCRYPTION), 0);
test_CryptoCb_AesNoSw_Decline = 0;
ExpectIntEQ(wc_AesXtsSetKeyNoInit(&xts, xtsKey, (word32)sizeof(xtsKey),
AES_ENCRYPTION), 0);
ExpectIntEQ(wc_AesXtsEncrypt(&xts, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
wc_AesXtsFree(&xts);
Comment thread
night1rider marked this conversation as resolved.
Resolved
#endif

wc_AesFree(&aes);
wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_AES_NOSW_DEVID);

return EXPECT_RESULT();
}

#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY && HAVE_AES_CBC &&
* HAVE_AES_DECRYPT && WOLFSSL_AES_128 &&
* WOLFSSL_AES_REQUIRE_KEY_SET */

/*----------------------------------------------------------------------------*
| CryptoCB AES SetKey Test
*----------------------------------------------------------------------------*/
Expand Down
21 changes: 21 additions & 0 deletions tests/api/test_aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,25 @@ int test_wc_CryptoCb_AesDirect(void);
#define TEST_CRYPTOCB_AES_DIRECT_DECL
#endif

#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) && \
!defined(NO_AES)
int test_wc_CryptoCb_SetKeyLocation(void);
#define TEST_CRYPTOCB_SETKEY_LOCATION_DECL \
, TEST_DECL_GROUP("aes", test_wc_CryptoCb_SetKeyLocation)
#else
#define TEST_CRYPTOCB_SETKEY_LOCATION_DECL
#endif

#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) && \
defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) && \
defined(WOLFSSL_AES_128) && defined(WOLFSSL_AES_REQUIRE_KEY_SET)
int test_wc_CryptoCb_AesNoSwKey(void);
#define TEST_CRYPTOCB_AES_NOSW_KEY_DECL \
, TEST_DECL_GROUP("aes", test_wc_CryptoCb_AesNoSwKey)
#else
#define TEST_CRYPTOCB_AES_NOSW_KEY_DECL
#endif

#define TEST_AES_DECLS \
TEST_DECL_GROUP("aes", test_wc_AesSetKey), \
TEST_DECL_GROUP("aes", test_wc_AesSetIV), \
Expand Down Expand Up @@ -280,6 +299,8 @@ int test_wc_CryptoCb_AesDirect(void);
TEST_CRYPTOCB_AES_SETKEY_DECL \
TEST_CRYPTOCB_AES_KEYWRAP_DECL \
TEST_CRYPTOCB_AES_DIRECT_DECL \
TEST_CRYPTOCB_SETKEY_LOCATION_DECL \
TEST_CRYPTOCB_AES_NOSW_KEY_DECL \
TEST_CRYPTOCB_TLS13_KEY_ZERO_DECL \
TEST_CRYPTOCB_AESCFB_DECL \
TEST_CRYPTOCB_AESOFB_DECL
Expand Down
64 changes: 64 additions & 0 deletions tests/api/test_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,70 @@ int test_wc_HmacId_NoDevice(void)
return EXPECT_RESULT();
} /* END test_wc_HmacId_NoDevice */

#if !defined(NO_HMAC) && !defined(NO_SHA256) && defined(WOLF_CRYPTO_CB) && \
defined(WOLF_CRYPTO_CB_SETKEY) && \
!defined(WOLFSSL_NO_HMAC_KEY_LOCATION) && !defined(WOLFSSL_KCAPI_HMAC)
#define TEST_HMAC_NOSW_DEVID 0x484d4b48 /* "HMKH" */

/* Set to make the mock decline SetKey, so software keeps the key. */
static int test_hmac_nosw_decline = 0;

/* Mock device that keeps the key in hardware: SetKey succeeds and marks the
* key HW stored. Every HMAC request is declined. */
static int test_hmac_nosw_cb(int cbDevId, wc_CryptoInfo* info, void* ctx)
{
(void)ctx;
if (cbDevId != TEST_HMAC_NOSW_DEVID || info == NULL)
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
if (info->algo_type == WC_ALGO_TYPE_SETKEY &&
info->setkey.type == WC_SETKEY_HMAC && !test_hmac_nosw_decline) {
return wc_CryptoCb_SetKeyLocation(info, WC_KEY_HW_STORED);
}
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
}
#endif

/* A SetKey callback that keeps the key in hardware leaves software with no
* ipad/opad, so a declined update/final must fail rather than MAC with an
* empty key. */
int test_wc_HmacNoSwKey_CryptoCb(void)
{
EXPECT_DECLS;
#if !defined(NO_HMAC) && !defined(NO_SHA256) && defined(WOLF_CRYPTO_CB) && \
defined(WOLF_CRYPTO_CB_SETKEY) && \
!defined(WOLFSSL_NO_HMAC_KEY_LOCATION) && !defined(WOLFSSL_KCAPI_HMAC)
Hmac hmac;
byte msg[16];
byte out[WC_SHA256_DIGEST_SIZE];

XMEMSET(msg, 0, sizeof(msg));
XMEMSET(&hmac, 0, sizeof(hmac));

ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_HMAC_NOSW_DEVID,
test_hmac_nosw_cb, NULL), 0);
ExpectIntEQ(wc_HmacInit(&hmac, NULL, TEST_HMAC_NOSW_DEVID), 0);

/* The device took the key; software has none to fall back on */
ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256,
(const byte*)"0123456789abcdef", 16), 0);
ExpectIntEQ(wc_HmacUpdate(&hmac, msg, sizeof(msg)),
WC_NO_ERR_TRACE(MISSING_KEY));
ExpectIntEQ(wc_HmacFinal(&hmac, out), WC_NO_ERR_TRACE(MISSING_KEY));

/* A new key the device declines is kept in software and must work */
test_hmac_nosw_decline = 1;
ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256,
(const byte*)"0123456789abcdef", 16), 0);
ExpectIntEQ(wc_HmacUpdate(&hmac, msg, sizeof(msg)), 0);
ExpectIntEQ(wc_HmacFinal(&hmac, out), 0);
test_hmac_nosw_decline = 0;

wc_HmacFree(&hmac);
wc_CryptoCb_UnRegisterDevice(TEST_HMAC_NOSW_DEVID);
#endif
return EXPECT_RESULT();
} /* END test_wc_HmacNoSwKey_CryptoCb */

/*
* MC/DC: wc_HKDF_Extract_ex()/wc_HKDF_Expand_ex() share the guard shape
* (out == NULL || (inKey == NULL && inKeySz > 0)) at two physical
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_hmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ int test_wc_HmacInit_Label(void);
int test_wc_HmacFree_CryptoCb(void);
int test_wc_HmacId_CryptoCb(void);
int test_wc_HmacId_NoDevice(void);
int test_wc_HmacNoSwKey_CryptoCb(void);
int test_wc_HKDF_NullKeyEdgeCases(void);
int test_wc_Tls13_HKDF_Extract_ZeroLenIkm(void);

Expand Down Expand Up @@ -76,6 +77,7 @@ int test_wc_Tls13_HKDF_Extract_ZeroLenIkm(void);
TEST_DECL_GROUP("hmac", test_wc_HmacFree_CryptoCb), \
TEST_DECL_GROUP("hmac", test_wc_HmacId_CryptoCb), \
TEST_DECL_GROUP("hmac", test_wc_HmacId_NoDevice), \
TEST_DECL_GROUP("hmac", test_wc_HmacNoSwKey_CryptoCb), \
TEST_DECL_GROUP("hmac", test_wc_HKDF_NullKeyEdgeCases), \
TEST_DECL_GROUP("hmac", test_wc_Tls13_HKDF_Extract_ZeroLenIkm)

Expand Down
29 changes: 29 additions & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4637,6 +4637,35 @@ int wc_CryptoCb_SetKey(int devId, int type, void* obj,

return wc_CryptoCb_TranslateErrorCode(ret);
}

/* Lets a SetKey callback say where the key in its info is kept (default
* WC_KEY_SW_STORED), using the setter for the key's algorithm.
* Returns 0, BAD_FUNC_ARG on bad args, NOT_COMPILED_IN for other types. */
int wc_CryptoCb_SetKeyLocation(wc_CryptoInfo* info, int location)
{
if (info == NULL || info->algo_type != WC_ALGO_TYPE_SETKEY ||
info->setkey.obj == NULL) {
return BAD_FUNC_ARG;
}

switch (info->setkey.type) {
#ifndef NO_AES
case WC_SETKEY_AES:
/* The AES key guards already refuse a claimed key with no
* schedule, so there is nothing to record. */
if (location != WC_KEY_SW_STORED && location != WC_KEY_HW_STORED)
return BAD_FUNC_ARG;
return 0;
#endif
#ifdef WC_HMAC_HAVE_KEY_LOCATION
case WC_SETKEY_HMAC:
return wc_HmacSetKeyLocation((Hmac*)info->setkey.obj, location);
#endif
default:
(void)location;
return NOT_COMPILED_IN;
}
}
#endif /* WOLF_CRYPTO_CB_SETKEY */

#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
Expand Down
Loading
Loading