Clean up memcpy/memset patterns.
Define `GFp_memcpy` and `GFp_memset` with fallback implementations. Sync up some code that diverged from BoringSSL due to the lack of these functions.
This commit is contained in:
parent
d12e36fec5
commit
46d39428cb
@ -159,7 +159,7 @@ static void fe_frombytes_strict(fe *h, const uint8_t s[32]) {
|
||||
|
||||
static void fe_frombytes(fe *h, const uint8_t s[32]) {
|
||||
uint8_t s_copy[32];
|
||||
bytes_copy(s_copy, s, 32);
|
||||
GFp_memcpy(s_copy, s, 32);
|
||||
s_copy[31] &= 0x7f;
|
||||
fe_frombytes_strict(h, s_copy);
|
||||
}
|
||||
@ -171,21 +171,21 @@ static void fe_tobytes(uint8_t s[32], const fe *f) {
|
||||
|
||||
// h = 0
|
||||
static void fe_0(fe *h) {
|
||||
fe_limbs_zero(h->v);
|
||||
GFp_memset(h, 0, sizeof(fe));
|
||||
}
|
||||
|
||||
static void fe_loose_0(fe_loose *h) {
|
||||
fe_limbs_zero(h->v);
|
||||
GFp_memset(h, 0, sizeof(fe_loose));
|
||||
}
|
||||
|
||||
// h = 1
|
||||
static void fe_1(fe *h) {
|
||||
fe_0(h);
|
||||
GFp_memset(h, 0, sizeof(fe));
|
||||
h->v[0] = 1;
|
||||
}
|
||||
|
||||
static void fe_loose_1(fe_loose *h) {
|
||||
fe_loose_0(h);
|
||||
GFp_memset(h, 0, sizeof(fe_loose));
|
||||
h->v[0] = 1;
|
||||
}
|
||||
|
||||
@ -1782,7 +1782,7 @@ void GFp_x25519_scalar_mult_generic_masked(uint8_t out[32],
|
||||
fe_loose x2l, z2l, x3l, tmp0l, tmp1l;
|
||||
|
||||
uint8_t e[32];
|
||||
bytes_copy(e, scalar_masked, 32);
|
||||
GFp_memcpy(e, scalar_masked, 32);
|
||||
// The following implementation was transcribed to Coq and proven to
|
||||
// correspond to unary scalar multiplication in affine coordinates given that
|
||||
// x1 != 0 is the x coordinate of some point on the curve. It was also checked
|
||||
@ -1856,7 +1856,7 @@ void GFp_x25519_scalar_mult_generic_masked(uint8_t out[32],
|
||||
void GFp_x25519_public_from_private_generic_masked(uint8_t out_public_value[32],
|
||||
const uint8_t private_key_masked[32]) {
|
||||
uint8_t e[32];
|
||||
bytes_copy(e, private_key_masked, 32);
|
||||
GFp_memcpy(e, private_key_masked, 32);
|
||||
|
||||
ge_p3 A;
|
||||
GFp_x25519_ge_scalarmult_base(&A, e);
|
||||
|
@ -65,12 +65,6 @@ static inline void fe_limbs_copy(fe_limb_t r[], const fe_limb_t a[]) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fe_limbs_zero(fe_limb_t r[]) {
|
||||
for (size_t i = 0; i < FE_NUM_LIMBS; ++i) {
|
||||
r[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ge means group element.
|
||||
//
|
||||
// Here the group is the set of pairs (x,y) of field elements (see fe.h)
|
||||
|
@ -14,13 +14,6 @@
|
||||
|
||||
#include <GFp/aes.h>
|
||||
|
||||
#if !defined(__wasm__)
|
||||
#include <string.h>
|
||||
#else
|
||||
void *memcpy(void *, const void*, size_t);
|
||||
void *memset(void *, int, size_t);
|
||||
#endif
|
||||
|
||||
#include "../../internal.h"
|
||||
|
||||
#if defined(OPENSSL_SSE2)
|
||||
@ -353,7 +346,7 @@ static inline uint8_t lo(uint32_t a) {
|
||||
|
||||
static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS],
|
||||
const uint8_t in[16]) {
|
||||
memcpy(out, in, 16);
|
||||
GFp_memcpy(out, in, 16);
|
||||
#if defined(OPENSSL_SSE2)
|
||||
// No conversions needed.
|
||||
#elif defined(OPENSSL_64_BIT)
|
||||
@ -381,7 +374,7 @@ static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS],
|
||||
static inline void aes_nohw_uncompact_block(
|
||||
uint8_t out[16], const aes_word_t in[AES_NOHW_BLOCK_WORDS]) {
|
||||
#if defined(OPENSSL_SSE2)
|
||||
memcpy(out, in, 16); // No conversions needed.
|
||||
GFp_memcpy(out, in, 16); // No conversions needed.
|
||||
#elif defined(OPENSSL_64_BIT)
|
||||
uint64_t a0 = in[0];
|
||||
uint64_t a1 = in[1];
|
||||
@ -389,8 +382,8 @@ static inline void aes_nohw_uncompact_block(
|
||||
aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32));
|
||||
uint64_t b1 =
|
||||
aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32));
|
||||
memcpy(out, &b0, 8);
|
||||
memcpy(out + 8, &b1, 8);
|
||||
GFp_memcpy(out, &b0, 8);
|
||||
GFp_memcpy(out + 8, &b1, 8);
|
||||
#else
|
||||
uint32_t a0 = in[0];
|
||||
uint32_t a1 = in[1];
|
||||
@ -411,10 +404,10 @@ static inline void aes_nohw_uncompact_block(
|
||||
b1 = aes_nohw_uncompact_word(b1);
|
||||
b2 = aes_nohw_uncompact_word(b2);
|
||||
b3 = aes_nohw_uncompact_word(b3);
|
||||
memcpy(out, &b0, 4);
|
||||
memcpy(out + 4, &b1, 4);
|
||||
memcpy(out + 8, &b2, 4);
|
||||
memcpy(out + 12, &b3, 4);
|
||||
GFp_memcpy(out, &b0, 4);
|
||||
GFp_memcpy(out + 4, &b1, 4);
|
||||
GFp_memcpy(out + 8, &b2, 4);
|
||||
GFp_memcpy(out + 12, &b3, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -482,7 +475,7 @@ static void aes_nohw_transpose(AES_NOHW_BATCH *batch) {
|
||||
static void aes_nohw_to_batch(AES_NOHW_BATCH *out, const uint8_t *in,
|
||||
size_t num_blocks) {
|
||||
// Don't leave unused blocks uninitialized.
|
||||
memset(out, 0, sizeof(AES_NOHW_BATCH));
|
||||
GFp_memset(out, 0, sizeof(AES_NOHW_BATCH));
|
||||
debug_assert_nonsecret(num_blocks <= AES_NOHW_BATCH_SIZE);
|
||||
for (size_t i = 0; i < num_blocks; i++) {
|
||||
aes_word_t block[AES_NOHW_BLOCK_WORDS];
|
||||
@ -777,7 +770,7 @@ static void aes_nohw_expand_round_keys(AES_NOHW_SCHEDULE *out,
|
||||
// Copy the round key into each block in the batch.
|
||||
for (size_t j = 0; j < AES_NOHW_BATCH_SIZE; j++) {
|
||||
aes_word_t tmp[AES_NOHW_BLOCK_WORDS];
|
||||
memcpy(tmp, key->rd_key + 4 * i, 16);
|
||||
GFp_memcpy(tmp, key->rd_key + 4 * i, 16);
|
||||
aes_nohw_batch_set(&out->keys[i], tmp, j);
|
||||
}
|
||||
aes_nohw_transpose(&out->keys[i]);
|
||||
@ -801,7 +794,7 @@ static inline aes_word_t aes_nohw_rcon_slice(uint8_t rcon, size_t i) {
|
||||
static void aes_nohw_sub_block(aes_word_t out[AES_NOHW_BLOCK_WORDS],
|
||||
const aes_word_t in[AES_NOHW_BLOCK_WORDS]) {
|
||||
AES_NOHW_BATCH batch;
|
||||
memset(&batch, 0, sizeof(batch));
|
||||
GFp_memset(&batch, 0, sizeof(batch));
|
||||
aes_nohw_batch_set(&batch, in, 0);
|
||||
aes_nohw_transpose(&batch);
|
||||
aes_nohw_sub_bytes(&batch);
|
||||
@ -814,7 +807,7 @@ static void aes_nohw_setup_key_128(AES_KEY *key, const uint8_t in[16]) {
|
||||
|
||||
aes_word_t block[AES_NOHW_BLOCK_WORDS];
|
||||
aes_nohw_compact_block(block, in);
|
||||
memcpy(key->rd_key, block, 16);
|
||||
GFp_memcpy(key->rd_key, block, 16);
|
||||
|
||||
for (size_t i = 1; i <= 10; i++) {
|
||||
aes_word_t sub[AES_NOHW_BLOCK_WORDS];
|
||||
@ -833,7 +826,7 @@ static void aes_nohw_setup_key_128(AES_KEY *key, const uint8_t in[16]) {
|
||||
block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 8));
|
||||
block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 12));
|
||||
}
|
||||
memcpy(key->rd_key + 4 * i, block, 16);
|
||||
GFp_memcpy(key->rd_key + 4 * i, block, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -843,10 +836,10 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) {
|
||||
// Each key schedule iteration produces two round keys.
|
||||
aes_word_t block1[AES_NOHW_BLOCK_WORDS], block2[AES_NOHW_BLOCK_WORDS];
|
||||
aes_nohw_compact_block(block1, in);
|
||||
memcpy(key->rd_key, block1, 16);
|
||||
GFp_memcpy(key->rd_key, block1, 16);
|
||||
|
||||
aes_nohw_compact_block(block2, in + 16);
|
||||
memcpy(key->rd_key + 4, block2, 16);
|
||||
GFp_memcpy(key->rd_key + 4, block2, 16);
|
||||
|
||||
for (size_t i = 2; i <= 14; i += 2) {
|
||||
aes_word_t sub[AES_NOHW_BLOCK_WORDS];
|
||||
@ -864,7 +857,7 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) {
|
||||
block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 8));
|
||||
block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 12));
|
||||
}
|
||||
memcpy(key->rd_key + 4 * i, block1, 16);
|
||||
GFp_memcpy(key->rd_key + 4 * i, block1, 16);
|
||||
|
||||
if (i == 14) {
|
||||
break;
|
||||
@ -880,7 +873,7 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) {
|
||||
block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 8));
|
||||
block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 12));
|
||||
}
|
||||
memcpy(key->rd_key + 4 * (i + 1), block2, 16);
|
||||
GFp_memcpy(key->rd_key + 4 * (i + 1), block2, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -913,10 +906,10 @@ static inline void aes_nohw_xor_block(uint8_t out[16], const uint8_t a[16],
|
||||
const uint8_t b[16]) {
|
||||
for (size_t i = 0; i < 16; i += sizeof(aes_word_t)) {
|
||||
aes_word_t x, y;
|
||||
memcpy(&x, a + i, sizeof(aes_word_t));
|
||||
memcpy(&y, b + i, sizeof(aes_word_t));
|
||||
GFp_memcpy(&x, a + i, sizeof(aes_word_t));
|
||||
GFp_memcpy(&y, b + i, sizeof(aes_word_t));
|
||||
x = aes_nohw_xor(x, y);
|
||||
memcpy(out + i, &x, sizeof(aes_word_t));
|
||||
GFp_memcpy(out + i, &x, sizeof(aes_word_t));
|
||||
}
|
||||
}
|
||||
|
||||
@ -936,7 +929,7 @@ void GFp_aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
uint8_t u8[AES_NOHW_BATCH_SIZE * 16];
|
||||
} ivs, enc_ivs;
|
||||
for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) {
|
||||
memcpy(ivs.u8 + 16 * i, ivec, 16);
|
||||
GFp_memcpy(ivs.u8 + 16 * i, ivec, 16);
|
||||
}
|
||||
|
||||
uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]);
|
||||
|
@ -259,10 +259,49 @@ static inline uint32_t CRYPTO_bswap4(uint32_t x) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void bytes_copy(uint8_t out[], const uint8_t in[], size_t len) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
out[i] = in[i];
|
||||
// Assume we have <string.h> unless we can detect otherwise. The
|
||||
// targets that don't have string.h do have `__has_include`.
|
||||
#define GFp_HAS_STRING_H
|
||||
|
||||
#if defined(__has_include)
|
||||
# if !__has_include(<string.h>)
|
||||
# undef GFp_HAS_STRING_H
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(GFp_HAS_STRING_H)
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
static inline void *GFp_memcpy(void *dst, const void *src, size_t n) {
|
||||
#if defined(GFp_HAS_STRING_H)
|
||||
if (n == 0) {
|
||||
return dst;
|
||||
}
|
||||
return memcpy(dst, src, n);
|
||||
#else
|
||||
unsigned char *d = dst;
|
||||
const unsigned char *s = src;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
return dst;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void *GFp_memset(void *dst, int c, size_t n) {
|
||||
#if defined(GFp_HAS_STRING_H)
|
||||
if (n == 0) {
|
||||
return dst;
|
||||
}
|
||||
return memset(dst, c, n);
|
||||
#else
|
||||
unsigned char *d = dst;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
d[i] = (unsigned char)c;
|
||||
}
|
||||
return dst;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user