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

Fix 32-bit big-endian p521 bug #1240

Merged
merged 7 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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/ec/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ OPENSSL_STATIC_ASSERT(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS,
// An EC_SCALAR is an integer fully reduced modulo the order. Only the first
// |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP|
// and must not be mixed between groups.
typedef union {
typedef struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should have been done as part of the upstream merge of #1177.

// words is the representation of the scalar in little-endian order.
BN_ULONG words[EC_MAX_WORDS];
} EC_SCALAR;
Expand Down
11 changes: 7 additions & 4 deletions crypto/fipsmodule/ec/p384.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ static p384_limb_t p384_felem_nz(const p384_limb_t in1[P384_NLIMBS]) {
#endif // P384_USE_S2N_BIGNUM_FIELD_ARITH

#define P384_FELEM_BYTES (48)
#define P384_FELEM_WORDS ((P384_FELEM_BYTES + BN_BYTES - 1) / BN_BYTES)
justsmth marked this conversation as resolved.
Show resolved Hide resolved

static void p384_felem_copy(p384_limb_t out[P384_NLIMBS],
const p384_limb_t in1[P384_NLIMBS]) {
Expand All @@ -163,9 +164,10 @@ static void p384_felem_cmovznz(p384_limb_t out[P384_NLIMBS],
}

static void p384_from_generic(p384_felem out, const EC_FELEM *in) {
assert(P384_FELEM_WORDS <= EC_MAX_WORDS);
#ifdef OPENSSL_BIG_ENDIAN
uint8_t tmp[P384_FELEM_BYTES];
bn_words_to_little_endian(tmp, P384_FELEM_BYTES, in->words, P384_NLIMBS);
bn_words_to_little_endian(tmp, P384_FELEM_BYTES, in->words, P384_FELEM_WORDS);
p384_felem_from_bytes(out, tmp);
#else
p384_felem_from_bytes(out, (const uint8_t *)in->words);
Expand All @@ -178,20 +180,21 @@ static void p384_to_generic(EC_FELEM *out, const p384_felem in) {
OPENSSL_STATIC_ASSERT(
384 / 8 == sizeof(BN_ULONG) * ((384 + BN_BITS2 - 1) / BN_BITS2),
p384_felem_to_bytes_leaves_bytes_uninitialized);

assert(P384_FELEM_WORDS <= EC_MAX_WORDS);
#ifdef OPENSSL_BIG_ENDIAN
uint8_t tmp[P384_FELEM_BYTES];
p384_felem_to_bytes(tmp, in);
bn_little_endian_to_words(out->words, P384_NLIMBS, tmp, P384_FELEM_BYTES);
bn_little_endian_to_words(out->words, P384_FELEM_WORDS, tmp, P384_FELEM_BYTES);
#else
p384_felem_to_bytes((uint8_t *)out->words, in);
#endif
}

static void p384_from_scalar(p384_felem out, const EC_SCALAR *in) {
assert(P384_FELEM_WORDS <= EC_MAX_WORDS);
#ifdef OPENSSL_BIG_ENDIAN
uint8_t tmp[P384_FELEM_BYTES];
bn_words_to_little_endian(tmp, P384_FELEM_BYTES, in->words, P384_NLIMBS);
bn_words_to_little_endian(tmp, P384_FELEM_BYTES, in->words, P384_FELEM_WORDS);
p384_felem_from_bytes(out, tmp);
#else
p384_felem_from_bytes(out, (const uint8_t *)in->words);
Expand Down
7 changes: 5 additions & 2 deletions crypto/fipsmodule/ec/p521.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ static const p521_limb_t p521_felem_p[P521_NLIMBS] = {
#endif // P521_USE_S2N_BIGNUM_FIELD_ARITH

#define P521_FELEM_BYTES (66)
#define P521_FELEM_WORDS ((P521_FELEM_BYTES + BN_BYTES - 1) / BN_BYTES)

static p521_limb_t p521_felem_nz(const p521_limb_t in1[P521_NLIMBS]) {
p521_limb_t is_not_zero = 0;
Expand Down Expand Up @@ -218,9 +219,10 @@ static void p521_felem_cmovznz(p521_limb_t out[P521_NLIMBS],

// NOTE: the input and output are in little-endian representation.
static void p521_from_generic(p521_felem out, const EC_FELEM *in) {
assert(P521_FELEM_WORDS <= EC_MAX_WORDS);
#ifdef OPENSSL_BIG_ENDIAN
uint8_t tmp[P521_FELEM_BYTES];
bn_words_to_little_endian(tmp, P521_FELEM_BYTES, in->words, P521_NLIMBS);
bn_words_to_little_endian(tmp, P521_FELEM_BYTES, in->words, P521_FELEM_WORDS);
p521_felem_from_bytes(out, tmp);
#else
p521_felem_from_bytes(out, (const uint8_t *)in->words);
Expand All @@ -237,10 +239,11 @@ static void p521_to_generic(EC_FELEM *out, const p521_felem in) {
// translate to 72 bytes, which means that we have to make sure that the
// extra 6 bytes are zeroed out. To avoid confusion over 32 vs. 64 bit
// systems and Fiat's vs. ours representation we zero out the whole element.
assert(P521_FELEM_WORDS <= EC_MAX_WORDS);
#ifdef OPENSSL_BIG_ENDIAN
uint8_t tmp[P521_FELEM_BYTES];
p521_felem_to_bytes(tmp, in);
bn_little_endian_to_words(out->words, P521_NLIMBS, tmp, P521_FELEM_BYTES);
bn_little_endian_to_words(out->words, P521_FELEM_WORDS, tmp, P521_FELEM_BYTES);
#else
OPENSSL_memset((uint8_t*)out->words, 0, sizeof(out->words));
// Convert the element to bytes.
Expand Down
Loading