Skip to content

Commit dfbc8af

Browse files
committed
- Fix async AES CBC IV handling for streaming CBC
- Move new async AES CBC test to wh_test_crypto.c, no longer needs to be sequential
1 parent a2e05f5 commit dfbc8af

3 files changed

Lines changed: 112 additions & 75 deletions

File tree

src/wh_client_crypto.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,14 +1134,11 @@ int wh_Client_AesCbcResponse(whClientContext* ctx, Aes* aes, uint8_t* out,
11341134
ret = _getCryptoResponse(dataPtr, WC_CIPHER_AES_CBC, (uint8_t**)&res);
11351135
if (ret == WH_ERROR_OK) {
11361136
uint8_t* res_out = (uint8_t*)(res + 1);
1137+
uint8_t* res_iv = res_out + res->sz;
11371138
memcpy(out, res_out, res->sz);
1138-
/* For encryption, update the IV with the last ciphertext
1139-
* block for CBC chaining */
1140-
if (res->sz >= AES_BLOCK_SIZE) {
1141-
uint32_t last_offset =
1142-
((res->sz / AES_BLOCK_SIZE) - 1) * AES_BLOCK_SIZE;
1143-
memcpy((uint8_t*)aes->reg, out + last_offset, AES_IV_SIZE);
1144-
}
1139+
/* Update the IV from the server response for CBC chaining.
1140+
* The server provides the updated IV after the output data. */
1141+
memcpy((uint8_t*)aes->reg, res_iv, AES_IV_SIZE);
11451142
if (out_size != NULL) {
11461143
*out_size = res->sz;
11471144
}

test/wh_test_clientserver.c

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -507,69 +507,6 @@ static int _clientServerSequentialTestConnectCb(void* context,
507507
connected);
508508
}
509509

510-
#if !defined(WOLFHSM_CFG_NO_CRYPTO)
511-
#ifdef HAVE_AES_CBC
512-
static int _testAesCbcRequestResponse(whClientContext* client,
513-
whServerContext* server)
514-
{
515-
Aes aes[1];
516-
uint8_t key[AES_BLOCK_SIZE] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
517-
0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
518-
0x77, 0x88, 0x99, 0x00};
519-
uint8_t iv[AES_BLOCK_SIZE] = {0};
520-
uint8_t plainIn[AES_BLOCK_SIZE] = {0x77, 0x6F, 0x6C, 0x66, 0x48, 0x53,
521-
0x4D, 0x20, 0x41, 0x45, 0x53, 0x20,
522-
0x74, 0x65, 0x73, 0x74};
523-
uint8_t cipherOut[AES_BLOCK_SIZE] = {0};
524-
uint8_t plainOut[AES_BLOCK_SIZE] = {0};
525-
uint32_t outSize = 0;
526-
int rc;
527-
528-
WH_TEST_PRINT(" Testing AES CBC request/response...\n");
529-
530-
/* Encrypt */
531-
WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, INVALID_DEVID));
532-
WH_TEST_RETURN_ON_FAIL(
533-
wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION));
534-
535-
WH_TEST_RETURN_ON_FAIL(
536-
wh_Client_AesCbcRequest(client, aes, 1, plainIn, sizeof(plainIn)));
537-
538-
/* Response should not be ready before server processes */
539-
rc = wh_Client_AesCbcResponse(client, aes, cipherOut, &outSize);
540-
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_NOTREADY);
541-
542-
/* Server processes the request */
543-
WH_TEST_RETURN_ON_FAIL(wh_Server_HandleRequestMessage(server));
544-
545-
/* Now response should be available */
546-
WH_TEST_RETURN_ON_FAIL(
547-
wh_Client_AesCbcResponse(client, aes, cipherOut, &outSize));
548-
WH_TEST_ASSERT_RETURN(outSize == sizeof(plainIn));
549-
/* Ciphertext should differ from plaintext */
550-
WH_TEST_ASSERT_RETURN(memcmp(cipherOut, plainIn, sizeof(plainIn)) != 0);
551-
wc_AesFree(aes);
552-
553-
/* Decrypt */
554-
WH_TEST_RETURN_ON_FAIL(wc_AesInit(aes, NULL, INVALID_DEVID));
555-
WH_TEST_RETURN_ON_FAIL(
556-
wc_AesSetKey(aes, key, sizeof(key), iv, AES_DECRYPTION));
557-
558-
WH_TEST_RETURN_ON_FAIL(
559-
wh_Client_AesCbcRequest(client, aes, 0, cipherOut, sizeof(cipherOut)));
560-
WH_TEST_RETURN_ON_FAIL(wh_Server_HandleRequestMessage(server));
561-
WH_TEST_RETURN_ON_FAIL(
562-
wh_Client_AesCbcResponse(client, aes, plainOut, &outSize));
563-
WH_TEST_ASSERT_RETURN(outSize == sizeof(cipherOut));
564-
/* Decrypted output should match original plaintext */
565-
WH_TEST_ASSERT_RETURN(memcmp(plainOut, plainIn, sizeof(plainIn)) == 0);
566-
wc_AesFree(aes);
567-
568-
return WH_ERROR_OK;
569-
}
570-
#endif /* HAVE_AES_CBC */
571-
#endif /* !WOLFHSM_CFG_NO_CRYPTO */
572-
573510
static int _testOutOfBoundsNvmReads(whClientContext* client,
574511
whServerContext* server, whNvmId id)
575512
{
@@ -1171,11 +1108,6 @@ int whTest_ClientServerSequential(whTestNvmBackendType nvmType)
11711108
WH_TEST_RETURN_ON_FAIL(_testDma(server, client));
11721109
#endif /* WOLFHSM_CFG_DMA */
11731110

1174-
#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(HAVE_AES_CBC)
1175-
/* Test split AES CBC request/response */
1176-
WH_TEST_RETURN_ON_FAIL(_testAesCbcRequestResponse(client, server));
1177-
#endif /* !WOLFHSM_CFG_NO_CRYPTO && HAVE_AES_CBC */
1178-
11791111
/* Check that we are still connected */
11801112
WH_TEST_RETURN_ON_FAIL(wh_Server_GetConnected(server, &server_connected));
11811113
WH_TEST_ASSERT_RETURN(server_connected == WH_COMM_CONNECTED);

test/wh_test_crypto.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,6 +3641,114 @@ static int whTestCrypto_Aes(whClientContext* ctx, int devId, WC_RNG* rng)
36413641
memset(cipher, 0, sizeof(cipher));
36423642
memset(plainOut, 0, sizeof(plainOut));
36433643
}
3644+
if (ret == 0) {
3645+
/* test async AES CBC with incremental steps (streaming IV chaining) */
3646+
uint32_t outSize = 0;
3647+
uint32_t halfSize = sizeof(plainIn) / 2;
3648+
3649+
WH_TEST_PRINT("AES CBC ASYNC STREAMING test\n");
3650+
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
3651+
if (ret != 0) {
3652+
WH_ERROR_PRINT("Failed to wc_AesInit %d\n", ret);
3653+
}
3654+
3655+
/* Encrypt first half */
3656+
if (ret == 0) {
3657+
ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_ENCRYPTION);
3658+
if (ret != 0) {
3659+
WH_ERROR_PRINT("Failed to wc_AesSetKey %d\n", ret);
3660+
}
3661+
}
3662+
if (ret == 0) {
3663+
ret = wh_Client_AesCbcRequest(ctx, aes, 1, plainIn, halfSize);
3664+
if (ret != 0) {
3665+
WH_ERROR_PRINT("Failed to AesCbcRequest enc1 %d\n", ret);
3666+
}
3667+
}
3668+
if (ret == 0) {
3669+
do {
3670+
ret = wh_Client_AesCbcResponse(ctx, aes, cipher, &outSize);
3671+
} while (ret == WH_ERROR_NOTREADY);
3672+
if (ret != 0) {
3673+
WH_ERROR_PRINT("Failed to AesCbcResponse enc1 %d\n", ret);
3674+
}
3675+
}
3676+
3677+
/* Encrypt second half (IV should chain from first half) */
3678+
if (ret == 0) {
3679+
ret = wh_Client_AesCbcRequest(ctx, aes, 1,
3680+
plainIn + halfSize, halfSize);
3681+
if (ret != 0) {
3682+
WH_ERROR_PRINT("Failed to AesCbcRequest enc2 %d\n", ret);
3683+
}
3684+
}
3685+
if (ret == 0) {
3686+
do {
3687+
ret = wh_Client_AesCbcResponse(ctx, aes,
3688+
cipher + halfSize, &outSize);
3689+
} while (ret == WH_ERROR_NOTREADY);
3690+
if (ret != 0) {
3691+
WH_ERROR_PRINT("Failed to AesCbcResponse enc2 %d\n", ret);
3692+
}
3693+
}
3694+
3695+
/* Decrypt first half */
3696+
if (ret == 0) {
3697+
ret = wc_AesSetKey(aes, key, sizeof(key), iv, AES_DECRYPTION);
3698+
if (ret != 0) {
3699+
WH_ERROR_PRINT("Failed to wc_AesSetKey dec %d\n", ret);
3700+
}
3701+
}
3702+
if (ret == 0) {
3703+
ret = wh_Client_AesCbcRequest(ctx, aes, 0, cipher, halfSize);
3704+
if (ret != 0) {
3705+
WH_ERROR_PRINT("Failed to AesCbcRequest dec1 %d\n", ret);
3706+
}
3707+
}
3708+
if (ret == 0) {
3709+
do {
3710+
ret = wh_Client_AesCbcResponse(ctx, aes, plainOut, &outSize);
3711+
} while (ret == WH_ERROR_NOTREADY);
3712+
if (ret != 0) {
3713+
WH_ERROR_PRINT("Failed to AesCbcResponse dec1 %d\n", ret);
3714+
}
3715+
}
3716+
3717+
/* Decrypt second half (IV should chain from first half) */
3718+
if (ret == 0) {
3719+
ret = wh_Client_AesCbcRequest(ctx, aes, 0,
3720+
cipher + halfSize, halfSize);
3721+
if (ret != 0) {
3722+
WH_ERROR_PRINT("Failed to AesCbcRequest dec2 %d\n", ret);
3723+
}
3724+
}
3725+
if (ret == 0) {
3726+
do {
3727+
ret = wh_Client_AesCbcResponse(ctx, aes,
3728+
plainOut + halfSize, &outSize);
3729+
} while (ret == WH_ERROR_NOTREADY);
3730+
if (ret != 0) {
3731+
WH_ERROR_PRINT("Failed to AesCbcResponse dec2 %d\n", ret);
3732+
}
3733+
}
3734+
3735+
/* Verify round-trip */
3736+
if (ret == 0) {
3737+
if (memcmp(plainIn, plainOut, sizeof(plainIn)) != 0) {
3738+
WH_ERROR_PRINT("Failed to match async AES-CBC streaming\n");
3739+
ret = -1;
3740+
}
3741+
}
3742+
3743+
(void)wc_AesFree(aes);
3744+
memset(cipher, 0, sizeof(cipher));
3745+
memset(plainOut, 0, sizeof(plainOut));
3746+
3747+
if (ret == 0) {
3748+
WH_TEST_PRINT("AES CBC ASYNC STREAMING DEVID=0x%X SUCCESS\n",
3749+
devId);
3750+
}
3751+
}
36443752
#endif /* HAVE_AES_CBC */
36453753

36463754
#ifdef HAVE_AESGCM

0 commit comments

Comments
 (0)