Also add OPENSSL_calloc

This is not in upstream OpenSSL but saves a bunch of manual overflow
checks. Note it does also introduce some zeroing of buffers, but I think
this should be fine here.

Change-Id: I0c3e65ce2d21ee9d206ccbe3075ce5291c3acb30
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63365
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
chromium-stable
David Benjamin 1 year ago committed by Boringssl LUCI CQ
parent dd68e4bb4d
commit 216db679a7
  1. 7
      crypto/asn1/tasn_enc.c
  2. 5
      crypto/bytestring/cbb.c
  3. 2
      crypto/evp/scrypt.c
  4. 2
      crypto/fipsmodule/bn/bn.c
  5. 9
      crypto/fipsmodule/ec/wnaf.c
  6. 2
      crypto/fipsmodule/rsa/rsa_impl.c
  7. 2
      crypto/lhash/lhash.c
  8. 9
      crypto/mem.c
  9. 2
      crypto/stack/stack.c
  10. 32
      crypto/trust_token/pmbtoken.c
  11. 48
      crypto/trust_token/voprf.c
  12. 15
      include/openssl/mem.h

@ -452,14 +452,9 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
return 1;
}
if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
return 0;
}
int ret = 0;
unsigned char *const buf = OPENSSL_malloc(skcontlen);
DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded));
DER_ENC *encoded = OPENSSL_calloc(sk_ASN1_VALUE_num(sk), sizeof(*encoded));
if (encoded == NULL || buf == NULL) {
goto err;
}

@ -649,16 +649,13 @@ int CBB_flush_asn1_set_of(CBB *cbb) {
if (num_children < 2) {
return 1; // Nothing to do. This is the common case for X.509.
}
if (num_children > ((size_t)-1) / sizeof(CBS)) {
return 0; // Overflow.
}
// Parse out the children and sort. We alias them into a copy of so they
// remain valid as we rewrite |cbb|.
int ret = 0;
size_t buf_len = CBB_len(cbb);
uint8_t *buf = OPENSSL_memdup(CBB_data(cbb), buf_len);
CBS *children = OPENSSL_malloc(num_children * sizeof(CBS));
CBS *children = OPENSSL_calloc(num_children, sizeof(CBS));
if (buf == NULL || children == NULL) {
goto err;
}

@ -175,7 +175,7 @@ int EVP_PBE_scrypt(const char *password, size_t password_len,
size_t B_bytes = B_blocks * sizeof(block_t);
size_t T_blocks = 2 * r;
size_t V_blocks = N * 2 * r;
block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t));
block_t *B = OPENSSL_calloc(B_blocks + T_blocks + V_blocks, sizeof(block_t));
if (B == NULL) {
return 0;
}

@ -361,7 +361,7 @@ int bn_wexpand(BIGNUM *bn, size_t words) {
return 0;
}
a = OPENSSL_malloc(sizeof(BN_ULONG) * words);
a = OPENSSL_calloc(words, sizeof(BN_ULONG));
if (a == NULL) {
return 0;
}

@ -197,13 +197,8 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
wNAF = wNAF_stack;
precomp = precomp_stack;
} else {
if (num >= ((size_t)-1) / sizeof(wNAF_alloc[0]) ||
num >= ((size_t)-1) / sizeof(precomp_alloc[0])) {
OPENSSL_PUT_ERROR(EC, ERR_R_OVERFLOW);
goto err;
}
wNAF_alloc = OPENSSL_malloc(num * sizeof(wNAF_alloc[0]));
precomp_alloc = OPENSSL_malloc(num * sizeof(precomp_alloc[0]));
wNAF_alloc = OPENSSL_calloc(num, sizeof(wNAF_alloc[0]));
precomp_alloc = OPENSSL_calloc(num, sizeof(precomp_alloc[0]));
if (wNAF_alloc == NULL || precomp_alloc == NULL) {
goto err;
}

@ -376,7 +376,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, size_t *index_used,
assert(new_num_blindings > rsa->num_blindings);
BN_BLINDING **new_blindings =
OPENSSL_malloc(sizeof(BN_BLINDING *) * new_num_blindings);
OPENSSL_calloc(new_num_blindings, sizeof(BN_BLINDING *));
uint8_t *new_blindings_inuse = OPENSSL_malloc(new_num_blindings);
if (new_blindings == NULL || new_blindings_inuse == NULL) {
goto err;

@ -110,7 +110,7 @@ _LHASH *OPENSSL_lh_new(lhash_hash_func hash, lhash_cmp_func comp) {
}
ret->num_buckets = kMinNumBuckets;
ret->buckets = OPENSSL_zalloc(sizeof(LHASH_ITEM *) * ret->num_buckets);
ret->buckets = OPENSSL_calloc(ret->num_buckets, sizeof(LHASH_ITEM *));
if (ret->buckets == NULL) {
OPENSSL_free(ret);
return NULL;

@ -275,6 +275,15 @@ void *OPENSSL_zalloc(size_t size) {
return ret;
}
void *OPENSSL_calloc(size_t num, size_t size) {
if (size != 0 && num > SIZE_MAX / size) {
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
return NULL;
}
return OPENSSL_zalloc(num * size);
}
void OPENSSL_free(void *orig_ptr) {
if (orig_ptr == NULL) {
return;

@ -89,7 +89,7 @@ OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) {
return NULL;
}
ret->data = OPENSSL_zalloc(sizeof(void *) * kMinSize);
ret->data = OPENSSL_calloc(kMinSize, sizeof(void *));
if (ret->data == NULL) {
goto err;
}

@ -799,18 +799,12 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
return 0;
}
if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return 0;
}
int ret = 0;
EC_JACOBIAN *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
EC_JACOBIAN *Tps = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Sps = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wps = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wsps = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR));
CBB batch_cbb;
CBB_zero(&batch_cbb);
if (!Tps ||
@ -940,19 +934,13 @@ static STACK_OF(TRUST_TOKEN) *pmbtoken_unblind(
return NULL;
}
if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
count > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return NULL;
}
int ok = 0;
STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
EC_JACOBIAN *Tps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Sps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wsps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR));
EC_JACOBIAN *Tps = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Sps = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wps = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Wsps = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_calloc(count, sizeof(EC_SCALAR));
CBB batch_cbb;
CBB_zero(&batch_cbb);
if (ret == NULL ||

@ -483,16 +483,10 @@ static int voprf_sign_tt(const VOPRF_METHOD *method,
return 0;
}
if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return 0;
}
int ret = 0;
EC_JACOBIAN *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
EC_JACOBIAN *BTs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR));
CBB batch_cbb;
CBB_zero(&batch_cbb);
if (!BTs ||
@ -582,17 +576,11 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
return NULL;
}
if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
count > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return NULL;
}
int ok = 0;
STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
EC_JACOBIAN *BTs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR));
EC_JACOBIAN *BTs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_SCALAR *es = OPENSSL_calloc(count, sizeof(EC_SCALAR));
CBB batch_cbb;
CBB_zero(&batch_cbb);
if (ret == NULL ||
@ -868,16 +856,10 @@ static int voprf_sign_impl(const VOPRF_METHOD *method,
return 0;
}
if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return 0;
}
int ret = 0;
EC_JACOBIAN *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN));
EC_SCALAR *dis = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
EC_JACOBIAN *BTs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_calloc(num_to_issue, sizeof(EC_JACOBIAN));
EC_SCALAR *dis = OPENSSL_calloc(num_to_issue, sizeof(EC_SCALAR));
if (!BTs || !Zs || !dis) {
goto err;
}
@ -984,17 +966,11 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind(
return NULL;
}
if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) ||
count > ((size_t)-1) / sizeof(EC_SCALAR)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
return NULL;
}
int ok = 0;
STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
EC_JACOBIAN *BTs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN));
EC_SCALAR *dis = OPENSSL_malloc(count * sizeof(EC_SCALAR));
EC_JACOBIAN *BTs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_JACOBIAN *Zs = OPENSSL_calloc(count, sizeof(EC_JACOBIAN));
EC_SCALAR *dis = OPENSSL_calloc(count, sizeof(EC_SCALAR));
if (ret == NULL || !BTs || !Zs || !dis) {
goto err;
}

@ -85,14 +85,12 @@ OPENSSL_EXPORT void *OPENSSL_malloc(size_t size);
// OPENSSL_zalloc behaves like |OPENSSL_malloc| except it also initializes the
// resulting memory to zero.
OPENSSL_EXPORT void *OPENSSL_zalloc(size_t size);
#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC
// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the
// memory allocated at |ptr| and frees it along with the private data.
// It must only be used on on |ptr| values obtained from |OPENSSL_malloc|
OPENSSL_EXPORT void OPENSSL_free(void *ptr);
// OPENSSL_calloc is similar to a regular |calloc|, but allocates data with
// |OPENSSL_malloc|. On overflow, it will push |ERR_R_OVERFLOW| onto the error
// queue.
OPENSSL_EXPORT void *OPENSSL_calloc(size_t num, size_t size);
#ifndef _BORINGSSL_PROHIBIT_OPENSSL_MALLOC
// OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that
// contains the contents of |ptr|. Unlike |realloc|, a new buffer is always
// allocated and the data at |ptr| is always wiped and freed. Memory is
@ -100,6 +98,11 @@ OPENSSL_EXPORT void OPENSSL_free(void *ptr);
OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size);
#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC
// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the
// memory allocated at |ptr| and frees it along with the private data.
// It must only be used on on |ptr| values obtained from |OPENSSL_malloc|
OPENSSL_EXPORT void OPENSSL_free(void *ptr);
// OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to
// |memset_s| from C11.
OPENSSL_EXPORT void OPENSSL_cleanse(void *ptr, size_t len);

Loading…
Cancel
Save