Add one-shot SHE LoadKey and LoadKey Verify convenience APIs: wc_SHE_LoadKey, wc_SHE_LoadKey_Id, wc_SHE_LoadKey_Label and their verify counterparts

This commit is contained in:
night1rider
2026-03-31 14:24:46 -06:00
parent f8956abcc1
commit 994b0cdedd
2 changed files with 396 additions and 0 deletions
+314
View File
@@ -770,6 +770,320 @@ int wc_SHE_GenerateM4M5(wc_SHE* she,
return ret;
}
/* -------------------------------------------------------------------------- */
/* One-shot Load Key helpers */
/* */
/* Internal helper that does the actual work: imports M1/M2/M3 into the */
/* already-initialized SHE context, calls GenerateM4M5 (which dispatches to */
/* the crypto callback to send M1/M2/M3 to the HSM and receive M4/M5 back), */
/* and frees the context. */
/* -------------------------------------------------------------------------- */
#ifndef NO_WC_SHE_LOADKEY
#if defined(WOLF_CRYPTO_CB) || !defined(NO_WC_SHE_IMPORT_M123)
static int wc_SHE_LoadKey_Internal(wc_SHE* she,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz)
{
int ret;
ret = wc_SHE_ImportM1M2M3(she, m1, m1Sz, m2, m2Sz, m3, m3Sz);
if (ret != 0) {
wc_SHE_Free(she);
return ret;
}
/* GenerateM4M5 with NULL uid/newKey -- the callback reads M1/M2/M3
* from the context and sends them to the HSM which returns M4/M5. */
ret = wc_SHE_GenerateM4M5(she, NULL, 0, 0, 0, NULL, 0, 0,
m4, m4Sz, m5, m5Sz);
wc_SHE_Free(she);
return ret;
}
/* -------------------------------------------------------------------------- */
/* wc_SHE_LoadKey */
/* */
/* One-shot: Init, ImportM1M2M3, GenerateM4M5 (via callback), Free. */
/* Requires a valid devId (not INVALID_DEVID) since the operation dispatches */
/* to a hardware crypto callback. */
/* -------------------------------------------------------------------------- */
int wc_SHE_LoadKey(
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz)
{
int ret;
WC_DECLARE_VAR(she, wc_SHE, 1, heap);
if (m1 == NULL || m2 == NULL || m3 == NULL ||
m4 == NULL || m5 == NULL) {
return BAD_FUNC_ARG;
}
if (devId == INVALID_DEVID) {
return BAD_FUNC_ARG;
}
if (m1Sz != WC_SHE_M1_SZ || m2Sz != WC_SHE_M2_SZ ||
m3Sz != WC_SHE_M3_SZ) {
return BAD_FUNC_ARG;
}
if (m4Sz < WC_SHE_M4_SZ || m5Sz < WC_SHE_M5_SZ) {
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR(she, wc_SHE, 1, heap);
if (!WC_VAR_OK(she)) {
return MEMORY_E;
}
ret = wc_SHE_Init(she, heap, devId);
if (ret != 0) {
WC_FREE_VAR(she, heap);
return ret;
}
ret = wc_SHE_LoadKey_Internal(she, m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
WC_FREE_VAR(she, heap);
return ret;
}
#ifdef WOLF_PRIVATE_KEY_ID
/* -------------------------------------------------------------------------- */
/* wc_SHE_LoadKey_Id */
/* */
/* One-shot with opaque hardware key identifier. */
/* Requires a valid devId (not INVALID_DEVID) since the operation dispatches */
/* to a hardware crypto callback. */
/* -------------------------------------------------------------------------- */
int wc_SHE_LoadKey_Id(
unsigned char* id, int idLen,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz)
{
int ret;
WC_DECLARE_VAR(she, wc_SHE, 1, heap);
if (id == NULL || m1 == NULL || m2 == NULL || m3 == NULL ||
m4 == NULL || m5 == NULL) {
return BAD_FUNC_ARG;
}
if (devId == INVALID_DEVID) {
return BAD_FUNC_ARG;
}
if (idLen < 0 || idLen > WC_SHE_MAX_ID_LEN) {
return BAD_FUNC_ARG;
}
if (m1Sz != WC_SHE_M1_SZ || m2Sz != WC_SHE_M2_SZ ||
m3Sz != WC_SHE_M3_SZ) {
return BAD_FUNC_ARG;
}
if (m4Sz < WC_SHE_M4_SZ || m5Sz < WC_SHE_M5_SZ) {
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR(she, wc_SHE, 1, heap);
if (!WC_VAR_OK(she)) {
return MEMORY_E;
}
ret = wc_SHE_Init_Id(she, id, idLen, heap, devId);
if (ret != 0) {
WC_FREE_VAR(she, heap);
return ret;
}
ret = wc_SHE_LoadKey_Internal(she, m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
WC_FREE_VAR(she, heap);
return ret;
}
/* -------------------------------------------------------------------------- */
/* wc_SHE_LoadKey_Label */
/* */
/* One-shot with human-readable key label. */
/* Requires a valid devId (not INVALID_DEVID) since the operation dispatches */
/* to a hardware crypto callback. */
/* -------------------------------------------------------------------------- */
int wc_SHE_LoadKey_Label(
const char* label,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz)
{
int ret;
WC_DECLARE_VAR(she, wc_SHE, 1, heap);
if (label == NULL || m1 == NULL || m2 == NULL || m3 == NULL ||
m4 == NULL || m5 == NULL) {
return BAD_FUNC_ARG;
}
if (devId == INVALID_DEVID) {
return BAD_FUNC_ARG;
}
if (XSTRLEN(label) == 0 || XSTRLEN(label) > WC_SHE_MAX_LABEL_LEN) {
return BAD_FUNC_ARG;
}
if (m1Sz != WC_SHE_M1_SZ || m2Sz != WC_SHE_M2_SZ ||
m3Sz != WC_SHE_M3_SZ) {
return BAD_FUNC_ARG;
}
if (m4Sz < WC_SHE_M4_SZ || m5Sz < WC_SHE_M5_SZ) {
return BAD_FUNC_ARG;
}
WC_ALLOC_VAR(she, wc_SHE, 1, heap);
if (!WC_VAR_OK(she)) {
return MEMORY_E;
}
ret = wc_SHE_Init_Label(she, label, heap, devId);
if (ret != 0) {
WC_FREE_VAR(she, heap);
return ret;
}
ret = wc_SHE_LoadKey_Internal(she, m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
WC_FREE_VAR(she, heap);
return ret;
}
#endif /* WOLF_PRIVATE_KEY_ID */
/* -------------------------------------------------------------------------- */
/* One-shot Load Key with Verification */
/* */
/* Same as the LoadKey variants but also compares the M4/M5 returned by the */
/* HSM against caller-provided expected values. Returns SIG_VERIFY_E on */
/* mismatch. The actual M4/M5 from the HSM are still written to the output */
/* buffers so the caller can inspect them on failure. */
/* -------------------------------------------------------------------------- */
static int wc_SHE_VerifyM4M5(
const byte* m4, word32 m4Sz,
const byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz)
{
if (m4Expected == NULL || m5Expected == NULL) {
return BAD_FUNC_ARG;
}
if (m4ExpectedSz != WC_SHE_M4_SZ || m5ExpectedSz != WC_SHE_M5_SZ ||
m4Sz < WC_SHE_M4_SZ || m5Sz < WC_SHE_M5_SZ) {
return BAD_FUNC_ARG;
}
if (ConstantCompare(m4, m4Expected, WC_SHE_M4_SZ) != 0 ||
ConstantCompare(m5, m5Expected, WC_SHE_M5_SZ) != 0) {
return SIG_VERIFY_E;
}
return 0;
}
int wc_SHE_LoadKey_Verify(
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz)
{
int ret;
ret = wc_SHE_LoadKey(heap, devId, m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
if (ret != 0) {
return ret;
}
return wc_SHE_VerifyM4M5(m4, m4Sz, m5, m5Sz,
m4Expected, m4ExpectedSz,
m5Expected, m5ExpectedSz);
}
#ifdef WOLF_PRIVATE_KEY_ID
int wc_SHE_LoadKey_Verify_Id(
unsigned char* id, int idLen,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz)
{
int ret;
ret = wc_SHE_LoadKey_Id(id, idLen, heap, devId,
m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
if (ret != 0) {
return ret;
}
return wc_SHE_VerifyM4M5(m4, m4Sz, m5, m5Sz,
m4Expected, m4ExpectedSz,
m5Expected, m5ExpectedSz);
}
int wc_SHE_LoadKey_Verify_Label(
const char* label,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz)
{
int ret;
ret = wc_SHE_LoadKey_Label(label, heap, devId,
m1, m1Sz, m2, m2Sz, m3, m3Sz,
m4, m4Sz, m5, m5Sz);
if (ret != 0) {
return ret;
}
return wc_SHE_VerifyM4M5(m4, m4Sz, m5, m5Sz,
m4Expected, m4ExpectedSz,
m5Expected, m5ExpectedSz);
}
#endif /* WOLF_PRIVATE_KEY_ID */
#endif /* WOLF_CRYPTO_CB || !NO_WC_SHE_IMPORT_M123 */
#endif /* !NO_WC_SHE_LOADKEY */
/* -------------------------------------------------------------------------- */
/* Export Key */
/* */
+82
View File
@@ -292,6 +292,88 @@ WOLFSSL_API int wc_SHE_GenerateM4M5(wc_SHE* she,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz);
/* One-shot Load Key: Init, ImportM1M2M3, GenerateM4M5 (via callback), Free.
* Requires a valid devId (not INVALID_DEVID) -- dispatches to a hardware
* crypto callback that sends M1/M2/M3 to the HSM and returns M4/M5.
* Define NO_WC_SHE_LOADKEY to compile out all LoadKey/Verify wrappers.
* heap - heap hint for internal allocations, or NULL
* devId - crypto callback device ID (must not be INVALID_DEVID)
* m1-m3 - input: externally-provided SHE key update messages
* m4,m5 - output: verification messages returned by the HSM */
#ifndef NO_WC_SHE_LOADKEY
#if defined(WOLF_CRYPTO_CB) || !defined(NO_WC_SHE_IMPORT_M123)
WOLFSSL_API int wc_SHE_LoadKey(
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz);
#ifdef WOLF_PRIVATE_KEY_ID
/* One-shot Load Key with opaque hardware key identifier. */
WOLFSSL_API int wc_SHE_LoadKey_Id(
unsigned char* id, int idLen,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz);
/* One-shot Load Key with human-readable key label. */
WOLFSSL_API int wc_SHE_LoadKey_Label(
const char* label,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz);
#endif /* WOLF_PRIVATE_KEY_ID */
/* One-shot Load Key with M4/M5 verification.
* Same as wc_SHE_LoadKey but also compares the M4/M5 returned by the HSM
* against caller-provided expected values. Returns SIG_VERIFY_E on mismatch.
* The actual M4/M5 are still written to the output buffers on failure.
* m4Expected, m5Expected - expected verification messages to compare against */
WOLFSSL_API int wc_SHE_LoadKey_Verify(
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz);
#ifdef WOLF_PRIVATE_KEY_ID
WOLFSSL_API int wc_SHE_LoadKey_Verify_Id(
unsigned char* id, int idLen,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz);
WOLFSSL_API int wc_SHE_LoadKey_Verify_Label(
const char* label,
void* heap, int devId,
const byte* m1, word32 m1Sz,
const byte* m2, word32 m2Sz,
const byte* m3, word32 m3Sz,
byte* m4, word32 m4Sz,
byte* m5, word32 m5Sz,
const byte* m4Expected, word32 m4ExpectedSz,
const byte* m5Expected, word32 m5ExpectedSz);
#endif /* WOLF_PRIVATE_KEY_ID */
#endif /* WOLF_CRYPTO_CB || !NO_WC_SHE_IMPORT_M123 */
#endif /* !NO_WC_SHE_LOADKEY */
/* Export a key from hardware in SHE loadable format (M1-M5).
* Some HSMs allow exporting certain key slots (e.g. RAM key) so they
* can be re-loaded later via the SHE key update protocol.