Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SHAKE Incremental Byte Squeezes && EVP_ Tests #2155

Merged
merged 68 commits into from
Feb 24, 2025

Conversation

manastasova
Copy link
Contributor

Issues:

Resolves #CryptoAlg-2835 &&
Resolves #CryptoAlg-2836

Description of changes:

AWS-LC supports SHA3 and SHAKE algorithms. SHAKE, as defined in FIPS202, is an extendible output function, where the output data could be generated by multiple calls to "squeeze" function. Currently, there are two main features (internal and external APIs support) that are not supported by AWS-LC:

  • (Internal APIs) Currently, AWS-LC supports incremental XOF output (internal only via SHAKE_Squeeze) generation when the requested data is a multiple of the |block_size|. I.e., ceil(requested_output_bytes/block_size) full blocks will be generated and directly outputted without internal buffering. Thus, it is the user's (other algorithm) responsibility to manage output data when the request is not a multiple of the |block_size|.
  • Currently, AWS-LC does not support external (EVP_Digest) APIs for incremental squeezes.

This PR add both features for incremental squeezes in arbitrary length output requests (up to a byte):

  • Internal APIs (SHAKE_) changes:
    • Add support for incremental |SHAKE_Squeeze| with arbitrary size (up to a byte) output requests via internal buffer.
    • Add KECCAK600_CTX struct |state| field updates and checks yo ensure functions are called only in the corresponding bitstate, e.g., |KECCAK1600_STATE_SQUEEZE| allows further bitstate squeezes, |KECCAK1600_STATE_FINAL| does not allow further squeezes, etc.
  • External APIs (EVP_Digest) changes:
    • Add external API support for incremental |SHAKE_Squeeze| with arbitrary size (up to a byte) output requests via |EVP_DigestSqueeze|.
    • Restrict the number of calls to |EVP_DigestFinalXOF| to only one. For incremental squeeze functionality |EVP_DigestSqueeze| should be used.
    • Restrict the use of |EVP_DigestFinal| to hash algorithms only. For XOF algorithms |EVP_DigestFinalXOF| and |EVP_DigestSqueeze| should be used.

This PR adds more tests for EVP_Digest XOF functionality (all test are running through the entire NIST Test Vector list):

  • External APIs (EVP_Digest) additional tests:
    • Test Final - Assert fail when |EVP_DigestFinal| is called for XOF algorithms
    • Test Absorb - Assert success when |EVP_DigestUpdate| is called byte-by-byte
    • Test Squeeze - Assert success when |EVP_DigestSqueeze| is called byte-by-byte
    • Test Squeeze - Assert success when |EVP_DigestSqueeze| is called in set byte increments
    • Test Squeeze with random Input - Assert success when |EVP_DigestSqueeze| is called on a random message
    • Test Squeeze with random Input - Assert success when |EVP_DigestSqueeze| is called on a random message in set byte increments
    • Test Final XOF without Update - Assert fail when |EVP_DigestFinalXOF| is called as a streaming API

Call-outs:

Service indicator is updated:

  • Inside SHAKE_Squeeze (Streaming XOF Squeezes output generation does not update the service indicator after each extendable output update);

Testing:

./crypto/crypto_test --gtest_filter="SHAKETest.*"

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

manastasova and others added 30 commits December 30, 2024 16:57
Define Keccak1600, FIPS202, and SHA3/SHAKE API layers

Keccak1600 implements absorb and squeeze functionalities. It defines the lowest lever APIs for SHA3/SHAKE; Keccak1600 functions only process complete blocks; internal input/output buffers are handles by higher layer (FIPS202) APIs.

FIPS202 APIs handle the internal input/output buffers to allow incremental function calls. FIPS202 layer is used by both SHA3 and SHAKE high level APIs. FIPS202 defines Reset, Init, Update, Finalize APIs.

SHA3/SHAKE layer implements the SHA3 and SHAKE algorithms. SHA3 supports Init, Update and Final APIs since it produces a given length digest and should be Finalized in a single Final function call. SHAKE supports Init, Update, Finalize and Squeeze APIs since it can generate arbitrary length output in incremental way. SHAKE_Finalize processes padding and absorb of last input block and generates the first output value; Incremental XOF output generation is defined by SHAKE_Squeeze function which implements the squeeze phase (it does not finalize the absorb, SHAKE_Squeeze can be only called after SHAKE_Finalize
Note: symmetric-shake.c will be inlined, therefore, additional checks for |ctx->padded| flag will be omitted (SHAKE_Finalize should be called once to finalize absorb and initialize squeeze phase; SHAKE_Squeeze should be called to generate additional incremental XOF output).
…on may not be completed (incremental XOF output request); however, the SHAKE_Finalize function completes the first requested output, thus, SHAKE has processed the first valid output value
Rename SHAKE_Update to SHAKE_Absorb; Define SHAKE_Final as a single-shot API; Defined SHAKE_Squeeze as an incremental (independent) API. It can can be called immediately after SHAKE_Absorb; SHAKE_Squeeze will finalize absorb phase and initiate squeeze phase; When called a signle time SHAKE_Squeeze has the same behavior as SHAKE_Final, SHAKE_Final cannot be called consecutive times; SHAKE_Squeeze can be called multiple times; SHAKE_Squeeze can be called after SHAKE_Final (to squeeze more bytes).
Allow KECCAK1600_STATE_ABSORB, KECCAK1600_STATE_SQUEEZE, KECCAK1600_STATE_FINAL state flag values to prevent incremental usage of SHAKE_Final or SHAKE_Squeeze after SHAKE_Final

The cahnge is introduced for consistency reasons

KECCAK1600_STATE_ABSORB corresponds to |ctx->padded| = 0 (NOT_PADDED), KECCAK1600_STATE_SQUEEZE corresponds to |ctx->padded| = 1 (PADDED), and KECCAK1600_STATE_FINAL blocks incremental Squeeze calls.
Make FIPS202 functions static; Do not export SHA3 and SHAKE internal functions
Clean redefinition of SHAKE blocksize/rate macros; Update their use inside MLKEM and MLDSA.
Fix alignment

Co-authored-by: Jake Massimo <jakemas@amazon.com>
Upon Init, the |ctx->state| is set to |KECCAK1600_STATE_ABSORB| allowing absorb calls from both SHA3 and SHAKE; Upon Finalize (padding and last absorb) SHA3 and SHAKE (Final or incremental Squeeze) behave in a different way; thus, the |ctx->state| is set to |KECCAK1600_STATE_FINAL| when no incremental calls are allowed (|SHA3_Final| and |SHAKE_Final| and to |KECCAK1600_STATE_SQUEEZE| when incremental squeezes are allowed (SHAKE_Squeeze).
Remove local variable updates before return; Add return values comments
justsmth
justsmth previously approved these changes Feb 11, 2025
… XOF digests to increase code coverage

upstream merge - squash commits from upstream.
justsmth
justsmth previously approved these changes Feb 20, 2025
manastasova and others added 5 commits February 20, 2025 09:37
Test each possible chunck size (|to_sq_bytes| from 1 to |digest_length|) to generate the expected output as incremental Squeeze calls, requesting |to_sq_bytes| bytes in each individual call
Test each possible chunck size (|to_sq_bytes| from 1 to |digest_length|) to generate the expected output as incremental Squeeze calls, requesting |to_sq_bytes| bytes in each individual call
@justsmth justsmth merged commit 493207c into aws:main Feb 24, 2025
111 of 113 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants