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

SHA3 and SHAKE - New API Design #2098

Open
wants to merge 27 commits into
base: main
Choose a base branch
from

Conversation

manastasova
Copy link
Contributor

@manastasova manastasova commented Jan 7, 2025

Issues:

Resolves #CryptoAlg-2810

Description of changes:

AWS-LC supports SHA3 and SHAKE algorithms though low level SHA3_Init, SHA3_Update, SHA3_Final and SHAKE_init, SHAKE_Final APIs. Currently, there are two issues with the implementation and usage of SHA3 and SHAKE:

  • There is no support for SHAKE_Update function. SHAKE is implemented by calling SHAKE_Init, SHA3_Update and SHAKE_Final.
  • SHAKE_Final allows multiple consecutive calls to enable incremental XOF output generation.

This PR addresses both of them as follows:

  • Introduce new API layers - FIPS202, SHA3 and SHAKE.

    • Keccak1600 layer (Keccak1600_Squeeze/Absorb Layer (rename) #2097) implements KeccakF1600 Absorb and Squeeze functions; Keccak1600 layer does not manage internal input/output buffers.
    • FIPS202 layer implements Reset, Init, Update, and Finalize functionalities; FIPS202 layer manages the internal input/output buffers, allowing incremental requests (not necessarily multiple of block size) to Update (Absorb) and Squeeze for input/output processing. (Other functionalities, such as zero-ing of bitstate, block size checks, etc. are also handled by FIPS202 API layer).
      • FIPS202 layer implements all common behavior between SHA3 and SHAKE algorithms.
      • FIPS202 layer checks/updates the |ctx->state| flag when handling a common behavior between SHA3 and SHAKE algorithms. |ctx->state| is updated in the higher level SHA3_ SHAKE_ API layer when the behavior of both algorithms diverges (SHAKE can allow incremental squeezes).
    • SHA3 layer implements Init, Update, and Final functionalities; SHA3 layer only implements SHA3 algorithm, thus, offers a single-call SHA3_Final function. SHA3_Final will update internal |ctx->state| flag to prevent any sequential calls.
    • SHAKE layer implements XOF SHAKE algorithm, therefore, offers Init, Absorb, Squeeze, and Final functionalities;
      • SHAKE layer implements Init, and Absorb, Squeeze with incremental call support for absorb (byte-wise) and squeeze (block-wise).
      • SHAKE layer implements a single-call SHAKE_Final function that generates an arbitrary length output and finalizes SHAKE. Incremental XOF output generation is handled by |SHAKE_Squeeze|. |SHAKE_Squeeze| can be called multiple times. SHAKE_Final should be called only once.
  • KECCAK600_CTX struct updates:

    • Remove |padded| field
    • Introduce |state| field
      • |state| can be |KECCAK1600_STATE_ABSORB|, |KECCAK1600_STATE_SQUEEZE|, |KECCAK1600_STATE_FINAL|
      • |KECCAK1600_STATE_ABSORB| - allows incremental absorbs until the state is changed
      • |KECCAK1600_STATE_SQUEEZE| - allows incremental squeezes for |SHAKE_Squeeze|
      • |KECCAK1600_STATE_Final| - prevents from incremental squeezes via |SHAKE_Final| and prevents from consecutive calls to |SHA3_Final| (Final functions are single-shot functions).

SHA3 vs SHAKE algorithms (APIs usage):

  • SHA3 digest generation: SHA3_Init; SHA3_Update; SHA3_Final;
  • SHAKE (single-shot-output) output generation: SHAKE_Init; SHAKE_Absorb; SHAKE_Final;
  • SHAKE (incremental) output generation: SHAKE_Init; SHAKE_Absorb; SHAKE_Squeeze+;

Call-outs:

Service indicator is updated:

  • Inside SHA3 and SHAKE single shot APIs (as previously in AWS-LC);
  • Inside SHA3_Final (as previously in AWS-LC);
  • Inside SHAKE_Final (Single-Shot XOF Final output generation as previously in AWS-LC);
  • Inside SHAKE_Squeeze (Streaming XOF Squeezes output generation updates the service indicator after each extendable output update);

All other algorithms that use SHA3/SHAKE APIs are updated:

  • ML-KEM (SHA3/SHAKE calls will be inlined later)
  • ML-DSA (SHAKE_Squeeze (incremental XOF output functionality) inside ML-DSA is never invoked with the KAT test vectors and gtests)

Testing:

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

./crypto/crypto_test --gtest_filter="All/PerKEMTest.*"
./crypto/crypto_test --gtest_filter="All/PQDSAParameterTest.*"

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 23 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
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).
@manastasova manastasova requested a review from a team as a code owner January 7, 2025 21:11
@codecov-commenter
Copy link

codecov-commenter commented Jan 7, 2025

Codecov Report

Attention: Patch coverage is 83.87097% with 15 lines in your changes missing coverage. Please review.

Project coverage is 78.76%. Comparing base (3cea179) to head (077ef78).

Files with missing lines Patch % Lines
crypto/fipsmodule/sha/sha3.c 81.92% 15 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2098      +/-   ##
==========================================
+ Coverage   78.75%   78.76%   +0.01%     
==========================================
  Files         598      598              
  Lines      103657   103700      +43     
  Branches    14720    14732      +12     
==========================================
+ Hits        81637    81682      +45     
+ Misses      21368    21366       -2     
  Partials      652      652              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

// SHA3_Final pads the last data block and processes it through Keccak1600_Absorb.
// It writes |md_digest| bytes of finalized digest to |md|, returns 1 on
// success and 0 on failure.
OPENSSL_EXPORT int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx);
Copy link
Contributor

Choose a reason for hiding this comment

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

You're removing a parameter from the public API. Will there be any impact for downstream users?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this function is currently public. To verify, I checked our Rust bindings to see whether it was listed. I don't see it here: https://docs.rs/aws-lc-sys/latest/aws_lc_sys/#functions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From my understanding, only the functions defined in the include/openssl are consider external APIs.
These APIs should be internal, however, they are exported so that they can be used in our tests. However, I am not sure if there may be some customers that use these internal APIs as well.

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