diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index 78d1f09e9..27845c0be 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -122,14 +122,17 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { // |ASN1_INTEGER|s should be represented minimally, but it is possible to // construct invalid ones. Skip leading zeros so this does not produce an // invalid encoding or break invariants. - int start = 0; - while (start < in->length && in->data[start] == 0) { - start++; + CBS cbs; + CBS_init(&cbs, in->data, in->length); + while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) { + CBS_skip(&cbs, 1); } int is_negative = (in->type & V_ASN1_NEG) != 0; - int pad; - if (start >= in->length) { + size_t pad; + CBS copy = cbs; + uint8_t msb; + if (!CBS_get_u8(©, &msb)) { // Zero is represented as a single byte. is_negative = 0; pad = 1; @@ -138,20 +141,19 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { // through 0x00...01 and need an extra byte to be negative. // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff // through 0x80...00 and can be negated as-is. - pad = in->data[start] > 0x80 || - (in->data[start] == 0x80 && - !is_all_zeros(in->data + start + 1, in->length - start - 1)); + pad = msb > 0x80 || + (msb == 0x80 && !is_all_zeros(CBS_data(©), CBS_len(©))); } else { // If the high bit is set, the signed representation needs an extra // byte to be positive. - pad = (in->data[start] & 0x80) != 0; + pad = (msb & 0x80) != 0; } - if (in->length - start > INT_MAX - pad) { + if (CBS_len(&cbs) > INT_MAX - pad) { OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); return 0; } - int len = pad + in->length - start; + int len = (int)(pad + CBS_len(&cbs)); assert(len > 0); if (outp == NULL) { return len; @@ -160,7 +162,7 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { if (pad) { (*outp)[0] = 0; } - OPENSSL_memcpy(*outp + pad, in->data + start, in->length - start); + OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs)); if (is_negative) { negate_twos_complement(*outp, len); assert((*outp)[0] >= 0x80); diff --git a/crypto/blake2/blake2.c b/crypto/blake2/blake2.c index 5c6b17edf..848ed4fa2 100644 --- a/crypto/blake2/blake2.c +++ b/crypto/blake2/blake2.c @@ -105,8 +105,12 @@ void BLAKE2B256_Init(BLAKE2B_CTX *b2b) { } void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) { - const uint8_t *data = (const uint8_t *)in_data; + if (len == 0) { + // Work around a C language bug. See https://crbug.com/1019588. + return; + } + const uint8_t *data = in_data; size_t todo = sizeof(b2b->block.bytes) - b2b->block_used; if (todo > len) { todo = len;