diff options
author | Robert Sloan <varomodt@google.com> | 2017-04-03 09:16:40 -0700 |
---|---|---|
committer | Robert Sloan <varomodt@google.com> | 2017-04-03 10:01:30 -0700 |
commit | 6f79a50fbad5817b8fc7a07c5657d8249c57a0f7 (patch) | |
tree | 1dd4855cacce1b01341ed8b8e1557bedf0c2aa0b /src/crypto | |
parent | 6d0d00e090b753250659b9a2d67dab7467257900 (diff) | |
download | boringssl-6f79a50fbad5817b8fc7a07c5657d8249c57a0f7.tar.gz |
external/boringssl: Sync to faa539f877432814d0f2de19846eb99f2ea1e207.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/bbfe603519bc54fbc4c8dd87efe1ed385df550b4..faa539f877432814d0f2de19846eb99f2ea1e207
Test: BoringSSL CTS Presubmits
Change-Id: I3ea66c6a16d30b31f9a51e8154fa581a7d386918
Diffstat (limited to 'src/crypto')
26 files changed, 343 insertions, 396 deletions
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl index d645de4c..92f5ecef 100644 --- a/src/crypto/aes/asm/bsaes-armv7.pl +++ b/src/crypto/aes/asm/bsaes-armv7.pl @@ -1,4 +1,11 @@ -#!/usr/bin/env perl +#! /usr/bin/env perl +# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + # ==================================================================== # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL @@ -731,6 +738,7 @@ $code.=<<___; .thumb #else .code 32 +# undef __thumb2__ #endif .type _bsaes_decrypt8,%function @@ -1357,7 +1365,7 @@ bsaes_cbc_encrypt: vmov @XMM[4],@XMM[15] @ just in case ensure that IV vmov @XMM[5],@XMM[0] @ and input are preserved bl AES_decrypt - vld1.8 {@XMM[0]}, [$fp,:64] @ load result + vld1.8 {@XMM[0]}, [$fp] @ load result veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV vmov @XMM[15], @XMM[5] @ @XMM[5] holds input vst1.8 {@XMM[0]}, [$rounds] @ write output diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c index 7d9bbeea..41b74701 100644 --- a/src/crypto/cipher/e_tls.c +++ b/src/crypto/cipher/e_tls.c @@ -262,24 +262,24 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, /* Remove CBC padding. Code from here on is timing-sensitive with respect to * |padding_ok| and |data_plus_mac_len| for CBC ciphers. */ - unsigned padding_ok, data_plus_mac_len; + size_t padding_ok, data_plus_mac_len; if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { if (!EVP_tls_cbc_remove_padding( &padding_ok, &data_plus_mac_len, out, total, EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), - (unsigned)HMAC_size(&tls_ctx->hmac_ctx))) { + HMAC_size(&tls_ctx->hmac_ctx))) { /* Publicly invalid. This can be rejected in non-constant time. */ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } } else { - padding_ok = ~0u; + padding_ok = CONSTTIME_TRUE_S; data_plus_mac_len = total; /* |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has * already been checked against the MAC size at the top of the function. */ assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); } - unsigned data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); /* At this point, if the padding is valid, the first |data_plus_mac_len| bytes * after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is @@ -332,8 +332,8 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, * safe to simply perform the padding check first, but it would not be under a * different choice of MAC location on padding failure. See * EVP_tls_cbc_remove_padding. */ - unsigned good = constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), - 0); + size_t good = + constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0); good &= padding_ok; if (!good) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); diff --git a/src/crypto/cipher/internal.h b/src/crypto/cipher/internal.h index d29ce599..b9f88f27 100644 --- a/src/crypto/cipher/internal.h +++ b/src/crypto/cipher/internal.h @@ -110,9 +110,9 @@ struct evp_aead_st { * If the function returns one, it runs in time independent of the contents of * |in|. It is also guaranteed that |*out_len| >= |mac_size|, satisfying * |EVP_tls_cbc_copy_mac|'s precondition. */ -int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size); +int EVP_tls_cbc_remove_padding(size_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size); /* EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first * |in_len| bytes of |in| to |out| in constant time (independent of the concrete @@ -122,9 +122,8 @@ int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, * On entry: * orig_len >= in_len >= md_size * md_size <= EVP_MAX_MD_SIZE */ -void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, - const uint8_t *in, unsigned in_len, - unsigned orig_len); +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len); /* EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function * which EVP_tls_cbc_digest_record supports. */ diff --git a/src/crypto/cipher/tls_cbc.c b/src/crypto/cipher/tls_cbc.c index 52880b0c..a825c1ce 100644 --- a/src/crypto/cipher/tls_cbc.c +++ b/src/crypto/cipher/tls_cbc.c @@ -73,20 +73,19 @@ * supported by TLS.) */ #define MAX_HASH_BLOCK_SIZE 128 -int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size) { - unsigned padding_length, good, to_check, i; - const unsigned overhead = 1 /* padding length byte */ + mac_size; +int EVP_tls_cbc_remove_padding(size_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size) { + const size_t overhead = 1 /* padding length byte */ + mac_size; /* These lengths are all public so we can test them in non-constant time. */ if (overhead > in_len) { return 0; } - padding_length = in[in_len - 1]; + size_t padding_length = in[in_len - 1]; - good = constant_time_ge(in_len, overhead + padding_length); + size_t good = constant_time_ge_s(in_len, overhead + padding_length); /* The padding consists of a length byte at the end of the record and * then that many bytes of padding, all with the same value as the * length byte. Thus, with the length byte included, there are i+1 @@ -96,12 +95,12 @@ int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, * decrypted information. Therefore we always have to check the maximum * amount of padding possible. (Again, the length of the record is * public information so we can use it.) */ - to_check = 256; /* maximum amount of padding, inc length byte. */ + size_t to_check = 256; /* maximum amount of padding, inc length byte. */ if (to_check > in_len) { to_check = in_len; } - for (i = 0; i < to_check; i++) { + for (size_t i = 0; i < to_check; i++) { uint8_t mask = constant_time_ge_8(padding_length, i); uint8_t b = in[in_len - 1 - i]; /* The final |padding_length+1| bytes should all have the value @@ -111,7 +110,7 @@ int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, /* If any of the final |padding_length+1| bytes had the wrong value, * one or more of the lower eight bits of |good| will be cleared. */ - good = constant_time_eq(0xff, good & 0xff); + good = constant_time_eq_s(0xff, good & 0xff); /* Always treat |padding_length| as zero on error. If, assuming block size of * 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16 @@ -123,16 +122,15 @@ int EVP_tls_cbc_remove_padding(unsigned *out_padding_ok, unsigned *out_len, return 1; } -void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, - const uint8_t *in, unsigned in_len, - unsigned orig_len) { +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len) { uint8_t rotated_mac1[EVP_MAX_MD_SIZE], rotated_mac2[EVP_MAX_MD_SIZE]; uint8_t *rotated_mac = rotated_mac1; uint8_t *rotated_mac_tmp = rotated_mac2; /* mac_end is the index of |in| just after the end of the MAC. */ - unsigned mac_end = in_len; - unsigned mac_start = mac_end - md_size; + size_t mac_end = in_len; + size_t mac_start = mac_end - md_size; assert(orig_len >= in_len); assert(in_len >= md_size); @@ -140,20 +138,20 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, /* scan_start contains the number of bytes that we can ignore because * the MAC's position can only vary by 255 bytes. */ - unsigned scan_start = 0; + size_t scan_start = 0; /* This information is public so it's safe to branch based on it. */ if (orig_len > md_size + 255 + 1) { scan_start = orig_len - (md_size + 255 + 1); } - unsigned rotate_offset = 0; + size_t rotate_offset = 0; uint8_t mac_started = 0; OPENSSL_memset(rotated_mac, 0, md_size); - for (unsigned i = scan_start, j = 0; i < orig_len; i++, j++) { + for (size_t i = scan_start, j = 0; i < orig_len; i++, j++) { if (j >= md_size) { j -= md_size; } - unsigned is_mac_start = constant_time_eq(i, mac_start); + size_t is_mac_start = constant_time_eq_s(i, mac_start); mac_started |= is_mac_start; uint8_t mac_ended = constant_time_ge_8(i, mac_end); rotated_mac[j] |= in[i] & mac_started & ~mac_ended; @@ -163,12 +161,11 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, /* Now rotate the MAC. We rotate in log(md_size) steps, one for each bit * position. */ - for (unsigned offset = 1; offset < md_size; - offset <<= 1, rotate_offset >>= 1) { + for (size_t offset = 1; offset < md_size; offset <<= 1, rotate_offset >>= 1) { /* Rotate by |offset| iff the corresponding bit is set in * |rotate_offset|, placing the result in |rotated_mac_tmp|. */ const uint8_t skip_rotate = (rotate_offset & 1) - 1; - for (unsigned i = 0, j = offset; i < md_size; i++, j++) { + for (size_t i = 0, j = offset; i < md_size; i++, j++) { if (j >= md_size) { j -= md_size; } @@ -211,40 +208,49 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, *((p)++) = (uint8_t)((n)); \ } while (0) +typedef union { + SHA_CTX sha1; + SHA256_CTX sha256; + SHA512_CTX sha512; +} HASH_CTX; + +static void tls1_sha1_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA1_Transform(&ctx->sha1, block); +} + +static void tls1_sha256_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA256_Transform(&ctx->sha256, block); +} + +static void tls1_sha512_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA512_Transform(&ctx->sha512, block); +} + /* These functions serialize the state of a hash and thus perform the standard * "final" operation without adding the padding and length that such a function * typically does. */ -static void tls1_sha1_final_raw(void *ctx, uint8_t *md_out) { - SHA_CTX *sha1 = ctx; +static void tls1_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA_CTX *sha1 = &ctx->sha1; u32toBE(sha1->h[0], md_out); u32toBE(sha1->h[1], md_out); u32toBE(sha1->h[2], md_out); u32toBE(sha1->h[3], md_out); u32toBE(sha1->h[4], md_out); } -#define LARGEST_DIGEST_CTX SHA_CTX -static void tls1_sha256_final_raw(void *ctx, uint8_t *md_out) { - SHA256_CTX *sha256 = ctx; - unsigned i; - - for (i = 0; i < 8; i++) { +static void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA256_CTX *sha256 = &ctx->sha256; + for (unsigned i = 0; i < 8; i++) { u32toBE(sha256->h[i], md_out); } } -#undef LARGEST_DIGEST_CTX -#define LARGEST_DIGEST_CTX SHA256_CTX - -static void tls1_sha512_final_raw(void *ctx, uint8_t *md_out) { - SHA512_CTX *sha512 = ctx; - unsigned i; - for (i = 0; i < 8; i++) { +static void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA512_CTX *sha512 = &ctx->sha512; + for (unsigned i = 0; i < 8; i++) { u64toBE(sha512->h[i], md_out); } } -#undef LARGEST_DIGEST_CTX -#define LARGEST_DIGEST_CTX SHA512_CTX int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { switch (EVP_MD_type(md)) { @@ -264,54 +270,42 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, size_t data_plus_mac_plus_padding_size, const uint8_t *mac_secret, unsigned mac_secret_length) { - union { - double align; - uint8_t c[sizeof(LARGEST_DIGEST_CTX)]; - } md_state; - void (*md_final_raw)(void *ctx, uint8_t *md_out); - void (*md_transform)(void *ctx, const uint8_t *block); + HASH_CTX md_state; + void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out); + void (*md_transform)(HASH_CTX *ctx, const uint8_t *block); unsigned md_size, md_block_size = 64; - unsigned len, max_mac_bytes, num_blocks, num_starting_blocks, k, - mac_end_offset, c, index_a, index_b; - unsigned int bits; /* at most 18 bits */ - uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; - /* hmac_pad is the masked HMAC key. */ - uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; - uint8_t first_block[MAX_HASH_BLOCK_SIZE]; - uint8_t mac_out[EVP_MAX_MD_SIZE]; - unsigned i, j, md_out_size_u; - EVP_MD_CTX md_ctx; - /* mdLengthSize is the number of bytes in the length field that terminates - * the hash. */ + /* md_length_size is the number of bytes in the length field that terminates + * the hash. */ unsigned md_length_size = 8; - /* This is a, hopefully redundant, check that allows us to forget about - * many possible overflows later in this function. */ - assert(data_plus_mac_plus_padding_size < 1024 * 1024); + /* Bound the acceptable input so we can forget about many possible overflows + * later in this function. This is redundant with the record size limits in + * TLS. */ + if (data_plus_mac_plus_padding_size >= 1024 * 1024) { + assert(0); + return 0; + } switch (EVP_MD_type(md)) { case NID_sha1: - SHA1_Init((SHA_CTX *)md_state.c); + SHA1_Init(&md_state.sha1); md_final_raw = tls1_sha1_final_raw; - md_transform = - (void (*)(void *ctx, const uint8_t *block))SHA1_Transform; - md_size = 20; + md_transform = tls1_sha1_transform; + md_size = SHA_DIGEST_LENGTH; break; case NID_sha256: - SHA256_Init((SHA256_CTX *)md_state.c); + SHA256_Init(&md_state.sha256); md_final_raw = tls1_sha256_final_raw; - md_transform = - (void (*)(void *ctx, const uint8_t *block))SHA256_Transform; - md_size = 32; + md_transform = tls1_sha256_transform; + md_size = SHA256_DIGEST_LENGTH; break; case NID_sha384: - SHA384_Init((SHA512_CTX *)md_state.c); + SHA384_Init(&md_state.sha512); md_final_raw = tls1_sha512_final_raw; - md_transform = - (void (*)(void *ctx, const uint8_t *block))SHA512_Transform; - md_size = 384 / 8; + md_transform = tls1_sha512_transform; + md_size = SHA384_DIGEST_LENGTH; md_block_size = 128; md_length_size = 16; break; @@ -328,7 +322,7 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, assert(md_block_size <= MAX_HASH_BLOCK_SIZE); assert(md_size <= EVP_MAX_MD_SIZE); - static const unsigned kHeaderLength = 13; + static const size_t kHeaderLength = 13; /* kVarianceBlocks is the number of blocks of the hash that we have to * calculate in constant time because they could be altered by the @@ -337,16 +331,16 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not * required to be minimal. Therefore we say that the final six blocks * can vary based on the padding. */ - static const unsigned kVarianceBlocks = 6; + static const size_t kVarianceBlocks = 6; /* From now on we're dealing with the MAC, which conceptually has 13 * bytes of `header' before the start of the data. */ - len = data_plus_mac_plus_padding_size + kHeaderLength; + size_t len = data_plus_mac_plus_padding_size + kHeaderLength; /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including - * |header|, assuming that there's no padding. */ - max_mac_bytes = len - md_size - 1; + * |header|, assuming that there's no padding. */ + size_t max_mac_bytes = len - md_size - 1; /* num_blocks is the maximum number of hash blocks. */ - num_blocks = + size_t num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; /* In order to calculate the MAC in constant time we have to handle * the final blocks specially because the padding value could cause the @@ -354,43 +348,47 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, * can't leak where. However, |num_starting_blocks| worth of data can * be hashed right away because no padding value can affect whether * they are plaintext. */ - num_starting_blocks = 0; + size_t num_starting_blocks = 0; /* k is the starting byte offset into the conceptual header||data where * we start processing. */ - k = 0; + size_t k = 0; /* mac_end_offset is the index just past the end of the data to be * MACed. */ - mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; + size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; /* c is the index of the 0x80 byte in the final hash block that * contains application data. */ - c = mac_end_offset % md_block_size; + size_t c = mac_end_offset % md_block_size; /* index_a is the hash block number that contains the 0x80 terminating * value. */ - index_a = mac_end_offset / md_block_size; + size_t index_a = mac_end_offset / md_block_size; /* index_b is the hash block number that contains the 64-bit hash * length, in bits. */ - index_b = (mac_end_offset + md_length_size) / md_block_size; - /* bits is the hash-length in bits. It includes the additional hash - * block for the masked HMAC key. */ + size_t index_b = (mac_end_offset + md_length_size) / md_block_size; if (num_blocks > kVarianceBlocks) { num_starting_blocks = num_blocks - kVarianceBlocks; k = md_block_size * num_starting_blocks; } - bits = 8 * mac_end_offset; + /* bits is the hash-length in bits. It includes the additional hash + * block for the masked HMAC key. */ + size_t bits = 8 * mac_end_offset; /* at most 18 bits to represent */ /* Compute the initial HMAC block. */ bits += 8 * md_block_size; + /* hmac_pad is the masked HMAC key. */ + uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; OPENSSL_memset(hmac_pad, 0, md_block_size); assert(mac_secret_length <= sizeof(hmac_pad)); OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); - for (i = 0; i < md_block_size; i++) { + for (size_t i = 0; i < md_block_size; i++) { hmac_pad[i] ^= 0x36; } - md_transform(md_state.c, hmac_pad); + md_transform(&md_state, hmac_pad); + /* The length check means |bits| fits in four bytes. */ + uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; OPENSSL_memset(length_bytes, 0, md_length_size - 4); length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); @@ -399,27 +397,29 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, if (k > 0) { /* k is a multiple of md_block_size. */ + uint8_t first_block[MAX_HASH_BLOCK_SIZE]; OPENSSL_memcpy(first_block, header, 13); OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size; i++) { - md_transform(md_state.c, data + md_block_size * i - 13); + md_transform(&md_state, first_block); + for (size_t i = 1; i < k / md_block_size; i++) { + md_transform(&md_state, data + md_block_size * i - 13); } } + uint8_t mac_out[EVP_MAX_MD_SIZE]; OPENSSL_memset(mac_out, 0, sizeof(mac_out)); /* We now process the final hash blocks. For each block, we construct * it in constant time. If the |i==index_a| then we'll include the 0x80 * bytes and zero pad etc. For each block we selectively copy it, in * constant time, to |mac_out|. */ - for (i = num_starting_blocks; i <= num_starting_blocks + kVarianceBlocks; - i++) { + for (size_t i = num_starting_blocks; + i <= num_starting_blocks + kVarianceBlocks; i++) { uint8_t block[MAX_HASH_BLOCK_SIZE]; uint8_t is_block_a = constant_time_eq_8(i, index_a); uint8_t is_block_b = constant_time_eq_8(i, index_b); - for (j = 0; j < md_block_size; j++) { - uint8_t b = 0, is_past_c, is_past_cp1; + for (size_t j = 0; j < md_block_size; j++) { + uint8_t b = 0; if (k < kHeaderLength) { b = header[k]; } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { @@ -427,8 +427,8 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, } k++; - is_past_c = is_block_a & constant_time_ge_8(j, c); - is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); + uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c); + uint8_t is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); /* If this is the block containing the end of the * application data, and we are at the offset for the * 0x80 value, then overwrite b with 0x80. */ @@ -453,14 +453,15 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, block[j] = b; } - md_transform(md_state.c, block); - md_final_raw(md_state.c, block); + md_transform(&md_state, block); + md_final_raw(&md_state, block); /* If this is index_b, copy the hash value to |mac_out|. */ - for (j = 0; j < md_size; j++) { + for (size_t j = 0; j < md_size; j++) { mac_out[j] |= block[j] & is_block_b; } } + EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) { EVP_MD_CTX_cleanup(&md_ctx); @@ -468,12 +469,13 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, } /* Complete the HMAC in the standard manner. */ - for (i = 0; i < md_block_size; i++) { + for (size_t i = 0; i < md_block_size; i++) { hmac_pad[i] ^= 0x6a; } EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); EVP_DigestUpdate(&md_ctx, mac_out, md_size); + unsigned md_out_size_u; EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); *md_out_size = md_out_size_u; EVP_MD_CTX_cleanup(&md_ctx); diff --git a/src/crypto/constant_time_test.cc b/src/crypto/constant_time_test.cc index adfe272d..0ad7192f 100644 --- a/src/crypto/constant_time_test.cc +++ b/src/crypto/constant_time_test.cc @@ -49,62 +49,66 @@ #include <stdio.h> #include <stdlib.h> -#include <gtest/gtest.h> - +#include <limits> -static const unsigned CONSTTIME_TRUE = (unsigned)(~0); -static const unsigned CONSTTIME_FALSE = 0; -static const uint8_t CONSTTIME_TRUE_8 = 0xff; -static const uint8_t CONSTTIME_FALSE_8 = 0; +#include <gtest/gtest.h> -static unsigned FromBool(bool b) { - return b ? CONSTTIME_TRUE : CONSTTIME_FALSE; -} static uint8_t FromBool8(bool b) { return b ? CONSTTIME_TRUE_8 : CONSTTIME_FALSE_8; } -static unsigned test_values[] = { +static size_t FromBoolS(bool b) { + return b ? CONSTTIME_TRUE_S : CONSTTIME_FALSE_S; +} + +static const uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255}; + +static size_t test_values_s[] = { 0, 1, 1024, 12345, 32000, - UINT_MAX / 2 - 1, - UINT_MAX / 2, - UINT_MAX / 2 + 1, - UINT_MAX - 1, - UINT_MAX, +#if defined(OPENSSL_64_BIT) + 0xffffffff / 2 - 1, + 0xffffffff / 2, + 0xffffffff / 2 + 1, + 0xffffffff - 1, + 0xffffffff, +#endif + std::numeric_limits<size_t>::max() / 2 - 1, + std::numeric_limits<size_t>::max() / 2, + std::numeric_limits<size_t>::max() / 2 + 1, + std::numeric_limits<size_t>::max() - 1, + std::numeric_limits<size_t>::max(), }; -static uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255}; - static int signed_test_values[] = { 0, 1, -1, 1024, -1024, 12345, -12345, 32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1}; TEST(ConstantTimeTest, Test) { - for (unsigned a : test_values) { + for (size_t a : test_values_s) { SCOPED_TRACE(a); - EXPECT_EQ(FromBool(a == 0), constant_time_is_zero(a)); + EXPECT_EQ(FromBoolS(a == 0), constant_time_is_zero_s(a)); EXPECT_EQ(FromBool8(a == 0), constant_time_is_zero_8(a)); - for (unsigned b : test_values) { + for (size_t b : test_values_s) { SCOPED_TRACE(b); - EXPECT_EQ(FromBool(a < b), constant_time_lt(a, b)); + EXPECT_EQ(FromBoolS(a < b), constant_time_lt_s(a, b)); EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b)); - EXPECT_EQ(FromBool(a >= b), constant_time_ge(a, b)); + EXPECT_EQ(FromBoolS(a >= b), constant_time_ge_s(a, b)); EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b)); - EXPECT_EQ(FromBool(a == b), constant_time_eq(a, b)); + EXPECT_EQ(FromBoolS(a == b), constant_time_eq_s(a, b)); EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b)); - EXPECT_EQ(a, constant_time_select(CONSTTIME_TRUE, a, b)); - EXPECT_EQ(b, constant_time_select(CONSTTIME_FALSE, a, b)); + EXPECT_EQ(a, constant_time_select_s(CONSTTIME_TRUE_S, a, b)); + EXPECT_EQ(b, constant_time_select_s(CONSTTIME_FALSE_S, a, b)); } } @@ -113,10 +117,10 @@ TEST(ConstantTimeTest, Test) { for (int b : signed_test_values) { SCOPED_TRACE(b); - EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE, a, b)); - EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE, a, b)); + EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE_S, a, b)); + EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE_S, a, b)); - EXPECT_EQ(FromBool(a == b), constant_time_eq_int(a, b)); + EXPECT_EQ(FromBoolS(a == b), constant_time_eq_int(a, b)); EXPECT_EQ(FromBool8(a == b), constant_time_eq_int_8(a, b)); } } diff --git a/src/crypto/curve25519/ed25519_tests.txt b/src/crypto/curve25519/ed25519_tests.txt index 4d43417d..2e185a7e 100644 --- a/src/crypto/curve25519/ed25519_tests.txt +++ b/src/crypto/curve25519/ed25519_tests.txt @@ -2575,3 +2575,16 @@ PRIV: 4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742c94576641f PUB: c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357 MESSAGE: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb SIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02 + + +# Additional test vectors from RFC 8032 + +PRIV: f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e +PUB: 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e +MESSAGE: 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0 +SIG: 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03 + +PRIV: 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf +PUB: ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf +MESSAGE: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f +SIG: dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704 diff --git a/src/crypto/digest/digest_test.cc b/src/crypto/digest/digest_test.cc index 36a62ab0..15c48e0b 100644 --- a/src/crypto/digest/digest_test.cc +++ b/src/crypto/digest/digest_test.cc @@ -225,13 +225,6 @@ static int TestDigest(const TestVector *test) { if (!CompareDigest(test, digest.get(), EVP_MD_size(test->md.func()))) { return false; } - - // Test the deprecated static buffer variant, until it's removed. - out = test->md.one_shot_func((const uint8_t *)test->input, - strlen(test->input), NULL); - if (!CompareDigest(test, out, EVP_MD_size(test->md.func()))) { - return false; - } } return true; diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c index f0838797..f8fe6ce8 100644 --- a/src/crypto/evp/evp.c +++ b/src/crypto/evp/evp.c @@ -120,13 +120,6 @@ int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { return 0; } -int EVP_PKEY_supports_digest(const EVP_PKEY *pkey, const EVP_MD *md) { - if (pkey->ameth && pkey->ameth->pkey_supports_digest) { - return pkey->ameth->pkey_supports_digest(pkey, md); - } - return 1; -} - int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { if (a->type != b->type) { return -1; diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h index 0783143d..cdbd56a7 100644 --- a/src/crypto/evp/internal.h +++ b/src/crypto/evp/internal.h @@ -100,12 +100,6 @@ struct evp_pkey_asn1_method_st { * custom implementations which do not expose key material and parameters.*/ int (*pkey_opaque)(const EVP_PKEY *pk); - /* pkey_supports_digest returns one if |pkey| supports digests of - * type |md|. This is intended for use with EVP_PKEYs backing custom - * implementations which can't sign all digests. If null, it is - * assumed that all digests are supported. */ - int (*pkey_supports_digest)(const EVP_PKEY *pkey, const EVP_MD *md); - int (*pkey_size)(const EVP_PKEY *pk); int (*pkey_bits)(const EVP_PKEY *pk); diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c index d4f41328..0e5cdeec 100644 --- a/src/crypto/evp/p_dsa_asn1.c +++ b/src/crypto/evp/p_dsa_asn1.c @@ -256,7 +256,6 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { dsa_priv_encode, NULL /* pkey_opaque */, - NULL /* pkey_supports_digest */, int_dsa_size, dsa_bits, diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c index 8d44dcdc..1f1bf2fc 100644 --- a/src/crypto/evp/p_ec_asn1.c +++ b/src/crypto/evp/p_ec_asn1.c @@ -244,7 +244,6 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { eckey_priv_encode, eckey_opaque, - 0 /* pkey_supports_digest */, int_ec_size, ec_bits, diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c index ea2ba998..6b25fa2d 100644 --- a/src/crypto/evp/p_rsa.c +++ b/src/crypto/evp/p_rsa.c @@ -386,22 +386,15 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - size_t plaintext_len; - int message_len; - + size_t padded_len; if (!setup_tbuf(rctx, ctx) || - !RSA_decrypt(rsa, &plaintext_len, rctx->tbuf, key_len, in, inlen, - RSA_NO_PADDING)) { - return 0; - } - - message_len = RSA_padding_check_PKCS1_OAEP_mgf1( - out, key_len, rctx->tbuf, plaintext_len, rctx->oaep_label, - rctx->oaep_labellen, rctx->md, rctx->mgf1md); - if (message_len < 0) { + !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + RSA_NO_PADDING) || + !RSA_padding_check_PKCS1_OAEP_mgf1( + out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, + rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { return 0; } - *outlen = message_len; return 1; } diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c index 2c4b266d..2072595a 100644 --- a/src/crypto/evp/p_rsa_asn1.c +++ b/src/crypto/evp/p_rsa_asn1.c @@ -162,10 +162,6 @@ static int rsa_opaque(const EVP_PKEY *pkey) { return RSA_is_opaque(pkey->pkey.rsa); } -static int rsa_supports_digest(const EVP_PKEY *pkey, const EVP_MD *md) { - return RSA_supports_digest(pkey->pkey.rsa, md); -} - static int int_rsa_size(const EVP_PKEY *pkey) { return RSA_size(pkey->pkey.rsa); } @@ -189,7 +185,6 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { rsa_priv_encode, rsa_opaque, - rsa_supports_digest, int_rsa_size, rsa_bits, diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c index a2526678..931f7a1b 100644 --- a/src/crypto/hmac/hmac.c +++ b/src/crypto/hmac/hmac.c @@ -69,15 +69,6 @@ uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *out, unsigned int *out_len) { HMAC_CTX ctx; - static uint8_t static_out_buffer[EVP_MAX_MD_SIZE]; - - /* OpenSSL has traditionally supported using a static buffer if |out| is - * NULL. We maintain that but don't document it. This behaviour should be - * considered to be deprecated. */ - if (out == NULL) { - out = static_out_buffer; - } - HMAC_CTX_init(&ctx); if (!HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) || !HMAC_Update(&ctx, data, data_len) || diff --git a/src/crypto/internal.h b/src/crypto/internal.h index 27249567..7ce99a4e 100644 --- a/src/crypto/internal.h +++ b/src/crypto/internal.h @@ -183,17 +183,22 @@ static inline int buffers_alias(const uint8_t *a, size_t a_len, * * can be written as * - * unsigned int lt = constant_time_lt(a, b); - * c = constant_time_select(lt, a, b); */ + * size_t lt = constant_time_lt_s(a, b); + * c = constant_time_select_s(lt, a, b); */ -/* constant_time_msb returns the given value with the MSB copied to all the +#define CONSTTIME_TRUE_S ~((size_t)0) +#define CONSTTIME_FALSE_S ((size_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) +#define CONSTTIME_FALSE_8 ((uint8_t)0) + +/* constant_time_msb_s returns the given value with the MSB copied to all the * other bits. */ -static inline unsigned int constant_time_msb(unsigned int a) { - return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1)); +static inline size_t constant_time_msb_s(size_t a) { + return 0u - (a >> (sizeof(a) * 8 - 1)); } -/* constant_time_lt returns 0xff..f if a < b and 0 otherwise. */ -static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) { +/* constant_time_lt_s returns 0xff..f if a < b and 0 otherwise. */ +static inline size_t constant_time_lt_s(size_t a, size_t b) { /* Consider the two cases of the problem: * msb(a) == msb(b): a < b iff the MSB of a - b is set. * msb(a) != msb(b): a < b iff the MSB of b is set. @@ -225,26 +230,28 @@ static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) { * (check-sat) * (get-model) */ - return constant_time_msb(a^((a^b)|((a-b)^a))); + return constant_time_msb_s(a^((a^b)|((a-b)^a))); } -/* constant_time_lt_8 acts like |constant_time_lt| but returns an 8-bit mask. */ -static inline uint8_t constant_time_lt_8(unsigned int a, unsigned int b) { - return (uint8_t)(constant_time_lt(a, b)); +/* constant_time_lt_8 acts like |constant_time_lt_s| but returns an 8-bit + * mask. */ +static inline uint8_t constant_time_lt_8(size_t a, size_t b) { + return (uint8_t)(constant_time_lt_s(a, b)); } -/* constant_time_gt returns 0xff..f if a >= b and 0 otherwise. */ -static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) { - return ~constant_time_lt(a, b); +/* constant_time_ge_s returns 0xff..f if a >= b and 0 otherwise. */ +static inline size_t constant_time_ge_s(size_t a, size_t b) { + return ~constant_time_lt_s(a, b); } -/* constant_time_ge_8 acts like |constant_time_ge| but returns an 8-bit mask. */ -static inline uint8_t constant_time_ge_8(unsigned int a, unsigned int b) { - return (uint8_t)(constant_time_ge(a, b)); +/* constant_time_ge_8 acts like |constant_time_ge_s| but returns an 8-bit + * mask. */ +static inline uint8_t constant_time_ge_8(size_t a, size_t b) { + return (uint8_t)(constant_time_ge_s(a, b)); } /* constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. */ -static inline unsigned int constant_time_is_zero(unsigned int a) { +static inline size_t constant_time_is_zero_s(size_t a) { /* Here is an SMT-LIB verification of this formula: * * (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32) @@ -257,41 +264,42 @@ static inline unsigned int constant_time_is_zero(unsigned int a) { * (check-sat) * (get-model) */ - return constant_time_msb(~a & (a - 1)); + return constant_time_msb_s(~a & (a - 1)); } -/* constant_time_is_zero_8 acts like constant_time_is_zero but returns an 8-bit - * mask. */ -static inline uint8_t constant_time_is_zero_8(unsigned int a) { - return (uint8_t)(constant_time_is_zero(a)); +/* constant_time_is_zero_8 acts like |constant_time_is_zero_s| but returns an + * 8-bit mask. */ +static inline uint8_t constant_time_is_zero_8(size_t a) { + return (uint8_t)(constant_time_is_zero_s(a)); } -/* constant_time_eq returns 0xff..f if a == b and 0 otherwise. */ -static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) { - return constant_time_is_zero(a ^ b); +/* constant_time_eq_s returns 0xff..f if a == b and 0 otherwise. */ +static inline size_t constant_time_eq_s(size_t a, size_t b) { + return constant_time_is_zero_s(a ^ b); } -/* constant_time_eq_8 acts like |constant_time_eq| but returns an 8-bit mask. */ -static inline uint8_t constant_time_eq_8(unsigned int a, unsigned int b) { - return (uint8_t)(constant_time_eq(a, b)); +/* constant_time_eq_8 acts like |constant_time_eq_s| but returns an 8-bit + * mask. */ +static inline uint8_t constant_time_eq_8(size_t a, size_t b) { + return (uint8_t)(constant_time_eq_s(a, b)); } -/* constant_time_eq_int acts like |constant_time_eq| but works on int values. */ -static inline unsigned int constant_time_eq_int(int a, int b) { - return constant_time_eq((unsigned)(a), (unsigned)(b)); +/* constant_time_eq_int acts like |constant_time_eq_s| but works on int + * values. */ +static inline size_t constant_time_eq_int(int a, int b) { + return constant_time_eq_s((size_t)(a), (size_t)(b)); } /* constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit * mask. */ static inline uint8_t constant_time_eq_int_8(int a, int b) { - return constant_time_eq_8((unsigned)(a), (unsigned)(b)); + return constant_time_eq_8((size_t)(a), (size_t)(b)); } -/* constant_time_select returns (mask & a) | (~mask & b). When |mask| is all 1s - * or all 0s (as returned by the methods above), the select methods return +/* constant_time_select_s returns (mask & a) | (~mask & b). When |mask| is all + * 1s or all 0s (as returned by the methods above), the select methods return * either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). */ -static inline unsigned int constant_time_select(unsigned int mask, - unsigned int a, unsigned int b) { +static inline size_t constant_time_select_s(size_t mask, size_t a, size_t b) { return (mask & a) | (~mask & b); } @@ -299,13 +307,13 @@ static inline unsigned int constant_time_select(unsigned int mask, * 8-bit values. */ static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a, uint8_t b) { - return (uint8_t)(constant_time_select(mask, a, b)); + return (uint8_t)(constant_time_select_s(mask, a, b)); } /* constant_time_select_int acts like |constant_time_select| but operates on * ints. */ -static inline int constant_time_select_int(unsigned int mask, int a, int b) { - return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); +static inline int constant_time_select_int(size_t mask, int a, int b) { + return (int)(constant_time_select_s(mask, (size_t)(a), (size_t)(b))); } diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c index 7712f475..adc59578 100644 --- a/src/crypto/md5/md5.c +++ b/src/crypto/md5/md5.c @@ -65,13 +65,6 @@ uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out) { MD5_CTX ctx; - static uint8_t digest[MD5_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = digest; - } - MD5_Init(&ctx); MD5_Update(&ctx, data, len); MD5_Final(out, &ctx); diff --git a/src/crypto/modes/polyval.c b/src/crypto/modes/polyval.c index 33d37eb7..83df0abc 100644 --- a/src/crypto/modes/polyval.c +++ b/src/crypto/modes/polyval.c @@ -36,11 +36,11 @@ static void byte_reverse(polyval_block *b) { static void reverse_and_mulX_ghash(polyval_block *b) { uint64_t hi = b->u[0]; uint64_t lo = b->u[1]; - const unsigned carry = constant_time_eq(hi & 1, 1); + const size_t carry = constant_time_eq_s(hi & 1, 1); hi >>= 1; hi |= lo << 63; lo >>= 1; - lo ^= ((uint64_t) constant_time_select(carry, 0xe1, 0)) << 56; + lo ^= ((uint64_t) constant_time_select_s(carry, 0xe1, 0)) << 56; b->u[0] = CRYPTO_bswap8(lo); b->u[1] = CRYPTO_bswap8(hi); diff --git a/src/crypto/perlasm/x86_64-xlate.pl b/src/crypto/perlasm/x86_64-xlate.pl index 6e487b8e..6043bc71 100755 --- a/src/crypto/perlasm/x86_64-xlate.pl +++ b/src/crypto/perlasm/x86_64-xlate.pl @@ -1134,7 +1134,7 @@ ___ OPTION DOTNAME ___ } -print STDOUT "#if defined(__x86_64__)\n" if ($gas); +print STDOUT "#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)\n" if ($gas); while(defined(my $line=<>)) { diff --git a/src/crypto/rsa/internal.h b/src/crypto/rsa/internal.h index b6a07276..b865a0aa 100644 --- a/src/crypto/rsa/internal.h +++ b/src/crypto/rsa/internal.h @@ -97,16 +97,19 @@ int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); -int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len); +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); -int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len); -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len, - const uint8_t *param, unsigned plen, - const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c index ac583c46..dee44dd0 100644 --- a/src/crypto/rsa/padding.c +++ b/src/crypto/rsa/padding.c @@ -92,56 +92,56 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, return 1; } -int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len) { - unsigned i, j; - const uint8_t *p; - +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + /* See RFC 8017, section 9.2. This is part of signature verification and thus + * does not need to run in constant-time. */ if (from_len < 2) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); - return -1; + return 0; } - p = from; - if ((*(p++) != 0) || (*(p++) != 1)) { + /* Check the header. */ + if (from[0] != 0 || from[1] != 1) { OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); - return -1; - } - - /* scan over padding data */ - j = from_len - 2; /* one for leading 00, one for type. */ - for (i = 0; i < j; i++) { - /* should decrypt to 0xff */ - if (*p != 0xff) { - if (*p == 0) { - p++; - break; - } else { - OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); - return -1; - } + return 0; + } + + /* Scan over padded data, looking for the 00. */ + size_t pad; + for (pad = 2 /* header */; pad < from_len; pad++) { + if (from[pad] == 0x00) { + break; + } + + if (from[pad] != 0xff) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); + return 0; } - p++; } - if (i == j) { + if (pad == from_len) { OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); - return -1; + return 0; } - if (i < 8) { + if (pad < 2 /* header */ + 8) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT); - return -1; + return 0; } - i++; /* Skip over the '\0' */ - j -= i; - if (j > to_len) { + + /* Skip over the 00. */ + pad++; + + if (from_len - pad > max_out) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); - return -1; + return 0; } - OPENSSL_memcpy(to, p, j); - return j; + OPENSSL_memcpy(out, from + pad, from_len - pad); + *out_len = from_len - pad; + return 1; } static int rand_nonzero(uint8_t *out, size_t len) { @@ -186,11 +186,12 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, return 1; } -int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len) { +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { if (from_len == 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); - return -1; + return 0; } /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography @@ -199,29 +200,29 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, /* |from| is zero-padded to the size of the RSA modulus, a public value, so * this can be rejected in non-constant time. */ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return -1; + return 0; } - unsigned first_byte_is_zero = constant_time_eq(from[0], 0); - unsigned second_byte_is_two = constant_time_eq(from[1], 2); + size_t first_byte_is_zero = constant_time_eq_s(from[0], 0); + size_t second_byte_is_two = constant_time_eq_s(from[1], 2); - unsigned i, zero_index = 0, looking_for_index = ~0u; - for (i = 2; i < from_len; i++) { - unsigned equals0 = constant_time_is_zero(from[i]); - zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i, - zero_index); - looking_for_index = constant_time_select(equals0, 0, looking_for_index); + size_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_S; + for (size_t i = 2; i < from_len; i++) { + size_t equals0 = constant_time_is_zero_s(from[i]); + zero_index = + constant_time_select_s(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_s(equals0, 0, looking_for_index); } /* The input must begin with 00 02. */ - unsigned valid_index = first_byte_is_zero; + size_t valid_index = first_byte_is_zero; valid_index &= second_byte_is_two; /* We must have found the end of PS. */ valid_index &= ~looking_for_index; /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */ - valid_index &= constant_time_ge(zero_index, 2 + 8); + valid_index &= constant_time_ge_s(zero_index, 2 + 8); /* Skip the zero byte. */ zero_index++; @@ -229,27 +230,24 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, /* NOTE: Although this logic attempts to be constant time, the API contracts * of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it * impossible to completely avoid Bleichenbacher's attack. Consumers should - * use |RSA_unpad_key_pkcs1|. */ + * use |RSA_PADDING_NONE| and perform the padding check in constant-time + * combined with a swap to a random session key or other mitigation. */ if (!valid_index) { OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return -1; + return 0; } - const unsigned msg_len = from_len - zero_index; - if (msg_len > to_len) { + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { /* This shouldn't happen because this function is always called with - * |to_len| as the key size and |from_len| is bounded by the key size. */ + * |max_out| as the key size and |from_len| is bounded by the key size. */ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return -1; - } - - if (msg_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; + return 0; } - OPENSSL_memcpy(to, &from[zero_index], msg_len); - return (int)msg_len; + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; } int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, @@ -382,13 +380,12 @@ out: return ret; } -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, - const uint8_t *from, unsigned from_len, - const uint8_t *param, unsigned param_len, - const EVP_MD *md, const EVP_MD *mgf1md) { - unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index = 0; - const uint8_t *maskeddb, *maskedseed; - uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE]; +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; if (md == NULL) { md = EVP_sha1(); @@ -397,7 +394,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, mgf1md = md; } - mdlen = EVP_MD_size(md); + size_t mdlen = EVP_MD_size(md); /* The encoded message is one byte smaller than the modulus to ensure that it * doesn't end up greater than the modulus. Thus there's an extra "+1" here @@ -408,45 +405,47 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, goto decoding_err; } - dblen = from_len - mdlen - 1; + size_t dblen = from_len - mdlen - 1; db = OPENSSL_malloc(dblen); if (db == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } - maskedseed = from + 1; - maskeddb = from + 1 + mdlen; + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + uint8_t seed[EVP_MAX_MD_SIZE]; if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { goto err; } - for (i = 0; i < mdlen; i++) { + for (size_t i = 0; i < mdlen; i++) { seed[i] ^= maskedseed[i]; } if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { goto err; } - for (i = 0; i < dblen; i++) { + for (size_t i = 0; i < dblen; i++) { db[i] ^= maskeddb[i]; } + uint8_t phash[EVP_MAX_MD_SIZE]; if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { goto err; } - bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); - bad |= ~constant_time_is_zero(from[0]); + size_t bad = ~constant_time_is_zero_s(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_s(from[0]); - looking_for_one_byte = ~0u; - for (i = mdlen; i < dblen; i++) { - unsigned equals1 = constant_time_eq(db[i], 1); - unsigned equals0 = constant_time_eq(db[i], 0); - one_index = constant_time_select(looking_for_one_byte & equals1, i, - one_index); + size_t looking_for_one_byte = CONSTTIME_TRUE_S, one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + size_t equals1 = constant_time_eq_s(db[i], 1); + size_t equals0 = constant_time_eq_s(db[i], 0); + one_index = + constant_time_select_s(looking_for_one_byte & equals1, i, one_index); looking_for_one_byte = - constant_time_select(equals1, 0, looking_for_one_byte); + constant_time_select_s(equals1, 0, looking_for_one_byte); bad |= looking_for_one_byte & ~equals0; } @@ -457,16 +456,16 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len, } one_index++; - mlen = dblen - one_index; - if (to_len < mlen) { + size_t mlen = dblen - one_index; + if (max_out < mlen) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); - mlen = -1; - } else { - OPENSSL_memcpy(to, db + one_index, mlen); + goto err; } + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; OPENSSL_free(db); - return mlen; + return 1; decoding_err: /* to avoid chosen ciphertext attacks, the error message should not reveal @@ -474,7 +473,7 @@ decoding_err: OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); err: OPENSSL_free(db); - return -1; + return 0; } static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c index 731293f8..6d56238c 100644 --- a/src/crypto/rsa/rsa.c +++ b/src/crypto/rsa/rsa.c @@ -321,13 +321,6 @@ int RSA_is_opaque(const RSA *rsa) { return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); } -int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) { - if (rsa->meth && rsa->meth->supports_digest) { - return rsa->meth->supports_digest(rsa, md); - } - return 1; -} - int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { int index; diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c index 8e0aa9c6..e385e603 100644 --- a/src/crypto/rsa/rsa_impl.c +++ b/src/crypto/rsa/rsa_impl.c @@ -363,7 +363,6 @@ err: int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { const unsigned rsa_size = RSA_size(rsa); - int r = -1; uint8_t *buf = NULL; int ret = 0; @@ -394,26 +393,25 @@ int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, switch (padding) { case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_2(out, rsa_size, buf, rsa_size); + ret = + RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); break; case RSA_PKCS1_OAEP_PADDING: /* Use the default parameters: SHA-1 for both hashes and no label. */ - r = RSA_padding_check_PKCS1_OAEP_mgf1(out, rsa_size, buf, rsa_size, - NULL, 0, NULL, NULL); + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); break; case RSA_NO_PADDING: - r = rsa_size; + *out_len = rsa_size; + ret = 1; break; default: OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } - if (r < 0) { + if (!ret) { OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); - } else { - *out_len = r; - ret = 1; } err: @@ -436,7 +434,6 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const unsigned rsa_size = RSA_size(rsa); BIGNUM *f, *result; - int r = -1; if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); @@ -500,21 +497,21 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, switch (padding) { case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size); + ret = + RSA_padding_check_PKCS1_type_1(out, out_len, rsa_size, buf, rsa_size); break; case RSA_NO_PADDING: - r = rsa_size; + ret = 1; + *out_len = rsa_size; break; default: OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } - if (r < 0) { + if (!ret) { OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); - } else { - *out_len = r; - ret = 1; + goto err; } err: diff --git a/src/crypto/sha/sha1-altivec.c b/src/crypto/sha/sha1-altivec.c index 500986e1..0b643154 100644 --- a/src/crypto/sha/sha1-altivec.c +++ b/src/crypto/sha/sha1-altivec.c @@ -105,7 +105,9 @@ static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; * Byte shifting code below may not be correct for big-endian systems. */ static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, vec_uint32_t k) { - const vec_uint32_t v = *((const vec_uint32_t *)data); + const vector unsigned char unaligned_data = + vec_vsx_ld(0, (const unsigned char*) data); + const vec_uint32_t v = (vec_uint32_t) unaligned_data; const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); vec_st(w + k, 0, pre_added); return w; diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c index 7c727132..4eb8189c 100644 --- a/src/crypto/sha/sha1.c +++ b/src/crypto/sha/sha1.c @@ -82,12 +82,6 @@ int SHA1_Init(SHA_CTX *sha) { uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) { SHA_CTX ctx; - static uint8_t buf[SHA_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = buf; - } if (!SHA1_Init(&ctx)) { return NULL; } diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c index fb950d75..c3bd5ad1 100644 --- a/src/crypto/sha/sha256.c +++ b/src/crypto/sha/sha256.c @@ -99,12 +99,6 @@ int SHA256_Init(SHA256_CTX *sha) { uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out) { SHA256_CTX ctx; - static uint8_t buf[SHA224_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = buf; - } SHA224_Init(&ctx); SHA224_Update(&ctx, data, len); SHA224_Final(out, &ctx); @@ -114,12 +108,6 @@ uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out) { uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out) { SHA256_CTX ctx; - static uint8_t buf[SHA256_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = buf; - } SHA256_Init(&ctx); SHA256_Update(&ctx, data, len); SHA256_Final(out, &ctx); diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c index 87611508..e8284f11 100644 --- a/src/crypto/sha/sha512.c +++ b/src/crypto/sha/sha512.c @@ -123,13 +123,6 @@ int SHA512_Init(SHA512_CTX *sha) { uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out) { SHA512_CTX ctx; - static uint8_t buf[SHA384_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = buf; - } - SHA384_Init(&ctx); SHA384_Update(&ctx, data, len); SHA384_Final(out, &ctx); @@ -139,12 +132,6 @@ uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out) { uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out) { SHA512_CTX ctx; - static uint8_t buf[SHA512_DIGEST_LENGTH]; - - /* TODO(fork): remove this static buffer. */ - if (out == NULL) { - out = buf; - } SHA512_Init(&ctx); SHA512_Update(&ctx, data, len); SHA512_Final(out, &ctx); |