diff --git a/Package.swift b/Package.swift index 70a10b1e..5cf73b97 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ // Sources/CCryptoBoringSSL directory. The source repository is at // https://boringssl.googlesource.com/boringssl. // -// BoringSSL Commit: cab31f65f1ad6e6daca62e95b25dd6cd805fce0b +// BoringSSL Commit: 0faffc7a30eeb195248ea43056f4848e2a9b1c6d import PackageDescription diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index 0b1b702d..f767ee57 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -29,7 +29,6 @@ add_library(CCryptoBoringSSL STATIC "crypto/asn1/a_time.c" "crypto/asn1/a_type.c" "crypto/asn1/a_utctm.c" - "crypto/asn1/a_utf8.c" "crypto/asn1/asn1_lib.c" "crypto/asn1/asn1_par.c" "crypto/asn1/asn_pack.c" @@ -76,10 +75,12 @@ add_library(CCryptoBoringSSL STATIC "crypto/cipher_extra/tls_cbc.c" "crypto/conf/conf.c" "crypto/cpu_aarch64_apple.c" + "crypto/cpu_aarch64_freebsd.c" "crypto/cpu_aarch64_fuchsia.c" "crypto/cpu_aarch64_linux.c" "crypto/cpu_aarch64_win.c" "crypto/cpu_arm.c" + "crypto/cpu_arm_freebsd.c" "crypto/cpu_arm_linux.c" "crypto/cpu_intel.c" "crypto/cpu_ppc64le.c" diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.c b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.c index 10dd88ef..b8df3d8f 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.c +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.c @@ -115,6 +115,10 @@ int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) { uint8_t bits; int len = asn1_bit_string_length(a, &bits); + if (len > INT_MAX - 1) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } int ret = 1 + len; if (pp == NULL) { return ret; diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_strex.c b/Sources/CCryptoBoringSSL/crypto/asn1/a_strex.c index 77fc4d7e..2d34cd26 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_strex.c +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_strex.c @@ -167,12 +167,17 @@ static int do_buf(const unsigned char *buf, int buflen, int encoding, } const int is_last = CBS_len(&cbs) == 0; if (flags & ASN1_STRFLGS_UTF8_CONVERT) { - unsigned char utfbuf[6]; - int utflen; - utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c); - for (int i = 0; i < utflen; i++) { - int len = do_esc_char(utfbuf[i], flags, quotes, out, is_first && i == 0, - is_last && i == utflen - 1); + uint8_t utf8_buf[6]; + CBB utf8_cbb; + CBB_init_fixed(&utf8_cbb, utf8_buf, sizeof(utf8_buf)); + if (!cbb_add_utf8(&utf8_cbb, c)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return 1; + } + size_t utf8_len = CBB_len(&utf8_cbb); + for (size_t i = 0; i < utf8_len; i++) { + int len = do_esc_char(utf8_buf[i], flags, quotes, out, + is_first && i == 0, is_last && i == utf8_len - 1); if (len < 0) { return -1; } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_utf8.c b/Sources/CCryptoBoringSSL/crypto/asn1/a_utf8.c deleted file mode 100644 index 2a6ece82..00000000 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_utf8.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include -#include - -#include "internal.h" - -// UTF8 utilities - -// This takes a character 'value' and writes the UTF8 encoded value in 'str' -// where 'str' is a buffer containing 'len' characters. Returns the number of -// characters written or -1 if 'len' is too small. 'str' can be set to NULL -// in which case it just returns the number of characters. It will need at -// most 6 characters. - -int UTF8_putc(unsigned char *str, int len, uint32_t value) { - if (!str) { - len = 6; // Maximum we will need - } else if (len <= 0) { - return -1; - } - if (value < 0x80) { - if (str) { - *str = (unsigned char)value; - } - return 1; - } - if (value < 0x800) { - if (len < 2) { - return -1; - } - if (str) { - *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 2; - } - if (value < 0x10000) { - if (len < 3) { - return -1; - } - if (str) { - *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 3; - } - if (value < 0x200000) { - if (len < 4) { - return -1; - } - if (str) { - *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 4; - } - if (value < 0x4000000) { - if (len < 5) { - return -1; - } - if (str) { - *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 5; - } - if (len < 6) { - return -1; - } - if (str) { - *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); - *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 6; -} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h index f16b2fea..2958cc52 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h @@ -96,7 +96,8 @@ OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out); // |offset_day| days and |offset_sec| seconds. It returns zero on failure. |tm| // must be in the range of year 0000 to 9999 both before and after the update or // a failure will be returned. -int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +OPENSSL_EXPORT int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, + long offset_sec); // OPENSSL_gmtime_diff calculates the difference between |from| and |to|. It // returns one, and outputs the difference as a number of days and seconds in @@ -156,8 +157,6 @@ OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); -int UTF8_putc(unsigned char *str, int len, uint32_t value); - int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/posix_time.c b/Sources/CCryptoBoringSSL/crypto/asn1/posix_time.c index 81fbe833..7dd9e5b3 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/posix_time.c +++ b/Sources/CCryptoBoringSSL/crypto/asn1/posix_time.c @@ -191,9 +191,10 @@ int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { tm->tm_hour, tm->tm_min, tm->tm_sec, &posix_time)) { return 0; } - if (!utc_from_posix_time(posix_time + off_day * SECS_PER_DAY + offset_sec, - &tm->tm_year, &tm->tm_mon, &tm->tm_mday, - &tm->tm_hour, &tm->tm_min, &tm->tm_sec)) { + if (!utc_from_posix_time( + posix_time + (int64_t)off_day * SECS_PER_DAY + offset_sec, + &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min, + &tm->tm_sec)) { return 0; } tm->tm_year -= 1900; diff --git a/Sources/CCryptoBoringSSL/crypto/bio/bio.c b/Sources/CCryptoBoringSSL/crypto/bio/bio.c index bed97a7d..63516321 100644 --- a/Sources/CCryptoBoringSSL/crypto/bio/bio.c +++ b/Sources/CCryptoBoringSSL/crypto/bio/bio.c @@ -192,7 +192,13 @@ int BIO_write_all(BIO *bio, const void *data, size_t len) { } int BIO_puts(BIO *bio, const char *in) { - return BIO_write(bio, in, strlen(in)); + size_t len = strlen(in); + if (len > INT_MAX) { + // |BIO_write| and the return value both assume the string fits in |int|. + OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW); + return -1; + } + return BIO_write(bio, in, (int)len); } int BIO_flush(BIO *bio) { diff --git a/Sources/CCryptoBoringSSL/crypto/bio/fd.c b/Sources/CCryptoBoringSSL/crypto/bio/fd.c index 1d6b87d0..cdbc53d6 100644 --- a/Sources/CCryptoBoringSSL/crypto/bio/fd.c +++ b/Sources/CCryptoBoringSSL/crypto/bio/fd.c @@ -158,7 +158,7 @@ static int fd_free(BIO *bio) { static int fd_read(BIO *b, char *out, int outl) { int ret = 0; - ret = BORINGSSL_READ(b->num, out, outl); + ret = (int)BORINGSSL_READ(b->num, out, outl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -170,7 +170,7 @@ static int fd_read(BIO *b, char *out, int outl) { } static int fd_write(BIO *b, const char *in, int inl) { - int ret = BORINGSSL_WRITE(b->num, in, inl); + int ret = (int)BORINGSSL_WRITE(b->num, in, inl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { diff --git a/Sources/CCryptoBoringSSL/crypto/bio/socket.c b/Sources/CCryptoBoringSSL/crypto/bio/socket.c index 36fcaa32..4bd6f616 100644 --- a/Sources/CCryptoBoringSSL/crypto/bio/socket.c +++ b/Sources/CCryptoBoringSSL/crypto/bio/socket.c @@ -101,7 +101,7 @@ static int sock_read(BIO *b, char *out, int outl) { #if defined(OPENSSL_WINDOWS) int ret = recv(b->num, out, outl, 0); #else - int ret = read(b->num, out, outl); + int ret = (int)read(b->num, out, outl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { @@ -113,13 +113,11 @@ static int sock_read(BIO *b, char *out, int outl) { } static int sock_write(BIO *b, const char *in, int inl) { - int ret; - bio_clear_socket_error(); #if defined(OPENSSL_WINDOWS) - ret = send(b->num, in, inl, 0); + int ret = send(b->num, in, inl, 0); #else - ret = write(b->num, in, inl); + int ret = (int)write(b->num, in, inl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { diff --git a/Sources/CCryptoBoringSSL/crypto/bytestring/asn1_compat.c b/Sources/CCryptoBoringSSL/crypto/bytestring/asn1_compat.c index e085c62f..e4525181 100644 --- a/Sources/CCryptoBoringSSL/crypto/bytestring/asn1_compat.c +++ b/Sources/CCryptoBoringSSL/crypto/bytestring/asn1_compat.c @@ -26,7 +26,8 @@ int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { - assert(cbb->base->can_resize); + assert(!cbb->is_child); + assert(cbb->u.base.can_resize); uint8_t *der; size_t der_len; diff --git a/Sources/CCryptoBoringSSL/crypto/bytestring/cbb.c b/Sources/CCryptoBoringSSL/crypto/bytestring/cbb.c index f07e31cc..1a2e29a8 100644 --- a/Sources/CCryptoBoringSSL/crypto/bytestring/cbb.c +++ b/Sources/CCryptoBoringSSL/crypto/bytestring/cbb.c @@ -27,24 +27,14 @@ void CBB_zero(CBB *cbb) { OPENSSL_memset(cbb, 0, sizeof(CBB)); } -static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { - // This assumes that |cbb| has already been zeroed. - struct cbb_buffer_st *base; - - base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); - if (base == NULL) { - return 0; - } - - base->buf = buf; - base->len = 0; - base->cap = cap; - base->can_resize = 1; - base->error = 0; - - cbb->base = base; +static void cbb_init(CBB *cbb, uint8_t *buf, size_t cap, int can_resize) { cbb->is_child = 0; - return 1; + cbb->child = NULL; + cbb->u.base.buf = buf; + cbb->u.base.len = 0; + cbb->u.base.cap = cap; + cbb->u.base.can_resize = can_resize; + cbb->u.base.error = 0; } int CBB_init(CBB *cbb, size_t initial_capacity) { @@ -55,22 +45,13 @@ int CBB_init(CBB *cbb, size_t initial_capacity) { return 0; } - if (!cbb_init(cbb, buf, initial_capacity)) { - OPENSSL_free(buf); - return 0; - } - + cbb_init(cbb, buf, initial_capacity, /*can_resize=*/1); return 1; } int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { CBB_zero(cbb); - - if (!cbb_init(cbb, buf, len)) { - return 0; - } - - cbb->base->can_resize = 0; + cbb_init(cbb, buf, len, /*can_resize=*/0); return 1; } @@ -82,41 +63,33 @@ void CBB_cleanup(CBB *cbb) { return; } - if (cbb->base) { - if (cbb->base->can_resize) { - OPENSSL_free(cbb->base->buf); - } - OPENSSL_free(cbb->base); + if (cbb->u.base.can_resize) { + OPENSSL_free(cbb->u.base.buf); } - cbb->base = NULL; } static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, size_t len) { - size_t newlen; - if (base == NULL) { return 0; } - newlen = base->len + len; + size_t newlen = base->len + len; if (newlen < base->len) { // Overflow goto err; } if (newlen > base->cap) { - size_t newcap = base->cap * 2; - uint8_t *newbuf; - if (!base->can_resize) { goto err; } + size_t newcap = base->cap * 2; if (newcap < base->cap || newcap < newlen) { newcap = newlen; } - newbuf = OPENSSL_realloc(base->buf, newcap); + uint8_t *newbuf = OPENSSL_realloc(base->buf, newcap); if (newbuf == NULL) { goto err; } @@ -146,30 +119,6 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, return 1; } -static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint64_t v, - size_t len_len) { - if (len_len == 0) { - return 1; - } - - uint8_t *buf; - if (!cbb_buffer_add(base, &buf, len_len)) { - return 0; - } - - for (size_t i = len_len - 1; i < len_len; i--) { - buf[i] = v; - v >>= 8; - } - - if (v != 0) { - base->error = 1; - return 0; - } - - return 1; -} - int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { if (cbb->is_child) { return 0; @@ -179,57 +128,67 @@ int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { return 0; } - if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { + if (cbb->u.base.can_resize && (out_data == NULL || out_len == NULL)) { // |out_data| and |out_len| can only be NULL if the CBB is fixed. return 0; } if (out_data != NULL) { - *out_data = cbb->base->buf; + *out_data = cbb->u.base.buf; } if (out_len != NULL) { - *out_len = cbb->base->len; + *out_len = cbb->u.base.len; } - cbb->base->buf = NULL; + cbb->u.base.buf = NULL; CBB_cleanup(cbb); return 1; } +static struct cbb_buffer_st *cbb_get_base(CBB *cbb) { + if (cbb->is_child) { + return cbb->u.child.base; + } + return &cbb->u.base; +} + // CBB_flush recurses and then writes out any pending length prefix. The // current length of the underlying base is taken to be the length of the // length-prefixed data. int CBB_flush(CBB *cbb) { - size_t child_start, i, len; - - // If |cbb->base| has hit an error, the buffer is in an undefined state, so + // If |base| has hit an error, the buffer is in an undefined state, so // fail all following calls. In particular, |cbb->child| may point to invalid // memory. - if (cbb->base == NULL || cbb->base->error) { + struct cbb_buffer_st *base = cbb_get_base(cbb); + if (base == NULL || base->error) { return 0; } - if (cbb->child == NULL || cbb->child->pending_len_len == 0) { + if (cbb->child == NULL) { + // Nothing to flush. return 1; } - child_start = cbb->child->offset + cbb->child->pending_len_len; + assert(cbb->child->is_child); + struct cbb_child_st *child = &cbb->child->u.child; + assert(child->base == base); + size_t child_start = child->offset + child->pending_len_len; if (!CBB_flush(cbb->child) || - child_start < cbb->child->offset || - cbb->base->len < child_start) { + child_start < child->offset || + base->len < child_start) { goto err; } - len = cbb->base->len - child_start; + size_t len = base->len - child_start; - if (cbb->child->pending_is_asn1) { + if (child->pending_is_asn1) { // For ASN.1 we assume that we'll only need a single byte for the length. // If that turned out to be incorrect, we have to move the contents along // in order to make space. uint8_t len_len; uint8_t initial_length_byte; - assert (cbb->child->pending_len_len == 1); + assert (child->pending_len_len == 1); if (len > 0xfffffffe) { // Too large. @@ -255,70 +214,85 @@ int CBB_flush(CBB *cbb) { if (len_len != 1) { // We need to move the contents along in order to make space. size_t extra_bytes = len_len - 1; - if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { + if (!cbb_buffer_add(base, NULL, extra_bytes)) { goto err; } - OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes, - cbb->base->buf + child_start, len); + OPENSSL_memmove(base->buf + child_start + extra_bytes, + base->buf + child_start, len); } - cbb->base->buf[cbb->child->offset++] = initial_length_byte; - cbb->child->pending_len_len = len_len - 1; + base->buf[child->offset++] = initial_length_byte; + child->pending_len_len = len_len - 1; } - for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; - i--) { - cbb->base->buf[cbb->child->offset + i] = (uint8_t)len; + for (size_t i = child->pending_len_len - 1; i < child->pending_len_len; i--) { + base->buf[child->offset + i] = (uint8_t)len; len >>= 8; } if (len != 0) { goto err; } - cbb->child->base = NULL; + child->base = NULL; cbb->child = NULL; return 1; err: - cbb->base->error = 1; + base->error = 1; return 0; } const uint8_t *CBB_data(const CBB *cbb) { assert(cbb->child == NULL); - return cbb->base->buf + cbb->offset + cbb->pending_len_len; + if (cbb->is_child) { + return cbb->u.child.base->buf + cbb->u.child.offset + + cbb->u.child.pending_len_len; + } + return cbb->u.base.buf; } size_t CBB_len(const CBB *cbb) { assert(cbb->child == NULL); - assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); - - return cbb->base->len - cbb->offset - cbb->pending_len_len; + if (cbb->is_child) { + assert(cbb->u.child.offset + cbb->u.child.pending_len_len <= + cbb->u.child.base->len); + return cbb->u.child.base->len - cbb->u.child.offset - + cbb->u.child.pending_len_len; + } + return cbb->u.base.len; } -static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, - uint8_t len_len) { - uint8_t *prefix_bytes; +static int cbb_add_child(CBB *cbb, CBB *out_child, uint8_t len_len, + int is_asn1) { + assert(cbb->child == NULL); + assert(!is_asn1 || len_len == 1); + struct cbb_buffer_st *base = cbb_get_base(cbb); + size_t offset = base->len; - if (!CBB_flush(cbb)) { + // Reserve space for the length prefix. + uint8_t *prefix_bytes; + if (!cbb_buffer_add(base, &prefix_bytes, len_len)) { return 0; } + OPENSSL_memset(prefix_bytes, 0, len_len); + + CBB_zero(out_child); + out_child->is_child = 1; + out_child->u.child.base = base; + out_child->u.child.offset = offset; + out_child->u.child.pending_len_len = len_len; + out_child->u.child.pending_is_asn1 = is_asn1; + cbb->child = out_child; + return 1; +} - size_t offset = cbb->base->len; - if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { +static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, + uint8_t len_len) { + if (!CBB_flush(cbb)) { return 0; } - OPENSSL_memset(prefix_bytes, 0, len_len); - OPENSSL_memset(out_contents, 0, sizeof(CBB)); - out_contents->base = cbb->base; - out_contents->is_child = 1; - cbb->child = out_contents; - cbb->child->offset = offset; - cbb->child->pending_len_len = len_len; - cbb->child->pending_is_asn1 = 0; - - return 1; + return cbb_add_child(cbb, out_contents, len_len, /*is_asn1=*/0); } int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { @@ -377,30 +351,16 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { return 0; } - size_t offset = cbb->base->len; - if (!CBB_add_u8(cbb, 0)) { - return 0; - } - - OPENSSL_memset(out_contents, 0, sizeof(CBB)); - out_contents->base = cbb->base; - out_contents->is_child = 1; - cbb->child = out_contents; - cbb->child->offset = offset; - cbb->child->pending_len_len = 1; - cbb->child->pending_is_asn1 = 1; - - return 1; + // Reserve one byte of length prefix. |CBB_flush| will finish it later. + return cbb_add_child(cbb, out_contents, /*len_len=*/1, /*is_asn1=*/1); } int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { - uint8_t *dest; - - if (!CBB_flush(cbb) || - !cbb_buffer_add(cbb->base, &dest, len)) { + uint8_t *out; + if (!CBB_add_space(cbb, &out, len)) { return 0; } - OPENSSL_memcpy(dest, data, len); + OPENSSL_memcpy(out, data, len); return 1; } @@ -415,7 +375,7 @@ int CBB_add_zeros(CBB *cbb, size_t len) { int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { if (!CBB_flush(cbb) || - !cbb_buffer_add(cbb->base, out_data, len)) { + !cbb_buffer_add(cbb_get_base(cbb), out_data, len)) { return 0; } return 1; @@ -423,37 +383,50 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { if (!CBB_flush(cbb) || - !cbb_buffer_reserve(cbb->base, out_data, len)) { + !cbb_buffer_reserve(cbb_get_base(cbb), out_data, len)) { return 0; } return 1; } int CBB_did_write(CBB *cbb, size_t len) { - size_t newlen = cbb->base->len + len; + struct cbb_buffer_st *base = cbb_get_base(cbb); + size_t newlen = base->len + len; if (cbb->child != NULL || - newlen < cbb->base->len || - newlen > cbb->base->cap) { + newlen < base->len || + newlen > base->cap) { return 0; } - cbb->base->len = newlen; + base->len = newlen; return 1; } -int CBB_add_u8(CBB *cbb, uint8_t value) { - if (!CBB_flush(cbb)) { +static int cbb_add_u(CBB *cbb, uint64_t v, size_t len_len) { + uint8_t *buf; + if (!CBB_add_space(cbb, &buf, len_len)) { return 0; } - return cbb_buffer_add_u(cbb->base, value, 1); -} + for (size_t i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } -int CBB_add_u16(CBB *cbb, uint16_t value) { - if (!CBB_flush(cbb)) { + // |v| must fit in |len_len| bytes. + if (v != 0) { + cbb_get_base(cbb)->error = 1; return 0; } - return cbb_buffer_add_u(cbb->base, value, 2); + return 1; +} + +int CBB_add_u8(CBB *cbb, uint8_t value) { + return cbb_add_u(cbb, value, 1); +} + +int CBB_add_u16(CBB *cbb, uint16_t value) { + return cbb_add_u(cbb, value, 2); } int CBB_add_u16le(CBB *cbb, uint16_t value) { @@ -461,19 +434,11 @@ int CBB_add_u16le(CBB *cbb, uint16_t value) { } int CBB_add_u24(CBB *cbb, uint32_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 3); + return cbb_add_u(cbb, value, 3); } int CBB_add_u32(CBB *cbb, uint32_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 4); + return cbb_add_u(cbb, value, 4); } int CBB_add_u32le(CBB *cbb, uint32_t value) { @@ -481,10 +446,7 @@ int CBB_add_u32le(CBB *cbb, uint32_t value) { } int CBB_add_u64(CBB *cbb, uint64_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - return cbb_buffer_add_u(cbb->base, value, 8); + return cbb_add_u(cbb, value, 8); } int CBB_add_u64le(CBB *cbb, uint64_t value) { @@ -496,20 +458,25 @@ void CBB_discard_child(CBB *cbb) { return; } - cbb->base->len = cbb->child->offset; + struct cbb_buffer_st *base = cbb_get_base(cbb); + assert(cbb->child->is_child); + base->len = cbb->child->u.child.offset; - cbb->child->base = NULL; + cbb->child->u.child.base = NULL; cbb->child = NULL; } int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { - CBB child; - int started = 0; + return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER); +} - if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { +int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, unsigned tag) { + CBB child; + if (!CBB_add_asn1(cbb, &child, tag)) { return 0; } + int started = 0; for (size_t i = 0; i < 8; i++) { uint8_t byte = (value >> 8*(7-i)) & 0xff; if (!started) { @@ -538,8 +505,12 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { } int CBB_add_asn1_int64(CBB *cbb, int64_t value) { + return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER); +} + +int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, unsigned tag) { if (value >= 0) { - return CBB_add_asn1_uint64(cbb, value); + return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag); } uint8_t bytes[sizeof(int64_t)]; @@ -551,7 +522,7 @@ int CBB_add_asn1_int64(CBB *cbb, int64_t value) { } CBB child; - if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + if (!CBB_add_asn1(cbb, &child, tag)) { return 0; } for (int i = start; i >= 0; i--) { @@ -707,14 +678,14 @@ int CBB_flush_asn1_set_of(CBB *cbb) { } qsort(children, num_children, sizeof(CBS), compare_set_of_element); - // Rewind |cbb| and write the contents back in the new order. - cbb->base->len = cbb->offset + cbb->pending_len_len; + // Write the contents back in the new order. + uint8_t *out = (uint8_t *)CBB_data(cbb); + size_t offset = 0; for (size_t i = 0; i < num_children; i++) { - if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) { - goto err; - } + OPENSSL_memcpy(out + offset, CBS_data(&children[i]), CBS_len(&children[i])); + offset += CBS_len(&children[i]); } - assert(CBB_len(cbb) == buf_len); + assert(offset == buf_len); ret = 1; diff --git a/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c b/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c index df1e4461..b839380a 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c +++ b/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_chacha20poly1305.c @@ -145,7 +145,7 @@ static int chacha20_poly1305_seal_scatter( // encrypted byte-by-byte first. if (extra_in_len) { static const size_t kChaChaBlockSize = 64; - uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + uint32_t block_counter = (uint32_t)(1 + (in_len / kChaChaBlockSize)); size_t offset = in_len % kChaChaBlockSize; uint8_t block[64 /* kChaChaBlockSize */]; diff --git a/Sources/CCryptoBoringSSL/crypto/cpu_aarch64_freebsd.c b/Sources/CCryptoBoringSSL/crypto/cpu_aarch64_freebsd.c new file mode 100644 index 00000000..fd849356 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/cpu_aarch64_freebsd.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FREEBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include + +#include + +extern uint32_t OPENSSL_armcap_P; + +// ID_AA64ISAR0_*_VAL are defined starting FreeBSD 13.0. When FreeBSD +// 12.x is out of support, these compatibility macros can be removed. + +#ifndef ID_AA64ISAR0_AES_VAL +#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES +#endif +#ifndef ID_AA64ISAR0_SHA1_VAL +#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1 +#endif +#ifndef ID_AA64ISAR0_SHA2_VAL +#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2 +#endif + +void OPENSSL_cpuid_setup(void) { + uint64_t id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1); + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) >= ID_AA64ISAR0_AES_BASE) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) >= ID_AA64ISAR0_AES_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA1_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA2_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA2_512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_FREEBSD && !OPENSSL_STATIC_ARMCAP diff --git a/Sources/CCryptoBoringSSL/crypto/cpu_arm_freebsd.c b/Sources/CCryptoBoringSSL/crypto/cpu_arm_freebsd.c new file mode 100644 index 00000000..a5e20777 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/cpu_arm_freebsd.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_ARM) && defined(OPENSSL_FREEBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) +#include +#include + +#include +#include + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = 0, hwcap2 = 0; + + // |elf_aux_info| may fail, in which case |hwcap| and |hwcap2| will be + // left at zero. The rest of this function will then gracefully report + // the features are absent. + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); + + // Matching OpenSSL, only report other features if NEON is present. + if (hwcap & HWCAP_NEON) { + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap2 & HWCAP2_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap2 & HWCAP2_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap2 & HWCAP2_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap2 & HWCAP2_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + } +} + +#endif // OPENSSL_ARM && OPENSSL_OPENBSD && !OPENSSL_STATIC_ARMCAP diff --git a/Sources/CCryptoBoringSSL/crypto/dh_extra/dh_asn1.c b/Sources/CCryptoBoringSSL/crypto/dh_extra/dh_asn1.c index c1b87acf..ef38d71f 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh_extra/dh_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/dh_extra/dh_asn1.c @@ -63,6 +63,7 @@ #include #include "../bytestring/internal.h" +#include "../fipsmodule/dh/internal.h" static int parse_integer(CBS *cbs, BIGNUM **out) { diff --git a/Sources/CCryptoBoringSSL/crypto/dh_extra/params.c b/Sources/CCryptoBoringSSL/crypto/dh_extra/params.c index 370b9d32..2aec8619 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh_extra/params.c +++ b/Sources/CCryptoBoringSSL/crypto/dh_extra/params.c @@ -57,6 +57,7 @@ #include #include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/dh/internal.h" static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, size_t num_words) { @@ -452,23 +453,10 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942) { return 1; } - if (!int_dh_bn_cpy(&to->q, from->q) || - !int_dh_bn_cpy(&to->j, from->j)) { + if (!int_dh_bn_cpy(&to->q, from->q)) { return 0; } - OPENSSL_free(to->seed); - to->seed = NULL; - to->seedlen = 0; - - if (from->seed) { - to->seed = OPENSSL_memdup(from->seed, from->seedlen); - if (!to->seed) { - return 0; - } - to->seedlen = from->seedlen; - } - return 1; } diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.c b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.c index 73401828..081dd807 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.c +++ b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.c @@ -74,6 +74,7 @@ #include "internal.h" #include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/dh/internal.h" #include "../internal.h" @@ -216,16 +217,14 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, BIGNUM *g = NULL, *q = NULL, *p = NULL; BN_MONT_CTX *mont = NULL; int k, n = 0, m = 0; - unsigned i; int counter = 0; int r = 0; BN_CTX *ctx = NULL; unsigned int h = 2; - unsigned qsize; const EVP_MD *evpmd; evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); - qsize = EVP_MD_size(evpmd); + size_t qsize = EVP_MD_size(evpmd); if (bits < 512) { bits = 512; @@ -234,10 +233,10 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, bits = (bits + 63) / 64 * 64; if (seed_in != NULL) { - if (seed_len < (size_t)qsize) { + if (seed_len < qsize) { return 0; } - if (seed_len > (size_t)qsize) { + if (seed_len > qsize) { // Only consume as much seed as is expected. seed_len = qsize; } @@ -283,7 +282,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, OPENSSL_memcpy(buf, seed, qsize); OPENSSL_memcpy(buf2, seed, qsize); // precompute "SEED + 1" for step 7: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; @@ -295,7 +294,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) { goto err; } - for (i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { md[i] ^= buf2[i]; } @@ -339,7 +338,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, // now 'buf' contains "SEED + offset - 1" for (k = 0; k <= n; k++) { // obtain "SEED + offset + k" by incrementing: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; diff --git a/Sources/CCryptoBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c b/Sources/CCryptoBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c index 5c672770..3650858e 100644 --- a/Sources/CCryptoBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/ecdsa_extra/ecdsa_asn1.c @@ -81,13 +81,11 @@ int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, } CBB cbb; - CBB_zero(&cbb); + CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)); size_t len; - if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || - !ECDSA_SIG_marshal(&cbb, s) || + if (!ECDSA_SIG_marshal(&cbb, s) || !CBB_finish(&cbb, NULL, &len)) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); - CBB_cleanup(&cbb); *sig_len = 0; goto err; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp.c b/Sources/CCryptoBoringSSL/crypto/evp/evp.c index cc11af03..9820a05e 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp.c @@ -153,21 +153,24 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (to->type != from->type) { + if (to->type == EVP_PKEY_NONE) { + if (!EVP_PKEY_set_type(to, from->type)) { + return 0; + } + } else if (to->type != from->type) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); - goto err; + return 0; } if (EVP_PKEY_missing_parameters(from)) { OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); - goto err; + return 0; } if (from->ameth && from->ameth->param_copy) { return from->ameth->param_copy(to, from); } -err: return 0; } @@ -448,6 +451,25 @@ void OpenSSL_add_all_digests(void) {} void EVP_cleanup(void) {} +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + if (pkey->ameth->set1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->set1_tls_encodedpoint(pkey, in, len); +} + +size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { + if (pkey->ameth->get1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->get1_tls_encodedpoint(pkey, out_ptr); +} + int EVP_PKEY_base_id(const EVP_PKEY *pkey) { // OpenSSL has two notions of key type because it supports multiple OIDs for // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling diff --git a/Sources/CCryptoBoringSSL/crypto/evp/internal.h b/Sources/CCryptoBoringSSL/crypto/evp/internal.h index 17d6713a..5d2d2925 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/evp/internal.h @@ -103,6 +103,17 @@ struct evp_pkey_asn1_method_st { int (*get_priv_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); int (*get_pub_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); + // TODO(davidben): Can these be merged with the functions above? OpenSSL does + // not implement |EVP_PKEY_get_raw_public_key|, etc., for |EVP_PKEY_EC|, but + // the distinction seems unimportant. OpenSSL 3.0 has since renamed + // |EVP_PKEY_get1_tls_encodedpoint| to |EVP_PKEY_get1_encoded_public_key|, and + // what is the difference between "raw" and an "encoded" public key. + // + // One nuisance is the notion of "raw" is slightly ambiguous for EC keys. Is + // it a DER ECPrivateKey or just the scalar? + int (*set1_tls_encodedpoint)(EVP_PKEY *pkey, const uint8_t *in, size_t len); + size_t (*get1_tls_encodedpoint)(const EVP_PKEY *pkey, uint8_t **out_ptr); + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by // custom implementations which do not expose key material and parameters. int (*pkey_opaque)(const EVP_PKEY *pk); diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.c b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.c index 482469c8..ac1efee0 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.c @@ -248,34 +248,37 @@ static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { - EVP_PKEY_DSA, - // 1.2.840.10040.4.1 - {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, + 7, - NULL /* pkey_method */, + /*pkey_method=*/NULL, - dsa_pub_decode, - dsa_pub_encode, - dsa_pub_cmp, + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, - dsa_priv_decode, - dsa_priv_encode, + dsa_priv_decode, + dsa_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - NULL /* pkey_opaque */, + /*pkey_opaque=*/NULL, - int_dsa_size, - dsa_bits, + int_dsa_size, + dsa_bits, - dsa_missing_parameters, - dsa_copy_parameters, - dsa_cmp_parameters, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, - int_dsa_free, + int_dsa_free, }; int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.c b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.c index 49a708d7..021de4c1 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.c @@ -93,7 +93,6 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 5480, section 2. // The parameters are a named curve. - EC_POINT *point = NULL; EC_KEY *eckey = NULL; EC_GROUP *group = EC_KEY_parse_curve_name(params); if (group == NULL || CBS_len(params) != 0) { @@ -102,25 +101,18 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } eckey = EC_KEY_new(); - if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { - goto err; - } - - point = EC_POINT_new(group); - if (point == NULL || - !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || - !EC_KEY_set_public_key(eckey, point)) { + if (eckey == NULL || // + !EC_KEY_set_group(eckey, group) || + !EC_KEY_oct2key(eckey, CBS_data(key), CBS_len(key), NULL)) { goto err; } EC_GROUP_free(group); - EC_POINT_free(point); EVP_PKEY_assign_EC_KEY(out, eckey); return 1; err: EC_GROUP_free(group); - EC_POINT_free(point); EC_KEY_free(eckey); return 0; } @@ -188,6 +180,28 @@ static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { return 1; } +static int eckey_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + EC_KEY *ec_key = pkey->pkey.ec; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_oct2key(ec_key, in, len, NULL); +} + +static size_t eckey_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const EC_KEY *ec_key = pkey->pkey.ec; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED, out_ptr, NULL); +} + static int int_ec_size(const EVP_PKEY *pkey) { return ECDSA_size(pkey->pkey.ec); } @@ -206,7 +220,22 @@ static int ec_missing_parameters(const EVP_PKEY *pkey) { } static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); + if (from->pkey.ec == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + const EC_GROUP *group = EC_KEY_get0_group(from->pkey.ec); + if (group == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + if (to->pkey.ec == NULL) { + to->pkey.ec = EC_KEY_new(); + if (to->pkey.ec == NULL) { + return 0; + } + } + return EC_KEY_set_group(to->pkey.ec, group); } static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { @@ -226,32 +255,35 @@ static int eckey_opaque(const EVP_PKEY *pkey) { } const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { - EVP_PKEY_EC, - // 1.2.840.10045.2.1 - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, + 7, - &ec_pkey_meth, + &ec_pkey_meth, - eckey_pub_decode, - eckey_pub_encode, - eckey_pub_cmp, + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, - eckey_priv_decode, - eckey_priv_encode, + eckey_priv_decode, + eckey_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + eckey_set1_tls_encodedpoint, + eckey_get1_tls_encodedpoint, - eckey_opaque, + eckey_opaque, - int_ec_size, - ec_bits, + int_ec_size, + ec_bits, - ec_missing_parameters, - ec_copy_parameters, - ec_cmp_parameters, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, - int_ec_free, + int_ec_free, }; diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.c b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.c index cfec4d26..6c54d890 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.c @@ -214,11 +214,13 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ed25519_set_pub_raw, ed25519_get_priv_raw, ed25519_get_pub_raw, - NULL /* pkey_opaque */, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, + /*pkey_opaque=*/NULL, ed25519_size, ed25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, ed25519_free, }; diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.c b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.c index a7aa47dd..a38f54da 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.c @@ -167,30 +167,35 @@ static int rsa_bits(const EVP_PKEY *pkey) { static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { - EVP_PKEY_RSA, - // 1.2.840.113549.1.1.1 - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, + 9, - &rsa_pkey_meth, + &rsa_pkey_meth, - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, - rsa_priv_decode, - rsa_priv_encode, + rsa_priv_decode, + rsa_priv_encode, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - rsa_opaque, + rsa_opaque, - int_rsa_size, - rsa_bits, + int_rsa_size, + rsa_bits, - 0,0,0, + 0, + 0, + 0, - int_rsa_free, + int_rsa_free, }; diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.c b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.c index f48737e7..4bd1c501 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.c @@ -110,6 +110,23 @@ static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 1; } +static int x25519_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + return x25519_set_pub_raw(pkey, in, len); +} + +static size_t x25519_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const X25519_KEY *key = pkey->pkey.ptr; + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + *out_ptr = OPENSSL_memdup(key->pub, 32); + return *out_ptr == NULL ? 0 : 32; +} + static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 8410, section 4. @@ -209,41 +226,13 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { x25519_set_pub_raw, x25519_get_priv_raw, x25519_get_pub_raw, - NULL /* pkey_opaque */, + x25519_set1_tls_encodedpoint, + x25519_get1_tls_encodedpoint, + /*pkey_opaque=*/NULL, x25519_size, x25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, x25519_free, }; - -int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, - size_t len) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - return x25519_set_pub_raw(pkey, in, len); -} - -size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - const X25519_KEY *key = pkey->pkey.ptr; - if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); - return 0; - } - - *out_ptr = OPENSSL_memdup(key->pub, 32); - return *out_ptr == NULL ? 0 : 32; -} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/print.c b/Sources/CCryptoBoringSSL/crypto/evp/print.c index 1c97a531..63ee956c 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/print.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/print.c @@ -64,8 +64,25 @@ #include "../fipsmodule/rsa/internal.h" -static int bn_print(BIO *bp, const char *number, const BIGNUM *num, - uint8_t *buf, int off) { +static int print_hex(BIO *bp, const uint8_t *data, size_t len, int off) { + for (size_t i = 0; i < len; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 || // + !BIO_indent(bp, off + 4, 128)) { + return 0; + } + } + if (BIO_printf(bp, "%02x%s", data[i], (i + 1 == len) ? "" : ":") <= 0) { + return 0; + } + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + return 1; +} + +static int bn_print(BIO *bp, const char *name, const BIGNUM *num, int off) { if (num == NULL) { return 1; } @@ -74,140 +91,101 @@ static int bn_print(BIO *bp, const char *number, const BIGNUM *num, return 0; } if (BN_is_zero(num)) { - if (BIO_printf(bp, "%s 0\n", number) <= 0) { + if (BIO_printf(bp, "%s 0\n", name) <= 0) { return 0; } return 1; } - if (BN_num_bytes(num) <= sizeof(long)) { + uint64_t u64; + if (BN_get_u64(num, &u64)) { const char *neg = BN_is_negative(num) ? "-" : ""; - if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, - (unsigned long)num->d[0], neg, - (unsigned long)num->d[0]) <= 0) { - return 0; - } - } else { - buf[0] = 0; - if (BIO_printf(bp, "%s%s", number, - (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { - return 0; - } - int n = BN_bn2bin(num, &buf[1]); - - if (buf[1] & 0x80) { - n++; - } else { - buf++; - } + return BIO_printf(bp, "%s %s%" PRIu64 " (%s0x%" PRIx64 ")\n", name, neg, + u64, neg, u64) > 0; + } - int i; - for (i = 0; i < n; i++) { - if ((i % 15) == 0) { - if (BIO_puts(bp, "\n") <= 0 || - !BIO_indent(bp, off + 4, 128)) { - return 0; - } - } - if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) { - return 0; - } - } - if (BIO_write(bp, "\n", 1) <= 0) { - return 0; - } + if (BIO_printf(bp, "%s%s", name, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; } - return 1; -} -static void update_buflen(const BIGNUM *b, size_t *pbuflen) { - if (!b) { - return; + // Print |num| in hex, adding a leading zero, as in ASN.1, if the high bit + // is set. + // + // TODO(davidben): Do we need to do this? We already print "(Negative)" above + // and negative values are never valid in keys anyway. + size_t len = BN_num_bytes(num); + uint8_t *buf = OPENSSL_malloc(len + 1); + if (buf == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; } - size_t len = BN_num_bytes(b); - if (*pbuflen < len) { - *pbuflen = len; + buf[0] = 0; + BN_bn2bin(num, buf + 1); + int ret; + if (len > 0 && (buf[1] & 0x80) != 0) { + // Print the whole buffer. + ret = print_hex(bp, buf, len + 1, off); + } else { + // Skip the leading zero. + ret = print_hex(bp, buf + 1, len, off); } + OPENSSL_free(buf); + return ret; } // RSA keys. static int do_rsa_print(BIO *out, const RSA *rsa, int off, int include_private) { - const char *s, *str; - uint8_t *m = NULL; - int ret = 0, mod_len = 0; - size_t buf_len = 0; - - update_buflen(rsa->n, &buf_len); - update_buflen(rsa->e, &buf_len); - - if (include_private) { - update_buflen(rsa->d, &buf_len); - update_buflen(rsa->p, &buf_len); - update_buflen(rsa->q, &buf_len); - update_buflen(rsa->dmp1, &buf_len); - update_buflen(rsa->dmq1, &buf_len); - update_buflen(rsa->iqmp, &buf_len); - } - - m = (uint8_t *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); - goto err; - } - + int mod_len = 0; if (rsa->n != NULL) { mod_len = BN_num_bits(rsa->n); } if (!BIO_indent(out, off, 128)) { - goto err; + return 0; } + const char *s, *str; if (include_private && rsa->d) { if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "modulus:"; s = "publicExponent:"; } else { if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "Modulus:"; s = "Exponent:"; } - if (!bn_print(out, str, rsa->n, m, off) || - !bn_print(out, s, rsa->e, m, off)) { - goto err; + if (!bn_print(out, str, rsa->n, off) || + !bn_print(out, s, rsa->e, off)) { + return 0; } if (include_private) { - if (!bn_print(out, "privateExponent:", rsa->d, m, off) || - !bn_print(out, "prime1:", rsa->p, m, off) || - !bn_print(out, "prime2:", rsa->q, m, off) || - !bn_print(out, "exponent1:", rsa->dmp1, m, off) || - !bn_print(out, "exponent2:", rsa->dmq1, m, off) || - !bn_print(out, "coefficient:", rsa->iqmp, m, off)) { - goto err; + if (!bn_print(out, "privateExponent:", rsa->d, off) || + !bn_print(out, "prime1:", rsa->p, off) || + !bn_print(out, "prime2:", rsa->q, off) || + !bn_print(out, "exponent1:", rsa->dmp1, off) || + !bn_print(out, "exponent2:", rsa->dmq1, off) || + !bn_print(out, "coefficient:", rsa->iqmp, off)) { + return 0; } } - ret = 1; -err: - OPENSSL_free(m); - return ret; + return 1; } -static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); } -static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); } @@ -215,75 +193,47 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, // DSA keys. static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { - uint8_t *m = NULL; - int ret = 0; - size_t buf_len = 0; - const char *ktype = NULL; - - const BIGNUM *priv_key, *pub_key; - - priv_key = NULL; + const BIGNUM *priv_key = NULL; if (ptype == 2) { priv_key = x->priv_key; } - pub_key = NULL; + const BIGNUM *pub_key = NULL; if (ptype > 0) { pub_key = x->pub_key; } - ktype = "DSA-Parameters"; + const char *ktype = "DSA-Parameters"; if (ptype == 2) { ktype = "Private-Key"; } else if (ptype == 1) { ktype = "Public-Key"; } - update_buflen(x->p, &buf_len); - update_buflen(x->q, &buf_len); - update_buflen(x->g, &buf_len); - update_buflen(priv_key, &buf_len); - update_buflen(pub_key, &buf_len); - - m = (uint8_t *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (priv_key) { - if (!BIO_indent(bp, off, 128) || - BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(x->p)) <= 0) { - goto err; - } - } - - if (!bn_print(bp, "priv:", priv_key, m, off) || - !bn_print(bp, "pub: ", pub_key, m, off) || - !bn_print(bp, "P: ", x->p, m, off) || - !bn_print(bp, "Q: ", x->q, m, off) || - !bn_print(bp, "G: ", x->g, m, off)) { - goto err; + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(x->p)) <= 0 || + // |priv_key| and |pub_key| may be NULL, in which case |bn_print| will + // silently skip them. + !bn_print(bp, "priv:", priv_key, off) || + !bn_print(bp, "pub:", pub_key, off) || + !bn_print(bp, "P:", x->p, off) || + !bn_print(bp, "Q:", x->q, off) || + !bn_print(bp, "G:", x->g, off)) { + return 0; } - ret = 1; -err: - OPENSSL_free(m); - return ret; + return 1; } -static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); } -static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); } -static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); } @@ -291,70 +241,13 @@ static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, // EC keys. static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { - uint8_t *buffer = NULL; - const char *ecstr; - size_t buf_len = 0, i; - int ret = 0, reason = ERR_R_BIO_LIB; - BIGNUM *order = NULL; - BN_CTX *ctx = NULL; const EC_GROUP *group; - const EC_POINT *public_key; - const BIGNUM *priv_key; - uint8_t *pub_key_bytes = NULL; - size_t pub_key_bytes_len = 0; - if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (ktype > 0) { - public_key = EC_KEY_get0_public_key(x); - if (public_key != NULL) { - pub_key_bytes_len = EC_POINT_point2oct( - group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); - if (pub_key_bytes == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - pub_key_bytes_len = - EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), - pub_key_bytes, pub_key_bytes_len, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - buf_len = pub_key_bytes_len; - } - } - - if (ktype == 2) { - priv_key = EC_KEY_get0_private_key(x); - if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) { - buf_len = i; - } - } else { - priv_key = NULL; + OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - if (ktype > 0) { - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - } + const char *ecstr; if (ktype == 2) { ecstr = "Private-Key"; } else if (ktype == 1) { @@ -364,62 +257,61 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { } if (!BIO_indent(bp, off, 128)) { - goto err; + return 0; } - order = BN_new(); - if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || - BIO_printf(bp, "%s: (%u bit)\n", ecstr, BN_num_bits(order)) <= 0) { - goto err; + int curve_name = EC_GROUP_get_curve_name(group); + if (BIO_printf(bp, "%s: (%s)\n", ecstr, + curve_name == NID_undef + ? "unknown curve" + : EC_curve_nid2nist(curve_name)) <= 0) { + return 0; } - if ((priv_key != NULL) && - !bn_print(bp, "priv:", priv_key, buffer, off)) { - goto err; - } - if (pub_key_bytes != NULL) { - BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); + if (ktype == 2) { + const BIGNUM *priv_key = EC_KEY_get0_private_key(x); + if (priv_key != NULL && // + !bn_print(bp, "priv:", priv_key, off)) { + return 0; + } } - // TODO(fork): implement - /* - if (!ECPKParameters_print(bp, group, off)) - goto err; */ - ret = 1; - -err: - if (!ret) { - OPENSSL_PUT_ERROR(EVP, reason); + + if (ktype > 0 && EC_KEY_get0_public_key(x) != NULL) { + uint8_t *pub = NULL; + size_t pub_len = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL); + if (pub_len == 0) { + return 0; + } + int ret = BIO_indent(bp, off, 128) && // + BIO_puts(bp, "pub:") > 0 && // + print_hex(bp, pub, pub_len, off); + OPENSSL_free(pub); + if (!ret) { + return 0; + } } - OPENSSL_free(pub_key_bytes); - BN_free(order); - BN_CTX_free(ctx); - OPENSSL_free(buffer); - return ret; + + return 1; } -static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); } -static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); } -static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); } typedef struct { int type; - int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); - int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent); } EVP_PKEY_PRINT_METHOD; static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { @@ -465,7 +357,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); if (method != NULL && method->pub_print != NULL) { - return method->pub_print(out, pkey, indent, pctx); + return method->pub_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Public Key"); } @@ -474,7 +366,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); if (method != NULL && method->priv_print != NULL) { - return method->priv_print(out, pkey, indent, pctx); + return method->priv_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Private Key"); } @@ -483,7 +375,7 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); if (method != NULL && method->param_print != NULL) { - return method->param_print(out, pkey, indent, pctx); + return method->param_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Parameters"); } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/sign.c b/Sources/CCryptoBoringSSL/crypto/evp/sign.c index b7bacb3d..a8bb181a 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/sign.c +++ b/Sources/CCryptoBoringSSL/crypto/evp/sign.c @@ -56,6 +56,8 @@ #include +#include + #include #include @@ -74,15 +76,20 @@ int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { return EVP_DigestUpdate(ctx, data, len); } -int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, - unsigned int *out_sig_len, EVP_PKEY *pkey) { +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, unsigned *out_sig_len, + EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; size_t sig_len = EVP_PKEY_size(pkey); + // Ensure the final result will fit in |unsigned|. + if (sig_len > UINT_MAX) { + sig_len = UINT_MAX; + } + *out_sig_len = 0; EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || @@ -92,19 +99,17 @@ int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, EVP_MD_CTX_cleanup(&tmp_ctx); pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + if (!pkctx || // + !EVP_PKEY_sign_init(pkctx) || !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { goto out; } - *out_sig_len = sig_len; + *out_sig_len = (unsigned)sig_len; ret = 1; out: - if (pkctx) { - EVP_PKEY_CTX_free(pkctx); - } - + EVP_PKEY_CTX_free(pkctx); return ret; } @@ -123,7 +128,7 @@ int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/check.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/check.c index 757850f4..79efd2dd 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/check.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/check.c @@ -58,6 +58,8 @@ #include +#include "internal.h" + int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) { *out_flags = 0; @@ -165,9 +167,6 @@ int DH_check(const DH *dh, int *out_flags) { if (!BN_is_one(t2)) { *out_flags |= DH_CHECK_INVALID_Q_VALUE; } - if (dh->j && BN_cmp(dh->j, t1)) { - *out_flags |= DH_CHECK_INVALID_J_VALUE; - } } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { l = BN_mod_word(dh->p, 24); if (l == (BN_ULONG)-1) { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.c index d1b4820f..a542c6f4 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.c @@ -101,9 +101,6 @@ void DH_free(DH *dh) { BN_clear_free(dh->p); BN_clear_free(dh->g); BN_clear_free(dh->q); - BN_clear_free(dh->j); - OPENSSL_free(dh->seed); - BN_clear_free(dh->counter); BN_clear_free(dh->pub_key); BN_clear_free(dh->priv_key); CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h index fd56c83c..54542066 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h @@ -17,11 +17,31 @@ #include +#include + #if defined(__cplusplus) extern "C" { #endif +struct dh_st { + BIGNUM *p; + BIGNUM *g; + BIGNUM *q; + BIGNUM *pub_key; // g^x mod p + BIGNUM *priv_key; // x + + // priv_length contains the length, in bits, of the private value. If zero, + // the private value will be the same length as |p|. + unsigned priv_length; + + CRYPTO_MUTEX method_mont_p_lock; + BN_MONT_CTX *method_mont_p; + + int flags; + CRYPTO_refcount_t references; +}; + // dh_compute_key_padded_no_self_test does the same as |DH_compute_key_padded|, // but doesn't try to run the self-test first. This is for use in the self tests // themselves, to prevent an infinite loop. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c index a0e08f01..1fbe60c2 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c @@ -394,25 +394,85 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, return ok; } +int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, BN_CTX *ctx) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + EC_POINT *point = EC_POINT_new(key->group); + int ok = point != NULL && + EC_POINT_oct2point(key->group, point, in, len, ctx) && + EC_KEY_set_public_key(key, point); + EC_POINT_free(point); + return ok; +} + size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx) { + uint8_t **out_buf, BN_CTX *ctx) { if (key == NULL || key->pub_key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); return 0; } - const size_t len = - EC_POINT_point2oct(key->group, key->pub_key, form, NULL, 0, ctx); + return EC_POINT_point2buf(key->group, key->pub_key, form, out_buf, ctx); +} + +int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (len != BN_num_bytes(EC_GROUP_get0_order(key->group))) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + BIGNUM *priv_key = BN_bin2bn(in, len, NULL); + int ok = priv_key != NULL && // + EC_KEY_set_private_key(key, priv_key); + BN_free(priv_key); + return ok; +} + +size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, size_t max_out) { + if (key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + size_t len = BN_num_bytes(EC_GROUP_get0_order(key->group)); + if (out == NULL) { + return len; + } + + if (max_out < len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + size_t bytes_written; + ec_scalar_to_bytes(key->group, out, &bytes_written, &key->priv_key->scalar); + assert(bytes_written == len); + return len; +} + +size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf) { + *out_buf = NULL; + size_t len = EC_KEY_priv2oct(key, NULL, 0); if (len == 0) { return 0; } uint8_t *buf = OPENSSL_malloc(len); if (buf == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return 0; } - if (EC_POINT_point2oct(key->group, key->pub_key, form, buf, len, ctx) != - len) { + len = EC_KEY_priv2oct(key, buf, len); + if (len == 0) { OPENSSL_free(buf); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/internal.h index 70828df6..a757ada0 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/internal.h @@ -439,11 +439,18 @@ int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, size_t max_out, const EC_RAW_POINT *p); -// ec_point_to_bytes behaves like |EC_POINT_point2oct| but takes an -// |EC_AFFINE|. +// ec_point_byte_len returns the number of bytes in the byte representation of +// a non-infinity point in |group|, encoded according to |form|, or zero if +// |form| is invalid. +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form); + +// ec_point_to_bytes encodes |point| according to |form| and writes the result +// |buf|. It returns the size of the output on success or zero on error. At most +// |max_out| bytes will be written. The buffer should be at least +// |ec_point_byte_len| long to guarantee success. size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, point_conversion_form_t form, uint8_t *buf, - size_t len); + size_t max_out); // ec_point_from_uncompressed parses |in| as a point in uncompressed form and // sets the result to |out|. It returns one on success and zero if the input was diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.c index 993c7ec7..43641617 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.c @@ -73,9 +73,7 @@ #include "internal.h" -size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, - point_conversion_form_t form, uint8_t *buf, - size_t len) { +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form) { if (form != POINT_CONVERSION_COMPRESSED && form != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); @@ -88,27 +86,30 @@ size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, // Uncompressed points have a second coordinate. output_len += field_len; } + return output_len; +} - // if 'buf' is NULL, just return required length - if (buf != NULL) { - if (len < output_len) { - OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); - return 0; - } +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, + point_conversion_form_t form, uint8_t *buf, + size_t max_out) { + size_t output_len = ec_point_byte_len(group, form); + if (max_out < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } - size_t field_len_out; - ec_felem_to_bytes(group, buf + 1, &field_len_out, &point->X); - assert(field_len_out == field_len); + size_t field_len; + ec_felem_to_bytes(group, buf + 1, &field_len, &point->X); + assert(field_len == BN_num_bytes(&group->field)); - if (form == POINT_CONVERSION_UNCOMPRESSED) { - ec_felem_to_bytes(group, buf + 1 + field_len, &field_len_out, &point->Y); - assert(field_len_out == field_len); - buf[0] = form; - } else { - uint8_t y_buf[EC_MAX_BYTES]; - ec_felem_to_bytes(group, y_buf, &field_len_out, &point->Y); - buf[0] = form + (y_buf[field_len_out - 1] & 1); - } + if (form == POINT_CONVERSION_UNCOMPRESSED) { + ec_felem_to_bytes(group, buf + 1 + field_len, &field_len, &point->Y); + assert(field_len == BN_num_bytes(&group->field)); + buf[0] = form; + } else { + uint8_t y_buf[EC_MAX_BYTES]; + ec_felem_to_bytes(group, y_buf, &field_len, &point->Y); + buf[0] = form + (y_buf[field_len - 1] & 1); } return output_len; @@ -209,16 +210,47 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, uint8_t *buf, - size_t len, BN_CTX *ctx) { + size_t max_out, BN_CTX *ctx) { if (EC_GROUP_cmp(group, point->group, NULL) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } + if (buf == NULL) { + // When |buf| is NULL, just return the number of bytes that would be + // written, without doing an expensive Jacobian-to-affine conversion. + if (ec_GFp_simple_is_at_infinity(group, &point->raw)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + return ec_point_byte_len(group, form); + } EC_AFFINE affine; if (!ec_jacobian_to_affine(group, &affine, &point->raw)) { return 0; } - return ec_point_to_bytes(group, &affine, form, buf, len); + return ec_point_to_bytes(group, &affine, form, buf, max_out); +} + +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t **out_buf, + BN_CTX *ctx) { + *out_buf = NULL; + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *buf = OPENSSL_malloc(len); + if (buf == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + len = EC_POINT_point2oct(group, point, form, buf, len, ctx); + if (len == 0) { + OPENSSL_free(buf); + return 0; + } + *out_buf = buf; + return len; } int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S b/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S index e7db10ff..304e10bf 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.ios.aarch64.S @@ -1404,7 +1404,7 @@ _ecp_nistz256_ord_mul_mont: //////////////////////////////////////////////////////////////////////// // void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -// int rep); +// uint64_t rep); .globl _ecp_nistz256_ord_sqr_mont .private_extern _ecp_nistz256_ord_sqr_mont diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S b/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S index 5aff65a9..6b48dee7 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/p256-armv8-asm.linux.aarch64.S @@ -1405,7 +1405,7 @@ ecp_nistz256_ord_mul_mont: //////////////////////////////////////////////////////////////////////// // void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -// int rep); +// uint64_t rep); .globl ecp_nistz256_ord_sqr_mont .hidden ecp_nistz256_ord_sqr_mont .type ecp_nistz256_ord_sqr_mont,%function diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/internal.h index 9e097c40..11980904 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/internal.h @@ -142,7 +142,7 @@ int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, size_t in_len, int padding); int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, - unsigned digest_len, uint8_t *out, unsigned *out_len, + size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c index 6b525b21..44cb0300 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c @@ -56,6 +56,7 @@ #include +#include #include #include @@ -470,18 +471,43 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { }, }; -int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, - int *is_alloced, int hash_nid, const uint8_t *digest, - size_t digest_len) { +static int rsa_check_digest_size(int hash_nid, size_t digest_len) { if (hash_nid == NID_md5_sha1) { - // Special case: SSL signature, just check the length. if (digest_len != SSL_SIG_LENGTH) { OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } + return 1; + } + + for (size_t i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; + if (sig_prefix->nid == hash_nid) { + if (digest_len != sig_prefix->hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + return 1; + } + } + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + +} + +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *digest, + size_t digest_len) { + if (!rsa_check_digest_size(hash_nid, digest_len)) { + return 0; + } + + if (hash_nid == NID_md5_sha1) { + // The length should already have been checked. + assert(digest_len == SSL_SIG_LENGTH); *out_msg = (uint8_t *)digest; - *out_msg_len = SSL_SIG_LENGTH; + *out_msg_len = digest_len; *is_alloced = 0; return 1; } @@ -492,11 +518,8 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, continue; } - if (digest_len != sig_prefix->hash_len) { - OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); - return 0; - } - + // The length should already have been checked. + assert(digest_len == sig_prefix->hash_len); const uint8_t* prefix = sig_prefix->bytes; size_t prefix_len = sig_prefix->len; size_t signed_msg_len = prefix_len + digest_len; @@ -526,19 +549,25 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, } int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, - unsigned digest_len, uint8_t *out, unsigned *out_len, + size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa) { + if (rsa->meth->sign) { + if (!rsa_check_digest_size(hash_nid, digest_len)) { + return 0; + } + // All supported digest lengths fit in |unsigned|. + assert(digest_len <= EVP_MAX_MD_SIZE); + static_assert(EVP_MAX_MD_SIZE <= UINT_MAX, "digest too long"); + return rsa->meth->sign(hash_nid, digest, (unsigned)digest_len, out, out_len, + rsa); + } + const unsigned rsa_size = RSA_size(rsa); int ret = 0; uint8_t *signed_msg = NULL; size_t signed_msg_len = 0; int signed_msg_is_alloced = 0; size_t size_t_out_len; - - if (rsa->meth->sign) { - return rsa->meth->sign(hash_nid, digest, digest_len, out, out_len, rsa); - } - if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, hash_nid, digest, digest_len) || @@ -563,7 +592,7 @@ int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, return ret; } -int RSA_sign(int hash_nid, const uint8_t *digest, unsigned digest_len, +int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa) { boringssl_ensure_rsa_self_test(); diff --git a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.c b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.c index fb352fc2..6c012aae 100644 --- a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.c +++ b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.c @@ -228,6 +228,14 @@ const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void) { uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem) { return kem->id; } +size_t EVP_HPKE_KEM_public_key_len(const EVP_HPKE_KEM *kem) { + return kem->public_key_len; +} + +size_t EVP_HPKE_KEM_private_key_len(const EVP_HPKE_KEM *kem) { + return kem->private_key_len; +} + size_t EVP_HPKE_KEM_enc_len(const EVP_HPKE_KEM *kem) { return kem->enc_len; } void EVP_HPKE_KEY_zero(EVP_HPKE_KEY *key) { @@ -358,13 +366,11 @@ const EVP_AEAD *EVP_HPKE_AEAD_aead(const EVP_HPKE_AEAD *aead) { static int hpke_build_suite_id(const EVP_HPKE_CTX *ctx, uint8_t out[HPKE_SUITE_ID_LEN]) { CBB cbb; - int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) && - add_label_string(&cbb, "HPKE") && // - CBB_add_u16(&cbb, ctx->kem->id) && // - CBB_add_u16(&cbb, ctx->kdf->id) && // - CBB_add_u16(&cbb, ctx->aead->id); - CBB_cleanup(&cbb); - return ret; + CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN); + return add_label_string(&cbb, "HPKE") && // + CBB_add_u16(&cbb, ctx->kem->id) && // + CBB_add_u16(&cbb, ctx->kdf->id) && // + CBB_add_u16(&cbb, ctx->aead->id); } #define HPKE_MODE_BASE 0 @@ -401,8 +407,8 @@ static int hpke_key_schedule(EVP_HPKE_CTX *ctx, const uint8_t *shared_secret, uint8_t context[sizeof(uint8_t) + 2 * EVP_MAX_MD_SIZE]; size_t context_len; CBB context_cbb; - if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) || - !CBB_add_u8(&context_cbb, HPKE_MODE_BASE) || + CBB_init_fixed(&context_cbb, context, sizeof(context)); + if (!CBB_add_u8(&context_cbb, HPKE_MODE_BASE) || !CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) || !CBB_add_bytes(&context_cbb, info_hash, info_hash_len) || !CBB_finish(&context_cbb, NULL, &context_len)) { diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.c b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.c index f3e9fc7c..69fbb5e7 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.c +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.c @@ -123,8 +123,7 @@ static int derive_scalar_from_secret(const PMBTOKEN_METHOD *method, static int point_to_cbb(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); if (len == 0) { return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.c b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.c index 8afa8ce2..ce3329d4 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.c +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.c @@ -113,34 +113,26 @@ int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method, size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id) { // Prepend the key ID in front of the PMBTokens format. - int ret = 0; CBB priv_cbb, pub_cbb; - CBB_zero(&priv_cbb); - CBB_zero(&pub_cbb); - if (!CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len) || - !CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len) || - !CBB_add_u32(&priv_cbb, id) || + CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len); + CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len); + if (!CBB_add_u32(&priv_cbb, id) || // !CBB_add_u32(&pub_cbb, id)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } if (!method->generate_key(&priv_cbb, &pub_cbb)) { - goto err; + return 0; } if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) || !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } - ret = 1; - -err: - CBB_cleanup(&priv_cbb); - CBB_cleanup(&pub_cbb); - return ret; + return 1; } int TRUST_TOKEN_derive_key_from_secret( @@ -149,35 +141,27 @@ int TRUST_TOKEN_derive_key_from_secret( size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id, const uint8_t *secret, size_t secret_len) { // Prepend the key ID in front of the PMBTokens format. - int ret = 0; CBB priv_cbb, pub_cbb; - CBB_zero(&priv_cbb); - CBB_zero(&pub_cbb); - if (!CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len) || - !CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len) || - !CBB_add_u32(&priv_cbb, id) || + CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len); + CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len); + if (!CBB_add_u32(&priv_cbb, id) || // !CBB_add_u32(&pub_cbb, id)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret, secret_len)) { - goto err; + return 0; } if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) || !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } - ret = 1; - -err: - CBB_cleanup(&priv_cbb); - CBB_cleanup(&pub_cbb); - return ret; + return 1; } TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, @@ -628,22 +612,21 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type, uint64_t value) { if (value <= 23) { - return CBB_add_u8(cbb, value | major_type); + return CBB_add_u8(cbb, (uint8_t)value | major_type); } if (value <= 0xff) { - return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value); + return CBB_add_u8(cbb, 0x18 | major_type) && + CBB_add_u8(cbb, (uint8_t)value); } if (value <= 0xffff) { - return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value); + return CBB_add_u8(cbb, 0x19 | major_type) && + CBB_add_u16(cbb, (uint16_t)value); } if (value <= 0xffffffff) { - return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value); + return CBB_add_u8(cbb, 0x1a | major_type) && + CBB_add_u32(cbb, (uint32_t)value); } - if (value <= 0xffffffffffffffff) { - return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value); - } - - return 0; + return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value); } // https://tools.ietf.org/html/rfc7049#section-2.1 diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.c b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.c index e20c16ad..d64497d2 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.c +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.c @@ -62,8 +62,7 @@ static int voprf_init_method(VOPRF_METHOD *method, int curve_nid, static int cbb_add_point(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); if (len == 0) { return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.c b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.c index af74f1c8..e0f24618 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.c +++ b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.c @@ -202,7 +202,7 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } - int md_len = EVP_MD_size(sigmd); + int md_len = (int)EVP_MD_size(sigmd); if (saltlen == -1) { saltlen = md_len; } else if (saltlen != md_len) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_all.c b/Sources/CCryptoBoringSSL/crypto/x509/x_all.c index bdd3ed44..7381a564 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_all.c +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_all.c @@ -96,11 +96,13 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) { } int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { + x->req_info->enc.modified = 1; return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, x->signature, x->req_info, pkey, md)); } int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { + x->req_info->enc.modified = 1; return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, x->signature, x->req_info, ctx); } diff --git a/Sources/CCryptoBoringSSL/hash.txt b/Sources/CCryptoBoringSSL/hash.txt index 4b06eeff..30fafa95 100644 --- a/Sources/CCryptoBoringSSL/hash.txt +++ b/Sources/CCryptoBoringSSL/hash.txt @@ -1 +1 @@ -This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision cab31f65f1ad6e6daca62e95b25dd6cd805fce0b +This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 0faffc7a30eeb195248ea43056f4848e2a9b1c6d diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bio.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bio.h index e2c40b2b..7b565a9e 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bio.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bio.h @@ -328,7 +328,7 @@ OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); // BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented -// by |indent| spaces. +// by |indent| spaces. It returns one on success and zero otherwise. OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h index 4d985dae..d9955310 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h @@ -467,9 +467,11 @@ #define CBB_add_asn1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1) #define CBB_add_asn1_bool BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_bool) #define CBB_add_asn1_int64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_int64) +#define CBB_add_asn1_int64_with_tag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_int64_with_tag) #define CBB_add_asn1_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_octet_string) #define CBB_add_asn1_oid_from_text BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_oid_from_text) #define CBB_add_asn1_uint64 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_uint64) +#define CBB_add_asn1_uint64_with_tag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_asn1_uint64_with_tag) #define CBB_add_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_bytes) #define CBB_add_space BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_space) #define CBB_add_u16 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CBB_add_u16) @@ -815,9 +817,13 @@ #define EC_KEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new) #define EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) #define EC_KEY_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_method) +#define EC_KEY_oct2key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2key) +#define EC_KEY_oct2priv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2priv) #define EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) #define EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_parameters) #define EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define EC_KEY_priv2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2buf) +#define EC_KEY_priv2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2oct) #define EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) #define EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_conv_form) #define EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) @@ -843,6 +849,7 @@ #define EC_POINT_mul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_mul) #define EC_POINT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_new) #define EC_POINT_oct2point BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define EC_POINT_point2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2buf) #define EC_POINT_point2cbb BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2cbb) #define EC_POINT_point2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_point2oct) #define EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) @@ -1011,6 +1018,8 @@ #define EVP_HPKE_KDF_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KDF_id) #define EVP_HPKE_KEM_enc_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEM_enc_len) #define EVP_HPKE_KEM_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEM_id) +#define EVP_HPKE_KEM_private_key_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEM_private_key_len) +#define EVP_HPKE_KEM_public_key_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEM_public_key_len) #define EVP_HPKE_KEY_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_cleanup) #define EVP_HPKE_KEY_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_copy) #define EVP_HPKE_KEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_free) @@ -1691,7 +1700,6 @@ #define USERNOTICE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_free) #define USERNOTICE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_it) #define USERNOTICE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, USERNOTICE_new) -#define UTF8_putc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, UTF8_putc) #define X25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519) #define X25519_keypair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_keypair) #define X25519_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_public_from_private) @@ -2538,6 +2546,7 @@ #define ec_jacobian_to_affine BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine) #define ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) #define ec_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_pkey_meth) +#define ec_point_byte_len BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_byte_len) #define ec_point_from_uncompressed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_from_uncompressed) #define ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_no_self_test) #define ec_point_mul_scalar BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_point_mul_scalar) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h index d3433174..e0a0d28d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h @@ -472,9 +472,11 @@ #define _CBB_add_asn1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1) #define _CBB_add_asn1_bool BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_bool) #define _CBB_add_asn1_int64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_int64) +#define _CBB_add_asn1_int64_with_tag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_int64_with_tag) #define _CBB_add_asn1_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_octet_string) #define _CBB_add_asn1_oid_from_text BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_oid_from_text) #define _CBB_add_asn1_uint64 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_uint64) +#define _CBB_add_asn1_uint64_with_tag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_asn1_uint64_with_tag) #define _CBB_add_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_bytes) #define _CBB_add_space BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_space) #define _CBB_add_u16 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CBB_add_u16) @@ -820,9 +822,13 @@ #define _EC_KEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new) #define _EC_KEY_new_by_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_by_curve_name) #define _EC_KEY_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_method) +#define _EC_KEY_oct2key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2key) +#define _EC_KEY_oct2priv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2priv) #define _EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) #define _EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_parameters) #define _EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_private_key) +#define _EC_KEY_priv2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2buf) +#define _EC_KEY_priv2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2oct) #define _EC_KEY_set_asn1_flag BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_asn1_flag) #define _EC_KEY_set_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_conv_form) #define _EC_KEY_set_enc_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_set_enc_flags) @@ -848,6 +854,7 @@ #define _EC_POINT_mul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_mul) #define _EC_POINT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_new) #define _EC_POINT_oct2point BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_oct2point) +#define _EC_POINT_point2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2buf) #define _EC_POINT_point2cbb BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2cbb) #define _EC_POINT_point2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_point2oct) #define _EC_POINT_set_affine_coordinates BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_POINT_set_affine_coordinates) @@ -1016,6 +1023,8 @@ #define _EVP_HPKE_KDF_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KDF_id) #define _EVP_HPKE_KEM_enc_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEM_enc_len) #define _EVP_HPKE_KEM_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEM_id) +#define _EVP_HPKE_KEM_private_key_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEM_private_key_len) +#define _EVP_HPKE_KEM_public_key_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEM_public_key_len) #define _EVP_HPKE_KEY_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_cleanup) #define _EVP_HPKE_KEY_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_copy) #define _EVP_HPKE_KEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_free) @@ -1696,7 +1705,6 @@ #define _USERNOTICE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_free) #define _USERNOTICE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_it) #define _USERNOTICE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, USERNOTICE_new) -#define _UTF8_putc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, UTF8_putc) #define _X25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519) #define _X25519_keypair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_keypair) #define _X25519_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_public_from_private) @@ -2543,6 +2551,7 @@ #define _ec_jacobian_to_affine BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine) #define _ec_jacobian_to_affine_batch BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_jacobian_to_affine_batch) #define _ec_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_pkey_meth) +#define _ec_point_byte_len BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_byte_len) #define _ec_point_from_uncompressed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_from_uncompressed) #define _ec_point_mul_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_no_self_test) #define _ec_point_mul_scalar BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_point_mul_scalar) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bytestring.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bytestring.h index 63ef8056..77329bfd 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bytestring.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bytestring.h @@ -391,28 +391,40 @@ OPENSSL_EXPORT int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm, struct cbb_buffer_st { uint8_t *buf; - size_t len; // The number of valid bytes. - size_t cap; // The size of buf. - char can_resize; /* One iff |buf| is owned by this object. If not then |buf| - cannot be resized. */ - char error; /* One iff there was an error writing to this CBB. All future - operations will fail. */ + // len is the number of valid bytes in |buf|. + size_t len; + // cap is the size of |buf|. + size_t cap; + // can_resize is one iff |buf| is owned by this object. If not then |buf| + // cannot be resized. + unsigned can_resize : 1; + // error is one if there was an error writing to this CBB. All future + // operations will fail. + unsigned error : 1; }; -struct cbb_st { +struct cbb_child_st { + // base is a pointer to the buffer this |CBB| writes to. struct cbb_buffer_st *base; - // child points to a child CBB if a length-prefix is pending. - CBB *child; // offset is the number of bytes from the start of |base->buf| to this |CBB|'s // pending length prefix. size_t offset; // pending_len_len contains the number of bytes in this |CBB|'s pending // length-prefix, or zero if no length-prefix is pending. uint8_t pending_len_len; - char pending_is_asn1; - // is_child is true iff this is a child |CBB| (as opposed to a top-level - // |CBB|). Top-level objects are valid arguments for |CBB_finish|. + unsigned pending_is_asn1 : 1; +}; + +struct cbb_st { + // child points to a child CBB if a length-prefix is pending. + CBB *child; + // is_child is one if this is a child |CBB| and zero if it is a top-level + // |CBB|. This determines which arm of the union is valid. char is_child; + union { + struct cbb_buffer_st base; + struct cbb_child_st child; + } u; }; // CBB_zero sets an uninitialised |cbb| to the zero state. It must be @@ -428,7 +440,8 @@ OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity); // CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since // |buf| cannot grow, trying to write more than |len| bytes will cause CBB -// functions to fail. It returns one on success or zero on error. +// functions to fail. This function is infallible and always returns one. It is +// safe, but not necessary, to call |CBB_cleanup| on |cbb|. OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); // CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects @@ -557,11 +570,23 @@ OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); // error. OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); +// CBB_add_asn1_uint64_with_tag behaves like |CBB_add_asn1_uint64| but uses +// |tag| as the tag instead of INTEGER. This is useful if the INTEGER type uses +// implicit tagging. +OPENSSL_EXPORT int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, + unsigned tag); + // CBB_add_asn1_int64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| // and writes |value| in its contents. It returns one on success and zero on // error. OPENSSL_EXPORT int CBB_add_asn1_int64(CBB *cbb, int64_t value); +// CBB_add_asn1_int64_with_tag behaves like |CBB_add_asn1_int64| but uses |tag| +// as the tag instead of INTEGER. This is useful if the INTEGER type uses +// implicit tagging. +OPENSSL_EXPORT int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, + unsigned tag); + // CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the // given contents. It returns one on success and zero on error. OPENSSL_EXPORT int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h index d4377fa5..d11f1f9a 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h @@ -244,7 +244,6 @@ OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); #define DH_CHECK_NOT_SUITABLE_GENERATOR 0x08 #define DH_CHECK_Q_NOT_PRIME 0x10 #define DH_CHECK_INVALID_Q_VALUE 0x20 -#define DH_CHECK_INVALID_J_VALUE 0x40 // These are compatibility defines. #define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR @@ -330,31 +329,6 @@ OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, DH *dh); -struct dh_st { - BIGNUM *p; - BIGNUM *g; - BIGNUM *pub_key; // g^x mod p - BIGNUM *priv_key; // x - - // priv_length contains the length, in bits, of the private value. If zero, - // the private value will be the same length as |p|. - unsigned priv_length; - - CRYPTO_MUTEX method_mont_p_lock; - BN_MONT_CTX *method_mont_p; - - // Place holders if we want to do X9.42 DH - BIGNUM *q; - BIGNUM *j; - unsigned char *seed; - int seedlen; - BIGNUM *counter; - - int flags; - CRYPTO_refcount_t references; -}; - - #if defined(__cplusplus) } // extern C diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h index ed9adca7..b919a5d0 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h @@ -253,13 +253,23 @@ OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx); // EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| -// into, at most, |len| bytes at |buf|. It returns the number of bytes written -// or zero on error if |buf| is non-NULL, else the number of bytes needed. The -// |ctx| argument may be used if not NULL. +// into, at most, |max_out| bytes at |buf|. It returns the number of bytes +// written or zero on error if |buf| is non-NULL, else the number of bytes +// needed. The |ctx| argument may be used if not NULL. OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, - uint8_t *buf, size_t len, BN_CTX *ctx); + uint8_t *buf, size_t max_out, + BN_CTX *ctx); + +// EC_POINT_point2buf serialises |point| into the X9.62 form given by |form| to +// a newly-allocated buffer and sets |*out_buf| to point to it. It returns the +// length of the result on success or zero on error. The caller must release +// |*out_buf| with |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_POINT_point2buf(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t **out_buf, BN_CTX *ctx); // EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the // serialised point to |cbb|. It returns one on success and zero on error. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h index be79b189..9ab69053 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h @@ -179,12 +179,38 @@ OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, const BIGNUM *y); -// EC_KEY_key2buf encodes the public key in |key| to an allocated octet string -// and sets |*out_buf| to point to it. It returns the length of the encoded -// octet string or zero if an error occurred. +// EC_KEY_oct2key decodes |len| bytes from |in| as an EC public key in X9.62 +// form. |key| must already have a group configured. On success, it sets the +// public key in |key| to the result and returns one. Otherwise, it returns +// zero. +OPENSSL_EXPORT int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, + BN_CTX *ctx); + +// EC_KEY_key2buf behaves like |EC_POINT_point2buf|, except it encodes the +// public key in |key|. OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx); + uint8_t **out_buf, BN_CTX *ctx); + +// EC_KEY_oct2priv decodes a big-endian, zero-padded integer from |len| bytes +// from |in| and sets |key|'s private key to the result. It returns one on +// success and zero on error. The input must be padded to the size of |key|'s +// group order. +OPENSSL_EXPORT int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len); + +// EC_KEY_priv2oct serializes |key|'s private key as a big-endian integer, +// zero-padded to the size of |key|'s group order and writes the result to at +// most |max_out| bytes of |out|. It returns the number of bytes written on +// success and zero on error. If |out| is NULL, it returns the number of bytes +// needed without writing anything. +OPENSSL_EXPORT size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, + size_t max_out); + +// EC_KEY_priv2buf behaves like |EC_KEY_priv2oct| but sets |*out_buf| to a +// newly-allocated buffer containing the result. It returns the size of the +// result on success and zero on error. The caller must release |*out_buf| with +// |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf); // Key generation. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h index 202249e1..3c130337 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h @@ -936,7 +936,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, // EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by // |in|. It returns one on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point and |pkey| must already +// have an EC group configured. If it is an X25519 key, it is the 32-byte X25519 +// public key representation. This function is not supported for other key types +// and will fail. OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, size_t len); @@ -946,7 +949,10 @@ OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, // |OPENSSL_free| to release this buffer. The function returns the length of the // buffer on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point with uncompressed +// coordinates. If it is an X25519 key, it is the 32-byte X25519 public key +// representation. This function is not supported for other key types and will +// fail. OPENSSL_EXPORT size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h index b2de694e..71b318d9 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h @@ -51,8 +51,24 @@ OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void); // will be one of the |EVP_HPKE_KEM_*| constants. OPENSSL_EXPORT uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem); +// EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of an encoded public key +// for all KEMs currently supported by this library. +#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 32 + +// EVP_HPKE_KEM_public_key_len returns the length of a public key for |kem|. +// This value will be at most |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH|. +OPENSSL_EXPORT size_t EVP_HPKE_KEM_public_key_len(const EVP_HPKE_KEM *kem); + +// EVP_HPKE_MAX_PRIVATE_KEY_LENGTH is the maximum length of an encoded private +// key for all KEMs currently supported by this library. +#define EVP_HPKE_MAX_PRIVATE_KEY_LENGTH 32 + +// EVP_HPKE_KEM_private_key_len returns the length of a private key for |kem|. +// This value will be at most |EVP_HPKE_MAX_PRIVATE_KEY_LENGTH|. +OPENSSL_EXPORT size_t EVP_HPKE_KEM_private_key_len(const EVP_HPKE_KEM *kem); + // EVP_HPKE_MAX_ENC_LENGTH is the maximum length of "enc", the encapsulated -// shared secret, for all supported KEMs in this library. +// shared secret, for all KEMs currently supported by this library. #define EVP_HPKE_MAX_ENC_LENGTH 32 // EVP_HPKE_KEM_enc_len returns the length of the "enc", the encapsulated shared @@ -140,28 +156,22 @@ OPENSSL_EXPORT int EVP_HPKE_KEY_generate(EVP_HPKE_KEY *key, // EVP_HPKE_KEY_kem returns the HPKE KEM used by |key|. OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_HPKE_KEY_kem(const EVP_HPKE_KEY *key); -// EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of a public key for all -// KEMs supported by this library. -#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 32 - // EVP_HPKE_KEY_public_key writes |key|'s public key to |out| and sets // |*out_len| to the number of bytes written. On success, it returns one and // writes at most |max_out| bytes. If |max_out| is too small, it returns zero. // Setting |max_out| to |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH| will ensure the public -// key fits. +// key fits. An exact size can also be determined by +// |EVP_HPKE_KEM_public_key_len|. OPENSSL_EXPORT int EVP_HPKE_KEY_public_key(const EVP_HPKE_KEY *key, uint8_t *out, size_t *out_len, size_t max_out); -// EVP_HPKE_MAX_PRIVATE_KEY_LENGTH is the maximum length of a private key for -// all KEMs supported by this library. -#define EVP_HPKE_MAX_PRIVATE_KEY_LENGTH 32 - // EVP_HPKE_KEY_private_key writes |key|'s private key to |out| and sets // |*out_len| to the number of bytes written. On success, it returns one and // writes at most |max_out| bytes. If |max_out| is too small, it returns zero. // Setting |max_out| to |EVP_HPKE_MAX_PRIVATE_KEY_LENGTH| will ensure the -// private key fits. +// private key fits. An exact size can also be determined by +// |EVP_HPKE_KEM_private_key_len|. OPENSSL_EXPORT int EVP_HPKE_KEY_private_key(const EVP_HPKE_KEY *key, uint8_t *out, size_t *out_len, size_t max_out); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h index d8910781..c21f2b06 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h @@ -298,8 +298,8 @@ OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, // |hash_nid|. Passing unhashed inputs will not result in a secure signature // scheme. OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, - unsigned digest_len, uint8_t *out, - unsigned *out_len, RSA *rsa); + size_t digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa); // RSA_sign_pss_mgf1 signs |digest_len| bytes from |digest| with the public key // from |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It @@ -625,7 +625,7 @@ OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); // should use instead. It returns NULL on error, or a newly-allocated |RSA| on // success. This function is provided for compatibility only. The |callback| // and |cb_arg| parameters must be NULL. -OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback, +OPENSSL_EXPORT RSA *RSA_generate_key(int bits, uint64_t e, void *callback, void *cb_arg); // d2i_RSAPublicKey parses a DER-encoded RSAPublicKey structure (RFC 8017) from diff --git a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc index ac8f9bd7..6f2688c9 100644 --- a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -464,9 +464,11 @@ %xdefine _CBB_add_asn1 _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1 %xdefine _CBB_add_asn1_bool _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_bool %xdefine _CBB_add_asn1_int64 _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_int64 +%xdefine _CBB_add_asn1_int64_with_tag _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_int64_with_tag %xdefine _CBB_add_asn1_octet_string _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_octet_string %xdefine _CBB_add_asn1_oid_from_text _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_oid_from_text %xdefine _CBB_add_asn1_uint64 _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_uint64 +%xdefine _CBB_add_asn1_uint64_with_tag _ %+ BORINGSSL_PREFIX %+ _CBB_add_asn1_uint64_with_tag %xdefine _CBB_add_bytes _ %+ BORINGSSL_PREFIX %+ _CBB_add_bytes %xdefine _CBB_add_space _ %+ BORINGSSL_PREFIX %+ _CBB_add_space %xdefine _CBB_add_u16 _ %+ BORINGSSL_PREFIX %+ _CBB_add_u16 @@ -812,9 +814,13 @@ %xdefine _EC_KEY_new _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new %xdefine _EC_KEY_new_by_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new_by_curve_name %xdefine _EC_KEY_new_method _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new_method +%xdefine _EC_KEY_oct2key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2key +%xdefine _EC_KEY_oct2priv _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2priv %xdefine _EC_KEY_parse_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name %xdefine _EC_KEY_parse_parameters _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters %xdefine _EC_KEY_parse_private_key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key +%xdefine _EC_KEY_priv2buf _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2buf +%xdefine _EC_KEY_priv2oct _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2oct %xdefine _EC_KEY_set_asn1_flag _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_asn1_flag %xdefine _EC_KEY_set_conv_form _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_conv_form %xdefine _EC_KEY_set_enc_flags _ %+ BORINGSSL_PREFIX %+ _EC_KEY_set_enc_flags @@ -840,6 +846,7 @@ %xdefine _EC_POINT_mul _ %+ BORINGSSL_PREFIX %+ _EC_POINT_mul %xdefine _EC_POINT_new _ %+ BORINGSSL_PREFIX %+ _EC_POINT_new %xdefine _EC_POINT_oct2point _ %+ BORINGSSL_PREFIX %+ _EC_POINT_oct2point +%xdefine _EC_POINT_point2buf _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2buf %xdefine _EC_POINT_point2cbb _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2cbb %xdefine _EC_POINT_point2oct _ %+ BORINGSSL_PREFIX %+ _EC_POINT_point2oct %xdefine _EC_POINT_set_affine_coordinates _ %+ BORINGSSL_PREFIX %+ _EC_POINT_set_affine_coordinates @@ -1008,6 +1015,8 @@ %xdefine _EVP_HPKE_KDF_id _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KDF_id %xdefine _EVP_HPKE_KEM_enc_len _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_enc_len %xdefine _EVP_HPKE_KEM_id _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_id +%xdefine _EVP_HPKE_KEM_private_key_len _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_private_key_len +%xdefine _EVP_HPKE_KEM_public_key_len _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_public_key_len %xdefine _EVP_HPKE_KEY_cleanup _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_cleanup %xdefine _EVP_HPKE_KEY_copy _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_copy %xdefine _EVP_HPKE_KEY_free _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_free @@ -1688,7 +1697,6 @@ %xdefine _USERNOTICE_free _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_free %xdefine _USERNOTICE_it _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_it %xdefine _USERNOTICE_new _ %+ BORINGSSL_PREFIX %+ _USERNOTICE_new -%xdefine _UTF8_putc _ %+ BORINGSSL_PREFIX %+ _UTF8_putc %xdefine _X25519 _ %+ BORINGSSL_PREFIX %+ _X25519 %xdefine _X25519_keypair _ %+ BORINGSSL_PREFIX %+ _X25519_keypair %xdefine _X25519_public_from_private _ %+ BORINGSSL_PREFIX %+ _X25519_public_from_private @@ -2535,6 +2543,7 @@ %xdefine _ec_jacobian_to_affine _ %+ BORINGSSL_PREFIX %+ _ec_jacobian_to_affine %xdefine _ec_jacobian_to_affine_batch _ %+ BORINGSSL_PREFIX %+ _ec_jacobian_to_affine_batch %xdefine _ec_pkey_meth _ %+ BORINGSSL_PREFIX %+ _ec_pkey_meth +%xdefine _ec_point_byte_len _ %+ BORINGSSL_PREFIX %+ _ec_point_byte_len %xdefine _ec_point_from_uncompressed _ %+ BORINGSSL_PREFIX %+ _ec_point_from_uncompressed %xdefine _ec_point_mul_no_self_test _ %+ BORINGSSL_PREFIX %+ _ec_point_mul_no_self_test %xdefine _ec_point_mul_scalar _ %+ BORINGSSL_PREFIX %+ _ec_point_mul_scalar @@ -3350,9 +3359,11 @@ %xdefine CBB_add_asn1 BORINGSSL_PREFIX %+ _CBB_add_asn1 %xdefine CBB_add_asn1_bool BORINGSSL_PREFIX %+ _CBB_add_asn1_bool %xdefine CBB_add_asn1_int64 BORINGSSL_PREFIX %+ _CBB_add_asn1_int64 +%xdefine CBB_add_asn1_int64_with_tag BORINGSSL_PREFIX %+ _CBB_add_asn1_int64_with_tag %xdefine CBB_add_asn1_octet_string BORINGSSL_PREFIX %+ _CBB_add_asn1_octet_string %xdefine CBB_add_asn1_oid_from_text BORINGSSL_PREFIX %+ _CBB_add_asn1_oid_from_text %xdefine CBB_add_asn1_uint64 BORINGSSL_PREFIX %+ _CBB_add_asn1_uint64 +%xdefine CBB_add_asn1_uint64_with_tag BORINGSSL_PREFIX %+ _CBB_add_asn1_uint64_with_tag %xdefine CBB_add_bytes BORINGSSL_PREFIX %+ _CBB_add_bytes %xdefine CBB_add_space BORINGSSL_PREFIX %+ _CBB_add_space %xdefine CBB_add_u16 BORINGSSL_PREFIX %+ _CBB_add_u16 @@ -3698,9 +3709,13 @@ %xdefine EC_KEY_new BORINGSSL_PREFIX %+ _EC_KEY_new %xdefine EC_KEY_new_by_curve_name BORINGSSL_PREFIX %+ _EC_KEY_new_by_curve_name %xdefine EC_KEY_new_method BORINGSSL_PREFIX %+ _EC_KEY_new_method +%xdefine EC_KEY_oct2key BORINGSSL_PREFIX %+ _EC_KEY_oct2key +%xdefine EC_KEY_oct2priv BORINGSSL_PREFIX %+ _EC_KEY_oct2priv %xdefine EC_KEY_parse_curve_name BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name %xdefine EC_KEY_parse_parameters BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters %xdefine EC_KEY_parse_private_key BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key +%xdefine EC_KEY_priv2buf BORINGSSL_PREFIX %+ _EC_KEY_priv2buf +%xdefine EC_KEY_priv2oct BORINGSSL_PREFIX %+ _EC_KEY_priv2oct %xdefine EC_KEY_set_asn1_flag BORINGSSL_PREFIX %+ _EC_KEY_set_asn1_flag %xdefine EC_KEY_set_conv_form BORINGSSL_PREFIX %+ _EC_KEY_set_conv_form %xdefine EC_KEY_set_enc_flags BORINGSSL_PREFIX %+ _EC_KEY_set_enc_flags @@ -3726,6 +3741,7 @@ %xdefine EC_POINT_mul BORINGSSL_PREFIX %+ _EC_POINT_mul %xdefine EC_POINT_new BORINGSSL_PREFIX %+ _EC_POINT_new %xdefine EC_POINT_oct2point BORINGSSL_PREFIX %+ _EC_POINT_oct2point +%xdefine EC_POINT_point2buf BORINGSSL_PREFIX %+ _EC_POINT_point2buf %xdefine EC_POINT_point2cbb BORINGSSL_PREFIX %+ _EC_POINT_point2cbb %xdefine EC_POINT_point2oct BORINGSSL_PREFIX %+ _EC_POINT_point2oct %xdefine EC_POINT_set_affine_coordinates BORINGSSL_PREFIX %+ _EC_POINT_set_affine_coordinates @@ -3894,6 +3910,8 @@ %xdefine EVP_HPKE_KDF_id BORINGSSL_PREFIX %+ _EVP_HPKE_KDF_id %xdefine EVP_HPKE_KEM_enc_len BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_enc_len %xdefine EVP_HPKE_KEM_id BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_id +%xdefine EVP_HPKE_KEM_private_key_len BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_private_key_len +%xdefine EVP_HPKE_KEM_public_key_len BORINGSSL_PREFIX %+ _EVP_HPKE_KEM_public_key_len %xdefine EVP_HPKE_KEY_cleanup BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_cleanup %xdefine EVP_HPKE_KEY_copy BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_copy %xdefine EVP_HPKE_KEY_free BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_free @@ -4574,7 +4592,6 @@ %xdefine USERNOTICE_free BORINGSSL_PREFIX %+ _USERNOTICE_free %xdefine USERNOTICE_it BORINGSSL_PREFIX %+ _USERNOTICE_it %xdefine USERNOTICE_new BORINGSSL_PREFIX %+ _USERNOTICE_new -%xdefine UTF8_putc BORINGSSL_PREFIX %+ _UTF8_putc %xdefine X25519 BORINGSSL_PREFIX %+ _X25519 %xdefine X25519_keypair BORINGSSL_PREFIX %+ _X25519_keypair %xdefine X25519_public_from_private BORINGSSL_PREFIX %+ _X25519_public_from_private @@ -5421,6 +5438,7 @@ %xdefine ec_jacobian_to_affine BORINGSSL_PREFIX %+ _ec_jacobian_to_affine %xdefine ec_jacobian_to_affine_batch BORINGSSL_PREFIX %+ _ec_jacobian_to_affine_batch %xdefine ec_pkey_meth BORINGSSL_PREFIX %+ _ec_pkey_meth +%xdefine ec_point_byte_len BORINGSSL_PREFIX %+ _ec_point_byte_len %xdefine ec_point_from_uncompressed BORINGSSL_PREFIX %+ _ec_point_from_uncompressed %xdefine ec_point_mul_no_self_test BORINGSSL_PREFIX %+ _ec_point_mul_no_self_test %xdefine ec_point_mul_scalar BORINGSSL_PREFIX %+ _ec_point_mul_scalar