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

Draft
wants to merge 44 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c6ed451
Introduce SHA3/SHAKE layered API design; Only SHA3/SHAKE files updates
manastasova Dec 30, 2024
a05d255
Add changes to ML-KEM based on SHA3/SHAKE new API Design
manastasova Dec 30, 2024
50cf7fa
Add changes to ML-DSA based on SHA3/SHAKE new API Design
manastasova Dec 30, 2024
4b0b92e
Update build files in generated-src
manastasova Dec 30, 2024
eb992ea
Update service indicator in SHA3_Final
manastasova Dec 30, 2024
d40fbec
Initialize |ctx->padded| to 0 for SHAKE inside SHAKE_Init
manastasova Dec 31, 2024
adb910d
Update service indicator at the end of SHAKE_Finalize; The XOF functi…
manastasova Dec 31, 2024
02b8085
Fix conflicts with MLDSA parameters renaming
manastasova Dec 31, 2024
e61be0d
Merge branch 'main' into sha3_absorb_squeeze
manastasova Dec 31, 2024
3008821
Merge branch 'aws:main' into sha3_absorb_squeeze
manastasova Jan 3, 2025
2a1622f
Update SHAKE single-shot and streaming APIs
manastasova Jan 3, 2025
c5d0afd
Update incremental block-wise SHAKE squeezes in MLKEM
manastasova Jan 3, 2025
b6a5590
Update incremental block-wise SHAKE squeezes in MLDSA
manastasova Jan 3, 2025
7ccaeba
Replace |keccak_st->padded| flag with |keccak_st->state| flag
manastasova Jan 3, 2025
7edb6c7
Update MLKEM and MLDSA
manastasova Jan 3, 2025
7386c1b
Update Keccak state flag in SHA3 functions
manastasova Jan 3, 2025
e424771
Address code review comments
manastasova Jan 4, 2025
6597af1
Add export macro to functions in the tests
manastasova Jan 4, 2025
7766425
Merge branch 'aws:main' into sha3_absorb_squeeze
manastasova Jan 6, 2025
ff3cbd8
Rename Absorb and Squeeze functions to Keccak1600_ layer specific
manastasova Jan 6, 2025
680dd43
Update build files in generated-src
manastasova Jan 6, 2025
872d368
Apply suggestions from code review
manastasova Jan 7, 2025
5780ee5
Move all common |ctx->state| flag checks in the FIPS202 layer
manastasova Jan 7, 2025
3f43dde
Merge branch 'sha3_absorb_squeeze' of github.com:manastasova/aws-lc i…
manastasova Jan 7, 2025
07bac7c
Update MLKEM and MLDSA
manastasova Jan 7, 2025
2973e4a
Merge branch 'main' of github.com:aws/aws-lc into sha3_absorb_squeeze
manastasova Jan 7, 2025
86fa4b0
Remove SHAKE_Squeeze service indicator update
manastasova Jan 8, 2025
36ab448
Merge branch 'main' of github.com:aws/aws-lc into sha3_absorb_squeeze
manastasova Jan 8, 2025
b2228b6
Bring back exports
manastasova Jan 8, 2025
14da500
Merge branch 'main' of github.com:aws/aws-lc into sha3_only_rename
manastasova Jan 8, 2025
97b02c6
Only add shanges to Init functions
manastasova Jan 8, 2025
95c7e26
add new line at the end of file
manastasova Jan 8, 2025
077ef78
Merge branch 'main' into sha3_absorb_squeeze
manastasova Jan 8, 2025
b4ce7b2
Merge branch 'main' into sha3_only_rename
manastasova Jan 9, 2025
5b18483
Merge branch 'main' into sha3_only_rename
manastasova Jan 13, 2025
d3bba6b
Merge branch 'main' into sha3_only_rename
manastasova Jan 13, 2025
f48fb78
merge with aws-lc main and sha3/shake_only_Init PR changes
manastasova Jan 13, 2025
d4a1ec0
Add only internal API changes (SHAKE_Squeeze)
manastasova Jan 23, 2025
ae6ef3f
Add EVP_DigestSqueeze
manastasova Jan 23, 2025
83df460
Move EVP_DigestSqueeze new tests is sha3_test.c
manastasova Jan 31, 2025
24784c4
fix sha3.c file
manastasova Feb 1, 2025
2de348a
Merge branch 'main' into shake_bytes
manastasova Feb 1, 2025
dc83a25
Fix Upstream Conflicts
manastasova Feb 1, 2025
672a67a
Fix incremental squeeze tests memleaks
manastasova Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crypto/digest_extra/digest_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ static const EVP_MD evp_md_blake2b256 = {
blake2b256_final,
BLAKE2B_CBLOCK,
sizeof(BLAKE2B_CTX),
/*finalXOf*/ NULL,
/*finalXOf*/ NULL,
/*squeezeXOf*/ NULL
};

const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; }
Expand All @@ -291,7 +292,8 @@ static const EVP_MD evp_md_null = {
null_final,
0,
sizeof(EVP_MD_CTX),
NULL,
/*finalXOf*/ NULL,
/*squeezeXOf*/ NULL
};

const EVP_MD *EVP_md_null(void) { return &evp_md_null; }
17 changes: 17 additions & 0 deletions crypto/fipsmodule/digest/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx) {

void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); }

// EVP_DigestFinalXOF is a single-shot XOF output generation function
// It can be called once. On sequential calls, it returns 0.
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, size_t len) {
if (ctx->digest == NULL) {
return 0;
Expand All @@ -148,6 +150,21 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, size_t len) {
return 1;
}

// EVP_DigestSqueeze is a streaming XOF output generation function
// It can be called multiple times to generate an output of length
// |len| bytes.
int EVP_DigestSqueeze(EVP_MD_CTX *ctx, uint8_t *out, size_t len) {
if (ctx->digest == NULL) {
return 0;
}
if ((EVP_MD_flags(ctx->digest) & EVP_MD_FLAG_XOF) == 0) {
OPENSSL_PUT_ERROR(DIGEST, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
ctx->digest->squeezeXOF(ctx, out, len);
return 1;
}

uint32_t EVP_MD_meth_get_flags(const EVP_MD *md) { return EVP_MD_flags(md); }

void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) {}
Expand Down
33 changes: 28 additions & 5 deletions crypto/fipsmodule/digest/digests.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) {
out->init = md4_init;
out->update = md4_update;
out->final = md4_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(MD4_CTX);
Expand All @@ -120,6 +121,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) {
out->init = md5_init;
out->update = md5_update;
out->final = md5_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(MD5_CTX);
Expand All @@ -145,6 +147,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_ripemd160) {
out->init = ripemd160_init;
out->update = ripemd160_update;
out->final = ripemd160_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(RIPEMD160_CTX);
Expand All @@ -170,6 +173,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) {
out->init = sha1_init;
out->update = sha1_update;
out->final = sha1_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(SHA_CTX);
Expand All @@ -195,6 +199,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) {
out->init = sha224_init;
out->update = sha224_update;
out->final = sha224_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(SHA256_CTX);
Expand All @@ -220,6 +225,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) {
out->init = sha256_init;
out->update = sha256_update;
out->final = sha256_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(SHA256_CTX);
Expand All @@ -245,6 +251,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) {
out->init = sha384_init;
out->update = sha384_update;
out->final = sha384_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 128;
out->ctx_size = sizeof(SHA512_CTX);
Expand All @@ -270,6 +277,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) {
out->init = sha512_init;
out->update = sha512_update;
out->final = sha512_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 128;
out->ctx_size = sizeof(SHA512_CTX);
Expand Down Expand Up @@ -319,6 +327,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512_256) {
out->init = sha512_256_init;
out->update = sha512_256_update;
out->final = sha512_256_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 128;
out->ctx_size = sizeof(SHA512_CTX);
Expand All @@ -344,6 +353,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha3_224) {
out->init = sha3_224_init;
out->update = sha3_224_update;
out->final = sha3_224_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = SHA3_BLOCKSIZE(SHA3_224_DIGEST_BITLENGTH);
out->ctx_size = sizeof(KECCAK1600_CTX);
Expand All @@ -369,6 +379,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha3_256) {
out->init = sha3_256_init;
out->update = sha3_256_update;
out->final = sha3_256_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = SHA3_BLOCKSIZE(SHA3_256_DIGEST_BITLENGTH);
out->ctx_size = sizeof(KECCAK1600_CTX);
Expand All @@ -394,6 +405,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha3_384) {
out->init = sha3_384_init;
out->update = sha3_384_update;
out->final = sha3_384_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = SHA3_BLOCKSIZE(SHA3_384_DIGEST_BITLENGTH);
out->ctx_size = sizeof(KECCAK1600_CTX);
Expand All @@ -419,6 +431,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha3_512) {
out->init = sha3_512_init;
out->update = sha3_512_update;
out->final = sha3_512_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = SHA3_BLOCKSIZE(SHA3_512_DIGEST_BITLENGTH);
out->ctx_size = sizeof(KECCAK1600_CTX);
Expand All @@ -430,20 +443,25 @@ static void shake128_init(EVP_MD_CTX *ctx) {
}

static void shake128_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
CHECK(SHAKE_Absorb(ctx->md_data, data, count));
}

static void shake128_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Final(md, ctx->md_data, len));
}

static void shake128_squeeze(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Squeeze(md, ctx->md_data, len));
}

DEFINE_METHOD_FUNCTION(EVP_MD, EVP_shake128) {
out->type = NID_shake128;
out->md_size = 0;
out->flags = EVP_MD_FLAG_XOF;
out->init = shake128_init;
out->update = shake128_update;
out->final = NULL;
out->squeezeXOF = shake128_squeeze;
out->finalXOF = shake128_final;
out->block_size = SHAKE128_BLOCKSIZE;
out->ctx_size = sizeof(KECCAK1600_CTX);
Expand All @@ -455,26 +473,30 @@ static void shake256_init(EVP_MD_CTX *ctx) {
}

static void shake256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
CHECK(SHAKE_Absorb(ctx->md_data, data, count));
}

static void shake256_finalXOF(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
static void shake256_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Final(md, ctx->md_data, len));
}

static void shake256_squeeze(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Squeeze(md, ctx->md_data, len));
}

DEFINE_METHOD_FUNCTION(EVP_MD, EVP_shake256) {
out->type = NID_shake256;
out->md_size = 0;
out->flags = EVP_MD_FLAG_XOF;
out->init = shake256_init;
out->update = shake256_update;
out->final = NULL;
out->finalXOF = shake256_finalXOF;
out->squeezeXOF = shake256_squeeze;
out->finalXOF = shake256_final;
out->block_size = SHAKE256_BLOCKSIZE;
out->ctx_size = sizeof(KECCAK1600_CTX);
}


typedef struct {
MD5_CTX md5;
SHA_CTX sha1;
Expand Down Expand Up @@ -505,6 +527,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) {
out->init = md5_sha1_init;
out->update = md5_sha1_update;
out->final = md5_sha1_final;
out->squeezeXOF = NULL;
out->finalXOF = NULL;
out->block_size = 64;
out->ctx_size = sizeof(MD5_SHA1_CTX);
Expand Down
4 changes: 4 additions & 0 deletions crypto/fipsmodule/digest/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ struct env_md_st {
// finalXOF completes the hash and writes |len| bytes of digest extended output
// to |out|.
void (*finalXOF)(EVP_MD_CTX *ctx, uint8_t *out, size_t len);

// squeezeXOF incrementally generates |len| bytes of digest extended output
// to |out|.
void (*squeezeXOF)(EVP_MD_CTX *ctx, uint8_t *out, size_t len);
};

// evp_md_pctx_ops contains function pointers to allow the |pctx| member of
Expand Down
18 changes: 9 additions & 9 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/symmetric-shake.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ void kyber_shake128_absorb(KECCAK1600_CTX *ctx,
// SHAKE_Init always returns 1 when called with correct block size value
SHAKE_Init(ctx, SHAKE128_BLOCKSIZE);

// SHA3_Update always returns 1 on first call of sizeof(extseed) (34 bytes)
SHA3_Update(ctx, extseed, sizeof(extseed));
// SHAKE_Absorb always returns 1 on first call of sizeof(extseed) (34 bytes)
SHAKE_Absorb(ctx, extseed, sizeof(extseed));
}

/*************************************************
Expand All @@ -48,8 +48,8 @@ void kyber_shake128_absorb(KECCAK1600_CTX *ctx,
void kyber_shake128_squeeze(KECCAK1600_CTX *ctx, uint8_t *out, int nblocks)
{
// Return code checks can be omitted
// SHAKE_Final always returns 1
SHAKE_Final(out, ctx, nblocks * SHAKE128_BLOCKSIZE);
// SHAKE_Squeeze always returns 1 when |ctx->padded| flag is cleared
SHAKE_Squeeze(out, ctx, nblocks * SHAKE128_BLOCKSIZE);
}

/*************************************************
Expand Down Expand Up @@ -94,12 +94,12 @@ void kyber_shake256_rkprf(ml_kem_params *params, uint8_t out[KYBER_SSBYTES], con
// SHAKE_Init always returns 1 when called with correct block size value
SHAKE_Init(&ctx, SHAKE256_BLOCKSIZE);

// SHA3_Update always returns 1 on first call of KYBER_SYMBYTES (32 bytes)
SHA3_Update(&ctx, key, KYBER_SYMBYTES);
// SHAKE_Absorb always returns 1 on first call of KYBER_SYMBYTES (32 bytes)
SHAKE_Absorb(&ctx, key, KYBER_SYMBYTES);

// SHA3_Update always returns 1 processing all data blocks that don't need pad
SHA3_Update(&ctx, input, params->ciphertext_bytes);
// SHAKE_Absorb always returns 1 processing all data blocks that don't need pad
SHAKE_Absorb(&ctx, input, params->ciphertext_bytes);

// SHAKE_Final always returns 1
// SHAKE_Squeeze always returns 1 when |ctx->padded| flag is cleared (no previous calls to SHAKE_Squeeze)
SHAKE_Final(out, &ctx, KYBER_SSBYTES);
}
55 changes: 36 additions & 19 deletions crypto/fipsmodule/sha/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ extern "C" {
// SHAKE128 has the maximum block size among the SHA3/SHAKE algorithms.
#define SHA3_MAX_BLOCKSIZE SHAKE128_BLOCKSIZE

// Define state flag values for Keccak-based functions
#define KECCAK1600_STATE_ABSORB 0
#define KECCAK1600_STATE_SQUEEZE 1
// KECCAK1600_STATE_FINAL restricts the incremental calls to SHAKE_Final .
// KECCAK1600_STATE_FINAL can be called once. SHAKE_Squeeze cannot be called after SHAKE_Final.
// SHAKE_Squeeze should be called for streaming XOF output.
#define KECCAK1600_STATE_FINAL 2

typedef struct keccak_st KECCAK1600_CTX;

// The data buffer should have at least the maximum number of
Expand All @@ -82,7 +90,7 @@ struct keccak_st {
size_t buf_load; // used bytes in below buffer
uint8_t buf[SHA3_MAX_BLOCKSIZE]; // should have at least the max data block size bytes
uint8_t pad; // padding character
uint8_t padded; // denotes if padding has been performed
uint8_t state; // denotes the keccak phase (absorb, squeeze, final)
};

// Define SHA{n}[_{variant}]_ASM if sha{n}_block_data_order[_{variant}] is
Expand Down Expand Up @@ -396,32 +404,41 @@ OPENSSL_EXPORT uint8_t *SHAKE128(const uint8_t *data, const size_t in_len,
OPENSSL_EXPORT uint8_t *SHAKE256(const uint8_t *data, const size_t in_len,
uint8_t *out, size_t out_len);

// SHAKE_Init initializes |ctx| with specified |block_size|, returns 1 on
// success and 0 on failure. Calls SHA3_Init under the hood.
int SHAKE_Init(KECCAK1600_CTX *ctx, size_t block_size);

// SHAKE_Final writes |len| bytes of finalized digest to |md|, returns 1 on
// success and 0 on failure. Calls SHA3_Final under the hood.
int SHAKE_Final(uint8_t *md, KECCAK1600_CTX *ctx, size_t len);

// SHA3_Reset zeros the bitstate and the amount of processed input.
void SHA3_Reset(KECCAK1600_CTX *ctx);

// SHA3_Init initialises |ctx| fields and returns 1 on success and 0 on failure.
// SHA3_Init initialises |ctx| fields through |FIPS202_Init| and
// returns 1 on success and 0 on failure.
OPENSSL_EXPORT int SHA3_Init(KECCAK1600_CTX *ctx, size_t bitlen);

// SHA3_Update processes all data blocks that don't need pad through
// |Keccak1600_Absorb| and returns 1 and 0 on failure.
// SHA3_Update check |ctx| pointer and |len| value, calls |FIPS202_Update|
// and returns 1 on success and 0 on failure.
int SHA3_Update(KECCAK1600_CTX *ctx, const void *data, size_t len);

// SHA3_Final pads the last data block and processes it through |Keccak1600_Absorb|.
// SHA3_Final pads the last data block absorbs it through |FIPS202_Finalize|.
// It processes the data through |Keccak1600_Squeeze| and returns 1 and 0 on failure.
int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx);

// Keccak1600_Absorb processes the largest multiple of |r| out of |len| bytes and
// SHAKE_Init initialises |ctx| fields through |FIPS202_Init| and
// returns 1 on success and 0 on failure.
OPENSSL_EXPORT int SHAKE_Init(KECCAK1600_CTX *ctx, size_t block_size);

// SHAKE_Absorb checks |ctx| pointer and |len| values. It updates and absorbs
// input blocks via |FIPS202_Update|.
OPENSSL_EXPORT int SHAKE_Absorb(KECCAK1600_CTX *ctx, const void *data,
size_t len);

// SHAKE_Squeeze pads the last data block absorbs it through |FIPS202_Finalize| on first call.
// It writes |len| bytes of incremental XOF output to |md|, returns 1 on
// success and 0 on failure. It can be called multiple times.
OPENSSL_EXPORT int SHAKE_Squeeze(uint8_t *md, KECCAK1600_CTX *ctx, size_t len);

// SHAKE_Final writes |len| bytes of finalized extendible output to |md|, returns 1 on
// success and 0 on failure. It should be called once to finalize absorb and
// squeeze phases. Incremental XOF output should be generated via SHAKE_Squeeze.
OPENSSL_EXPORT int SHAKE_Final(uint8_t *md, KECCAK1600_CTX *ctx, size_t len);

// Keccak1600_Absorb processes the largest multiple of |r| (block size) out of |len| bytes and
// returns the remaining number of bytes.
size_t Keccak1600_Absorb(uint64_t A[KECCAK1600_ROWS][KECCAK1600_ROWS],
const uint8_t *data, size_t len, size_t r);
OPENSSL_EXPORT size_t Keccak1600_Absorb(uint64_t A[KECCAK1600_ROWS][KECCAK1600_ROWS],
const uint8_t *data, size_t len, size_t r);

// Keccak1600_Squeeze generates |out| value of |len| bytes (per call). It can be called
// multiple times when used as eXtendable Output Function. |padded| indicates
Expand Down
Loading
Loading