Skip to content

Commit

Permalink
Internal: Separate <string.h> polyfills from OPENSSL_mem*.
Browse files Browse the repository at this point in the history
Previously `OPENSSL_memset` and `OPENSSL_memcpy` diverged from BoringSSL
by providing a fallback implementation for when we can't use <string.h>.
Separate out those fallbacks into `RING_mem*` and re-sync `OPENSSL_mem*`
with BoringSSL, except using `RING_mem*` in their implementations
instead of the C standard library functions.

Re-sync aes_nohw.c with BoringSSL in the same manner.
  • Loading branch information
briansmith committed Oct 30, 2023
1 parent 711d9fc commit a57f3b7
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 48 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ include = [
"include/ring-core/check.h",
"include/ring-core/mem.h",
"include/ring-core/poly1305.h",
"include/ring-core/string_polyfill.h",
"include/ring-core/target.h",
"include/ring-core/type_check.h",
"src/**/*.rs",
Expand Down
42 changes: 21 additions & 21 deletions crypto/fipsmodule/aes/aes_nohw.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,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]) {
OPENSSL_memcpy(out, in, 16);
RING_memcpy(out, in, 16);
#if defined(OPENSSL_SSE2)
// No conversions needed.
#elif defined(OPENSSL_64_BIT)
Expand Down Expand Up @@ -374,16 +374,16 @@ 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)
OPENSSL_memcpy(out, in, 16); // No conversions needed.
RING_memcpy(out, in, 16); // No conversions needed.
#elif defined(OPENSSL_64_BIT)
uint64_t a0 = in[0];
uint64_t a1 = in[1];
uint64_t b0 =
aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32));
uint64_t b1 =
aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32));
OPENSSL_memcpy(out, &b0, 8);
OPENSSL_memcpy(out + 8, &b1, 8);
RING_memcpy(out, &b0, 8);
RING_memcpy(out + 8, &b1, 8);
#else
uint32_t a0 = in[0];
uint32_t a1 = in[1];
Expand All @@ -404,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);
OPENSSL_memcpy(out, &b0, 4);
OPENSSL_memcpy(out + 4, &b1, 4);
OPENSSL_memcpy(out + 8, &b2, 4);
OPENSSL_memcpy(out + 12, &b3, 4);
RING_memcpy(out, &b0, 4);
RING_memcpy(out + 4, &b1, 4);
RING_memcpy(out + 8, &b2, 4);
RING_memcpy(out + 12, &b3, 4);

Check warning on line 410 in crypto/fipsmodule/aes/aes_nohw.c

View check run for this annotation

Codecov / codecov/patch

crypto/fipsmodule/aes/aes_nohw.c#L407-L410

Added lines #L407 - L410 were not covered by tests
#endif
}

Expand Down Expand Up @@ -475,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.
OPENSSL_memset(out, 0, sizeof(AES_NOHW_BATCH));
RING_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];
Expand Down Expand Up @@ -770,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];
OPENSSL_memcpy(tmp, key->rd_key + 4 * i, 16);
RING_memcpy(tmp, key->rd_key + 4 * i, 16);
aes_nohw_batch_set(&out->keys[i], tmp, j);
}
aes_nohw_transpose(&out->keys[i]);
Expand All @@ -794,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;
OPENSSL_memset(&batch, 0, sizeof(batch));
RING_memset(&batch, 0, sizeof(batch));
aes_nohw_batch_set(&batch, in, 0);
aes_nohw_transpose(&batch);
aes_nohw_sub_bytes(&batch);
Expand All @@ -807,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);
OPENSSL_memcpy(key->rd_key, block, 16);
RING_memcpy(key->rd_key, block, 16);

for (size_t i = 1; i <= 10; i++) {
aes_word_t sub[AES_NOHW_BLOCK_WORDS];
Expand All @@ -826,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));
}
OPENSSL_memcpy(key->rd_key + 4 * i, block, 16);
RING_memcpy(key->rd_key + 4 * i, block, 16);
}
}

Expand All @@ -836,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);
OPENSSL_memcpy(key->rd_key, block1, 16);
RING_memcpy(key->rd_key, block1, 16);

aes_nohw_compact_block(block2, in + 16);
OPENSSL_memcpy(key->rd_key + 4, block2, 16);
RING_memcpy(key->rd_key + 4, block2, 16);

for (size_t i = 2; i <= 14; i += 2) {
aes_word_t sub[AES_NOHW_BLOCK_WORDS];
Expand All @@ -857,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));
}
OPENSSL_memcpy(key->rd_key + 4 * i, block1, 16);
RING_memcpy(key->rd_key + 4 * i, block1, 16);

if (i == 14) {
break;
Expand All @@ -873,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));
}
OPENSSL_memcpy(key->rd_key + 4 * (i + 1), block2, 16);
RING_memcpy(key->rd_key + 4 * (i + 1), block2, 16);
}
}

Expand Down Expand Up @@ -906,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;
OPENSSL_memcpy(&x, a + i, sizeof(aes_word_t));
OPENSSL_memcpy(&y, b + i, sizeof(aes_word_t));
RING_memcpy(&x, a + i, sizeof(aes_word_t));
RING_memcpy(&y, b + i, sizeof(aes_word_t));
x = aes_nohw_xor(x, y);
OPENSSL_memcpy(out + i, &x, sizeof(aes_word_t));
RING_memcpy(out + i, &x, sizeof(aes_word_t));
}
}

Expand All @@ -927,7 +927,7 @@ void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
alignas(AES_NOHW_WORD_SIZE) uint8_t ivs[AES_NOHW_BATCH_SIZE * 16];
alignas(AES_NOHW_WORD_SIZE) uint8_t enc_ivs[AES_NOHW_BATCH_SIZE * 16];
for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) {
OPENSSL_memcpy(ivs + 16 * i, ivec, 16);
RING_memcpy(ivs + 16 * i, ivec, 16);
}

uint32_t ctr = CRYPTO_load_u32_be(ivs + 12);
Expand Down
32 changes: 5 additions & 27 deletions crypto/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@

#include <ring-core/base.h> // Must be first.

#include "ring-core/string_polyfill.h"
#include "ring-core/check.h"

#if defined(__clang__)
Expand Down Expand Up @@ -140,10 +141,6 @@
#define RING_CORE_POINTLESS_ARRAY_CONST_CAST(cast) cast
#endif

// `uint8_t` isn't guaranteed to be 'unsigned char' and only 'char' and
// 'unsigned char' are allowed to alias according to ISO C.
typedef unsigned char aliasing_uint8_t;

#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
#define BORINGSSL_HAS_UINT128
typedef __int128_t int128_t;
Expand Down Expand Up @@ -387,39 +384,20 @@ static inline uint64_t CRYPTO_bswap8(uint64_t x) {
}
#endif

#if !defined(RING_CORE_NOSTDLIBINC)
#include <string.h>
#endif

static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) {
#if !defined(RING_CORE_NOSTDLIBINC)
if (n == 0) {
return dst;
}
return memcpy(dst, src, n);
#else
aliasing_uint8_t *d = dst;
const aliasing_uint8_t *s = src;
for (size_t i = 0; i < n; ++i) {
d[i] = s[i];
}
return dst;
#endif

return RING_memcpy(dst, src, n);
}

static inline void *OPENSSL_memset(void *dst, int c, size_t n) {
#if !defined(RING_CORE_NOSTDLIBINC)
if (n == 0) {
return dst;
}
return memset(dst, c, n);
#else
aliasing_uint8_t *d = dst;
for (size_t i = 0; i < n; ++i) {
d[i] = (aliasing_uint8_t)c;
}
return dst;
#endif

return RING_memset(dst, c, n);
}


Expand Down
53 changes: 53 additions & 0 deletions include/ring-core/string_polyfill.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2016-2023 Brian Smith.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

// Polyfills for <string.h>.

#ifndef RING_HEADER_RING_CORE_STRING_POLYFILL_H
#define RING_HEADER_RING_CORE_STRING_POLYFILL_H

#if !defined(RING_CORE_NOSTDLIBINC)
#include <string.h>
#endif

// `uint8_t` isn't guaranteed to be 'unsigned char' and only 'char' and
// 'unsigned char' are allowed to alias according to ISO C.
typedef unsigned char aliasing_uint8_t;

static inline void *RING_memcpy(void *dst, const void *src, size_t n) {
#if !defined(RING_CORE_NOSTDLIBINC)
return memcpy(dst, src, n);
#else
aliasing_uint8_t *d = dst;
const aliasing_uint8_t *s = src;
for (size_t i = 0; i < n; ++i) {
d[i] = s[i];
}
return dst;
#endif
}

static inline void *RING_memset(void *dst, int c, size_t n) {
#if !defined(RING_CORE_NOSTDLIBINC)
return memset(dst, c, n);
#else
aliasing_uint8_t *d = dst;
for (size_t i = 0; i < n; ++i) {
d[i] = (aliasing_uint8_t)c;
}
return dst;
#endif
}

#endif // RING_HEADER_RING_CORE_STRING_POLYFILL_H

0 comments on commit a57f3b7

Please sign in to comment.