|
38 | 38 |
|
39 | 39 | #ifdef WOLF_CRYPTO_CB |
40 | 40 | #include <wolfssl/wolfcrypt/cryptocb.h> |
| 41 | + |
| 42 | +/* Pre-compute the message digest with the hash function dictated by the XMSS |
| 43 | + * parameter set. PKCS#11 v3.2 section 6.66 specifies that CKM_XMSS and |
| 44 | + * CKM_XMSSMT take the pre-computed digest, not the raw message (the section |
| 45 | + * is titled "XMSS and XMSSMT without hashing"), so every Sign/Verify |
| 46 | + * dispatch through the crypto-callback layer funnels through this helper. */ |
| 47 | +static int wc_xmss_hash_msg(const XmssParams* params, const byte* msg, |
| 48 | + word32 msgSz, byte* hash, word32 hashSz) |
| 49 | +{ |
| 50 | + int ret = 0; |
| 51 | + |
| 52 | + if ((params == NULL) || (msg == NULL) || (hash == NULL)) |
| 53 | + return BAD_FUNC_ARG; |
| 54 | + if (hashSz != params->n) |
| 55 | + return BAD_FUNC_ARG; |
| 56 | + |
| 57 | + switch (params->hash) { |
| 58 | + #ifdef WC_XMSS_SHA256 |
| 59 | + case WC_HASH_TYPE_SHA256: |
| 60 | + ret = wc_Hash(WC_HASH_TYPE_SHA256, msg, msgSz, hash, hashSz); |
| 61 | + break; |
| 62 | + #endif |
| 63 | + #ifdef WC_XMSS_SHA512 |
| 64 | + case WC_HASH_TYPE_SHA512: |
| 65 | + ret = wc_Hash(WC_HASH_TYPE_SHA512, msg, msgSz, hash, hashSz); |
| 66 | + break; |
| 67 | + #endif |
| 68 | + #ifdef WC_XMSS_SHAKE128 |
| 69 | + case WC_HASH_TYPE_SHAKE128: { |
| 70 | + wc_Shake shake; |
| 71 | + ret = wc_InitShake128(&shake, NULL, INVALID_DEVID); |
| 72 | + if (ret == 0) { |
| 73 | + ret = wc_Shake128_Update(&shake, msg, msgSz); |
| 74 | + if (ret == 0) |
| 75 | + ret = wc_Shake128_Final(&shake, hash, hashSz); |
| 76 | + wc_Shake128_Free(&shake); |
| 77 | + } |
| 78 | + break; |
| 79 | + } |
| 80 | + #endif |
| 81 | + #ifdef WC_XMSS_SHAKE256 |
| 82 | + case WC_HASH_TYPE_SHAKE256: { |
| 83 | + wc_Shake shake; |
| 84 | + ret = wc_InitShake256(&shake, NULL, INVALID_DEVID); |
| 85 | + if (ret == 0) { |
| 86 | + ret = wc_Shake256_Update(&shake, msg, msgSz); |
| 87 | + if (ret == 0) |
| 88 | + ret = wc_Shake256_Final(&shake, hash, hashSz); |
| 89 | + wc_Shake256_Free(&shake); |
| 90 | + } |
| 91 | + break; |
| 92 | + } |
| 93 | + #endif |
| 94 | + default: |
| 95 | + WOLFSSL_MSG("XMSS: unsupported hash for CryptoCb pre-hash"); |
| 96 | + ret = NOT_COMPILED_IN; |
| 97 | + break; |
| 98 | + } |
| 99 | + |
| 100 | + return ret; |
| 101 | +} |
41 | 102 | #endif |
42 | 103 |
|
43 | 104 |
|
@@ -1351,8 +1412,13 @@ int wc_XmssKey_Sign(XmssKey* key, byte* sig, word32* sigLen, const byte* msg, |
1351 | 1412 | * device owns the private state. On CRYPTOCB_UNAVAILABLE fall-through the |
1352 | 1413 | * software checks below still run. */ |
1353 | 1414 | if ((ret == 0) && (key->devId != INVALID_DEVID)) { |
1354 | | - ret = wc_CryptoCb_PqcStatefulSigSign(msg, (word32)msgLen, sig, sigLen, |
1355 | | - WC_PQC_STATEFUL_SIG_TYPE_XMSS, key); |
| 1415 | + byte hash[WC_XMSS_MAX_N]; |
| 1416 | + word32 hashSz = key->params->n; |
| 1417 | + ret = wc_xmss_hash_msg(key->params, msg, (word32)msgLen, hash, hashSz); |
| 1418 | + if (ret == 0) { |
| 1419 | + ret = wc_CryptoCb_PqcStatefulSigSign(hash, hashSz, sig, sigLen, |
| 1420 | + WC_PQC_STATEFUL_SIG_TYPE_XMSS, key); |
| 1421 | + } |
1356 | 1422 | if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) |
1357 | 1423 | return ret; |
1358 | 1424 | ret = 0; /* fall through to software path */ |
@@ -1498,6 +1564,12 @@ int wc_XmssKey_ExportPub(XmssKey* keyDst, const XmssKey* keySrc) |
1498 | 1564 | keyDst->oid = keySrc->oid; |
1499 | 1565 | keyDst->is_xmssmt = keySrc->is_xmssmt; |
1500 | 1566 | keyDst->params = keySrc->params; |
| 1567 | + |
| 1568 | + #ifdef WOLF_CRYPTO_CB |
| 1569 | + /* Preserve the source key's device binding so the verify-only |
| 1570 | + * copy dispatches through the same crypto callback. */ |
| 1571 | + keyDst->devId = keySrc->devId; |
| 1572 | + #endif |
1501 | 1573 | } |
1502 | 1574 | if (ret == 0) { |
1503 | 1575 | /* Mark keyDst as verify only, to prevent misuse. */ |
@@ -1693,9 +1765,14 @@ int wc_XmssKey_Verify(XmssKey* key, const byte* sig, word32 sigLen, |
1693 | 1765 |
|
1694 | 1766 | #ifdef WOLF_CRYPTO_CB |
1695 | 1767 | if ((ret == 0) && (key->devId != INVALID_DEVID)) { |
| 1768 | + byte hash[WC_XMSS_MAX_N]; |
| 1769 | + word32 hashSz = key->params->n; |
1696 | 1770 | int res = 0; |
1697 | | - ret = wc_CryptoCb_PqcStatefulSigVerify(sig, sigLen, m, (word32)mLen, |
1698 | | - &res, WC_PQC_STATEFUL_SIG_TYPE_XMSS, key); |
| 1771 | + ret = wc_xmss_hash_msg(key->params, m, (word32)mLen, hash, hashSz); |
| 1772 | + if (ret == 0) { |
| 1773 | + ret = wc_CryptoCb_PqcStatefulSigVerify(sig, sigLen, hash, hashSz, |
| 1774 | + &res, WC_PQC_STATEFUL_SIG_TYPE_XMSS, key); |
| 1775 | + } |
1699 | 1776 | if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { |
1700 | 1777 | if (ret == 0 && res != 1) |
1701 | 1778 | ret = SIG_VERIFY_E; |
|
0 commit comments