Skip to content

Commit

Permalink
Address PR comments
Browse files Browse the repository at this point in the history
Fix comments

Replace memset with OPENSSL_memset

Add NULL pointer checks

Clean (reverse) logic of branches

Update the buf_load inside |FIPS202_Finalize| since last absorb free the internal buffer. Later, it will be used to store the intermediate result for the XOF output chunks (when incremental byte squeezes are added).
  • Loading branch information
manastasova committed Feb 5, 2025
1 parent 0973fc2 commit 2616442
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 25 deletions.
10 changes: 6 additions & 4 deletions crypto/fipsmodule/sha/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,12 @@ extern "C" {

// Define state flag values for Keccak-based functions
#define KECCAK1600_STATE_ABSORB 0
// KECCAK1600_STATE_SQUEEZE is set when |SHAKE_Squeeze| is called.
// It remains set while |SHAKE_Squeeze| is called repeatedly to output
// chunks of the XOF output.
#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.
// KECCAK1600_STATE_FINAL is set once |SHAKE_Final| is called
// so that |SHAKE_Squeeze| cannot be called anymore.
#define KECCAK1600_STATE_FINAL 2

typedef struct keccak_st KECCAK1600_CTX;
Expand Down Expand Up @@ -413,7 +415,7 @@ OPENSSL_EXPORT int SHA3_Init(KECCAK1600_CTX *ctx, size_t bitlen);
int SHA3_Update(KECCAK1600_CTX *ctx, const void *data, size_t len);

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

Expand Down
72 changes: 51 additions & 21 deletions crypto/fipsmodule/sha/sha3.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ uint8_t *SHAKE256(const uint8_t *data, const size_t in_len, uint8_t *out, size_t

// FIPS202 APIs manage internal input/output buffer on top of Keccak1600 API layer
static void FIPS202_Reset(KECCAK1600_CTX *ctx) {
memset(ctx->A, 0, sizeof(ctx->A));
OPENSSL_memset(ctx->A, 0, sizeof(ctx->A));
ctx->buf_load = 0;
ctx->state = KECCAK1600_STATE_ABSORB;
}
Expand Down Expand Up @@ -194,34 +194,45 @@ static int FIPS202_Finalize(uint8_t *md, KECCAK1600_CTX *ctx) {
// Pad the data with 10*1. Note that |num| can be |block_size - 1|
// in which case both byte operations below are performed on
// the same byte.
memset(ctx->buf + num, 0, block_size - num);
OPENSSL_memset(ctx->buf + num, 0, block_size - num);
ctx->buf[num] = ctx->pad;
ctx->buf[block_size - 1] |= 0x80;

if (Keccak1600_Absorb(ctx->A, ctx->buf, block_size, block_size) != 0) {
return 0;
}

// ctx->buf is processed, ctx->buf_load is guaranteed to be zero
ctx->buf_load = 0;

return 1;
}

// SHA3 APIs implement SHA3 functionalities on top of FIPS202 API layer
int SHA3_Init(KECCAK1600_CTX *ctx, size_t bit_len) {
if (bit_len == SHA3_224_DIGEST_BITLENGTH ||
bit_len == SHA3_256_DIGEST_BITLENGTH ||
bit_len == SHA3_384_DIGEST_BITLENGTH ||
bit_len == SHA3_512_DIGEST_BITLENGTH) {
// |block_size| depends on the SHA3 |bit_len| output (digest) length
return FIPS202_Init(ctx, SHA3_PAD_CHAR, SHA3_BLOCKSIZE(bit_len), bit_len);
}
return 0;
if (ctx == NULL) {
return 0;
}

if (bit_len != SHA3_224_DIGEST_BITLENGTH &&
bit_len != SHA3_256_DIGEST_BITLENGTH &&
bit_len != SHA3_384_DIGEST_BITLENGTH &&
bit_len != SHA3_512_DIGEST_BITLENGTH) {
return 0;
}
// |block_size| depends on the SHA3 |bit_len| output (digest) length
return FIPS202_Init(ctx, SHA3_PAD_CHAR, SHA3_BLOCKSIZE(bit_len), bit_len);
}

int SHA3_Update(KECCAK1600_CTX *ctx, const void *data, size_t len) {
if (ctx == NULL) {
return 0;
}

if (data == NULL && len != 0) {
return 0;
}

if (len == 0) {
return 1;
}
Expand All @@ -230,8 +241,11 @@ int SHA3_Update(KECCAK1600_CTX *ctx, const void *data, size_t len) {
}

// SHA3_Final should be called once to process final digest value
// |ctx->state| flag does not need to be updated
int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx) {
if (md == NULL || ctx == NULL) {
return 0;
}

if (ctx->md_size == 0) {
return 1;
}
Expand All @@ -248,31 +262,43 @@ int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx) {
}

int SHAKE_Init(KECCAK1600_CTX *ctx, size_t block_size) {
if (block_size == SHAKE128_BLOCKSIZE ||
block_size == SHAKE256_BLOCKSIZE) {
// |block_size| depends on the SHAKE security level
// The output length |bit_len| is initialized to 0
return FIPS202_Init(ctx, SHAKE_PAD_CHAR, block_size, 0);
if (ctx == NULL) {
return 0;
}

if (block_size != SHAKE128_BLOCKSIZE &&
block_size != SHAKE256_BLOCKSIZE) {
return 0;
}
return 0;
// |block_size| depends on the SHAKE security level
// The output length |bit_len| is initialized to 0
return FIPS202_Init(ctx, SHAKE_PAD_CHAR, block_size, 0);
}

int SHAKE_Absorb(KECCAK1600_CTX *ctx, const void *data, size_t len) {
if (ctx == NULL) {
return 0;
}

if (data == NULL && len != 0) {
return 0;
}

if (len == 0) {
return 1;
}

return FIPS202_Update(ctx, data, len);
}

// SHAKE_Final is a single-shot API and can be called once to finalize absorb and squeeze phases
// SHAKE_Final is to be called once to finalize absorb and squeeze phases
// |ctx->state| restricts consecutive calls to FIPS202_Finalize
// Function SHAKE_Squeeze should be used for incremental XOF output
int SHAKE_Final(uint8_t *md, KECCAK1600_CTX *ctx, size_t len) {
if (ctx == NULL || md == NULL) {
return 0;
}

ctx->md_size = len;
if (ctx->md_size == 0) {
return 1;
Expand All @@ -290,9 +316,12 @@ int SHAKE_Final(uint8_t *md, KECCAK1600_CTX *ctx, size_t len) {
return 1;
}

// SHAKE_Squeeze can be called multiple times
// SHAKE_Squeeze should be called for incremental XOF output
// SHAKE_Squeeze can be called multiple time for incremental XOF output
int SHAKE_Squeeze(uint8_t *md, KECCAK1600_CTX *ctx, size_t len) {
if (ctx == NULL || md == NULL) {
return 0;
}

ctx->md_size = len;

if (ctx->md_size == 0) {
Expand All @@ -303,8 +332,9 @@ int SHAKE_Squeeze(uint8_t *md, KECCAK1600_CTX *ctx, size_t len) {
return 0;
}

// Skip FIPS202_Finalize if the input has been padded and
// the last block has been processed
if (ctx->state == KECCAK1600_STATE_ABSORB) {
// Skip FIPS202_Finalize if the input has been padded and the last block has been processed
if (FIPS202_Finalize(md, ctx) == 0) {
return 0;
}
Expand Down

0 comments on commit 2616442

Please sign in to comment.