/* test_she.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 #ifdef NO_INLINE #include #else #define WOLFSSL_MISC_INCLUDED #include #endif #include #include #ifdef WOLF_CRYPTO_CB #include #endif #include #include /* Common test vector data */ #if defined(WOLFSSL_SHE) && !defined(NO_AES) static const byte sheTestUid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; static const byte sheTestAuthKey[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; static const byte sheTestNewKey[] = { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; static const byte sheTestExpM1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41 }; static const byte sheTestExpM4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0xb4, 0x72, 0xe8, 0xd8, 0x72, 0x7d, 0x70, 0xd5, 0x72, 0x95, 0xe7, 0x48, 0x49, 0xa2, 0x79, 0x17 }; static const byte sheTestExpM5[] = { 0x82, 0x0d, 0x8d, 0x95, 0xdc, 0x11, 0xb4, 0x66, 0x88, 0x78, 0x16, 0x0c, 0xb2, 0xa4, 0xe2, 0x3e }; #endif int test_wc_SHE_Init(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) wc_SHE she; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectTrue(she.heap == NULL); ExpectIntEQ(she.devId, INVALID_DEVID); wc_SHE_Free(&she); ExpectIntEQ(wc_SHE_Init(NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); #endif return EXPECT_RESULT(); } int test_wc_SHE_Init_Id(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) && defined(WOLF_PRIVATE_KEY_ID) wc_SHE she; unsigned char testId[] = {0x01, 0x02, 0x03, 0x04}; ExpectIntEQ(wc_SHE_Init_Id(&she, testId, (int)sizeof(testId), NULL, INVALID_DEVID), 0); ExpectIntEQ(she.idLen, (int)sizeof(testId)); wc_SHE_Free(&she); ExpectIntEQ(wc_SHE_Init_Id(NULL, testId, (int)sizeof(testId), NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_Init_Id(&she, testId, WC_SHE_MAX_ID_LEN + 1, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BUFFER_E)); ExpectIntEQ(wc_SHE_Init_Id(&she, testId, -1, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BUFFER_E)); #endif return EXPECT_RESULT(); } int test_wc_SHE_Init_Label(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) && defined(WOLF_PRIVATE_KEY_ID) wc_SHE she; ExpectIntEQ(wc_SHE_Init_Label(&she, "test", NULL, INVALID_DEVID), 0); ExpectIntEQ(she.labelLen, 4); wc_SHE_Free(&she); ExpectIntEQ(wc_SHE_Init_Label(NULL, "test", NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_Init_Label(&she, NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_Init_Label(&she, "", NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BUFFER_E)); #endif return EXPECT_RESULT(); } int test_wc_SHE_Free(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) wc_SHE she; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); wc_SHE_Free(&she); ExpectIntEQ(she.devId, 0); wc_SHE_Free(NULL); #endif return EXPECT_RESULT(); } int test_wc_SHE_ImportM1M2M3(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) && \ (defined(WOLF_CRYPTO_CB) && !defined(NO_WC_SHE_IMPORT_M123)) wc_SHE she; byte m1[WC_SHE_M1_SZ] = {0}; byte m2[WC_SHE_M2_SZ] = {0}; byte m3[WC_SHE_M3_SZ] = {0}; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_ImportM1M2M3(&she, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), 0); ExpectIntEQ(she.generated, 1); ExpectIntEQ(wc_SHE_ImportM1M2M3(NULL, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_ImportM1M2M3(&she, m1, WC_SHE_M1_SZ - 1, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); wc_SHE_Free(&she); #endif return EXPECT_RESULT(); } int test_wc_SHE_AesMp16(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) Aes aes; byte out[WC_SHE_KEY_SZ]; byte input[WC_SHE_KEY_SZ * 2] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x01, 0x01, 0x53, 0x48, 0x45, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0 }; byte shortInput[17] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xAA }; ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_AesMp16(&aes, input, sizeof(input), out), 0); ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_AesMp16(&aes, shortInput, sizeof(shortInput), out), 0); ExpectIntEQ(wc_SHE_AesMp16(NULL, input, sizeof(input), out), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_AesMp16(&aes, NULL, sizeof(input), out), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_AesMp16(&aes, input, 0, out), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_AesMp16(&aes, input, sizeof(input), NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); wc_AesFree(&aes); #endif return EXPECT_RESULT(); } int test_wc_SHE_GenerateM1M2M3(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) wc_SHE she; byte m1[WC_SHE_M1_SZ]; byte m2[WC_SHE_M2_SZ]; byte m3[WC_SHE_M3_SZ]; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); /* Generate and verify M1 against test vector */ ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), 0); ExpectIntEQ(XMEMCMP(m1, sheTestExpM1, WC_SHE_M1_SZ), 0); /* Bad args */ ExpectIntEQ(wc_SHE_GenerateM1M2M3(NULL, sheTestUid, sizeof(sheTestUid), 1, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); wc_SHE_Free(&she); #endif return EXPECT_RESULT(); } int test_wc_SHE_GenerateM4M5(void) { EXPECT_DECLS; #if defined(WOLFSSL_SHE) && !defined(NO_AES) wc_SHE she; byte m4[WC_SHE_M4_SZ]; byte m5[WC_SHE_M5_SZ]; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); /* Generate and verify against test vector */ ExpectIntEQ(wc_SHE_GenerateM4M5(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), 0); ExpectIntEQ(XMEMCMP(m4, sheTestExpM4, WC_SHE_M4_SZ), 0); ExpectIntEQ(XMEMCMP(m5, sheTestExpM5, WC_SHE_M5_SZ), 0); /* Bad args */ ExpectIntEQ(wc_SHE_GenerateM4M5(NULL, sheTestUid, sizeof(sheTestUid), 1, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); wc_SHE_Free(&she); #endif return EXPECT_RESULT(); } #if defined(WOLFSSL_SHE_EXTENDED) && defined(WOLFSSL_SHE) && !defined(NO_AES) int test_wc_SHE_SetKdfConstants(void) { EXPECT_DECLS; wc_SHE she; byte m1Def[WC_SHE_M1_SZ]; byte m2Def[WC_SHE_M2_SZ]; byte m3Def[WC_SHE_M3_SZ]; byte m1Cust[WC_SHE_M1_SZ]; byte m2Cust[WC_SHE_M2_SZ]; byte m3Cust[WC_SHE_M3_SZ]; byte m4[WC_SHE_M4_SZ]; byte m5[WC_SHE_M5_SZ]; byte customEncC[WC_SHE_KEY_SZ] = {0}; byte customMacC[WC_SHE_KEY_SZ] = {0}; customEncC[0] = 0xFF; customMacC[0] = 0xFE; /* Generate with defaults */ ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1Def, WC_SHE_M1_SZ, m2Def, WC_SHE_M2_SZ, m3Def, WC_SHE_M3_SZ), 0); wc_SHE_Free(&she); /* Generate with custom KDF constants */ ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_SetKdfConstants(&she, customEncC, WC_SHE_KEY_SZ, customMacC, WC_SHE_KEY_SZ), 0); ExpectIntEQ(she.kdfEncOverride, 1); ExpectIntEQ(she.kdfMacOverride, 1); ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1Cust, WC_SHE_M1_SZ, m2Cust, WC_SHE_M2_SZ, m3Cust, WC_SHE_M3_SZ), 0); /* M1 same, M2 should differ */ ExpectIntEQ(XMEMCMP(m1Def, m1Cust, WC_SHE_M1_SZ), 0); ExpectIntNE(XMEMCMP(m2Def, m2Cust, WC_SHE_M2_SZ), 0); /* Bad args */ ExpectIntEQ(wc_SHE_SetKdfConstants(NULL, customEncC, WC_SHE_KEY_SZ, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_SetKdfConstants(&she, customEncC, WC_SHE_KEY_SZ - 1, NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_SetKdfConstants(&she, NULL, 0, customMacC, WC_SHE_KEY_SZ - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Test KDF override in M4M5 path */ ExpectIntEQ(wc_SHE_GenerateM4M5(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), 0); wc_SHE_Free(&she); return EXPECT_RESULT(); } int test_wc_SHE_SetM2M4Header(void) { EXPECT_DECLS; wc_SHE she; byte customHeader[WC_SHE_KEY_SZ] = {0}; byte m1Def[WC_SHE_M1_SZ]; byte m2Def[WC_SHE_M2_SZ]; byte m3Def[WC_SHE_M3_SZ]; byte m1Ovr[WC_SHE_M1_SZ]; byte m2Ovr[WC_SHE_M2_SZ]; byte m3Ovr[WC_SHE_M3_SZ]; byte m4Def[WC_SHE_M4_SZ]; byte m5Def[WC_SHE_M5_SZ]; byte m4Ovr[WC_SHE_M4_SZ]; byte m5Ovr[WC_SHE_M5_SZ]; /* Bad args */ ExpectIntEQ(wc_SHE_SetM2Header(NULL, customHeader, WC_SHE_KEY_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_SetM4Header(NULL, customHeader, WC_SHE_KEY_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_SetM2Header(&she, NULL, WC_SHE_KEY_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_SetM2Header(&she, customHeader, WC_SHE_KEY_SZ - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Generate M1M2M3 with defaults */ ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1Def, WC_SHE_M1_SZ, m2Def, WC_SHE_M2_SZ, m3Def, WC_SHE_M3_SZ), 0); wc_SHE_Free(&she); /* Generate with overridden M2 header */ ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); customHeader[0] = 0xFF; ExpectIntEQ(wc_SHE_SetM2Header(&she, customHeader, WC_SHE_KEY_SZ), 0); ExpectIntEQ(she.m2pOverride, 1); ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1Ovr, WC_SHE_M1_SZ, m2Ovr, WC_SHE_M2_SZ, m3Ovr, WC_SHE_M3_SZ), 0); ExpectIntEQ(XMEMCMP(m1Def, m1Ovr, WC_SHE_M1_SZ), 0); ExpectIntNE(XMEMCMP(m2Def, m2Ovr, WC_SHE_M2_SZ), 0); wc_SHE_Free(&she); /* Test M4 header override */ ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_GenerateM4M5(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4Def, WC_SHE_M4_SZ, m5Def, WC_SHE_M5_SZ), 0); wc_SHE_Free(&she); ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); XMEMSET(customHeader, 0xBB, WC_SHE_KEY_SZ); ExpectIntEQ(wc_SHE_SetM4Header(&she, customHeader, WC_SHE_KEY_SZ), 0); ExpectIntEQ(she.m4pOverride, 1); ExpectIntEQ(wc_SHE_GenerateM4M5(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4Ovr, WC_SHE_M4_SZ, m5Ovr, WC_SHE_M5_SZ), 0); ExpectIntNE(XMEMCMP(m4Def, m4Ovr, WC_SHE_M4_SZ), 0); wc_SHE_Free(&she); return EXPECT_RESULT(); } #endif /* WOLFSSL_SHE_EXTENDED && WOLFSSL_SHE && !NO_AES */ #if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_SHE) && !defined(NO_AES) /* SHE callback -- re-calls with software devId */ static int test_she_crypto_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) { wc_SHE* she; int savedDevId; int ret; (void)ctx; (void)devIdArg; if (info == NULL) { return BAD_FUNC_ARG; } #ifdef WOLF_CRYPTO_CB_FREE if (info->algo_type == WC_ALGO_TYPE_FREE) { if (info->free.algo == WC_ALGO_TYPE_SHE) { she = (wc_SHE*)info->free.obj; she->devId = INVALID_DEVID; wc_SHE_Free(she); return 0; } return CRYPTOCB_UNAVAILABLE; } #endif if (info->algo_type != WC_ALGO_TYPE_SHE) { return CRYPTOCB_UNAVAILABLE; } she = (wc_SHE*)info->she.she; if (she == NULL) { return BAD_FUNC_ARG; } savedDevId = she->devId; she->devId = INVALID_DEVID; switch (info->she.type) { case WC_SHE_GET_UID: ret = 0; break; case WC_SHE_GET_COUNTER: { static word32 simCounter = 0; if (info->she.op.getCounter.counter != NULL) { *info->she.op.getCounter.counter = ++simCounter; } ret = 0; break; } case WC_SHE_GENERATE_M1M2M3: ret = wc_SHE_GenerateM1M2M3(she, info->she.op.generateM1M2M3.uid, info->she.op.generateM1M2M3.uidSz, info->she.op.generateM1M2M3.authKeyId, info->she.op.generateM1M2M3.authKey, info->she.op.generateM1M2M3.authKeySz, info->she.op.generateM1M2M3.targetKeyId, info->she.op.generateM1M2M3.newKey, info->she.op.generateM1M2M3.newKeySz, info->she.op.generateM1M2M3.counter, info->she.op.generateM1M2M3.flags, info->she.op.generateM1M2M3.m1, info->she.op.generateM1M2M3.m1Sz, info->she.op.generateM1M2M3.m2, info->she.op.generateM1M2M3.m2Sz, info->she.op.generateM1M2M3.m3, info->she.op.generateM1M2M3.m3Sz); break; case WC_SHE_GENERATE_M4M5: if (info->she.op.generateM4M5.uid == NULL && she->generated) { /* LoadKey flow: M1/M2/M3 already imported, simulate HSM * returning M4/M5 from known test vectors. */ if (info->she.op.generateM4M5.m4 != NULL) XMEMCPY(info->she.op.generateM4M5.m4, sheTestExpM4, WC_SHE_M4_SZ); if (info->she.op.generateM4M5.m5 != NULL) XMEMCPY(info->she.op.generateM4M5.m5, sheTestExpM5, WC_SHE_M5_SZ); ret = 0; } else { ret = wc_SHE_GenerateM4M5(she, info->she.op.generateM4M5.uid, info->she.op.generateM4M5.uidSz, info->she.op.generateM4M5.authKeyId, info->she.op.generateM4M5.targetKeyId, info->she.op.generateM4M5.newKey, info->she.op.generateM4M5.newKeySz, info->she.op.generateM4M5.counter, info->she.op.generateM4M5.m4, info->she.op.generateM4M5.m4Sz, info->she.op.generateM4M5.m5, info->she.op.generateM4M5.m5Sz); } break; case WC_SHE_EXPORT_KEY: /* Simulate hardware export -- fill with test pattern */ if (info->she.op.exportKey.m1 != NULL) { XMEMSET(info->she.op.exportKey.m1, 0x11, WC_SHE_M1_SZ); } if (info->she.op.exportKey.m2 != NULL) { XMEMSET(info->she.op.exportKey.m2, 0x22, WC_SHE_M2_SZ); } if (info->she.op.exportKey.m3 != NULL) { XMEMSET(info->she.op.exportKey.m3, 0x33, WC_SHE_M3_SZ); } if (info->she.op.exportKey.m4 != NULL) { XMEMSET(info->she.op.exportKey.m4, 0x44, WC_SHE_M4_SZ); } if (info->she.op.exportKey.m5 != NULL) { XMEMSET(info->she.op.exportKey.m5, 0x55, WC_SHE_M5_SZ); } ret = 0; break; default: ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); break; } she->devId = savedDevId; return ret; } int test_wc_SHE_CryptoCb(void) { EXPECT_DECLS; wc_SHE she; int sheTestDevId = 54321; byte m1[WC_SHE_M1_SZ]; byte m2[WC_SHE_M2_SZ]; byte m3[WC_SHE_M3_SZ]; byte m4[WC_SHE_M4_SZ]; byte m5[WC_SHE_M5_SZ]; ExpectIntEQ(wc_CryptoCb_RegisterDevice(sheTestDevId, test_she_crypto_cb, NULL), 0); ExpectIntEQ(wc_SHE_Init(&she, NULL, sheTestDevId), 0); /* Generate M1/M2/M3 via callback */ ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), 0); ExpectIntEQ(XMEMCMP(m1, sheTestExpM1, WC_SHE_M1_SZ), 0); /* Generate M4/M5 via callback */ ExpectIntEQ(wc_SHE_GenerateM4M5(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, 4, sheTestNewKey, sizeof(sheTestNewKey), 1, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), 0); ExpectIntEQ(XMEMCMP(m4, sheTestExpM4, WC_SHE_M4_SZ), 0); ExpectIntEQ(XMEMCMP(m5, sheTestExpM5, WC_SHE_M5_SZ), 0); /* ExportKey via callback -- simulated hardware */ #if !defined(NO_WC_SHE_EXPORTKEY) { byte em1[WC_SHE_M1_SZ]; byte em2[WC_SHE_M2_SZ]; byte em3[WC_SHE_M3_SZ]; byte em4[WC_SHE_M4_SZ]; byte em5[WC_SHE_M5_SZ]; byte pat[WC_SHE_M1_SZ]; ExpectIntEQ(wc_SHE_ExportKey(&she, em1, WC_SHE_M1_SZ, em2, WC_SHE_M2_SZ, em3, WC_SHE_M3_SZ, em4, WC_SHE_M4_SZ, em5, WC_SHE_M5_SZ, NULL), 0); /* Verify callback filled with test pattern */ XMEMSET(pat, 0x11, WC_SHE_M1_SZ); ExpectIntEQ(XMEMCMP(em1, pat, WC_SHE_M1_SZ), 0); /* Bad args */ ExpectIntEQ(wc_SHE_ExportKey(NULL, em1, WC_SHE_M1_SZ, em2, WC_SHE_M2_SZ, em3, WC_SHE_M3_SZ, em4, WC_SHE_M4_SZ, em5, WC_SHE_M5_SZ, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); } #endif #if !defined(NO_WC_SHE_GETUID) { byte cbUid[WC_SHE_UID_SZ]; ExpectIntEQ(wc_SHE_GetUID(&she, cbUid, WC_SHE_UID_SZ, NULL), 0); ExpectIntEQ(wc_SHE_GetUID(NULL, cbUid, WC_SHE_UID_SZ, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_GetUID(&she, NULL, WC_SHE_UID_SZ, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); } #endif #if !defined(NO_WC_SHE_GETCOUNTER) { word32 cnt1 = 0; word32 cnt2 = 0; /* Callback should return incrementing counter */ ExpectIntEQ(wc_SHE_GetCounter(&she, &cnt1, NULL), 0); ExpectIntEQ(wc_SHE_GetCounter(&she, &cnt2, NULL), 0); ExpectTrue(cnt2 > cnt1); /* Bad args */ ExpectIntEQ(wc_SHE_GetCounter(NULL, &cnt1, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_SHE_GetCounter(&she, NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); } #endif wc_SHE_Free(&she); wc_CryptoCb_UnRegisterDevice(sheTestDevId); return EXPECT_RESULT(); } #ifndef NO_WC_SHE_LOADKEY int test_wc_SHE_LoadKey(void) { EXPECT_DECLS; int sheTestDevId = 54322; byte m1[WC_SHE_M1_SZ]; byte m2[WC_SHE_M2_SZ]; byte m3[WC_SHE_M3_SZ]; byte m4[WC_SHE_M4_SZ]; byte m5[WC_SHE_M5_SZ]; ExpectIntEQ(wc_CryptoCb_RegisterDevice(sheTestDevId, test_she_crypto_cb, NULL), 0); /* Generate valid M1/M2/M3 from test vectors */ { wc_SHE she; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), 0); wc_SHE_Free(&she); } /* Basic: LoadKey should import M1/M2/M3 and produce M4/M5 via callback */ ExpectIntEQ(wc_SHE_LoadKey(NULL, sheTestDevId, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), 0); ExpectIntEQ(XMEMCMP(m4, sheTestExpM4, WC_SHE_M4_SZ), 0); ExpectIntEQ(XMEMCMP(m5, sheTestExpM5, WC_SHE_M5_SZ), 0); /* Bad args: NULL m1 */ ExpectIntEQ(wc_SHE_LoadKey(NULL, sheTestDevId, NULL, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Bad args: NULL m4 output */ ExpectIntEQ(wc_SHE_LoadKey(NULL, sheTestDevId, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, NULL, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Bad args: INVALID_DEVID */ ExpectIntEQ(wc_SHE_LoadKey(NULL, INVALID_DEVID, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); /* Bad args: wrong M1 size */ ExpectIntEQ(wc_SHE_LoadKey(NULL, sheTestDevId, m1, WC_SHE_M1_SZ - 1, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); wc_CryptoCb_UnRegisterDevice(sheTestDevId); return EXPECT_RESULT(); } int test_wc_SHE_LoadKey_Verify(void) { EXPECT_DECLS; int sheTestDevId = 54323; byte m1[WC_SHE_M1_SZ]; byte m2[WC_SHE_M2_SZ]; byte m3[WC_SHE_M3_SZ]; byte m4[WC_SHE_M4_SZ]; byte m5[WC_SHE_M5_SZ]; byte badM4[WC_SHE_M4_SZ]; ExpectIntEQ(wc_CryptoCb_RegisterDevice(sheTestDevId, test_she_crypto_cb, NULL), 0); /* Generate valid M1/M2/M3 from test vectors */ { wc_SHE she; ExpectIntEQ(wc_SHE_Init(&she, NULL, INVALID_DEVID), 0); ExpectIntEQ(wc_SHE_GenerateM1M2M3(&she, sheTestUid, sizeof(sheTestUid), WC_SHE_MASTER_ECU_KEY_ID, sheTestAuthKey, sizeof(sheTestAuthKey), 4, sheTestNewKey, sizeof(sheTestNewKey), 1, 0, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ), 0); wc_SHE_Free(&she); } /* Matching: expected M4/M5 match what the callback produces */ ExpectIntEQ(wc_SHE_LoadKey_Verify(NULL, sheTestDevId, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ, sheTestExpM4, WC_SHE_M4_SZ, sheTestExpM5, WC_SHE_M5_SZ), 0); /* Mismatch: wrong expected M4 should fail with SIG_VERIFY_E */ XMEMCPY(badM4, sheTestExpM4, WC_SHE_M4_SZ); badM4[0] ^= 0xFF; ExpectIntEQ(wc_SHE_LoadKey_Verify(NULL, sheTestDevId, m1, WC_SHE_M1_SZ, m2, WC_SHE_M2_SZ, m3, WC_SHE_M3_SZ, m4, WC_SHE_M4_SZ, m5, WC_SHE_M5_SZ, badM4, WC_SHE_M4_SZ, sheTestExpM5, WC_SHE_M5_SZ), WC_NO_ERR_TRACE(SIG_VERIFY_E)); wc_CryptoCb_UnRegisterDevice(sheTestDevId); return EXPECT_RESULT(); } #endif /* !NO_WC_SHE_LOADKEY */ #endif /* WOLF_CRYPTO_CB && WOLFSSL_SHE && !NO_AES */