Add more in depth comments in header file for she.h

This commit is contained in:
night1rider
2026-03-20 18:27:49 -06:00
parent ee7fe9e1b1
commit 802c34018c
5 changed files with 163 additions and 40 deletions
+1 -1
View File
@@ -892,9 +892,9 @@ WOLFSSL_SE050_NO_TRNG
WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
WOLFSSL_SERVER_EXAMPLE
WOLFSSL_SETTINGS_FILE
WOLFSSL_SH224
WOLFSSL_SHE
WOLFSSL_SHE_EXTENDED
WOLFSSL_SH224
WOLFSSL_SHA256_ALT_CH_MAJ
WOLFSSL_SHA512_HASHTYPE
WOLFSSL_SHUTDOWNONCE
+3 -3
View File
@@ -428,7 +428,7 @@ int test_wc_SHE_SetM2M4Header(void)
#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_SHE) && !defined(NO_AES)
/* SHE callback re-calls with software devId */
/* SHE callback -- re-calls with software devId */
static int test_she_crypto_cb(int devIdArg, wc_CryptoInfo* info, void* ctx)
{
wc_SHE* she;
@@ -513,7 +513,7 @@ static int test_she_crypto_cb(int devIdArg, wc_CryptoInfo* info, void* ctx)
info->she.op.generateM4M5.m5Sz);
break;
case WC_SHE_EXPORT_KEY:
/* Simulate hardware export fill with test pattern */
/* 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);
}
@@ -572,7 +572,7 @@ int test_wc_SHE_CryptoCb(void)
ExpectIntEQ(XMEMCMP(m4, sheTestExpM4, WC_SHE_M4_SZ), 0);
ExpectIntEQ(XMEMCMP(m5, sheTestExpM5, WC_SHE_M5_SZ), 0);
/* ExportKey via callback simulated hardware */
/* ExportKey via callback -- simulated hardware */
#if !defined(NO_WC_SHE_EXPORTKEY)
{
byte em1[WC_SHE_M1_SZ];
+11 -11
View File
@@ -123,7 +123,7 @@ int wc_SHE_Init(wc_SHE* she, void* heap, int devId)
ForceZero(she, sizeof(wc_SHE));
she->heap = heap;
she->devId = devId;
/* kdfEncOverride/kdfMacOverride are zero from XMEMSET defaults used */
/* kdfEncOverride/kdfMacOverride are zero from XMEMSET -- defaults used */
return 0;
}
@@ -222,7 +222,7 @@ void wc_SHE_Free(wc_SHE* she)
}
/* -------------------------------------------------------------------------- */
/* GetUID callback required */
/* GetUID -- callback required */
/* */
/* Dispatches to callback to fetch UID from hardware. */
/* Buffer size validation is the callback's responsibility. */
@@ -241,7 +241,7 @@ int wc_SHE_GetUID(wc_SHE* she, byte* uid, word32 uidSz,
#endif /* WOLF_CRYPTO_CB && !NO_WC_SHE_GETUID */
/* -------------------------------------------------------------------------- */
/* GetCounter callback required */
/* GetCounter -- callback required */
/* */
/* Dispatches to callback to read current counter from hardware. */
/* Returns CRYPTOCB_UNAVAILABLE if no callback. */
@@ -425,13 +425,13 @@ int wc_SHE_GenerateM1M2M3(wc_SHE* she,
WC_DECLARE_VAR(aes, Aes, 1, 0);
WC_DECLARE_VAR(cmac, Cmac, 1, 0);
/* Validate SHE context first required for both callback and software */
/* Validate SHE context first -- required for both callback and software */
if (she == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLF_CRYPTO_CB
/* Try callback first callback handles its own parameter validation.
/* Try callback first -- callback handles its own parameter validation.
* This allows callers to pass NULL authKey/newKey when a secure element
* holds the keys and the callback talks to it directly. */
if (she->devId != INVALID_DEVID) {
@@ -448,7 +448,7 @@ int wc_SHE_GenerateM1M2M3(wc_SHE* she,
}
#endif
/* Software path validate all parameters */
/* Software path -- validate all parameters */
if (uid == NULL || uidSz != WC_SHE_UID_SZ ||
authKey == NULL || authKeySz != WC_SHE_KEY_SZ ||
newKey == NULL || newKeySz != WC_SHE_KEY_SZ ||
@@ -482,7 +482,7 @@ int wc_SHE_GenerateM1M2M3(wc_SHE* she,
return MEMORY_E;
}
/* Init AES once used by both MP16 and CBC */
/* Init AES once -- used by both MP16 and CBC */
ret = wc_AesInit(aes, she->heap, she->devId);
if (ret != 0) {
WC_FREE_VAR(aes, she->heap);
@@ -584,7 +584,7 @@ int wc_SHE_GenerateM4M5(wc_SHE* she,
}
#ifdef WOLF_CRYPTO_CB
/* Try callback first useful for uploading M1/M2/M3 to an HSM which
/* Try callback first -- useful for uploading M1/M2/M3 to an HSM which
* loads the key and returns the correct M4/M5 proof values. The callback
* handles its own parameter validation. */
if (she->devId != INVALID_DEVID) {
@@ -599,7 +599,7 @@ int wc_SHE_GenerateM4M5(wc_SHE* she,
}
#endif
/* Software path validate all parameters */
/* Software path -- validate all parameters */
if (uid == NULL || uidSz != WC_SHE_UID_SZ ||
newKey == NULL || newKeySz != WC_SHE_KEY_SZ ||
m4 == NULL || m4Sz < WC_SHE_M4_SZ ||
@@ -631,7 +631,7 @@ int wc_SHE_GenerateM4M5(wc_SHE* she,
return MEMORY_E;
}
/* Init AES once used by both MP16 and ECB */
/* Init AES once -- used by both MP16 and ECB */
ret = wc_AesInit(aes, she->heap, she->devId);
if (ret != 0) {
WC_FREE_VAR(aes, she->heap);
@@ -700,7 +700,7 @@ int wc_SHE_GenerateM4M5(wc_SHE* she,
/* -------------------------------------------------------------------------- */
#if defined(WOLF_CRYPTO_CB) && !defined(NO_WC_SHE_EXPORTKEY)
/* -------------------------------------------------------------------------- */
/* Export Key callback required */
/* Export Key -- callback required */
/* */
/* Asks hardware to export a key slot as M1-M5 in SHE loadable format. */
/* -------------------------------------------------------------------------- */
+5 -3
View File
@@ -56739,6 +56739,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t she_test(void)
goto exit_SHE_Test;
}
#if defined(WOLF_CRYPTO_CB) || !defined(NO_WC_SHE_IMPORT_M123)
/* ---- Import M1/M2/M3 and generate M4/M5 (only NewKey needed) ---- */
wc_SHE_Free(she);
ret = wc_SHE_Init(she, HEAP_HINT, devId);
@@ -56746,7 +56747,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t she_test(void)
goto exit_SHE_Test;
}
/* Import M1/M2/M3, then generate M4/M5 via one-shot */
/* Import M1/M2/M3, then generate M4/M5 */
ret = wc_SHE_ImportM1M2M3(she,
expM1, WC_SHE_M1_SZ,
expM2, WC_SHE_M2_SZ,
@@ -56773,6 +56774,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t she_test(void)
ret = WC_TEST_RET_ENC_NC;
goto exit_SHE_Test;
}
#endif /* WOLF_CRYPTO_CB || !NO_WC_SHE_IMPORT_M123 */
/* ---- One-shot M1/M2/M3 ---- */
wc_SHE_Free(she);
@@ -56864,7 +56866,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t she_test(void)
goto exit_SHE_Test;
}
/* Generate M4/M5 on second context completely independent */
/* Generate M4/M5 on second context -- completely independent */
ret = wc_SHE_GenerateM4M5(she2,
sheUid, sizeof(sheUid),
WC_SHE_MASTER_ECU_KEY_ID, 4,
@@ -67523,7 +67525,7 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
info->she.op.generateM4M5.m5Sz);
break;
case WC_SHE_EXPORT_KEY:
/* Simulate hardware export fill with test pattern */
/* 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);
+143 -22
View File
@@ -34,14 +34,14 @@
extern "C" {
#endif
#define WC_SHE_KEY_SZ 16
#define WC_SHE_UID_SZ 15
#define WC_SHE_KEY_SZ 16 /* AES-128 key size (128 bits) */
#define WC_SHE_UID_SZ 15 /* SHE UID size (120 bits) */
#define WC_SHE_M1_SZ 16
#define WC_SHE_M2_SZ 32
#define WC_SHE_M3_SZ 16
#define WC_SHE_M4_SZ 32
#define WC_SHE_M5_SZ 16
#define WC_SHE_M1_SZ 16 /* UID(15B) | KeyID(4b) | AuthID(4b) */
#define WC_SHE_M2_SZ 32 /* AES-CBC(K1, counter|flags|pad|newkey) */
#define WC_SHE_M3_SZ 16 /* AES-CMAC(K2, M1|M2) */
#define WC_SHE_M4_SZ 32 /* UID|IDs + AES-ECB(K3, counter|pad) */
#define WC_SHE_M5_SZ 16 /* AES-CMAC(K4, M4) */
/* crypto callback sub-types for WC_ALGO_TYPE_SHE */
enum wc_SheType {
@@ -129,28 +129,55 @@ typedef struct wc_SHE {
} wc_SHE;
/* Initialize SHE context, store heap hint and device ID */
/* Initialize SHE context, store heap hint and device ID.
* she - pointer to wc_SHE structure to initialize
* heap - heap hint for internal allocations, or NULL
* devId - crypto callback device ID, or INVALID_DEVID for software */
WOLFSSL_API int wc_SHE_Init(wc_SHE* she, void* heap, int devId);
#ifdef WOLF_PRIVATE_KEY_ID
/* Initialize with opaque hardware key identifier */
/* Initialize with opaque hardware key identifier.
* Useful when using callbacks and additional info needs to be attached
* to the SHE context to determine slot or key group information.
* she - pointer to wc_SHE structure to initialize
* id - opaque key identifier bytes
* len - length of id in bytes (0 to WC_SHE_MAX_ID_LEN)
* heap - heap hint for internal allocations, or NULL
* devId - crypto callback device ID */
WOLFSSL_API int wc_SHE_Init_Id(wc_SHE* she, unsigned char* id, int len,
void* heap, int devId);
/* Initialize with human-readable key label */
/* Initialize with human-readable key label.
* Useful when using callbacks and additional info needs to be attached
* to the SHE context to determine slot or key group information.
* she - pointer to wc_SHE structure to initialize
* label - NUL-terminated key label string
* heap - heap hint for internal allocations, or NULL
* devId - crypto callback device ID */
WOLFSSL_API int wc_SHE_Init_Label(wc_SHE* she, const char* label,
void* heap, int devId);
#endif
/* Scrub and zero the context */
/* Scrub all data and zero the context. Safe to call on NULL. */
WOLFSSL_API void wc_SHE_Free(wc_SHE* she);
/* Get UID from hardware; callback required (WC_SHE_SET_UID) */
/* Get UID from hardware via callback (WC_SHE_SET_UID).
* she - initialized SHE context with a registered callback
* uid - buffer to receive the 120-bit (15-byte) SHE UID
* uidSz - size of uid buffer in bytes
* ctx - read-only caller context passed to the callback
* (e.g. challenge buffer, HSM handle) */
#if defined(WOLF_CRYPTO_CB) && !defined(NO_WC_SHE_GETUID)
WOLFSSL_API int wc_SHE_GetUID(wc_SHE* she, byte* uid, word32 uidSz,
const void* ctx);
#endif
/* Get counter from hardware; callback required */
/* Get monotonic counter from hardware via callback (WC_SHE_GET_COUNTER).
* she - initialized SHE context with a registered callback
* counter - pointer to receive the current counter value.
* The SHE spec uses a 28-bit counter. The caller should
* increment this value before passing to GenerateM1M2M3/M4M5.
* ctx - read-only caller context passed to the callback */
#if defined(WOLF_CRYPTO_CB) && !defined(NO_WC_SHE_GETCOUNTER)
WOLFSSL_API int wc_SHE_GetCounter(wc_SHE* she, word32* counter,
const void* ctx);
@@ -160,21 +187,47 @@ WOLFSSL_API int wc_SHE_GetCounter(wc_SHE* she, word32* counter,
* Useful for some HSMs that support multiple key groups with
* different derivation constants. */
#ifdef WOLFSSL_SHE_EXTENDED
/* Set KDF constants (CENC/CMAC). Defaults set by Init. NULL to skip. */
/* Set KDF constants used in Miyaguchi-Preneel key derivation.
* Defaults are KEY_UPDATE_ENC_C and KEY_UPDATE_MAC_C from the SHE spec.
* Either pointer may be NULL to leave that constant unchanged.
* she - initialized SHE context
* encC - 16-byte encryption derivation constant (CENC), or NULL
* encCSz - must be WC_SHE_KEY_SZ (16) when encC is non-NULL
* macC - 16-byte MAC derivation constant (CMAC), or NULL
* macCSz - must be WC_SHE_KEY_SZ (16) when macC is non-NULL */
WOLFSSL_API int wc_SHE_SetKdfConstants(wc_SHE* she,
const byte* encC, word32 encCSz,
const byte* macC, word32 macCSz);
/* Override M2P cleartext header. Skips auto-build from counter/flags. */
/* Override M2 cleartext header (first 16 bytes of M2 before encryption).
* When set, GenerateM1M2M3 uses this instead of auto-building from
* counter and flags. The header is: counter(28b)|flags(4b)|zeros(96b).
* she - initialized SHE context
* header - 16-byte cleartext header block
* headerSz - must be WC_SHE_KEY_SZ (16) */
WOLFSSL_API int wc_SHE_SetM2Header(wc_SHE* she,
const byte* header, word32 headerSz);
/* Override M4P cleartext header. Skips auto-build from counter. */
/* Override M4 cleartext counter block (16-byte block encrypted with K3).
* When set, GenerateM4M5 uses this instead of auto-building from counter.
* The block is: counter(28b)|1(1b)|zeros(99b).
* she - initialized SHE context
* header - 16-byte cleartext counter block
* headerSz - must be WC_SHE_KEY_SZ (16) */
WOLFSSL_API int wc_SHE_SetM4Header(wc_SHE* she,
const byte* header, word32 headerSz);
#endif /* WOLFSSL_SHE_EXTENDED */
/* Import externally-provided M1/M2/M3 into context; sets generated flag */
/* Import externally-provided M1/M2/M3 into context.
* Sets the generated flag so the callback for GenerateM4M5 can
* read M1/M2/M3 from the context to send to hardware.
* she - initialized SHE context
* m1 - 16-byte M1 message (UID | KeyID | AuthID)
* m1Sz - must be WC_SHE_M1_SZ (16)
* m2 - 32-byte M2 message (encrypted counter|flags|pad|newkey)
* m2Sz - must be WC_SHE_M2_SZ (32)
* m3 - 16-byte M3 message (CMAC over M1|M2)
* m3Sz - must be WC_SHE_M3_SZ (16) */
#if defined(WOLF_CRYPTO_CB) || !defined(NO_WC_SHE_IMPORT_M123)
WOLFSSL_API int wc_SHE_ImportM1M2M3(wc_SHE* she,
const byte* m1, word32 m1Sz,
@@ -182,7 +235,36 @@ WOLFSSL_API int wc_SHE_ImportM1M2M3(wc_SHE* she,
const byte* m3, word32 m3Sz);
#endif
/* Generate M1/M2/M3 and write to caller buffers */
/* Generate M1/M2/M3 for the SHE key update protocol and write to
* caller-provided buffers. Callback optional -- if a callback is
* registered it is tried first; if it returns CRYPTOCB_UNAVAILABLE
* the software path runs. This allows a secure element to generate
* M1/M2/M3 when it holds the auth key internally.
*
* she - initialized SHE context
* uid - 15-byte SHE UID (120-bit ECU/module identifier)
* uidSz - must be WC_SHE_UID_SZ (15)
* authKeyId - slot ID of the authorizing key (0-14, e.g.
* MASTER_ECU_KEY=1, KEY_1..KEY_10=4..13)
* authKey - 16-byte value of the authorizing key. Used to derive
* K1 (encryption) and K2 (MAC). May be NULL when the
* callback handles key access.
* authKeySz - must be WC_SHE_KEY_SZ (16) when authKey is non-NULL
* targetKeyId - slot ID of the key being loaded (1-14)
* newKey - 16-byte value of the new key to load. Placed in M2
* cleartext and used to derive K3/K4 for M4/M5.
* May be NULL when the callback handles key access.
* newKeySz - must be WC_SHE_KEY_SZ (16) when newKey is non-NULL
* counter - 28-bit monotonic counter value. Must be strictly greater
* than the counter stored in the target slot on the SHE.
* flags - key protection flags (lower 4 bits of the counter|flags
* word in M2).
* m1 - output buffer for M1 (16 bytes)
* m1Sz - size of m1 buffer, must be >= WC_SHE_M1_SZ
* m2 - output buffer for M2 (32 bytes)
* m2Sz - size of m2 buffer, must be >= WC_SHE_M2_SZ
* m3 - output buffer for M3 (16 bytes)
* m3Sz - size of m3 buffer, must be >= WC_SHE_M3_SZ */
WOLFSSL_API int wc_SHE_GenerateM1M2M3(wc_SHE* she,
const byte* uid, word32 uidSz,
byte authKeyId, const byte* authKey, word32 authKeySz,
@@ -192,7 +274,25 @@ WOLFSSL_API int wc_SHE_GenerateM1M2M3(wc_SHE* she,
byte* m2, word32 m2Sz,
byte* m3, word32 m3Sz);
/* Generate M4/M5 and write to caller buffers */
/* Generate M4/M5 verification messages and write to caller-provided
* buffers. Independent of M1/M2/M3 -- can be called on a separate
* context. Callback optional -- useful for uploading M1/M2/M3 to an
* HSM which loads the key and returns M4/M5 as proof.
*
* she - initialized SHE context
* uid - 15-byte SHE UID (same UID used for M1)
* uidSz - must be WC_SHE_UID_SZ (15)
* authKeyId - slot ID of the authorizing key (same as in M1)
* targetKeyId - slot ID of the key being loaded (same as in M1)
* newKey - 16-byte value of the new key. Used to derive K3
* (encryption for M4 counter block) and K4 (MAC for M5).
* May be NULL when the callback handles key access.
* newKeySz - must be WC_SHE_KEY_SZ (16) when newKey is non-NULL
* counter - 28-bit monotonic counter (same value as in M2)
* m4 - output buffer for M4 (32 bytes)
* m4Sz - size of m4 buffer, must be >= WC_SHE_M4_SZ
* m5 - output buffer for M5 (16 bytes)
* m5Sz - size of m5 buffer, must be >= WC_SHE_M5_SZ */
WOLFSSL_API int wc_SHE_GenerateM4M5(wc_SHE* she,
const byte* uid, word32 uidSz,
byte authKeyId, byte targetKeyId,
@@ -201,8 +301,22 @@ WOLFSSL_API int wc_SHE_GenerateM4M5(wc_SHE* she,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz);
/* Export key from hardware as M1-M5; callback required.
* Some HSMs allow exporting certain key slots (e.g. RAM key) in SHE format. */
/* Export a key from hardware in SHE loadable format (M1-M5).
* Callback required -- dispatches to WC_SHE_EXPORT_KEY.
* Some HSMs allow exporting certain key slots (e.g. RAM key) so they
* can be re-loaded later via the SHE key update protocol.
* she - initialized SHE context with a registered callback
* m1 - output buffer for M1 (16 bytes), or NULL to skip
* m1Sz - size of m1 buffer
* m2 - output buffer for M2 (32 bytes), or NULL to skip
* m2Sz - size of m2 buffer
* m3 - output buffer for M3 (16 bytes), or NULL to skip
* m3Sz - size of m3 buffer
* m4 - output buffer for M4 (32 bytes), or NULL to skip
* m4Sz - size of m4 buffer
* m5 - output buffer for M5 (16 bytes), or NULL to skip
* m5Sz - size of m5 buffer
* ctx - read-only caller context passed to the callback */
#if defined(WOLF_CRYPTO_CB) && !defined(NO_WC_SHE_EXPORTKEY)
WOLFSSL_API int wc_SHE_ExportKey(wc_SHE* she,
byte* m1, word32 m1Sz,
@@ -213,7 +327,14 @@ WOLFSSL_API int wc_SHE_ExportKey(wc_SHE* she,
const void* ctx);
#endif
/* Internal: Miyaguchi-Preneel AES-128 compression, exposed for testing */
/* Internal: Miyaguchi-Preneel AES-128 one-way compression.
* H_0 = 0, H_i = E_{H_{i-1}}(M_i) XOR M_i XOR H_{i-1}.
* Only valid for AES-128 where key size equals block size.
* Exposed via WOLFSSL_TEST_VIS for testing.
* aes - caller-owned, already-initialized Aes structure
* in - input data (e.g. BaseKey || KDF_Constant, 32 bytes)
* inSz - length of input in bytes (zero-padded to block boundary)
* out - output buffer for 16-byte compressed result */
WOLFSSL_TEST_VIS int wc_She_AesMp16(Aes* aes, const byte* in, word32 inSz,
byte* out);