mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 19:30:48 +02:00
769 lines
27 KiB
C
769 lines
27 KiB
C
/* 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 <tests/unit.h>
|
|
|
|
#ifdef NO_INLINE
|
|
#include <wolfssl/wolfcrypt/misc.h>
|
|
#else
|
|
#define WOLFSSL_MISC_INCLUDED
|
|
#include <wolfcrypt/src/misc.c>
|
|
#endif
|
|
|
|
#include <wolfssl/wolfcrypt/wc_she.h>
|
|
#include <wolfssl/wolfcrypt/types.h>
|
|
#ifdef WOLF_CRYPTO_CB
|
|
#include <wolfssl/wolfcrypt/cryptocb.h>
|
|
#endif
|
|
#include <tests/api/api.h>
|
|
#include <tests/api/test_she.h>
|
|
|
|
/* 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 */
|