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

Only SHA3/SHAKE Init Updates via FIPS202 API layer #2101

Merged
merged 18 commits into from
Jan 30, 2025

Conversation

manastasova
Copy link
Contributor

@manastasova manastasova commented Jan 8, 2025

Issues:

Resolves (some of) #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 introduces the APIs that need changes in the function parameter list. Particularly, SHA3_Init used a parameter |pad_char|, which was used for differentiating SHA3_Init from SHAKE_Init functions.

This PR introduces only the changes in the Init functions (FIPS202_Init, FIPS202_Reset, SHA3_Init, and SHAKE_Init):

  • Introduce (partially) 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 (so far) Reset and Init functions. (Update and Finalize functionalities are to be introduced in following PRs); 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 (so far) Reset and Init common behavior between SHA3 and SHAKE algorithms.
      • FIPS202 layer checks/updates the |ctx->padded| flag when handling a common behavior between SHA3 and SHAKE algorithms.
    • SHA3 layer implements (so far) Init functionality (Update, and Final are to be introduced in following PRs);
    • SHAKE layer implements XOF SHAKE algorithm, therefore, offers (so far) Init functionality (Absorb, Squeeze, and Final functionalities are to be introduced in following PRs);

Call-outs:

All SHA3_Init calls are updated:

  • digests.c
  • sha3_test.cc

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 5 commits January 6, 2025 22:58
Clean redefinition of SHAKE blocksize/rate macros; Update their use inside MLKEM and MLDSA.
Fix alignment

Co-authored-by: Jake Massimo <jakemas@amazon.com>
Add FIPS202 layer for FIPS202_Init and FIPS202_Reset functions

Introduce SHA3_Init API change; remove the padding character from parameters; is it handled internally by the SHA3/SHAKE functions via the FIPS layer

Introduce SHAKE_Init consuming FIPS202 layer APIs
@manastasova manastasova changed the title SHA3/SHAKE Init Updates via FIPS202 API layer Only SHA3/SHAKE Init Updates via FIPS202 API layer Jan 8, 2025
@codecov-commenter
Copy link

codecov-commenter commented Jan 8, 2025

Codecov Report

Attention: Patch coverage is 91.17647% with 3 lines in your changes missing coverage. Please review.

Project coverage is 78.95%. Comparing base (695c3a0) to head (36545c6).

Files with missing lines Patch % Lines
crypto/fipsmodule/sha/sha3.c 90.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2101      +/-   ##
==========================================
- Coverage   78.96%   78.95%   -0.02%     
==========================================
  Files         611      611              
  Lines      105514   105522       +8     
  Branches    14941    14945       +4     
==========================================
- Hits        83319    83314       -5     
- Misses      21543    21555      +12     
- Partials      652      653       +1     

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

@manastasova manastasova marked this pull request as ready for review January 8, 2025 23:55
@manastasova manastasova requested a review from a team as a code owner January 8, 2025 23:55
Comment on lines +120 to +122
if (pad != SHA3_PAD_CHAR &&
pad != SHAKE_PAD_CHAR) {
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Reading FIPS 202 section B.2 where it defines the sha and shake pad values, why are we using the q = 2 values? Should that be configurable in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The values for the padding are the same, however, they are 'interleaved' by 0's in case the message is shorter than the block. E.g. the pad for sha3 is 0x06 (added after the last byte of the input); the rest of the block size is set to zero, where the last byte of the block is set to 0x80. When the last byte (+1 byte) of the message (message of length block size - 1 bytes) and the last byte of the block coincide, the last byte becomes 0x06 ^ 0x80, which will be 0x86. When messages are shorter, more zero's are added in the middle of these values. However, the implementation covers all the cases using only the 0x06 and 0x1f pad, where all the rest is 0's and last block byte is 0x80.

Copy link
Contributor

Choose a reason for hiding this comment

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

When the message length is -1 modulo the block size, i.e. one byte is left, and is filled with 0x86, how is it differentiated from a similar message that's one byte longer and has this value, 0x86, as the last byte? should another full block be added for padding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, in this case another full block is absorbed; consisting of padding 0x06 ... 0x00 ... 0x80 with block_size-2 bytes of 0x00's.

crypto/fipsmodule/sha/sha3.c Show resolved Hide resolved
@nebeid nebeid self-requested a review January 24, 2025 22:28
return 0;
}

if (block_size <= sizeof(ctx->buf)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: my preference is to check for the erroneous condition and return 0 within the if statement, then continue with the regular processing afterwards as in (most of, if not all) the rest of the code base.
Update: I see that similar processing below is following the same pattern, so you can ignore this comment.

}

// SHA3 APIs implement SHA3 functionalities on top of FIPS202 API layer
void SHA3_Reset(KECCAK1600_CTX *ctx) {
memset(ctx->A, 0, sizeof(ctx->A));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not call FIPS202_Reset()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I change it in the next PR:

static void FIPS202_Reset(KECCAK1600_CTX *ctx) {

Comment on lines +120 to +122
if (pad != SHA3_PAD_CHAR &&
pad != SHAKE_PAD_CHAR) {
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

When the message length is -1 modulo the block size, i.e. one byte is left, and is filled with 0x86, how is it differentiated from a similar message that's one byte longer and has this value, 0x86, as the last byte? should another full block be added for padding?

@nebeid nebeid merged commit 39a4383 into aws:main Jan 30, 2025
121 of 126 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