Skip to content

LMS: Key ID fixup #8786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions wolfcrypt/src/ext_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,15 @@ int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
return 0;
}

int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid, word32* kidSz)
{
if ((key == NULL) || (kid == NULL) || (kidSz == NULL)) {
return BAD_FUNC_ARG;
}

return NOT_COMPILED_IN;
}

const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz)
{
if ((priv == NULL) || (privSz < 16)) {
Expand Down
32 changes: 30 additions & 2 deletions wolfcrypt/src/wc_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,34 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz,
return ret;
}

/* Get the Key ID from the LMS key.
*
* PRIV = Q | PARAMS | SEED | I
* where I is the Key ID.
*
* @param [in] key LMS key.
* @param [out] kid Key ID data.
* @param [out] kidSz Size of key ID.
* @return 0 on success.
* @return BAD_FUNC_ARG when a key, kid or kidSz is NULL.
*/
int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid, word32* kidSz)
{
word32 offset;

if ((key == NULL) || (kid == NULL) || (kidSz == NULL)) {
return BAD_FUNC_ARG;
}

/* SEED length is hash length. */
offset = HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + key->params->hash_len;
*kid = key->priv_raw + offset;
*kidSz = HSS_PRIVATE_KEY_LEN(key->params->hash_len) - offset;

return 0;
}


/* Get the Key ID from the raw private key data.
*
* PRIV = Q | PARAMS | SEED | I
Expand All @@ -1270,7 +1298,7 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz,
*/
const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz)
{
word32 seedSz = privSz - LMS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN - LMS_I_LEN;
word32 seedSz = privSz - HSS_Q_LEN - HSS_PRIV_KEY_PARAM_SET_LEN - LMS_I_LEN;

if (priv == NULL) {
return NULL;
Expand All @@ -1279,7 +1307,7 @@ const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz)
(seedSz != WC_SHA256_DIGEST_SIZE)) {
return NULL;
}
return priv - LMS_I_LEN;
return priv + privSz - LMS_I_LEN;
}

#endif /* WOLFSSL_HAVE_LMS && WOLFSSL_WC_LMS */
34 changes: 34 additions & 0 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -47891,6 +47891,11 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
#else
byte sig[WC_TEST_LMS_SIG_LEN];
#endif
#if !defined(HAVE_LIBLMS)
const byte * kid;
word32 kidSz;
#endif

WOLFSSL_ENTER("lms_test");

XMEMSET(priv, 0, sizeof(priv));
Expand Down Expand Up @@ -47939,6 +47944,35 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)

XMEMCPY(old_priv, priv, sizeof(priv));

#if !defined(HAVE_LIBLMS)
ret = wc_LmsKey_GetKid(NULL, NULL, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(&signingKey, NULL, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(NULL, &kid, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(NULL, NULL, &kidSz);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(&signingKey, &kid, NULL);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(&signingKey, NULL, &kidSz);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(NULL, &kid, &kidSz);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_LmsKey_GetKid(&signingKey, &kid, &kidSz);
if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); }
if (kidSz != WC_LMS_I_LEN) {
ERROR_OUT(WC_TEST_RET_ENC_I(kidSz), out);
}
#endif

ret = wc_LmsKey_ExportPub(&verifyKey, &signingKey);
if (ret != 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); }

Expand Down
5 changes: 5 additions & 0 deletions wolfssl/wolfcrypt/lms.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@

#ifdef WOLFSSL_HAVE_LMS

/* Length of the Key ID. */
#define WC_LMS_I_LEN 16

typedef struct LmsKey LmsKey;

/* Private key write and read callbacks. */
Expand Down Expand Up @@ -187,6 +190,8 @@ WOLFSSL_API int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
WOLFSSL_API const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm);
WOLFSSL_API const char * wc_LmsKey_RcToStr(enum wc_LmsRc lmsRc);

WOLFSSL_API int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid,
word32* kidSz);
WOLFSSL_API const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv,
word32 privSz);
#ifdef __cplusplus
Expand Down