diff --git a/crypto/ec/ec_asn1.cc b/crypto/ec/ec_asn1.cc index ce81580..58f379c 100644 --- a/crypto/ec/ec_asn1.cc +++ b/crypto/ec/ec_asn1.cc
@@ -19,6 +19,7 @@ #include <openssl/bn.h> #include <openssl/bytestring.h> +#include <openssl/ec_key.h> #include <openssl/err.h> #include <openssl/mem.h> #include <openssl/nid.h>
diff --git a/crypto/ec/ec_derive.cc b/crypto/ec/ec_derive.cc index 8bea9c9..2d88ac6 100644 --- a/crypto/ec/ec_derive.cc +++ b/crypto/ec/ec_derive.cc
@@ -31,7 +31,7 @@ const char *name = EC_curve_nid2nist(EC_GROUP_get_curve_name(group)); if (name == NULL || strlen(name) > EC_KEY_DERIVE_MAX_NAME_LEN) { OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); - return NULL; + return nullptr; } // Assemble a label string to provide some key separation in case |secret| is @@ -51,7 +51,7 @@ // (The actual bound is a bit tighter, but our curves are much larger than // 128-bit.) OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - return NULL; + return nullptr; } uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES]; @@ -59,38 +59,35 @@ BN_num_bytes(EC_GROUP_get0_order(group)) + EC_KEY_DERIVE_EXTRA_BYTES; assert(derived_len <= sizeof(derived)); if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len, - /*salt=*/NULL, /*salt_len=*/0, (const uint8_t *)info, + /*salt=*/nullptr, /*salt_len=*/0, (const uint8_t *)info, strlen(info))) { - return NULL; + return nullptr; } - EC_KEY *key = EC_KEY_new(); - BN_CTX *ctx = BN_CTX_new(); - BIGNUM *priv = BN_bin2bn(derived, derived_len, NULL); - EC_POINT *pub = EC_POINT_new(group); - if (key == NULL || ctx == NULL || priv == NULL || pub == NULL || + bssl::UniquePtr<EC_KEY> key(EC_KEY_new()); + bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new()); + bssl::UniquePtr<BIGNUM> priv(BN_bin2bn(derived, derived_len, nullptr)); + bssl::UniquePtr<EC_POINT> pub(EC_POINT_new(group)); + if (key == nullptr || ctx == nullptr || priv == nullptr || pub == nullptr || // Reduce |priv| with Montgomery reduction. First, convert "from" // Montgomery form to compute |priv| * R^-1 mod |order|. This requires // |priv| be under order * R, which is true if the group order is large // enough. 2^(num_bytes(order)) < 2^8 * order, so: // // priv < 2^8 * order * 2^128 < order * order < order * R - !BN_from_montgomery(priv, priv, &group->order, ctx) || + !BN_from_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) || // Multiply by R^2 and do another Montgomery reduction to compute // priv * R^-1 * R^2 * R^-1 = priv mod order. - !BN_to_montgomery(priv, priv, &group->order, ctx) || - !EC_POINT_mul(group, pub, priv, NULL, NULL, ctx) || - !EC_KEY_set_group(key, group) || !EC_KEY_set_public_key(key, pub) || - !EC_KEY_set_private_key(key, priv)) { - EC_KEY_free(key); - key = NULL; - goto err; + !BN_to_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) || + !EC_POINT_mul(group, pub.get(), priv.get(), nullptr, nullptr, + ctx.get()) || + !EC_KEY_set_group(key.get(), group) || + !EC_KEY_set_public_key(key.get(), pub.get()) || + !EC_KEY_set_private_key(key.get(), priv.get())) { + OPENSSL_cleanse(derived, sizeof(derived)); + return nullptr; } -err: OPENSSL_cleanse(derived, sizeof(derived)); - BN_CTX_free(ctx); - BN_free(priv); - EC_POINT_free(pub); - return key; + return key.release(); }
diff --git a/crypto/ecdsa/ecdsa_p1363_test.cc b/crypto/ecdsa/ecdsa_p1363_test.cc index 0600115..d8f1a32 100644 --- a/crypto/ecdsa/ecdsa_p1363_test.cc +++ b/crypto/ecdsa/ecdsa_p1363_test.cc
@@ -14,7 +14,6 @@ #include <stdio.h> -#include <utility> #include <vector> #include <gtest/gtest.h> @@ -27,7 +26,6 @@ #include <openssl/rand.h> #include "../test/file_test.h" -#include "../test/test_util.h" #include "../test/wycheproof_util.h"
diff --git a/crypto/ex_data.cc b/crypto/ex_data.cc index 825c35f..cb8a681 100644 --- a/crypto/ex_data.cc +++ b/crypto/ex_data.cc
@@ -27,8 +27,6 @@ #include "internal.h" -DEFINE_STACK_OF(CRYPTO_EX_DATA_FUNCS) - struct crypto_ex_data_func_st { long argl; // Arbitary long void *argp; // Arbitary void pointer
diff --git a/crypto/fipsmodule/bn/ctx.cc.inc b/crypto/fipsmodule/bn/ctx.cc.inc index 7cc7c9b..a862ac2 100644 --- a/crypto/fipsmodule/bn/ctx.cc.inc +++ b/crypto/fipsmodule/bn/ctx.cc.inc
@@ -17,175 +17,91 @@ #include <assert.h> #include <string.h> +#include <utility> + #include <openssl/err.h> #include <openssl/mem.h> -#include "../../internal.h" +#include "../../mem_internal.h" -// The stack frame info is resizing, set a first-time expansion size; -#define BN_CTX_START_FRAMES 32 - - -// BN_STACK - -// A |BN_STACK| is a stack of |size_t| values. -typedef struct { - // Array of indexes into |ctx->bignums|. - size_t *indexes; - // Number of stack frames, and the size of the allocated array - size_t depth, size; -} BN_STACK; - -static void BN_STACK_init(BN_STACK *); -static void BN_STACK_cleanup(BN_STACK *); -static int BN_STACK_push(BN_STACK *, size_t idx); -static size_t BN_STACK_pop(BN_STACK *); - - -// BN_CTX - -DEFINE_STACK_OF(BIGNUM) - -// The opaque BN_CTX type struct bignum_ctx { - // bignums is the stack of |BIGNUM|s managed by this |BN_CTX|. - STACK_OF(BIGNUM) *bignums; - // stack is the stack of |BN_CTX_start| frames. It is the value of |used| at + ~bignum_ctx() { + // All |BN_CTX_start| calls must be matched with |BN_CTX_end|, otherwise the + // function may use more memory than expected, potentially without bound if + // done in a loop. Assert that all |BIGNUM|s have been released. + assert(used_ == 0 || error_); + } + + // bignums_ is the stack of |BIGNUM|s managed by this |BN_CTX|. + bssl::Vector<bssl::UniquePtr<BIGNUM>> bignums_; + // stack_ is the stack of |BN_CTX_start| frames. It is the value of |used_| at // the time |BN_CTX_start| was called. - BN_STACK stack; - // used is the number of |BIGNUM|s from |bignums| that have been used. - size_t used; - // error is one if any operation on this |BN_CTX| failed. All subsequent + bssl::Vector<size_t> stack_; + // used_ is the number of |BIGNUM|s from |bignums_| that have been used. + size_t used_ = 0; + // error_ is whether any operation on this |BN_CTX| failed. All subsequent // operations will fail. - char error; - // defer_error is one if an operation on this |BN_CTX| has failed, but no + bool error_ = false; + // defer_error_ is whether an operation on this |BN_CTX| has failed, but no // error has been pushed to the queue yet. This is used to defer errors from // |BN_CTX_start| to |BN_CTX_get|. - char defer_error; -}; + bool defer_error_ = false; +} /* BN_CTX */; -BN_CTX *BN_CTX_new(void) { - BN_CTX *ret = reinterpret_cast<BN_CTX *>(OPENSSL_malloc(sizeof(BN_CTX))); - if (!ret) { - return NULL; - } +BN_CTX *BN_CTX_new(void) { return bssl::New<BN_CTX>(); } - // Initialise the structure - ret->bignums = NULL; - BN_STACK_init(&ret->stack); - ret->used = 0; - ret->error = 0; - ret->defer_error = 0; - return ret; -} - -void BN_CTX_free(BN_CTX *ctx) { - // All |BN_CTX_start| calls must be matched with |BN_CTX_end|, otherwise the - // function may use more memory than expected, potentially without bound if - // done in a loop. Assert that all |BIGNUM|s have been released. - if (ctx == nullptr) { - return; - } - assert(ctx->used == 0 || ctx->error); - sk_BIGNUM_pop_free(ctx->bignums, BN_free); - BN_STACK_cleanup(&ctx->stack); - OPENSSL_free(ctx); -} +void BN_CTX_free(BN_CTX *ctx) { bssl::Delete(ctx); } void BN_CTX_start(BN_CTX *ctx) { - if (ctx->error) { + if (ctx->error_) { // Once an operation has failed, |ctx->stack| no longer matches the number // of |BN_CTX_end| calls to come. Do nothing. return; } - if (!BN_STACK_push(&ctx->stack, ctx->used)) { - ctx->error = 1; + if (!ctx->stack_.Push(ctx->used_)) { + ctx->error_ = true; // |BN_CTX_start| cannot fail, so defer the error to |BN_CTX_get|. - ctx->defer_error = 1; + ctx->defer_error_ = true; + ERR_clear_error(); } } BIGNUM *BN_CTX_get(BN_CTX *ctx) { // Once any operation has failed, they all do. - if (ctx->error) { - if (ctx->defer_error) { + if (ctx->error_) { + if (ctx->defer_error_) { OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); - ctx->defer_error = 0; + ctx->defer_error_ = false; } - return NULL; + return nullptr; } - if (ctx->bignums == NULL) { - ctx->bignums = sk_BIGNUM_new_null(); - if (ctx->bignums == NULL) { - ctx->error = 1; - return NULL; - } - } - - if (ctx->used == sk_BIGNUM_num(ctx->bignums)) { - BIGNUM *bn = BN_new(); - if (bn == NULL || !sk_BIGNUM_push(ctx->bignums, bn)) { + if (ctx->used_ == ctx->bignums_.size()) { + bssl::UniquePtr<BIGNUM> bn(BN_new()); + if (bn == nullptr || !ctx->bignums_.Push(std::move(bn))) { OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); - BN_free(bn); - ctx->error = 1; - return NULL; + ctx->error_ = true; + return nullptr; } } - BIGNUM *ret = sk_BIGNUM_value(ctx->bignums, ctx->used); + BIGNUM *ret = ctx->bignums_[ctx->used_].get(); BN_zero(ret); - // This is bounded by |sk_BIGNUM_num|, so it cannot overflow. - ctx->used++; + // This is bounded by |ctx->bignums_.size()|, so it cannot overflow. + ctx->used_++; return ret; } void BN_CTX_end(BN_CTX *ctx) { - if (ctx->error) { - // Once an operation has failed, |ctx->stack| no longer matches the number + if (ctx->error_) { + // Once an operation has failed, |ctx->stack_| no longer matches the number // of |BN_CTX_end| calls to come. Do nothing. return; } - ctx->used = BN_STACK_pop(&ctx->stack); -} - - -// BN_STACK - -static void BN_STACK_init(BN_STACK *st) { - st->indexes = NULL; - st->depth = st->size = 0; -} - -static void BN_STACK_cleanup(BN_STACK *st) { OPENSSL_free(st->indexes); } - -static int BN_STACK_push(BN_STACK *st, size_t idx) { - if (st->depth == st->size) { - // This function intentionally does not push to the error queue on error. - // Error-reporting is deferred to |BN_CTX_get|. - size_t new_size = st->size != 0 ? st->size * 3 / 2 : BN_CTX_START_FRAMES; - if (new_size <= st->size || new_size > SIZE_MAX / sizeof(size_t)) { - return 0; - } - size_t *new_indexes = reinterpret_cast<size_t *>( - OPENSSL_realloc(st->indexes, new_size * sizeof(size_t))); - if (new_indexes == NULL) { - return 0; - } - st->indexes = new_indexes; - st->size = new_size; - } - - st->indexes[st->depth] = idx; - st->depth++; - return 1; -} - -static size_t BN_STACK_pop(BN_STACK *st) { - assert(st->depth > 0); - st->depth--; - return st->indexes[st->depth]; + assert(!ctx->stack_.empty()); + ctx->used_ = ctx->stack_.back(); + ctx->stack_.pop_back(); }
diff --git a/crypto/fipsmodule/digest/md32_common.h b/crypto/fipsmodule/digest/md32_common.h index b64f20b..9e237b2 100644 --- a/crypto/fipsmodule/digest/md32_common.h +++ b/crypto/fipsmodule/digest/md32_common.h
@@ -16,14 +16,13 @@ #define OPENSSL_HEADER_CRYPTO_FIPSMODULE_DIGEST_MD32_COMMON_H #include <openssl/base.h> +#include <openssl/span.h> #include <assert.h> #include "../../internal.h" -#if defined(__cplusplus) -extern "C" { -#endif +BSSL_NAMESPACE_BEGIN // This is a generic 32-bit "collector" for message digest algorithms. It @@ -48,70 +47,80 @@ // |h| is the hash state and is updated by a function of type // |crypto_md32_block_func|. |data| is the partial unprocessed block and has // |num| bytes. |Nl| and |Nh| maintain the number of bits processed so far. +// +// The template parameter is then a traits struct defined as follows: +// +// struct HashTraits { +// // HashContext is the hash type defined above. +// using HashContext = <NAME>_CTX; +// +// // kBlockSize is the block size of the hash function. +// static constexpr size_t kBlockSize = <block size>; +// +// // kLengthIsBigEndian determines whether the final length is encoded in +// // big or little endian. +// static constexpr bool kLengthIsBigEndian = ...; +// +// // HashBlocks incorporates |num_blocks| blocks of input from |data| +// // into |state|. It is assumed the caller has sized |state| and |data| +// // for the hash function. +// static void HashBlocks(uint32_t *state, const uint8_t *data, +// size_t num_blocks) { +// <name>_block_data_order(state, data, num_blocks); +// } +// }; +// +// The reason for this formulation is to encourage the compiler to specialize +// all the code for the block size and block function. -// A crypto_md32_block_func should incorporate |num_blocks| of input from |data| -// into |state|. It is assumed the caller has sized |state| and |data| for the -// hash function. -typedef void (*crypto_md32_block_func)(uint32_t *state, const uint8_t *data, - size_t num_blocks); - -// crypto_md32_update adds |len| bytes from |in| to the digest. |data| must be a -// buffer of length |block_size| with the first |*num| bytes containing a -// partial block. This function combines the partial block with |in| and -// incorporates any complete blocks into the digest state |h|. It then updates -// |data| and |*num| with the new partial block and updates |*Nh| and |*Nl| with -// the data consumed. -static inline void crypto_md32_update(crypto_md32_block_func block_func, - uint32_t *h, uint8_t *data, - size_t block_size, unsigned *num, - uint32_t *Nh, uint32_t *Nl, - const uint8_t *in, size_t len) { - if (len == 0) { +// crypto_md32_update hashes |in| to |ctx|. +template <typename Traits> +inline void crypto_md32_update(typename Traits::HashContext *ctx, + Span<const uint8_t> in) { + static_assert(Traits::kBlockSize == sizeof(ctx->data), "block size is wrong"); + if (in.empty()) { return; } - uint32_t l = *Nl + (((uint32_t)len) << 3); - if (l < *Nl) { + uint32_t l = ctx->Nl + ((static_cast<uint32_t>(in.size())) << 3); + if (l < ctx->Nl) { // Handle carries. - (*Nh)++; + ctx->Nh++; } - *Nh += (uint32_t)(len >> 29); - *Nl = l; + ctx->Nh += static_cast<uint32_t>(in.size() >> 29); + ctx->Nl = l; - size_t n = *num; + size_t n = ctx->num; if (n != 0) { - if (len >= block_size || len + n >= block_size) { - OPENSSL_memcpy(data + n, in, block_size - n); - block_func(h, data, 1); - n = block_size - n; - in += n; - len -= n; - *num = 0; + if (in.size() >= Traits::kBlockSize || + in.size() + n >= Traits::kBlockSize) { + OPENSSL_memcpy(ctx->data + n, in.data(), Traits::kBlockSize - n); + Traits::HashBlocks(ctx->h, ctx->data, 1); + in = in.subspan(Traits::kBlockSize - n); + ctx->num = 0; // Keep |data| zeroed when unused. - OPENSSL_memset(data, 0, block_size); + OPENSSL_memset(ctx->data, 0, Traits::kBlockSize); } else { - OPENSSL_memcpy(data + n, in, len); - *num += (unsigned)len; + OPENSSL_memcpy(ctx->data + n, in.data(), in.size()); + ctx->num += static_cast<unsigned>(in.size()); return; } } - n = len / block_size; + n = in.size() / Traits::kBlockSize; if (n > 0) { - block_func(h, in, n); - n *= block_size; - in += n; - len -= n; + Traits::HashBlocks(ctx->h, in.data(), n); + in = in.subspan(n * Traits::kBlockSize); } - if (len != 0) { - *num = (unsigned)len; - OPENSSL_memcpy(data, in, len); + if (!in.empty()) { + ctx->num = static_cast<unsigned>(in.size()); + OPENSSL_memcpy(ctx->data, in.data(), in.size()); } } // crypto_md32_final incorporates the partial block and trailing length into the -// digest state |h|. The trailing length is encoded in little-endian if +// digest state in |ctx|. The trailing length is encoded in little-endian if // |is_big_endian| is zero and big-endian otherwise. |data| must be a buffer of // length |block_size| with the first |*num| bytes containing a partial block. // |Nh| and |Nl| contain the total number of bits processed. On return, this @@ -120,42 +129,38 @@ // // This function does not serialize |h| into a final digest. This is the // responsibility of the caller. -static inline void crypto_md32_final(crypto_md32_block_func block_func, - uint32_t *h, uint8_t *data, - size_t block_size, unsigned *num, - uint32_t Nh, uint32_t Nl, - int is_big_endian) { +template <typename Traits> +inline void crypto_md32_final(typename Traits::HashContext *ctx) { + static_assert(Traits::kBlockSize == sizeof(ctx->data), "block size is wrong"); // |data| always has room for at least one byte. A full block would have // been consumed. - size_t n = *num; - assert(n < block_size); - data[n] = 0x80; + size_t n = ctx->num; + assert(n < Traits::kBlockSize); + ctx->data[n] = 0x80; n++; // Fill the block with zeros if there isn't room for a 64-bit length. - if (n > block_size - 8) { - OPENSSL_memset(data + n, 0, block_size - n); + if (n > Traits::kBlockSize - 8) { + OPENSSL_memset(ctx->data + n, 0, Traits::kBlockSize - n); n = 0; - block_func(h, data, 1); + Traits::HashBlocks(ctx->h, ctx->data, 1); } - OPENSSL_memset(data + n, 0, block_size - 8 - n); + OPENSSL_memset(ctx->data + n, 0, Traits::kBlockSize - 8 - n); // Append a 64-bit length to the block and process it. - if (is_big_endian) { - CRYPTO_store_u32_be(data + block_size - 8, Nh); - CRYPTO_store_u32_be(data + block_size - 4, Nl); + if constexpr (Traits::kLengthIsBigEndian) { + CRYPTO_store_u32_be(ctx->data + Traits::kBlockSize - 8, ctx->Nh); + CRYPTO_store_u32_be(ctx->data + Traits::kBlockSize - 4, ctx->Nl); } else { - CRYPTO_store_u32_le(data + block_size - 8, Nl); - CRYPTO_store_u32_le(data + block_size - 4, Nh); + CRYPTO_store_u32_le(ctx->data + Traits::kBlockSize - 8, ctx->Nl); + CRYPTO_store_u32_le(ctx->data + Traits::kBlockSize - 4, ctx->Nh); } - block_func(h, data, 1); - *num = 0; - OPENSSL_memset(data, 0, block_size); + Traits::HashBlocks(ctx->h, ctx->data, 1); + ctx->num = 0; + OPENSSL_memset(ctx->data, 0, Traits::kBlockSize); } -#if defined(__cplusplus) -} // extern C -#endif +BSSL_NAMESPACE_END #endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_DIGEST_MD32_COMMON_H
diff --git a/crypto/fipsmodule/sha/sha1.cc.inc b/crypto/fipsmodule/sha/sha1.cc.inc index ca591fd..530ab93 100644 --- a/crypto/fipsmodule/sha/sha1.cc.inc +++ b/crypto/fipsmodule/sha/sha1.cc.inc
@@ -15,6 +15,7 @@ #include <string.h> #include <openssl/mem.h> +#include <openssl/span.h> #include "../../internal.h" #include "../bcm_interface.h" @@ -43,10 +44,21 @@ return bcm_infallible::approved; } +namespace { +struct SHA1Traits { + using HashContext = SHA_CTX; + static constexpr size_t kBlockSize = BCM_SHA_CBLOCK; + static constexpr bool kLengthIsBigEndian = true; + static void HashBlocks(uint32_t *state, const uint8_t *data, + size_t num_blocks) { + sha1_block_data_order(state, data, num_blocks); + } +}; +} // namespace + bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len) { - crypto_md32_update(&sha1_block_data_order, c->h, c->data, SHA_CBLOCK, &c->num, - &c->Nh, &c->Nl, reinterpret_cast<const uint8_t *>(data), - len); + bssl::crypto_md32_update<SHA1Traits>( + c, bssl::Span(static_cast<const uint8_t *>(data), len)); return bcm_infallible::approved; } @@ -60,9 +72,7 @@ } bcm_infallible BCM_sha1_final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *c) { - crypto_md32_final(&sha1_block_data_order, c->h, c->data, SHA_CBLOCK, &c->num, - c->Nh, c->Nl, /*is_big_endian=*/1); - + bssl::crypto_md32_final<SHA1Traits>(c); sha1_output_state(out, c); FIPS_service_indicator_update_state(); return bcm_infallible::approved;
diff --git a/crypto/fipsmodule/sha/sha256.cc.inc b/crypto/fipsmodule/sha/sha256.cc.inc index 1ce4210..a1a22a9 100644 --- a/crypto/fipsmodule/sha/sha256.cc.inc +++ b/crypto/fipsmodule/sha/sha256.cc.inc
@@ -15,6 +15,7 @@ #include <string.h> #include <openssl/mem.h> +#include <openssl/span.h> #include "../../internal.h" #include "../bcm_interface.h" @@ -62,10 +63,21 @@ return bcm_infallible::approved; } +namespace { +struct SHA256Traits { + using HashContext = SHA256_CTX; + static constexpr size_t kBlockSize = BCM_SHA256_CBLOCK; + static constexpr bool kLengthIsBigEndian = true; + static void HashBlocks(uint32_t *state, const uint8_t *data, + size_t num_blocks) { + sha256_block_data_order(state, data, num_blocks); + } +}; +} // namespace + bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) { - crypto_md32_update(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK, - &c->num, &c->Nh, &c->Nl, - reinterpret_cast<const uint8_t *>(data), len); + bssl::crypto_md32_update<SHA256Traits>( + c, bssl::Span(static_cast<const uint8_t *>(data), len)); return bcm_infallible::approved; } @@ -75,8 +87,7 @@ } static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) { - crypto_md32_final(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK, - &c->num, c->Nh, c->Nl, /*is_big_endian=*/1); + bssl::crypto_md32_final<SHA256Traits>(c); BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
diff --git a/crypto/hrss/hrss.cc b/crypto/hrss/hrss.cc index e035ff5..81807c2 100644 --- a/crypto/hrss/hrss.cc +++ b/crypto/hrss/hrss.cc
@@ -275,7 +275,7 @@ #endif // (ARM || AARCH64) && NEON // Polynomials in this scheme have N terms. -// #define N 701 +#define N HRSS_N // Underlying data types and arithmetic operations. // ------------------------------------------------
diff --git a/crypto/hrss/hrss_test.cc b/crypto/hrss/hrss_test.cc index d921dc2..fd67e45 100644 --- a/crypto/hrss/hrss_test.cc +++ b/crypto/hrss/hrss_test.cc
@@ -50,7 +50,7 @@ p.s.v[0] = 0; p.a.v[0] = 1; - for (size_t i = 0; i < N - 1; i++) { + for (size_t i = 0; i < HRSS_N - 1; i++) { SCOPED_TRACE(i); poly3 r; OPENSSL_memset(&r, 0, sizeof(r)); @@ -485,9 +485,9 @@ return; } - alignas(16) uint16_t r[N + 3]; - alignas(16) uint16_t a[N + 3] = {0}; - alignas(16) uint16_t b[N + 3] = {0}; + alignas(16) uint16_t r[HRSS_N + 3]; + alignas(16) uint16_t a[HRSS_N + 3] = {0}; + alignas(16) uint16_t b[HRSS_N + 3] = {0}; uint8_t kCanary[256]; static_assert(sizeof(kCanary) % 32 == 0, "needed for alignment");
diff --git a/crypto/hrss/internal.h b/crypto/hrss/internal.h index ab7ebc8..753a491 100644 --- a/crypto/hrss/internal.h +++ b/crypto/hrss/internal.h
@@ -23,10 +23,10 @@ #endif -#define N 701 +#define HRSS_N 701 #define BITS_PER_WORD (sizeof(crypto_word_t) * 8) -#define WORDS_PER_POLY ((N + BITS_PER_WORD - 1) / BITS_PER_WORD) -#define BITS_IN_LAST_WORD (N % BITS_PER_WORD) +#define WORDS_PER_POLY ((HRSS_N + BITS_PER_WORD - 1) / BITS_PER_WORD) +#define BITS_IN_LAST_WORD (HRSS_N % BITS_PER_WORD) struct poly2 { crypto_word_t v[WORDS_PER_POLY]; @@ -54,7 +54,8 @@ // poly_Rq_mul is defined in assembly. Inputs and outputs must be 16-byte- // aligned. extern void poly_Rq_mul( - uint16_t r[N + 3], const uint16_t a[N + 3], const uint16_t b[N + 3], + uint16_t r[HRSS_N + 3], const uint16_t a[HRSS_N + 3], + const uint16_t b[HRSS_N + 3], // The following should be `scratch[POLY_MUL_RQ_SCRATCH_SPACE]` but // GCC 11.1 has a bug with unions that breaks that. uint8_t scratch[]);
diff --git a/crypto/md4/md4.cc b/crypto/md4/md4.cc index ae6dea8..10a8130 100644 --- a/crypto/md4/md4.cc +++ b/crypto/md4/md4.cc
@@ -17,6 +17,8 @@ #include <stdlib.h> #include <string.h> +#include <openssl/span.h> + #include "../fipsmodule/digest/md32_common.h" #include "../internal.h" @@ -48,17 +50,26 @@ md4_block_data_order(c->h, data, 1); } +namespace { +struct MD4Traits { + using HashContext = MD4_CTX; + static constexpr size_t kBlockSize = MD4_CBLOCK; + static constexpr bool kLengthIsBigEndian = false; + static void HashBlocks(uint32_t *state, const uint8_t *data, + size_t num_blocks) { + md4_block_data_order(state, data, num_blocks); + } +}; +} // namespace + int MD4_Update(MD4_CTX *c, const void *data, size_t len) { - crypto_md32_update(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num, - &c->Nh, &c->Nl, reinterpret_cast<const uint8_t *>(data), - len); + bssl::crypto_md32_update<MD4Traits>( + c, bssl::Span(static_cast<const uint8_t *>(data), len)); return 1; } int MD4_Final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *c) { - crypto_md32_final(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num, - c->Nh, c->Nl, /*is_big_endian=*/0); - + bssl::crypto_md32_final<MD4Traits>(c); CRYPTO_store_u32_le(out, c->h[0]); CRYPTO_store_u32_le(out + 4, c->h[1]); CRYPTO_store_u32_le(out + 8, c->h[2]);
diff --git a/crypto/md5/md5.cc b/crypto/md5/md5.cc index 89444e9..3bd2a2b 100644 --- a/crypto/md5/md5.cc +++ b/crypto/md5/md5.cc
@@ -17,6 +17,7 @@ #include <string.h> #include <openssl/mem.h> +#include <openssl/span.h> #include "../fipsmodule/digest/md32_common.h" #include "../internal.h" @@ -52,17 +53,26 @@ md5_block_data_order(c->h, data, 1); } +namespace { +struct MD5Traits { + using HashContext = MD5_CTX; + static constexpr size_t kBlockSize = MD5_CBLOCK; + static constexpr bool kLengthIsBigEndian = false; + static void HashBlocks(uint32_t *state, const uint8_t *data, + size_t num_blocks) { + md5_block_data_order(state, data, num_blocks); + } +}; +} // namespace + int MD5_Update(MD5_CTX *c, const void *data, size_t len) { - crypto_md32_update(&md5_block_data_order, c->h, c->data, MD5_CBLOCK, &c->num, - &c->Nh, &c->Nl, reinterpret_cast<const uint8_t *>(data), - len); + bssl::crypto_md32_update<MD5Traits>( + c, bssl::Span(static_cast<const uint8_t *>(data), len)); return 1; } int MD5_Final(uint8_t out[MD5_DIGEST_LENGTH], MD5_CTX *c) { - crypto_md32_final(&md5_block_data_order, c->h, c->data, MD5_CBLOCK, &c->num, - c->Nh, c->Nl, /*is_big_endian=*/0); - + bssl::crypto_md32_final<MD5Traits>(c); CRYPTO_store_u32_le(out, c->h[0]); CRYPTO_store_u32_le(out + 4, c->h[1]); CRYPTO_store_u32_le(out + 8, c->h[2]);
diff --git a/crypto/mem_test.cc b/crypto/mem_test.cc index 70b283c..96fbc68 100644 --- a/crypto/mem_test.cc +++ b/crypto/mem_test.cc
@@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <openssl/mem.h> + +#include <memory> +#include <utility> +#include <vector> + #include <gtest/gtest.h> #include "mem_internal.h"
diff --git a/crypto/pem/pem_lib.cc b/crypto/pem/pem_lib.cc index 7679aa0..e7c4e0b 100644 --- a/crypto/pem/pem_lib.cc +++ b/crypto/pem/pem_lib.cc
@@ -21,6 +21,7 @@ #include <openssl/base64.h> #include <openssl/buf.h> +#include <openssl/cipher.h> #include <openssl/des.h> #include <openssl/err.h> #include <openssl/evp.h>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index aa96a28..6159d40 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc
@@ -33,6 +33,7 @@ #include <openssl/nid.h> #include <openssl/pem.h> #include <openssl/pool.h> +#include <openssl/span.h> #include <openssl/x509.h> #include "../internal.h"
diff --git a/crypto/x509/x_x509.cc b/crypto/x509/x_x509.cc index 485231f..01b3569 100644 --- a/crypto/x509/x_x509.cc +++ b/crypto/x509/x_x509.cc
@@ -16,6 +16,7 @@ #include <limits.h> #include <stdio.h> +#include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/bytestring.h> #include <openssl/evp.h>
diff --git a/decrepit/ripemd/ripemd.cc b/decrepit/ripemd/ripemd.cc index 716a14e..dbbb2b3 100644 --- a/decrepit/ripemd/ripemd.cc +++ b/decrepit/ripemd/ripemd.cc
@@ -44,18 +44,26 @@ ripemd160_block_data_order(c->h, data, 1); } +namespace { +struct RIPEMD160Traits { + using HashContext = RIPEMD160_CTX; + static constexpr size_t kBlockSize = RIPEMD160_CBLOCK; + static constexpr bool kLengthIsBigEndian = false; + static void HashBlocks(uint32_t *state, const uint8_t *data, + size_t num_blocks) { + ripemd160_block_data_order(state, data, num_blocks); + } +}; +} // namespace + int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len) { - crypto_md32_update(&ripemd160_block_data_order, c->h, c->data, - RIPEMD160_CBLOCK, &c->num, &c->Nh, &c->Nl, - reinterpret_cast<const uint8_t *>(data), len); + bssl::crypto_md32_update<RIPEMD160Traits>( + c, bssl::Span(static_cast<const uint8_t *>(data), len)); return 1; } int RIPEMD160_Final(uint8_t out[RIPEMD160_DIGEST_LENGTH], RIPEMD160_CTX *c) { - crypto_md32_final(&ripemd160_block_data_order, c->h, c->data, - RIPEMD160_CBLOCK, &c->num, c->Nh, c->Nl, - /*is_big_endian=*/0); - + bssl::crypto_md32_final<RIPEMD160Traits>(c); CRYPTO_store_u32_le(out, c->h[0]); CRYPTO_store_u32_le(out + 4, c->h[1]); CRYPTO_store_u32_le(out + 8, c->h[2]);
diff --git a/pki/test_helpers.cc b/pki/test_helpers.cc index 123aacb..3237614 100644 --- a/pki/test_helpers.cc +++ b/pki/test_helpers.cc
@@ -31,6 +31,7 @@ #include "../crypto/test/test_data.h" #include "cert_error_params.h" #include "cert_errors.h" +#include "parse_values.h" #include "parser.h" #include "pem.h" #include "simple_path_builder_delegate.h"
diff --git a/ssl/handshake.cc b/ssl/handshake.cc index cd6a25d..1b1a9b5 100644 --- a/ssl/handshake.cc +++ b/ssl/handshake.cc
@@ -17,6 +17,7 @@ #include <assert.h> +#include <algorithm> #include <utility> #include <openssl/rand.h>
diff --git a/ssl/test/packeted_bio.cc b/ssl/test/packeted_bio.cc index dfd8c91..b30699b 100644 --- a/ssl/test/packeted_bio.cc +++ b/ssl/test/packeted_bio.cc
@@ -24,6 +24,7 @@ #include <utility> #include <vector> +#include <openssl/bio.h> #include <openssl/mem.h> #include "../../crypto/internal.h"
diff --git a/util/fipstools/delocate/delocate.go b/util/fipstools/delocate/delocate.go index 0252781..ec1cd14 100644 --- a/util/fipstools/delocate/delocate.go +++ b/util/fipstools/delocate/delocate.go
@@ -627,8 +627,10 @@ } return statement, nil } else if parts.pegRule == ruleLow12BitsSymbolRef { - if instructionName != "ldr" { - panic("Symbol reference outside of ldr instruction") + switch instructionName { + case "ldr", "ldrh", "ldrb", "ldrsw", "ldrsh", "ldrsb": + default: + panic("Symbol reference outside of load instruction") } // Suppress the offset; adrp loaded the full address. This assumes the
diff --git a/util/fipstools/delocate/testdata/aarch64-Basic/in.s b/util/fipstools/delocate/testdata/aarch64-Basic/in.s index a2334f0..8aebf05 100644 --- a/util/fipstools/delocate/testdata/aarch64-Basic/in.s +++ b/util/fipstools/delocate/testdata/aarch64-Basic/in.s
@@ -28,10 +28,24 @@ // Load from local symbol adrp x10, .Llocal_data2 ldr q0, [x10, :lo12:.Llocal_data2] + ldr x0, [x10, :lo12:.Llocal_data2] + ldr w0, [x10, :lo12:.Llocal_data2] + ldrh w0, [x10, :lo12:.Llocal_data2] + ldrb w0, [x10, :lo12:.Llocal_data2] + ldrsw x0, [x10, :lo12:.Llocal_data2] + ldrsh w0, [x10, :lo12:.Llocal_data2] + ldrsb w0, [x10, :lo12:.Llocal_data2] // Load from local symbol with offset adrp x10, .Llocal_data2+16 ldr q0, [x10, :lo12:.Llocal_data2+16] + ldr x0, [x10, :lo12:.Llocal_data2+16] + ldr w0, [x10, :lo12:.Llocal_data2+16] + ldrh w0, [x10, :lo12:.Llocal_data2+16] + ldrb w0, [x10, :lo12:.Llocal_data2+16] + ldrsw x0, [x10, :lo12:.Llocal_data2+16] + ldrsh w0, [x10, :lo12:.Llocal_data2+16] + ldrsb w0, [x10, :lo12:.Llocal_data2+16] bl local_function
diff --git a/util/fipstools/delocate/testdata/aarch64-Basic/out.s b/util/fipstools/delocate/testdata/aarch64-Basic/out.s index 9ff57b5..9c5614b 100644 --- a/util/fipstools/delocate/testdata/aarch64-Basic/out.s +++ b/util/fipstools/delocate/testdata/aarch64-Basic/out.s
@@ -58,12 +58,40 @@ adr x10, .Llocal_data2 // WAS ldr q0, [x10, :lo12:.Llocal_data2] ldr q0, [x10] +// WAS ldr x0, [x10, :lo12:.Llocal_data2] + ldr x0, [x10] +// WAS ldr w0, [x10, :lo12:.Llocal_data2] + ldr w0, [x10] +// WAS ldrh w0, [x10, :lo12:.Llocal_data2] + ldrh w0, [x10] +// WAS ldrb w0, [x10, :lo12:.Llocal_data2] + ldrb w0, [x10] +// WAS ldrsw x0, [x10, :lo12:.Llocal_data2] + ldrsw x0, [x10] +// WAS ldrsh w0, [x10, :lo12:.Llocal_data2] + ldrsh w0, [x10] +// WAS ldrsb w0, [x10, :lo12:.Llocal_data2] + ldrsb w0, [x10] // Load from local symbol with offset // WAS adrp x10, .Llocal_data2+16 adr x10, .Llocal_data2+16 // WAS ldr q0, [x10, :lo12:.Llocal_data2+16] ldr q0, [x10] +// WAS ldr x0, [x10, :lo12:.Llocal_data2+16] + ldr x0, [x10] +// WAS ldr w0, [x10, :lo12:.Llocal_data2+16] + ldr w0, [x10] +// WAS ldrh w0, [x10, :lo12:.Llocal_data2+16] + ldrh w0, [x10] +// WAS ldrb w0, [x10, :lo12:.Llocal_data2+16] + ldrb w0, [x10] +// WAS ldrsw x0, [x10, :lo12:.Llocal_data2+16] + ldrsw x0, [x10] +// WAS ldrsh w0, [x10, :lo12:.Llocal_data2+16] + ldrsh w0, [x10] +// WAS ldrsb w0, [x10, :lo12:.Llocal_data2+16] + ldrsb w0, [x10] // WAS bl local_function bl .Llocal_function_local_target