Skip to content

Commit 752ca63

Browse files
committed
Fix sha512 buffer copy
1 parent 5ac5385 commit 752ca63

File tree

4 files changed

+240
-30
lines changed

4 files changed

+240
-30
lines changed

src/wh_client_crypto.c

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5249,11 +5249,10 @@ static int _xferSha512BlockAndUpdateDigest(whClientContext* ctx,
52495249
}
52505250

52515251
int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
5252-
uint32_t inLen, uint8_t* out)
5252+
uint32_t inLen, uint8_t* out, int hashType)
52535253
{
52545254
int ret = 0;
52555255
uint8_t* sha512BufferBytes = (uint8_t*)sha512->buffer;
5256-
int hashType = WC_HASH_TYPE_SHA512;
52575256

52585257
/* Caller invoked SHA Update:
52595258
* wc_CryptoCb_Sha512Hash(sha512, data, len, NULL) */
@@ -5291,17 +5290,33 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
52915290
/* Caller invoked SHA finalize:
52925291
* wc_CryptoCb_Sha512Hash(sha512, NULL, 0, * hash) */
52935292
if (ret == 0 && out != NULL) {
5293+
word32 digestSz;
5294+
52945295
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 1);
52955296

5297+
/* Use the hashType from the dispatcher (info->hash.type) to
5298+
* select the correct output size. This is more reliable than
5299+
* sha512->hashType which depends on the wolfSSL port setting
5300+
* it during init. */
5301+
switch (hashType) {
5302+
case WC_HASH_TYPE_SHA512_224:
5303+
digestSz = WC_SHA512_224_DIGEST_SIZE;
5304+
break;
5305+
case WC_HASH_TYPE_SHA512_256:
5306+
digestSz = WC_SHA512_256_DIGEST_SIZE;
5307+
break;
5308+
default:
5309+
digestSz = WC_SHA512_DIGEST_SIZE;
5310+
break;
5311+
}
5312+
52965313
/* Copy out the final hash value */
52975314
if (ret == 0) {
5298-
memcpy(out, sha512->digest, WC_SHA512_DIGEST_SIZE);
5315+
memcpy(out, sha512->digest, digestSz);
52995316
}
5300-
/* keep hashtype before initialization */
5301-
hashType = sha512->hashType;
5302-
/* reset the state of the sha context (without blowing away devId and
5303-
* hashType)
5304-
*/
5317+
5318+
/* Reset the sha context for potential reuse, calling the
5319+
* variant-appropriate init to preserve devId and hashType */
53055320
switch (hashType) {
53065321
case WC_HASH_TYPE_SHA512_224:
53075322
(void)wc_InitSha512_224_ex(sha512, NULL, sha512->devId);
@@ -5320,7 +5335,7 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
53205335

53215336
#ifdef WOLFHSM_CFG_DMA
53225337
int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
5323-
uint32_t inLen, uint8_t* out)
5338+
uint32_t inLen, uint8_t* out, int hashType)
53245339
{
53255340
int ret = WH_ERROR_OK;
53265341
wc_Sha512* sha512 = sha;
@@ -5332,6 +5347,20 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
53325347
uintptr_t inAddr = 0;
53335348
uintptr_t outAddr = 0;
53345349
uintptr_t stateAddr = 0;
5350+
word32 digestSz;
5351+
5352+
/* Select digest size based on variant */
5353+
switch (hashType) {
5354+
case WC_HASH_TYPE_SHA512_224:
5355+
digestSz = WC_SHA512_224_DIGEST_SIZE;
5356+
break;
5357+
case WC_HASH_TYPE_SHA512_256:
5358+
digestSz = WC_SHA512_256_DIGEST_SIZE;
5359+
break;
5360+
default:
5361+
digestSz = WC_SHA512_DIGEST_SIZE;
5362+
break;
5363+
}
53355364

53365365
/* Get data pointer from the context to use as request/response storage */
53375366
dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm);
@@ -5341,12 +5370,12 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
53415370

53425371
/* Setup generic header and get pointer to request data */
53435372
req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest(
5344-
dataPtr, WC_HASH_TYPE_SHA512, ctx->cryptoAffinity);
5373+
dataPtr, hashType, ctx->cryptoAffinity);
53455374

53465375
if (in != NULL || out != NULL) {
53475376
req->state.sz = sizeof(*sha512);
53485377
req->input.sz = inLen;
5349-
req->output.sz = WC_SHA512_DIGEST_SIZE; /* not needed, but YOLO */
5378+
req->output.sz = digestSz;
53505379

53515380
/* Perform address translations */
53525381
ret = wh_Client_DmaProcessClientAddress(
@@ -5396,10 +5425,10 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
53965425
if (ret == WH_ERROR_OK) {
53975426
/* Get response structure pointer, validates generic header
53985427
* rc */
5399-
ret = _getCryptoResponse(dataPtr, WC_HASH_TYPE_SHA512,
5428+
ret = _getCryptoResponse(dataPtr, hashType,
54005429
(uint8_t**)&resp);
5401-
/* Nothing to do on success, as server will have updated the context
5402-
* in client memory */
5430+
/* Nothing to do on success, as server will have updated the
5431+
* context in client memory */
54035432
}
54045433
}
54055434

@@ -5427,10 +5456,10 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
54275456
if (ret == WH_ERROR_OK) {
54285457
/* Get response structure pointer, validates generic header
54295458
* rc */
5430-
ret = _getCryptoResponse(dataPtr, WC_HASH_TYPE_SHA512,
5459+
ret = _getCryptoResponse(dataPtr, hashType,
54315460
(uint8_t**)&resp);
5432-
/* Nothing to do on success, as server will have updated the output
5433-
* hash in client memory */
5461+
/* Nothing to do on success, as server will have updated the
5462+
* output hash in client memory */
54345463
}
54355464
}
54365465

@@ -5442,12 +5471,12 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
54425471
ctx, (uintptr_t)in, (void**)&inAddr, inLen,
54435472
WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0});
54445473
(void)wh_Client_DmaProcessClientAddress(
5445-
ctx, (uintptr_t)out, (void**)&outAddr, WC_SHA512_DIGEST_SIZE,
5474+
ctx, (uintptr_t)out, (void**)&outAddr, digestSz,
54465475
WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0});
54475476
}
54485477
return ret;
54495478
}
5450-
#endif /* WOLFHSM_CFG_DMA */
5479+
#endif /* WOLFHSM_CFG_DMA */
54515480
#endif /* WOLFSSL_SHA512 */
54525481

54535482
#ifdef HAVE_DILITHIUM

src/wh_client_cryptocb.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,21 @@ int wh_Client_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
514514
} break;
515515
#endif /* WOLFSSL_SHA384 */
516516
#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA512_HASHTYPE)
517-
case WC_HASH_TYPE_SHA512: {
517+
case WC_HASH_TYPE_SHA512:
518+
#if !defined(WOLFSSL_NOSHA512_224)
519+
case WC_HASH_TYPE_SHA512_224:
520+
#endif
521+
#if !defined(WOLFSSL_NOSHA512_256)
522+
case WC_HASH_TYPE_SHA512_256:
523+
#endif
524+
{
518525
wc_Sha512* sha = info->hash.sha512;
519526
const uint8_t* in = info->hash.in;
520527
uint32_t inLen = info->hash.inSz;
521528
uint8_t* out = info->hash.digest;
522529

523-
ret = wh_Client_Sha512(ctx, sha, in, inLen, out);
530+
ret = wh_Client_Sha512(ctx, sha, in, inLen,
531+
out, info->hash.type);
524532
} break;
525533
#endif /* WOLFSSL_SHA512 && WOLFSSL_SHA512_HASHTYPE */
526534
default:
@@ -839,15 +847,23 @@ int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx)
839847
} break;
840848
#endif /* WOLFSSL_SHA384 */
841849
#if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA512_HASHTYPE)
842-
case WC_HASH_TYPE_SHA512: {
850+
case WC_HASH_TYPE_SHA512:
851+
#if !defined(WOLFSSL_NOSHA512_224)
852+
case WC_HASH_TYPE_SHA512_224:
853+
#endif
854+
#if !defined(WOLFSSL_NOSHA512_256)
855+
case WC_HASH_TYPE_SHA512_256:
856+
#endif
857+
{
843858
wc_Sha512* sha = info->hash.sha512;
844859
const uint8_t* in = info->hash.in;
845860
uint32_t inLen = info->hash.inSz;
846861
uint8_t* out = info->hash.digest;
847862

848-
ret = wh_Client_Sha512Dma(ctx, sha, in, inLen, out);
863+
ret = wh_Client_Sha512Dma(ctx, sha, in, inLen,
864+
out, info->hash.type);
849865
} break;
850-
#endif /* WOLFSSL_SHA512 && defined(WOLFSSL_SHA512_HASHTYPE) */
866+
#endif /* WOLFSSL_SHA512 && WOLFSSL_SHA512_HASHTYPE */
851867
default:
852868
ret = CRYPTOCB_UNAVAILABLE;
853869
break;

test/wh_test_crypto.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,149 @@ static int whTest_CryptoSha512(whClientContext* ctx, int devId, WC_RNG* rng)
19501950
}
19511951
return ret;
19521952
}
1953+
1954+
#if !defined(WOLFSSL_NOSHA512_224)
1955+
static int whTest_CryptoSha512_224(whClientContext* ctx, int devId,
1956+
WC_RNG* rng)
1957+
{
1958+
(void)ctx;
1959+
(void)rng;
1960+
int ret = WH_ERROR_OK;
1961+
wc_Sha512 sha512[1];
1962+
/* Buffer sized for the variant, plus canary to detect overwrite */
1963+
uint8_t out[WC_SHA512_224_DIGEST_SIZE + 8];
1964+
const uint8_t canary = 0xA5;
1965+
/* Same one-block input vector as the SHA512 test */
1966+
const char inOne[] =
1967+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1968+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1969+
const uint8_t expectedOut[WC_SHA512_224_DIGEST_SIZE] = {
1970+
0x26, 0x1b, 0x94, 0xbc, 0xba, 0x55, 0x42, 0x64,
1971+
0xb3, 0xb7, 0x38, 0xe9, 0xe0, 0x9e, 0x7d, 0xc6,
1972+
0x8a, 0xc8, 0xe0, 0xb4, 0xc8, 0x51, 0x7f, 0xe9,
1973+
0xbb, 0x7c, 0x36, 0x17};
1974+
1975+
/* Fill canary bytes after the digest area */
1976+
memset(out, canary, sizeof(out));
1977+
1978+
ret = wc_InitSha512_224_ex(sha512, NULL, devId);
1979+
if (ret != 0) {
1980+
WH_ERROR_PRINT("Failed to wc_InitSha512_224 on devId 0x%X: "
1981+
"%d\n", devId, ret);
1982+
}
1983+
else {
1984+
ret = wc_Sha512_224Update(sha512, (const byte*)inOne,
1985+
WC_SHA512_BLOCK_SIZE);
1986+
if (ret != 0) {
1987+
WH_ERROR_PRINT("Failed to wc_Sha512_224Update %d\n", ret);
1988+
}
1989+
else {
1990+
ret = wc_Sha512_224Final(sha512, out);
1991+
if (ret != 0) {
1992+
WH_ERROR_PRINT("Failed to wc_Sha512_224Final %d\n",
1993+
ret);
1994+
}
1995+
else {
1996+
if (memcmp(out, expectedOut,
1997+
WC_SHA512_224_DIGEST_SIZE) != 0) {
1998+
WH_ERROR_PRINT("SHA512/224 hash mismatch.\n");
1999+
ret = -1;
2000+
}
2001+
else {
2002+
/* Verify canary was not overwritten */
2003+
int i;
2004+
for (i = WC_SHA512_224_DIGEST_SIZE;
2005+
i < (int)sizeof(out); i++) {
2006+
if (out[i] != canary) {
2007+
WH_ERROR_PRINT("SHA512/224 overwrote "
2008+
"buffer at byte %d\n", i);
2009+
ret = -1;
2010+
break;
2011+
}
2012+
}
2013+
}
2014+
}
2015+
}
2016+
(void)wc_Sha512_224Free(sha512);
2017+
}
2018+
if (ret == 0) {
2019+
WH_TEST_PRINT("SHA512/224 DEVID=0x%X SUCCESS\n", devId);
2020+
}
2021+
return ret;
2022+
}
2023+
#endif /* !WOLFSSL_NOSHA512_224 */
2024+
2025+
#if !defined(WOLFSSL_NOSHA512_256)
2026+
static int whTest_CryptoSha512_256(whClientContext* ctx, int devId,
2027+
WC_RNG* rng)
2028+
{
2029+
(void)ctx;
2030+
(void)rng;
2031+
int ret = WH_ERROR_OK;
2032+
wc_Sha512 sha512[1];
2033+
/* Buffer sized for the variant, plus canary to detect overwrite */
2034+
uint8_t out[WC_SHA512_256_DIGEST_SIZE + 8];
2035+
const uint8_t canary = 0xA5;
2036+
/* Same one-block input vector as the SHA512 test */
2037+
const char inOne[] =
2038+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
2039+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
2040+
const uint8_t expectedOut[WC_SHA512_256_DIGEST_SIZE] = {
2041+
0xb8, 0x8f, 0x97, 0xe2, 0x74, 0xf9, 0xc1, 0xd4,
2042+
0x9f, 0x18, 0x1c, 0x8c, 0xbd, 0x01, 0xa9, 0xc7,
2043+
0x49, 0x30, 0xad, 0x05, 0x5a, 0x46, 0xac, 0x44,
2044+
0x99, 0xa1, 0xd6, 0x01, 0xf1, 0xc8, 0x0b, 0xf2};
2045+
2046+
/* Fill canary bytes after the digest area */
2047+
memset(out, canary, sizeof(out));
2048+
2049+
ret = wc_InitSha512_256_ex(sha512, NULL, devId);
2050+
if (ret != 0) {
2051+
WH_ERROR_PRINT("Failed to wc_InitSha512_256 on devId 0x%X: "
2052+
"%d\n", devId, ret);
2053+
}
2054+
else {
2055+
ret = wc_Sha512_256Update(sha512, (const byte*)inOne,
2056+
WC_SHA512_BLOCK_SIZE);
2057+
if (ret != 0) {
2058+
WH_ERROR_PRINT("Failed to wc_Sha512_256Update %d\n", ret);
2059+
}
2060+
else {
2061+
ret = wc_Sha512_256Final(sha512, out);
2062+
if (ret != 0) {
2063+
WH_ERROR_PRINT("Failed to wc_Sha512_256Final %d\n",
2064+
ret);
2065+
}
2066+
else {
2067+
if (memcmp(out, expectedOut,
2068+
WC_SHA512_256_DIGEST_SIZE) != 0) {
2069+
WH_ERROR_PRINT("SHA512/256 hash mismatch.\n");
2070+
ret = -1;
2071+
}
2072+
else {
2073+
/* Verify canary was not overwritten */
2074+
int i;
2075+
for (i = WC_SHA512_256_DIGEST_SIZE;
2076+
i < (int)sizeof(out); i++) {
2077+
if (out[i] != canary) {
2078+
WH_ERROR_PRINT("SHA512/256 overwrote "
2079+
"buffer at byte %d\n", i);
2080+
ret = -1;
2081+
break;
2082+
}
2083+
}
2084+
}
2085+
}
2086+
}
2087+
(void)wc_Sha512_256Free(sha512);
2088+
}
2089+
if (ret == 0) {
2090+
WH_TEST_PRINT("SHA512/256 DEVID=0x%X SUCCESS\n", devId);
2091+
}
2092+
return ret;
2093+
}
2094+
#endif /* !WOLFSSL_NOSHA512_256 */
2095+
19532096
#endif /* WOLFSSL_SHA512 */
19542097

19552098
#ifdef HAVE_HKDF
@@ -5915,6 +6058,24 @@ int whTest_CryptoClientConfig(whClientConfig* config)
59156058
i++;
59166059
}
59176060
}
6061+
#if !defined(WOLFSSL_NOSHA512_224)
6062+
i = 0;
6063+
while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) {
6064+
ret = whTest_CryptoSha512_224(client, WH_DEV_IDS_ARRAY[i], rng);
6065+
if (ret == WH_ERROR_OK) {
6066+
i++;
6067+
}
6068+
}
6069+
#endif /* !WOLFSSL_NOSHA512_224 */
6070+
#if !defined(WOLFSSL_NOSHA512_256)
6071+
i = 0;
6072+
while ((ret == WH_ERROR_OK) && (i < WH_NUM_DEVIDS)) {
6073+
ret = whTest_CryptoSha512_256(client, WH_DEV_IDS_ARRAY[i], rng);
6074+
if (ret == WH_ERROR_OK) {
6075+
i++;
6076+
}
6077+
}
6078+
#endif /* !WOLFSSL_NOSHA512_256 */
59186079
#endif /* WOLFSSL_SHA512 */
59196080

59206081
#ifdef HAVE_HKDF

0 commit comments

Comments
 (0)