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

Migrated ML-KEM SHA3/SHAKE usage to fipsmodule #1851

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion crypto/fipsmodule/ml_kem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The code was refactored in [this PR](https://github.com/aws/aws-lc/pull/1763) by
that initialize a given structure with values corresponding to a parameter set. This structure is then passed to every function that requires it as a function argument. In addition, the following changes were made to the source code in `ml_kem_ref` directory:
- `randombytes.{h|c}` are deleted because we are using the randomness generation functions provided by AWS-LC.
- `kem.c`: call to randombytes function is replaced with a call to RAND_bytes and the appropriate header file is included (openssl/rand.h).
- `fips202.{h|c}` are deleted and the ones from `crypto/kyber/pqcrystals_kyber_ref_common` directory are used.
- `fips202.{h|c}` are deleted as all SHA3/SHAKE functionality is provided instead by AWS-LC fipsmodule/sha rather than the reference implementation.
- `symmetric-shake.c`: unnecessary include of fips202.h is removed.
- `api.h`: `pqcrystals` prefix substituted with `ml_kem` (to be able to build alongside `crypto/kyber`).
- `poly.c`: the `poly_frommsg` function was modified to address the constant-time issue described [here](https://github.com/pq-crystals/kyber/commit/9b8d30698a3e7449aeb34e62339d4176f11e3c6c).
Expand Down
10 changes: 5 additions & 5 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/indcpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,24 +167,24 @@ void gen_matrix(ml_kem_params *params, polyvec *a, const uint8_t seed[KYBER_SYMB
unsigned int ctr, i, j, k;
unsigned int buflen, off;
uint8_t buf[GEN_MATRIX_NBLOCKS*XOF_BLOCKBYTES+2];
xof_state state;
KECCAK1600_CTX ctx;

for(i=0;i<params->k;i++) {
for(j=0;j<params->k;j++) {
if(transposed)
xof_absorb(&state, seed, i, j);
xof_absorb(&ctx, seed, i, j);
else
xof_absorb(&state, seed, j, i);
xof_absorb(&ctx, seed, j, i);

xof_squeezeblocks(buf, GEN_MATRIX_NBLOCKS, &state);
xof_squeezeblocks(buf, GEN_MATRIX_NBLOCKS, &ctx);
buflen = GEN_MATRIX_NBLOCKS*XOF_BLOCKBYTES;
ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, buflen);

while(ctr < KYBER_N) {
off = buflen % 3;
for(k = 0; k < off; k++)
buf[k] = buf[buflen - off + k];
xof_squeezeblocks(buf + off, 1, &state);
xof_squeezeblocks(buf + off, 1, &ctx);
buflen = off + XOF_BLOCKBYTES;
ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, buflen);
}
Expand Down
38 changes: 27 additions & 11 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/symmetric-shake.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
*
* Description: Absorb step of the SHAKE128 specialized for the Kyber context.
*
* Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak state
* Arguments: - KECCAK1600_CTX *ctx: pointer to (uninitialized) output Keccak state
* - const uint8_t *seed: pointer to KYBER_SYMBYTES input to be absorbed into state
* - uint8_t i: additional byte of input
* - uint8_t j: additional byte of input
**************************************************/
void kyber_shake128_absorb(keccak_state *state,
void kyber_shake128_absorb(KECCAK1600_CTX *ctx,
const uint8_t seed[KYBER_SYMBYTES],
uint8_t x,
uint8_t y)
Expand All @@ -25,7 +25,25 @@ void kyber_shake128_absorb(keccak_state *state,
extseed[KYBER_SYMBYTES+0] = x;
extseed[KYBER_SYMBYTES+1] = y;

shake128_absorb_once(state, extseed, sizeof(extseed));
SHAKE_Init(ctx, SHAKE128_BLOCKSIZE);
SHA3_Update(ctx, extseed, sizeof(extseed));
}

/*************************************************
* Name: kyber_shake128_squeeze
*
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
* SHAKE128_RATE bytes each. Can be called multiple times
* to keep squeezing. Assumes new block has not yet been
* started.
*
* Arguments: - uint8_t *out: pointer to output blocks
* - size_t nblocks: number of blocks to be squeezed (written to output)
* - KECCAK1600_CTX *ctx: pointer to input/output Keccak state
**************************************************/
void kyber_shake128_squeeze(KECCAK1600_CTX *ctx, uint8_t *out, int nblocks)
{
SHAKE_Final(out, ctx, nblocks * SHAKE128_BLOCKSIZE);
}

/*************************************************
Expand All @@ -46,7 +64,7 @@ void kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYM
memcpy(extkey, key, KYBER_SYMBYTES);
extkey[KYBER_SYMBYTES] = nonce;

shake256(out, outlen, extkey, sizeof(extkey));
SHAKE256(extkey, sizeof(extkey), out, outlen);
}

/*************************************************
Expand All @@ -62,11 +80,9 @@ void kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYM
**************************************************/
void kyber_shake256_rkprf(ml_kem_params *params, uint8_t out[KYBER_SSBYTES], const uint8_t key[KYBER_SYMBYTES], const uint8_t *input)
{
keccak_state s;

shake256_init(&s);
shake256_absorb(&s, key, KYBER_SYMBYTES);
shake256_absorb(&s, input, params->ciphertext_bytes);
shake256_finalize(&s);
shake256_squeeze(out, KYBER_SSBYTES, &s);
KECCAK1600_CTX ctx;
SHAKE_Init(&ctx, SHAKE256_BLOCKSIZE);
SHA3_Update(&ctx, key, KYBER_SYMBYTES);
SHA3_Update(&ctx, input, params->ciphertext_bytes);
SHAKE_Final(out, &ctx, KYBER_SSBYTES);
}
15 changes: 7 additions & 8 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/symmetric.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
#include <stdint.h>
#include "params.h"

#include "../../../kyber/pqcrystals_kyber_ref_common/fips202.h"

typedef keccak_state xof_state;
#include "../../sha/internal.h"

#define kyber_shake128_absorb KYBER_NAMESPACE(kyber_shake128_absorb)
void kyber_shake128_absorb(keccak_state *s,
void kyber_shake128_absorb(KECCAK1600_CTX *ctx,
const uint8_t seed[KYBER_SYMBYTES],
uint8_t x,
uint8_t y);
Expand All @@ -21,12 +19,13 @@ void kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYM
#define kyber_shake256_rkprf KYBER_NAMESPACE(kyber_shake256_rkprf)
void kyber_shake256_rkprf(ml_kem_params *params, uint8_t out[KYBER_SSBYTES], const uint8_t key[KYBER_SYMBYTES], const uint8_t *input);

#define XOF_BLOCKBYTES SHAKE128_RATE
#define kyber_shake128_squeeze KYBER_NAMESPACE(kyber_shake128_squeeze)
void kyber_shake128_squeeze(KECCAK1600_CTX *ctx, uint8_t *out, int nblocks);

#define hash_h(OUT, IN, INBYTES) sha3_256(OUT, IN, INBYTES)
#define hash_g(OUT, IN, INBYTES) sha3_512(OUT, IN, INBYTES)
#define hash_h(OUT, IN, INBYTES) SHA3_256(IN, INBYTES, OUT)
#define hash_g(OUT, IN, INBYTES) SHA3_512(IN, INBYTES, OUT)
#define xof_absorb(STATE, SEED, X, Y) kyber_shake128_absorb(STATE, SEED, X, Y)
#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) kyber_shake128_squeeze(STATE, OUT, OUTBLOCKS)
#define prf(OUT, OUTBYTES, KEY, NONCE) kyber_shake256_prf(OUT, OUTBYTES, KEY, NONCE)
#define rkprf(PARAMS, OUT, KEY, INPUT) kyber_shake256_rkprf(PARAMS, OUT, KEY, INPUT)

Expand Down
2 changes: 2 additions & 0 deletions crypto/fipsmodule/sha/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ extern "C" {
#define SHAKE_PAD_CHAR 0x1F
#define SHAKE128_BLOCKSIZE (KECCAK1600_WIDTH - 128 * 2) / 8
#define SHAKE256_BLOCKSIZE (KECCAK1600_WIDTH - 256 * 2) / 8
#define SHAKE128_RATE 168
#define XOF_BLOCKBYTES SHAKE128_RATE

// SHAKE128 has the maximum block size among the SHA3/SHAKE algorithms.
#define SHA3_MAX_BLOCKSIZE SHAKE128_BLOCKSIZE
Expand Down
Loading