From 25fd15ccc0b59d2669a9f190ca15407c48a73401 Mon Sep 17 00:00:00 2001 From: Gerardo Ravago Date: Wed, 12 Jun 2024 12:28:04 -0400 Subject: [PATCH] [Backport] Prevent non-constant-time code in Kyber-R3 implementation (#1632) ### Issues: Resolves V1399146249 ### Description of changes: Backports PR #1619. This change is isolated to the Kyber-round3 implementation which is outside of the FIPS boundary. ### Call-outs: The original PR applied the mitigation to both Kyber-r3 and ML-KEM-IPD implementations. Only the former exists in this branch. ### Testing: How is this change tested (unit tests, fuzz tests, etc.)? Are there any testing steps to be verified by the reviewer? CI 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. --- crypto/kyber/README.md | 1 + crypto/kyber/pqcrystals_kyber_ref_common/poly.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/crypto/kyber/README.md b/crypto/kyber/README.md index aa56a1ab5c..d47e4850fd 100644 --- a/crypto/kyber/README.md +++ b/crypto/kyber/README.md @@ -24,5 +24,6 @@ The following changes were made to the source code in `pqcrystals_kyber_ref_comm * `symmetric-shake.c`: unnecessary include of `fips202.h` is removed. * `api.h`, `fips202.h`, `params.h`: modified [in this PR](https://github.com/aws/aws-lc/pull/655) to support our [prefixed symbols build](https://github.com/aws/aws-lc/blob/main/BUILDING.md#building-with-prefixed-symbols). * `poly.c` and 'polyvec.c' were modified to remove 6 lines of comment from these two reference commits ([dda29cc](https://github.com/pq-crystals/kyber/commit/dda29cc63af721981ee2c831cf00822e69be3220), [272125f](https://github.com/pq-crystals/kyber/commit/272125f6acc8e8b6850fd68ceb901a660ff48196)) +* `poly.c`: the `poly_frommsg` function was modified to address the constant-time issue described [here](https://github.com/pq-crystals/kyber/commit/9b8d30698a3e7449aeb34e62339d4176f11e3c6c). **Usage.** The KEM API is defined and documented in `include/openssl/evp.h`. To see examples of how to use any KEM, including Kyber, see `crypto/kem/README.md`. diff --git a/crypto/kyber/pqcrystals_kyber_ref_common/poly.c b/crypto/kyber/pqcrystals_kyber_ref_common/poly.c index 0aac83a5d8..eee8508392 100644 --- a/crypto/kyber/pqcrystals_kyber_ref_common/poly.c +++ b/crypto/kyber/pqcrystals_kyber_ref_common/poly.c @@ -1,4 +1,7 @@ #include + +#include + #include "params.h" #include "poly.h" #include "ntt.h" @@ -6,6 +9,8 @@ #include "cbd.h" #include "symmetric.h" +#include "../../internal.h" + /************************************************* * Name: poly_compress * @@ -164,7 +169,7 @@ void poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]) void poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { unsigned int i,j; - int16_t mask; + crypto_word_t mask; #if (KYBER_INDCPA_MSGBYTES != KYBER_N/8) #error "KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!" @@ -172,8 +177,13 @@ void poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) for(i=0;i> j)&1); - r->coeffs[8*i+j] = mask & ((KYBER_Q+1)/2); + mask = constant_time_is_zero_w((msg[i] >> j) & 1); + // We cast the result of constant_time_select_w, which is a crypto_word_t, + // to int16_t. The constants must be within the range of int16_t. + OPENSSL_STATIC_ASSERT(((KYBER_Q+1)/2) <= INT16_MAX, + value_exceeds_int16_max); + r->coeffs[8*i+j] = (int16_t) constant_time_select_w(mask, + 0, ((KYBER_Q+1)/2)); } } }