Peer review fixes
parent
27f686821b
commit
31bc616dc8
|
|
@ -19,11 +19,11 @@ It is built inside the RealTek AmebaPro2 FreeRTOS SDK (which provides the startu
|
|||
|
||||
- RealTek AmebaPro2 FreeRTOS SDK: https://github.com/Ameba-AIoT/ameba-rtos-pro2
|
||||
- RealTek ASDK 10.3.0 toolchain (GCC 10.3.0): https://github.com/Ameba-AIoT/ameba-toolchain (tag `V10.3.0-ameba-rtos-pro2`). The stock system `arm-none-eabi-gcc` does not build the SDK (newlib/lwip header clashes); use the ASDK toolchain.
|
||||
- wolfSSL with the RealTek HUK port (`wolfcrypt/src/port/realtek/rtl8735b.c` and `wolfssl/wolfcrypt/port/realtek/rtl8735b.h`). Enable with `WOLFSSL_RTL8735B_HUK` and `WOLF_CRYPTO_CB`.
|
||||
- wolfSSL with the RealTek HUK port (`wolfcrypt/src/port/realtek/rtl8735b.c` and `wolfssl/wolfcrypt/port/realtek/rtl8735b.h`). Enable with `WOLFSSL_RTL8735B_HUK` and `WOLF_CRYPTO_CB`. This example's `user_settings.h` also defines `WOLFSSL_RTL8735B_AES` (the plaintext-key AES device), so the wolfSSL tree must be new enough to provide `wc_Rtl8735b_AesRegister` / `WC_RTL8735B_AES_DEVID`; remove that define to build against an older HUK-only port.
|
||||
|
||||
## Files
|
||||
|
||||
- `main.c` -- the example application (a FreeRTOS task that registers the HUK device and runs the AES-GCM/ECB/CBC/CTR checks plus unaligned-buffer GCM, in-place/multi-call CBC, non-12-byte-IV rejection, HMAC-SHA256, and HUK-bound ECDSA sign + HW verify checks).
|
||||
- `main.c` -- the example application (a FreeRTOS task that registers the HUK device and runs the AES-GCM/ECB/CBC/CTR checks plus unaligned-buffer GCM, in-place/multi-call CBC, non-12-byte-IV rejection, HMAC-SHA256, and HUK-bound ECDSA sign + HW verify checks). With `WOLFSSL_RTL8735B_AES` it also registers the plaintext-key AES device and runs its GCM KAT + coexistence, ECB FIPS-197 KAT, unaligned-buffer, and non-12-byte-IV checks.
|
||||
- `user_settings.h` -- a lean wolfCrypt configuration for this example.
|
||||
- `wolfcrypt_huk.cmake` -- wiring that adds wolfCrypt + the RealTek HUK port to the SDK app build.
|
||||
- `test/` -- a separate `wolfcrypt_test` + `wolfcrypt_benchmark` example for this target with three backend modes (pure C, Thumb-2 / SP Cortex-M, and RealTek hardware offload); see `test/README.md`.
|
||||
|
|
@ -57,6 +57,7 @@ Remove the J27 jumper and reset to boot. The console (UART, 115200) prints:
|
|||
=== wolfCrypt AmebaPro2 (RTL8735B) HUK example ===
|
||||
[PASS] wolfCrypt_Init
|
||||
[PASS] wc_Rtl8735b_HukRegister
|
||||
[PASS] wc_Rtl8735b_AesRegister
|
||||
== AES-GCM (full payload) under HUK-derived key ==
|
||||
[PASS] AesInit(devId=WC_HUK_DEVID)
|
||||
[PASS] AesGcmSetKey(seed,32)
|
||||
|
|
@ -77,6 +78,23 @@ Remove the J27 jumper and reset to boot. The console (UART, 115200) prints:
|
|||
[PASS] verify with software public key
|
||||
[PASS] HW ECDSA verify (good sig)
|
||||
[PASS] HW ECDSA verify (tampered -> reject)
|
||||
== AES-GCM with a plaintext key (devId=WC_RTL8735B_AES_DEVID) ==
|
||||
[PASS] AesInit(devId=WC_RTL8735B_AES_DEVID)
|
||||
[PASS] AesGcmSetKey(plaintext 128-bit key)
|
||||
[PASS] AesGcmEncrypt
|
||||
[PASS] ciphertext matches published vector
|
||||
[PASS] tag matches published vector
|
||||
[PASS] AesGcmDecrypt verifies
|
||||
[PASS] plaintext round-trips
|
||||
[PASS] tampered tag -> AES_GCM_AUTH_E
|
||||
[PASS] plaintext-key encrypt (256-bit)
|
||||
[PASS] HUK-seed encrypt (same 32 bytes)
|
||||
[PASS] plaintext CT != HUK CT (distinct keys per devId)
|
||||
== AES-ECB with a plaintext key (FIPS-197 KAT) ==
|
||||
[PASS] ciphertext matches FIPS-197 vector
|
||||
[PASS] AesEcb round-trip
|
||||
== AES-GCM plaintext key, UNALIGNED buffers (port bounces) == ... round-trip PASS
|
||||
== AES-GCM plaintext key, non-12-byte IV must hard-fail == ... 16-byte IV rejected PASS
|
||||
=== done ===
|
||||
```
|
||||
|
||||
|
|
|
|||
389
rtl8735b/main.c
389
rtl8735b/main.c
|
|
@ -7,6 +7,12 @@
|
|||
* (port bounce path), in-place multi-call CBC, and a non-12-byte GCM IV that
|
||||
* must hard-fail (no silent software fallback).
|
||||
*
|
||||
* With WOLFSSL_RTL8735B_AES also enabled it registers a second crypto-callback
|
||||
* device (WC_RTL8735B_AES_DEVID) that runs a caller-supplied plaintext AES key
|
||||
* directly on the HW engine (no HUK binding), selected per Aes by devId, and
|
||||
* exercises it with AES-GCM (published KAT + coexistence), an AES-ECB FIPS-197
|
||||
* KAT, the unaligned-buffer bounce path, and non-12-byte-IV rejection.
|
||||
*
|
||||
* Build: configure with -DEXAMPLE=wolfcrypt_huk (see wolfcrypt_huk.cmake).
|
||||
*/
|
||||
|
||||
|
|
@ -126,119 +132,6 @@ static void huk_gcm_test(void)
|
|||
ForceZero(seed, sizeof(seed)); /* scrub key material before return */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_RTL8735B_AES
|
||||
/* AES-GCM with a plaintext key through the second device (WC_RTL8735B_AES_DEVID).
|
||||
* Unlike the HUK device, the key bytes are the actual AES key, so the output
|
||||
* matches a published GCM vector. Then the same 32 key bytes are run through
|
||||
* both devices to show they coexist and are selected per Aes by devId: the
|
||||
* plaintext-key ciphertext differs from the HUK device-bound ciphertext. */
|
||||
static void plain_gcm_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
/* McGrew & Viega GCM test case 3: 128-bit key, 64-byte payload, no AAD. */
|
||||
static const byte katKey[16] = {
|
||||
0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,
|
||||
0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08
|
||||
};
|
||||
static const byte katIv[12] = {
|
||||
0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88
|
||||
};
|
||||
static const byte katPt[64] = {
|
||||
0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,
|
||||
0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
|
||||
0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,
|
||||
0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
|
||||
0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,
|
||||
0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
|
||||
0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,
|
||||
0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55
|
||||
};
|
||||
static const byte katCt[64] = {
|
||||
0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,
|
||||
0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
|
||||
0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,
|
||||
0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
|
||||
0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,
|
||||
0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
|
||||
0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,
|
||||
0x3d,0x58,0xe0,0x91,0x47,0x3f,0x59,0x85
|
||||
};
|
||||
static const byte katTag[16] = {
|
||||
0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,
|
||||
0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4
|
||||
};
|
||||
/* HAL crypto engine requires 32-byte-aligned key/iv/buffers. */
|
||||
byte key[32] __attribute__((aligned(32)));
|
||||
byte iv[12] __attribute__((aligned(32)));
|
||||
byte pt[64] __attribute__((aligned(32)));
|
||||
byte ct[64] __attribute__((aligned(32)));
|
||||
byte ctHuk[64] __attribute__((aligned(32)));
|
||||
byte dec[64] __attribute__((aligned(32)));
|
||||
byte tag[16] __attribute__((aligned(32)));
|
||||
byte tagHuk[16] __attribute__((aligned(32)));
|
||||
int ret;
|
||||
|
||||
dbg_printf("\r\n== AES-GCM with a plaintext key "
|
||||
"(devId=WC_RTL8735B_AES_DEVID) ==\r\n");
|
||||
|
||||
/* Known-answer test: the plaintext key must reproduce the published vector. */
|
||||
memcpy(iv, katIv, sizeof(iv));
|
||||
memcpy(pt, katPt, sizeof(pt));
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(devId=WC_RTL8735B_AES_DEVID)", ret == 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmSetKey(&aes, katKey, sizeof(katKey));
|
||||
CHECK("AesGcmSetKey(plaintext 128-bit key)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("AesGcmEncrypt", ret == 0);
|
||||
}
|
||||
CHECK("ciphertext matches published vector",
|
||||
ret == 0 && memcmp(ct, katCt, sizeof(katCt)) == 0);
|
||||
CHECK("tag matches published vector",
|
||||
ret == 0 && memcmp(tag, katTag, sizeof(katTag)) == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmDecrypt(&aes, dec, ct, sizeof(ct), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("AesGcmDecrypt verifies", ret == 0);
|
||||
CHECK("plaintext round-trips", memcmp(dec, pt, sizeof(pt)) == 0);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
|
||||
/* Coexistence: same 32 key bytes -> plaintext device vs HUK device produce
|
||||
* different ciphertext (one uses the key verbatim, the other as a seed). */
|
||||
memset(key, 0x5A, sizeof(key));
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(key));
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
CHECK("plaintext-key encrypt (256-bit)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesInit(&aes, NULL, WC_HUK_DEVID);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(key));
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ctHuk, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tagHuk, sizeof(tagHuk), NULL, 0);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
CHECK("HUK-seed encrypt (same 32 bytes)", ret == 0);
|
||||
CHECK("plaintext CT != HUK CT (distinct keys per devId)",
|
||||
ret == 0 && memcmp(ct, ctHuk, sizeof(ct)) != 0);
|
||||
}
|
||||
ForceZero(key, sizeof(key)); /* scrub key material before return */
|
||||
}
|
||||
#endif /* WOLFSSL_RTL8735B_AES */
|
||||
|
||||
static void huk_ecb_cbc_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
|
|
@ -677,9 +570,263 @@ cleanup:
|
|||
ForceZero(seed, sizeof(seed));
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_RTL8735B_AES
|
||||
/* AES-GCM with a plaintext key through the second device (WC_RTL8735B_AES_DEVID).
|
||||
* Unlike the HUK device, the key bytes are the actual AES key, so the output
|
||||
* matches a published GCM vector. Then the same 32 key bytes are run through
|
||||
* both devices to show they coexist and are selected per Aes by devId: the
|
||||
* plaintext-key ciphertext differs from the HUK device-bound ciphertext. */
|
||||
static void plain_gcm_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
/* McGrew & Viega GCM test case 3: 128-bit key, 64-byte payload, no AAD. */
|
||||
static const byte katKey[16] = {
|
||||
0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,
|
||||
0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08
|
||||
};
|
||||
static const byte katIv[12] = {
|
||||
0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88
|
||||
};
|
||||
static const byte katPt[64] = {
|
||||
0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,
|
||||
0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
|
||||
0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,
|
||||
0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
|
||||
0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,
|
||||
0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
|
||||
0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,
|
||||
0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55
|
||||
};
|
||||
static const byte katCt[64] = {
|
||||
0x42,0x83,0x1e,0xc2,0x21,0x77,0x74,0x24,
|
||||
0x4b,0x72,0x21,0xb7,0x84,0xd0,0xd4,0x9c,
|
||||
0xe3,0xaa,0x21,0x2f,0x2c,0x02,0xa4,0xe0,
|
||||
0x35,0xc1,0x7e,0x23,0x29,0xac,0xa1,0x2e,
|
||||
0x21,0xd5,0x14,0xb2,0x54,0x66,0x93,0x1c,
|
||||
0x7d,0x8f,0x6a,0x5a,0xac,0x84,0xaa,0x05,
|
||||
0x1b,0xa3,0x0b,0x39,0x6a,0x0a,0xac,0x97,
|
||||
0x3d,0x58,0xe0,0x91,0x47,0x3f,0x59,0x85
|
||||
};
|
||||
static const byte katTag[16] = {
|
||||
0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,
|
||||
0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4
|
||||
};
|
||||
/* HAL crypto engine requires 32-byte-aligned key/iv/buffers. */
|
||||
byte key[32] __attribute__((aligned(32)));
|
||||
byte iv[12] __attribute__((aligned(32)));
|
||||
byte pt[64] __attribute__((aligned(32)));
|
||||
byte ct[64] __attribute__((aligned(32)));
|
||||
byte ctHuk[64] __attribute__((aligned(32)));
|
||||
byte dec[64] __attribute__((aligned(32)));
|
||||
byte tag[16] __attribute__((aligned(32)));
|
||||
byte tagHuk[16] __attribute__((aligned(32)));
|
||||
int ret;
|
||||
|
||||
dbg_printf("\r\n== AES-GCM with a plaintext key "
|
||||
"(devId=WC_RTL8735B_AES_DEVID) ==\r\n");
|
||||
|
||||
/* Known-answer test: the plaintext key must reproduce the published vector.
|
||||
* Stage the vector key into the 32-byte-aligned buffer the HAL DMA wants. */
|
||||
memcpy(key, katKey, sizeof(katKey));
|
||||
memcpy(iv, katIv, sizeof(iv));
|
||||
memcpy(pt, katPt, sizeof(pt));
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(devId=WC_RTL8735B_AES_DEVID)", ret == 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(katKey));
|
||||
CHECK("AesGcmSetKey(plaintext 128-bit key)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("AesGcmEncrypt", ret == 0);
|
||||
}
|
||||
CHECK("ciphertext matches published vector",
|
||||
ret == 0 && memcmp(ct, katCt, sizeof(katCt)) == 0);
|
||||
CHECK("tag matches published vector",
|
||||
ret == 0 && memcmp(tag, katTag, sizeof(katTag)) == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmDecrypt(&aes, dec, ct, sizeof(ct), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("AesGcmDecrypt verifies", ret == 0);
|
||||
CHECK("plaintext round-trips", memcmp(dec, pt, sizeof(pt)) == 0);
|
||||
|
||||
/* Negative: a tampered tag must be rejected by the HW decrypt-verify. */
|
||||
tag[0] ^= 0xFFu;
|
||||
ret = wc_AesGcmDecrypt(&aes, dec, ct, sizeof(ct), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("tampered tag -> AES_GCM_AUTH_E", ret == AES_GCM_AUTH_E);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
|
||||
/* Coexistence: same 32 key bytes -> plaintext device vs HUK device produce
|
||||
* different ciphertext (one uses the key verbatim, the other as a seed). */
|
||||
memset(key, 0x5A, sizeof(key));
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(plaintext devId)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(key));
|
||||
CHECK("AesGcmSetKey(plaintext 256-bit key)", ret == 0);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
CHECK("plaintext-key encrypt (256-bit)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesInit(&aes, NULL, WC_HUK_DEVID);
|
||||
CHECK("AesInit(HUK devId)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(key));
|
||||
CHECK("AesGcmSetKey(HUK seed, same 32 bytes)", ret == 0);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(&aes, ctHuk, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tagHuk, sizeof(tagHuk), NULL, 0);
|
||||
}
|
||||
wc_AesFree(&aes);
|
||||
CHECK("HUK-seed encrypt (same 32 bytes)", ret == 0);
|
||||
CHECK("plaintext CT != HUK CT (distinct keys per devId)",
|
||||
ret == 0 && memcmp(ct, ctHuk, sizeof(ct)) != 0);
|
||||
}
|
||||
ForceZero(key, sizeof(key)); /* scrub key material before return */
|
||||
}
|
||||
|
||||
/* AES-ECB with a plaintext key: FIPS-197 appendix C.1 known-answer vector. The
|
||||
* plaintext device runs the key verbatim, so the HW output must match the
|
||||
* published ciphertext exactly (the HUK device cannot -- its key is derived). */
|
||||
static void plain_ecb_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
static const byte katKey[16] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
|
||||
};
|
||||
static const byte katPt[16] = {
|
||||
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
|
||||
0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
|
||||
};
|
||||
static const byte katCt[16] = {
|
||||
0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30,
|
||||
0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a
|
||||
};
|
||||
byte key[16] __attribute__((aligned(32)));
|
||||
byte pt[16] __attribute__((aligned(32)));
|
||||
byte ct[16] __attribute__((aligned(32)));
|
||||
byte dec[16] __attribute__((aligned(32)));
|
||||
int ret;
|
||||
|
||||
memcpy(key, katKey, sizeof(key));
|
||||
memcpy(pt, katPt, sizeof(pt));
|
||||
|
||||
dbg_printf("\r\n== AES-ECB with a plaintext key (FIPS-197 KAT) ==\r\n");
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(devId=WC_RTL8735B_AES_DEVID)", ret == 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
ret = wc_AesSetKey(&aes, key, sizeof(key), NULL, AES_ENCRYPTION);
|
||||
CHECK("AesSetKey(ECB enc)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesEcbEncrypt(&aes, ct, pt, sizeof(pt));
|
||||
CHECK("AesEcbEncrypt", ret == 0);
|
||||
}
|
||||
CHECK("ciphertext matches FIPS-197 vector",
|
||||
ret == 0 && memcmp(ct, katCt, sizeof(katCt)) == 0);
|
||||
ret = wc_AesSetKey(&aes, key, sizeof(key), NULL, AES_DECRYPTION);
|
||||
CHECK("AesSetKey(ECB dec)", ret == 0);
|
||||
if (ret == 0) {
|
||||
ret = wc_AesEcbDecrypt(&aes, dec, ct, sizeof(ct));
|
||||
}
|
||||
CHECK("AesEcb round-trip", ret == 0 && memcmp(dec, pt, sizeof(pt)) == 0);
|
||||
wc_AesFree(&aes);
|
||||
ForceZero(key, sizeof(key)); /* scrub key material before return */
|
||||
}
|
||||
|
||||
/* AES-GCM with a plaintext key over deliberately-unaligned caller buffers, so
|
||||
* the port's bounce-to-aligned path is exercised for the second device too. */
|
||||
static void plain_gcm_unaligned_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
/* 32-byte-aligned backing; the +1 views below are deliberately unaligned. */
|
||||
byte buf[6][48] __attribute__((aligned(32)));
|
||||
byte* key = buf[0] + 1;
|
||||
byte* iv = buf[1] + 1;
|
||||
byte* pt = buf[2] + 1;
|
||||
byte* ct = buf[3] + 1;
|
||||
byte* dec = buf[4] + 1;
|
||||
byte* tag = buf[5] + 1;
|
||||
int ret;
|
||||
|
||||
memset(key, 0x5A, 16); memset(iv, 0x11, 12);
|
||||
memset(pt, 0x33, 32);
|
||||
|
||||
dbg_printf("\r\n== AES-GCM plaintext key, UNALIGNED buffers "
|
||||
"(port bounces) ==\r\n");
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(devId=WC_RTL8735B_AES_DEVID)", ret == 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmSetKey(&aes, key, 16);
|
||||
CHECK("AesGcmSetKey (unaligned key)", ret == 0);
|
||||
if (ret != 0) {
|
||||
wc_AesFree(&aes);
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, 32, iv, 12, tag, 16, NULL, 0);
|
||||
CHECK("AesGcmEncrypt (unaligned)", ret == 0);
|
||||
ret = wc_AesGcmDecrypt(&aes, dec, ct, 32, iv, 12, tag, 16, NULL, 0);
|
||||
CHECK("AesGcmDecrypt (unaligned) verifies", ret == 0);
|
||||
CHECK("unaligned round-trip", memcmp(dec, pt, 32) == 0);
|
||||
wc_AesFree(&aes);
|
||||
ForceZero(key, 16); /* scrub key material before return */
|
||||
}
|
||||
|
||||
/* A non-12-byte GCM IV must hard-fail on the plaintext device too, NOT silently
|
||||
* fall back to software GCM (regression for the IV hard-error contract). */
|
||||
static void plain_gcm_badiv_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
byte key[16] __attribute__((aligned(32)));
|
||||
byte iv[16] __attribute__((aligned(32))); /* 16 bytes, not the supported 12 */
|
||||
byte pt[16] __attribute__((aligned(32)));
|
||||
byte ct[16] __attribute__((aligned(32)));
|
||||
byte tag[16] __attribute__((aligned(32)));
|
||||
int ret;
|
||||
|
||||
memset(key, 0x5A, sizeof(key)); memset(iv, 0x11, sizeof(iv));
|
||||
memset(pt, 0x33, sizeof(pt));
|
||||
|
||||
dbg_printf("\r\n== AES-GCM plaintext key, non-12-byte IV must hard-fail "
|
||||
"==\r\n");
|
||||
ret = wc_AesInit(&aes, NULL, WC_RTL8735B_AES_DEVID);
|
||||
CHECK("AesInit(devId=WC_RTL8735B_AES_DEVID)", ret == 0);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmSetKey(&aes, key, sizeof(key));
|
||||
CHECK("AesGcmSetKey(key,16)", ret == 0);
|
||||
if (ret != 0) {
|
||||
wc_AesFree(&aes);
|
||||
return;
|
||||
}
|
||||
ret = wc_AesGcmEncrypt(&aes, ct, pt, sizeof(pt), iv, sizeof(iv),
|
||||
tag, sizeof(tag), NULL, 0);
|
||||
CHECK("16-byte IV rejected (no silent SW fallback)", ret != 0);
|
||||
wc_AesFree(&aes);
|
||||
ForceZero(key, sizeof(key)); /* scrub key material before return */
|
||||
}
|
||||
#endif /* WOLFSSL_RTL8735B_AES */
|
||||
|
||||
static void wolf_huk_thread(void* param)
|
||||
{
|
||||
int ret;
|
||||
#ifdef WOLFSSL_RTL8735B_AES
|
||||
int aesRet = 0;
|
||||
#endif
|
||||
(void)param;
|
||||
|
||||
dbg_printf("\r\n=== wolfCrypt AmebaPro2 (RTL8735B) HUK example ===\r\n");
|
||||
|
|
@ -694,9 +841,12 @@ static void wolf_huk_thread(void* param)
|
|||
CHECK("wc_Rtl8735b_HukRegister", ret == 0);
|
||||
}
|
||||
#ifdef WOLFSSL_RTL8735B_AES
|
||||
/* The plaintext-key AES device is an optional add-on; track its registration
|
||||
* in its own result so a failure only skips its demo -- it must never
|
||||
* suppress the HUK suite or leak the HUK device registration. */
|
||||
if (ret == 0) {
|
||||
ret = wc_Rtl8735b_AesRegister(WC_RTL8735B_AES_DEVID);
|
||||
CHECK("wc_Rtl8735b_AesRegister", ret == 0);
|
||||
aesRet = wc_Rtl8735b_AesRegister(WC_RTL8735B_AES_DEVID);
|
||||
CHECK("wc_Rtl8735b_AesRegister", aesRet == 0);
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
|
|
@ -709,8 +859,13 @@ static void wolf_huk_thread(void* param)
|
|||
huk_hmac_test();
|
||||
huk_ecdsa_test();
|
||||
#ifdef WOLFSSL_RTL8735B_AES
|
||||
plain_gcm_test();
|
||||
wc_Rtl8735b_AesUnRegister(WC_RTL8735B_AES_DEVID);
|
||||
if (aesRet == 0) {
|
||||
plain_gcm_test();
|
||||
plain_ecb_test();
|
||||
plain_gcm_unaligned_test();
|
||||
plain_gcm_badiv_test();
|
||||
wc_Rtl8735b_AesUnRegister(WC_RTL8735B_AES_DEVID);
|
||||
}
|
||||
#endif
|
||||
wc_Rtl8735b_HukUnRegister(WC_HUK_DEVID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* user_settings.h -- wolfCrypt config for the AmebaPro2 (RTL8735B) HUK example
|
||||
* built inside the RealTek FreeRTOS SDK. HUK crypto-callback demo: AES
|
||||
* (GCM/ECB/CBC/CTR), HMAC-SHA256, and ECDSA P-256. */
|
||||
* (GCM/ECB/CBC/CTR), HMAC-SHA256, and ECDSA P-256. Also enables the plaintext-
|
||||
* key AES device (WOLFSSL_RTL8735B_AES) -- a second crypto-callback device that
|
||||
* runs a caller-supplied AES key directly on the HW engine (no HUK binding). */
|
||||
|
||||
#ifndef RTL8735B_HUK_USER_SETTINGS_H
|
||||
#define RTL8735B_HUK_USER_SETTINGS_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue