|
41 | 41 | #include <wolfssl/wolfcrypt/cryptocb.h> |
42 | 42 | #endif |
43 | 43 |
|
44 | | -/* Compute the digest of msg using the hash function dictated by the LMS |
45 | | - * parameter set. Crypto-callback / HSM backends that follow PKCS#11 v3.2 |
46 | | - * CKM_HSS semantics (pre-computed digest input) can call this from within |
47 | | - * their callback; backends that take the raw message (e.g. wolfHSM) can |
48 | | - * ignore it. *hashSz is in/out: it must be at least params->hash_len on |
49 | | - * entry and is set to the actual digest length on success. |
50 | | - * |
51 | | - * @param [in] key LMS key (must have a parameter set bound). |
52 | | - * @param [in] msg Message to hash. |
53 | | - * @param [in] msgSz Length of msg in bytes. |
54 | | - * @param [out] hash Buffer receiving the digest. |
55 | | - * @param [in,out] hashSz On entry, size of hash buffer. On success, |
56 | | - * the digest length. |
57 | | - * @return 0 on success. |
58 | | - * @return BAD_FUNC_ARG when an argument is NULL or the buffer is too |
59 | | - * small for the digest. |
60 | | - * @return NOT_COMPILED_IN when the param set's hash family is disabled. |
61 | | - */ |
62 | | -int wc_LmsKey_HashMsg(const LmsKey* key, const byte* msg, word32 msgSz, |
63 | | - byte* hash, word32* hashSz) |
64 | | -{ |
65 | | - int ret = 0; |
66 | | - word32 needSz; |
67 | | - |
68 | | - if ((key == NULL) || (msg == NULL) || (hash == NULL) || (hashSz == NULL)) |
69 | | - return BAD_FUNC_ARG; |
70 | | - if (key->params == NULL) |
71 | | - return BAD_FUNC_ARG; |
72 | | - needSz = (word32)key->params->hash_len; |
73 | | - if (*hashSz < needSz) |
74 | | - return BAD_FUNC_ARG; |
75 | | - |
76 | | - switch (key->params->lmsType & 0xF000) { |
77 | | - case LMS_SHA256: /* 32-byte SHA-256 */ |
78 | | - case LMS_SHA256_192: /* SHA-256 truncated to 24 bytes */ { |
79 | | - byte full[WC_SHA256_DIGEST_SIZE]; |
80 | | - ret = wc_Sha256Hash(msg, msgSz, full); |
81 | | - if (ret == 0) |
82 | | - XMEMCPY(hash, full, needSz); |
83 | | - break; |
84 | | - } |
85 | | - #ifdef WOLFSSL_LMS_SHAKE256 |
86 | | - case LMS_SHAKE256: /* SHAKE256 with 32-byte output */ |
87 | | - case LMS_SHAKE256_192: /* SHAKE256 with 24-byte output */ { |
88 | | - wc_Shake shake; |
89 | | - ret = wc_InitShake256(&shake, NULL, INVALID_DEVID); |
90 | | - if (ret == 0) { |
91 | | - ret = wc_Shake256_Update(&shake, msg, msgSz); |
92 | | - if (ret == 0) |
93 | | - ret = wc_Shake256_Final(&shake, hash, needSz); |
94 | | - wc_Shake256_Free(&shake); |
95 | | - } |
96 | | - break; |
97 | | - } |
98 | | - #endif |
99 | | - default: |
100 | | - WOLFSSL_MSG("LMS: unsupported hash family for HashMsg"); |
101 | | - ret = NOT_COMPILED_IN; |
102 | | - break; |
103 | | - } |
104 | | - |
105 | | - if (ret == 0) |
106 | | - *hashSz = needSz; |
107 | | - |
108 | | - return ret; |
109 | | -} |
110 | | - |
111 | 44 |
|
112 | 45 | /* Calculate u. Appendix B. Works for w of 1, 2, 4, or 8. |
113 | 46 | * |
@@ -1134,10 +1067,6 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng) |
1134 | 1067 | WOLFSSL_MSG("error: LmsKey write callback is not set"); |
1135 | 1068 | ret = BAD_FUNC_ARG; |
1136 | 1069 | } |
1137 | | - /* Callback context is opaque to wolfCrypt and may legitimately be NULL |
1138 | | - * (e.g. callbacks that read/write a static buffer or HSM-backed keys |
1139 | | - * with stub callbacks); no check needed here. */ |
1140 | | - |
1141 | 1070 | if (ret == 0) { |
1142 | 1071 | const LmsParams* params = key->params; |
1143 | 1072 | priv_data_len = LMS_PRIV_DATA_LEN(params->levels, params->height, |
@@ -1250,7 +1179,6 @@ int wc_LmsKey_Reload(LmsKey* key) |
1250 | 1179 | WOLFSSL_MSG("error: LmsKey read callback is not set"); |
1251 | 1180 | ret = BAD_FUNC_ARG; |
1252 | 1181 | } |
1253 | | - /* Callback context is opaque; NULL is allowed. */ |
1254 | 1182 |
|
1255 | 1183 | if (ret == 0) { |
1256 | 1184 | const LmsParams* params = key->params; |
@@ -1354,6 +1282,66 @@ int wc_LmsKey_GetPrivLen(const LmsKey* key, word32* len) |
1354 | 1282 | return ret; |
1355 | 1283 | } |
1356 | 1284 |
|
| 1285 | +/* Compute the digest of msg using the hash function dictated by the LMS |
| 1286 | + * parameter set. Crypto-callback / HSM backends that follow PKCS#11 v3.2 |
| 1287 | + * CKM_HSS semantics (pre-computed digest input) can call this from within |
| 1288 | + * their callback; backends that take the raw message (e.g. wolfHSM) can |
| 1289 | + * ignore it. *hashSz is in/out: it must be at least params->hash_len on |
| 1290 | + * entry and is set to the actual digest length on success. |
| 1291 | + * |
| 1292 | + * @param [in] key LMS key (must have a parameter set bound). |
| 1293 | + * @param [in] msg Message to hash. |
| 1294 | + * @param [in] msgSz Length of msg in bytes. |
| 1295 | + * @param [out] hash Buffer receiving the digest. |
| 1296 | + * @param [in,out] hashSz On entry, size of hash buffer. On success, |
| 1297 | + * the digest length. |
| 1298 | + * @return 0 on success. |
| 1299 | + * @return BAD_FUNC_ARG when an argument is NULL or the buffer is too |
| 1300 | + * small for the digest. |
| 1301 | + * @return NOT_COMPILED_IN when the param set's hash family is disabled. |
| 1302 | + */ |
| 1303 | +int wc_LmsKey_HashMsg(const LmsKey* key, const byte* msg, word32 msgSz, |
| 1304 | + byte* hash, word32* hashSz) |
| 1305 | +{ |
| 1306 | + int ret = 0; |
| 1307 | + word32 needSz; |
| 1308 | + |
| 1309 | + if ((key == NULL) || (msg == NULL) || (hash == NULL) || (hashSz == NULL)) |
| 1310 | + return BAD_FUNC_ARG; |
| 1311 | + if (key->params == NULL) |
| 1312 | + return BAD_FUNC_ARG; |
| 1313 | + needSz = (word32)key->params->hash_len; |
| 1314 | + if (*hashSz < needSz) |
| 1315 | + return BAD_FUNC_ARG; |
| 1316 | + |
| 1317 | + switch (key->params->lmsType & LMS_HASH_MASK) { |
| 1318 | + case LMS_SHA256: /* 32-byte SHA-256 */ |
| 1319 | + case LMS_SHA256_192: /* SHA-256 truncated to 24 bytes */ { |
| 1320 | + byte full[WC_SHA256_DIGEST_SIZE]; |
| 1321 | + ret = wc_Sha256Hash(msg, msgSz, full); |
| 1322 | + if (ret == 0) |
| 1323 | + XMEMCPY(hash, full, needSz); |
| 1324 | + break; |
| 1325 | + } |
| 1326 | + #ifdef WOLFSSL_LMS_SHAKE256 |
| 1327 | + case LMS_SHAKE256: /* SHAKE256 with 32-byte output */ |
| 1328 | + case LMS_SHAKE256_192: /* SHAKE256 with 24-byte output */ { |
| 1329 | + ret = wc_Shake256Hash(msg, msgSz, hash, needSz); |
| 1330 | + break; |
| 1331 | + } |
| 1332 | + #endif |
| 1333 | + default: |
| 1334 | + WOLFSSL_MSG("LMS: unsupported hash family for HashMsg"); |
| 1335 | + ret = NOT_COMPILED_IN; |
| 1336 | + break; |
| 1337 | + } |
| 1338 | + |
| 1339 | + if (ret == 0) |
| 1340 | + *hashSz = needSz; |
| 1341 | + |
| 1342 | + return ret; |
| 1343 | +} |
| 1344 | + |
1357 | 1345 | /* Sign a message. |
1358 | 1346 | * |
1359 | 1347 | * @param [in, out] key LMS key to sign with. |
@@ -1419,7 +1407,6 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg, |
1419 | 1407 | WOLFSSL_MSG("error: LmsKey write/read callbacks are not set"); |
1420 | 1408 | ret = BAD_FUNC_ARG; |
1421 | 1409 | } |
1422 | | - /* Callback context is opaque; NULL is allowed. */ |
1423 | 1410 |
|
1424 | 1411 | if (ret == 0) { |
1425 | 1412 | WC_DECLARE_VAR(state, LmsState, 1, 0); |
@@ -1493,9 +1480,7 @@ int wc_LmsKey_SigsLeft(LmsKey* key) |
1493 | 1480 | int cbRet = wc_CryptoCb_PqcStatefulSigSigsLeft( |
1494 | 1481 | WC_PQC_STATEFUL_SIG_TYPE_LMS, key, &sigsLeft); |
1495 | 1482 | if (cbRet == 0) { |
1496 | | - /* Clamp to int range; callers treat 0 as "exhausted". */ |
1497 | | - return (sigsLeft > (word32)0x7FFFFFFF) |
1498 | | - ? 0x7FFFFFFF : (int)sigsLeft; |
| 1483 | + return (sigsLeft != 0) ? 1 : 0; |
1499 | 1484 | } |
1500 | 1485 | /* The device owns the private state; no safe software fallback |
1501 | 1486 | * exists because key->priv_raw does not reflect HSM state. */ |
@@ -1734,9 +1719,6 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz, |
1734 | 1719 | if ((key == NULL) || (sig == NULL) || (msg == NULL)) { |
1735 | 1720 | ret = BAD_FUNC_ARG; |
1736 | 1721 | } |
1737 | | - if ((ret == 0) && (msgSz <= 0)) { |
1738 | | - ret = BAD_FUNC_ARG; |
1739 | | - } |
1740 | 1722 | /* Check state. */ |
1741 | 1723 | if ((ret == 0) && (key->state != WC_LMS_STATE_OK) && |
1742 | 1724 | (key->state != WC_LMS_STATE_VERIFYONLY)) { |
|
0 commit comments