Skip to content

Commit 2711970

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

4 files changed

Lines changed: 561 additions & 30 deletions

File tree

src/wh_client_crypto.c

Lines changed: 130 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5162,7 +5162,8 @@ int wh_Client_Sha384Dma(whClientContext* ctx, wc_Sha384* sha, const uint8_t* in,
51625162

51635163
static int _xferSha512BlockAndUpdateDigest(whClientContext* ctx,
51645164
wc_Sha512* sha512,
5165-
uint32_t isLastBlock)
5165+
uint32_t isLastBlock,
5166+
int hashType)
51665167
{
51675168
uint16_t group = WH_MESSAGE_GROUP_CRYPTO;
51685169
uint16_t action = WH_MESSAGE_ACTION_NONE;
@@ -5199,10 +5200,13 @@ static int _xferSha512BlockAndUpdateDigest(whClientContext* ctx,
51995200

52005201
/* Send the hash state - this will be 0 on the first block on a properly
52015202
* initialized sha512 struct */
5203+
/* Source hashType from the dispatcher (info->hash.type) rather
5204+
* than sha512->hashType, since some wolfSSL ports do not
5205+
* populate the struct field. */
52025206
memcpy(req->resumeState.hash, sha512->digest, WC_SHA512_DIGEST_SIZE);
52035207
req->resumeState.hiLen = sha512->hiLen;
52045208
req->resumeState.loLen = sha512->loLen;
5205-
req->resumeState.hashType = sha512->hashType;
5209+
req->resumeState.hashType = hashType;
52065210
uint32_t req_len =
52075211
sizeof(whMessageCrypto_GenericRequestHeader) + sizeof(*req);
52085212

@@ -5232,7 +5236,7 @@ static int _xferSha512BlockAndUpdateDigest(whClientContext* ctx,
52325236
/* wolfCrypt allows positive error codes on success in some scenarios */
52335237
if (ret >= 0) {
52345238
WH_DEBUG_CLIENT_VERBOSE("Client SHA512 Res recv: ret=%d", ret);
5235-
WH_DEBUG_CLIENT_VERBOSE("hashType: %d\n", sha512->hashType);
5239+
WH_DEBUG_CLIENT_VERBOSE("hashType: %d\n", hashType);
52365240
/* Store the received intermediate hash in the sha512
52375241
* context and indicate the field is now valid and
52385242
* should be passed back and forth to the server */
@@ -5248,12 +5252,18 @@ static int _xferSha512BlockAndUpdateDigest(whClientContext* ctx,
52485252
return ret;
52495253
}
52505254

5251-
int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
5252-
uint32_t inLen, uint8_t* out)
5255+
/* Shared implementation for SHA-512 and its truncated variants
5256+
* (SHA-512/224, SHA-512/256). The hashType parameter selects the
5257+
* output digest size and the variant-appropriate re-init on
5258+
* finalize. Sourcing hashType from the caller (the dispatcher)
5259+
* rather than sha512->hashType avoids a dependency on the wolfSSL
5260+
* port populating that struct field. */
5261+
static int _doSha512(whClientContext* ctx, wc_Sha512* sha512,
5262+
const uint8_t* in, uint32_t inLen, uint8_t* out,
5263+
int hashType)
52535264
{
52545265
int ret = 0;
52555266
uint8_t* sha512BufferBytes = (uint8_t*)sha512->buffer;
5256-
int hashType = WC_HASH_TYPE_SHA512;
52575267

52585268
/* Caller invoked SHA Update:
52595269
* wc_CryptoCb_Sha512Hash(sha512, data, len, NULL) */
@@ -5268,15 +5278,16 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
52685278
sha512BufferBytes[sha512->buffLen++] = in[i++];
52695279
}
52705280
if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
5271-
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 0);
5281+
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 0,
5282+
hashType);
52725283
sha512->buffLen = 0;
52735284
}
52745285
}
52755286

52765287
/* Process as many full blocks from the input data as we can */
52775288
while (ret == 0 && (inLen - i) >= WC_SHA512_BLOCK_SIZE) {
52785289
memcpy(sha512BufferBytes, in + i, WC_SHA512_BLOCK_SIZE);
5279-
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 0);
5290+
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 0, hashType);
52805291
i += WC_SHA512_BLOCK_SIZE;
52815292
}
52825293

@@ -5291,17 +5302,33 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
52915302
/* Caller invoked SHA finalize:
52925303
* wc_CryptoCb_Sha512Hash(sha512, NULL, 0, * hash) */
52935304
if (ret == 0 && out != NULL) {
5294-
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 1);
5305+
word32 digestSz;
5306+
5307+
ret = _xferSha512BlockAndUpdateDigest(ctx, sha512, 1, hashType);
5308+
5309+
/* Use the hashType from the dispatcher (info->hash.type) to
5310+
* select the correct output size. This is more reliable than
5311+
* sha512->hashType which depends on the wolfSSL port setting
5312+
* it during init. */
5313+
switch (hashType) {
5314+
case WC_HASH_TYPE_SHA512_224:
5315+
digestSz = WC_SHA512_224_DIGEST_SIZE;
5316+
break;
5317+
case WC_HASH_TYPE_SHA512_256:
5318+
digestSz = WC_SHA512_256_DIGEST_SIZE;
5319+
break;
5320+
default:
5321+
digestSz = WC_SHA512_DIGEST_SIZE;
5322+
break;
5323+
}
52955324

52965325
/* Copy out the final hash value */
52975326
if (ret == 0) {
5298-
memcpy(out, sha512->digest, WC_SHA512_DIGEST_SIZE);
5327+
memcpy(out, sha512->digest, digestSz);
52995328
}
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-
*/
5329+
5330+
/* Reset the sha context for potential reuse, calling the
5331+
* variant-appropriate init to preserve devId and hashType */
53055332
switch (hashType) {
53065333
case WC_HASH_TYPE_SHA512_224:
53075334
(void)wc_InitSha512_224_ex(sha512, NULL, sha512->devId);
@@ -5318,9 +5345,32 @@ int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha512, const uint8_t* in,
53185345
return ret;
53195346
}
53205347

5348+
int wh_Client_Sha512(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
5349+
uint32_t inLen, uint8_t* out)
5350+
{
5351+
return _doSha512(ctx, sha, in, inLen, out, WC_HASH_TYPE_SHA512);
5352+
}
5353+
5354+
#if !defined(WOLFSSL_NOSHA512_224)
5355+
int wh_Client_Sha512_224(whClientContext* ctx, wc_Sha512* sha,
5356+
const uint8_t* in, uint32_t inLen, uint8_t* out)
5357+
{
5358+
return _doSha512(ctx, sha, in, inLen, out, WC_HASH_TYPE_SHA512_224);
5359+
}
5360+
#endif /* !WOLFSSL_NOSHA512_224 */
5361+
5362+
#if !defined(WOLFSSL_NOSHA512_256)
5363+
int wh_Client_Sha512_256(whClientContext* ctx, wc_Sha512* sha,
5364+
const uint8_t* in, uint32_t inLen, uint8_t* out)
5365+
{
5366+
return _doSha512(ctx, sha, in, inLen, out, WC_HASH_TYPE_SHA512_256);
5367+
}
5368+
#endif /* !WOLFSSL_NOSHA512_256 */
5369+
53215370
#ifdef WOLFHSM_CFG_DMA
5322-
int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
5323-
uint32_t inLen, uint8_t* out)
5371+
static int _doSha512Dma(whClientContext* ctx, wc_Sha512* sha,
5372+
const uint8_t* in, uint32_t inLen, uint8_t* out,
5373+
int hashType)
53245374
{
53255375
int ret = WH_ERROR_OK;
53265376
wc_Sha512* sha512 = sha;
@@ -5332,21 +5382,50 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
53325382
uintptr_t inAddr = 0;
53335383
uintptr_t outAddr = 0;
53345384
uintptr_t stateAddr = 0;
5385+
word32 digestSz;
5386+
5387+
/* Select digest size based on variant */
5388+
switch (hashType) {
5389+
case WC_HASH_TYPE_SHA512_224:
5390+
if (sha->hashType != WC_HASH_TYPE_SHA512_224) {
5391+
return WH_ERROR_BADARGS;
5392+
}
5393+
digestSz = WC_SHA512_224_DIGEST_SIZE;
5394+
break;
5395+
case WC_HASH_TYPE_SHA512_256:
5396+
if (sha->hashType != WC_HASH_TYPE_SHA512_256) {
5397+
return WH_ERROR_BADARGS;
5398+
}
5399+
digestSz = WC_SHA512_256_DIGEST_SIZE;
5400+
break;
5401+
default:
5402+
/* No sha->hashType match required here: many wolfcrypt
5403+
* ports do not populate the field, and this path uses
5404+
* the maximum digest size (WC_SHA512_DIGEST_SIZE), so
5405+
* the server cannot write past the mapped region no
5406+
* matter which Final variant it dispatches. */
5407+
digestSz = WC_SHA512_DIGEST_SIZE;
5408+
break;
5409+
}
53355410

53365411
/* Get data pointer from the context to use as request/response storage */
53375412
dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm);
53385413
if (dataPtr == NULL) {
53395414
return WH_ERROR_BADARGS;
53405415
}
53415416

5342-
/* Setup generic header and get pointer to request data */
5417+
/* Setup generic header and get pointer to request data. The
5418+
* algorithm-category is always WC_HASH_TYPE_SHA512 at this layer;
5419+
* the server's top-level dispatcher keys on this to find the
5420+
* SHA512 handler. The specific variant (512/224/256) is handled
5421+
* internally via sha512->hashType on the server side. */
53435422
req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest(
53445423
dataPtr, WC_HASH_TYPE_SHA512, ctx->cryptoAffinity);
53455424

53465425
if (in != NULL || out != NULL) {
53475426
req->state.sz = sizeof(*sha512);
53485427
req->input.sz = inLen;
5349-
req->output.sz = WC_SHA512_DIGEST_SIZE; /* not needed, but YOLO */
5428+
req->output.sz = digestSz;
53505429

53515430
/* Perform address translations */
53525431
ret = wh_Client_DmaProcessClientAddress(
@@ -5398,8 +5477,8 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
53985477
* rc */
53995478
ret = _getCryptoResponse(dataPtr, WC_HASH_TYPE_SHA512,
54005479
(uint8_t**)&resp);
5401-
/* Nothing to do on success, as server will have updated the context
5402-
* in client memory */
5480+
/* Nothing to do on success, as server will have updated the
5481+
* context in client memory */
54035482
}
54045483
}
54055484

@@ -5429,8 +5508,8 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
54295508
* rc */
54305509
ret = _getCryptoResponse(dataPtr, WC_HASH_TYPE_SHA512,
54315510
(uint8_t**)&resp);
5432-
/* Nothing to do on success, as server will have updated the output
5433-
* hash in client memory */
5511+
/* Nothing to do on success, as server will have updated the
5512+
* output hash in client memory */
54345513
}
54355514
}
54365515

@@ -5442,12 +5521,38 @@ int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha, const uint8_t* in,
54425521
ctx, (uintptr_t)in, (void**)&inAddr, inLen,
54435522
WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0});
54445523
(void)wh_Client_DmaProcessClientAddress(
5445-
ctx, (uintptr_t)out, (void**)&outAddr, WC_SHA512_DIGEST_SIZE,
5524+
ctx, (uintptr_t)out, (void**)&outAddr, digestSz,
54465525
WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0});
54475526
}
54485527
return ret;
54495528
}
5450-
#endif /* WOLFHSM_CFG_DMA */
5529+
5530+
int wh_Client_Sha512Dma(whClientContext* ctx, wc_Sha512* sha,
5531+
const uint8_t* in, uint32_t inLen, uint8_t* out)
5532+
{
5533+
return _doSha512Dma(ctx, sha, in, inLen, out, WC_HASH_TYPE_SHA512);
5534+
}
5535+
5536+
#if !defined(WOLFSSL_NOSHA512_224)
5537+
int wh_Client_Sha512_224Dma(whClientContext* ctx, wc_Sha512* sha,
5538+
const uint8_t* in, uint32_t inLen,
5539+
uint8_t* out)
5540+
{
5541+
return _doSha512Dma(ctx, sha, in, inLen, out,
5542+
WC_HASH_TYPE_SHA512_224);
5543+
}
5544+
#endif /* !WOLFSSL_NOSHA512_224 */
5545+
5546+
#if !defined(WOLFSSL_NOSHA512_256)
5547+
int wh_Client_Sha512_256Dma(whClientContext* ctx, wc_Sha512* sha,
5548+
const uint8_t* in, uint32_t inLen,
5549+
uint8_t* out)
5550+
{
5551+
return _doSha512Dma(ctx, sha, in, inLen, out,
5552+
WC_HASH_TYPE_SHA512_256);
5553+
}
5554+
#endif /* !WOLFSSL_NOSHA512_256 */
5555+
#endif /* WOLFHSM_CFG_DMA */
54515556
#endif /* WOLFSSL_SHA512 */
54525557

54535558
#ifdef HAVE_DILITHIUM

src/wh_client_cryptocb.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,26 @@ int wh_Client_CryptoCb(int devId, wc_CryptoInfo* info, void* inCtx)
522522

523523
ret = wh_Client_Sha512(ctx, sha, in, inLen, out);
524524
} break;
525+
#if !defined(WOLFSSL_NOSHA512_224)
526+
case WC_HASH_TYPE_SHA512_224: {
527+
wc_Sha512* sha = info->hash.sha512;
528+
const uint8_t* in = info->hash.in;
529+
uint32_t inLen = info->hash.inSz;
530+
uint8_t* out = info->hash.digest;
531+
532+
ret = wh_Client_Sha512_224(ctx, sha, in, inLen, out);
533+
} break;
534+
#endif /* !WOLFSSL_NOSHA512_224 */
535+
#if !defined(WOLFSSL_NOSHA512_256)
536+
case WC_HASH_TYPE_SHA512_256: {
537+
wc_Sha512* sha = info->hash.sha512;
538+
const uint8_t* in = info->hash.in;
539+
uint32_t inLen = info->hash.inSz;
540+
uint8_t* out = info->hash.digest;
541+
542+
ret = wh_Client_Sha512_256(ctx, sha, in, inLen, out);
543+
} break;
544+
#endif /* !WOLFSSL_NOSHA512_256 */
525545
#endif /* WOLFSSL_SHA512 && WOLFSSL_SHA512_HASHTYPE */
526546
default:
527547
ret = CRYPTOCB_UNAVAILABLE;
@@ -847,7 +867,27 @@ int wh_Client_CryptoCbDma(int devId, wc_CryptoInfo* info, void* inCtx)
847867

848868
ret = wh_Client_Sha512Dma(ctx, sha, in, inLen, out);
849869
} break;
850-
#endif /* WOLFSSL_SHA512 && defined(WOLFSSL_SHA512_HASHTYPE) */
870+
#if !defined(WOLFSSL_NOSHA512_224)
871+
case WC_HASH_TYPE_SHA512_224: {
872+
wc_Sha512* sha = info->hash.sha512;
873+
const uint8_t* in = info->hash.in;
874+
uint32_t inLen = info->hash.inSz;
875+
uint8_t* out = info->hash.digest;
876+
877+
ret = wh_Client_Sha512_224Dma(ctx, sha, in, inLen, out);
878+
} break;
879+
#endif /* !WOLFSSL_NOSHA512_224 */
880+
#if !defined(WOLFSSL_NOSHA512_256)
881+
case WC_HASH_TYPE_SHA512_256: {
882+
wc_Sha512* sha = info->hash.sha512;
883+
const uint8_t* in = info->hash.in;
884+
uint32_t inLen = info->hash.inSz;
885+
uint8_t* out = info->hash.digest;
886+
887+
ret = wh_Client_Sha512_256Dma(ctx, sha, in, inLen, out);
888+
} break;
889+
#endif /* !WOLFSSL_NOSHA512_256 */
890+
#endif /* WOLFSSL_SHA512 && WOLFSSL_SHA512_HASHTYPE */
851891
default:
852892
ret = CRYPTOCB_UNAVAILABLE;
853893
break;

0 commit comments

Comments
 (0)