Skip to content

Fix AES-CTS one-block, split-init IV, and TLS record HMAC handling - #476

Open
gasbytes wants to merge 3 commits into
wolfSSL:masterfrom
gasbytes:aes-related-fix
Open

Fix AES-CTS one-block, split-init IV, and TLS record HMAC handling#476
gasbytes wants to merge 3 commits into
wolfSSL:masterfrom
gasbytes:aes-related-fix

Conversation

@gasbytes

@gasbytes gasbytes commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
  • In wp_aes_cts_encrypt/wp_aes_cts_decrypt handle an input of exactly one block as plain CBC;
  • In wp_aes_stream_init pass ctx->iv to wc_AesSetKey, which is the cached iv from the wolfprovider context;
  • In wp_aes_stream_init restore oiv into iv when re-initializing without an iv, matching wp_aes_block_init;
  • In wp_hmac_set_ctx_params consume OSSL_MAC_PARAM_TLS_DATA_SIZE and advertise it in wp_hmac_settable_ctx_params;
  • In wp_hmac_final hash dummy blocks so the number of blocks hashed depends only on the padded record length;

Added associated regression test for each change (test_aes128_cts_one_block, test_aes128_cts_split_init and test_hmac_tls_data_size).

@gasbytes gasbytes self-assigned this Aug 26, 2026
Copilot AI lite review requested due to automatic review settings August 26, 2026 12:54
@gasbytes gasbytes added the ci:all PR OSP toggle: run all label Aug 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes two AES-CTS correctness issues in the wolfProvider AES stream implementation: (1) handling CTS for exactly one block, and (2) ensuring split-init sequences correctly preserve/use the IV when the key is set in a separate init call. It also adds targeted regression tests to prevent both issues from recurring.

Changes:

  • Treat AES-CTS input of exactly one block as plain CBC (encrypt/decrypt) to match OpenSSL behavior and avoid out-of-bounds behavior.
  • Update AES stream initialization to pass the cached ctx->iv into wc_AesSetKey so split init sequences keep the correct IV.
  • Add regression tests for one-block CTS and split-init IV handling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/wp_aes_stream.c Adjusts key setup IV handling and adds special-case CTS logic for one-block inputs.
test/test_cipher.c Adds regression tests covering one-block CTS behavior and split-init IV behavior.
test/unit.c Registers the new unit tests in the test case table.
test/unit.h Declares prototypes for the new unit tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/wp_aes_stream.c
Comment thread test/test_cipher.c Outdated
Comment thread test/test_cipher.c Outdated
@gasbytes
gasbytes marked this pull request as ready for review August 26, 2026 13:37
@gasbytes
gasbytes requested a review from aidangarske August 26, 2026 13:52
@gasbytes gasbytes assigned aidangarske and unassigned gasbytes Aug 26, 2026
@gasbytes gasbytes changed the title Fix AES-CTS one-block and split-init IV handling Fix AES-CTS one-block, split-init IV, and TLS record HMAC handling Aug 28, 2026

@aidangarske aidangarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Code Review

Scan type: review

Overall recommendation: REQUEST_CHANGES
Findings: 4 total — 4 posted, 0 skipped
4 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] Use the length-field width when counting final hash blockssrc/wp_hmac.c:313-321
  • [High] Preserve TLS state when duplicating HMAC contextssrc/wp_hmac.c:55-58
  • [Medium] Exercise the TLS block-count behavior in the regression testtest/test_hmac.c:814-863
  • [Medium] Cover the new CFB no-IV reinitialization branchsrc/wp_aes_stream.c:314-320

Review generated by Skoll

Comment thread src/wp_hmac.c
while (((word32)1 << blockBits) < blockSz) {
blockBits++;
}
padSz = (blockSz >> 3) + 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the length-field width when counting final hash blocks

padSz includes the 0x80 byte, causing wp_hmac_blocks() to count a padding spill one byte too early. For SHA-256, realSz values 55 and 56 produce the same helper count, although wolfCrypt finalization processes one block for 55 bytes and two for 56. Consequently, records with 42 and 43 data bytes can receive the same dummy count at a fixed padded-record size while their total compression counts differ by one. This defeats the equalization introduced by the PR at every padding boundary.

Fix: Use the encoded length-field width—8 bytes for the 64-byte TLS hashes and 16 bytes for the 128-byte hashes—when detecting whether final padding needs another block. Add boundary cases for real message lengths 55/56 and 111/112.

Suggestion:

Suggested change
padSz = (blockSz >> 3) + 1;
padSz = blockSz >> 3;

Comment thread src/wp_hmac.c
/** Length of private key in bytes. */
size_t keyLen;

/** Length of the padded TLS record including MAC and padding. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preserve TLS state when duplicating HMAC contexts

The PR adds tlsDataSize and tlsDummyBlocks, but wp_hmac_dup() manually copies only the pre-existing fields. Because the destination is zero-allocated, EVP_MAC_CTX_dup() or EVP_MD_CTX_copy_ex() after setting TLS_DATA_SIZE loses the configured record size and computed dummy count. The duplicate therefore finalizes without the new TLS equalization behavior, violating the provider's dupctx state-copy contract. The existing duplication tests do not set this new parameter.

Fix: Copy both TLS fields in wp_hmac_dup() and add a regression that duplicates the context after setting TLS_DATA_SIZE, including a duplicate taken after the second update.

Comment thread test/test_hmac.c
int ret = 0;
unsigned char key[32];
unsigned char header[13];
unsigned char msg[100];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exercise the TLS block-count behavior in the regression test

The test only compares the resulting MAC. Dummy hashing occurs after wc_HmacFinal(), so its count cannot affect those bytes; the test still passes if the block calculator or dummy loop is removed entirely. It also advertises a 148-byte TLS record while the second update is backed by only msg[100], despite the TLS_DATA_SIZE contract requiring the pointer to cover the entire record, including MAC and padding.

Fix: Back the TLS update with a complete, block-aligned record buffer and directly validate compression/update counts through instrumentation or a focused unit test of the block-count helper. Cover both sides of each hash-padding boundary.

Comment thread src/wp_aes_stream.c
if (ok && (iv != NULL) && (!wp_aes_init_iv(ctx, iv, ivLen))) {
ok = 0;
}
if (ok && (iv == NULL) && ctx->ivSet &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cover the new CFB no-IV reinitialization branch

The new original-IV restoration condition changes AES-CFB as well as AES-CTS, but the added split-initialization test fetches only AES-128-CBC-CTS. Existing CFB stream tests always provide an explicit IV on initialization, so the new CFB branch is not exercised.

Fix: Add an AES-CFB encrypt/decrypt regression that processes data, reinitializes the same context with a NULL IV, and verifies that output matches OpenSSL and the first run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all PR OSP toggle: run all

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants