Add buffer size and callback checks to wc_LmsKey_Sign

Fixes ZD#21439
This commit is contained in:
Josh Holtrop
2026-03-26 15:20:02 -04:00
parent 7efc962d04
commit 048a03e8bf
2 changed files with 54 additions and 0 deletions
+21
View File
@@ -963,6 +963,11 @@ int wc_LmsKey_GetPrivLen(const LmsKey* key, word32* len)
* @return 0 on success.
* @return BAD_FUNC_ARG when key, sig, sigSz or msg is NULL.
* @return BAD_FUNC_ARG when msgSz is not greater than 0.
* @return BAD_FUNC_ARG when a write private key is not set.
* @return BAD_FUNC_ARG when a read/write private key context is not set.
* @return BUFFER_E when sigSz is too small.
* @return BAD_STATE_E when wrong state for operation.
* @return IO_FAILED_E when reading or writing private key failed.
*/
int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
int msgSz)
@@ -987,6 +992,22 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
WOLFSSL_MSG("error: can't sign, LMS key not in good state");
ret = BAD_STATE_E;
}
/* Check signature buffer size. */
if ((ret == 0) && (*sigSz < key->params->sig_len)) {
/* Signature buffer too small. */
WOLFSSL_MSG("error: LMS sig buffer too small");
ret = BUFFER_E;
}
/* Check read and write callbacks available. */
if ((ret == 0) && (key->write_private_key == NULL)) {
WOLFSSL_MSG("error: LmsKey write/read callbacks are not set");
ret = BAD_FUNC_ARG;
}
/* Check read/write callback context available. */
if ((ret == 0) && (key->context == NULL)) {
WOLFSSL_MSG("error: LmsKey context is not set");
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
WC_DECLARE_VAR(state, LmsState, 1, 0);
+33
View File
@@ -51593,6 +51593,39 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
ERROR_OUT(WC_TEST_RET_ENC_I(sigSz), out);
}
/* Test wc_LmsKey_Sign input validation. */
{
word32 smallSz = 1;
wc_lms_write_private_key_cb saved_write_cb;
void* saved_ctx;
/* Undersized sig buffer should return BUFFER_E. */
ret = wc_LmsKey_Sign(&signingKey, sig, &smallSz, (byte *) msg, msgSz);
if (ret != WC_NO_ERR_TRACE(BUFFER_E)) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
/* NULL write callback should return BAD_FUNC_ARG. */
saved_write_cb = signingKey.write_private_key;
signingKey.write_private_key = NULL;
ret = wc_LmsKey_Sign(&signingKey, sig, &sigSz, (byte *) msg, msgSz);
signingKey.write_private_key = saved_write_cb;
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
/* NULL context should return BAD_FUNC_ARG. */
saved_ctx = signingKey.context;
signingKey.context = NULL;
ret = wc_LmsKey_Sign(&signingKey, sig, &sigSz, (byte *) msg, msgSz);
signingKey.context = saved_ctx;
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
ret = 0;
}
/* 2 ** 5 should be the max number of signatures */
for (i = 0; i < 32; ++i) {
/* We should have remaining signstures. */