diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9e537d8b8..4559640ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,14 +14,17 @@ jobs: linux_5_10_arguments_override: "--explicit-target-dependency-import-check error" linux_6_0_arguments_override: "--explicit-target-dependency-import-check error" linux_6_1_arguments_override: "--explicit-target-dependency-import-check error" + linux_6_2_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true windows_6_0_arguments_override: "--explicit-target-dependency-import-check error" windows_6_1_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_2_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" @@ -31,6 +34,7 @@ jobs: with: windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 3ff06facc..6af47aa05 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -19,14 +19,17 @@ jobs: linux_5_10_arguments_override: "--explicit-target-dependency-import-check error" linux_6_0_arguments_override: "--explicit-target-dependency-import-check error" linux_6_1_arguments_override: "--explicit-target-dependency-import-check error" + linux_6_2_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true windows_6_0_arguments_override: "--explicit-target-dependency-import-check error" windows_6_1_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_2_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" @@ -36,6 +39,7 @@ jobs: with: windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true diff --git a/Package.swift b/Package.swift index 596beb7ec..04b795686 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: 035e720641f385e82c72b7b0a9e1d89e58cb5ed5 +// BoringSSL Commit: 0226f30467f540a3f62ef48d453f93927da199b6 import PackageDescription diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index 9da329bd4..7e58e0d86 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -255,7 +255,6 @@ add_library(CCryptoBoringSSL STATIC "crypto/x509/x_req.cc" "crypto/x509/x_sig.cc" "crypto/x509/x_spki.cc" - "crypto/x509/x_val.cc" "crypto/x509/x_x509.cc" "crypto/x509/x_x509a.cc" "crypto/xwing/xwing.cc" diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc index dcfc1fe09..4f26f2250 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include "../internal.h" #include "internal.h" @@ -110,76 +111,96 @@ int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, CBB_flush(out); } -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long len) { - ASN1_BIT_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - int padding; - uint8_t padding_mask; - - if (len < 1) { +static int asn1_parse_bit_string_contents(bssl::Span in, + ASN1_BIT_STRING *out) { + CBS cbs = in; + uint8_t padding; + if (!CBS_get_u8(&cbs, &padding)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); - goto err; + return 0; } - if (len > INT_MAX) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); - goto err; + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; } - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_BIT_STRING_new()) == NULL) { - return NULL; + // Unused bits in a BIT STRING must be zero. + uint8_t padding_mask = (1 << padding) - 1; + if (padding != 0) { + CBS copy = cbs; + uint8_t last; + if (!CBS_get_last_u8(©, &last) || (last & padding_mask) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); + return 0; } - } else { - ret = (*a); } - p = *pp; - padding = *(p++); - len--; - if (padding > 7) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - goto err; + if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) { + return 0; } - // Unused bits in a BIT STRING must be zero. - padding_mask = (1 << padding) - 1; - if (padding != 0 && (len < 1 || (p[len - 1] & padding_mask) != 0)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); - goto err; - } + out->type = V_ASN1_BIT_STRING; + // |ASN1_STRING_FLAG_BITS_LEFT| and the bottom 3 bits encode |padding|. + out->flags &= ~0x07; + out->flags |= ASN1_STRING_FLAG_BITS_LEFT | padding; + return 1; +} - // We do this to preserve the settings. If we modify the settings, via - // the _set_bit function, we will recalculate on output - ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); // clear - ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); // set +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + return nullptr; + } - if (len > 0) { - s = reinterpret_cast(OPENSSL_memdup(p, len)); - if (s == NULL) { - goto err; + ASN1_BIT_STRING *ret = nullptr; + if (a == nullptr || *a == nullptr) { + if ((ret = ASN1_BIT_STRING_new()) == nullptr) { + return nullptr; } - p += len; } else { - s = NULL; + ret = *a; } - ret->length = (int)len; - OPENSSL_free(ret->data); - ret->data = s; - ret->type = V_ASN1_BIT_STRING; - if (a != NULL) { - (*a) = ret; + if (!asn1_parse_bit_string_contents(bssl::Span(*pp, len), ret)) { + if (ret != nullptr && (a == nullptr || *a != ret)) { + ASN1_BIT_STRING_free(ret); + } + return nullptr; } - *pp = p; + + if (a != nullptr) { + *a = ret; + } + *pp += len; return ret; -err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) { - ASN1_BIT_STRING_free(ret); +} + +int asn1_parse_bit_string(CBS *cbs, ASN1_BIT_STRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_BITSTRING : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return asn1_parse_bit_string_contents(child, out); +} + +int asn1_parse_bit_string_with_bad_length(CBS *cbs, ASN1_BIT_STRING *out) { + CBS child; + CBS_ASN1_TAG tag; + size_t header_len; + int indefinite; + if (!CBS_get_any_ber_asn1_element(cbs, &child, &tag, &header_len, + /*out_ber_found=*/nullptr, + &indefinite) || + tag != CBS_ASN1_BITSTRING || indefinite || // + !CBS_skip(&child, header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - return NULL; + return asn1_parse_bit_string_contents(child, out); } // These next 2 functions from Goetz Babin-Ebell diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc index 5a52ac477..ea18ba964 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc @@ -21,13 +21,10 @@ int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp) { - CBB cbb; - if (!CBB_init(&cbb, 3) || // - !CBB_add_asn1_bool(&cbb, a != ASN1_BOOLEAN_FALSE)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/3, outp, [&](CBB *cbb) -> bool { + return CBB_add_asn1_bool(cbb, a != ASN1_BOOLEAN_FALSE); + }); } ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc index dbbbf99e9..645b136a1 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc @@ -36,6 +36,23 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) { return 1; } +int asn1_parse_generalized_time(CBS *cbs, ASN1_GENERALIZEDTIME *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_GENERALIZEDTIME : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_parse_generalized_time(&child, nullptr, + /*allow_timezone_offset=*/0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_GENERALIZEDTIME; + return 1; +} + int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) { return asn1_generalizedtime_to_tm(NULL, d); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc index 53a28aedf..5a3eaf07e 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "../internal.h" #include "internal.h" @@ -146,32 +147,13 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { return len; } -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, - long len) { - // This function can handle lengths up to INT_MAX - 1, but the rest of the - // legacy ASN.1 code mixes integer types, so avoid exposing it to - // ASN1_INTEGERS with larger lengths. - if (len < 0 || len > INT_MAX / 2) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); +static int asn1_parse_integer_contents(bssl::Span in, + ASN1_INTEGER *out) { + CBS cbs = in; int is_negative; if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); - return NULL; - } - - ASN1_INTEGER *ret = NULL; - if (out == NULL || *out == NULL) { - ret = ASN1_INTEGER_new(); - if (ret == NULL) { - return NULL; - } - } else { - ret = *out; + return 0; } // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First, @@ -192,33 +174,75 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, } } - if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) { - goto err; + if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) { + return 0; } if (is_negative) { - ret->type = V_ASN1_NEG_INTEGER; - negate_twos_complement(ret->data, ret->length); + out->type = V_ASN1_NEG_INTEGER; + negate_twos_complement(out->data, out->length); } else { - ret->type = V_ASN1_INTEGER; + out->type = V_ASN1_INTEGER; } // The value should be minimally-encoded. - assert(ret->length == 0 || ret->data[0] != 0); + assert(out->length == 0 || out->data[0] != 0); // Zero is not negative. - assert(!is_negative || ret->length > 0); + assert(!is_negative || out->length > 0); + return 1; +} + +int asn1_parse_integer(CBS *cbs, ASN1_INTEGER *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_INTEGER : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return asn1_parse_integer_contents(child, out); +} + +int asn1_parse_enumerated(CBS *cbs, ASN1_ENUMERATED *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_ENUMERATED : tag; + if (!asn1_parse_integer(cbs, out, tag)) { + return 0; + } + // Fix the type value. + out->type = + (out->type & V_ASN1_NEG) ? V_ASN1_NEG_ENUMERATED : V_ASN1_ENUMERATED; + return 1; +} + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + return nullptr; + } + + ASN1_INTEGER *ret = nullptr; + if (out == nullptr || *out == nullptr) { + ret = ASN1_INTEGER_new(); + if (ret == nullptr) { + return nullptr; + } + } else { + ret = *out; + } + + if (!asn1_parse_integer_contents(bssl::Span(*inp, len), ret)) { + if (ret != nullptr && (out == nullptr || *out != ret)) { + ASN1_INTEGER_free(ret); + } + return nullptr; + } *inp += len; - if (out != NULL) { + if (out != nullptr) { *out = ret; } return ret; -err: - if (ret != NULL && (out == NULL || *out != ret)) { - ASN1_INTEGER_free(ret); - } - return NULL; } int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) { diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc index e6e97d6d5..3ed780276 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc @@ -27,26 +27,27 @@ #include "internal.h" -int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { +int asn1_marshal_object(CBB *out, const ASN1_OBJECT *in, CBS_ASN1_TAG tag) { if (in == NULL) { OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); - return -1; + return 0; } if (in->length <= 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - return -1; + return 0; } - CBB cbb, child; - if (!CBB_init(&cbb, (size_t)in->length + 2) || - !CBB_add_asn1(&cbb, &child, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&child, in->data, in->length)) { - CBB_cleanup(&cbb); - return -1; - } + tag = tag == 0 ? CBS_ASN1_OBJECT : tag; + return CBB_add_asn1_element(out, tag, in->data, in->length); +} - return CBB_finish_i2d(&cbb, outp); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { + return bssl::I2DFromCBB( + /*initial_capacity=*/static_cast(in->length) + 2, outp, + [&](CBB *cbb) -> bool { + return asn1_marshal_object(cbb, in, /*tag=*/0); + }); } int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) { @@ -90,53 +91,48 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) { ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs, child; - CBS_init(&cbs, *inp, (size_t)len); - if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_OBJECT)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return NULL; - } - - const uint8_t *contents = CBS_data(&child); - ASN1_OBJECT *ret = c2i_ASN1_OBJECT(out, &contents, CBS_len(&child)); - if (ret != NULL) { - // |c2i_ASN1_OBJECT| should have consumed the entire input. - assert(CBS_data(&cbs) == contents); - *inp = CBS_data(&cbs); - } - return ret; + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> ASN1_OBJECT * { + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + const uint8_t *contents = CBS_data(&child); + return c2i_ASN1_OBJECT(nullptr, &contents, CBS_len(&child)); + }); } ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, long len) { - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - if (!CBS_is_valid_asn1_oid(&cbs)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> ASN1_OBJECT * { + if (!CBS_is_valid_asn1_oid(cbs)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return nullptr; + } + ASN1_OBJECT *ret = + ASN1_OBJECT_create(NID_undef, CBS_data(cbs), CBS_len(cbs), + /*sn=*/nullptr, /*ln=*/nullptr); + if (ret != nullptr) { + // |c2i_ASN1_OBJECT| consumes its whole input on success. + BSSL_CHECK(CBS_skip(cbs, CBS_len(cbs))); + } + return ret; + }); +} - ASN1_OBJECT *ret = ASN1_OBJECT_create(NID_undef, *inp, (size_t)len, - /*sn=*/NULL, /*ln=*/NULL); - if (ret == NULL) { - return NULL; +ASN1_OBJECT *asn1_parse_object(CBS *cbs, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OBJECT : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; } - - if (out != NULL) { - ASN1_OBJECT_free(*out); - *out = ret; + if (!CBS_is_valid_asn1_oid(&child)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return nullptr; } - *inp += len; // All bytes were consumed. - return ret; + return ASN1_OBJECT_create(NID_undef, CBS_data(&child), CBS_len(&child), + /*sn=*/nullptr, /*ln=*/nullptr); } ASN1_OBJECT *ASN1_OBJECT_new(void) { diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc index 0cd7663f4..61007f3a4 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -129,7 +131,7 @@ static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) { ASN1_STRING_TABLE key; key.nid = nid; const ASN1_STRING_TABLE *tbl = reinterpret_cast( - bsearch(&key, tbl_standard, OPENSSL_ARRAY_SIZE(tbl_standard), + bsearch(&key, tbl_standard, std::size(tbl_standard), sizeof(ASN1_STRING_TABLE), table_cmp_void)); if (tbl != NULL) { return tbl; @@ -202,5 +204,5 @@ void ASN1_STRING_TABLE_cleanup(void) {} void asn1_get_string_table_for_testing(const ASN1_STRING_TABLE **out_ptr, size_t *out_len) { *out_ptr = tbl_standard; - *out_len = OPENSSL_ARRAY_SIZE(tbl_standard); + *out_len = std::size(tbl_standard); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc index a0ac63462..2d9db622b 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc @@ -222,3 +222,19 @@ int ASN1_TIME_to_posix(const ASN1_TIME *t, int64_t *out_time) { } return OPENSSL_tm_to_posix(&tm, out_time); } + +int asn1_parse_time(CBS *cbs, ASN1_TIME *out, int allow_utc_timezone_offset) { + if (CBS_peek_asn1_tag(cbs, CBS_ASN1_UTCTIME)) { + return asn1_parse_utc_time(cbs, out, /*tag=*/0, allow_utc_timezone_offset); + } + return asn1_parse_generalized_time(cbs, out, /*tag=*/0); +} + +int asn1_marshal_time(CBB *cbb, const ASN1_TIME *in) { + if (in->type != V_ASN1_UTCTIME && in->type != V_ASN1_GENERALIZEDTIME) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } + return asn1_marshal_octet_string(cbb, in, + static_cast(in->type)); +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc index bebe0f906..9423ed0e1 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -170,3 +171,220 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) { return result; } + +int asn1_parse_any(CBS *cbs, ASN1_TYPE *out) { + CBS_ASN1_TAG tag; + CBS elem; + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, &elem, &tag, &header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // Handle the non-string types. + if (tag == CBS_ASN1_OBJECT) { + bssl::UniquePtr obj(asn1_parse_object(&elem, /*tag=*/0)); + if (obj == nullptr) { + return 0; + } + ASN1_TYPE_set(out, V_ASN1_OBJECT, obj.release()); + return 1; + } + if (tag == CBS_ASN1_NULL) { + if (CBS_len(&elem) != header_len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + ASN1_TYPE_set(out, V_ASN1_NULL, nullptr); + return 1; + } + if (tag == CBS_ASN1_BOOLEAN) { + int b; + if (!CBS_get_asn1_bool(&elem, &b)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + // V_ASN1_BOOLEAN will interpret the pointer as null for false and any + // arbitrary non-null pointer for true. + ASN1_TYPE_set(out, V_ASN1_BOOLEAN, b ? out : nullptr); + return 1; + } + + // All other cases are handled identically to the string-based ANY parser. + bssl::UniquePtr str(ASN1_STRING_new()); + if (str == nullptr || !asn1_parse_any_as_string(&elem, str.get())) { + return 0; + } + asn1_type_set0_string(out, str.release()); + return 1; +} + +int asn1_parse_any_as_string(CBS *cbs, ASN1_STRING *out) { + CBS_ASN1_TAG tag; + CBS elem; + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, &elem, &tag, &header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // Reject unexpectedly constructed or primitive universal types, rather than + // encoding them as an opaque |V_ASN1_OTHER|. As of X.680 (02/2021), tag + // numbers 0-36 have been allocated, except 15. Of these, only 8 (EXTERNAL), + // 11 (EMBEDDED PDV), 16 (SEQUENCE), 17 (SET), and 29 (CHARACTER STRING) are + // constructed. + const CBS_ASN1_TAG tag_class = (tag & CBS_ASN1_CLASS_MASK); + const CBS_ASN1_TAG number = tag & CBS_ASN1_TAG_NUMBER_MASK; + if (tag_class == CBS_ASN1_UNIVERSAL && number <= 36 && number != 15) { + const bool is_constructed = (tag & CBS_ASN1_CONSTRUCTED) != 0; + if (number == V_ASN1_EXTERNAL || number == 11 /* EMBEDDED PDV */ || + number == V_ASN1_SEQUENCE || number == V_ASN1_SET || + number == 29 /* CHARACTER STRING*/) { + if (!is_constructed) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + } else { + if (is_constructed) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } + } + } + + // Historically, parsing high universal tag numbers made OpenSSL's + // |ASN1_STRING| representation ambiguous. We've since fixed this with + // |V_ASN1_OTHER| but, for now, continue to enforce the limit. + if (tag_class == CBS_ASN1_UNIVERSAL && number > V_ASN1_MAX_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // These types are just parsed as |V_ASN1_OTHER| here. Check the contents + // before the generic |V_ASN1_OTHER| path. + CBS body = elem; + BSSL_CHECK(CBS_skip(&body, header_len)); + switch (tag) { + case CBS_ASN1_OBJECT: + if (!CBS_is_valid_asn1_oid(&body)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return 0; + } + break; + case CBS_ASN1_NULL: + if (CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + return 0; + } + break; + case CBS_ASN1_BOOLEAN: { + uint8_t v; + if (!CBS_get_u8(&body, &v) || CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + return 0; + } + if (v != 0 && v != 0xff) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + break; + } + } + + switch (tag) { + case CBS_ASN1_INTEGER: + return asn1_parse_integer(&elem, out, tag); + case CBS_ASN1_ENUMERATED: + return asn1_parse_enumerated(&elem, out, tag); + case CBS_ASN1_BITSTRING: + return asn1_parse_bit_string(&elem, out, tag); + case CBS_ASN1_UNIVERSALSTRING: + return asn1_parse_universal_string(&elem, out, tag); + case CBS_ASN1_BMPSTRING: + return asn1_parse_bmp_string(&elem, out, tag); + case CBS_ASN1_UTF8STRING: + return asn1_parse_utf8_string(&elem, out, tag); + case CBS_ASN1_UTCTIME: + // TODO(crbug.com/42290221): Reject timezone offsets here. We have no + // known cases where UTCTime inside ANY needs accept invalid timezones. + return asn1_parse_utc_time(&elem, out, tag, /*allow_timezone_offset=*/1); + case CBS_ASN1_GENERALIZEDTIME: + return asn1_parse_generalized_time(&elem, out, tag); + case CBS_ASN1_OCTETSTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_NUMERICSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_VIDEOTEXSTRING: + case CBS_ASN1_GRAPHICSTRING: + case CBS_ASN1_VISIBLESTRING: + case CBS_ASN1_GENERALSTRING: + // T61String is parsed as Latin-1, so all byte strings are valid. The + // others we currently do not enforce. + // + // TODO(crbug.com/42290290): Enforce the encoding of the other string + // types. + if (!asn1_parse_octet_string(&elem, out, tag)) { + return 0; + } + out->type = static_cast(tag); + return 1; + default: + // All unrecognized types, or types that cannot be represented as + // |ASN1_STRING|, are represented as the whole element. + if (!ASN1_STRING_set(out, CBS_data(&elem), CBS_len(&elem))) { + return 0; + } + if (tag == CBS_ASN1_SEQUENCE) { + out->type = V_ASN1_SEQUENCE; + } else if (tag == CBS_ASN1_SET) { + out->type = V_ASN1_SET; + } else { + out->type = V_ASN1_OTHER; + } + return 1; + } +} + +int asn1_marshal_any(CBB *out, const ASN1_TYPE *in) { + switch (in->type) { + case V_ASN1_OBJECT: + return asn1_marshal_object(out, in->value.object, /*tag=*/0); + case V_ASN1_NULL: + return CBB_add_asn1_element(out, CBS_ASN1_NULL, nullptr, 0); + case V_ASN1_BOOLEAN: + return CBB_add_asn1_bool(out, in->value.boolean != ASN1_BOOLEAN_FALSE); + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + return asn1_marshal_integer(out, in->value.integer, + static_cast(in->type)); + case V_ASN1_BIT_STRING: + return asn1_marshal_bit_string(out, in->value.bit_string, /*tag=*/0); + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + return asn1_marshal_octet_string(out, in->value.asn1_string, + static_cast(in->type)); + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_OTHER: + // These three types store the whole TLV as contents. + return CBB_add_bytes(out, ASN1_STRING_get0_data(in->value.asn1_string), + ASN1_STRING_length(in->value.asn1_string)); + default: + // |ASN1_TYPE|s can have type -1 when default-constructed. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc index bedf96fe2..b2452116d 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc @@ -37,6 +37,22 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, return 1; } +int asn1_parse_utc_time(CBS *cbs, ASN1_UTCTIME *out, CBS_ASN1_TAG tag, + int allow_timezone_offset) { + tag = tag == 0 ? CBS_ASN1_UTCTIME : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_parse_utc_time(&child, nullptr, allow_timezone_offset)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_UTCTIME; + return 1; +} + int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) { return asn1_utctime_to_tm(NULL, d, /*allow_timezone_offset=*/1); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc b/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc index aeb3660b3..6efa45028 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc @@ -295,11 +295,21 @@ ASN1_STRING *ASN1_STRING_type_new(int type) { return ret; } +void asn1_string_init(ASN1_STRING *str, int type) { + OPENSSL_memset(str, 0, sizeof(ASN1_STRING)); + str->type = type; +} + +void asn1_string_cleanup(ASN1_STRING *str) { + OPENSSL_free(str->data); + str->data = nullptr; +} + void ASN1_STRING_free(ASN1_STRING *str) { if (str == NULL) { return; } - OPENSSL_free(str->data); + asn1_string_cleanup(str); OPENSSL_free(str); } @@ -353,3 +363,70 @@ unsigned char *ASN1_STRING_data(ASN1_STRING *str) { return str->data; } const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str) { return str->data; } + +int asn1_parse_octet_string(CBS *cbs, ASN1_STRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_OCTET_STRING; + return 1; +} + +int asn1_marshal_octet_string(CBB *out, const ASN1_STRING *in, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + return CBB_add_asn1_element(out, tag, ASN1_STRING_get0_data(in), + ASN1_STRING_length(in)); +} + +static int asn1_parse_character_string(CBS *cbs, ASN1_STRING *out, + CBS_ASN1_TAG tag, int str_type, + int (*get_char)(CBS *cbs, uint32_t *), + int bad_char_err) { + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + CBS copy = child; + while (CBS_len(©) != 0) { + uint32_t c; + if (!get_char(©, &c)) { + OPENSSL_PUT_ERROR(ASN1, bad_char_err); + return 0; + } + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = str_type; + return 1; +} + +int asn1_parse_bmp_string(CBS *cbs, ASN1_BMPSTRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_BMPSTRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_BMPSTRING, + &CBS_get_ucs2_be, + ASN1_R_INVALID_BMPSTRING); +} + +int asn1_parse_universal_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_UNIVERSALSTRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_UNIVERSALSTRING, + &CBS_get_utf32_be, + ASN1_R_INVALID_UNIVERSALSTRING); +} + +int asn1_parse_utf8_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_UTF8STRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_UTF8STRING, + &CBS_get_utf8, ASN1_R_INVALID_UTF8STRING); +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h index 7c1576b51..5b8c63b50 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h @@ -48,7 +48,8 @@ OPENSSL_EXPORT int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, const struct tm *to); -// Internal ASN1 structures and functions: not for application use + +// Object identifiers. // These are used internally in the ASN1_OBJECT to keep track of // whether the names and data need to be free()ed @@ -72,6 +73,130 @@ struct asn1_object_st { ASN1_OBJECT *ASN1_OBJECT_new(void); +// asn1_parse_object parses a DER-encoded ASN.1 OBJECT IDENTIFIER from |cbs| and +// write the result to |out|. If |tag| is non-zero, the value is implicitly +// tagged with |tag|. On success, it returns a newly-allocated |ASN1_OBJECT| +// with the result and advances |cbs| past the parsed element. +// +// TODO(crbug.com/boringssl/414361735): This should return a bssl::UniquePtr, +// but cannot until it is made C++ linkage. +ASN1_OBJECT *asn1_parse_object(CBS *cbs, CBS_ASN1_TAG tag); + +// asn1_marshal_object marshals |in| as a DER-encoded, ASN.1 OBJECT IDENTIFIER +// and writes the result to |out|. It returns one on success and zero on error. +// If |tag| is non-zero, the tag is replaced with |tag|. +int asn1_marshal_object(CBB *out, const ASN1_OBJECT *in, CBS_ASN1_TAG tag); + + +// Strings. + +// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an +// ASN.1 PrintableString, and zero otherwise. +int asn1_is_printable(uint32_t value); + +// asn1_string_init initializes |str|, which may be uninitialized, with type +// |type|. +void asn1_string_init(ASN1_STRING *str, int type); + +// asn1_string_cleanup releases memory associated with |str|'s value, without +// freeing |str| itself. +void asn1_string_cleanup(ASN1_STRING *str); + +// asn1_bit_string_length returns the number of bytes in |str| and sets +// |*out_padding_bits| to the number of padding bits. +// +// This function should be used instead of |ASN1_STRING_length| to correctly +// handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. +int asn1_bit_string_length(const ASN1_BIT_STRING *str, + uint8_t *out_padding_bits); + +// The following functions parse a DER-encoded ASN.1 value of the specified +// type from |cbs| and write the result to |*out|. If |tag| is non-zero, the +// value is implicitly tagged with |tag|. On success, they return one and +// advance |cbs| past the parsed element. On entry, |*out| must contain an +// |ASN1_STRING| in some valid state. +int asn1_parse_bit_string(CBS *cbs, ASN1_BIT_STRING *out, CBS_ASN1_TAG tag); +int asn1_parse_integer(CBS *cbs, ASN1_INTEGER *out, CBS_ASN1_TAG tag); +int asn1_parse_enumerated(CBS *cbs, ASN1_ENUMERATED *out, CBS_ASN1_TAG tag); +int asn1_parse_octet_string(CBS *cbs, ASN1_STRING *out, CBS_ASN1_TAG tag); +int asn1_parse_bmp_string(CBS *cbs, ASN1_BMPSTRING *out, CBS_ASN1_TAG tag); +int asn1_parse_universal_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag); +int asn1_parse_utf8_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag); +int asn1_parse_generalized_time(CBS *cbs, ASN1_GENERALIZEDTIME *out, + CBS_ASN1_TAG tag); +int asn1_parse_utc_time(CBS *cbs, ASN1_UTCTIME *out, CBS_ASN1_TAG tag, + int allow_timezone_offset); + +// asn1_parse_bit_string_with_bad_length behaves like |asn1_parse_bit_string| +// but tolerates BER non-minimal, definite lengths. +int asn1_parse_bit_string_with_bad_length(CBS *cbs, ASN1_BIT_STRING *out); + +// asn1_marshal_bit_string marshals |in| as a DER-encoded, ASN.1 BIT STRING and +// writes the result to |out|. It returns one on success and zero on error. If +// |tag| is non-zero, the tag is replaced with |tag|. +int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, + CBS_ASN1_TAG tag); + +// asn1_marshal_integer marshals |in| as a DER-encoded, ASN.1 INTEGER and writes +// the result to |out|. It returns one on success and zero on error. If |tag| is +// non-zero, the tag is replaced with |tag|. This can also be used to marshal an +// ASN.1 ENUMERATED value by overriding the tag. +int asn1_marshal_integer(CBB *out, const ASN1_INTEGER *in, CBS_ASN1_TAG tag); + +// asn1_marshal_octet_string marshals |in| as a DER-encoded, ASN.1 OCTET STRING +// and writes the result to |out|. It returns one on success and zero on error. +// If |tag| is non-zero, the tag is replaced with |tag|. +// +// This function may be used to marshal other string-based universal types whose +// encoding is that of an implicitly-tagged OCTET STRING, e.g. UTF8String. +int asn1_marshal_octet_string(CBB *out, const ASN1_STRING *in, + CBS_ASN1_TAG tag); + +OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, + int allow_timezone_offset); +OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, + const ASN1_GENERALIZEDTIME *d); + +int asn1_parse_time(CBS *cbs, ASN1_TIME *out, int allow_utc_timezone_offset); +int asn1_marshal_time(CBB *cbb, const ASN1_TIME *in); + + +// The ASN.1 ANY type. + +// asn1_type_value_as_pointer returns |a|'s value in pointer form. This is +// usually the value object but, for BOOLEAN values, is 0 or 0xff cast to +// a pointer. +const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); + +// asn1_type_set0_string sets |a|'s value to the object represented by |str| and +// takes ownership of |str|. +void asn1_type_set0_string(ASN1_TYPE *a, ASN1_STRING *str); + +// asn1_type_cleanup releases memory associated with |a|'s value, without +// freeing |a| itself. +void asn1_type_cleanup(ASN1_TYPE *a); + +// asn1_parse_any parses a DER-encoded ASN.1 value of any type from |cbs| and +// writes the result to |*out|. On success, it advances |cbs| past the parsed +// element and returns one. On entry, |*out| must contain an |ASN1_TYPE| in some +// valid state. +int asn1_parse_any(CBS *cbs, ASN1_TYPE *out); + +// asn1_parse_any_as_string behaves like |asn1_parse_any| but represents the +// value as an |ASN1_STRING|. Types which are not represented with +// |ASN1_STRING|, such as |ASN1_OBJECT|, are represented with type +// |V_ASN1_OTHER|. +int asn1_parse_any_as_string(CBS *cbs, ASN1_STRING *out); + +// asn1_marshal_any marshals |in| as a DER-encoded ASN.1 value and writes the +// result to |out|. It returns one on success and zeron on error. +int asn1_marshal_any(CBB *out, const ASN1_TYPE *in); + + +// Support structures for the template-based encoder. + // ASN1_ENCODING is used to save the received encoding of an ASN.1 type. This // avoids problems with invalid encodings that break signatures. typedef struct ASN1_ENCODING_st { @@ -79,16 +204,8 @@ typedef struct ASN1_ENCODING_st { uint8_t *enc; // len is the length of |enc|. If zero, there is no saved encoding. size_t len; - // buf, if non-NULL, is the |CRYPTO_BUFFER| that |enc| points into. If NULL, - // |enc| must be released with |OPENSSL_free|. - CRYPTO_BUFFER *buf; } ASN1_ENCODING; -OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, - int allow_timezone_offset); -OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, - const ASN1_GENERALIZEDTIME *d); - int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); @@ -97,14 +214,12 @@ void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); // ASN1_item_ex_d2i parses |len| bytes from |*in| as a structure of type |it| // and writes the result to |*pval|. If |tag| is non-negative, |it| is // implicitly tagged with the tag specified by |tag| and |aclass|. If |opt| is -// non-zero, the value is optional. If |buf| is non-NULL, |*in| must point into -// |buf|. +// non-zero, the value is optional. // // This function returns one and advances |*in| if an object was successfully // parsed, -1 if an optional value was successfully skipped, and zero on error. int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - CRYPTO_BUFFER *buf); + const ASN1_ITEM *it, int tag, int aclass, char opt); // ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the // i2d output convention. It returns a non-zero length on success and -1 on @@ -150,47 +265,11 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, // returns one on success and zero on error. If |buf| is non-NULL, |in| must // point into |buf|. int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t inlen, - const ASN1_ITEM *it, CRYPTO_BUFFER *buf); + const ASN1_ITEM *it); // asn1_encoding_clear clears the cached encoding in |enc|. void asn1_encoding_clear(ASN1_ENCODING *enc); -// asn1_type_value_as_pointer returns |a|'s value in pointer form. This is -// usually the value object but, for BOOLEAN values, is 0 or 0xff cast to -// a pointer. -const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); - -// asn1_type_set0_string sets |a|'s value to the object represented by |str| and -// takes ownership of |str|. -void asn1_type_set0_string(ASN1_TYPE *a, ASN1_STRING *str); - -// asn1_type_cleanup releases memory associated with |a|'s value, without -// freeing |a| itself. -void asn1_type_cleanup(ASN1_TYPE *a); - -// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an -// ASN.1 PrintableString, and zero otherwise. -int asn1_is_printable(uint32_t value); - -// asn1_bit_string_length returns the number of bytes in |str| and sets -// |*out_padding_bits| to the number of padding bits. -// -// This function should be used instead of |ASN1_STRING_length| to correctly -// handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. -int asn1_bit_string_length(const ASN1_BIT_STRING *str, - uint8_t *out_padding_bits); - -// asn1_marshal_bit_string marshals |in| as a DER-encoded, ASN.1 BIT STRING and -// writes the result to |out|. It returns one on success and zero on error. If -// |tag| is non-zero, the tag is replaced with |tag|. -int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, - CBS_ASN1_TAG tag); - -// asn1_marshal_integer marshals |in| as a DER-encoded, ASN.1 INTEGER and writes -// the result to |out|. It returns one on success and zero on error. If |tag| is -// non-zero, the tag is replaced with |tag|. -int asn1_marshal_integer(CBB *out, const ASN1_INTEGER *in, CBS_ASN1_TAG tag); - typedef struct { int nid; long minsize; @@ -210,8 +289,18 @@ typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, long length); typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int opt, ASN1_TLC *ctx); +// An ASN1_ex_parse function should parse a value from |cbs| and set |*pval| to +// the result. It should return one on success and zero on failure. If |opt| is +// non-zero, the field may be optional. If an optional element is missing, the +// function should return one and consume zero bytes from |cbs|. +// +// If |opt| is non-zero, the function can assume that |*pval| is nullptr on +// entry. Otherwise, |*pval| may either be nullptr, or the result of +// |ASN1_ex_new_func|. The function may either write into the existing object, +// if any, or unconditionally make a new one. (The existing object comes from +// tasn_new.cc recursively filling in objects before parsing into them.) +typedef int ASN1_ex_parse(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, + int opt); typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it); @@ -221,10 +310,57 @@ typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); typedef struct ASN1_EXTERN_FUNCS_st { ASN1_ex_new_func *asn1_ex_new; ASN1_ex_free_func *asn1_ex_free; - ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_parse *asn1_ex_parse; ASN1_ex_i2d *asn1_ex_i2d; } ASN1_EXTERN_FUNCS; +#define IMPLEMENT_EXTERN_ASN1_SIMPLE(name, new_func, free_func, parse_func, \ + i2d_func) \ + static int name##_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { \ + *pval = (ASN1_VALUE *)new_func(); \ + return *pval != nullptr; \ + } \ + \ + static void name##_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { \ + free_func((name *)*pval); \ + *pval = nullptr; \ + } \ + \ + static int name##_parse_cb(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, \ + int opt) { \ + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { \ + return 1; \ + } \ + \ + if ((*pval == nullptr && !name##_new_cb(pval, it)) || \ + !parse_func(cbs, (name *)*pval)) { \ + return 0; \ + } \ + return 1; \ + } \ + \ + static int name##_i2d_cb(ASN1_VALUE **pval, unsigned char **out, \ + const ASN1_ITEM *it) { \ + return i2d_func((name *)*pval, out); \ + } \ + \ + static const ASN1_EXTERN_FUNCS name##_extern_funcs = { \ + name##_new_cb, name##_free_cb, name##_parse_cb, name##_i2d_cb}; \ + \ + IMPLEMENT_EXTERN_ASN1(name, name##_extern_funcs) + +// ASN1_TIME is an |ASN1_ITEM| whose ASN.1 type is X.509 Time (RFC 5280) and C +// type is |ASN1_TIME*|. +DECLARE_ASN1_ITEM(ASN1_TIME) + +// DIRECTORYSTRING is an |ASN1_ITEM| whose ASN.1 type is X.509 DirectoryString +// (RFC 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DIRECTORYSTRING) + +// DISPLAYTEXT is an |ASN1_ITEM| whose ASN.1 type is X.509 DisplayText (RFC +// 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DISPLAYTEXT) + // ASN1_ANY_AS_STRING is an |ASN1_ITEM| with ASN.1 type ANY and C type // |ASN1_STRING*|. Types which are not represented with |ASN1_STRING|, such as // |ASN1_OBJECT|, are represented with type |V_ASN1_OTHER|. diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc index 690083665..acc3cf661 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc @@ -39,18 +39,16 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth); + int depth); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth); -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, - int utype, const ASN1_ITEM *it); + int depth); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt); static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, CRYPTO_BUFFER *buf, int depth); + char opt, int depth); unsigned long ASN1_tag2bit(int tag) { switch (tag) { @@ -91,25 +89,6 @@ unsigned long ASN1_tag2bit(int tag) { } } -static int is_supported_universal_type(int tag, int aclass) { - if (aclass != V_ASN1_UNIVERSAL) { - return 0; - } - return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN || - tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER || - tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING || - tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING || - tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING || - tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME || - tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING || - tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING || - tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING || - tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET || - tag == V_ASN1_SEQUENCE; -} - -// Macro to initialize and invalidate the cache - // Decode an ASN1 item, this currently behaves just like a standard 'd2i' // function. 'in' points to a buffer to read the data from, in future we // will have more advanced versions that can input data a piece at a time and @@ -119,7 +98,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it) { ASN1_VALUE *ret = NULL; if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0, - /*buf=*/NULL, /*depth=*/0) <= 0) { + /*depth=*/0) <= 0) { // Clean up, in case the caller left a partial object. // // TODO(davidben): I don't think it can leave one, but the codepaths below @@ -149,7 +128,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, CRYPTO_BUFFER *buf, int depth) { + char opt, int depth) { const ASN1_TEMPLATE *tt, *errtt = NULL; const unsigned char *p = NULL, *q; unsigned char oclass; @@ -161,10 +140,9 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, if (!pval) { return 0; } - - if (buf != NULL) { - assert(CRYPTO_BUFFER_data(buf) <= *in && - *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + goto err; } // Bound |len| to comfortably fit in an int. Lengths in this module often @@ -189,11 +167,9 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; } - return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf, - depth); + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, depth); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt); - break; case ASN1_ITYPE_MSTRING: // It never makes sense for multi-strings to have implicit tagging, so @@ -239,7 +215,18 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } const ASN1_EXTERN_FUNCS *ef = reinterpret_cast(it->funcs); - return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL); + CBS cbs; + CBS_init(&cbs, *in, len); + CBS copy = cbs; + if (!ef->asn1_ex_parse(pval, &cbs, it, opt)) { + goto err; + } + *in = CBS_data(&cbs); + // Check whether the function skipped an optional element. + // + // TODO(crbug.com/42290418): Switch the rest of this function to + // |asn1_ex_parse|'s calling convention. + return CBS_len(&cbs) == CBS_len(©) ? -1 : 1; } case ASN1_ITYPE_CHOICE: { @@ -274,7 +261,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { pchptr = asn1_get_field_ptr(pval, tt); // We mark field as OPTIONAL so its absence can be recognised. - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, depth); // If field not present, try the next one if (ret == -1) { continue; @@ -380,7 +367,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } // attempt to read in field, allowing each to be OPTIONAL - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth); + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, depth); if (!ret) { errtt = seqtt; goto err; @@ -419,7 +406,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } } // Save encoding - if (!asn1_enc_save(pval, *in, p - *in, it, buf)) { + if (!asn1_enc_save(pval, *in, p - *in, it)) { goto auxerr; } if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { @@ -445,10 +432,8 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - CRYPTO_BUFFER *buf) { - return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf, - /*depth=*/0); + const ASN1_ITEM *it, int tag, int aclass, char opt) { + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, /*depth=*/0); } // Templates are handled with two separate functions. One handles any @@ -456,7 +441,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth) { + int depth) { int aclass; int ret; long len; @@ -488,7 +473,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, return 0; } // We've found the field so it can't be OPTIONAL now - ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth); + ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); return 0; @@ -501,7 +486,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, goto err; } } else { - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, depth); } *in = p; @@ -514,7 +499,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth) { + int depth) { int aclass; int ret; const unsigned char *p; @@ -572,7 +557,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, const unsigned char *q = p; skfield = NULL; if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), - /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) { + /*tag=*/-1, /*aclass=*/0, /*opt=*/0, depth)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; } @@ -585,7 +571,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } else if (flags & ASN1_TFLG_IMPTAG) { // IMPLICIT tagging ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, - aclass, opt, buf, depth); + aclass, opt, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -595,7 +581,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } else { // Nothing special ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1, - /*aclass=*/0, opt, buf, depth); + /*aclass=*/0, opt, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -612,306 +598,211 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, return 0; } +// TODO(crbug.com/42290418): Switch the whole file to use a CBS-based calling +// convention. +static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, + const ASN1_ITEM *it, int tag, int aclass, + char opt); + +// asn1_d2i_ex_primitive returns one on success, zero on error, and -1 if an +// optional value was skipped. static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, const ASN1_ITEM *it, int tag, int aclass, char opt) { - int ret = 0, utype; - long plen; - char cst; - const unsigned char *p; - const unsigned char *cont = NULL; - long len; - if (!pval) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); - return 0; // Should never happen + CBS cbs; + CBS_init(&cbs, *in, inlen); + int ret = asn1_d2i_ex_primitive_cbs(pval, &cbs, it, tag, aclass, opt); + if (ret <= 0) { + return ret; + } + *in = CBS_data(&cbs); + return 1; +} + +static ASN1_STRING *ensure_string(ASN1_VALUE **pval) { + if (*pval) { + return (ASN1_STRING *)*pval; } + ASN1_STRING *str = ASN1_STRING_new(); + if (str == nullptr) { + return nullptr; + } + *pval = (ASN1_VALUE *)str; + return str; +} + +static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, + const ASN1_ITEM *it, int tag, int aclass, + char opt) { + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of callbacks. + assert(it->funcs == NULL); + int utype; assert(it->itype == ASN1_ITYPE_PRIMITIVE || it->itype == ASN1_ITYPE_MSTRING); if (it->itype == ASN1_ITYPE_MSTRING) { + // MSTRING passes utype in |tag|, normally used for implicit tagging. utype = tag; tag = -1; } else { utype = it->utype; } + // Handle ANY types. if (utype == V_ASN1_ANY || utype == V_ASN1_ANY_AS_STRING) { - // If type is ANY need to figure out type from tag - unsigned char oclass; if (tag >= 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); return 0; } - if (opt) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); - return 0; - } - const int is_string = utype == V_ASN1_ANY_AS_STRING; - p = *in; - ret = asn1_check_tlen(&plen, &utype, &oclass, &cst, &p, inlen, -1, 0, 0); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } - if (!is_supported_universal_type(utype, oclass)) { - utype = V_ASN1_OTHER; + if (opt && CBS_len(cbs) == 0) { + return -1; // Omitted OPTIONAL value. } - // These three types are not represented as |ASN1_STRING|, so they must be - // parsed separately and then treated as an opaque |V_ASN1_OTHER|. - if (is_string && (utype == V_ASN1_OBJECT || utype == V_ASN1_NULL || - utype == V_ASN1_BOOLEAN)) { - if (cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } - CBS cbs; - CBS_init(&cbs, p, plen); - if (utype == V_ASN1_OBJECT && !CBS_is_valid_asn1_oid(&cbs)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return 0; - } - if (utype == V_ASN1_NULL && CBS_len(&cbs) != 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + } + if (utype == V_ASN1_ANY) { + ASN1_TYPE *typ; + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) { return 0; } - if (utype == V_ASN1_BOOLEAN) { - if (CBS_len(&cbs) != 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - return 0; - } - uint8_t v = CBS_data(&cbs)[0]; - if (v != 0 && v != 0xff) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return 0; - } - } - utype = V_ASN1_OTHER; + *pval = (ASN1_VALUE *)typ; + } else { + typ = (ASN1_TYPE *)*pval; + } + return asn1_parse_any(cbs, typ); + } + if (utype == V_ASN1_ANY_AS_STRING) { + ASN1_STRING *str = ensure_string(pval); + if (str == nullptr) { + return 0; } + return asn1_parse_any_as_string(cbs, str); } + + // Convert the crypto/asn1 tag into a CBS one. if (tag == -1) { tag = utype; aclass = V_ASN1_UNIVERSAL; } - p = *in; - // Check header - ret = asn1_check_tlen(&plen, NULL, NULL, &cst, &p, inlen, tag, aclass, opt); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) { - return -1; - } - ret = 0; - // SEQUENCE, SET and "OTHER" are left in encoded form - if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || - (utype == V_ASN1_OTHER)) { - // SEQUENCE and SET must be constructed - if (utype != V_ASN1_OTHER && !cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); - return 0; - } - cont = *in; - len = p - cont + plen; - p += plen; - } else if (cst) { - // This parser historically supported BER constructed strings. We no - // longer do and will gradually tighten this parser into a DER - // parser. BER types should use |CBS_asn1_ber_to_der|. - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } else { - cont = p; - len = plen; - p += plen; + // All edge cases of |utype| should have been handled already. |utype| is now + // either a primitive |ASN1_ITEM|, handled by |DECLARE_ASN1_ITEM|, or a + // multistring option with a corresponding |B_ASN1_*| constant. + assert(utype >= 0 && utype <= V_ASN1_MAX_UNIVERSAL); + CBS_ASN1_TAG cbs_tag = + (static_cast(aclass) << CBS_ASN1_TAG_SHIFT) | + static_cast(tag); + if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET) { + cbs_tag |= CBS_ASN1_CONSTRUCTED; } - // We now have content length and type: translate into a structure - if (!asn1_ex_c2i(pval, cont, len, utype, it)) { - goto err; + if (opt && !CBS_peek_asn1_tag(cbs, cbs_tag)) { + return -1; // Omitted OPTIONAL value. } - *in = p; - ret = 1; -err: - return ret; -} - -// Translate ASN1 content octets into a structure - -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, - int utype, const ASN1_ITEM *it) { - ASN1_VALUE **opval = NULL; - ASN1_STRING *stmp; - ASN1_TYPE *typ = NULL; - int ret = 0; - ASN1_INTEGER **tint; - - // Historically, |it->funcs| for primitive types contained an - // |ASN1_PRIMITIVE_FUNCS| table of callbacks. - assert(it->funcs == NULL); - - // If ANY type clear type and set pointer to internal value - if (it->utype == V_ASN1_ANY) { - if (!*pval) { - typ = ASN1_TYPE_new(); - if (typ == NULL) { - goto err; + // Handle non-|ASN1_STRING| types. + switch (utype) { + case V_ASN1_OBJECT: { + bssl::UniquePtr obj(asn1_parse_object(cbs, cbs_tag)); + if (obj == nullptr) { + return 0; } - *pval = (ASN1_VALUE *)typ; - } else { - typ = (ASN1_TYPE *)*pval; - } - - if (utype != typ->type) { - ASN1_TYPE_set(typ, utype, NULL); + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + *pval = (ASN1_VALUE *)obj.release(); + return 1; } - opval = pval; - pval = &typ->value.asn1_value; - } - - // If implementing a type that is not represented in |ASN1_STRING|, the - // |V_ASN1_ANY_AS_STRING| logic must be modified to redirect it to - // |V_ASN1_OTHER|. - switch (utype) { - case V_ASN1_OBJECT: - if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) { - goto err; + case V_ASN1_NULL: { + CBS null; + if (!CBS_get_asn1(cbs, &null, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - break; - - case V_ASN1_NULL: - if (len) { + if (CBS_len(&null) != 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); - goto err; + return 0; } *pval = (ASN1_VALUE *)1; - break; - - case V_ASN1_BOOLEAN: - if (len != 1) { + return 1; + } + case V_ASN1_BOOLEAN: { + CBS child; + if (!CBS_get_asn1(cbs, &child, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + // TODO(crbug.com/42290221): Reject invalid BOOLEAN encodings and just + // call |CBS_get_asn1_bool|. + if (CBS_len(&child) != 1) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - goto err; - } else { - ASN1_BOOLEAN *tbool; - tbool = (ASN1_BOOLEAN *)pval; - *tbool = *cont; + return 0; } - break; + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = CBS_data(&child)[0]; + return 1; + } + } - case V_ASN1_BIT_STRING: - if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) { - goto err; - } - break; + // All other types as an |ASN1_STRING| representation. + ASN1_STRING *str = ensure_string(pval); + if (str == nullptr) { + return 0; + } + switch (utype) { + case V_ASN1_BIT_STRING: + return asn1_parse_bit_string(cbs, str, cbs_tag); case V_ASN1_INTEGER: + return asn1_parse_integer(cbs, str, cbs_tag); case V_ASN1_ENUMERATED: - tint = (ASN1_INTEGER **)pval; - if (!c2i_ASN1_INTEGER(tint, &cont, len)) { - goto err; - } - // Fixup type to match the expected form - (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); - break; - + return asn1_parse_enumerated(cbs, str, cbs_tag); + case V_ASN1_UNIVERSALSTRING: + return asn1_parse_universal_string(cbs, str, cbs_tag); + case V_ASN1_BMPSTRING: + return asn1_parse_bmp_string(cbs, str, cbs_tag); + case V_ASN1_UTF8STRING: + return asn1_parse_utf8_string(cbs, str, cbs_tag); + case V_ASN1_UTCTIME: + // TODO(crbug.com/42290221): Reject timezone offsets. We need to parse + // invalid timestamps in |X509| objects, but that parser no longer uses + // this code. + return asn1_parse_utc_time(cbs, str, cbs_tag, + /*allow_timezone_offset=*/1); + case V_ASN1_GENERALIZEDTIME: + return asn1_parse_generalized_time(cbs, str, cbs_tag); case V_ASN1_OCTET_STRING: case V_ASN1_NUMERICSTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_VIDEOTEXSTRING: case V_ASN1_IA5STRING: - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: case V_ASN1_GRAPHICSTRING: case V_ASN1_VISIBLESTRING: case V_ASN1_GENERALSTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_BMPSTRING: - case V_ASN1_UTF8STRING: - case V_ASN1_OTHER: - case V_ASN1_SET: - case V_ASN1_SEQUENCE: { - CBS cbs; - CBS_init(&cbs, cont, (size_t)len); - if (utype == V_ASN1_BMPSTRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_ucs2_be(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); - goto err; - } - } - } - if (utype == V_ASN1_UNIVERSALSTRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_utf32_be(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); - goto err; - } - } - } - if (utype == V_ASN1_UTF8STRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_utf8(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); - goto err; - } - } - } - if (utype == V_ASN1_UTCTIME) { - if (!CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - } - if (utype == V_ASN1_GENERALIZEDTIME) { - if (!CBS_parse_generalized_time(&cbs, NULL, - /*allow_timezone_offset=*/0)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - } - // TODO(https://crbug.com/boringssl/427): Check other string types. - - // All based on ASN1_STRING and handled the same - if (!*pval) { - stmp = ASN1_STRING_type_new(utype); - if (!stmp) { - goto err; - } - *pval = (ASN1_VALUE *)stmp; - } else { - stmp = (ASN1_STRING *)*pval; - stmp->type = utype; + // T61String is parsed as Latin-1, so all byte strings are valid. The + // others we currently do not enforce. + // + // TODO(crbug.com/42290290): Enforce the encoding of the other string + // types. + if (!asn1_parse_octet_string(cbs, str, cbs_tag)) { + return 0; } - if (!ASN1_STRING_set(stmp, cont, len)) { - ASN1_STRING_free(stmp); - *pval = NULL; - goto err; + str->type = utype; + return 1; + case V_ASN1_SEQUENCE: { + // Save the entire element in the string. + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - break; + str->type = V_ASN1_SEQUENCE; + return ASN1_STRING_set(str, CBS_data(&elem), CBS_len(&elem)); } - default: OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - goto err; - } - // If ASN1_ANY and NULL type fix up value - if (typ && (utype == V_ASN1_NULL)) { - typ->value.ptr = NULL; - } - - ret = 1; -err: - if (!ret) { - ASN1_TYPE_free(typ); - if (opval) { - *opval = NULL; + return 0; } - } - return ret; } // Check an ASN1 tag and length: a bit like ASN1_get_object but it diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc index 313abb814..05526b5f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc @@ -19,6 +19,9 @@ #include "internal.h" +// TODO(crbug.com/42290417): While we need |ASN1_ITEM|s, the exposed new, free, +// i2d, and d2i functions should call the underlying implementations directly. + #define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ IMPLEMENT_ASN1_TYPE(sname) \ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \ diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc index ebdbe7362..12e9d195a 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc @@ -94,7 +94,6 @@ void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { if (enc) { enc->enc = NULL; enc->len = 0; - enc->buf = NULL; } } @@ -106,7 +105,7 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { } int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, - const ASN1_ITEM *it, CRYPTO_BUFFER *buf) { + const ASN1_ITEM *it) { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); if (!enc) { @@ -114,17 +113,9 @@ int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, } asn1_encoding_clear(enc); - if (buf != NULL) { - assert(CRYPTO_BUFFER_data(buf) <= in && - in + in_len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); - CRYPTO_BUFFER_up_ref(buf); - enc->buf = buf; - enc->enc = (uint8_t *)in; - } else { - enc->enc = reinterpret_cast(OPENSSL_memdup(in, in_len)); - if (!enc->enc) { - return 0; - } + enc->enc = reinterpret_cast(OPENSSL_memdup(in, in_len)); + if (!enc->enc) { + return 0; } enc->len = in_len; @@ -132,14 +123,9 @@ int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, } void asn1_encoding_clear(ASN1_ENCODING *enc) { - if (enc->buf != NULL) { - CRYPTO_BUFFER_free(enc->buf); - } else { - OPENSSL_free(enc->enc); - } + OPENSSL_free(enc->enc); enc->enc = NULL; enc->len = 0; - enc->buf = NULL; } int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, diff --git a/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc b/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc index 71125f7b4..fd9e3995c 100644 --- a/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc +++ b/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc @@ -16,6 +16,8 @@ #include +#include + #include "../internal.h" // https://tools.ietf.org/html/rfc7693#section-2.6 @@ -99,7 +101,7 @@ static void blake2b_transform(BLAKE2B_CTX *b2b, blake2b_load(block, s[15])); } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(b2b->h); i++) { + for (size_t i = 0; i < std::size(b2b->h); i++) { b2b->h[i] ^= v[i]; b2b->h[i] ^= v[i + 8]; } diff --git a/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h b/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h index b0d55f018..19b76ab51 100644 --- a/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h @@ -15,12 +15,14 @@ #ifndef OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H -#include +#include +#include +#include + +#include -#if defined(__cplusplus) -extern "C" { -#endif +extern "C" { // CBS_asn1_ber_to_der reads a BER element from |in|. If it finds // indefinite-length elements or constructed strings then it converts the BER @@ -66,9 +68,53 @@ OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, // This function may be used to help implement legacy i2d ASN.1 functions. int CBB_finish_i2d(CBB *cbb, uint8_t **outp); - -#if defined(__cplusplus) } // extern C -#endif + +BSSL_NAMESPACE_BEGIN + +// D2IFromCBS takes a functor of type |Unique(CBS*)| and implements the d2i +// calling convention. For compatibility with functions that don't tag their +// return value (e.g. public APIs), |T*(CBS)| is also accepted. The callback can +// assume that the |CBS|'s length fits in |long|. The callback should not access +// |out|, |inp|, or |len| directly. +template +inline T *D2IFromCBS(T **out, const uint8_t **inp, long len, CBSFunc func) { + static_assert(std::is_invocable_v); + static_assert( + std::is_same_v, UniquePtr> || + std::is_same_v, T *>); + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + return nullptr; + } + CBS cbs; + CBS_init(&cbs, *inp, len); + UniquePtr ret(func(&cbs)); + if (ret == nullptr) { + return nullptr; + } + if (out != nullptr) { + UniquePtr free_out(*out); + *out = ret.get(); + } + *inp = CBS_data(&cbs); + return ret.release(); +} + +// I2DFromCBB takes a functor of type |bool(CBB*)| and implements the i2d +// calling convention. It internally makes a |CBB| with the specified initial +// capacity. The callback should not access |outp| directly. +template +inline int I2DFromCBB(size_t initial_capacity, uint8_t **outp, CBBFunc func) { + static_assert(std::is_invocable_v); + static_assert(std::is_same_v, bool>); + ScopedCBB cbb; + if (!CBB_init(cbb.get(), initial_capacity) || !func(cbb.get())) { + return -1; + } + return CBB_finish_i2d(cbb.get(), outp); +} + +BSSL_NAMESPACE_END #endif // OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc b/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc index 2ff4614a7..1a3ec9694 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "../fipsmodule/aes/internal.h" #include "../fipsmodule/cipher/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc b/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc index a418df43f..3c18c91cd 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc @@ -31,7 +31,7 @@ typedef struct { EVP_CIPHER_CTX cipher_ctx; - HMAC_CTX hmac_ctx; + HMAC_CTX *hmac_ctx; // mac_key is the portion of the key used for the MAC. It is retained // separately for the constant-time CBC code. uint8_t mac_key[EVP_MAX_MD_SIZE]; @@ -51,15 +51,14 @@ static_assert(alignof(union evp_aead_ctx_st_state) >= alignof(AEAD_TLS_CTX), static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); - HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); + HMAC_CTX_free(tls_ctx->hmac_ctx); } static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, enum evp_aead_direction_t dir, const EVP_CIPHER *cipher, const EVP_MD *md, char implicit_iv) { - if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && - tag_len != EVP_MD_size(md)) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && tag_len != EVP_MD_size(md)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); return 0; } @@ -72,11 +71,15 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t mac_key_len = EVP_MD_size(md); size_t enc_key_len = EVP_CIPHER_key_length(cipher); assert(mac_key_len + enc_key_len + - (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); + (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == + key_len); AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + tls_ctx->hmac_ctx = HMAC_CTX_new(); + if (!tls_ctx->hmac_ctx) { + return 0; + } EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); - HMAC_CTX_init(&tls_ctx->hmac_ctx); assert(mac_key_len <= EVP_MAX_MD_SIZE); OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len); tls_ctx->mac_key_len = (uint8_t)mac_key_len; @@ -85,7 +88,7 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, dir == evp_aead_seal) || - !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { + !HMAC_Init_ex(tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { aead_tls_cleanup(ctx); return 0; } @@ -99,7 +102,7 @@ static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, assert(extra_in_len == 0); const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; - const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx); + const size_t hmac_len = HMAC_size(tls_ctx->hmac_ctx); if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { // The NULL cipher. return hmac_len; @@ -160,11 +163,11 @@ static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, // in-place. uint8_t mac[EVP_MAX_MD_SIZE]; unsigned mac_len; - if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || - !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || - !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { + if (!HMAC_Init_ex(tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len)) { return 0; } @@ -187,7 +190,8 @@ static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, // block from encrypting the input and split the result between |out| and // |out_tag|. Then feed the rest. - const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + const size_t early_mac_len = + (block_size - (in_len % block_size)) % block_size; if (early_mac_len != 0) { assert(len + block_size - early_mac_len == in_len); uint8_t buf[EVP_MAX_BLOCK_LENGTH]; @@ -245,7 +249,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, return 0; } - if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { + if (in_len < HMAC_size(tls_ctx->hmac_ctx)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } @@ -303,7 +307,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, if (!EVP_tls_cbc_remove_padding( &padding_ok, &data_plus_mac_len, out, total, EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), - HMAC_size(&tls_ctx->hmac_ctx))) { + HMAC_size(tls_ctx->hmac_ctx))) { // Publicly invalid. This can be rejected in non-constant time. OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; @@ -313,9 +317,9 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, data_plus_mac_len = total; // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has // already been checked against the MAC size at the top of the function. - assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); + assert(data_plus_mac_len >= HMAC_size(tls_ctx->hmac_ctx)); } - size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + size_t data_len = data_plus_mac_len - HMAC_size(tls_ctx->hmac_ctx); // At this point, if the padding is valid, the first |data_plus_mac_len| bytes // after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is @@ -335,14 +339,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; uint8_t *record_mac; if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && - EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { - if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len, ad_fixed, out, data_len, total, tls_ctx->mac_key, tls_ctx->mac_key_len)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } - assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + assert(mac_len == HMAC_size(tls_ctx->hmac_ctx)); record_mac = record_mac_tmp; EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); @@ -352,15 +356,15 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); unsigned mac_len_u; - if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || - !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || - !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { + if (!HMAC_Init_ex(tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len_u)) { return 0; } mac_len = mac_len_u; - assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + assert(mac_len == HMAC_size(tls_ctx->hmac_ctx)); record_mac = &out[data_len]; } diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc b/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc index 24a6e3183..43934b950 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc @@ -55,17 +55,17 @@ static const struct { }; const EVP_CIPHER *EVP_get_cipherbynid(int nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { - if (kCiphers[i].nid == nid) { - return kCiphers[i].func(); + for (const auto &cipher : kCiphers) { + if (cipher.nid == nid) { + return cipher.func(); } } - return NULL; + return nullptr; } const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { - if (name == NULL) { - return NULL; + if (name == nullptr) { + return nullptr; } // This is not a name used by OpenSSL, but tcpdump registers it with @@ -75,11 +75,11 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { name = "des-ede3-cbc"; } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { - if (OPENSSL_strcasecmp(kCiphers[i].name, name) == 0) { - return kCiphers[i].func(); + for (const auto &cipher : kCiphers) { + if (OPENSSL_strcasecmp(cipher.name, name) == 0) { + return cipher.func(); } } - return NULL; + return nullptr; } diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/internal.h b/Sources/CCryptoBoringSSL/crypto/cipher/internal.h index a4106a4f1..6fde1487e 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/cipher/internal.h @@ -19,6 +19,7 @@ #include #include +#include #include "../internal.h" @@ -129,7 +130,7 @@ union chacha20_poly1305_seal_data { } out; }; -#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ +#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_NO_ASM) static_assert(sizeof(union chacha20_poly1305_open_data) == 48, diff --git a/Sources/CCryptoBoringSSL/crypto/conf/conf.cc b/Sources/CCryptoBoringSSL/crypto/conf/conf.cc index f29418e98..94931bf7c 100644 --- a/Sources/CCryptoBoringSSL/crypto/conf/conf.cc +++ b/Sources/CCryptoBoringSSL/crypto/conf/conf.cc @@ -623,6 +623,8 @@ int CONF_modules_load_file(const char *filename, const char *appname, return 1; } +void CONF_modules_unload(int all) {} + void CONF_modules_free(void) {} void OPENSSL_config(const char *config_name) {} diff --git a/Sources/CCryptoBoringSSL/crypto/crypto.cc b/Sources/CCryptoBoringSSL/crypto/crypto.cc index 773e351d0..d94b6f810 100644 --- a/Sources/CCryptoBoringSSL/crypto/crypto.cc +++ b/Sources/CCryptoBoringSSL/crypto/crypto.cc @@ -137,6 +137,8 @@ void ENGINE_load_builtin_engines(void) {} int ENGINE_register_all_complete(void) { return 1; } +void ENGINE_cleanup(void) {} + void OPENSSL_load_builtin_modules(void) {} int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { diff --git a/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc b/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc index 5a2bdf65b..c61e31361 100644 --- a/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc @@ -24,7 +24,7 @@ #include #include -#include +#include #include "../internal.h" #include "internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc b/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc index b04f875f4..8f890faea 100644 --- a/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc @@ -17,10 +17,12 @@ #include #include +#include + #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../internal.h" @@ -333,18 +335,17 @@ static const scalar kOrder = { // scalar_cmov copies |src| to |dest| if |mask| is all ones. static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { bn_select_words(dest->words, mask, src->words, dest->words, - OPENSSL_ARRAY_SIZE(dest->words)); + std::size(dest->words)); } // scalar_double sets |s| to |2×s|. static void scalar_double(scalar *s) { - bn_add_words(s->words, s->words, s->words, OPENSSL_ARRAY_SIZE(s->words)); + bn_add_words(s->words, s->words, s->words, std::size(s->words)); } // scalar_add sets |dest| to |dest| plus |src|. static void scalar_add(scalar *dest, const scalar *src) { - bn_add_words(dest->words, dest->words, src->words, - OPENSSL_ARRAY_SIZE(dest->words)); + bn_add_words(dest->words, dest->words, src->words, std::size(dest->words)); } int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, diff --git a/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc b/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc index 60fe212c7..3c44926d1 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc @@ -95,29 +95,11 @@ int DH_marshal_parameters(CBB *cbb, const DH *dh) { } DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DH *ret = DH_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DH_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DH_parse_parameters); } int i2d_DHparams(const DH *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DH_marshal_parameters(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DH_marshal_parameters(cbb, in); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/dh/params.cc b/Sources/CCryptoBoringSSL/crypto/dh/params.cc index 02287926f..35fcf9a09 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh/params.cc +++ b/Sources/CCryptoBoringSSL/crypto/dh/params.cc @@ -17,13 +17,13 @@ #include #include #include +#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) { +static BIGNUM *get_params(BIGNUM *ret, bssl::Span words) { BIGNUM *alloc = NULL; if (ret == NULL) { alloc = BN_new(); @@ -33,7 +33,7 @@ static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, ret = alloc; } - if (!bn_set_words(ret, words, num_words)) { + if (!bn_set_words(ret, words.data(), words.size())) { BN_free(alloc); return NULL; } @@ -56,7 +56,7 @@ BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret) { @@ -78,7 +78,7 @@ BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret) { @@ -108,7 +108,7 @@ BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret) { @@ -146,7 +146,7 @@ BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret) { @@ -200,7 +200,7 @@ BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret) { @@ -270,7 +270,7 @@ BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, diff --git a/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc b/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc index d7b0c1a06..ab46cd9d7 100644 --- a/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc +++ b/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "../asn1/internal.h" #include "../fipsmodule/digest/internal.h" @@ -71,9 +73,9 @@ const EVP_MD *EVP_get_digestbynid(int nid) { return NULL; } - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { - if (nid_to_digest_mapping[i].nid == nid) { - return nid_to_digest_mapping[i].md_func(); + for (const auto &mapping : nid_to_digest_mapping) { + if (mapping.nid == nid) { + return mapping.md_func(); } } @@ -101,42 +103,41 @@ static const struct { {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224}, }; -static const EVP_MD *cbs_to_md(const CBS *cbs) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { - if (CBS_len(cbs) == kMDOIDs[i].oid_len && - OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == - 0) { - return EVP_get_digestbynid(kMDOIDs[i].nid); +static int cbs_to_digest_nid(const CBS *cbs) { + for (const auto &md : kMDOIDs) { + if (bssl::Span(*cbs) == + bssl::Span(md.oid).first(md.oid_len)) { + return md.nid; } } - - return NULL; + return NID_undef; } const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) { - // Handle objects with no corresponding OID. Note we don't use |OBJ_obj2nid| - // here to avoid pulling in the OID table. - if (obj->nid != NID_undef) { - return EVP_get_digestbynid(obj->nid); + int nid = obj->nid; + if (nid == NID_undef) { + // Handle objects with no saved NID. Note we don't use |OBJ_obj2nid| here to + // avoid pulling in the OID table. + CBS cbs; + CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj)); + nid = cbs_to_digest_nid(&cbs); } - CBS cbs; - CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj)); - return cbs_to_md(&cbs); + return nid == NID_undef ? nullptr : EVP_get_digestbynid(nid); } -const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { +int EVP_parse_digest_algorithm_nid(CBS *cbs) { CBS algorithm, oid; if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); - return NULL; + return NID_undef; } - const EVP_MD *ret = cbs_to_md(&oid); - if (ret == NULL) { + int ret = cbs_to_digest_nid(&oid); + if (ret == NID_undef) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); - return NULL; + return NID_undef; } // The parameters, if present, must be NULL. Historically, whether the NULL @@ -149,13 +150,21 @@ const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { CBS_len(¶m) != 0 || // CBS_len(&algorithm) != 0) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); - return NULL; + return NID_undef; } } return ret; } +const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { + int nid = EVP_parse_digest_algorithm_nid(cbs); + if (nid == NID_undef) { + return nullptr; + } + return EVP_get_digestbynid(nid); +} + static int marshal_digest_algorithm(CBB *cbb, const EVP_MD *md, bool with_null) { CBB algorithm, oid, null; @@ -198,16 +207,16 @@ int EVP_marshal_digest_algorithm_no_params(CBB *cbb, const EVP_MD *md) { } const EVP_MD *EVP_get_digestbyname(const char *name) { - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { - const char *short_name = nid_to_digest_mapping[i].short_name; - const char *long_name = nid_to_digest_mapping[i].long_name; + for (const auto &mapping : nid_to_digest_mapping) { + const char *short_name = mapping.short_name; + const char *long_name = mapping.long_name; if ((short_name && strcmp(short_name, name) == 0) || (long_name && strcmp(long_name, name) == 0)) { - return nid_to_digest_mapping[i].md_func(); + return mapping.md_func(); } } - return NULL; + return nullptr; } static void blake2b256_init(EVP_MD_CTX *ctx) { @@ -230,6 +239,8 @@ static const EVP_MD evp_md_blake2b256 = { const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; } +static_assert(sizeof(BLAKE2B_CTX) <= EVP_MAX_MD_DATA_SIZE); + static void md4_init(EVP_MD_CTX *ctx) { BSSL_CHECK(MD4_Init(reinterpret_cast(ctx->md_data))); @@ -257,6 +268,9 @@ static const EVP_MD evp_md_md4 = { const EVP_MD *EVP_md4(void) { return &evp_md_md4; } +static_assert(sizeof(MD4_CTX) <= EVP_MAX_MD_DATA_SIZE); + + static void md5_init(EVP_MD_CTX *ctx) { BSSL_CHECK(MD5_Init(reinterpret_cast(ctx->md_data))); } @@ -277,6 +291,9 @@ static const EVP_MD evp_md_md5 = { const EVP_MD *EVP_md5(void) { return &evp_md_md5; } +static_assert(sizeof(MD5_CTX) <= EVP_MAX_MD_DATA_SIZE); + + typedef struct { MD5_CTX md5; SHA_CTX sha1; @@ -312,3 +329,5 @@ const EVP_MD evp_md_md5_sha1 = { }; const EVP_MD *EVP_md5_sha1(void) { return &evp_md_md5_sha1; } + +static_assert(sizeof(MD5_SHA1_CTX) <= EVP_MAX_MD_DATA_SIZE); diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc index 778237d3e..cbc382731 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/dh/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc index 743f21fdf..08a63413d 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc @@ -255,113 +255,41 @@ int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { } DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA_SIG *ret = DSA_SIG_parse(&cbs); - if (ret == NULL) { - return NULL; - } - if (out_sig != NULL) { - DSA_SIG_free(*out_sig); - *out_sig = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out_sig, inp, len, DSA_SIG_parse); } int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_SIG_marshal(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_SIG_marshal(cbb, in); }); } DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_public_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_public_key); } int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_public_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_public_key(cbb, in); }); } DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_private_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_private_key); } int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_private_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_private_key(cbb, in); }); } DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_parameters); } int i2d_DSAparams(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_parameters(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_parameters(cbb, in); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc b/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc index e7e4ff339..092e8845b 100644 --- a/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include #include @@ -27,6 +30,7 @@ #include "../bytestring/internal.h" #include "../fipsmodule/ec/internal.h" #include "../internal.h" +#include "internal.h" static const CBS_ASN1_TAG kParametersTag = @@ -34,17 +38,23 @@ static const CBS_ASN1_TAG kParametersTag = static const CBS_ASN1_TAG kPublicKeyTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -// TODO(https://crbug.com/boringssl/497): Allow parsers to specify a list of -// acceptable groups, so parsers don't have to pull in all four. -typedef const EC_GROUP *(*ec_group_func)(void); -static const ec_group_func kAllGroups[] = { - &EC_group_p224, - &EC_group_p256, - &EC_group_p384, - &EC_group_p521, -}; +static auto get_all_groups() { + return std::array{ + EC_group_p224(), + EC_group_p256(), + EC_group_p384(), + EC_group_p521(), + }; +} + +EC_KEY *ec_key_parse_private_key( + CBS *cbs, const EC_GROUP *group, + bssl::Span allowed_groups) { + // If a group was supplied externally, no other groups can be parsed. + if (group != nullptr) { + allowed_groups = bssl::Span(&group, 1); + } -EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { CBS ec_private_key, private_key; uint64_t version; if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) || @@ -66,23 +76,31 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); return nullptr; } - const EC_GROUP *inner_group = EC_KEY_parse_parameters(&child); + const EC_GROUP *inner_group = + ec_key_parse_parameters(&child, allowed_groups); if (inner_group == nullptr) { + // If the caller already supplied a group, any explicit group is required + // to match. On mismatch, |ec_key_parse_parameters| will fail to recognize + // any other groups, so remap the error. + if (group != nullptr && + ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + } return nullptr; } - if (group == nullptr) { - group = inner_group; - } else if (EC_GROUP_cmp(group, inner_group, nullptr) != 0) { - // If a group was supplied externally, it must match. - OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); - return nullptr; - } + // Overriding |allowed_groups| above ensures the only returned group will be + // the matching one. + assert(group == nullptr || inner_group == group); + group = inner_group; if (CBS_len(&child) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); return nullptr; } } + // The group must have been specified either externally, or explicitly in the + // structure. if (group == nullptr) { OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); return nullptr; @@ -151,6 +169,10 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { return ret.release(); } +EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + return ec_key_parse_private_key(cbs, group, get_all_groups()); +} + int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, unsigned enc_flags) { if (key == NULL || key->group == NULL || key->priv_key == NULL) { @@ -296,23 +318,29 @@ static int integers_equal(const CBS *bytes, const BIGNUM *bn) { return CBS_mem_equal(©, buf, CBS_len(©)); } -EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { +const EC_GROUP *ec_key_parse_curve_name( + CBS *cbs, bssl::Span allowed_groups) { CBS named_curve; if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); - return NULL; + return nullptr; } // Look for a matching curve. - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kAllGroups); i++) { - const EC_GROUP *group = kAllGroups[i](); - if (CBS_mem_equal(&named_curve, group->oid, group->oid_len)) { - return (EC_GROUP *)group; + for (const EC_GROUP *group : allowed_groups) { + if (named_curve == bssl::Span(group->oid, group->oid_len)) { + return group; } } OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); - return NULL; + return nullptr; +} + +EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { + // This function only ever returns a static |EC_GROUP|, but currently returns + // a non-const pointer for historical reasons. + return const_cast(ec_key_parse_curve_name(cbs, get_all_groups())); } int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { @@ -324,9 +352,10 @@ int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { return CBB_add_asn1_element(cbb, CBS_ASN1_OBJECT, group->oid, group->oid_len); } -EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { +const EC_GROUP *ec_key_parse_parameters( + CBS *cbs, bssl::Span allowed_groups) { if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { - return EC_KEY_parse_curve_name(cbs); + return ec_key_parse_curve_name(cbs, allowed_groups); } // OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions @@ -348,8 +377,7 @@ EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { return nullptr; } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kAllGroups); i++) { - const EC_GROUP *group = kAllGroups[i](); + for (const EC_GROUP *group : allowed_groups) { if (!integers_equal(&curve.order, EC_GROUP_get0_order(group))) { continue; } @@ -372,13 +400,19 @@ EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { !integers_equal(&curve.base_y, y.get())) { break; } - return const_cast(group); + return group; } OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); return nullptr; } +EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { + // This function only ever returns a static |EC_GROUP|, but currently returns + // a non-const pointer for historical reasons. + return const_cast(ec_key_parse_parameters(cbs, get_all_groups())); +} + int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, BN_CTX *ctx) { size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); @@ -398,52 +432,20 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) { group = EC_KEY_get0_group(*out); } - if (len < 0) { - OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - EC_KEY_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, [&](CBS *cbs) { + return EC_KEY_parse_private_key(cbs, group); + }); } int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/64, outp, [&](CBB *cbb) -> bool { + return EC_KEY_marshal_private_key(cbb, key, EC_KEY_get_enc_flags(key)); + }); } EC_GROUP *d2i_ECPKParameters(EC_GROUP **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - EC_GROUP *ret = EC_KEY_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - - if (out != NULL) { - EC_GROUP_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, EC_KEY_parse_parameters); } int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { @@ -451,40 +453,24 @@ int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return -1; } - - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_KEY_marshal_curve_name(&cbb, group)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/16, outp, + [&](CBB *cbb) -> bool { return EC_KEY_marshal_curve_name(cbb, group); }); } EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - const EC_GROUP *group = EC_KEY_parse_parameters(&cbs); - if (group == NULL) { - return NULL; - } - - EC_KEY *ret = EC_KEY_new(); - if (ret == NULL || !EC_KEY_set_group(ret, group)) { - EC_KEY_free(ret); - return NULL; - } - - if (out_key != NULL) { - EC_KEY_free(*out_key); - *out_key = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS( + out_key, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + const EC_GROUP *group = EC_KEY_parse_parameters(cbs); + if (group == nullptr) { + return nullptr; + } + bssl::UniquePtr ret(EC_KEY_new()); + if (ret == nullptr || !EC_KEY_set_group(ret.get(), group)) { + return nullptr; + } + return ret; + }); } int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { @@ -492,14 +478,10 @@ int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return -1; } - - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_KEY_marshal_curve_name(&cbb, key->group)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/16, outp, [&](CBB *cbb) -> bool { + return EC_KEY_marshal_curve_name(cbb, key->group); + }); } EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { @@ -529,27 +511,25 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_POINT_point2cbb(&cbb, key->group, key->pub_key, key->conv_form, - NULL)) { - CBB_cleanup(&cbb); - return -1; - } - int ret = CBB_finish_i2d(&cbb, outp); + // No initial capacity because |EC_POINT_point2cbb| will internally reserve + // the right size in one shot, so it's best to leave this at zero. + int ret = bssl::I2DFromCBB( + /*initial_capacity=*/0, outp, [&](CBB *cbb) -> bool { + return EC_POINT_point2cbb(cbb, key->group, key->pub_key, key->conv_form, + nullptr); + }); // Historically, this function used the wrong return value on error. return ret > 0 ? ret : 0; } size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, size_t max_num_curves) { - if (max_num_curves > OPENSSL_ARRAY_SIZE(kAllGroups)) { - max_num_curves = OPENSSL_ARRAY_SIZE(kAllGroups); - } + auto all = get_all_groups(); + max_num_curves = std::min(all.size(), max_num_curves); for (size_t i = 0; i < max_num_curves; i++) { - const EC_GROUP *group = kAllGroups[i](); + const EC_GROUP *group = all[i]; out_curves[i].nid = group->curve_name; out_curves[i].comment = group->comment; } - return OPENSSL_ARRAY_SIZE(kAllGroups); + return all.size(); } diff --git a/Sources/CCryptoBoringSSL/crypto/ec/internal.h b/Sources/CCryptoBoringSSL/crypto/ec/internal.h index 336c3f298..7409e888b 100644 --- a/Sources/CCryptoBoringSSL/crypto/ec/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/ec/internal.h @@ -17,6 +17,8 @@ #include +#include + #include "../fipsmodule/ec/internal.h" #if defined(__cplusplus) @@ -24,6 +26,31 @@ extern "C" { #endif +// Parsing functions. + +// ec_key_parse_curve_name behaves like |EC_KEY_parse_curve_name| but only +// supports the groups in |allowed_groups|. If no syntax errors were found but +// the group is unknown, it will fail with an error of |EC_R_UNKNOWN_GROUP|. +const EC_GROUP *ec_key_parse_curve_name( + CBS *cbs, bssl::Span allowed_groups); + +// ec_key_parse_parameters behaves like |EC_KEY_parse_parameters| but only +// supports the groups in |allowed_groups|. If no syntax errors were found but +// the group is unknown, it will fail with an error of |EC_R_UNKNOWN_GROUP|. +const EC_GROUP *ec_key_parse_parameters( + CBS *cbs, bssl::Span allowed_groups); + +// ec_key_parse_private_key behaves like |EC_KEY_parse_private_key| but only +// supports the groups in |allowed_groups|. If |group| is non-NULL, +// |allowed_groups| is ignored and instead only |group| is supported. +// +// TODO(crbug.com/boringssl/414361735): This should return a bssl::UniquePtr, +// but cannot until it is made C++ linkage. +EC_KEY *ec_key_parse_private_key( + CBS *cbs, const EC_GROUP *group, + bssl::Span allowed_groups); + + // Hash-to-curve. // // Internal |EC_JACOBIAN| versions of the corresponding public APIs. diff --git a/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc index b2dd3b259..8c06fcea3 100644 --- a/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc @@ -324,28 +324,11 @@ size_t ECDSA_SIG_max_len(size_t order_len) { } ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - ECDSA_SIG_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, ECDSA_SIG_parse); } int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || !ECDSA_SIG_marshal(&cbb, sig)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/64, outp, + [&](CBB *cbb) -> bool { return ECDSA_SIG_marshal(cbb, sig); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp.cc index c14565da1..9afa1ff6f 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp.cc @@ -41,19 +41,10 @@ EVP_PKEY *EVP_PKEY_new(void) { return NULL; } - ret->type = EVP_PKEY_NONE; ret->references = 1; return ret; } -static void free_it(EVP_PKEY *pkey) { - if (pkey->ameth && pkey->ameth->pkey_free) { - pkey->ameth->pkey_free(pkey); - pkey->pkey = NULL; - pkey->type = EVP_PKEY_NONE; - } -} - void EVP_PKEY_free(EVP_PKEY *pkey) { if (pkey == NULL) { return; @@ -63,7 +54,7 @@ void EVP_PKEY_free(EVP_PKEY *pkey) { return; } - free_it(pkey); + evp_pkey_set0(pkey, nullptr, nullptr); OPENSSL_free(pkey); } @@ -80,7 +71,7 @@ int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - if (a->type != b->type) { + if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) { return -1; } @@ -103,9 +94,13 @@ 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 == EVP_PKEY_NONE) { - evp_pkey_set_method(to, from->ameth); - } else if (to->type != from->type) { + if (EVP_PKEY_id(to) == EVP_PKEY_NONE) { + // TODO(crbug.com/42290409): This shouldn't leave |to| in a half-empty state + // on error. The complexity here largely comes from parameterless DSA keys, + // which we no longer support, so this function can probably be trimmed + // down. + evp_pkey_set0(to, from->ameth, nullptr); + } else if (EVP_PKEY_id(to) != EVP_PKEY_id(from)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); return 0; } @@ -128,8 +123,9 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { return from->ameth->param_copy(to, from); } - // TODO(https://crbug.com/boringssl/536): If the algorithm takes no - // parameters, copying them should vacuously succeed. + // TODO(https://crbug.com/42290406): If the algorithm takes no parameters, + // copying them should vacuously succeed. Better yet, simplify this whole + // notion of parameter copying above. return 0; } @@ -154,32 +150,17 @@ int EVP_PKEY_bits(const EVP_PKEY *pkey) { return 0; } -int EVP_PKEY_id(const EVP_PKEY *pkey) { return pkey->type; } - -// evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which -// should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is -// unknown. -static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { - switch (nid) { - case EVP_PKEY_RSA: - return &rsa_asn1_meth; - case EVP_PKEY_EC: - return &ec_asn1_meth; - case EVP_PKEY_DSA: - return &dsa_asn1_meth; - case EVP_PKEY_ED25519: - return &ed25519_asn1_meth; - case EVP_PKEY_X25519: - return &x25519_asn1_meth; - default: - return NULL; - } +int EVP_PKEY_id(const EVP_PKEY *pkey) { + return pkey->ameth != nullptr ? pkey->ameth->pkey_id : EVP_PKEY_NONE; } -void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method) { - free_it(pkey); +void evp_pkey_set0(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method, + void *pkey_data) { + if (pkey->ameth && pkey->ameth->pkey_free) { + pkey->ameth->pkey_free(pkey); + } pkey->ameth = method; - pkey->type = pkey->ameth->pkey_id; + pkey->pkey = pkey_data; } int EVP_PKEY_type(int nid) { @@ -210,84 +191,85 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { if (pkey && pkey->pkey) { - // This isn't strictly necessary, but historically |EVP_PKEY_set_type| would - // clear |pkey| even if |evp_pkey_asn1_find| failed, so we preserve that - // behavior. - free_it(pkey); + // Some callers rely on |pkey| getting cleared even if |type| is + // unsupported, usually setting |type| to |EVP_PKEY_NONE|. + evp_pkey_set0(pkey, nullptr, nullptr); } - const EVP_PKEY_ASN1_METHOD *ameth = evp_pkey_asn1_find(type); - if (ameth == NULL) { + // This function broadly isn't useful. It initializes |EVP_PKEY| for a type, + // but forgets to put anything in the |pkey|. The one pattern where it does + // anything is |EVP_PKEY_X25519|, where it's needed to make + // |EVP_PKEY_set1_tls_encodedpoint| work, so we support only that. + const EVP_PKEY_ASN1_METHOD *ameth; + if (type == EVP_PKEY_X25519) { + ameth = &x25519_asn1_meth; + } else { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", type); return 0; } if (pkey) { - evp_pkey_set_method(pkey, ameth); + evp_pkey_set0(pkey, ameth, nullptr); } return 1; } +EVP_PKEY *EVP_PKEY_from_raw_private_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, size_t len) { + if (alg->method->set_priv_raw == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; + } + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr || !alg->method->set_priv_raw(ret.get(), in, len)) { + return nullptr; + } + return ret.release(); +} + +EVP_PKEY *EVP_PKEY_from_raw_public_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, size_t len) { + if (alg->method->set_pub_raw == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; + } + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr || !alg->method->set_pub_raw(ret.get(), in, len)) { + return nullptr; + } + return ret.release(); +} + EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, const uint8_t *in, size_t len) { // To avoid pulling in all key types, look for specifically the key types that // support |set_priv_raw|. - const EVP_PKEY_ASN1_METHOD *method; switch (type) { case EVP_PKEY_X25519: - method = &x25519_asn1_meth; - break; + return EVP_PKEY_from_raw_private_key(EVP_pkey_x25519(), in, len); case EVP_PKEY_ED25519: - method = &ed25519_asn1_meth; - break; + return EVP_PKEY_from_raw_private_key(EVP_pkey_ed25519(), in, len); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); return nullptr; } - - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - evp_pkey_set_method(ret.get(), method); - - if (!ret->ameth->set_priv_raw(ret.get(), in, len)) { - return nullptr; - } - - return ret.release(); } EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, const uint8_t *in, size_t len) { // To avoid pulling in all key types, look for specifically the key types that // support |set_pub_raw|. - const EVP_PKEY_ASN1_METHOD *method; switch (type) { case EVP_PKEY_X25519: - method = &x25519_asn1_meth; - break; + return EVP_PKEY_from_raw_public_key(EVP_pkey_x25519(), in, len); case EVP_PKEY_ED25519: - method = &ed25519_asn1_meth; - break; + return EVP_PKEY_from_raw_public_key(EVP_pkey_ed25519(), in, len); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); return nullptr; } - - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - evp_pkey_set_method(ret.get(), method); - - if (!ret->ameth->set_pub_raw(ret.get(), in, len)) { - return nullptr; - } - - return ret.release(); } int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out, @@ -311,7 +293,7 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out, } int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - if (a->type != b->type) { + if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) { return -1; } if (a->ameth && a->ameth->param_cmp) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc index 6740d4a2b..26c4b29dd 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc @@ -16,84 +16,68 @@ #include +#include + #include #include #include #include #include +#include #include "internal.h" #include "../bytestring/internal.h" #include "../internal.h" -// We intentionally omit |dh_asn1_meth| from this list. It is not serializable. -static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { - &rsa_asn1_meth, - &ec_asn1_meth, - &dsa_asn1_meth, - &ed25519_asn1_meth, - &x25519_asn1_meth, -}; - -static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) { - CBS oid; - if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { - return NULL; - } - - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { - const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; - if (CBS_len(&oid) == method->oid_len && - OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { - return method; - } - } - - return NULL; -} - -EVP_PKEY *EVP_parse_public_key(CBS *cbs) { +EVP_PKEY *EVP_PKEY_from_subject_public_key_info(const uint8_t *in, size_t len, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { // Parse the SubjectPublicKeyInfo. - CBS spki, algorithm, key; - uint8_t padding; - if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || + CBS cbs, spki, algorithm, oid, key; + CBS_init(&cbs, in, len); + if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || - CBS_len(&spki) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return nullptr; - } - const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm); - if (method == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (// Every key type defined encodes the key as a byte string with the same - // conversion to BIT STRING. - !CBS_get_u8(&key, &padding) || - padding != 0) { + CBS_len(&spki) != 0 || // + CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return nullptr; } - // Set up an |EVP_PKEY| of the appropriate type. bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { return nullptr; } - evp_pkey_set_method(ret.get(), method); - - // Call into the type-specific SPKI decoding function. - if (ret->ameth->pub_decode == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (!ret->ameth->pub_decode(ret.get(), &algorithm, &key)) { - return nullptr; + for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) { + if (alg->method->pub_decode == nullptr || + bssl::Span(alg->method->oid, alg->method->oid_len) != oid) { + continue; + } + // Every key type we support encodes the key as a byte string with the same + // conversion to BIT STRING, so perform that common conversion ahead of + // time, but only after the OID is recognized as supported. + CBS key_bytes = key; + uint8_t padding; + if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + CBS params = algorithm; + switch (alg->method->pub_decode(alg, ret.get(), ¶ms, &key_bytes)) { + case evp_decode_error: + return nullptr; + case evp_decode_ok: + return ret.release(); + case evp_decode_unsupported: + // Continue trying other algorithms. + break; + } } - return ret.release(); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; } int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { @@ -105,43 +89,47 @@ int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { return key->ameth->pub_encode(cbb, key); } -EVP_PKEY *EVP_parse_private_key(CBS *cbs) { +EVP_PKEY *EVP_PKEY_from_private_key_info(const uint8_t *in, size_t len, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { // Parse the PrivateKeyInfo. - CBS pkcs8, algorithm, key; + CBS cbs, pkcs8, oid, algorithm, key; uint64_t version; - if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1_uint64(&pkcs8, &version) || - version != 0 || + CBS_init(&cbs, in, len); + if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 || !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) || + // A PrivateKeyInfo ends with a SET of Attributes which we ignore. + CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return nullptr; } - const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm); - if (method == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - - // A PrivateKeyInfo ends with a SET of Attributes which we ignore. - // Set up an |EVP_PKEY| of the appropriate type. bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { return nullptr; } - evp_pkey_set_method(ret.get(), method); - - // Call into the type-specific PrivateKeyInfo decoding function. - if (ret->ameth->priv_decode == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (!ret->ameth->priv_decode(ret.get(), &algorithm, &key)) { - return nullptr; + for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) { + if (alg->method->priv_decode == nullptr || + bssl::Span(alg->method->oid, alg->method->oid_len) != oid) { + continue; + } + CBS params = algorithm, key_copy = key; + switch (alg->method->priv_decode(alg, ret.get(), ¶ms, &key_copy)) { + case evp_decode_error: + return nullptr; + case evp_decode_ok: + return ret.release(); + case evp_decode_unsupported: + // Continue trying other algorithms. + break; + } } - return ret.release(); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; } int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { @@ -153,6 +141,30 @@ int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { return key->ameth->priv_encode(cbb, key); } +EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + + auto algs = bssl::GetDefaultEVPAlgorithms(); + return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem), + algs.data(), algs.size()); +} + +EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + + auto algs = bssl::GetDefaultEVPAlgorithms(); + return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem), + algs.data(), algs.size()); +} + static bssl::UniquePtr old_priv_decode(CBS *cbs, int type) { bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { @@ -192,35 +204,26 @@ static bssl::UniquePtr old_priv_decode(CBS *cbs, int type) { EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, long len) { - if (len < 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return nullptr; - } - - // Parse with the legacy format. - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr ret = old_priv_decode(&cbs, type); - if (ret == nullptr) { - // Try again with PKCS#8. - ERR_clear_error(); - CBS_init(&cbs, *inp, (size_t)len); - ret.reset(EVP_parse_private_key(&cbs)); - if (ret == nullptr) { - return nullptr; - } - if (ret->type != type) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); - return nullptr; - } - } - - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - *inp = CBS_data(&cbs); - return ret.release(); + return bssl::D2IFromCBS( + out, inp, len, [&](CBS *cbs) -> bssl::UniquePtr { + // Parse with the legacy format. + CBS copy = *cbs; + bssl::UniquePtr ret = old_priv_decode(cbs, type); + if (ret == nullptr) { + // Try again with PKCS#8. + ERR_clear_error(); + *cbs = copy; + ret.reset(EVP_parse_private_key(cbs)); + if (ret == nullptr) { + return nullptr; + } + if (EVP_PKEY_id(ret.get()) != type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + return nullptr; + } + } + return ret; + }); } // num_elements parses one SEQUENCE from |in| and returns the number of elements @@ -279,7 +282,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { } int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { - switch (key->type) { + switch (EVP_PKEY_id(key)) { case EVP_PKEY_RSA: return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp); case EVP_PKEY_DSA: @@ -294,93 +297,70 @@ int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp, long len) { - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - - CBS cbs; - CBS_init(&cbs, *inp, len < 0 ? 0 : (size_t)len); - switch (type) { - case EVP_PKEY_RSA: { - bssl::UniquePtr rsa(RSA_parse_public_key(&cbs)); - if (rsa == nullptr) { - return nullptr; - } - EVP_PKEY_assign_RSA(ret.get(), rsa.release()); - break; - } - - // Unlike OpenSSL, we do not support EC keys with this API. The raw EC - // public key serialization requires knowing the group. In OpenSSL, calling - // this function with |EVP_PKEY_EC| and setting |out| to nullptr does not - // work. It requires |*out| to include a partially-initialized |EVP_PKEY| to - // extract the group. - default: - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return nullptr; - } - - *inp = CBS_data(&cbs); - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - return ret.release(); + return bssl::D2IFromCBS( + out, inp, len, [&](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr) { + return nullptr; + } + switch (type) { + case EVP_PKEY_RSA: { + bssl::UniquePtr rsa(RSA_parse_public_key(cbs)); + if (rsa == nullptr) { + return nullptr; + } + EVP_PKEY_assign_RSA(ret.get(), rsa.release()); + return ret; + } + + // Unlike OpenSSL, we do not support EC keys with this API. The raw EC + // public key serialization requires knowing the group. In OpenSSL, + // calling this function with |EVP_PKEY_EC| and setting |out| to + // nullptr does not work. It requires |*out| to include a + // partially-initialized |EVP_PKEY| to extract the group. + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return nullptr; + } + }); } EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr ret(EVP_parse_public_key(&cbs)); - if (ret == nullptr) { - return nullptr; - } - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - *inp = CBS_data(&cbs); - return ret.release(); + return bssl::D2IFromCBS(out, inp, len, EVP_parse_public_key); } int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) { - if (pkey == NULL) { + if (pkey == nullptr) { return 0; } + return bssl::I2DFromCBB( + /*initial_capacity=*/128, outp, + [&](CBB *cbb) -> bool { return EVP_marshal_public_key(cbb, pkey); }); +} - CBB cbb; - if (!CBB_init(&cbb, 128) || - !EVP_marshal_public_key(&cbb, pkey)) { - CBB_cleanup(&cbb); - return -1; +static bssl::UniquePtr parse_spki( + CBS *cbs, bssl::Span algs) { + CBS spki; + if (!CBS_get_asn1_element(cbs, &spki, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; } - return CBB_finish_i2d(&cbb, outp); + return bssl::UniquePtr(EVP_PKEY_from_subject_public_key_info( + CBS_data(&spki), CBS_len(&spki), algs.data(), algs.size())); +} + +static bssl::UniquePtr parse_spki(CBS *cbs, const EVP_PKEY_ALG *alg) { + return parse_spki(cbs, bssl::Span(&alg, 1)); } RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr rsa(EVP_PKEY_get1_RSA(pkey.get())); - if (rsa == nullptr) { - return nullptr; - } - if (out != nullptr) { - RSA_free(*out); - *out = rsa.get(); - } - *inp = CBS_data(&cbs); - return rsa.release(); + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr pkey = parse_spki(cbs, EVP_pkey_rsa()); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_RSA(pkey.get())); + }); } int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) { @@ -398,25 +378,13 @@ int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) { } DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr dsa(EVP_PKEY_get1_DSA(pkey.get())); - if (dsa == nullptr) { - return nullptr; - } - if (out != nullptr) { - DSA_free(*out); - *out = dsa.get(); - } - *inp = CBS_data(&cbs); - return dsa.release(); + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr pkey = parse_spki(cbs, EVP_pkey_dsa()); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_DSA(pkey.get())); + }); } int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) { @@ -434,25 +402,17 @@ int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) { } EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey.get())); - if (ec_key == nullptr) { - return nullptr; - } - if (out != nullptr) { - EC_KEY_free(*out); - *out = ec_key.get(); - } - *inp = CBS_data(&cbs); - return ec_key.release(); + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + const EVP_PKEY_ALG *const algs[] = { + EVP_pkey_ec_p224(), EVP_pkey_ec_p256(), EVP_pkey_ec_p384(), + EVP_pkey_ec_p521()}; + bssl::UniquePtr pkey = parse_spki(cbs, algs); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_EC_KEY(pkey.get())); + }); } int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc index ebf9034f6..f9ff9b94c 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc @@ -25,29 +25,31 @@ #include "internal.h" -static const EVP_PKEY_METHOD *const evp_methods[] = { +// |EVP_PKEY_RSA_PSS| is intentionally omitted from this list. These are types +// that can be created without an |EVP_PKEY|, and we do not support +// |EVP_PKEY_RSA_PSS| keygen. +static const EVP_PKEY_CTX_METHOD *const evp_methods[] = { &rsa_pkey_meth, &ec_pkey_meth, &ed25519_pkey_meth, &x25519_pkey_meth, &hkdf_pkey_meth, }; -static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { - for (size_t i = 0; i < sizeof(evp_methods) / sizeof(EVP_PKEY_METHOD *); i++) { - if (evp_methods[i]->pkey_id == type) { - return evp_methods[i]; +static const EVP_PKEY_CTX_METHOD *evp_pkey_meth_find(int type) { + for (auto method : evp_methods) { + if (method->pkey_id == type) { + return method; } } - return NULL; + return nullptr; } -static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, - const EVP_PKEY_METHOD *pmeth) { +static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, + const EVP_PKEY_CTX_METHOD *pmeth) { bssl::UniquePtr ret = bssl::MakeUnique(); if (!ret) { return nullptr; } - ret->engine = e; ret->pmeth = pmeth; ret->operation = EVP_PKEY_OP_UNDEFINED; ret->pkey = bssl::UpRef(pkey); @@ -66,25 +68,25 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { return NULL; } - const EVP_PKEY_METHOD *pkey_method = pkey->ameth->pkey_method; + const EVP_PKEY_CTX_METHOD *pkey_method = pkey->ameth->pkey_method; if (pkey_method == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", pkey->ameth->pkey_id); return NULL; } - return evp_pkey_ctx_new(pkey, e, pkey_method); + return evp_pkey_ctx_new(pkey, pkey_method); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - const EVP_PKEY_METHOD *pkey_method = evp_pkey_meth_find(id); + const EVP_PKEY_CTX_METHOD *pkey_method = evp_pkey_meth_find(id); if (pkey_method == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", id); return NULL; } - return evp_pkey_ctx_new(NULL, e, pkey_method); + return evp_pkey_ctx_new(NULL, pkey_method); } evp_pkey_ctx_st::~evp_pkey_ctx_st() { @@ -106,7 +108,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { } ret->pmeth = ctx->pmeth; - ret->engine = ctx->engine; ret->operation = ctx->operation; ret->pkey = bssl::UpRef(ctx->pkey); ret->peerkey = bssl::UpRef(ctx->peerkey); @@ -297,7 +298,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { return 0; } - if (ctx->pkey->type != peer->type) { + if (EVP_PKEY_id(ctx->pkey.get()) != EVP_PKEY_id(peer)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/internal.h b/Sources/CCryptoBoringSSL/crypto/evp/internal.h index 913fe3888..baf4c29a0 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/evp/internal.h @@ -15,9 +15,11 @@ #ifndef OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H -#include +#include -#include +#include + +#include #include "../internal.h" @@ -27,23 +29,46 @@ extern "C" { typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; -typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_method_st EVP_PKEY_CTX_METHOD; + +struct evp_pkey_alg_st { + // method implements operations for this |EVP_PKEY_ALG|. + const EVP_PKEY_ASN1_METHOD *method; + + // ec_group returns the |EC_GROUP| for this algorithm, if |method| is for + // |EVP_PKEY_EC|. + const EC_GROUP *(*ec_group)(); +}; + +enum evp_decode_result_t { + evp_decode_error = 0, + evp_decode_ok = 1, + evp_decode_unsupported = 2, +}; struct evp_pkey_asn1_method_st { + // pkey_id contains one of the |EVP_PKEY_*| values and corresponds to the OID + // in the key type's AlgorithmIdentifier. int pkey_id; uint8_t oid[9]; uint8_t oid_len; - const EVP_PKEY_METHOD *pkey_method; + const EVP_PKEY_CTX_METHOD *pkey_method; // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo - // and writes the result into |out|. It returns one on success and zero on - // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER - // type field, and |key| is the contents of the subjectPublicKey with the - // leading padding byte checked and removed. Although X.509 uses BIT STRINGs - // to represent SubjectPublicKeyInfo, every key type defined encodes the key - // as a byte string with the same conversion to BIT STRING. - int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key); + // and writes the result into |out|. It returns |evp_decode_ok| on success, + // and |evp_decode_error| on error, and |evp_decode_unsupported| if the input + // was not supported by this |EVP_PKEY_ALG|. In case of + // |evp_decode_unsupported|, it does not add an error to the error queue. May + // modify |params| and |key|. Callers must make a copy if calling in a loop. + // + // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, + // and |key| is the contents of the subjectPublicKey with the leading padding + // byte checked and removed. Although X.509 uses BIT STRINGs to represent + // SubjectPublicKeyInfo, every key type defined encodes the key as a byte + // string with the same conversion to BIT STRING. + evp_decode_result_t (*pub_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out, + CBS *params, CBS *key); // pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result // to |out|. It returns one on success and zero on error. @@ -52,10 +77,16 @@ struct evp_pkey_asn1_method_st { int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); // priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the - // result into |out|. It returns one on success and zero on error. |params| is - // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key| - // is the contents of the OCTET STRING privateKey field. - int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key); + // result into |out|. It returns |evp_decode_ok| on success, and + // |evp_decode_error| on error, and |evp_decode_unsupported| if the key type + // was not supported by this |EVP_PKEY_ALG|. In case of + // |evp_decode_unsupported|, it does not add an error to the error queue. May + // modify |params| and |key|. Callers must make a copy if calling in a loop. + // + // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, + // and |key| is the contents of the OCTET STRING privateKey field. + evp_decode_result_t (*priv_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out, + CBS *params, CBS *key); // priv_encode encodes |key| as a PrivateKeyInfo and appends the result to // |out|. It returns one on success and zero on error. @@ -94,15 +125,11 @@ struct evp_pkey_asn1_method_st { struct evp_pkey_st { CRYPTO_refcount_t references; - // type contains one of the EVP_PKEY_* values or NID_undef and determines - // the type of |pkey|. - int type; - - // pkey contains a pointer to a structure dependent on |type|. + // pkey contains a pointer to a structure dependent on |ameth|. void *pkey; - // ameth contains a pointer to a method table that contains many ASN.1 - // methods for the key type. + // ameth contains a pointer to a method table that determines the key type, or + // nullptr if the key is empty. const EVP_PKEY_ASN1_METHOD *ameth; } /* EVP_PKEY */; @@ -167,7 +194,7 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, #define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 10) #define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) #define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) -#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 13) +#define EVP_PKEY_CTRL_EC_PARAMGEN_GROUP (EVP_PKEY_ALG_CTRL + 13) #define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 14) #define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 15) #define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 16) @@ -179,20 +206,21 @@ struct evp_pkey_ctx_st { ~evp_pkey_ctx_st(); // Method associated with this operation - const EVP_PKEY_METHOD *pmeth = nullptr; - // Engine that implements this method or nullptr if builtin - ENGINE *engine = nullptr; + const EVP_PKEY_CTX_METHOD *pmeth = nullptr; // Key: may be nullptr bssl::UniquePtr pkey; // Peer key for key agreement, may be nullptr bssl::UniquePtr peerkey; // operation contains one of the |EVP_PKEY_OP_*| values. int operation = EVP_PKEY_OP_UNDEFINED; - // Algorithm specific data + // Algorithm specific data. + // TODO(davidben): Since a |EVP_PKEY_CTX| never has its type change after + // creation, this should instead be a base class, with the algorithm-specific + // data on the subclass, coming from the same allocation. void *data = nullptr; } /* EVP_PKEY_CTX */; -struct evp_pkey_method_st { +struct evp_pkey_ctx_method_st { int pkey_id; int (*init)(EVP_PKEY_CTX *ctx); @@ -227,7 +255,7 @@ struct evp_pkey_method_st { int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); -} /* EVP_PKEY_METHOD */; +} /* EVP_PKEY_CTX_METHOD */; typedef struct { // key is the concatenation of the private seed and public key. It is stored @@ -249,24 +277,47 @@ typedef struct { extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_pss_sha256_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; -extern const EVP_PKEY_METHOD rsa_pkey_meth; -extern const EVP_PKEY_METHOD ec_pkey_meth; -extern const EVP_PKEY_METHOD ed25519_pkey_meth; -extern const EVP_PKEY_METHOD x25519_pkey_meth; -extern const EVP_PKEY_METHOD hkdf_pkey_meth; -extern const EVP_PKEY_METHOD dh_pkey_meth; +extern const EVP_PKEY_CTX_METHOD rsa_pkey_meth; +extern const EVP_PKEY_CTX_METHOD rsa_pss_sha256_pkey_meth; +extern const EVP_PKEY_CTX_METHOD ec_pkey_meth; +extern const EVP_PKEY_CTX_METHOD ed25519_pkey_meth; +extern const EVP_PKEY_CTX_METHOD x25519_pkey_meth; +extern const EVP_PKEY_CTX_METHOD hkdf_pkey_meth; +extern const EVP_PKEY_CTX_METHOD dh_pkey_meth; -// evp_pkey_set_method behaves like |EVP_PKEY_set_type|, but takes a pointer to -// a method table. This avoids depending on every |EVP_PKEY_ASN1_METHOD|. -void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method); +// evp_pkey_set0 sets |pkey|'s method to |method| and data to |pkey_data|, +// freeing any key that may previously have been configured. This function takes +// ownership of |pkey_data|, which must be of the type expected by |method|. +void evp_pkey_set0(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method, + void *pkey_data); #if defined(__cplusplus) } // extern C #endif +BSSL_NAMESPACE_BEGIN +inline auto GetDefaultEVPAlgorithms() { + // A set of algorithms to use by default in |EVP_parse_public_key| and + // |EVP_parse_private_key|. + return std::array{ + EVP_pkey_ec_p224(), + EVP_pkey_ec_p256(), + EVP_pkey_ec_p384(), + EVP_pkey_ec_p521(), + EVP_pkey_ed25519(), + EVP_pkey_rsa(), + EVP_pkey_x25519(), + // TODO(crbug.com/438761503): Remove DSA from this set, after callers that + // need DSA pass in |EVP_pkey_dsa| explicitly. + EVP_pkey_dsa(), + }; +} +BSSL_NAMESPACE_END + #endif // OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc index dcf4e7c81..b70d92fd6 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc @@ -129,7 +129,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD dh_pkey_meth = { +const EVP_PKEY_CTX_METHOD dh_pkey_meth = { /*pkey_id=*/EVP_PKEY_DH, /*init=*/pkey_dh_init, /*copy=*/pkey_dh_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc index f600f43c6..55fbca3e9 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc @@ -120,13 +120,15 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { } int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { - evp_pkey_set_method(pkey, &dh_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &dh_asn1_meth, key); + return 1; } DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_DH) { + if (EVP_PKEY_id(pkey) != EVP_PKEY_DH) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY); return NULL; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc index c8e40ad97..c4df801d4 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc @@ -24,36 +24,32 @@ #include "internal.h" -static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t dsa_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 3279, section 2.3.2. - // Parameters may or may not be present. - bssl::UniquePtr dsa; - if (CBS_len(params) == 0) { - dsa.reset(DSA_new()); - if (dsa == nullptr) { - return 0; - } - } else { - dsa.reset(DSA_parse_parameters(params)); - if (dsa == nullptr || CBS_len(params) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; - } + // Decode parameters. RFC 3279 permits DSA parameters to be omitted, in which + // case they are implicitly determined from the issuing certificate, or + // somewhere unspecified and out-of-band. We do not support this mode. + bssl::UniquePtr dsa(DSA_parse_parameters(params)); + if (dsa == nullptr || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } dsa->pub_key = BN_new(); if (dsa->pub_key == nullptr) { - return 0; + return evp_decode_error; } if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } EVP_PKEY_assign_DSA(out, dsa.release()); - return 1; + return evp_decode_ok; } static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { @@ -78,23 +74,25 @@ static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t dsa_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See PKCS#11, v2.40, section 2.5. // Decode parameters. bssl::UniquePtr dsa(DSA_parse_parameters(params)); if (dsa == nullptr || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } dsa->priv_key = BN_new(); if (dsa->priv_key == nullptr) { - return 0; + return evp_decode_error; } if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } // To avoid DoS attacks when importing private keys, check bounds on |dsa|. @@ -102,7 +100,7 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { // width. if (!dsa_check_key(dsa.get())) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } // Calculate the public key. @@ -111,11 +109,11 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (ctx == nullptr || dsa->pub_key == nullptr || !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx.get(), nullptr)) { - return 0; + return evp_decode_error; } EVP_PKEY_assign_DSA(out, dsa.release()); - return 1; + return evp_decode_ok; } static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { @@ -236,6 +234,14 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { int_dsa_free, }; +const EVP_PKEY_ALG *EVP_pkey_dsa(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&dsa_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { // BoringSSL does not support DSA in |EVP_PKEY_CTX|. OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -257,13 +263,15 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { } int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { - evp_pkey_set_method(pkey, &dsa_asn1_meth); - pkey->pkey = key; - return key != nullptr; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &dsa_asn1_meth, key); + return 1; } DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_DSA) { + if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return nullptr; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc index a19b97bfb..9bd2396f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc @@ -148,12 +148,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { // Default behaviour is OK return 1; - case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: { - const EC_GROUP *group = EC_GROUP_new_by_curve_name(p1); - if (group == NULL) { - return 0; - } - dctx->gen_group = group; + case EVP_PKEY_CTRL_EC_PARAMGEN_GROUP: { + dctx->gen_group = static_cast(p2); return 1; } @@ -197,7 +193,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 1; } -const EVP_PKEY_METHOD ec_pkey_meth = { +const EVP_PKEY_CTX_METHOD ec_pkey_meth = { EVP_PKEY_EC, pkey_ec_init, pkey_ec_copy, @@ -216,8 +212,13 @@ const EVP_PKEY_METHOD ec_pkey_meth = { }; int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(nid); + if (group == nullptr) { + return 0; + } return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN, - EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL); + EVP_PKEY_CTRL_EC_PARAMGEN_GROUP, 0, + const_cast(group)); } int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int encoding) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc index 942769b1b..812d3deba 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc @@ -20,7 +20,10 @@ #include #include #include +#include +#include +#include "../ec/internal.h" #include "internal.h" @@ -48,25 +51,35 @@ static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t eckey_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 5480, section 2. - // The parameters are a named curve. - const EC_GROUP *group = EC_KEY_parse_curve_name(params); - if (group == NULL || CBS_len(params) != 0) { + // Check that |params| matches |alg|. Only the namedCurve form is allowed. + const EC_GROUP *group = alg->ec_group(); + if (ec_key_parse_curve_name(params, bssl::Span(&group, 1)) == nullptr) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + return evp_decode_unsupported; + } OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; + } + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } bssl::UniquePtr eckey(EC_KEY_new()); if (eckey == nullptr || // !EC_KEY_set_group(eckey.get(), group) || !EC_KEY_oct2key(eckey.get(), CBS_data(key), CBS_len(key), nullptr)) { - return 0; + return evp_decode_error; } EVP_PKEY_assign_EC_KEY(out, eckey.release()); - return 1; + return evp_decode_ok; } static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { @@ -85,23 +98,32 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } } -static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t eckey_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 5915. - const EC_GROUP *group = EC_KEY_parse_parameters(params); - if (group == NULL || CBS_len(params) != 0) { + const EC_GROUP *group = alg->ec_group(); + if (ec_key_parse_parameters(params, bssl::Span(&group, 1)) == nullptr) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + return evp_decode_unsupported; + } OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; + } + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } - EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); - if (ec_key == NULL || CBS_len(key) != 0) { + bssl::UniquePtr ec_key(ec_key_parse_private_key(key, group, {})); + if (ec_key == nullptr || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - EC_KEY_free(ec_key); - return 0; + return evp_decode_error; } - EVP_PKEY_assign_EC_KEY(out, ec_key); - return 1; + EVP_PKEY_assign_EC_KEY(out, ec_key.release()); + return evp_decode_ok; } static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { @@ -255,6 +277,39 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { int_ec_free, }; +const EVP_PKEY_ALG *EVP_pkey_ec_p224(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p224, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p256(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p256, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p384(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p384, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p521(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p521, + }; + return &kAlg; +} + + int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { if (EVP_PKEY_assign_EC_KEY(pkey, key)) { EC_KEY_up_ref(key); @@ -264,14 +319,16 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { } int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { - evp_pkey_set_method(pkey, &ec_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &ec_asn1_meth, key); + return 1; } EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_EC) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_EC_KEY); return NULL; } return reinterpret_cast(pkey->pkey); @@ -284,3 +341,23 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { } return ec_key; } + +int EVP_PKEY_get_ec_curve_nid(const EVP_PKEY *pkey) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key == nullptr) { + return NID_undef; + } + const EC_GROUP *group = EC_KEY_get0_group(ec_key); + if (group == nullptr) { + return NID_undef; + } + return EC_GROUP_get_curve_name(group); +} + +int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key == nullptr) { + return 0; + } + return EC_KEY_get_conv_form(ec_key); +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc index a8d19912f..5bfc553a6 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc @@ -31,14 +31,11 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 0; } - evp_pkey_set_method(pkey, &ed25519_asn1_meth); - uint8_t pubkey_unused[32]; ED25519_keypair(pubkey_unused, key->key); key->has_private = 1; - OPENSSL_free(pkey->pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -84,7 +81,7 @@ static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, return 1; } -const EVP_PKEY_METHOD ed25519_pkey_meth = { +const EVP_PKEY_CTX_METHOD ed25519_pkey_meth = { /*pkey_id=*/EVP_PKEY_ED25519, /*init=*/nullptr, /*copy=*/pkey_ed25519_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc index 6b2f7b9b2..6625fe68a 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc @@ -45,9 +45,7 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { uint8_t pubkey_unused[32]; ED25519_keypair_from_seed(pubkey_unused, key->key, in); key->has_private = 1; - - ed25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -65,9 +63,7 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { OPENSSL_memcpy(key->key + ED25519_PUBLIC_KEY_OFFSET, in, 32); key->has_private = 0; - - ed25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -113,16 +109,20 @@ static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 1; } -static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t ed25519_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 4. // The parameters must be omitted. Public keys have length 32. if (CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); + return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key)) + ? evp_decode_ok + : evp_decode_error; } static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { @@ -153,7 +153,9 @@ static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0; } -static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t ed25519_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 7. // Parameters must be empty. The key is a 32-byte value wrapped in an extra @@ -162,10 +164,12 @@ static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (CBS_len(params) != 0 || !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); + return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)) + ? evp_decode_ok + : evp_decode_error; } static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { @@ -223,3 +227,11 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { /*param_cmp=*/NULL, ed25519_free, }; + +const EVP_PKEY_ALG *EVP_pkey_ed25519(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ed25519_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc index 00af6034a..1e917fe7f 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc @@ -183,7 +183,7 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD hkdf_pkey_meth = { +const EVP_PKEY_CTX_METHOD hkdf_pkey_meth = { /*pkey_id=*/EVP_PKEY_HKDF, pkey_hkdf_init, pkey_hkdf_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc index a55dd4c8a..0d5912493 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc @@ -24,50 +24,59 @@ #include #include #include +#include #include "../internal.h" +#include "../mem_internal.h" #include "../rsa/internal.h" #include "internal.h" -typedef struct { +namespace { + +struct RSA_PKEY_CTX { // Key gen parameters - int nbits; - BIGNUM *pub_exp; + int nbits = 2048; + bssl::UniquePtr pub_exp; // RSA padding mode - int pad_mode; + int pad_mode = RSA_PKCS1_PADDING; // message digest - const EVP_MD *md; + const EVP_MD *md = nullptr; // message digest for MGF1 - const EVP_MD *mgf1md; + const EVP_MD *mgf1md = nullptr; // PSS salt length - int saltlen; - // tbuf is a buffer which is either NULL, or is the size of the RSA modulus. - // It's used to store the output of RSA operations. - uint8_t *tbuf; - // OAEP label - uint8_t *oaep_label; - size_t oaep_labellen; -} RSA_PKEY_CTX; - -typedef struct { - uint8_t *data; - size_t len; -} RSA_OAEP_LABEL_PARAMS; + int saltlen = RSA_PSS_SALTLEN_DIGEST; + // restrict_pss_params, if true, indicates that the PSS signing/verifying + // parameters are restricted by the key's parameters. |md| and |mgf1md| may + // not change, and |saltlen| must be at least |md|'s hash length. + bool restrict_pss_params = false; + bssl::Array oaep_label; +}; + +static bool is_pss_only(const EVP_PKEY_CTX *ctx) { + return ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS; +} static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { - RSA_PKEY_CTX *rctx = - reinterpret_cast(OPENSSL_zalloc(sizeof(RSA_PKEY_CTX))); + RSA_PKEY_CTX *rctx = bssl::New(); if (!rctx) { return 0; } - rctx->nbits = 2048; - rctx->pad_mode = RSA_PKCS1_PADDING; - rctx->saltlen = -2; + if (is_pss_only(ctx)) { + rctx->pad_mode = RSA_PKCS1_PSS_PADDING; + // Pick up PSS parameters from the key. For now, we only support the SHA-256 + // parameter set, so every key is necessarily SHA-256. If we ever support + // other parameters, we will need more state in |EVP_PKEY| and to translate + // that state into defaults here. + if (ctx->pkey != nullptr) { + rctx->md = rctx->mgf1md = EVP_sha256(); + rctx->saltlen = EVP_MD_size(rctx->md); + rctx->restrict_pss_params = true; + } + } ctx->data = rctx; - return 1; } @@ -80,7 +89,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { dctx = reinterpret_cast(dst->data); dctx->nbits = sctx->nbits; if (sctx->pub_exp) { - dctx->pub_exp = BN_dup(sctx->pub_exp); + dctx->pub_exp.reset(BN_dup(sctx->pub_exp.get())); if (!dctx->pub_exp) { return 0; } @@ -90,42 +99,16 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; dctx->saltlen = sctx->saltlen; - if (sctx->oaep_label) { - OPENSSL_free(dctx->oaep_label); - dctx->oaep_label = reinterpret_cast( - OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen)); - if (!dctx->oaep_label) { - return 0; - } - dctx->oaep_labellen = sctx->oaep_labellen; + dctx->restrict_pss_params = sctx->restrict_pss_params; + if (!dctx->oaep_label.CopyFrom(sctx->oaep_label)) { + return 0; } return 1; } static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { - RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); - - if (rctx == NULL) { - return; - } - - BN_free(rctx->pub_exp); - OPENSSL_free(rctx->tbuf); - OPENSSL_free(rctx->oaep_label); - OPENSSL_free(rctx); -} - -static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { - if (ctx->tbuf) { - return 1; - } - ctx->tbuf = reinterpret_cast( - OPENSSL_malloc(EVP_PKEY_size(pk->pkey.get()))); - if (!ctx->tbuf) { - return 0; - } - return 1; + bssl::Delete(reinterpret_cast(ctx->data)); } static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, @@ -187,12 +170,13 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, size_t rslen; const size_t key_len = EVP_PKEY_size(ctx->pkey.get()); - if (!setup_tbuf(rctx, ctx) || - !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, + bssl::Array tbuf; + if (!tbuf.InitForOverwrite(key_len) || + !RSA_verify_raw(rsa, &rslen, tbuf.data(), tbuf.size(), sig, siglen, rctx->pad_mode)) { return 0; } - if (rslen != tbslen || CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { + if (rslen != tbslen || CRYPTO_memcmp(tbs, tbuf.data(), rslen) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); return 0; } @@ -232,33 +216,28 @@ static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, uint8_t *asn1_prefix; size_t asn1_prefix_len; int asn1_prefix_allocated; - if (!setup_tbuf(rctx, ctx) || - !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, + if (!RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, &asn1_prefix_allocated, EVP_MD_type(rctx->md), kDummyHash, hash_len)) { return 0; } + bssl::UniquePtr free_asn1_prefix(asn1_prefix_allocated ? asn1_prefix + : nullptr); + bssl::Array tbuf; size_t rslen; - int ok = 1; - if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len, + if (!tbuf.InitForOverwrite(key_len) || + !RSA_verify_raw(rsa, &rslen, tbuf.data(), tbuf.size(), sig, sig_len, RSA_PKCS1_PADDING) || rslen != asn1_prefix_len || // Compare all but the hash suffix. - CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) { - ok = 0; - } - - if (asn1_prefix_allocated) { - OPENSSL_free(asn1_prefix); - } - - if (!ok) { + CRYPTO_memcmp(tbuf.data(), asn1_prefix, asn1_prefix_len - hash_len) != + 0) { return 0; } if (out != NULL) { - OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len); + OPENSSL_memcpy(out, tbuf.data() + rslen - hash_len, hash_len); } *out_len = hash_len; @@ -282,11 +261,12 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - if (!setup_tbuf(rctx, ctx) || - !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, - rctx->oaep_label, rctx->oaep_labellen, - rctx->md, rctx->mgf1md) || - !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, + bssl::Array tbuf; + if (!tbuf.InitForOverwrite(key_len) || + !RSA_padding_add_PKCS1_OAEP_mgf1( + tbuf.data(), tbuf.size(), in, inlen, rctx->oaep_label.data(), + rctx->oaep_label.size(), rctx->md, rctx->mgf1md) || + !RSA_encrypt(rsa, outlen, out, *outlen, tbuf.data(), tbuf.size(), RSA_NO_PADDING)) { return 0; } @@ -313,13 +293,15 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + bssl::Array tbuf; size_t padded_len; - if (!setup_tbuf(rctx, ctx) || - !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + if (!tbuf.InitForOverwrite(key_len) || + !RSA_decrypt(rsa, &padded_len, tbuf.data(), tbuf.size(), in, inlen, RSA_NO_PADDING) || - !RSA_padding_check_PKCS1_OAEP_mgf1( - out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, - rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { + !RSA_padding_check_PKCS1_OAEP_mgf1(out, outlen, key_len, tbuf.data(), + padded_len, rctx->oaep_label.data(), + rctx->oaep_label.size(), rctx->md, + rctx->mgf1md)) { return 0; } return 1; @@ -357,6 +339,11 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: + // PSS keys cannot be switched to other padding types. + if (is_pss_only(ctx) && p1 != RSA_PKCS1_PSS_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || (p1 == RSA_PKCS1_PSS_PADDING && 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || @@ -365,8 +352,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } - if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && - rctx->md == NULL) { + if (p1 == RSA_PKCS1_OAEP_PADDING && rctx->md == NULL) { rctx->md = EVP_sha1(); } rctx->pad_mode = p1; @@ -385,7 +371,21 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { *(int *)p2 = rctx->saltlen; } else { - if (p1 < -2) { + // Negative salt lengths are special values. + if (p1 < 0) { + if (p1 != RSA_PSS_SALTLEN_DIGEST && p1 != RSA_PSS_SALTLEN_AUTO) { + return 0; + } + // All our PSS restrictions accept saltlen == hashlen, so allow + // |RSA_PSS_SALTLEN_DIGEST|. Reject |RSA_PSS_SALTLEN_AUTO| for + // simplicity. + if (rctx->restrict_pss_params && p1 != RSA_PSS_SALTLEN_DIGEST) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + return 0; + } + } else if (rctx->restrict_pss_params && + static_cast(p1) < EVP_MD_size(rctx->md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); return 0; } rctx->saltlen = p1; @@ -404,8 +404,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (!p2) { return 0; } - BN_free(rctx->pub_exp); - rctx->pub_exp = reinterpret_cast(p2); + rctx->pub_exp.reset(reinterpret_cast(p2)); return 1; case EVP_PKEY_CTRL_RSA_OAEP_MD: @@ -421,12 +420,19 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } return 1; - case EVP_PKEY_CTRL_MD: - if (!check_padding_md(reinterpret_cast(p2), rctx->pad_mode)) { + case EVP_PKEY_CTRL_MD: { + const EVP_MD *md = reinterpret_cast(p2); + if (!check_padding_md(md, rctx->pad_mode)) { return 0; } - rctx->md = reinterpret_cast(p2); + if (rctx->restrict_pss_params && + EVP_MD_type(rctx->md) != EVP_MD_type(md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); + return 0; + } + rctx->md = md; return 1; + } case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = rctx->md; @@ -446,7 +452,13 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { *(const EVP_MD **)p2 = rctx->md; } } else { - rctx->mgf1md = reinterpret_cast(p2); + const EVP_MD *md = reinterpret_cast(p2); + if (rctx->restrict_pss_params && + EVP_MD_type(rctx->mgf1md) != EVP_MD_type(md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + return 0; + } + rctx->mgf1md = md; } return 1; @@ -455,11 +467,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); return 0; } - OPENSSL_free(rctx->oaep_label); - RSA_OAEP_LABEL_PARAMS *params = - reinterpret_cast(p2); - rctx->oaep_label = params->data; - rctx->oaep_labellen = params->len; + // |EVP_PKEY_CTRL_RSA_OAEP_LABEL| takes ownership of |label|'s underlying + // buffer (via |Reset|), but only on success. + auto *label = reinterpret_cast *>(p2); + rctx->oaep_label.Reset(label->data(), label->size()); return 1; } @@ -468,7 +479,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); return 0; } - CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + *reinterpret_cast(p2) = CBS(rctx->oaep_label); return 1; default: @@ -478,90 +489,130 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - RSA *rsa = NULL; RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); - if (!rctx->pub_exp) { - rctx->pub_exp = BN_new(); - if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) { + rctx->pub_exp.reset(BN_new()); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp.get(), RSA_F4)) { return 0; } } - rsa = RSA_new(); + bssl::UniquePtr rsa(RSA_new()); if (!rsa) { return 0; } - if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { - RSA_free(rsa); + if (!RSA_generate_key_ex(rsa.get(), rctx->nbits, rctx->pub_exp.get(), + nullptr)) { return 0; } - EVP_PKEY_assign_RSA(pkey, rsa); + EVP_PKEY_assign_RSA(pkey, rsa.release()); return 1; } -const EVP_PKEY_METHOD rsa_pkey_meth = { +} // namespace + +const EVP_PKEY_CTX_METHOD rsa_pkey_meth = { EVP_PKEY_RSA, pkey_rsa_init, pkey_rsa_copy, pkey_rsa_cleanup, pkey_rsa_keygen, pkey_rsa_sign, - NULL /* sign_message */, + /*sign_message=*/nullptr, pkey_rsa_verify, - NULL /* verify_message */, + /*verify_message=*/nullptr, pkey_rsa_verify_recover, pkey_rsa_encrypt, pkey_rsa_decrypt, - NULL /* derive */, - NULL /* paramgen */, + /*derive=*/nullptr, + /*paramgen=*/nullptr, + pkey_rsa_ctrl, +}; + +const EVP_PKEY_CTX_METHOD rsa_pss_sha256_pkey_meth = { + EVP_PKEY_RSA_PSS, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + // In OpenSSL, |EVP_PKEY_RSA_PSS| supports key generation and fills in PSS + // parameters based on a separate set of keygen-targetted setters: + // |EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen|, + // |EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md|, and + // |EVP_PKEY_CTX_rsa_pss_key_digest|. We do not currently implement this + // because we only support one parameter set. + /*keygen=*/nullptr, + pkey_rsa_sign, + /*sign_message=*/nullptr, + pkey_rsa_verify, + /*verify_message=*/nullptr, + /*verify_recover=*/nullptr, + /*encrypt=*/nullptr, + /*decrypt=*/nullptr, + /*derive=*/nullptr, + /*paramgen=*/nullptr, pkey_rsa_ctrl, }; +static int rsa_or_rsa_pss_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, + void *p2) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA && + ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + return EVP_PKEY_CTX_ctrl(ctx, /*keytype=*/-1, optype, cmd, p1, p2); +} + int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, - padding, NULL); + return rsa_or_rsa_pss_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, padding, + nullptr); } int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, - 0, out_padding); + return rsa_or_rsa_pss_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, + out_padding); } int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), - EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); + return rsa_or_rsa_pss_ctrl(ctx, (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, nullptr); } int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), - EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); + return rsa_or_rsa_pss_ctrl(ctx, (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, + out_salt_len); } int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, nullptr); } int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); } int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { @@ -575,22 +626,20 @@ int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { } int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); } int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)out_md); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)out_md); } int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label, size_t label_len) { - RSA_OAEP_LABEL_PARAMS params = {label, label_len}; + bssl::Span span(label, label_len); return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms); + EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, &span); } int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc index 682967835..8865b68a9 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc @@ -20,8 +20,10 @@ #include #include #include +#include #include "../fipsmodule/rsa/internal.h" +#include "../rsa/internal.h" #include "internal.h" @@ -45,7 +47,9 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t rsa_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 3279, section 2.3.1. // The parameters must be NULL. @@ -53,21 +57,25 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - RSA *rsa = RSA_parse_public_key(key); - if (rsa == NULL || CBS_len(key) != 0) { + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - RSA_free(rsa); - return 0; + return evp_decode_error; } - EVP_PKEY_assign_RSA(out, rsa); - return 1; + EVP_PKEY_assign_RSA(out, rsa.release()); + return evp_decode_ok; } static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + // We currently assume that all |EVP_PKEY_RSA_PSS| keys have the same + // parameters, so this vacuously compares parameters. If we ever support + // multiple PSS parameter sets, we probably should compare them too. Note, + // however, that OpenSSL does not compare parameters here. const RSA *a_rsa = reinterpret_cast(a->pkey); const RSA *b_rsa = reinterpret_cast(b->pkey); return BN_cmp(RSA_get0_n(b_rsa), RSA_get0_n(a_rsa)) == 0 && @@ -93,26 +101,122 @@ static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { - // Per RFC 3447, A.1, the parameters have type NULL. +static evp_decode_result_t rsa_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { + // Per RFC 8017, A.1, the parameters have type NULL. CBS null; if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + bssl::UniquePtr rsa( + RSA_private_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + EVP_PKEY_assign_RSA(out, rsa.release()); + return evp_decode_ok; +} + +static evp_decode_result_t rsa_decode_pss_params_sha256(CBS *params) { + // For now, we only support the SHA-256 parameter set. If we want to support + // more, we'll need to record a little more state in the |EVP_PKEY|. + if (CBS_len(params) == 0) { + return evp_decode_unsupported; + } + rsa_pss_params_t pss_params; + if (!rsa_parse_pss_params(params, &pss_params, + /*allow_explicit_trailer=*/false) || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + return pss_params == rsa_pss_sha256 ? evp_decode_ok : evp_decode_unsupported; +} + +static int rsa_pub_encode_pss_sha256(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = reinterpret_cast(key->pkey); + CBB spki, algorithm, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, + rsa_pss_sha256_asn1_meth.oid, + rsa_pss_sha256_asn1_meth.oid_len) || + !rsa_marshal_pss_params(&algorithm, rsa_pss_sha256) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !RSA_marshal_public_key(&key_bitstring, rsa) || // + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } - RSA *rsa = RSA_parse_private_key(key); - if (rsa == NULL || CBS_len(key) != 0) { + return 1; +} + +static evp_decode_result_t rsa_pub_decode_pss_sha256(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { + evp_decode_result_t ret = rsa_decode_pss_params_sha256(params); + if (ret != evp_decode_ok) { + return ret; + } + + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - RSA_free(rsa); + return evp_decode_error; + } + + evp_pkey_set0(out, &rsa_pss_sha256_asn1_meth, rsa.release()); + return evp_decode_ok; +} + +static int rsa_priv_encode_pss_sha256(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = reinterpret_cast(key->pkey); + CBB pkcs8, algorithm, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, + rsa_pss_sha256_asn1_meth.oid, + rsa_pss_sha256_asn1_meth.oid_len) || + !rsa_marshal_pss_params(&algorithm, rsa_pss_sha256) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !RSA_marshal_private_key(&private_key, rsa) || // + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } - EVP_PKEY_assign_RSA(out, rsa); return 1; } +static evp_decode_result_t rsa_priv_decode_pss_sha256(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, + CBS *params, CBS *key) { + evp_decode_result_t ret = rsa_decode_pss_params_sha256(params); + if (ret != evp_decode_ok) { + return ret; + } + + bssl::UniquePtr rsa( + RSA_private_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + evp_pkey_set0(out, &rsa_pss_sha256_asn1_meth, rsa.release()); + return evp_decode_ok; +} + static int rsa_opaque(const EVP_PKEY *pkey) { const RSA *rsa = reinterpret_cast(pkey->pkey); return RSA_is_opaque(rsa); @@ -148,25 +252,76 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { rsa_priv_decode, rsa_priv_encode, - /*set_priv_raw=*/NULL, - /*set_pub_raw=*/NULL, - /*get_priv_raw=*/NULL, - /*get_pub_raw=*/NULL, - /*set1_tls_encodedpoint=*/NULL, - /*get1_tls_encodedpoint=*/NULL, + /*set_priv_raw=*/nullptr, + /*set_pub_raw=*/nullptr, + /*get_priv_raw=*/nullptr, + /*get_pub_raw=*/nullptr, + /*set1_tls_encodedpoint=*/nullptr, + /*get1_tls_encodedpoint=*/nullptr, + + rsa_opaque, + + int_rsa_size, + rsa_bits, + + /*param_missing=*/nullptr, + /*param_copy=*/nullptr, + /*param_cmp=*/nullptr, + + int_rsa_free, +}; + +const EVP_PKEY_ASN1_METHOD rsa_pss_sha256_asn1_meth = { + EVP_PKEY_RSA_PSS, + // 1.2.840.113549.1.1.10 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a}, + 9, + + &rsa_pss_sha256_pkey_meth, + + rsa_pub_decode_pss_sha256, + rsa_pub_encode_pss_sha256, + rsa_pub_cmp, + + rsa_priv_decode_pss_sha256, + rsa_priv_encode_pss_sha256, + + /*set_priv_raw=*/nullptr, + /*set_pub_raw=*/nullptr, + /*get_priv_raw=*/nullptr, + /*get_pub_raw=*/nullptr, + /*set1_tls_encodedpoint=*/nullptr, + /*get1_tls_encodedpoint=*/nullptr, rsa_opaque, int_rsa_size, rsa_bits, - 0, - 0, - 0, + /*param_missing=*/nullptr, + /*param_copy=*/nullptr, + /*param_cmp=*/nullptr, int_rsa_free, }; + +const EVP_PKEY_ALG *EVP_pkey_rsa(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&rsa_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_rsa_pss_sha256(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&rsa_pss_sha256_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { if (EVP_PKEY_assign_RSA(pkey, key)) { RSA_up_ref(key); @@ -176,13 +331,16 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { } int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { - evp_pkey_set_method(pkey, &rsa_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &rsa_asn1_meth, key); + return 1; } RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_RSA) { + int pkey_id = EVP_PKEY_id(pkey); + if (pkey_id != EVP_PKEY_RSA && pkey_id != EVP_PKEY_RSA_PSS) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc index da526bc96..6e3d23b35 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc @@ -31,13 +31,9 @@ static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 0; } - evp_pkey_set_method(pkey, &x25519_asn1_meth); - X25519_keypair(key->pub, key->priv); key->has_private = 1; - - OPENSSL_free(pkey->pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -90,7 +86,7 @@ static int pkey_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD x25519_pkey_meth = { +const EVP_PKEY_CTX_METHOD x25519_pkey_meth = { /*pkey_id=*/EVP_PKEY_X25519, /*init=*/NULL, /*copy=*/pkey_x25519_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc index ced00a586..ed43ce3c3 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc @@ -44,8 +44,7 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_public_from_private(key->pub, key->priv); key->has_private = 1; - x25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -64,8 +63,7 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { OPENSSL_memcpy(key->pub, in, 32); key->has_private = 0; - x25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -127,16 +125,20 @@ static size_t x25519_get1_tls_encodedpoint(const EVP_PKEY *pkey, return *out_ptr == NULL ? 0 : 32; } -static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t x25519_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 4. // The parameters must be omitted. Public keys have length 32. if (CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); + return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key)) + ? evp_decode_ok + : evp_decode_error; } static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { @@ -165,7 +167,9 @@ static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0; } -static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t x25519_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 7. // Parameters must be empty. The key is a 32-byte value wrapped in an extra @@ -174,10 +178,12 @@ static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (CBS_len(params) != 0 || !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); + return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)) + ? evp_decode_ok + : evp_decode_error; } static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { @@ -235,3 +241,11 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { /*param_cmp=*/NULL, x25519_free, }; + +const EVP_PKEY_ALG *EVP_pkey_x25519(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&x25519_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/print.cc b/Sources/CCryptoBoringSSL/crypto/evp/print.cc index f052f89a7..718d8c79d 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/print.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/print.cc @@ -152,55 +152,6 @@ 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) { - const BIGNUM *priv_key = NULL; - if (ptype == 2) { - priv_key = DSA_get0_priv_key(x); - } - - const BIGNUM *pub_key = NULL; - if (ptype > 0) { - pub_key = DSA_get0_pub_key(x); - } - - const char *ktype = "DSA-Parameters"; - if (ptype == 2) { - ktype = "Private-Key"; - } else if (ptype == 1) { - ktype = "Public-Key"; - } - - if (!BIO_indent(bp, off, 128) || - BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(DSA_get0_p(x))) <= - 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:", DSA_get0_p(x), off) || - !bn_print(bp, "Q:", DSA_get0_q(x), off) || - !bn_print(bp, "G:", DSA_get0_g(x), off)) { - return 0; - } - - return 1; -} - -static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 0); -} - -static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 1); -} - -static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 2); -} - - // EC keys. static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { @@ -277,18 +228,12 @@ typedef struct { int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent); } EVP_PKEY_PRINT_METHOD; -static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { +static const EVP_PKEY_PRINT_METHOD kPrintMethods[] = { { EVP_PKEY_RSA, rsa_pub_print, rsa_priv_print, - NULL /* param_print */, - }, - { - EVP_PKEY_DSA, - dsa_pub_print, - dsa_priv_print, - dsa_param_print, + /*param_print=*/nullptr, }, { EVP_PKEY_EC, @@ -298,15 +243,13 @@ static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { }, }; -static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods); - -static EVP_PKEY_PRINT_METHOD *find_method(int type) { - for (size_t i = 0; i < kPrintMethodsLen; i++) { - if (kPrintMethods[i].type == type) { - return &kPrintMethods[i]; +static const EVP_PKEY_PRINT_METHOD *find_method(int type) { + for (const auto &p : kPrintMethods) { + if (p.type == type) { + return &p; } } - return NULL; + return nullptr; } static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, @@ -318,7 +261,7 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->pub_print != NULL) { return method->pub_print(out, pkey, indent); } @@ -327,7 +270,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->priv_print != NULL) { return method->priv_print(out, pkey, indent); } @@ -336,7 +279,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->param_print != NULL) { return method->param_print(out, pkey, indent); } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc index 6863c5535..257b2a260 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include "../bcm_support.h" #include "../internal.h" @@ -90,6 +90,7 @@ #include "ec/wnaf.cc.inc" #include "ecdh/ecdh.cc.inc" #include "ecdsa/ecdsa.cc.inc" +#include "entropy/jitter.cc.inc" #include "hkdf/hkdf.cc.inc" #include "hmac/hmac.cc.inc" #include "keccak/keccak.cc.inc" @@ -172,8 +173,8 @@ static void BORINGSSL_maybe_set_module_text_permissions(int permission) {} #endif // !ASAN -static void __attribute__((constructor)) -BORINGSSL_bcm_power_on_self_test(void) { +static void __attribute__((constructor)) BORINGSSL_bcm_power_on_self_test( + void) { #if !defined(OPENSSL_ASAN) // Integrity tests cannot run under ASAN because it involves reading the full // .text section, which triggers the global-buffer overflow detection. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h index d746fd8b7..14d64cb8c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h @@ -529,6 +529,140 @@ OPENSSL_EXPORT bcm_status BCM_mldsa87_verify_internal( OPENSSL_EXPORT bcm_status BCM_mldsa87_marshal_private_key( CBB *out, const struct BCM_mldsa87_private_key *private_key); +// BCM_MLDSA44_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// private key. +#define BCM_MLDSA44_PRIVATE_KEY_BYTES 2560 + +// BCM_MLDSA44_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// public key. +#define BCM_MLDSA44_PUBLIC_KEY_BYTES 1312 + +// BCM_MLDSA44_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-44 +// signature. +#define BCM_MLDSA44_SIGNATURE_BYTES 2420 + +struct BCM_mldsa44_private_key { + union { + uint8_t bytes[32 + 32 + 64 + 256 * 4 * (4 + 4 + 4)]; + uint32_t alignment; + } opaque; +}; + +struct BCM_mldsa44_public_key { + union { + uint8_t bytes[32 + 64 + 256 * 4 * 4]; + uint32_t alignment; + } opaque; +}; + +struct BCM_mldsa44_prehash { + union { + uint8_t bytes[200 + 4 + 4 + 4 * sizeof(size_t)]; + uint64_t alignment; + } opaque; +}; + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_public_from_private( + struct BCM_mldsa44_public_key *out_public_key, + const struct BCM_mldsa44_private_key *private_key); + +OPENSSL_EXPORT bcm_status +BCM_mldsa44_check_key_fips(struct BCM_mldsa44_private_key *private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed_fips( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len); + +OPENSSL_EXPORT bcm_status +BCM_mldsa44_verify(const struct BCM_mldsa44_public_key *public_key, + const uint8_t *signature, const uint8_t *msg, size_t msg_len, + const uint8_t *context, size_t context_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_init( + struct BCM_mldsa44_prehash *out_prehash_ctx, + const struct BCM_mldsa44_public_key *public_key, const uint8_t *context, + size_t context_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_update( + struct BCM_mldsa44_prehash *inout_prehash_ctx, const uint8_t *msg, + size_t msg_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_finalize( + uint8_t out_msg_rep[BCM_MLDSA_MU_BYTES], + struct BCM_mldsa44_prehash *inout_prehash_ctx); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_message_representative( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, + const uint8_t msg_rep[BCM_MLDSA_MU_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_marshal_public_key( + CBB *out, const struct BCM_mldsa44_public_key *public_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_parse_public_key( + struct BCM_mldsa44_public_key *public_key, CBS *in); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_parse_private_key( + struct BCM_mldsa44_private_key *private_key, CBS *in); + +// BCM_mldsa44_generate_key_external_entropy generates a public/private key pair +// using the given seed, writes the encoded public key to +// |out_encoded_public_key| and sets |out_private_key| to the private key. +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]); + +// BCM_mldsa44_sign_internal signs |msg| using |private_key| and writes the +// signature to |out_encoded_signature|. The |context_prefix| and |context| are +// prefixed to the message, in that order, before signing. The |randomizer| +// value can be set to zero bytes in order to make a deterministic signature, or +// else filled with entropy for the usual |MLDSA_sign| behavior. +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_internal( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len, + const uint8_t *context, size_t context_len, + const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); + +// BCM_mldsa44_verify_internal verifies that |encoded_signature| is a valid +// signature of |msg| by |public_key|. The |context_prefix| and |context| are +// prefixed to the message before verification, in that order. +OPENSSL_EXPORT bcm_status BCM_mldsa44_verify_internal( + const struct BCM_mldsa44_public_key *public_key, + const uint8_t encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, + size_t context_prefix_len, const uint8_t *context, size_t context_len); + +// BCM_mldsa44_marshal_private_key serializes |private_key| to |out| in the +// NIST format for ML-DSA-44 private keys. +OPENSSL_EXPORT bcm_status BCM_mldsa44_marshal_private_key( + CBB *out, const struct BCM_mldsa44_private_key *private_key); + // ML-KEM // diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc index ffcea64b6..3206708c0 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc @@ -560,9 +560,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, // |bn_mul_mont_gather5| and |bn_power5| implement the "almost" reduction // variant, so the values here may not be fully reduced. They are bounded by R // (i.e. they fit in |top| words), not |m|. Additionally, we pass these - // "almost" reduced inputs into |bn_mul_mont|, which implements the normal - // reduction variant. Given those inputs, |bn_mul_mont| may not give reduced - // output, but it will still produce "almost" reduced output. + // "almost" reduced inputs into |bn_mul_mont_words|, which implements the + // normal reduction variant. Given those inputs, |bn_mul_mont_words| may not + // give reduced output, but it will still produce "almost" reduced output. // // TODO(davidben): Using "almost" reduction complicates analysis of this code, // and its interaction with other parts of the project. Determine whether this @@ -578,12 +578,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BN_ULONG *n0 = mont->n0; bn_scatter5(tmp.d, top, powerbuf, 0); bn_scatter5(am.d, am.width, powerbuf, 1); - bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_mul_mont_words(tmp.d, am.d, am.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, 2); // Square to compute powers of two. for (i = 4; i < 32; i *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, i); } // Compute odd powers |i| based on |i - 1|, then all powers |i * 2^j|. @@ -591,7 +591,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); bn_scatter5(tmp.d, top, powerbuf, i); for (int j = 2 * i; j < 32; j *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, j); } } @@ -614,11 +614,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); } - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); } } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc index 54d22f65f..90ee6acb1 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc @@ -44,24 +44,24 @@ do { \ BN_ULLONG t; \ t = (BN_ULLONG)(w) * (a) + (r) + (c); \ - (r) = Lw(t); \ - (c) = Hw(t); \ + (r) = (BN_ULONG)(t); \ + (c) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) -#define mul(r, a, w, c) \ - do { \ - BN_ULLONG t; \ - t = (BN_ULLONG)(w) * (a) + (c); \ - (r) = Lw(t); \ - (c) = Hw(t); \ +#define mul(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (c); \ + (r) = (BN_ULONG)(t); \ + (c) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) -#define sqr(r0, r1, a) \ - do { \ - BN_ULLONG t; \ - t = (BN_ULLONG)(a) * (a); \ - (r0) = Lw(t); \ - (r1) = Hw(t); \ +#define sqr(r0, r1, a) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(a) * (a); \ + (r0) = (BN_ULONG)(t); \ + (r1) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) #else @@ -198,8 +198,8 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a) * (b); \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += (hi); \ (c2) += (c1) < hi; \ } while (0) @@ -209,13 +209,13 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a) * (b); \ BN_ULLONG tt = t + (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(tt); \ - hi = (BN_ULONG)Hw(tt); \ + (c0) = (BN_ULONG)(tt); \ + hi = (BN_ULONG)((tt) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ } while (0) @@ -225,8 +225,8 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ } while (0) diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h index 289f86f53..a68a7d1af 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h @@ -105,11 +105,6 @@ extern "C" { sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ } -#if defined(BN_ULLONG) -#define Lw(t) ((BN_ULONG)(t)) -#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) -#endif - // bn_minimal_width returns the minimal number of words needed to represent // |bn|. int bn_minimal_width(const BIGNUM *bn); @@ -268,16 +263,27 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // |BIGNUM|s, in |bn_wexpand|, but the exactfloat library needs to create 8 MiB // values for other operations. // -// TODO(crbug.com/402677800): This is not quite tight enough to limit the -// |bn_mul_mont| allocation to under a page. Lower the maximum RSA key and then -// lower this to match. -#define BN_MONTGOMERY_MAX_WORDS (16384 / BN_BITS2) +// This limit is set so that one number fits within 1 KiB, giving room to +// allocate a few of them on the stack in |bn_mul_mont_words| without exceeding +// a page (4 KiB). It is also set to limit the DoS impact of large RSA, DH, and +// DSA keys, which scale cubically. +#define BN_MONTGOMERY_MAX_WORDS (8192 / BN_BITS2) + +struct bn_mont_ctx_st { + // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. It + // is guaranteed to have the same width as |N|. + BIGNUM RR; + // N is the modulus. It is always stored in minimal form, so |N.width| + // determines R. + BIGNUM N; + BN_ULONG n0[BN_MONT_CTX_N0_LIMBS]; // least significant words of (R*Ri-1)/N +}; #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) #define OPENSSL_BN_ASM_MONT -// bn_mul_mont writes |ap| * |bp| mod |np| to |rp|, each |num| words +// bn_mul_mont_words writes |ap| * |bp| mod |np| to |rp|, each |num| words // long. Inputs and outputs are in Montgomery form. |n0| is a pointer to the // corresponding field in |BN_MONT_CTX|. // @@ -295,8 +301,9 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // // See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word // inputs. -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); #if defined(OPENSSL_X86_64) inline int bn_mulx_adx_capable(void) { @@ -304,30 +311,36 @@ inline int bn_mulx_adx_capable(void) { return CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable(); } void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); inline int bn_mul4x_mont_capable(size_t num) { return num >= 8 && (num & 3) == 0; } void bn_mul4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); inline int bn_mulx4x_mont_capable(size_t num) { return bn_mul4x_mont_capable(num) && bn_mulx_adx_capable(); } void bn_mulx4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); inline int bn_sqr8x_mont_capable(size_t num) { return num >= 8 && (num & 7) == 0; } void bn_sqr8x_mont(BN_ULONG *rp, const BN_ULONG *ap, BN_ULONG mulx_adx_capable, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); #elif defined(OPENSSL_ARM) inline int bn_mul8x_mont_neon_capable(size_t num) { return (num & 7) == 0 && CRYPTO_is_NEON_capable(); } void bn_mul8x_mont_neon(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); #endif #endif // OPENSSL_BN_ASM_MONT @@ -340,7 +353,8 @@ void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, inline int bn_mul4x_mont_gather5_capable(int num) { return (num & 7) == 0; } void bn_mul4x_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); inline int bn_mulx4x_mont_gather5_capable(int num) { return bn_mul4x_mont_gather5_capable(num) && CRYPTO_is_ADX_capable() && @@ -348,11 +362,13 @@ inline int bn_mulx4x_mont_gather5_capable(int num) { } void bn_mulx4x_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); void bn_mul_mont_gather5_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); // bn_scatter5 stores |inp| to index |power| of |table|. |inp| and each entry of // |table| are |num| words long. |power| must be less than 32 and is treated as @@ -368,7 +384,8 @@ void bn_gather5(BN_ULONG *out, size_t num, const BN_ULONG *table, size_t power); // The following functions implement |bn_power5|. See |bn_power5| for details. void bn_power5_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, - const BN_ULONG *np, const BN_ULONG *n0, int num, int power); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + int num, int power); inline int bn_power5_capable(int num) { return (num & 7) == 0; } @@ -377,7 +394,8 @@ inline int bn_powerx5_capable(int num) { CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable(); } void bn_powerx5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, - const BN_ULONG *np, const BN_ULONG *n0, int num, int power); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + int num, int power); #endif // !OPENSSL_NO_ASM && OPENSSL_X86_64 diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc index 2746c060f..120ee218e 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc @@ -64,8 +64,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { if (!BN_copy(&to->RR, &from->RR) || !BN_copy(&to->N, &from->N)) { return NULL; } - to->n0[0] = from->n0[0]; - to->n0[1] = from->n0[1]; + for (size_t i = 0; i < BN_MONT_CTX_N0_LIMBS; i++) { + to->n0[i] = from->n0[i]; + } return to; } @@ -111,8 +112,6 @@ static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { mont->n0[0] = (BN_ULONG)n0; #if BN_MONT_CTX_N0_LIMBS == 2 mont->n0[1] = (BN_ULONG)(n0 >> BN_BITS2); -#else - mont->n0[1] = 0; #endif return 1; } @@ -309,16 +308,16 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, } #if defined(OPENSSL_BN_ASM_MONT) - // |bn_mul_mont| requires at least 128 bits of limbs. + // |bn_mul_mont_words| requires at least 128 bits of limbs. int num = mont->N.width; if (num >= (128 / BN_BITS2) && a->width == num && b->width == num) { if (!bn_wexpand(r, num)) { return 0; } - // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont| + // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont_words| // allocates |num| words on the stack, so |num| cannot be too large. assert((size_t)num <= BN_MONTGOMERY_MAX_WORDS); - bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num); + bn_mul_mont_words(r->d, a->d, b->d, mont->N.d, mont->n0, num); r->neg = 0; r->width = num; return 1; @@ -359,9 +358,9 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, } #if defined(OPENSSL_BN_ASM_MONT) - // |bn_mul_mont| requires at least 128 bits of limbs. + // |bn_mul_mont_words| requires at least 128 bits of limbs. if (num >= (128 / BN_BITS2)) { - bn_mul_mont(r, a, b, mont->N.d, mont->n0, num); + bn_mul_mont_words(r, a, b, mont->N.d, mont->n0, num); return; } #endif @@ -382,8 +381,8 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, } #if defined(OPENSSL_BN_ASM_MONT) && defined(OPENSSL_X86_64) -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num) { +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num) { if (ap == bp && bn_sqr8x_mont_capable(num)) { bn_sqr8x_mont(rp, ap, bn_mulx_adx_capable(), np, n0, num); } else if (bn_mulx4x_mont_capable(num)) { @@ -397,8 +396,8 @@ void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, #endif #if defined(OPENSSL_BN_ASM_MONT) && defined(OPENSSL_ARM) -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num) { +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num) { if (bn_mul8x_mont_neon_capable(num)) { bn_mul8x_mont_neon(rp, ap, bp, np, n0, num); } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc index 4c8d440c9..1ba28018c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc @@ -14,6 +14,8 @@ #include +#include + #include #include @@ -193,9 +195,9 @@ static int BN_prime_checks_for_size(int bits) { // of excluding a candidate with trial division is larger. static size_t num_trial_division_primes(const BIGNUM *n) { if (n->width * BN_BITS2 > 1024) { - return OPENSSL_ARRAY_SIZE(kPrimes); + return std::size(kPrimes); } - return OPENSSL_ARRAY_SIZE(kPrimes) / 2; + return std::size(kPrimes) / 2; } // BN_PRIME_CHECKS_BLINDED is the iteration count for blinding the constant-time diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc index b7a883548..05ede8e07 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -406,7 +408,7 @@ DH *DH_get_rfc7919_2048(void) { } bn_set_static_words(ffdhe2048_p.get(), kFFDHE2048Data, - OPENSSL_ARRAY_SIZE(kFFDHE2048Data)); + std::size(kFFDHE2048Data)); if (!BN_rshift1(ffdhe2048_q.get(), ffdhe2048_p.get()) || !BN_set_word(ffdhe2048_g.get(), 2) || diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc index 622efd3f5..99c75b803 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc @@ -36,7 +36,9 @@ size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { - OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); + ctx->digest = nullptr; + ctx->pctx = nullptr; + ctx->pctx_ops = nullptr; } EVP_MD_CTX *EVP_MD_CTX_new(void) { @@ -53,8 +55,6 @@ EVP_MD_CTX *EVP_MD_CTX_new(void) { EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { - OPENSSL_free(ctx->md_data); - assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); if (ctx->pctx_ops) { ctx->pctx_ops->free(ctx->pctx); @@ -66,7 +66,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { } void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx) { - OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + OPENSSL_cleanse(ctx->md_data, sizeof(ctx->md_data)); EVP_MD_CTX_cleanup(ctx); } @@ -97,6 +97,10 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); return 0; } + if (out == in) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } EVP_PKEY_CTX *pctx = NULL; assert(in->pctx == NULL || in->pctx_ops != NULL); @@ -107,31 +111,9 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { } } - uint8_t *tmp_buf = NULL; - if (in->digest != NULL) { - if (out->digest != in->digest) { - assert(in->digest->ctx_size != 0); - tmp_buf = - reinterpret_cast(OPENSSL_malloc(in->digest->ctx_size)); - if (tmp_buf == NULL) { - if (pctx) { - in->pctx_ops->free(pctx); - } - return 0; - } - } else { - // |md_data| will be the correct size in this case. It's removed from - // |out| so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's - // reused. - tmp_buf = reinterpret_cast(out->md_data); - out->md_data = NULL; - } - } - EVP_MD_CTX_cleanup(out); out->digest = in->digest; - out->md_data = tmp_buf; if (in->digest != NULL) { OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); } @@ -167,14 +149,7 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { if (ctx->digest != type) { assert(type->ctx_size != 0); - uint8_t *md_data = - reinterpret_cast(OPENSSL_malloc(type->ctx_size)); - if (md_data == NULL) { - return 0; - } - - OPENSSL_free(ctx->md_data); - ctx->md_data = md_data; + assert(type->ctx_size <= sizeof(ctx->md_data)); ctx->digest = type; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc index 98bd7726f..40cc2263f 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc @@ -54,6 +54,8 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { out->ctx_size = sizeof(SHA_CTX); } +static_assert(sizeof(SHA_CTX) <= EVP_MAX_MD_DATA_SIZE); + static void sha224_init(EVP_MD_CTX *ctx) { BCM_sha224_init(reinterpret_cast(ctx->md_data)); @@ -78,6 +80,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { out->ctx_size = sizeof(SHA256_CTX); } +static_assert(sizeof(SHA256_CTX) <= EVP_MAX_MD_DATA_SIZE); static void sha256_init(EVP_MD_CTX *ctx) { BCM_sha256_init(reinterpret_cast(ctx->md_data)); @@ -126,6 +129,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { out->ctx_size = sizeof(SHA512_CTX); } +static_assert(sizeof(SHA512_CTX) <= EVP_MAX_MD_DATA_SIZE); static void sha512_init(EVP_MD_CTX *ctx) { BCM_sha512_init(reinterpret_cast(ctx->md_data)); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc index 4b5ff980c..aa3cb4309 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -64,10 +66,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p224) { OPENSSL_memcpy(out->oid, kOIDP224, sizeof(kOIDP224)); out->oid_len = sizeof(kOIDP224); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP224Field), - kP224Field, kP224FieldRR, kP224FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP224Order), - kP224Order, kP224OrderRR, kP224OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP224Field), kP224Field, + kP224FieldRR, kP224FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP224Order), kP224Order, + kP224OrderRR, kP224OrderN0); #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) out->meth = EC_GFp_nistp224_method(); @@ -98,10 +100,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p256) { OPENSSL_memcpy(out->oid, kOIDP256, sizeof(kOIDP256)); out->oid_len = sizeof(kOIDP256); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP256Field), - kP256Field, kP256FieldRR, kP256FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP256Order), - kP256Order, kP256OrderRR, kP256OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP256Field), kP256Field, + kP256FieldRR, kP256FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP256Order), kP256Order, + kP256OrderRR, kP256OrderN0); #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ @@ -129,10 +131,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p384) { OPENSSL_memcpy(out->oid, kOIDP384, sizeof(kOIDP384)); out->oid_len = sizeof(kOIDP384); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP384Field), - kP384Field, kP384FieldRR, kP384FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP384Order), - kP384Order, kP384OrderRR, kP384OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP384Field), kP384Field, + kP384FieldRR, kP384FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP384Order), kP384Order, + kP384OrderRR, kP384OrderN0); out->meth = EC_GFp_mont_method(); out->generator.group = out; @@ -154,10 +156,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p521) { OPENSSL_memcpy(out->oid, kOIDP521, sizeof(kOIDP521)); out->oid_len = sizeof(kOIDP521); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP521Field), - kP521Field, kP521FieldRR, kP521FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP521Order), - kP521Order, kP521OrderRR, kP521OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP521Field), kP521Field, + kP521FieldRR, kP521FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP521Order), kP521Order, + kP521OrderRR, kP521OrderN0); out->meth = EC_GFp_mont_method(); out->generator.group = out; @@ -870,7 +872,7 @@ void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, const EC_PRECOMP *a, const EC_PRECOMP *b) { static_assert(sizeof(out->comb) == sizeof(*out), "out->comb does not span the entire structure"); - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(out->comb); i++) { + for (size_t i = 0; i < std::size(out->comb); i++) { ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]); } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc index 8bb562055..27b46ec76 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc @@ -262,9 +262,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, } if (!BN_mod_sqrt(y, tmp1, field, ctx)) { - uint32_t err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_BN && - ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_BN, BN_R_NOT_A_SQUARE)) { ERR_clear_error(); OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc index 9b1ffc44a..5a29419e6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc @@ -651,9 +651,9 @@ static void ecp_nistz256_inv0_mod_ord(const EC_GROUP *group, EC_SCALAR *out, {4, i_111}, {5, i_111}, {5, i_101}, {3, i_11}, {10, i_101111}, {2, i_11}, {5, i_11}, {5, i_11}, {3, i_1}, {7, i_10101}, {6, i_1111}}; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kChain); i++) { - ecp_nistz256_ord_sqr_mont(out->words, out->words, kChain[i].p); - ecp_nistz256_ord_mul_mont(out->words, out->words, table[kChain[i].i]); + for (const auto &step : kChain) { + ecp_nistz256_ord_sqr_mont(out->words, out->words, step.p); + ecp_nistz256_ord_mul_mont(out->words, out->words, table[step.i]); } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc index 71a6fe18d..cdbff6268 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc @@ -26,18 +26,14 @@ #include #include +#include + #include "../../internal.h" #include "../delocate.h" #include "./internal.h" -#if defined(BORINGSSL_HAS_UINT128) -#include "../../../third_party/fiat/p256_64.h" -#elif defined(OPENSSL_64_BIT) -#include "../../../third_party/fiat/p256_64_msvc.h" -#else -#include "../../../third_party/fiat/p256_32.h" -#endif - +#include "../../../third_party/fiat/p256_field.c.inc" +#include "../../../third_party/fiat/p256_point.br.c.inc" // utility functions, handwritten @@ -56,13 +52,6 @@ static const fiat_p256_felem fiat_p256_one = { #endif // 64BIT -static fiat_p256_limb_t fiat_p256_nz( - const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { - fiat_p256_limb_t ret; - fiat_p256_nonzero(&ret, in1); - return ret; -} - static void fiat_p256_copy(fiat_p256_limb_t out[FIAT_P256_NLIMBS], const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { for (size_t i = 0; i < FIAT_P256_NLIMBS; i++) { @@ -172,198 +161,44 @@ static void fiat_p256_inv_square(fiat_p256_felem out, // Building on top of the field operations we have the operations on the // elliptic curve group itself. Points on the curve are represented in Jacobian // coordinates. -// -// Both operations were transcribed to Coq and proven to correspond to naive -// implementations using Affine coordinates, for all suitable fields. In the -// Coq proofs, issues of constant-time execution and memory layout (aliasing) -// conventions were not considered. Specification of affine coordinates: -// -// As a sanity check, a proof that these points form a commutative group: -// - -// fiat_p256_point_double calculates 2*(x_in, y_in, z_in) -// -// The method is taken from: -// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b -// -// Coq transcription and correctness proof: -// -// -// -// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. -// while x_out == y_in is not (maybe this works, but it's not tested). + static void fiat_p256_point_double(fiat_p256_felem x_out, fiat_p256_felem y_out, fiat_p256_felem z_out, const fiat_p256_felem x_in, const fiat_p256_felem y_in, const fiat_p256_felem z_in) { - fiat_p256_felem delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; - // delta = z^2 - fiat_p256_square(delta, z_in); - // gamma = y^2 - fiat_p256_square(gamma, y_in); - // beta = x*gamma - fiat_p256_mul(beta, x_in, gamma); - - // alpha = 3*(x-delta)*(x+delta) - fiat_p256_sub(ftmp, x_in, delta); - fiat_p256_add(ftmp2, x_in, delta); - - fiat_p256_add(tmptmp, ftmp2, ftmp2); - fiat_p256_add(ftmp2, ftmp2, tmptmp); - fiat_p256_mul(alpha, ftmp, ftmp2); - - // x' = alpha^2 - 8*beta - fiat_p256_square(x_out, alpha); - fiat_p256_add(fourbeta, beta, beta); - fiat_p256_add(fourbeta, fourbeta, fourbeta); - fiat_p256_add(tmptmp, fourbeta, fourbeta); - fiat_p256_sub(x_out, x_out, tmptmp); - - // z' = (y + z)^2 - gamma - delta - fiat_p256_add(delta, gamma, delta); - fiat_p256_add(ftmp, y_in, z_in); - fiat_p256_square(z_out, ftmp); - fiat_p256_sub(z_out, z_out, delta); - - // y' = alpha*(4*beta - x') - 8*gamma^2 - fiat_p256_sub(y_out, fourbeta, x_out); - fiat_p256_add(gamma, gamma, gamma); - fiat_p256_square(gamma, gamma); - fiat_p256_mul(y_out, alpha, y_out); - fiat_p256_add(gamma, gamma, gamma); - fiat_p256_sub(y_out, y_out, gamma); + uint8_t out[3*32], in[3*32]; + static_assert(sizeof(fiat_p256_felem) == 32); + OPENSSL_memcpy(&in[0], x_in, 32); + OPENSSL_memcpy(&in[32], y_in, 32); + OPENSSL_memcpy(&in[64], z_in, 32); + p256_point_double((br_word_t)out, (br_word_t)in); + OPENSSL_memcpy(x_out, &out[0], 32); + OPENSSL_memcpy(y_out, &out[32], 32); + OPENSSL_memcpy(z_out, &out[64], 32); } -// fiat_p256_point_add calculates (x1, y1, z1) + (x2, y2, z2) -// -// The method is taken from: -// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, -// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). -// -// Coq transcription and correctness proof: -// -// -// -// This function includes a branch for checking whether the two input points -// are equal, (while not equal to the point at infinity). This case never -// happens during single point multiplication, so there is no timing leak for -// ECDH or ECDSA signing. static void fiat_p256_point_add(fiat_p256_felem x3, fiat_p256_felem y3, fiat_p256_felem z3, const fiat_p256_felem x1, const fiat_p256_felem y1, - const fiat_p256_felem z1, const int mixed, + const fiat_p256_felem z1, const fiat_p256_felem x2, const fiat_p256_felem y2, const fiat_p256_felem z2) { - fiat_p256_felem x_out, y_out, z_out; - fiat_p256_limb_t z1nz = fiat_p256_nz(z1); - fiat_p256_limb_t z2nz = fiat_p256_nz(z2); - - // z1z1 = z1z1 = z1**2 - fiat_p256_felem z1z1; - fiat_p256_square(z1z1, z1); - - fiat_p256_felem u1, s1, two_z1z2; - if (!mixed) { - // z2z2 = z2**2 - fiat_p256_felem z2z2; - fiat_p256_square(z2z2, z2); - - // u1 = x1*z2z2 - fiat_p256_mul(u1, x1, z2z2); - - // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 - fiat_p256_add(two_z1z2, z1, z2); - fiat_p256_square(two_z1z2, two_z1z2); - fiat_p256_sub(two_z1z2, two_z1z2, z1z1); - fiat_p256_sub(two_z1z2, two_z1z2, z2z2); - - // s1 = y1 * z2**3 - fiat_p256_mul(s1, z2, z2z2); - fiat_p256_mul(s1, s1, y1); - } else { - // We'll assume z2 = 1 (special case z2 = 0 is handled later). - - // u1 = x1*z2z2 - fiat_p256_copy(u1, x1); - // two_z1z2 = 2z1z2 - fiat_p256_add(two_z1z2, z1, z1); - // s1 = y1 * z2**3 - fiat_p256_copy(s1, y1); - } - - // u2 = x2*z1z1 - fiat_p256_felem u2; - fiat_p256_mul(u2, x2, z1z1); - - // h = u2 - u1 - fiat_p256_felem h; - fiat_p256_sub(h, u2, u1); - - fiat_p256_limb_t xneq = fiat_p256_nz(h); - - // z_out = two_z1z2 * h - fiat_p256_mul(z_out, h, two_z1z2); - - // z1z1z1 = z1 * z1z1 - fiat_p256_felem z1z1z1; - fiat_p256_mul(z1z1z1, z1, z1z1); - - // s2 = y2 * z1**3 - fiat_p256_felem s2; - fiat_p256_mul(s2, y2, z1z1z1); - - // r = (s2 - s1)*2 - fiat_p256_felem r; - fiat_p256_sub(r, s2, s1); - fiat_p256_add(r, r, r); - - fiat_p256_limb_t yneq = fiat_p256_nz(r); - - fiat_p256_limb_t is_nontrivial_double = constant_time_is_zero_w(xneq | yneq) & - ~constant_time_is_zero_w(z1nz) & - ~constant_time_is_zero_w(z2nz); - if (constant_time_declassify_w(is_nontrivial_double)) { - fiat_p256_point_double(x3, y3, z3, x1, y1, z1); - return; - } - - // I = (2h)**2 - fiat_p256_felem i; - fiat_p256_add(i, h, h); - fiat_p256_square(i, i); - - // J = h * I - fiat_p256_felem j; - fiat_p256_mul(j, h, i); - - // V = U1 * I - fiat_p256_felem v; - fiat_p256_mul(v, u1, i); - - // x_out = r**2 - J - 2V - fiat_p256_square(x_out, r); - fiat_p256_sub(x_out, x_out, j); - fiat_p256_sub(x_out, x_out, v); - fiat_p256_sub(x_out, x_out, v); - - // y_out = r(V-x_out) - 2 * s1 * J - fiat_p256_sub(y_out, v, x_out); - fiat_p256_mul(y_out, y_out, r); - fiat_p256_felem s1j; - fiat_p256_mul(s1j, s1, j); - fiat_p256_sub(y_out, y_out, s1j); - fiat_p256_sub(y_out, y_out, s1j); - - fiat_p256_cmovznz(x_out, z1nz, x2, x_out); - fiat_p256_cmovznz(x3, z2nz, x1, x_out); - fiat_p256_cmovznz(y_out, z1nz, y2, y_out); - fiat_p256_cmovznz(y3, z2nz, y1, y_out); - fiat_p256_cmovznz(z_out, z1nz, z2, z_out); - fiat_p256_cmovznz(z3, z2nz, z1, z_out); + uint8_t out[3 * 32], in1[3 * 32], in2[3 * 32]; + static_assert(sizeof(fiat_p256_felem) == 32); + OPENSSL_memcpy(&in1[0], x1, 32); + OPENSSL_memcpy(&in1[32], y1, 32); + OPENSSL_memcpy(&in1[64], z1, 32); + OPENSSL_memcpy(&in2[0], x2, 32); + OPENSSL_memcpy(&in2[32], y2, 32); + OPENSSL_memcpy(&in2[64], z2, 32); + p256_point_add_vartime_if_doubling((br_word_t)out, (br_word_t)in1, + (br_word_t)in2); + OPENSSL_memcpy(x3, &out[0], 32); + OPENSSL_memcpy(y3, &out[32], 32); + OPENSSL_memcpy(z3, &out[64], 32); } - #include "./p256_table.h" // fiat_p256_select_point_affine selects the |idx-1|th point from a @@ -454,8 +289,7 @@ static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_JACOBIAN *r, fiat_p256_from_generic(x2, &b->X); fiat_p256_from_generic(y2, &b->Y); fiat_p256_from_generic(z2, &b->Z); - fiat_p256_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, - z2); + fiat_p256_point_add(x1, y1, z1, x1, y1, z1, x2, y2, z2); fiat_p256_to_generic(&r->X, x1); fiat_p256_to_generic(&r->Y, y1); fiat_p256_to_generic(&r->Z, z1); @@ -486,7 +320,7 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, if (j & 1) { fiat_p256_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2], p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2], - 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], p_pre_comp[j - 1][2]); } else { fiat_p256_point_double(p_pre_comp[j][0], p_pre_comp[j][1], @@ -524,8 +358,8 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, fiat_p256_cmovznz(tmp[1], (fiat_p256_limb_t)sign, tmp[1], ftmp); if (!skip) { - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], - 0 /* mixed */, tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } else { fiat_p256_copy(nq[0], tmp[0]); fiat_p256_copy(nq[1], tmp[1]); @@ -562,8 +396,8 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, fiat_p256_g_pre_comp[1], tmp); if (!skip) { - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], - 1 /* mixed */, tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } else { fiat_p256_copy(nq[0], tmp[0]); fiat_p256_copy(nq[1], tmp[1]); @@ -579,8 +413,8 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, // Select the point to add, in constant time. fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, fiat_p256_g_pre_comp[0], tmp); - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, - tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } fiat_p256_to_generic(&r->X, nq[0]); @@ -602,11 +436,10 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, fiat_p256_felem p2[3]; fiat_p256_point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], p_pre_comp[0][1], p_pre_comp[0][2]); - for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) { + for (size_t i = 1; i < std::size(p_pre_comp); i++) { fiat_p256_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], - p_pre_comp[i - 1][2], 0 /* not mixed */, p2[0], p2[1], - p2[2]); + p_pre_comp[i - 1][2], p2[0], p2[1], p2[2]); } // Set up the coefficients for |p_scalar|. @@ -632,9 +465,8 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 1 /* mixed */, fiat_p256_g_pre_comp[1][index][0], - fiat_p256_g_pre_comp[1][index][1], - fiat_p256_one); + fiat_p256_g_pre_comp[1][index][0], + fiat_p256_g_pre_comp[1][index][1], fiat_p256_one); skip = 0; } @@ -646,9 +478,8 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 1 /* mixed */, fiat_p256_g_pre_comp[0][index][0], - fiat_p256_g_pre_comp[0][index][1], - fiat_p256_one); + fiat_p256_g_pre_comp[0][index][0], + fiat_p256_g_pre_comp[0][index][1], fiat_p256_one); skip = 0; } } @@ -664,8 +495,7 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, } if (!skip) { fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 0 /* not mixed */, p_pre_comp[idx][0], *y, - p_pre_comp[idx][2]); + p_pre_comp[idx][0], *y, p_pre_comp[idx][2]); } else { fiat_p256_copy(ret[0], p_pre_comp[idx][0]); fiat_p256_copy(ret[1], *y); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc index 2b659e205..cbe12bce6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc @@ -16,6 +16,9 @@ #include +#include +#include + #include "internal.h" #include "../bn/internal.h" #include "../../internal.h" @@ -31,7 +34,7 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, EC_JACOBIAN precomp[32]; ec_GFp_simple_point_set_to_infinity(group, &precomp[0]); ec_GFp_simple_point_copy(&precomp[1], p); - for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + for (size_t j = 2; j < std::size(precomp); j++) { if (j & 1) { ec_GFp_mont_add(group, &precomp[j], &precomp[1], &precomp[j - 1]); } else { @@ -58,7 +61,7 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, // Select the entry in constant-time. EC_JACOBIAN tmp; OPENSSL_memset(&tmp, 0, sizeof(EC_JACOBIAN)); - for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + for (size_t j = 0; j < std::size(precomp); j++) { BN_ULONG mask = constant_time_eq_w(j, window); ec_point_select(group, &tmp, mask, &precomp[j], &tmp); } @@ -202,10 +205,10 @@ int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, // Store the comb in affine coordinates to shrink the table. (This reduces // cache pressure and makes the constant-time selects faster.) - static_assert(OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb), - "comb sizes did not match"); - return ec_jacobian_to_affine_batch(group, out->comb, comb, - OPENSSL_ARRAY_SIZE(comb)); + static_assert( + std::extent_v == std::extent_vcomb)>, + "comb sizes did not match"); + return ec_jacobian_to_affine_batch(group, out->comb, comb, std::size(comb)); } static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, @@ -224,7 +227,7 @@ static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, // Select precomp->comb[window - 1]. If |window| is zero, |match| will always // be zero, which will leave |out| at infinity. OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN)); - for (unsigned j = 0; j < OPENSSL_ARRAY_SIZE(precomp->comb); j++) { + for (unsigned j = 0; j < std::size(precomp->comb); j++) { BN_ULONG match = constant_time_eq_w(window, j + 1); ec_felem_select(group, &out->X, match, &precomp->comb[j].X, &out->X); ec_felem_select(group, &out->Y, match, &precomp->comb[j].Y, &out->Y); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc index c3cc06d42..e8e1575e3 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -167,7 +169,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, int8_t g_wNAF[EC_MAX_BYTES * 8 + 1]; EC_JACOBIAN g_precomp[EC_WNAF_TABLE_SIZE]; - assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF)); + assert(wNAF_len <= std::size(g_wNAF)); const EC_JACOBIAN *g = &group->generator.raw; if (g_scalar != NULL) { ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS); @@ -175,7 +177,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, } for (size_t i = 0; i < num; i++) { - assert(wNAF_len <= OPENSSL_ARRAY_SIZE(wNAF[i])); + assert(wNAF_len <= std::size(wNAF[i])); ec_compute_wNAF(group, wNAF[i], &scalars[i], bits, EC_WNAF_WINDOW_BITS); compute_precomp(group, precomp[i], &points[i], EC_WNAF_TABLE_SIZE); } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h new file mode 100644 index 000000000..27affb47d --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h @@ -0,0 +1,38 @@ +// Copyright 2025 The BoringSSL Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H + +#include + +#if defined(OPENSSL_LINUX) || defined(OPENSSL_MACOS) + +BSSL_NAMESPACE_BEGIN +namespace entropy { + +// GetSeed fills `out` with random bytes from the jitter source. +OPENSSL_EXPORT bool GetSeed(uint8_t out[48]); + +// GetSamples fetches `n` raw delta time samples. +OPENSSL_EXPORT bool GetSamples(uint64_t *out, size_t n); + +// GetVersion returns the version of the entropy module. +int GetVersion(); + +} // namespace entropy +BSSL_NAMESPACE_END + +#endif // LINUX || MACOS +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc new file mode 100644 index 000000000..4b94acf18 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc @@ -0,0 +1,463 @@ +// Copyright 2025 The BoringSSL Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// BoringCrypto Jitter Entropy version 20250725. + +#include + +#if defined(OPENSSL_LINUX) || defined(OPENSSL_MACOS) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "sha512.cc.inc" + +#if defined(__x86_64__) +#include +#endif + + +BSSL_NAMESPACE_BEGIN +namespace entropy { +namespace { + +#if defined(__x86_64__) +static inline uint64_t GetTimestamp() { return _rdtsc(); } +#elif defined(__aarch64__) +static inline uint64_t GetTimestamp() { + // Ideally this would use __arm_rsr64 from . Clang has supported + // it Clang 3.7 (2016), but GCC did not add it until GCC 14.1.0 (2024). See + // https://crbug.com/440670941. When our minimum GCC is past that point, + // switch this back to __arm_rsr64. + uint64_t ret; + __asm__ volatile("mrs %0, cntvct_el0" : "=r"(ret)); + return ret; +} +#else +static inline uint64_t GetTimestamp() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return ts.tv_sec * 1000000000ULL + ts.tv_nsec; +} +#endif + +class MemoryOffsetLCG { + public: + MemoryOffsetLCG() : state(GetTimestamp() & 0xFFFFFFFF) {} + uint32_t Next() { + state = state * 1664525 + 1013904223; + return state; + } + + private: + uint32_t state; +}; + +class MemoryAccessSampler { + public: + MemoryAccessSampler(size_t array_size, unsigned num_samples) + : array_size_(array_size), + num_samples_(num_samples), + array_(reinterpret_cast(OPENSSL_malloc(array_size_))) { + if (array_ == nullptr || // + array_size_ == 0 || // + array_size_ > (1u << 26) || // + array_size_ & (array_size_ - 1)) { + abort(); + } + } + + ~MemoryAccessSampler() { OPENSSL_free(const_cast(array_)); } + + MemoryAccessSampler(const MemoryAccessSampler &) = delete; + MemoryAccessSampler &operator=(const MemoryAccessSampler &) = delete; + + MemoryAccessSampler(MemoryAccessSampler &&other) + : array_size_(other.array_size_), + num_samples_(other.num_samples_), + lcg_(other.lcg_), + array_(other.array_) { + other.array_ = nullptr; + } + + bool Next(uint64_t *out) { + // Perform some memory accesses and measure how long it took. The LCG is + // intended to defeat any CPU predictors and thus expose this code to as + // much system entropy as possible. + for (unsigned i = 0; i < num_samples_; i++) { + // The lower bits of an LCG tend to fall into short cycles and so are + // discarded here. + array_[(lcg_.Next() >> 6) & (array_size_ - 1)] += 1; + } + + *out = GetTimestamp(); + return true; + } + + private: + const size_t array_size_; + const unsigned num_samples_; + MemoryOffsetLCG lcg_; + volatile uint8_t *array_; +}; + +template +class DeltaSampler { + public: + explicit DeltaSampler(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + // Next function to return the delta between two subsequent samples + bool Next(uint64_t *out) { + uint64_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + + if (!initialized_) { + last_sample_ = sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + initialized_ = true; + } + + *out = sample - last_sample_; + last_sample_ = sample; + return true; + } + + private: + bool initialized_ = false; + T sub_sampler_; + uint64_t last_sample_; +}; + +template +DeltaSampler(U &&sub_sampler) -> DeltaSampler>; + +template +class MaskSampler { + public: + explicit MaskSampler(uint8_t mask, T &&sub_sampler) + : mask_(mask), sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t *out) { + uint64_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + + *out = sample & mask_; + return true; + } + + private: + const uint8_t mask_; + T sub_sampler_; +}; + +template +MaskSampler(uint8_t mask, U &&sub_sampler) -> MaskSampler>; + +// The estimated entropy per sample from MaskSampler. +constexpr float kH = 0.8; + +// kAlphaLog2 is log_2(alpha), where alpha is the standard false-positive +// probability from SP 800-90B. +static constexpr float kAlphaLog2 = -20; +// kAlpha is the variable of the same name from section 4.4.1 of SP 800-90B. +constexpr float kAlpha = 1.0 / (1 << static_cast(-kAlphaLog2)); + +// Ceil rounds up its non-negative argument to the next integer. (std::ceil +// isn't constexpr until C++23.) +constexpr unsigned Ceil(float val) { + auto truncated = static_cast(val); + if (val == static_cast(truncated)) { + return truncated; + } + if (val > 0) { + return truncated + 1; + } + __builtin_unreachable(); +} + +template +class RepetitionCountTest { + public: + static constexpr unsigned kThreshold = 1 + Ceil(-kAlphaLog2 / kH); + static_assert(kThreshold == 26); + + explicit RepetitionCountTest(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t *out) { + uint8_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + if (sample == last_sample_) { + count_++; + } else { + count_ = 1; + last_sample_ = sample; + } + if (count_ >= kThreshold) { + return false; + } + *out = sample; + return true; + } + + private: + T sub_sampler_; + unsigned count_ = 0; + uint8_t last_sample_ = 0; +}; + +template +RepetitionCountTest(U &&sub_sampler) -> RepetitionCountTest>; + +constexpr double BinomialPMF(int64_t k, int64_t n, double p) { + if (k < 0 || k > n) { + return 0.0; + } + + double result = 1.0; + for (int64_t i = 0; i < k; ++i) { + result *= (n - i); + result /= (i + 1); + } + + for (int64_t i = 0; i < k; ++i) { + result *= p; + } + for (int64_t i = 0; i < n - k; ++i) { + result *= (1 - p); + } + + return result; +} + +// CritBinom implements the Excel function of the same name. +constexpr unsigned CritBinom(unsigned trials, double probability_s, + double alpha) { + if (probability_s < 0.0 || probability_s > 1.0 || alpha < 0.0 || + alpha > 1.0) { + __builtin_unreachable(); + } + + double cumulative = 0.0; + for (unsigned k = 0; k <= trials; ++k) { + cumulative += BinomialPMF(k, trials, probability_s); + if (cumulative >= alpha) { + return k; + } + } + + return trials; +} + +// ExpTaylor calculates e^x using the Taylor series: e^x = 1 + x + x²/2! + +// x³/3! + ... +constexpr double ExpTaylor(double x) { + double sum = 1.0; + double term = 1.0; + + for (int i = 1; i < 25; ++i) { + term *= x / i; + sum += term; + } + + return sum; +} + +// Power2 calculates 2^exp by calculating e^(ln(2) * exp) = e^(ln(2)) ^ exp = +// 2^exp. (std::pow isn't constexpr until C++26.) +constexpr double Power2(double exp) { + constexpr double ln2 = 0.693147180559945309417232121458; + return ExpTaylor(exp * ln2); +} + +// AdaptiveProportionTestCutoff implements the function from the footnote on +// page 27 of SP 800-90B. +constexpr unsigned AdaptiveProportionTestCutoff(unsigned W, float H, + float alpha) { + return 1 + CritBinom(W, Power2(-H), 1.0 - alpha); +} + +// These are the example values from table 2 of SP 800-90B, to show that +// we're calculating the values correctly. +static_assert(AdaptiveProportionTestCutoff(512, 0.5, kAlpha) == 410); +static_assert(AdaptiveProportionTestCutoff(512, 1, kAlpha) == 311); +static_assert(AdaptiveProportionTestCutoff(512, 2, kAlpha) == 177); +static_assert(AdaptiveProportionTestCutoff(512, 4, kAlpha) == 62); +static_assert(AdaptiveProportionTestCutoff(512, 8, kAlpha) == 13); + +template +class AdaptiveProportionTest { + public: + // The size of the sliding window, representing the number of recent samples + // to analyze. + static constexpr unsigned kWindowSize = 512; + + // The maximum number of times any single byte value is allowed to appear + // within the sliding window. + static constexpr unsigned kThreshold = + AdaptiveProportionTestCutoff(kWindowSize, kH, kAlpha); + static_assert(kThreshold == 348); + + explicit AdaptiveProportionTest(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) { + counts_.fill(0); + } + + bool Next(uint8_t *out) { + uint8_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + *out = sample; + + if (samples_processed_ >= kWindowSize) { + const uint8_t evicted_sample = buffer_[buffer_idx_]; + counts_[evicted_sample]--; + } + + buffer_[buffer_idx_] = sample; + const uint16_t new_count = ++counts_[sample]; + + if (new_count > kThreshold) { + return false; + } + + buffer_idx_ = (buffer_idx_ + 1) % kWindowSize; + samples_processed_++; + + return true; + } + + private: + T sub_sampler_; + + // A circular buffer to store the most recent `kWindowSize` samples. + std::array buffer_{}; + + // An array to store the frequency counts of each possible byte value (0-255) + // within the current window. + std::array counts_{}; + + // The current index for writing into the circular buffer. + size_t buffer_idx_ = 0; + + // The total number of samples processed. Used to determine when the buffer + // is full and eviction should begin. + size_t samples_processed_ = 0; +}; + +template +AdaptiveProportionTest(U &&sub_sampler) + -> AdaptiveProportionTest>; + +template +class SeedSampler { + public: + // NIST requires 1024 samples at start-up time. This code is structured so + // that the entropy generator is considered to be starting afresh for each + // seed. + static constexpr unsigned kNumSamples = 1024; + + explicit SeedSampler(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t out_seed[48]) { + // HMAC-SHA384 `kNumSamples` samples with an all-zero key: + SHA512_CTX ctx; + SHA384_Init(&ctx); + + uint8_t block[kSHA384Block]; + memset(block, 0x36, sizeof(block)); + SHA384_Update(&ctx, block, sizeof(block)); + + static_assert(kNumSamples % sizeof(block) == 0); + for (unsigned i = 0; i < kNumSamples / sizeof(block); i++) { + for (unsigned j = 0; j < sizeof(block); j++) { + if (!sub_sampler_.Next(&block[j])) { + return false; + } + } + SHA384_Update(&ctx, block, sizeof(block)); + } + + SHA384_Final(out_seed, &ctx); + + SHA384_Init(&ctx); + memset(block, 0x5c, sizeof(block)); + SHA384_Update(&ctx, block, sizeof(block)); + SHA384_Update(&ctx, out_seed, kSHA384DigestLength); + SHA384_Final(out_seed, &ctx); + + return true; + } + + private: + T sub_sampler_; +}; + +template +SeedSampler(U &&sub_sampler) -> SeedSampler>; + +constexpr size_t kMemorySize = 1u << 25; +constexpr size_t kMemoryAccessesPerSample = 16; +constexpr size_t kBitsPerSample = 8; +constexpr uint8_t kMask = (1u << kBitsPerSample) - 1; + +} // namespace + +int GetVersion() { return 20250725; } + +bool GetSeed(uint8_t out[48]) { + auto sampler(SeedSampler(AdaptiveProportionTest(RepetitionCountTest( + MaskSampler(kMask, DeltaSampler(MemoryAccessSampler( + kMemorySize, kMemoryAccessesPerSample))))))); + return sampler.Next(out); +} + +bool GetSamples(uint64_t *out, size_t n) { + auto sampler( + DeltaSampler(MemoryAccessSampler(kMemorySize, kMemoryAccessesPerSample))); + for (size_t i = 0; i < n; i++) { + if (!sampler.Next(&out[i])) { + return false; + } + } + return true; +} + +} // namespace entropy +BSSL_NAMESPACE_END + +#endif // LINUX || MACOS diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc new file mode 100644 index 000000000..14e2975bc --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc @@ -0,0 +1,324 @@ +// Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + + +// This is a copy of the SHA-384 code for the purpose of isolating the jitter +// entropy source certification from any changes to the normal implementation. + +namespace bssl::entropy { +namespace { + +constexpr size_t kSHA384Block = 128; +constexpr size_t kSHA384DigestLength = (384 / 8); + +struct SHA512_CTX { + uint64_t h[8]; + uint64_t Nl, Nh; + uint8_t p[kSHA384Block]; + unsigned num, md_len; +}; + +uint64_t CRYPTO_bswap8(uint64_t x) { return __builtin_bswap64(x); } + +uint64_t CRYPTO_load_u64_be(const void *ptr) { + uint64_t ret; + memcpy(&ret, ptr, sizeof(ret)); + return CRYPTO_bswap8(ret); +} + +void CRYPTO_store_u64_be(void *out, uint64_t v) { + v = CRYPTO_bswap8(v); + memcpy(out, &v, sizeof(v)); +} + +uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) { + return (value >> shift) | (value << ((-shift) & 63)); +} + +void sha512_update(SHA512_CTX *c, const void *in_data, size_t len); +void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha); + +void SHA384_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = kSHA384DigestLength; + return; +} + +void SHA384_Final(uint8_t out[kSHA384DigestLength], SHA512_CTX *sha) { + // This function must be paired with |SHA384_Init|, which sets + // |sha->md_len| to |kSHA384DigestLength|. + sha512_final_impl(out, kSHA384DigestLength, sha); + return; +} + +void SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + return sha512_update(sha, data, len); +} + +void sha512_block_data_order(uint64_t state[8], const uint8_t *in, + size_t num_blocks); + +void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { + uint8_t *p = sha->p; + size_t n = sha->num; + + p[n] = 0x80; // There always is a room for one + n++; + if (n > (sizeof(sha->p) - 16)) { + memset(p + n, 0, sizeof(sha->p) - n); + n = 0; + sha512_block_data_order(sha->h, p, 1); + } + + memset(p + n, 0, sizeof(sha->p) - 16 - n); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, sha->Nh); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, sha->Nl); + + sha512_block_data_order(sha->h, p, 1); + + const size_t out_words = md_len / 8; + for (size_t i = 0; i < out_words; i++) { + CRYPTO_store_u64_be(out, sha->h[i]); + out += 8; + } +} + +const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#define Sigma0(x) \ + (CRYPTO_rotr_u64((x), 28) ^ CRYPTO_rotr_u64((x), 34) ^ \ + CRYPTO_rotr_u64((x), 39)) +#define Sigma1(x) \ + (CRYPTO_rotr_u64((x), 14) ^ CRYPTO_rotr_u64((x), 18) ^ \ + CRYPTO_rotr_u64((x), 41)) +#define sigma0(x) \ + (CRYPTO_rotr_u64((x), 1) ^ CRYPTO_rotr_u64((x), 8) ^ ((x) >> 7)) +#define sigma1(x) \ + (CRYPTO_rotr_u64((x), 19) ^ CRYPTO_rotr_u64((x), 61) ^ ((x) >> 6)) + +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define ROUND_00_15(i, a, b, c, d, e, f, g, h) \ + do { \ + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; \ + h = Sigma0(a) + Maj(a, b, c); \ + d += T1; \ + h += T1; \ + } while (0) + +#define ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X) \ + do { \ + s0 = X[(j + 1) & 0x0f]; \ + s0 = sigma0(s0); \ + s1 = X[(j + 14) & 0x0f]; \ + s1 = sigma1(s1); \ + T1 = X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f]; \ + ROUND_00_15(i + j, a, b, c, d, e, f, g, h); \ + } while (0) + +void sha512_block_data_order(uint64_t state[8], const uint8_t *in, size_t num) { + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint64_t X[16]; + int i; + + while (num--) { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + T1 = X[0] = CRYPTO_load_u64_be(in); + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = CRYPTO_load_u64_be(in + 8); + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = CRYPTO_load_u64_be(in + 2 * 8); + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = CRYPTO_load_u64_be(in + 3 * 8); + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = CRYPTO_load_u64_be(in + 4 * 8); + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = CRYPTO_load_u64_be(in + 5 * 8); + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = CRYPTO_load_u64_be(in + 6 * 8); + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = CRYPTO_load_u64_be(in + 7 * 8); + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = CRYPTO_load_u64_be(in + 8 * 8); + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = CRYPTO_load_u64_be(in + 9 * 8); + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = CRYPTO_load_u64_be(in + 10 * 8); + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = CRYPTO_load_u64_be(in + 11 * 8); + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = CRYPTO_load_u64_be(in + 12 * 8); + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = CRYPTO_load_u64_be(in + 13 * 8); + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = CRYPTO_load_u64_be(in + 14 * 8); + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = CRYPTO_load_u64_be(in + 15 * 8); + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + for (i = 16; i < 80; i += 16) { + ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); + ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + in += 16 * 8; + } +} + +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_80 + +void sha512_update(SHA512_CTX *c, const void *in_data, size_t len) { + uint64_t l; + uint8_t *p = c->p; + const uint8_t *data = reinterpret_cast(in_data); + + if (len == 0) { + return; + } + + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); + if (l < c->Nl) { + c->Nh++; + } + if (sizeof(len) >= 8) { + c->Nh += (((uint64_t)len) >> 61); + } + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->p) - c->num; + + if (len < n) { + memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return; + } else { + memcpy(p + c->num, data, n), c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c->h, p, 1); + } + } + + if (len >= sizeof(c->p)) { + sha512_block_data_order(c->h, data, len / sizeof(c->p)); + data += len; + len %= sizeof(c->p); + data -= len; + } + + if (len != 0) { + memcpy(p, data, len); + c->num = (int)len; + } + + return; +} + +} // namespace +} // namespace bssl::entropy diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc index 20c99193a..4b1007bba 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc @@ -50,7 +50,6 @@ constexpr uint32_t kPrime = 8380417; constexpr uint32_t kPrimeNegInverse = 4236238847; constexpr int kDroppedBits = 13; constexpr uint32_t kHalfPrime = (kPrime - 1) / 2; -constexpr uint32_t kGamma2 = (kPrime - 1) / 32; // 256^-1 mod kPrime, in Montgomery form. constexpr uint32_t kInverseDegreeMontgomery = 41978; @@ -65,6 +64,8 @@ constexpr size_t public_key_bytes() { return BCM_MLDSA65_PUBLIC_KEY_BYTES; } else if constexpr (K == 8) { return BCM_MLDSA87_PUBLIC_KEY_BYTES; + } else if constexpr (K == 4) { + return BCM_MLDSA44_PUBLIC_KEY_BYTES; } } @@ -74,6 +75,8 @@ constexpr size_t signature_bytes() { return BCM_MLDSA65_SIGNATURE_BYTES; } else if constexpr (K == 8) { return BCM_MLDSA87_SIGNATURE_BYTES; + } else if constexpr (K == 4) { + return BCM_MLDSA44_SIGNATURE_BYTES; } } @@ -83,6 +86,8 @@ constexpr int tau() { return 49; } else if constexpr (K == 8) { return 60; + } else if constexpr (K == 4) { + return 39; } } @@ -92,22 +97,71 @@ constexpr int lambda_bytes() { return 192 / 8; } else if constexpr (K == 8) { return 256 / 8; + } else if constexpr (K == 4) { + return 128 / 8; + } +} + +template +constexpr int gamma1_bits() { + if constexpr (K == 6 || K == 8) { + return 19; + } else if constexpr (K == 4) { + return 17; } } template constexpr int gamma1() { + return 1 << gamma1_bits(); +} + +template +constexpr int scalar_le_gamma1_bytes() { + return ((gamma1_bits() + 1) * kDegree) / 8; +} + +template +constexpr uint32_t w1_coeffs_bits() { if constexpr (K == 6 || K == 8) { - return 1 << 19; + return 4; + } else if constexpr (K == 4) { + return 6; } } +template +constexpr uint32_t w1_scalar_bytes() { + return (w1_coeffs_bits() * kDegree) / 8; +} + +template +constexpr uint32_t w1_bytes() { + return w1_scalar_bytes() * K; +} + +template +constexpr uint32_t prime_minus_one_over_gamma2() { + if constexpr (K == 6 || K == 8) { + return 32; + } else if constexpr (K == 4) { + return 88; + } +} + +template +constexpr uint32_t gamma2() { + return (kPrime - 1) / prime_minus_one_over_gamma2(); +} + template constexpr int beta() { if constexpr (K == 6) { return 196; } else if constexpr (K == 8) { return 120; + } else if constexpr (K == 4) { + return 78; } } @@ -117,6 +171,8 @@ constexpr int omega() { return 55; } else if constexpr (K == 8) { return 75; + } else if constexpr (K == 4) { + return 80; } } @@ -124,7 +180,7 @@ template constexpr int eta() { if constexpr (K == 6) { return 4; - } else if constexpr (K == 8) { + } else if constexpr (K == 8 || K == 4) { return 2; } } @@ -133,7 +189,7 @@ template constexpr int plus_minus_eta_bitlen() { if constexpr (K == 6) { return 4; - } else if constexpr (K == 8) { + } else if constexpr (K == 8 || K == 4) { return 3; } } @@ -433,42 +489,54 @@ void scale_power2_round(uint32_t *out, uint32_t r1) { } // FIPS 204, Algorithm 37 (`HighBits`). +template uint32_t high_bits(uint32_t x) { // Reference description (given 0 <= x < q): // // ``` - // int32_t r0 = x mod+- (2 * kGamma2); + // int32_t r0 = x mod+- (2 * gamma2); // if (x - r0 == q - 1) { // return 0; // } else { - // return (x - r0) / (2 * kGamma2); + // return (x - r0) / (2 * gamma2); // } // ``` // - // Below is the formula taken from the reference implementation. - // - // Here, kGamma2 == 2^18 - 2^8 - // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4 uint32_t r1 = (x + 127) >> 7; - r1 = (r1 * 1025 + (1 << 21)) >> 22; - r1 &= 15; + if constexpr (prime_minus_one_over_gamma2() == 32) { + // Below is the formula taken from the reference implementation. + // + // Here, Gamma2 == 2^18 - 2^8 + // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4 + r1 = (r1 * 1025 + (1 << 21)) >> 22; + r1 &= 15; + } else if constexpr (prime_minus_one_over_gamma2() == 88) { + // 1488/2^24 is close enough to 1/1488 so that r1 becomes x/(2 gamma2) + // rounded down. + r1 = (r1 * 11275 + (1 << 23)) >> 24; + + // For corner-case r1 = (Q-1)/(2 gamma2) = 44, we have to set r1=0. + r1 ^= ((uint32_t)(((int32_t)(43 - r1)) >> 31)) & r1; + } return r1; } // FIPS 204, Algorithm 36 (`Decompose`). +template void decompose(uint32_t *r1, int32_t *r0, uint32_t r) { - *r1 = high_bits(r); + *r1 = high_bits(r); *r0 = r; - *r0 -= *r1 * 2 * (int32_t)kGamma2; + *r0 -= *r1 * 2 * (int32_t)gamma2(); *r0 -= (((int32_t)kHalfPrime - *r0) >> 31) & (int32_t)kPrime; } // FIPS 204, Algorithm 38 (`LowBits`). +template int32_t low_bits(uint32_t x) { uint32_t r1; int32_t r0; - decompose(&r1, &r0, x); + decompose(&r1, &r0, x); return r0; } @@ -480,24 +548,45 @@ int32_t low_bits(uint32_t x) { // // It then computes HighBits (algorithm 37) of z and z+r. But z+r is just w - // cs2, so this takes three arguments and saves an addition. +template int32_t make_hint(uint32_t ct0, uint32_t cs2, uint32_t w) { uint32_t r_plus_z = mod_sub(w, cs2); uint32_t r = reduce_once(r_plus_z + ct0); - return high_bits(r) != high_bits(r_plus_z); + return high_bits(r) != high_bits(r_plus_z); } // FIPS 204, Algorithm 40 (`UseHint`). +template uint32_t use_hint_vartime(uint32_t h, uint32_t r) { uint32_t r1; int32_t r0; - decompose(&r1, &r0, r); + decompose(&r1, &r0, r); if (h) { - if (r0 > 0) { - // m = 16, thus |mod m| in the spec turns into |& 15|. - return (r1 + 1) & 15; + if constexpr (prime_minus_one_over_gamma2() == 32) { + if (r0 > 0) { + // (Q-1)/(2 gamma2) = m = 16, thus |mod m| in the spec turns into |& + // 15|. + return (r1 + 1) & 15; + } else { + return (r1 - 1) & 15; + } } else { - return (r1 - 1) & 15; + // m = 44 + static_assert(prime_minus_one_over_gamma2() == 88); + if (r0 > 0) { + if (r1 == 43) { + return 0; + } else { + return r1 + 1; + } + } else { + if (r1 == 0) { + return 43; + } else { + return r1 - 1; + } + } } } return r1; @@ -515,15 +604,17 @@ void scalar_scale_power2_round(scalar *out, const scalar *in) { } } +template void scalar_high_bits(scalar *out, const scalar *in) { for (int i = 0; i < kDegree; i++) { - out->c[i] = high_bits(in->c[i]); + out->c[i] = high_bits(in->c[i]); } } +template void scalar_low_bits(scalar *out, const scalar *in) { for (int i = 0; i < kDegree; i++) { - out->c[i] = low_bits(in->c[i]); + out->c[i] = low_bits(in->c[i]); } } @@ -541,16 +632,18 @@ void scalar_max_signed(uint32_t *max, const scalar *s) { } } +template void scalar_make_hint(scalar *out, const scalar *ct0, const scalar *cs2, const scalar *w) { for (int i = 0; i < kDegree; i++) { - out->c[i] = make_hint(ct0->c[i], cs2->c[i], w->c[i]); + out->c[i] = make_hint(ct0->c[i], cs2->c[i], w->c[i]); } } +template void scalar_use_hint_vartime(scalar *out, const scalar *h, const scalar *r) { for (int i = 0; i < kDegree; i++) { - out->c[i] = use_hint_vartime(h->c[i], r->c[i]); + out->c[i] = use_hint_vartime(h->c[i], r->c[i]); } } @@ -568,17 +661,17 @@ void vector_scale_power2_round(vector *out, const vector *in) { } } -template -void vector_high_bits(vector *out, const vector *in) { - for (int i = 0; i < X; i++) { - scalar_high_bits(&out->v[i], &in->v[i]); +template +void vector_high_bits(vector *out, const vector *in) { + for (int i = 0; i < K; i++) { + scalar_high_bits(&out->v[i], &in->v[i]); } } -template -void vector_low_bits(vector *out, const vector *in) { - for (int i = 0; i < X; i++) { - scalar_low_bits(&out->v[i], &in->v[i]); +template +void vector_low_bits(vector *out, const vector *in) { + for (int i = 0; i < K; i++) { + scalar_low_bits(&out->v[i], &in->v[i]); } } @@ -612,19 +705,19 @@ size_t vector_count_ones(const vector *a) { return count; } -template -void vector_make_hint(vector *out, const vector *ct0, - const vector *cs2, const vector *w) { - for (int i = 0; i < X; i++) { - scalar_make_hint(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]); +template +void vector_make_hint(vector *out, const vector *ct0, + const vector *cs2, const vector *w) { + for (int i = 0; i < K; i++) { + scalar_make_hint(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]); } } -template -void vector_use_hint_vartime(vector *out, const vector *h, - const vector *r) { - for (int i = 0; i < X; i++) { - scalar_use_hint_vartime(&out->v[i], &h->v[i], &r->v[i]); +template +void vector_use_hint_vartime(vector *out, const vector *h, + const vector *r) { + for (int i = 0; i < K; i++) { + scalar_use_hint_vartime(&out->v[i], &h->v[i], &r->v[i]); } } @@ -643,6 +736,25 @@ static void scalar_encode_4(uint8_t out[128], const scalar *s) { } } +// FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 6. +void scalar_encode_6(uint8_t out[192], const scalar *s) { + // Every four elements lands on a byte boundary. + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = s->c[4 * i]; + uint32_t b = s->c[4 * i + 1]; + uint32_t c = s->c[4 * i + 2]; + uint32_t d = s->c[4 * i + 3]; + declassify_assert(a < 64); + declassify_assert(b < 64); + declassify_assert(c < 64); + declassify_assert(d < 64); + out[3 * i] = a | (b << 6); + out[3 * i + 1] = (b >> 2) | (c << 4); + out[3 * i + 2] = (c >> 4) | (d << 2); + } +} + // FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 10. void scalar_encode_10(uint8_t out[320], const scalar *s) { // Every four elements lands on a byte boundary. @@ -730,10 +842,10 @@ void scalar_encode_signed_13_12(uint8_t out[416], const scalar *s) { e |= g << 14; e |= h << 27; h >>= 5; - OPENSSL_memcpy(&out[13 * i], &a, sizeof(a)); - OPENSSL_memcpy(&out[13 * i + 4], &c, sizeof(c)); - OPENSSL_memcpy(&out[13 * i + 8], &e, sizeof(e)); - OPENSSL_memcpy(&out[13 * i + 12], &h, 1); + CRYPTO_store_u32_le(&out[13 * i], a); + CRYPTO_store_u32_le(&out[13 * i + 4], c); + CRYPTO_store_u32_le(&out[13 * i + 8], e); + out[13 * i + 12] = static_cast(h); } } @@ -757,9 +869,35 @@ void scalar_encode_signed_20_19(uint8_t out[640], const scalar *s) { b |= c << 8; b |= d << 28; d >>= 4; - OPENSSL_memcpy(&out[10 * i], &a, sizeof(a)); - OPENSSL_memcpy(&out[10 * i + 4], &b, sizeof(b)); - OPENSSL_memcpy(&out[10 * i + 8], &d, 2); + CRYPTO_store_u32_le(&out[10 * i], a); + CRYPTO_store_u32_le(&out[10 * i + 4], b); + CRYPTO_store_u16_le(&out[10 * i + 8], static_cast(d)); + } +} + +// FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 18 and b = +// 2^17. +void scalar_encode_signed_18_17(uint8_t out[576], const scalar *s) { + static const uint32_t kMax = 1u << 17; + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = mod_sub(kMax, s->c[4 * i]); + uint32_t b = mod_sub(kMax, s->c[4 * i + 1]); + uint32_t c = mod_sub(kMax, s->c[4 * i + 2]); + uint32_t d = mod_sub(kMax, s->c[4 * i + 3]); + declassify_assert(a < (1u << 18)); + declassify_assert(b < (1u << 18)); + declassify_assert(c < (1u << 18)); + declassify_assert(d < (1u << 18)); + out[9 * i] = (uint8_t)a; + out[9 * i + 1] = (uint8_t)(a >> 8); + out[9 * i + 2] = (uint8_t)(a >> 16) | (uint8_t)(b << 2); + out[9 * i + 3] = (uint8_t)(b >> 6); + out[9 * i + 4] = (uint8_t)(b >> 14) | (uint8_t)(c << 4); + out[9 * i + 5] = (uint8_t)(c >> 4); + out[9 * i + 6] = (uint8_t)(c >> 12) | (uint8_t)(d << 6); + out[9 * i + 7] = (uint8_t)(d >> 2); + out[9 * i + 8] = (uint8_t)(d >> 10); } } @@ -775,6 +913,9 @@ void scalar_encode_signed(uint8_t *out, const scalar *s, int bits, } else if (bits == 20) { assert(max == 1u << 19); scalar_encode_signed_20_19(out, s); + } else if (bits == 18) { + assert(max == 1u << 17); + scalar_encode_signed_18_17(out, s); } else { assert(bits == 13); assert(max == 1u << 12); @@ -784,10 +925,9 @@ void scalar_encode_signed(uint8_t *out, const scalar *s, int bits, // FIPS 204, Algorithm 18 (`SimpleBitUnpack`). Specialized for bitlen(b) == 10. void scalar_decode_10(scalar *out, const uint8_t in[320]) { - uint32_t v; static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); for (int i = 0; i < kDegree / 4; i++) { - OPENSSL_memcpy(&v, &in[5 * i], sizeof(v)); + uint32_t v = CRYPTO_load_u32_le(&in[5 * i]); out->c[4 * i] = v & 0x3ff; out->c[4 * i + 1] = (v >> 10) & 0x3ff; out->c[4 * i + 2] = (v >> 20) & 0x3ff; @@ -798,10 +938,9 @@ void scalar_decode_10(scalar *out, const uint8_t in[320]) { // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 4 and b = // 4. int scalar_decode_signed_4_4(scalar *out, const uint8_t in[128]) { - uint32_t v; static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8"); for (int i = 0; i < kDegree / 8; i++) { - OPENSSL_memcpy(&v, &in[4 * i], sizeof(v)); + uint32_t v = CRYPTO_load_u32_le(&in[4 * i]); // None of the nibbles may be >= 9. So if the MSB of any nibble is set, none // of the other bits may be set. First, select all the MSBs. const uint32_t msbs = v & 0x88888888u; @@ -865,14 +1004,12 @@ void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) { static const uint32_t k13Bits = (1u << 13) - 1; static const uint32_t k7Bits = (1u << 7) - 1; - uint32_t a, b, c; - uint8_t d; static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8"); for (int i = 0; i < kDegree / 8; i++) { - OPENSSL_memcpy(&a, &in[13 * i], sizeof(a)); - OPENSSL_memcpy(&b, &in[13 * i + 4], sizeof(b)); - OPENSSL_memcpy(&c, &in[13 * i + 8], sizeof(c)); - d = in[13 * i + 12]; + uint32_t a = CRYPTO_load_u32_le(&in[13 * i]); + uint32_t b = CRYPTO_load_u32_le(&in[13 * i + 4]); + uint32_t c = CRYPTO_load_u32_le(&in[13 * i + 8]); + uint8_t d = in[13 * i + 12]; // It's not possible for a 13-bit number to be out of range when the max is // 2^12. @@ -887,19 +1024,43 @@ void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) { } } +// FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 18 and b = +// 2^17. +void scalar_decode_signed_18_17(scalar *out, const uint8_t in[576]) { + static const uint32_t kMax = 1u << 17; + + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = uint32_t{in[9 * i]} | (uint32_t{in[9 * i + 1]} << 8) | + ((uint32_t{in[9 * i + 2]} & 0x3) << 16); + uint32_t b = (uint32_t{in[9 * i + 2]} >> 2) | + (uint32_t{in[9 * i + 3]} << 6) | + ((uint32_t{in[9 * i + 4]} & 0xf) << 14); + uint32_t c = (uint32_t{in[9 * i + 4]} >> 4) | + (uint32_t{in[9 * i + 5]} << 4) | + ((uint32_t{in[9 * i + 6]} & 0x3f) << 12); + uint32_t d = (uint32_t{in[9 * i + 6]} >> 6) | + (uint32_t{in[9 * i + 7]} << 2) | + (uint32_t{in[9 * i + 8]} << 10); + + out->c[i * 4] = mod_sub(kMax, a); + out->c[i * 4 + 1] = mod_sub(kMax, b); + out->c[i * 4 + 2] = mod_sub(kMax, c); + out->c[i * 4 + 3] = mod_sub(kMax, d); + } +} + // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 20 and b = // 2^19. void scalar_decode_signed_20_19(scalar *out, const uint8_t in[640]) { static const uint32_t kMax = 1u << 19; static const uint32_t k20Bits = (1u << 20) - 1; - uint32_t a, b; - uint16_t c; static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); for (int i = 0; i < kDegree / 4; i++) { - OPENSSL_memcpy(&a, &in[10 * i], sizeof(a)); - OPENSSL_memcpy(&b, &in[10 * i + 4], sizeof(b)); - OPENSSL_memcpy(&c, &in[10 * i + 8], sizeof(c)); + uint32_t a = CRYPTO_load_u32_le(&in[10 * i]); + uint32_t b = CRYPTO_load_u32_le(&in[10 * i + 4]); + uint16_t c = CRYPTO_load_u16_le(&in[10 * i + 8]); // It's not possible for a 20-bit number to be out of range when the max is // 2^19. @@ -923,6 +1084,10 @@ int scalar_decode_signed(scalar *out, const uint8_t *in, int bits, assert(max == (1u << 12)); scalar_decode_signed_13_12(out, in); return 1; + } else if (bits == 18) { + assert(max == (1u << 17)); + scalar_decode_signed_18_17(out, in); + return 1; } else if (bits == 20) { assert(max == (1u << 19)); scalar_decode_signed_20_19(out, in); @@ -1016,13 +1181,14 @@ void scalar_uniform(scalar *out, const uint8_t derived_seed[kSigmaBytes + 2]) { } // FIPS 204, Algorithm 34 (`ExpandMask`), but just a single step. +template void scalar_sample_mask(scalar *out, const uint8_t derived_seed[kRhoPrimeBytes + 2]) { - uint8_t buf[640]; + uint8_t buf[scalar_le_gamma1_bytes()]; BORINGSSL_keccak(buf, sizeof(buf), derived_seed, kRhoPrimeBytes + 2, boringssl_shake256); - scalar_decode_signed_20_19(out, buf); + scalar_decode_signed(out, buf, gamma1_bits() + 1, gamma1()); } // FIPS 204, Algorithm 29 (`SampleInBall`). @@ -1108,7 +1274,7 @@ void vector_expand_short(vector *s1, vector *s2, } // FIPS 204, Algorithm 34 (`ExpandMask`). -template +template void vector_expand_mask(vector *out, const uint8_t seed[kRhoPrimeBytes], size_t kappa) { assert(kappa + L <= 0x10000); @@ -1119,7 +1285,7 @@ void vector_expand_mask(vector *out, const uint8_t seed[kRhoPrimeBytes], size_t index = kappa + i; derived_seed[kRhoPrimeBytes] = index & 0xFF; derived_seed[kRhoPrimeBytes + 1] = (index >> 8) & 0xFF; - scalar_sample_mask(&out->v[i], derived_seed); + scalar_sample_mask(&out->v[i], derived_seed); } } @@ -1136,6 +1302,10 @@ void vector_encode(uint8_t *out, const vector *a, int bits) { for (int i = 0; i < K; i++) { scalar_encode_4(out + i * bits * kDegree / 8, &a->v[i]); } + } else if (bits == 6) { + for (int i = 0; i < K; i++) { + scalar_encode_6(out + i * bits * kDegree / 8, &a->v[i]); + } } else { assert(bits == 10); for (int i = 0; i < K; i++) { @@ -1179,8 +1349,8 @@ int vector_decode_signed(vector *out, const uint8_t *in, int bits, // FIPS 204, Algorithm 28 (`w1Encode`). template -void w1_encode(uint8_t out[128 * K], const vector *w1) { - vector_encode(out, w1, 4); +void w1_encode(uint8_t out[w1_bytes()], const vector *w1) { + vector_encode(out, w1, w1_coeffs_bits()); } // FIPS 204, Algorithm 20 (`HintBitPack`). @@ -1364,10 +1534,11 @@ int mldsa_marshal_signature(CBB *out, const struct signature *sign) { } uint8_t *vectorl_output; - if (!CBB_add_space(out, &vectorl_output, 640 * L)) { + if (!CBB_add_space(out, &vectorl_output, scalar_le_gamma1_bytes() * L)) { return 0; } - vector_encode_signed(vectorl_output, &sign->z, 20, 1 << 19); + vector_encode_signed(vectorl_output, &sign->z, gamma1_bits() + 1, + gamma1()); uint8_t *hint_output; if (!CBB_add_space(out, &hint_output, omega() + K)) { @@ -1384,9 +1555,10 @@ int mldsa_parse_signature(struct signature *sign, CBS *in) { CBS z_bytes; CBS hint_bytes; if (!CBS_copy_bytes(in, sign->c_tilde, sizeof(sign->c_tilde)) || - !CBS_get_bytes(in, &z_bytes, 640 * L) || - // Note: Decoding 20 bits into (-2^19, 2^19] cannot fail. - !vector_decode_signed(&sign->z, CBS_data(&z_bytes), 20, 1 << 19) || + !CBS_get_bytes(in, &z_bytes, scalar_le_gamma1_bytes() * L) || + // Note: Decoding b+1 bits into (-2^b, 2^b] cannot fail. + !vector_decode_signed(&sign->z, CBS_data(&z_bytes), gamma1_bits() + 1, + gamma1()) || !CBS_get_bytes(in, &hint_bytes, omega() + K) || !hint_bit_unpack(&sign->h, CBS_data(&hint_bytes))) { return 0; @@ -1561,7 +1733,7 @@ int mldsa_sign_mu( // kappa must not exceed 2**16/L = 13107. But the probability of it // exceeding even 1000 iterations is vanishingly small. for (size_t kappa = 0;; kappa += L) { - vector_expand_mask(&values->y, rho_prime, kappa); + vector_expand_mask(&values->y, rho_prime, kappa); vector *y_ntt = &values->cs1; OPENSSL_memcpy(y_ntt, &values->y, sizeof(*y_ntt)); @@ -1571,12 +1743,12 @@ int mldsa_sign_mu( vector_inverse_ntt(&values->w); vector_high_bits(&values->w1, &values->w); - uint8_t w1_encoded[128 * K]; + uint8_t w1_encoded[w1_bytes()]; w1_encode(w1_encoded, &values->w1); BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256); BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes); - BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K); + BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes()); BORINGSSL_keccak_squeeze(&keccak_ctx, values->sign.c_tilde, 2 * lambda_bytes()); @@ -1609,7 +1781,7 @@ int mldsa_sign_mu( uint32_t r0_max = vector_max_signed(r0); if (constant_time_declassify_w( constant_time_ge_w(z_max, gamma1() - beta()) | - constant_time_ge_w(r0_max, kGamma2 - beta()))) { + constant_time_ge_w(r0_max, gamma2() - beta()))) { #if defined(BORINGSSL_FIPS_BREAK_TESTS) // In order to show that our self-tests trigger both restart cases in // this loop, printf-logging is added when built in break-test mode. @@ -1626,7 +1798,7 @@ int mldsa_sign_mu( // See above. uint32_t ct0_max = vector_max(ct0); size_t h_ones = vector_count_ones(&values->sign.h); - if (constant_time_declassify_w(constant_time_ge_w(ct0_max, kGamma2) | + if (constant_time_declassify_w(constant_time_ge_w(ct0_max, gamma2()) | constant_time_lt_w(omega(), h_ones))) { #if defined(BORINGSSL_FIPS_BREAK_TESTS) // In order to show that our self-tests trigger both restart cases in @@ -1778,13 +1950,13 @@ int mldsa_verify_internal_no_self_test( vector_inverse_ntt(w1); vector_use_hint_vartime(w1, &values->sign.h, w1); - uint8_t w1_encoded[128 * K]; + uint8_t w1_encoded[w1_bytes()]; w1_encode(w1_encoded, w1); uint8_t c_tilde[2 * lambda_bytes()]; BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256); BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes); - BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K); + BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes()); BORINGSSL_keccak_squeeze(&keccak_ctx, c_tilde, 2 * lambda_bytes()); uint32_t z_max = vector_max(&values->sign.z); @@ -1871,6 +2043,39 @@ struct prehash_context *prehash_context_from_external_87( return reinterpret_cast(external); } +struct private_key<4, 4> *private_key_from_external_44( + const struct BCM_mldsa44_private_key *external) { + static_assert(sizeof(struct BCM_mldsa44_private_key) == + sizeof(struct private_key<4, 4>), + "MLDSA44 private key size incorrect"); + static_assert(alignof(struct BCM_mldsa44_private_key) == + alignof(struct private_key<4, 4>), + "MLDSA44 private key alignment incorrect"); + return (struct private_key<4, 4> *)external; +} + +struct public_key<4> *public_key_from_external_44( + const struct BCM_mldsa44_public_key *external) { + static_assert( + sizeof(struct BCM_mldsa44_public_key) == sizeof(struct public_key<4>), + "MLDSA44 public key size incorrect"); + static_assert( + alignof(struct BCM_mldsa44_public_key) == alignof(struct public_key<4>), + "MLDSA44 public key alignment incorrect"); + return (struct public_key<4> *)external; +} + +struct prehash_context *prehash_context_from_external_44( + struct BCM_mldsa44_prehash *external) { + static_assert( + sizeof(struct BCM_mldsa44_prehash) == sizeof(struct prehash_context), + "MLDSA pre-hash context size incorrect"); + static_assert( + alignof(struct BCM_mldsa44_prehash) == alignof(struct prehash_context), + "MLDSA pre-hash context alignment incorrect"); + return reinterpret_cast(external); +} + namespace fips { #include "fips_known_values.inc" @@ -2442,6 +2647,209 @@ bcm_status BCM_mldsa87_marshal_public_key( out, mldsa::public_key_from_external_87(public_key))); } + +// ML-DSA-44 specific wrappers. + +bcm_status BCM_mldsa44_parse_public_key( + struct BCM_mldsa44_public_key *public_key, CBS *in) { + return bcm_as_approved_status(mldsa_parse_public_key( + mldsa::public_key_from_external_44(public_key), in)); +} + +bcm_status BCM_mldsa44_marshal_private_key( + CBB *out, const struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status(mldsa_marshal_private_key( + out, mldsa::private_key_from_external_44(private_key))); +} + +bcm_status BCM_mldsa44_parse_private_key( + struct BCM_mldsa44_private_key *private_key, CBS *in) { + return bcm_as_approved_status( + mldsa_parse_private_key(mldsa::private_key_from_external_44(private_key), + in) && + CBS_len(in) == 0); +} + +bcm_status BCM_mldsa44_check_key_fips( + struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status( + mldsa::fips::check_key(mldsa::private_key_from_external_44(private_key))); +} + +// Calls |MLDSA_generate_key_external_entropy| with random bytes from +// |BCM_rand_bytes|. +bcm_status BCM_mldsa44_generate_key( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key) { + BCM_rand_bytes(out_seed, BCM_MLDSA_SEED_BYTES); + return BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key, + out_private_key, out_seed); +} + +bcm_status BCM_mldsa44_private_key_from_seed( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]) { + uint8_t public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES]; + return BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key, + seed); +} + +bcm_status BCM_mldsa44_generate_key_external_entropy( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + return bcm_as_not_approved_status(mldsa_generate_key_external_entropy( + out_encoded_public_key, + mldsa::private_key_from_external_44(out_private_key), entropy)); +} + +bcm_status BCM_mldsa44_generate_key_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } + if (BCM_mldsa44_generate_key(out_encoded_public_key, out_seed, + out_private_key) == bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_generate_key_external_entropy_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } + if (BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key, + out_private_key, entropy) == + bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_private_key_from_seed_fips( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]) { + uint8_t public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES]; + if (BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key, + seed) == bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_public_from_private( + struct BCM_mldsa44_public_key *out_public_key, + const struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status(mldsa_public_from_private( + mldsa::public_key_from_external_44(out_public_key), + mldsa::private_key_from_external_44(private_key))); +} + +bcm_status BCM_mldsa44_sign_internal( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len, + const uint8_t *context, size_t context_len, + const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) { + return bcm_as_approved_status(mldsa_sign_internal( + out_encoded_signature, mldsa::private_key_from_external_44(private_key), + msg, msg_len, context_prefix, context_prefix_len, context, context_len, + randomizer)); +} + +// ML-DSA signature in randomized mode, filling the random bytes with +// |BCM_rand_bytes|. +bcm_status BCM_mldsa44_sign( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len) { + BSSL_CHECK(context_len <= 255); + uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]; + BCM_rand_bytes(randomizer, sizeof(randomizer)); + + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + return BCM_mldsa44_sign_internal( + out_encoded_signature, private_key, msg, msg_len, context_prefix, + sizeof(context_prefix), context, context_len, randomizer); +} + +// ML-DSA pre-hashed API: initializing a pre-hashing context. +void BCM_mldsa44_prehash_init(struct BCM_mldsa44_prehash *out_prehash_ctx, + const struct BCM_mldsa44_public_key *public_key, + const uint8_t *context, size_t context_len) { + BSSL_CHECK(context_len <= 255); + + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + mldsa_prehash_init(mldsa::prehash_context_from_external_44(out_prehash_ctx), + mldsa::public_key_from_external_44(public_key), + context_prefix, sizeof(context_prefix), context, + context_len); +} + +// ML-DSA pre-hashed API: updating a pre-hashing context with a message chunk. +void BCM_mldsa44_prehash_update(struct BCM_mldsa44_prehash *inout_prehash_ctx, + const uint8_t *msg, size_t msg_len) { + mldsa_prehash_update( + mldsa::prehash_context_from_external_44(inout_prehash_ctx), msg, msg_len); +} + +// ML-DSA pre-hashed API: obtaining a message representative to sign. +void BCM_mldsa44_prehash_finalize( + uint8_t out_msg_rep[BCM_MLDSA_MU_BYTES], + struct BCM_mldsa44_prehash *inout_prehash_ctx) { + mldsa_prehash_finalize( + out_msg_rep, mldsa::prehash_context_from_external_44(inout_prehash_ctx)); +} + +// ML-DSA pre-hashed API: signing a message representative. +bcm_status BCM_mldsa44_sign_message_representative( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, + const uint8_t msg_rep[BCM_MLDSA_MU_BYTES]) { + uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]; + BCM_rand_bytes(randomizer, sizeof(randomizer)); + CONSTTIME_SECRET(randomizer, sizeof(randomizer)); + + return bcm_as_approved_status(mldsa_sign_mu( + out_encoded_signature, mldsa::private_key_from_external_44(private_key), + msg_rep, randomizer)); +} + +// FIPS 204, Algorithm 3 (`ML-DSA.Verify`). +bcm_status BCM_mldsa44_verify(const struct BCM_mldsa44_public_key *public_key, + const uint8_t *signature, const uint8_t *msg, + size_t msg_len, const uint8_t *context, + size_t context_len) { + BSSL_CHECK(context_len <= 255); + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + return BCM_mldsa44_verify_internal(public_key, signature, msg, msg_len, + context_prefix, sizeof(context_prefix), + context, context_len); +} + +bcm_status BCM_mldsa44_verify_internal( + const struct BCM_mldsa44_public_key *public_key, + const uint8_t encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, + size_t context_prefix_len, const uint8_t *context, size_t context_len) { + return bcm_as_approved_status(mldsa::mldsa_verify_internal<4, 4>( + mldsa::public_key_from_external_44(public_key), encoded_signature, msg, + msg_len, context_prefix, context_prefix_len, context, context_len)); +} + +bcm_status BCM_mldsa44_marshal_public_key( + CBB *out, const struct BCM_mldsa44_public_key *public_key) { + return bcm_as_approved_status(mldsa_marshal_public_key( + out, mldsa::public_key_from_external_44(public_key))); +} + int boringssl_self_test_mldsa() { return mldsa::fips::keygen_self_test() && mldsa::fips::sign_self_test() && mldsa::fips::verify_self_test(); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc index 72590382f..231c0bb46 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc @@ -17,6 +17,7 @@ #include #include +#include #include "../aes/internal.h" #include "../service_indicator/internal.h" @@ -26,8 +27,122 @@ // Section references in this file refer to SP 800-90Ar1: // http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf -// See table 3. -static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; +// Also see table 3. +constexpr uint64_t kMaxReseedCount = UINT64_C(1) << 48; + +// Implements the BCC function as described in Section 10.3.3. +static void bcc(uint8_t out[AES_BLOCK_SIZE], const AES_KEY *aes_key, + const uint8_t *data, size_t data_len) { + // 1. chaining_value = 0^outlen. + uint8_t *chaining_value = out; + OPENSSL_memset(chaining_value, 0, AES_BLOCK_SIZE); + + // 2. n = len (data)/outlen. + BSSL_CHECK(data_len % AES_BLOCK_SIZE == 0); + const size_t n = data_len / AES_BLOCK_SIZE; + + for (size_t i = 0; i < n; i++) { + const uint8_t *block = data + (i * AES_BLOCK_SIZE); + uint8_t input_block[AES_BLOCK_SIZE]; + + // 4.1: input_block = chaining_value ⊕ block_i. + CRYPTO_xor16(input_block, chaining_value, block); + + // 4.2: chaining_value = Block_Encrypt (Key, input_block). + BCM_aes_encrypt(input_block, chaining_value, aes_key); + } + + // 5. output_block = chaining_value. +} + +// Implements the derivation function as described in Section 10.3.2. +static int block_cipher_df(uint8_t *out, size_t out_len, const uint8_t *input, + size_t input_len) { + // Constants for AES-256 + constexpr size_t kAESKeyLen = 32; + constexpr size_t kAESOutLen = AES_BLOCK_SIZE; + constexpr size_t kMaxNumBits = 512; + + if (out_len > kMaxNumBits / 8 || input_len > (1u << 30)) { + return 0; + } + + // 4. S = L || N || input_string || 0x80. + const size_t s_rawlen = sizeof(uint32_t) + sizeof(uint32_t) + input_len + 1; + // S is padded up to a block size. + const size_t s_len = (s_rawlen + kAESOutLen - 1) & ~(kAESOutLen - 1); + uint8_t iv_plus_s[/* space used below */ kAESOutLen + 4 + 4 + + CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN + + CTR_DRBG_SEED_LEN + 1 + + /* padding */ 7]; + if (kAESOutLen + s_len > sizeof(iv_plus_s)) { + return 0; + } + OPENSSL_memset(iv_plus_s, 0, sizeof(iv_plus_s)); + uint8_t *s_ptr = iv_plus_s + kAESOutLen; + // 2. L = len (input_string)/8. + CRYPTO_store_u32_be(s_ptr, (uint32_t)input_len); + s_ptr += sizeof(uint32_t); + // 3. N = number_of_bits_to_return/8. + CRYPTO_store_u32_be(s_ptr, (uint32_t)out_len); + s_ptr += sizeof(uint32_t); + OPENSSL_memcpy(s_ptr, input, input_len); + s_ptr += input_len; + *s_ptr = 0x80; + + uint8_t temp[kAESKeyLen + kAESOutLen]; + size_t temp_len = 0; + + // 8. K = leftmost (0x00010203...1D1E1F, keylen). + static const uint8_t kInitialKey[kAESKeyLen] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; + AES_KEY aes_key; + bcm_status status = + BCM_aes_set_encrypt_key(kInitialKey, 8 * sizeof(kInitialKey), &aes_key); + BSSL_CHECK(status != bcm_status::failure); + + // 7. i = 0. + uint32_t i = 0; + while (temp_len < sizeof(temp)) { + // 9.1 IV = i || 0^(outlen - len(i)). + CRYPTO_store_u32_be(iv_plus_s, i); + + // 9.2 temp = temp || BCC (K, (IV || S)). + bcc(temp + temp_len, &aes_key, iv_plus_s, kAESOutLen + s_len); + temp_len += kAESOutLen; + + // 9.3 i = i + 1. + i++; + } + + // 10. K = leftmost (temp, keylen). + uint8_t *const k = temp; + + // 11. X = select (temp, keylen+1, keylen+outlen). + uint8_t *const x = temp + kAESKeyLen; + + // 12. temp = the Null string. + temp_len = 0; + + // Create an AES key schedule for the final encryption steps. + status = BCM_aes_set_encrypt_key(k, kAESKeyLen * 8, &aes_key); + BSSL_CHECK(status != bcm_status::failure); + + // 13. While len (temp) < number_of_bits_to_return, do: + while (temp_len < out_len) { + // 13.1 X = Block_Encrypt (K, X). + BCM_aes_encrypt(x, x, &aes_key); + + // 13.2 temp = temp || X. + size_t to_copy = std::min(kAESOutLen, out_len - temp_len); + OPENSSL_memcpy(out + temp_len, x, to_copy); + temp_len += to_copy; + } + + return 1; +} CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, @@ -35,7 +150,24 @@ CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], CTR_DRBG_STATE *drbg = reinterpret_cast( OPENSSL_malloc(sizeof(CTR_DRBG_STATE))); if (drbg == NULL || - !CTR_DRBG_init(drbg, entropy, personalization, personalization_len)) { + !CTR_DRBG_init(drbg, /*df=*/false, entropy, CTR_DRBG_ENTROPY_LEN, + /*nonce=*/nullptr, personalization, personalization_len)) { + CTR_DRBG_free(drbg); + return NULL; + } + + return drbg; +} + +CTR_DRBG_STATE *CTR_DRBG_new_df(const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], + const uint8_t *personalization, + size_t personalization_len) { + CTR_DRBG_STATE *drbg = reinterpret_cast( + OPENSSL_malloc(sizeof(CTR_DRBG_STATE))); + if (drbg == NULL || + !CTR_DRBG_init(drbg, /*df=*/true, entropy, entropy_len, nonce, + personalization, personalization_len)) { CTR_DRBG_free(drbg); return NULL; } @@ -45,26 +177,45 @@ CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], void CTR_DRBG_free(CTR_DRBG_STATE *state) { OPENSSL_free(state); } -int CTR_DRBG_init(CTR_DRBG_STATE *drbg, - const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], +int CTR_DRBG_init(CTR_DRBG_STATE *drbg, int df, const uint8_t *entropy, + size_t entropy_len, const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, size_t personalization_len) { - // Section 10.2.1.3.1 - if (personalization_len > CTR_DRBG_ENTROPY_LEN) { + // Section 10.2.1.3.1 and 10.2.1.3.2 + if (personalization_len > CTR_DRBG_SEED_LEN || + (!df && entropy_len != CTR_DRBG_ENTROPY_LEN) || + (df && (entropy_len < CTR_DRBG_MIN_ENTROPY_LEN || + entropy_len > CTR_DRBG_MAX_ENTROPY_LEN)) || // + (df != (nonce != nullptr))) { return 0; } - uint8_t seed_material[CTR_DRBG_ENTROPY_LEN]; - OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); - - for (size_t i = 0; i < personalization_len; i++) { - seed_material[i] ^= personalization[i]; + uint8_t seed_material[CTR_DRBG_SEED_LEN]; + if (df) { + uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN + + CTR_DRBG_SEED_LEN]; + OPENSSL_memcpy(pre_seed_material, entropy, entropy_len); + OPENSSL_memcpy(pre_seed_material + entropy_len, nonce, CTR_DRBG_NONCE_LEN); + OPENSSL_memcpy(pre_seed_material + entropy_len + CTR_DRBG_NONCE_LEN, + personalization, personalization_len); + const size_t pre_seed_material_length = + entropy_len + CTR_DRBG_NONCE_LEN + personalization_len; + + if (!block_cipher_df(seed_material, sizeof(seed_material), + pre_seed_material, pre_seed_material_length)) { + return 0; + } + } else { + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + for (size_t i = 0; i < personalization_len; i++) { + seed_material[i] ^= personalization[i]; + } } // Section 10.2.1.2 // kInitMask is the result of encrypting blocks with big-endian value 1, 2 // and 3 with the all-zero AES-256 key. - static const uint8_t kInitMask[CTR_DRBG_ENTROPY_LEN] = { + static const uint8_t kInitMask[CTR_DRBG_SEED_LEN] = { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca, @@ -75,6 +226,7 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg, seed_material[i] ^= kInitMask[i]; } + drbg->df = df; drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); OPENSSL_memcpy(drbg->counter, seed_material + 32, 16); drbg->reseed_counter = 1; @@ -82,7 +234,7 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg, return 1; } -static_assert(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, +static_assert(CTR_DRBG_SEED_LEN % AES_BLOCK_SIZE == 0, "not a multiple of AES block size"); // ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a @@ -92,22 +244,15 @@ static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { CRYPTO_store_u32_be(drbg->counter + 12, ctr + n); } -static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, - size_t data_len) { - // Per section 10.2.1.2, |data_len| must be |CTR_DRBG_ENTROPY_LEN|. Here, we - // allow shorter inputs and right-pad them with zeros. This is equivalent to - // the specified algorithm but saves a copy in |CTR_DRBG_generate|. - if (data_len > CTR_DRBG_ENTROPY_LEN) { - return 0; - } - - uint8_t temp[CTR_DRBG_ENTROPY_LEN]; - for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { +static int ctr_drbg_update(CTR_DRBG_STATE *drbg, + const uint8_t data[CTR_DRBG_SEED_LEN]) { + uint8_t temp[CTR_DRBG_SEED_LEN]; + for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i += AES_BLOCK_SIZE) { ctr32_add(drbg, 1); drbg->block(drbg->counter, temp + i, &drbg->ks); } - for (size_t i = 0; i < data_len; i++) { + for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i++) { temp[i] ^= data[i]; } @@ -121,23 +266,46 @@ int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *additional_data, size_t additional_data_len) { - // Section 10.2.1.4 - uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; + return CTR_DRBG_reseed_ex(drbg, entropy, CTR_DRBG_ENTROPY_LEN, + additional_data, additional_data_len); +} + +int CTR_DRBG_reseed_ex(CTR_DRBG_STATE *drbg, const uint8_t *entropy, + size_t entropy_len, const uint8_t *additional_data, + size_t additional_data_len) { + if (additional_data_len > CTR_DRBG_SEED_LEN || + (drbg->df && (entropy_len > CTR_DRBG_MAX_ENTROPY_LEN || + entropy_len < CTR_DRBG_MIN_ENTROPY_LEN)) || + (!drbg->df && entropy_len != CTR_DRBG_ENTROPY_LEN)) { + return 0; + } - if (additional_data_len > 0) { - if (additional_data_len > CTR_DRBG_ENTROPY_LEN) { + uint8_t seed_material[CTR_DRBG_SEED_LEN]; + if (drbg->df) { + // Section 10.2.1.4.2 + uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_SEED_LEN]; + static_assert(CTR_DRBG_MAX_ENTROPY_LEN <= sizeof(pre_seed_material)); + OPENSSL_memcpy(pre_seed_material, entropy, entropy_len); + OPENSSL_memcpy(pre_seed_material + entropy_len, additional_data, + additional_data_len); + const size_t pre_seed_material_len = entropy_len + additional_data_len; + + if (!block_cipher_df(seed_material, sizeof(seed_material), + pre_seed_material, pre_seed_material_len)) { return 0; } - - OPENSSL_memcpy(entropy_copy, entropy, CTR_DRBG_ENTROPY_LEN); - for (size_t i = 0; i < additional_data_len; i++) { - entropy_copy[i] ^= additional_data[i]; + } else { + // Section 10.2.1.4 + static_assert(CTR_DRBG_ENTROPY_LEN == sizeof(seed_material)); + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + if (additional_data_len > 0) { + for (size_t i = 0; i < additional_data_len; i++) { + seed_material[i] ^= additional_data[i]; + } } - - entropy = entropy_copy; } - if (!ctr_drbg_update(drbg, entropy, CTR_DRBG_ENTROPY_LEN)) { + if (!ctr_drbg_update(drbg, seed_material)) { return 0; } @@ -159,9 +327,26 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, return 0; } - if (additional_data_len != 0 && - !ctr_drbg_update(drbg, additional_data, additional_data_len)) { - return 0; + uint8_t processed_additional_data[CTR_DRBG_SEED_LEN]; + OPENSSL_memset(processed_additional_data, 0, + sizeof(processed_additional_data)); + if (additional_data_len != 0) { + if (drbg->df) { + if (!block_cipher_df(processed_additional_data, + sizeof(processed_additional_data), additional_data, + additional_data_len)) { + return 0; + } + } else { + if (additional_data_len > sizeof(processed_additional_data)) { + return 0; + } + OPENSSL_memcpy(processed_additional_data, additional_data, + additional_data_len); + } + if (!ctr_drbg_update(drbg, processed_additional_data)) { + return 0; + } } // kChunkSize is used to interact better with the cache. Since the AES-CTR @@ -170,7 +355,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, // the whole buffer, flushing the L1 cache, and then do another pass (missing // the cache every time) to “encrypt” it. The code can avoid this by // chunking. - static const size_t kChunkSize = 8 * 1024; + constexpr size_t kChunkSize = 8 * 1024; while (out_len >= AES_BLOCK_SIZE) { size_t todo = kChunkSize; @@ -198,9 +383,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, OPENSSL_memcpy(out, block, out_len); } - // Right-padding |additional_data| in step 2.2 is handled implicitly by - // |ctr_drbg_update|, to save a copy. - if (!ctr_drbg_update(drbg, additional_data, additional_data_len)) { + if (!ctr_drbg_update(drbg, processed_additional_data)) { return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h index 2d2262939..3913ff8df 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h @@ -37,14 +37,19 @@ struct ctr_drbg_state_st { ctr128_f ctr; uint8_t counter[16]; uint64_t reseed_counter; + int df; }; -// CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of -// entropy in |entropy| and, optionally, a personalization string up to -// |CTR_DRBG_ENTROPY_LEN| bytes in length. It returns one on success and zero -// on error. -OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, - const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], +// CTR_DRBG_init initialises |*drbg| given |entropy_len| bytes of entropy in +// |entropy| and, optionally, a personalization string up to +// |CTR_DRBG_SEED_LEN| bytes in length. It returns one on success and zero on +// error. +// +// If `df` is false then `entropy_len` must be |CTR_DRBG_ENTROPY_LEN| and +// |nonce| must be nullptr. +OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, int df, + const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, size_t personalization_len); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc index 96e7381e6..82cc41c42 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc @@ -187,8 +187,7 @@ bcm_status BCM_rand_bytes_hwrng(uint8_t *buf, const size_t len) { struct entropy_buffer { // bytes contains entropy suitable for seeding a DRBG. - uint8_t - bytes[CRNGT_BLOCK_SIZE + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t bytes[CRNGT_BLOCK_SIZE + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD]; // bytes_valid indicates the number of bytes of |bytes| that contain valid // data. size_t bytes_valid; @@ -250,11 +249,11 @@ static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, // fill |additional_input| with entropy to supplement |seed|. It sets // |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, - uint8_t seed[CTR_DRBG_ENTROPY_LEN], - uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + uint8_t seed[CTR_DRBG_SEED_LEN], + uint8_t additional_input[CTR_DRBG_SEED_LEN], size_t *out_additional_input_len) { uint8_t entropy_bytes[sizeof(state->last_block) + - CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD]; uint8_t *entropy = entropy_bytes; size_t entropy_len = sizeof(entropy_bytes); @@ -293,12 +292,12 @@ static void rand_get_seed(struct rand_thread_state *state, OPENSSL_memcpy(state->last_block, entropy + entropy_len - CRNGT_BLOCK_SIZE, CRNGT_BLOCK_SIZE); - assert(entropy_len == BORINGSSL_FIPS_OVERREAD * CTR_DRBG_ENTROPY_LEN); - OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); + assert(entropy_len == BORINGSSL_FIPS_OVERREAD * CTR_DRBG_SEED_LEN); + OPENSSL_memcpy(seed, entropy, CTR_DRBG_SEED_LEN); for (size_t i = 1; i < BORINGSSL_FIPS_OVERREAD; i++) { - for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { - seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; + for (size_t j = 0; j < CTR_DRBG_SEED_LEN; j++) { + seed[j] ^= entropy[CTR_DRBG_SEED_LEN * i + j]; } } @@ -307,8 +306,8 @@ static void rand_get_seed(struct rand_thread_state *state, // hardware once the entropy pool has been initialized. *out_additional_input_len = 0; if (want_additional_input && - CRYPTO_sysrand_if_available(additional_input, CTR_DRBG_ENTROPY_LEN)) { - *out_additional_input_len = CTR_DRBG_ENTROPY_LEN; + CRYPTO_sysrand_if_available(additional_input, CTR_DRBG_SEED_LEN)) { + *out_additional_input_len = CTR_DRBG_SEED_LEN; } } @@ -318,12 +317,12 @@ static void rand_get_seed(struct rand_thread_state *state, // fill |additional_input| with entropy to supplement |seed|. It sets // |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, - uint8_t seed[CTR_DRBG_ENTROPY_LEN], - uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + uint8_t seed[CTR_DRBG_SEED_LEN], + uint8_t additional_input[CTR_DRBG_SEED_LEN], size_t *out_additional_input_len) { // If not in FIPS mode, we don't overread from the system entropy source and // we don't depend only on the hardware RDRAND. - CRYPTO_sysrand_for_seed(seed, CTR_DRBG_ENTROPY_LEN); + CRYPTO_sysrand_for_seed(seed, CTR_DRBG_SEED_LEN); *out_additional_input_len = 0; } @@ -384,13 +383,13 @@ bcm_infallible BCM_rand_bytes_with_additional_data( } state->last_block_valid = 0; - uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - uint8_t personalization[CTR_DRBG_ENTROPY_LEN] = {0}; + uint8_t seed[CTR_DRBG_SEED_LEN]; + uint8_t personalization[CTR_DRBG_SEED_LEN] = {0}; size_t personalization_len = 0; rand_get_seed(state, seed, personalization, &personalization_len); - if (!CTR_DRBG_init(&state->drbg, seed, personalization, - personalization_len)) { + if (!CTR_DRBG_init(&state->drbg, /*df=*/true, seed, 32u, seed + 32, + personalization, personalization_len)) { abort(); } state->calls = 0; @@ -422,8 +421,8 @@ bcm_infallible BCM_rand_bytes_with_additional_data( // safety. The children must reseed to avoid working from the same PRNG // state. state->fork_unsafe_buffering != fork_unsafe_buffering) { - uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - uint8_t reseed_additional_data[CTR_DRBG_ENTROPY_LEN] = {0}; + uint8_t seed[CTR_DRBG_SEED_LEN]; + uint8_t reseed_additional_data[CTR_DRBG_SEED_LEN] = {0}; size_t reseed_additional_data_len = 0; rand_get_seed(state, seed, reseed_additional_data, &reseed_additional_data_len); @@ -433,8 +432,9 @@ bcm_infallible BCM_rand_bytes_with_additional_data( // |rand_thread_state_clear_all|. CRYPTO_MUTEX_lock_read(&state->clear_drbg_lock); #endif - if (!CTR_DRBG_reseed(&state->drbg, seed, reseed_additional_data, - reseed_additional_data_len)) { + if (!CTR_DRBG_reseed_ex(&state->drbg, seed, sizeof(seed), + reseed_additional_data, + reseed_additional_data_len)) { abort(); } state->calls = 0; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc index 2bd0ba9c7..c796122e6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc @@ -178,16 +178,14 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, size_t emLen, maskedDBLen, salt_start; FIPS_service_indicator_lock_state(); - // Negative sLen has special meanings: - // -1 sLen == hLen - // -2 salt length is autorecovered from signature - // -N reserved size_t hLen = EVP_MD_size(Hash); - if (sLen == -1) { + if (sLen == RSA_PSS_SALTLEN_DIGEST) { sLen = (int)hLen; - } else if (sLen == -2) { - sLen = -2; - } else if (sLen < -2) { + } else if (sLen == RSA_PSS_SALTLEN_AUTO) { + // Leave |sLen| negative, which will trigger the logic below to recover and + // allow any salt length. + } else if (sLen < 0) { + // Other negative values are reserved. OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } @@ -202,7 +200,7 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, EM++; emLen--; } - // |sLen| may be -2 for the non-standard salt length recovery mode. + // |sLen| may be negative for the non-standard salt length recovery mode. if (emLen < hLen + 2 || (sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); goto err; @@ -299,16 +297,14 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, goto err; } - // Negative sLenRequested has special meanings: - // -1 sLen == hLen - // -2 salt length is maximized - // -N reserved size_t sLen; - if (sLenRequested == -1) { + if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) { sLen = hLen; - } else if (sLenRequested == -2) { + } else if (sLenRequested == RSA_PSS_SALTLEN_AUTO) { + // Use the maximum possible salt length. sLen = emLen - hLen - 2; } else if (sLenRequested < 0) { + // Other negative values are reserved. OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc index 3187658f1..0884e7d00 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -276,12 +278,6 @@ void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, } } -const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { - // We do not support the id-RSASSA-PSS key encoding. If we add support later, - // the |maskHash| field should be filled in for OpenSSL compatibility. - return NULL; -} - void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { if (out_dmp1 != NULL) { @@ -875,8 +871,8 @@ static const BN_ULONG kSmallFactorsLimbs[] = {TOBN(0xc4309333, 0x3ef4e3e1), 0x000017b1}; DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { - out->d = (BN_ULONG *)kSmallFactorsLimbs; - out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs); + out->d = const_cast(kSmallFactorsLimbs); + out->width = std::size(kSmallFactorsLimbs); out->dmax = out->width; out->neg = 0; out->flags = BN_FLG_STATIC_DATA; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc index 29c388970..8689e09b2 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -840,7 +842,7 @@ const BN_ULONG kBoringSSLRSASqrtTwo[] = { TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c), TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484), }; -const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo); +const size_t kBoringSSLRSASqrtTwoLen = std::size(kBoringSSLRSASqrtTwo); // generate_prime sets |out| to a prime with length |bits| such that |out|-1 is // relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to @@ -1183,9 +1185,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, return 0; } - RSA *tmp = NULL; - uint32_t err; - int ret = 0; + bssl::UniquePtr tmp; // |rsa_generate_key_impl|'s 2^-20 failure probability is too high at scale, // so we run the FIPS algorithm four times, bringing it down to 2^-80. We @@ -1195,27 +1195,25 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, do { ERR_clear_error(); // Generate into scratch space, to avoid leaving partial work on failure. - tmp = RSA_new(); - if (tmp == NULL) { - goto out; + tmp.reset(RSA_new()); + if (tmp == nullptr) { + return 0; } - if (rsa_generate_key_impl(tmp, bits, e_value, cb)) { + if (rsa_generate_key_impl(tmp.get(), bits, e_value, cb)) { break; } - err = ERR_peek_error(); - RSA_free(tmp); - tmp = NULL; + tmp = nullptr; failures++; // Only retry on |RSA_R_TOO_MANY_ITERATIONS|. This is so a caller-induced // failure in |BN_GENCB_call| is still fatal. - } while (failures < 4 && ERR_GET_LIB(err) == ERR_LIB_RSA && - ERR_GET_REASON(err) == RSA_R_TOO_MANY_ITERATIONS); + } while (failures < 4 && ERR_equals(ERR_peek_error(), ERR_LIB_RSA, + RSA_R_TOO_MANY_ITERATIONS)); - if (tmp == NULL || (check_fips && !RSA_check_fips(tmp))) { - goto out; + if (tmp == nullptr || (check_fips && !RSA_check_fips(tmp.get()))) { + return 0; } rsa_invalidate_key(rsa); @@ -1235,11 +1233,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, replace_bignum(&rsa->dmq1_fixed, &tmp->dmq1_fixed); replace_bignum(&rsa->iqmp_mont, &tmp->iqmp_mont); rsa->private_key_frozen = tmp->private_key_frozen; - ret = 1; - -out: - RSA_free(tmp); - return ret; + return 1; } int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e_value, diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc index 187c38556..56f7e4b0b 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc @@ -67,8 +67,8 @@ int FIPS_query_algorithm_status(const char *algorithm) { "SHA2-512", "SHA2-512/256", }; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kApprovedAlgorithms); i++) { - if (strcmp(algorithm, kApprovedAlgorithms[i]) == 0) { + for (const char *approved : kApprovedAlgorithms) { + if (strcmp(algorithm, approved) == 0) { return 1; } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc index 2184d3ec2..6ab9abe98 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc @@ -17,6 +17,8 @@ #include #include +#include + #include #include #include @@ -269,7 +271,7 @@ static DH *self_test_dh(void) { }; bn_set_static_words(priv, kFFDHE2048PrivateKeyData, - OPENSSL_ARRAY_SIZE(kFFDHE2048PrivateKeyData)); + std::size(kFFDHE2048PrivateKeyData)); if (!DH_set0_key(dh, NULL, priv)) { goto err; @@ -569,7 +571,7 @@ static int boringssl_self_test_ffdh(void) { ffdhe2048_value = BN_new(); if (ffdhe2048_value) { bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData, - OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData)); + std::size(kFFDHE2048PublicValueData)); } dh = self_test_dh(); @@ -840,11 +842,14 @@ static int boringssl_self_test_fast(void) { } // DBRG KAT - static const uint8_t kDRBGEntropy[48] = { - 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, 0xe5, - 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, 0xbb, 0x4a, - 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, 0x40, 0xc2, 0xb5, 0x0b, - 0xab, 0xe1, 0x4a, 0xae, 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, + static const uint8_t kDRBGEntropy[32] = { + 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, + 0xe5, 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, + 0xbb, 0x4a, 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, + }; + static const uint8_t kDRBGNonce[CTR_DRBG_NONCE_LEN] = { + 0x40, 0xc2, 0xb5, 0x0b, 0xab, 0xe1, 0x4a, 0xae, + 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, }; static const uint8_t kDRBGPersonalization[18] = { 'B', 'C', 'M', 'P', 'e', 'r', 's', 'o', 'n', @@ -852,12 +857,12 @@ static int boringssl_self_test_fast(void) { static const uint8_t kDRBGAD[16] = {'B', 'C', 'M', ' ', 'D', 'R', 'B', 'G', ' ', 'K', 'A', 'T', ' ', 'A', 'D', ' '}; static const uint8_t kDRBGOutput[64] = { - 0x19, 0x1f, 0x2b, 0x49, 0x76, 0x85, 0xfd, 0x51, 0xb6, 0x56, 0xbc, - 0x1c, 0x7d, 0xd5, 0xdd, 0x44, 0x76, 0xa3, 0x5e, 0x17, 0x9b, 0x8e, - 0xb8, 0x98, 0x65, 0x12, 0xca, 0x35, 0x6c, 0xa0, 0x6f, 0xa0, 0x22, - 0xe4, 0xf6, 0xd8, 0x43, 0xed, 0x4e, 0x2d, 0x97, 0x39, 0x43, 0x3b, - 0x57, 0xfc, 0x23, 0x3f, 0x71, 0x0a, 0xe0, 0xed, 0xfe, 0xd5, 0xb8, - 0x67, 0x7a, 0x00, 0x39, 0xb2, 0x6e, 0xa9, 0x25, 0x97, + 0x55, 0x88, 0x81, 0x88, 0x16, 0x49, 0x68, 0xd8, 0x23, 0xc8, 0x18, + 0x57, 0x5d, 0x06, 0xc3, 0x5f, 0x60, 0x3a, 0xe8, 0xfe, 0x7c, 0x7e, + 0x1c, 0x4a, 0x6a, 0xa8, 0x91, 0x07, 0xc0, 0x0d, 0x1f, 0x70, 0x4a, + 0xbb, 0x20, 0x42, 0xd3, 0x3f, 0x19, 0xf1, 0xb1, 0xfc, 0xef, 0xa1, + 0x71, 0xfd, 0xf7, 0xaf, 0xc5, 0x12, 0x7a, 0x98, 0xad, 0x42, 0xbc, + 0x01, 0xe6, 0xa2, 0x83, 0xbc, 0x73, 0xb5, 0xba, 0x84, }; static const uint8_t kDRBGEntropy2[48] = { 0xc7, 0x16, 0x1c, 0xa3, 0x6c, 0x23, 0x09, 0xb7, 0x16, 0xe9, 0x85, 0x9b, @@ -866,21 +871,23 @@ static int boringssl_self_test_fast(void) { 0x76, 0xc1, 0x86, 0xe9, 0x35, 0x18, 0x03, 0x76, 0x3a, 0x79, 0x12, 0xfe, }; static const uint8_t kDRBGReseedOutput[64] = { - 0x00, 0xf2, 0x05, 0xaa, 0xfd, 0x11, 0x6c, 0x77, 0xbc, 0x81, 0x86, - 0x99, 0xca, 0x51, 0xcf, 0x80, 0x15, 0x9f, 0x02, 0x9e, 0x0b, 0xcd, - 0x26, 0xc8, 0x4b, 0x87, 0x8a, 0x15, 0x1a, 0xdd, 0xf2, 0xf3, 0xeb, - 0x94, 0x0b, 0x08, 0xc8, 0xc9, 0x57, 0xa4, 0x0b, 0x4b, 0x0f, 0x13, - 0xde, 0x7c, 0x0c, 0x6a, 0xac, 0x34, 0x4a, 0x9a, 0xf2, 0xd0, 0x83, - 0x02, 0x05, 0x17, 0xc9, 0x81, 0x8f, 0x2a, 0x81, 0x92, + 0xda, 0x49, 0xa1, 0x01, 0x31, 0x71, 0x77, 0xde, 0xf6, 0x8d, 0xb5, + 0x4f, 0x86, 0x0d, 0xc8, 0xd6, 0x3c, 0xaa, 0xbc, 0x72, 0x0a, 0x9c, + 0x8b, 0x68, 0xa9, 0x70, 0xf1, 0x21, 0x13, 0xce, 0xc6, 0xbc, 0xff, + 0xaf, 0xa8, 0xd5, 0x26, 0x76, 0x26, 0xcc, 0x0d, 0x89, 0x66, 0xab, + 0xc2, 0x11, 0xa8, 0x2f, 0xf1, 0x36, 0xa3, 0x2b, 0x52, 0xcd, 0x1a, + 0x2d, 0xe4, 0x82, 0xac, 0x3c, 0xbb, 0xa9, 0x17, 0x90, }; CTR_DRBG_STATE drbg; - if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + if (!CTR_DRBG_init(&drbg, /*df=*/true, kDRBGEntropy, sizeof(kDRBGEntropy), + kDRBGNonce, kDRBGPersonalization, sizeof(kDRBGPersonalization)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, sizeof(kDRBGAD)) || !BORINGSSL_check_test(kDRBGOutput, output, sizeof(kDRBGOutput), "DRBG Generate KAT") || - !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || + !CTR_DRBG_reseed_ex(&drbg, kDRBGEntropy2, sizeof(kDRBGEntropy2), kDRBGAD, + sizeof(kDRBGAD)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, sizeof(kDRBGAD)) || !BORINGSSL_check_test(kDRBGReseedOutput, output, diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h index c5a8113c8..27f806036 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h @@ -17,6 +17,9 @@ #include +#if defined(__cplusplus) +extern "C" { +#endif // FIPS_service_indicator_before_call and |FIPS_service_indicator_after_call| // both currently return the same local thread counter which is slowly @@ -37,6 +40,10 @@ OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(void); OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void); +#if defined(__cplusplus) +} +#endif + #if defined(BORINGSSL_FIPS) // FIPS_service_indicator_update_state records that an approved service has been diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc index 6f2e6c285..aed88be7a 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc @@ -217,7 +217,8 @@ static void evp_md_ctx_verify_service_indicator(const EVP_MD_CTX *ctx, const EVP_MD *mgf1_md; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pctx, &salt_len) || !EVP_PKEY_CTX_get_rsa_mgf1_md(pctx, &mgf1_md) || - (salt_len != -1 && salt_len != (int)EVP_MD_size(pctx_md)) || + (salt_len != RSA_PSS_SALTLEN_DIGEST && + salt_len != (int)EVP_MD_size(pctx_md)) || EVP_MD_type(mgf1_md) != md_type) { // Only PSS where saltLen == hashLen is tested with ACVP. Cases with // non-standard padding functions are also excluded. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc index b11f39824..8cbf88590 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc @@ -40,8 +40,8 @@ bcm_infallible BCM_sha384_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA384_DIGEST_LENGTH; return bcm_infallible::approved; @@ -58,8 +58,8 @@ bcm_infallible BCM_sha512_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); sha->h[7] = UINT64_C(0x5be0cd19137e2179); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA512_DIGEST_LENGTH; return bcm_infallible::approved; @@ -75,8 +75,8 @@ bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0x2b0199fc2c85b8aa); sha->h[7] = UINT64_C(0x0eb72ddc81c52ca2); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA512_256_DIGEST_LENGTH; return bcm_infallible::approved; @@ -124,7 +124,6 @@ bcm_infallible BCM_sha512_transform(SHA512_CTX *c, bcm_infallible BCM_sha512_update(SHA512_CTX *c, const void *in_data, size_t len) { - uint64_t l; uint8_t *p = c->p; const uint8_t *data = reinterpret_cast(in_data); @@ -132,14 +131,10 @@ bcm_infallible BCM_sha512_update(SHA512_CTX *c, const void *in_data, return bcm_infallible::approved; } - l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); - if (l < c->Nl) { - c->Nh++; + c->bytes_so_far_low += len; + if (c->bytes_so_far_low < len) { + c->bytes_so_far_high++; } - if (sizeof(len) >= 8) { - c->Nh += (((uint64_t)len) >> 61); - } - c->Nl = l; if (c->num != 0) { size_t n = sizeof(c->p) - c->num; @@ -195,8 +190,11 @@ static void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { } OPENSSL_memset(p + n, 0, sizeof(sha->p) - 16 - n); - CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, sha->Nh); - CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, sha->Nl); + const uint64_t Nh = (uint64_t{sha->bytes_so_far_high} << 3) | + (sha->bytes_so_far_low >> (64 - 3)); + const uint64_t Nl = sha->bytes_so_far_low << 3; + CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, Nh); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, Nl); sha512_block_data_order(sha->h, p, 1); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc index ec3084d12..3183061bd 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc @@ -17,7 +17,7 @@ #include #include -#include +#include #include "../../internal.h" #include "./params.h" diff --git a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc index 63a360d02..684c27963 100644 --- a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc +++ b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #include "../fipsmodule/ec/internal.h" #include "../internal.h" @@ -35,7 +36,7 @@ // This file implements RFC 9180. -#define MAX_SEED_LEN X25519_PRIVATE_KEY_LEN +#define MAX_SEED_LEN XWING_SEED_LEN #define MAX_SHARED_SECRET_LEN SHA256_DIGEST_LENGTH struct evp_hpke_kem_st { @@ -601,6 +602,122 @@ const EVP_HPKE_KEM *EVP_hpke_p256_hkdf_sha256(void) { return &kKEM; } +#define XWING_PRIVATE_KEY_LEN 32 +#define XWING_PUBLIC_KEY_LEN 1216 +#define XWING_PUBLIC_VALUE_LEN 1120 +#define XWING_SEED_LEN 64 +#define XWING_SHARED_KEY_LEN 32 + +static int xwing_init_key(EVP_HPKE_KEY *key, const uint8_t *priv_key, + size_t priv_key_len) { + CBS cbs; + CBS_init(&cbs, priv_key, priv_key_len); + XWING_private_key private_key; + if (!XWING_parse_private_key(&private_key, &cbs) || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_public_from_private(key->public_key, &private_key)) { + return 0; + } + + if (priv_key_len > sizeof(key->private_key)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + OPENSSL_memcpy(key->private_key, priv_key, priv_key_len); + return 1; +} + +static int xwing_generate_key(EVP_HPKE_KEY *key) { + XWING_private_key private_key; + if (!XWING_generate_key(key->public_key, &private_key)) { + return 0; + } + + CBB cbb; + CBB_init_fixed(&cbb, key->private_key, XWING_PRIVATE_KEY_LEN); + if (!XWING_marshal_private_key(&cbb, &private_key) || + CBB_len(&cbb) != XWING_PRIVATE_KEY_LEN) { + return 0; + } + + return 1; +} + +static int xwing_encap_with_seed(const EVP_HPKE_KEM *kem, + uint8_t *out_shared_secret, + size_t *out_shared_secret_len, + uint8_t *out_enc, size_t *out_enc_len, + size_t max_enc, const uint8_t *peer_public_key, + size_t peer_public_key_len, + const uint8_t *seed, size_t seed_len) { + if (max_enc < XWING_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + if (peer_public_key_len != XWING_PUBLIC_KEY_LEN || + seed_len != XWING_SEED_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_encap_external_entropy(out_enc, out_shared_secret, peer_public_key, + seed)) { + OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out_enc_len = XWING_PUBLIC_VALUE_LEN; + *out_shared_secret_len = XWING_SHARED_KEY_LEN; + return 1; +} + +static int xwing_decap(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len) { + if (enc_len != XWING_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + CBS cbs; + CBS_init(&cbs, key->private_key, XWING_PRIVATE_KEY_LEN); + XWING_private_key private_key; + if (!XWING_parse_private_key(&private_key, &cbs)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_decap(out_shared_secret, enc, &private_key)) { + OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out_shared_secret_len = XWING_SHARED_KEY_LEN; + return 1; +} + +const EVP_HPKE_KEM *EVP_hpke_xwing(void) { + static const EVP_HPKE_KEM kKEM = { + /*id=*/EVP_HPKE_XWING, + /*public_key_len=*/XWING_PUBLIC_KEY_LEN, + /*private_key_len=*/XWING_PRIVATE_KEY_LEN, + /*seed_len=*/XWING_SEED_LEN, + /*enc_len=*/XWING_PUBLIC_VALUE_LEN, + xwing_init_key, + xwing_generate_key, + xwing_encap_with_seed, + xwing_decap, + // X-Wing doesn't support authenticated encapsulation/decapsulation: + // https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem-08#name-use-in-hpke + /* auth_encap_with_seed= */ nullptr, + /* auth_decap= */ nullptr, + }; + return &kKEM; +} + 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) { diff --git a/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc b/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc index 457bdb663..3b2031e5a 100644 --- a/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc +++ b/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc @@ -17,13 +17,15 @@ #include #include #include + +#include #include #include #include #include #include -#include +#include #include "../internal.h" #include "internal.h" @@ -309,7 +311,7 @@ static crypto_word_t word_reverse(crypto_word_t in) { }; #endif - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMasks); i++) { + for (size_t i = 0; i < std::size(kMasks); i++) { in = ((in >> (1 << i)) & kMasks[i]) | ((in & kMasks[i]) << (1 << i)); } diff --git a/Sources/CCryptoBoringSSL/crypto/internal.h b/Sources/CCryptoBoringSSL/crypto/internal.h index 90d70645f..f371bcb5c 100644 --- a/Sources/CCryptoBoringSSL/crypto/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/internal.h @@ -23,6 +23,8 @@ #include #include +#include + #if defined(BORINGSSL_CONSTANT_TIME_VALIDATION) #include #endif @@ -50,6 +52,10 @@ #include #endif +#if defined(_M_X64) || defined(_M_IX86) +#include "intrin.h" +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -100,8 +106,6 @@ typedef __uint128_t uint128_t; #endif #endif -#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - // GCC-like compilers indicate SSE2 with |__SSE2__|. MSVC leaves the caller to // know that x86_64 has SSE2, and uses _M_IX86_FP to indicate SSE2 on x86. // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170 @@ -527,8 +531,6 @@ OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); using CRYPTO_atomic_u32 = std::atomic; -static_assert(sizeof(CRYPTO_atomic_u32) == sizeof(uint32_t)); - inline uint32_t CRYPTO_atomic_load_u32(const CRYPTO_atomic_u32 *val) { return val->load(std::memory_order_seq_cst); } @@ -567,12 +569,6 @@ inline void CRYPTO_atomic_store_u32(CRYPTO_atomic_u32 *val, uint32_t desired) { #endif -// See the comment in the |__cplusplus| section above. -static_assert(sizeof(CRYPTO_atomic_u32) == sizeof(uint32_t), - "CRYPTO_atomic_u32 does not match uint32_t size"); -static_assert(alignof(CRYPTO_atomic_u32) == alignof(uint32_t), - "CRYPTO_atomic_u32 does not match uint32_t alignment"); - // Reference counting. @@ -886,6 +882,16 @@ static inline void *OPENSSL_memset(void *dst, int c, size_t n) { // endianness. They use |memcpy|, and so avoid alignment or strict aliasing // requirements on the input and output pointers. +static inline uint16_t CRYPTO_load_u16_le(const void *in) { + uint16_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void CRYPTO_store_u16_le(void *out, uint16_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + static inline uint16_t CRYPTO_load_u16_be(const void *in) { uint16_t v; OPENSSL_memcpy(&v, in, sizeof(v)); @@ -1444,6 +1450,9 @@ inline int CRYPTO_fuzzer_mode_enabled(void) { return 0; } // CRYPTO_addc_* returns |x + y + carry|, and sets |*out_carry| to the carry // bit. |carry| must be zero or one. + +// NOTE: Unoptimized GCC builds may compile these builtins to non-constant-time +// code. For correct constant-time behavior, ensure builds are optimized. #if OPENSSL_HAS_BUILTIN(__builtin_addc) inline unsigned int CRYPTO_addc_impl(unsigned int x, unsigned int y, @@ -1480,16 +1489,26 @@ inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, static inline uint32_t CRYPTO_addc_u32(uint32_t x, uint32_t y, uint32_t carry, uint32_t *out_carry) { declassify_assert(carry <= 1); +#if defined(_M_IX86) + uint32_t sum = 0; + *out_carry = _addcarry_u32(carry, x, y, &sum); + return sum; +#else uint64_t ret = carry; ret += (uint64_t)x + y; *out_carry = (uint32_t)(ret >> 32); return (uint32_t)ret; +#endif } static inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, uint64_t *out_carry) { declassify_assert(carry <= 1); -#if defined(BORINGSSL_HAS_UINT128) +#if defined(_M_X64) + uint64_t sum = 0; + *out_carry = _addcarry_u64(carry, x, y, &sum); + return sum; +#elif defined(BORINGSSL_HAS_UINT128) uint128_t ret = carry; ret += (uint128_t)x + y; *out_carry = (uint64_t)(ret >> 64); @@ -1544,17 +1563,29 @@ inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, static inline uint32_t CRYPTO_subc_u32(uint32_t x, uint32_t y, uint32_t borrow, uint32_t *out_borrow) { declassify_assert(borrow <= 1); +#if defined(_M_IX86) + uint32_t diff = 0; + *out_borrow = _subborrow_u32(borrow, x, y, &diff); + return diff; +#else uint32_t ret = x - y - borrow; *out_borrow = (x < y) | ((x == y) & borrow); return ret; +#endif } static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, uint64_t *out_borrow) { declassify_assert(borrow <= 1); +#if defined(_M_X64) + uint64_t diff = 0; + *out_borrow = _subborrow_u64(borrow, x, y, &diff); + return diff; +#else uint64_t ret = x - y - borrow; *out_borrow = (x < y) | ((x == y) & borrow); return ret; +#endif } #endif @@ -1567,4 +1598,28 @@ static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, #endif +BSSL_NAMESPACE_BEGIN +// Cleanup implements a custom scope guard, when the cleanup logic does not fit +// in a destructor. Usage: +// +// bssl::Cleanup cleanup = [&] { SomeCleanupWork(local_var); }; +template +class Cleanup { + public: + static_assert(std::is_invocable_v); + static_assert(std::is_same_v, void>); + + Cleanup(F func) : func_(func) {} + Cleanup(const Cleanup &) = delete; + Cleanup &operator=(const Cleanup &) = delete; + ~Cleanup() { func_(); } + + private: + F func_; +}; +template +Cleanup(F func) -> Cleanup; +BSSL_NAMESPACE_END + + #endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/kyber/internal.h b/Sources/CCryptoBoringSSL/crypto/kyber/internal.h index 0d8dc06dc..c7a8d42d6 100644 --- a/Sources/CCryptoBoringSSL/crypto/kyber/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/kyber/internal.h @@ -16,13 +16,122 @@ #define OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H #include -#include #if defined(__cplusplus) extern "C" { #endif +// Kyber is the pre-standard version of ML-KEM. This was once exported as public +// API, but is now internal and only used by libssl. It will be removed entirely +// in the future. +// +// This implements the round-3 specification of Kyber, defined at +// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf + +// KYBER_public_key contains a Kyber768 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_public_key { + union { + uint8_t bytes[512 * (3 + 9) + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_private_key contains a Kyber768 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_private_key { + union { + uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public +// key. +#define KYBER_PUBLIC_KEY_BYTES 1184 + +// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared +// secret. Although the round-3 specification has a variable-length output, the +// final ML-KEM construction is expected to use a fixed 32-byte output. To +// simplify the future transition, we apply the same restriction. +#define KYBER_SHARED_SECRET_BYTES 32 + +// KYBER_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key| and sets |out_private_key| to +// the private key. +OPENSSL_EXPORT void KYBER_generate_key( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key); + +// KYBER_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. (This is faster than parsing the output of +// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key +// that was just generated.) +OPENSSL_EXPORT void KYBER_public_from_private( + struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key); + +// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. +#define KYBER_CIPHERTEXT_BYTES 1088 + +// KYBER_encap encrypts a random shared secret for |public_key|, writes the +// ciphertext to |out_ciphertext|, and writes the random shared secret to +// |out_shared_secret|. +OPENSSL_EXPORT void KYBER_encap( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], + const struct KYBER_public_key *public_key); + +// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key| +// and writes it to |out_shared_secret|. If |ciphertext| is invalid, +// |out_shared_secret| is filled with a key that will always be the same for the +// same |ciphertext| and |private_key|, but which appears to be random unless +// one has access to |private_key|. These alternatives occur in constant time. +// Any subsequent symmetric encryption using |out_shared_secret| must use an +// authenticated encryption scheme in order to discover the decapsulation +// failure. +OPENSSL_EXPORT void KYBER_decap( + uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key); + + +// Serialisation of keys. + +// KYBER_marshal_public_key serializes |public_key| to |out| in the standard +// format for Kyber public keys. It returns one on success or zero on allocation +// error. +OPENSSL_EXPORT int KYBER_marshal_public_key( + CBB *out, const struct KYBER_public_key *public_key); + +// KYBER_parse_public_key parses a public key, in the format generated by +// |KYBER_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_public_key( + struct KYBER_public_key *out_public_key, CBS *in); + +// KYBER_marshal_private_key serializes |private_key| to |out| in the standard +// format for Kyber private keys. It returns one on success or zero on +// allocation error. +OPENSSL_EXPORT int KYBER_marshal_private_key( + CBB *out, const struct KYBER_private_key *private_key); + +// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by +// |KYBER_marshal_private_key|. +#define KYBER_PRIVATE_KEY_BYTES 2400 + +// KYBER_parse_private_key parses a private key, in the format generated by +// |KYBER_marshal_private_key|, from |in| and writes the result to +// |out_private_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_private_key( + struct KYBER_private_key *out_private_key, CBS *in); + + +// Internal symbols. + // KYBER_ENCAP_ENTROPY is the number of bytes of uniformly random entropy // necessary to encapsulate a secret. The entropy will be leaked to the // decapsulating party. diff --git a/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc b/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc index 4af369604..581e701f9 100644 --- a/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc +++ b/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER -#include - #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc b/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc index 0e4d847bf..d18fc9ea3 100644 --- a/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc @@ -28,6 +28,12 @@ static_assert(sizeof(BCM_mldsa87_public_key) == sizeof(MLDSA87_public_key)); static_assert(alignof(BCM_mldsa87_public_key) == alignof(MLDSA87_public_key)); static_assert(sizeof(BCM_mldsa87_prehash) == sizeof(MLDSA87_prehash)); static_assert(alignof(BCM_mldsa87_prehash) == alignof(MLDSA87_prehash)); +static_assert(sizeof(BCM_mldsa44_private_key) == sizeof(MLDSA44_private_key)); +static_assert(alignof(BCM_mldsa44_private_key) == alignof(MLDSA44_private_key)); +static_assert(sizeof(BCM_mldsa44_public_key) == sizeof(MLDSA44_public_key)); +static_assert(alignof(BCM_mldsa44_public_key) == alignof(MLDSA44_public_key)); +static_assert(sizeof(BCM_mldsa44_prehash) == sizeof(MLDSA44_prehash)); +static_assert(alignof(BCM_mldsa44_prehash) == alignof(MLDSA44_prehash)); static_assert(MLDSA_SEED_BYTES == BCM_MLDSA_SEED_BYTES); static_assert(MLDSA_MU_BYTES == BCM_MLDSA_MU_BYTES); static_assert(MLDSA65_PRIVATE_KEY_BYTES == BCM_MLDSA65_PRIVATE_KEY_BYTES); @@ -36,6 +42,9 @@ static_assert(MLDSA65_SIGNATURE_BYTES == BCM_MLDSA65_SIGNATURE_BYTES); static_assert(MLDSA87_PRIVATE_KEY_BYTES == BCM_MLDSA87_PRIVATE_KEY_BYTES); static_assert(MLDSA87_PUBLIC_KEY_BYTES == BCM_MLDSA87_PUBLIC_KEY_BYTES); static_assert(MLDSA87_SIGNATURE_BYTES == BCM_MLDSA87_SIGNATURE_BYTES); +static_assert(MLDSA44_PRIVATE_KEY_BYTES == BCM_MLDSA44_PRIVATE_KEY_BYTES); +static_assert(MLDSA44_PUBLIC_KEY_BYTES == BCM_MLDSA44_PUBLIC_KEY_BYTES); +static_assert(MLDSA44_SIGNATURE_BYTES == BCM_MLDSA44_SIGNATURE_BYTES); int MLDSA65_generate_key( uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], @@ -226,3 +235,98 @@ int MLDSA87_parse_public_key(struct MLDSA87_public_key *public_key, CBS *in) { return bcm_success(BCM_mldsa87_parse_public_key( reinterpret_cast(public_key), in)); } + +int MLDSA44_generate_key( + uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[MLDSA_SEED_BYTES], + struct MLDSA44_private_key *out_private_key) { + return bcm_success(BCM_mldsa44_generate_key( + out_encoded_public_key, out_seed, + reinterpret_cast(out_private_key))); +} + +int MLDSA44_private_key_from_seed(struct MLDSA44_private_key *out_private_key, + const uint8_t *seed, size_t seed_len) { + if (seed_len != BCM_MLDSA_SEED_BYTES) { + return 0; + } + return bcm_success(BCM_mldsa44_private_key_from_seed( + reinterpret_cast(out_private_key), seed)); +} + +int MLDSA44_public_from_private(struct MLDSA44_public_key *out_public_key, + const struct MLDSA44_private_key *private_key) { + return bcm_success(BCM_mldsa44_public_from_private( + reinterpret_cast(out_public_key), + reinterpret_cast(private_key))); +} + +int MLDSA44_sign(uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255) { + return 0; + } + return bcm_success(BCM_mldsa44_sign( + out_encoded_signature, + reinterpret_cast(private_key), msg, + msg_len, context, context_len)); +} + +int MLDSA44_verify(const struct MLDSA44_public_key *public_key, + const uint8_t *signature, size_t signature_len, + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255 || signature_len != BCM_MLDSA44_SIGNATURE_BYTES) { + return 0; + } + return bcm_success(BCM_mldsa44_verify( + reinterpret_cast(public_key), signature, + msg, msg_len, context, context_len)); +} + +int MLDSA44_prehash_init(struct MLDSA44_prehash *out_state, + const struct MLDSA44_public_key *public_key, + const uint8_t *context, size_t context_len) { + if (context_len > 255) { + return 0; + } + BCM_mldsa44_prehash_init( + reinterpret_cast(out_state), + reinterpret_cast(public_key), context, + context_len); + return 1; +} + +void MLDSA44_prehash_update(struct MLDSA44_prehash *inout_state, + const uint8_t *msg, size_t msg_len) { + BCM_mldsa44_prehash_update( + reinterpret_cast(inout_state), msg, msg_len); +} + +void MLDSA44_prehash_finalize(uint8_t out_msg_rep[MLDSA_MU_BYTES], + struct MLDSA44_prehash *inout_state) { + BCM_mldsa44_prehash_finalize( + out_msg_rep, reinterpret_cast(inout_state)); +} + +int MLDSA44_sign_message_representative( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t msg_rep[MLDSA_MU_BYTES]) { + return bcm_success(BCM_mldsa44_sign_message_representative( + out_encoded_signature, + reinterpret_cast(private_key), msg_rep)); +} + +int MLDSA44_marshal_public_key(CBB *out, + const struct MLDSA44_public_key *public_key) { + return bcm_success(BCM_mldsa44_marshal_public_key( + out, reinterpret_cast(public_key))); +} + +int MLDSA44_parse_public_key(struct MLDSA44_public_key *public_key, CBS *in) { + return bcm_success(BCM_mldsa44_parse_public_key( + reinterpret_cast(public_key), in)); +} diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj.cc b/Sources/CCryptoBoringSSL/crypto/obj/obj.cc index aba6f2db0..28ef9f0bc 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj.cc +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj.cc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -173,7 +175,7 @@ int OBJ_obj2nid(const ASN1_OBJECT *obj) { CRYPTO_MUTEX_unlock_read(&global_added_lock); const uint16_t *nid_ptr = reinterpret_cast( - bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), + bsearch(obj, kNIDsInOIDOrder, std::size(kNIDsInOIDOrder), sizeof(kNIDsInOIDOrder[0]), obj_cmp)); if (nid_ptr == NULL) { return NID_undef; @@ -219,10 +221,9 @@ int OBJ_sn2nid(const char *short_name) { } CRYPTO_MUTEX_unlock_read(&global_added_lock); - const uint16_t *nid_ptr = reinterpret_cast( - bsearch(short_name, kNIDsInShortNameOrder, - OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder), - sizeof(kNIDsInShortNameOrder[0]), short_name_cmp)); + const uint16_t *nid_ptr = reinterpret_cast(bsearch( + short_name, kNIDsInShortNameOrder, std::size(kNIDsInShortNameOrder), + sizeof(kNIDsInShortNameOrder[0]), short_name_cmp)); if (nid_ptr == NULL) { return NID_undef; } @@ -254,9 +255,9 @@ int OBJ_ln2nid(const char *long_name) { } CRYPTO_MUTEX_unlock_read(&global_added_lock); - const uint16_t *nid_ptr = reinterpret_cast(bsearch( - long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), - sizeof(kNIDsInLongNameOrder[0]), long_name_cmp)); + const uint16_t *nid_ptr = reinterpret_cast( + bsearch(long_name, kNIDsInLongNameOrder, std::size(kNIDsInLongNameOrder), + sizeof(kNIDsInLongNameOrder[0]), long_name_cmp)); if (nid_ptr == NULL) { return NID_undef; } diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h b/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h index a857d535c..344e7f2ea 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h @@ -15,7 +15,7 @@ // This file is generated by crypto/obj/objects.go. -#define NUM_NID 966 +#define NUM_NID 967 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -8742,6 +8742,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { {"X25519Kyber768Draft00", "X25519Kyber768Draft00", NID_X25519Kyber768Draft00, 0, NULL, 0}, {"X25519MLKEM768", "X25519MLKEM768", NID_X25519MLKEM768, 0, NULL, 0}, + {"MLKEM1024", "MLKEM1024", NID_MLKEM1024, 0, NULL, 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -8864,6 +8865,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 114 /* MD5-SHA1 */, 95 /* MDC2 */, 911 /* MGF1 */, + 966 /* MLKEM1024 */, 388 /* Mail */, 57 /* Netscape */, 366 /* Nonce */, @@ -9755,6 +9757,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 647 /* International Organizations */, 142 /* Invalidity Date */, 504 /* MIME MHS */, + 966 /* MLKEM1024 */, 388 /* Mail */, 383 /* Management */, 417 /* Microsoft CSP Name */, diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc b/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc index 5715bb841..7d65724bc 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc @@ -50,13 +50,13 @@ static const nid_triple kTriples[] = { }; int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { - if (kTriples[i].sign_nid == sign_nid) { + for (const auto &triple : kTriples) { + if (triple.sign_nid == sign_nid) { if (out_digest_nid != NULL) { - *out_digest_nid = kTriples[i].digest_nid; + *out_digest_nid = triple.digest_nid; } if (out_pkey_nid != NULL) { - *out_pkey_nid = kTriples[i].pkey_nid; + *out_pkey_nid = triple.pkey_nid; } return 1; } @@ -66,11 +66,11 @@ int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { } int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { - if (kTriples[i].digest_nid == digest_nid && - kTriples[i].pkey_nid == pkey_nid) { + for (const auto &triple : kTriples) { + if (triple.digest_nid == digest_nid && + triple.pkey_nid == pkey_nid) { if (out_sign_nid != NULL) { - *out_sign_nid = kTriples[i].sign_nid; + *out_sign_nid = triple.sign_nid; } return 1; } diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc index ced7c76b0..832105b72 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc @@ -38,14 +38,17 @@ IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) // the relevant private key: this means can handle "traditional" and PKCS#8 // formats transparently. static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) { - RSA *rtmp; if (!key) { - return NULL; + return nullptr; } - rtmp = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); + if (EVP_PKEY_id(key) != EVP_PKEY_RSA) { + // Don't accept RSA-PSS keys in this function. + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return nullptr; + } + RSA *rtmp = EVP_PKEY_get1_RSA(key); if (!rtmp) { - return NULL; + return nullptr; } if (rsa) { RSA_free(*rsa); @@ -56,15 +59,13 @@ static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) { RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u) { - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); + bssl::UniquePtr pkey(PEM_read_bio_PrivateKey(bp, nullptr, cb, u)); + return pkey_get_rsa(pkey.get(), rsa); } RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) { - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); + bssl::UniquePtr pkey(PEM_read_PrivateKey(fp, nullptr, cb, u)); + return pkey_get_rsa(pkey.get(), rsa); } IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc index 1ea9b8214..1f80787f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc @@ -143,9 +143,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, for (;;) { if (!PEM_read_bio(bp, &name, &header, &data, &len)) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, PEM_R_NO_START_LINE)) { ERR_clear_error(); break; } diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc index 60aafc1b5..028147a4b 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc @@ -182,9 +182,7 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, for (;;) { if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { - uint32_t error = ERR_peek_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + if (ERR_equals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_NO_START_LINE)) { ERR_add_error_data(2, "Expecting: ", name); } return 0; diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc index d06855706..32a5edf58 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc index 0e4f8c581..facc5bb56 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc @@ -271,15 +271,15 @@ static const struct pbe_suite kBuiltinPBE[] = { }; static const struct pbe_suite *get_pkcs12_pbe_suite(int pbe_nid) { - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { - if (kBuiltinPBE[i].pbe_nid == pbe_nid && + for (const auto &pbe : kBuiltinPBE) { + if (pbe.pbe_nid == pbe_nid && // If |cipher_func| or |md_func| are missing, this is a PBES2 scheme. - kBuiltinPBE[i].cipher_func != NULL && kBuiltinPBE[i].md_func != NULL) { - return &kBuiltinPBE[i]; + pbe.cipher_func != nullptr && pbe.md_func != nullptr) { + return &pbe; } } - return NULL; + return nullptr; } int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg_nid, @@ -333,9 +333,9 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, goto err; } - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { - if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { - suite = &kBuiltinPBE[i]; + for (const auto &pbe : kBuiltinPBE) { + if (CBS_mem_equal(&obj, pbe.oid, pbe.oid_len)) { + suite = &pbe; break; } } diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc index 9f4f92a91..19a8bf43d 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/rand/passive.cc b/Sources/CCryptoBoringSSL/crypto/rand/passive.cc index c74ca369a..c73d0d9a1 100644 --- a/Sources/CCryptoBoringSSL/crypto/rand/passive.cc +++ b/Sources/CCryptoBoringSSL/crypto/rand/passive.cc @@ -38,7 +38,7 @@ static void passive_get_seed_entropy(uint8_t *out_entropy, } #define ENTROPY_READ_LEN \ - (/* last_block size */ 16 + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD) + (/* last_block size */ 16 + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD) #if defined(OPENSSL_ANDROID) diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/internal.h b/Sources/CCryptoBoringSSL/crypto/rsa/internal.h index d1702687a..297c90914 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/rsa/internal.h @@ -28,6 +28,31 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, size_t param_len, const EVP_MD *md, const EVP_MD *mgf1md); +enum rsa_pss_params_t { + // RSA-PSS using SHA-256, MGF1 with SHA-256, salt length 32. + rsa_pss_sha256, + // RSA-PSS using SHA-384, MGF1 with SHA-384, salt length 48. + rsa_pss_sha384, + // RSA-PSS using SHA-512, MGF1 with SHA-512, salt length 64. + rsa_pss_sha512, +}; + +// rsa_pss_params_get_md returns the hash function used with |params|. This also +// specifies the MGF-1 hash and the salt length because we do not support other +// configurations. +const EVP_MD *rsa_pss_params_get_md(rsa_pss_params_t params); + +// rsa_marshal_pss_params marshals |params| as a DER-encoded RSASSA-PSS-params +// (RFC 4055). It returns one on success and zero on error. +int rsa_marshal_pss_params(CBB *cbb, rsa_pss_params_t params); + +// rsa_marshal_pss_params decodes a DER-encoded RSASSA-PSS-params +// (RFC 4055). It returns one on success and zero on error. On success, it sets +// |*out| to the result. If |allow_explicit_trailer| is non-zero, an explicit +// encoding of the trailerField is allowed, although it is not valid DER. +int rsa_parse_pss_params(CBS *cbs, rsa_pss_params_t *out, + int allow_explicit_trailer); + #if defined(__cplusplus) } // extern C diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc index 3f66fd77d..f01ed4a3b 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc @@ -20,12 +20,17 @@ #include #include +#include #include #include +#include +#include +#include -#include "../fipsmodule/rsa/internal.h" #include "../bytestring/internal.h" +#include "../fipsmodule/rsa/internal.h" #include "../internal.h" +#include "internal.h" static int parse_integer(CBS *cbs, BIGNUM **out) { @@ -109,7 +114,7 @@ int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, } // kVersionTwoPrime is the value of the version field for a two-prime -// RSAPrivateKey structure (RFC 3447). +// RSAPrivateKey structure (RFC 8017). static const uint64_t kVersionTwoPrime = 0; RSA *RSA_parse_private_key(CBS *cbs) { @@ -205,59 +210,23 @@ int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, } RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - RSA *ret = RSA_parse_public_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - RSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, RSA_parse_public_key); } int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !RSA_marshal_public_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return RSA_marshal_public_key(cbb, in); }); } RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - RSA *ret = RSA_parse_private_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - RSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, RSA_parse_private_key); } int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !RSA_marshal_private_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/512, outp, + [&](CBB *cbb) -> bool { return RSA_marshal_private_key(cbb, in); }); } RSA *RSAPublicKey_dup(const RSA *rsa) { @@ -281,3 +250,146 @@ RSA *RSAPrivateKey_dup(const RSA *rsa) { OPENSSL_free(der); return ret; } + +static const uint8_t kPSSParamsSHA256[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20}; + +static const uint8_t kPSSParamsSHA384[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x30}; + +static const uint8_t kPSSParamsSHA512[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x40}; + +const EVP_MD *rsa_pss_params_get_md(rsa_pss_params_t params) { + switch (params) { + case rsa_pss_sha256: + return EVP_sha256(); + case rsa_pss_sha384: + return EVP_sha384(); + case rsa_pss_sha512: + return EVP_sha512(); + } + abort(); +} + +int rsa_marshal_pss_params(CBB *cbb, rsa_pss_params_t params) { + bssl::Span bytes; + switch (params) { + case rsa_pss_sha256: + bytes = kPSSParamsSHA256; + break; + case rsa_pss_sha384: + bytes = kPSSParamsSHA384; + break; + case rsa_pss_sha512: + bytes = kPSSParamsSHA512; + break; + } + + return CBB_add_bytes(cbb, bytes.data(), bytes.size()); +} + +// 1.2.840.113549.1.1.8 +static const uint8_t kMGF1OID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x08}; + +int rsa_parse_pss_params(CBS *cbs, rsa_pss_params_t *out, + int allow_explicit_trailer) { + // See RFC 4055, section 3.1. + // + // hashAlgorithm, maskGenAlgorithm, and saltLength all have DEFAULTs + // corresponding to SHA-1. We do not support SHA-1 with PSS, so we do not + // bother recognizing the omitted versions. + CBS params, hash_wrapper, mask_wrapper, mask_alg, mask_oid, salt_wrapper; + uint64_t salt_len; + if (!CBS_get_asn1(cbs, ¶ms, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(¶ms, &hash_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // |hash_wrapper| will be parsed below. + !CBS_get_asn1(¶ms, &mask_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1) || + !CBS_get_asn1(&mask_wrapper, &mask_alg, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&mask_alg, &mask_oid, CBS_ASN1_OBJECT) || + // We only support MGF-1. + bssl::Span(mask_oid) != kMGF1OID || + // The remainder of |mask_alg| will be parsed below. + CBS_len(&mask_wrapper) != 0 || + !CBS_get_asn1(¶ms, &salt_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2) || + !CBS_get_asn1_uint64(&salt_wrapper, &salt_len) || + CBS_len(&salt_wrapper) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // The trailer field must be 1 (0xbc). This value is DEFAULT, so the structure + // is required to omit it in DER. + if (CBS_len(¶ms) != 0 && allow_explicit_trailer) { + CBS trailer_wrapper; + uint64_t trailer; + if (!CBS_get_asn1(¶ms, &trailer_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) || + !CBS_get_asn1_uint64(&trailer_wrapper, &trailer) || // + trailer != 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + } + if (CBS_len(¶ms) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + int hash_nid = EVP_parse_digest_algorithm_nid(&hash_wrapper); + if (hash_nid == NID_undef || CBS_len(&hash_wrapper) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // We only support combinations where the MGF-1 hash matches the overall hash. + int mgf1_hash_nid = EVP_parse_digest_algorithm_nid(&mask_alg); + if (mgf1_hash_nid != hash_nid || CBS_len(&mask_alg) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // We only support salt lengths that match the hash length. + rsa_pss_params_t ret; + uint64_t hash_len; + switch (hash_nid) { + case NID_sha256: + ret = rsa_pss_sha256; + hash_len = 32; + break; + case NID_sha384: + ret = rsa_pss_sha384; + hash_len = 48; + break; + case NID_sha512: + ret = rsa_pss_sha512; + hash_len = 64; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + if (salt_len != hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + *out = ret; + return 1; +} diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc index f7f9bbbb7..64009a333 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc +++ b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc @@ -17,3 +17,14 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { return 1; } void RSA_blinding_off(RSA *rsa) {} + +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { + // We do not currently implement this function. By default, we will not parse + // |EVP_PKEY_RSA_PSS|. Callers that opt in with a BoringSSL-specific API are + // currently assumed to not need this function. Callers that need that opt-in + // and this functionality should contact the BoringSSL team. + // + // If we do add support later, the |maskHash| field should be filled in for + // OpenSSL compatibility. + return nullptr; +} diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc b/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc index 7d2f14629..85ecd0e99 100644 --- a/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc +++ b/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc b/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc index cd138db20..58702fc68 100644 --- a/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc +++ b/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include diff --git a/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h b/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h index 3d462cffc..69cf97ba6 100644 --- a/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h @@ -19,7 +19,7 @@ #include -#include +#include #include #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc b/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc index 83e31b272..def70f5cf 100644 --- a/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc +++ b/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc index 47328b602..ff0fcf2a9 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "../ec/internal.h" #include "../fipsmodule/bn/internal.h" @@ -196,13 +196,13 @@ static int pmbtoken_compute_keys(const PMBTOKEN_METHOD *method, const EC_SCALAR *scalars[] = {x0, y0, x1, y1, xs, ys}; size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + for (const EC_SCALAR *scalar : scalars) { uint8_t *buf; if (!CBB_add_space(out_private, &buf, scalar_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); return 0; } - ec_scalar_to_bytes(group, buf, &scalar_len, scalars[i]); + ec_scalar_to_bytes(group, buf, &scalar_len, scalar); } EC_AFFINE pub_affine[3]; @@ -287,10 +287,9 @@ static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); EC_SCALAR *scalars[] = {&key->x0, &key->y0, &key->x1, &key->y1, &key->xs, &key->ys}; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + for (EC_SCALAR *scalar : scalars) { if (!CBS_get_bytes(&cbs, &tmp, scalar_len) || - !ec_scalar_from_bytes(group, scalars[i], CBS_data(&tmp), - CBS_len(&tmp))) { + !ec_scalar_from_bytes(group, scalar, CBS_data(&tmp), CBS_len(&tmp))) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc index 3d2ef5219..b4cd9a165 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc @@ -12,12 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#include + #include #include #include #include -#include -#include +#include #include "internal.h" @@ -226,7 +229,7 @@ void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) { int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, const uint8_t *key, size_t key_len) { - if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + if (ctx->num_keys == std::size(ctx->keys) || ctx->num_keys >= ctx->method->max_keys) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); return 0; @@ -462,7 +465,7 @@ void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) { int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key, size_t key_len) { - if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + if (ctx->num_keys == std::size(ctx->keys) || ctx->num_keys >= ctx->method->max_keys) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); return 0; diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc index 7e68d9e71..c91e390b4 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "../ec/internal.h" #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc b/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc index 9004fb431..55c8d790a 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc @@ -18,12 +18,16 @@ #include #include #include +#include #include #include +#include "../internal.h" +#include "../mem_internal.h" #include "internal.h" + int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type) { @@ -41,55 +45,56 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) { - int ret = 0; - uint8_t *in = NULL, *out = NULL; - - { - if (signature->type != V_ASN1_BIT_STRING) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); - goto err; - } + // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some + // callers rely on this to avoid memory leaks. + bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); }; - // Write out the requested copies of the AlgorithmIdentifier. - if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { - goto err; - } - if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { - goto err; - } + // Write out the requested copies of the AlgorithmIdentifier. This may modify + // |asn|, so we must do it first. + if ((algor1 != nullptr && !x509_digest_sign_algorithm(ctx, algor1)) || + (algor2 != nullptr && !x509_digest_sign_algorithm(ctx, algor2))) { + return 0; + } - int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); - if (in_len < 0) { - goto err; - } + uint8_t *in = nullptr; + int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); + if (in_len < 0) { + return 0; + } + bssl::UniquePtr free_in(in); - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); - size_t out_len = EVP_PKEY_size(pkey); - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); - goto err; - } + return x509_sign_to_bit_string(ctx, signature, bssl::Span(in, in_len)); +} - out = reinterpret_cast(OPENSSL_malloc(out_len)); - if (out == NULL) { - goto err; - } +int x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out, + bssl::Span in) { + if (out->type != V_ASN1_BIT_STRING) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } - if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) { - OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; - } + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + size_t sig_len = EVP_PKEY_size(pkey); + if (sig_len > INT_MAX) { + // Ensure the signature will fit in |out|. + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return 0; + } + bssl::Array sig; + if (!sig.Init(sig_len)) { + return 0; + } - ASN1_STRING_set0(signature, out, (int)out_len); - out = NULL; - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - ret = (int)out_len; + if (!EVP_DigestSign(ctx, sig.data(), &sig_len, in.data(), in.size())) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + return 0; } + sig.Shrink(sig_len); -err: - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(in); - OPENSSL_free(out); - return ret; + uint8_t *sig_data; + sig.Release(&sig_data, &sig_len); + ASN1_STRING_set0(out, sig_data, static_cast(sig_len)); + out->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + out->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return static_cast(sig_len); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc b/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc index 0e15194b8..5b5f881d3 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc @@ -17,18 +17,21 @@ #include #include +#include #include #include #include #include #include #include +#include #include "internal.h" -int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, - const ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey) { + +int x509_verify_signature(const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, + bssl::Span in, EVP_PKEY *pkey) { if (!pkey) { OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -41,34 +44,29 @@ int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, return 0; } } else { - sig_len = (size_t)ASN1_STRING_length(signature); - } - - EVP_MD_CTX ctx; - uint8_t *buf_in = NULL; - int ret = 0, inl = 0; - EVP_MD_CTX_init(&ctx); - - if (!x509_digest_verify_init(&ctx, a, pkey)) { - goto err; + sig_len = static_cast(ASN1_STRING_length(signature)); } - inl = ASN1_item_i2d(reinterpret_cast(asn), &buf_in, it); - - if (buf_in == NULL) { - goto err; + bssl::ScopedEVP_MD_CTX ctx; + if (!x509_digest_verify_init(ctx.get(), sigalg, pkey)) { + return 0; } - - if (!EVP_DigestVerify(&ctx, ASN1_STRING_get0_data(signature), sig_len, buf_in, - inl)) { + if (!EVP_DigestVerify(ctx.get(), ASN1_STRING_get0_data(signature), sig_len, + in.data(), in.size())) { OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; + return 0; } + return 1; +} - ret = 1; - -err: - OPENSSL_free(buf_in); - EVP_MD_CTX_cleanup(&ctx); - return ret; +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey) { + uint8_t *in = nullptr; + int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); + if (in_len < 0) { + return 0; + } + bssl::UniquePtr free_in(in); + return x509_verify_signature(sigalg, signature, bssl::Span(in, in_len), pkey); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc b/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc index ff68574ab..602d1b675 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc @@ -22,6 +22,12 @@ #include "internal.h" + +// TODO(crbug.com/42290422): Rewrite this logic to recognize signature +// algorithms without pulling in the OID table. We can enumerate every supported +// signature algorithm into a small enum and convert them to/from |EVP_PKEY_CTX| +// and |X509_ALGOR|. + // Restrict the digests that are allowed in X509 certificates static int x509_digest_nid_ok(const int digest_nid) { switch (digest_nid) { @@ -39,7 +45,8 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return 0; } - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA || + EVP_PKEY_id(pkey) == EVP_PKEY_RSA_PSS) { int pad_mode; if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { return 0; @@ -88,7 +95,10 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, } // Check the public key OID matches the public key type. - if (pkey_nid != EVP_PKEY_id(pkey)) { + const bool pkey_matches = + pkey_nid == EVP_PKEY_id(pkey) || + (sigalg_nid == NID_rsassaPss && EVP_PKEY_id(pkey) == EVP_PKEY_RSA_PSS); + if (!pkey_matches) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc b/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc index 8375f27cc..edec46633 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc @@ -299,9 +299,9 @@ static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, {"SET", CBS_ASN1_SET}, }; CBS_ASN1_TAG type = 0; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTypes); i++) { - if (cbs_str_equal(&name, kTypes[i].name)) { - type = kTypes[i].type; + for (const auto &t : kTypes) { + if (cbs_str_equal(&name, t.name)) { + type = t.type; break; } } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc b/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc index 491d60b4e..3916fa568 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc @@ -70,9 +70,9 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) { for (;;) { x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, + PEM_R_NO_START_LINE) && + count > 0) { ERR_clear_error(); break; } @@ -131,9 +131,9 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { for (;;) { x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, + PEM_R_NO_START_LINE) && + count > 0) { ERR_clear_error(); break; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/internal.h b/Sources/CCryptoBoringSSL/crypto/x509/internal.h index 955143afb..a4f3be1ee 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/x509/internal.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "../asn1/internal.h" @@ -29,21 +30,24 @@ extern "C" { // Internal structures. -typedef struct X509_val_st { - ASN1_TIME *notBefore; - ASN1_TIME *notAfter; -} X509_VAL; - -DECLARE_ASN1_FUNCTIONS_const(X509_VAL) - struct X509_pubkey_st { - X509_ALGOR *algor; - ASN1_BIT_STRING *public_key; + X509_ALGOR algor; + ASN1_BIT_STRING public_key; EVP_PKEY *pkey; } /* X509_PUBKEY */; +void x509_pubkey_init(X509_PUBKEY *key); +void x509_pubkey_cleanup(X509_PUBKEY *key); + +int x509_parse_public_key(CBS *cbs, X509_PUBKEY *out, + bssl::Span algs); +int x509_marshal_public_key(CBB *cbb, const X509_PUBKEY *in); +int x509_pubkey_set1(X509_PUBKEY *key, EVP_PKEY *pkey); + // X509_PUBKEY is an |ASN1_ITEM| whose ASN.1 type is SubjectPublicKeyInfo and C // type is |X509_PUBKEY*|. +// TODO(crbug.com/42290417): Remove this when |X509| and |X509_REQ| no longer +// depend on the tables. DECLARE_ASN1_ITEM(X509_PUBKEY) struct X509_name_entry_st { @@ -97,28 +101,31 @@ DECLARE_ASN1_ITEM(X509_EXTENSION) // (RFC 5280) and C type is |STACK_OF(X509_EXTENSION)*|. DECLARE_ASN1_ITEM(X509_EXTENSIONS) -typedef struct { - ASN1_INTEGER *version; // [ 0 ] default of v1 - ASN1_INTEGER *serialNumber; - X509_ALGOR *signature; +struct x509_st { + // TBSCertificate fields: + uint8_t version; // One of the |X509_VERSION_*| constants. + ASN1_INTEGER serialNumber; + X509_ALGOR tbs_sig_alg; + // TODO(crbug.com/42290417): When |X509_NAME| no longer uses the macro system, + // try to embed this struct. X509_NAME *issuer; - X509_VAL *validity; + ASN1_TIME notBefore; + ASN1_TIME notAfter; + // TODO(crbug.com/42290417): When |X509_NAME| no longer uses the macro system, + // try to embed this struct. X509_NAME *subject; - X509_PUBKEY *key; + X509_PUBKEY key; ASN1_BIT_STRING *issuerUID; // [ 1 ] optional in v2 ASN1_BIT_STRING *subjectUID; // [ 2 ] optional in v2 STACK_OF(X509_EXTENSION) *extensions; // [ 3 ] optional in v3 - ASN1_ENCODING enc; -} X509_CINF; - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(X509_CINF) - -struct x509_st { - X509_CINF *cert_info; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; + // Certificate fields: + X509_ALGOR sig_alg; + ASN1_BIT_STRING signature; + // Other state: + // buf, if not nullptr, contains a copy of the serialized Certificate. + // TODO(davidben): Now every parsed |X509| has an underlying |CRYPTO_BUFFER|, + // but |X509|s created peacemeal do not. Can we make this more uniform? + CRYPTO_BUFFER *buf; CRYPTO_refcount_t references; CRYPTO_EX_DATA ex_data; // These contain copies of various extension values @@ -136,6 +143,8 @@ struct x509_st { CRYPTO_MUTEX lock; } /* X509 */; +int x509_marshal_tbs_cert(CBB *cbb, X509 *x509); + // X509 is an |ASN1_ITEM| whose ASN.1 type is X.509 Certificate (RFC 5280) and C // type is |X509*|. DECLARE_ASN1_ITEM(X509) @@ -385,6 +394,17 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); +// x509_verify_signature verifies a |signature| using |sigalg| and |pkey| over +// |in|. It returns one if the signature is valid and zero on error. +int x509_verify_signature(const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, + bssl::Span in, EVP_PKEY *pkey); + +// x509_sign_to_bit_string signs |in| using |ctx| and saves the result in |out|. +// It returns the length of the signature on success and zero on error. +int x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out, + bssl::Span in); + // Path-building functions. @@ -555,6 +575,13 @@ int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); // mutated. int x509_marshal_name(CBB *out, X509_NAME *in); +void x509_algor_init(X509_ALGOR *alg); +void x509_algor_cleanup(X509_ALGOR *alg); + +// x509_parse_algorithm parses a DER-encoded, AlgorithmIdentifier from |cbs| and +// writes the result to |*out|. It returns one on success and zero on error. +int x509_parse_algorithm(CBS *cbs, X509_ALGOR *out); + // x509_marshal_algorithm marshals |in| as a DER-encoded, AlgorithmIdentifier // and writes the result to |out|. It returns one on success and zero on error. int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in); diff --git a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc index 663476480..395e210d3 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc @@ -19,11 +19,14 @@ #include #include +#include #include #include #include #include +#include +#include "../rsa/internal.h" #include "internal.h" @@ -46,111 +49,18 @@ ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { IMPLEMENT_ASN1_FUNCTIONS_const(RSA_PSS_PARAMS) -// Given an MGF1 Algorithm ID decode to an Algorithm Identifier -static X509_ALGOR *rsa_mgf1_decode(const X509_ALGOR *alg) { - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || alg->parameter == NULL || - alg->parameter->type != V_ASN1_SEQUENCE) { - return NULL; - } - - const uint8_t *p = alg->parameter->value.sequence->data; - int plen = alg->parameter->value.sequence->length; - return d2i_X509_ALGOR(NULL, &p, plen); -} - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) { - if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { - return NULL; - } - - const uint8_t *p = alg->parameter->value.sequence->data; - int plen = alg->parameter->value.sequence->length; - return d2i_RSA_PSS_PARAMS(NULL, &p, plen); -} - -static int is_allowed_pss_md(const EVP_MD *md) { - int md_type = EVP_MD_type(md); - return md_type == NID_sha256 || md_type == NID_sha384 || - md_type == NID_sha512; -} - -// rsa_md_to_algor sets |*palg| to an |X509_ALGOR| describing the digest |md|, -// which must be an allowed PSS digest. -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) { - // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. - assert(is_allowed_pss_md(md)); - *palg = X509_ALGOR_new(); - if (*palg == NULL) { +static int rsa_pss_decode(const X509_ALGOR *alg, rsa_pss_params_t *out) { + if (alg->parameter == nullptr || alg->parameter->type != V_ASN1_SEQUENCE) { return 0; } - if (!X509_ALGOR_set_md(*palg, md)) { - X509_ALGOR_free(*palg); - *palg = NULL; - return 0; - } - return 1; -} - -// rsa_md_to_mgf1 sets |*palg| to an |X509_ALGOR| describing MGF-1 with the -// digest |mgf1md|, which must be an allowed PSS digest. -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { - // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. - assert(is_allowed_pss_md(mgf1md)); - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - // need to embed algorithm ID inside another - if (!rsa_md_to_algor(&algtmp, mgf1md) || - !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) { - goto err; - } - *palg = X509_ALGOR_new(); - if (!*palg) { - goto err; - } - if (!X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp)) { - goto err; - } - stmp = NULL; - -err: - ASN1_STRING_free(stmp); - X509_ALGOR_free(algtmp); - if (*palg) { - return 1; - } - return 0; -} - -static const EVP_MD *rsa_algor_to_md(const X509_ALGOR *alg) { - if (!alg) { - // If omitted, PSS defaults to SHA-1, which we do not allow. - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - const EVP_MD *md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL || !is_allowed_pss_md(md)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - return md; -} - -static const EVP_MD *rsa_mgf1_to_md(const X509_ALGOR *alg) { - if (!alg) { - // If omitted, PSS defaults to MGF-1 with SHA-1, which we do not allow. - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - // Check mask and lookup mask hash algorithm. - X509_ALGOR *maskHash = rsa_mgf1_decode(alg); - if (maskHash == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - const EVP_MD *ret = rsa_algor_to_md(maskHash); - X509_ALGOR_free(maskHash); - return ret; + // Although a syntax error in DER, we tolerate an explicitly-encoded trailer. + // See the certificates in cl/362617931. + CBS cbs; + CBS_init(&cbs, alg->parameter->value.sequence->data, + alg->parameter->value.sequence->length); + return rsa_parse_pss_params(&cbs, out, /*allow_explicit_trailer=*/true) && + CBS_len(&cbs) == 0; } int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { @@ -162,203 +72,111 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return 0; } - if (sigmd != mgf1md || !is_allowed_pss_md(sigmd)) { + if (sigmd != mgf1md) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } int md_len = (int)EVP_MD_size(sigmd); - if (saltlen == -1) { - saltlen = md_len; - } else if (saltlen != md_len) { + if (saltlen != RSA_PSS_SALTLEN_DIGEST && saltlen != md_len) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } - int ret = 0; - ASN1_STRING *os = NULL; - RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); - if (!pss) { - goto err; - } - - // The DEFAULT value is 20, but this does not match any supported digest. - assert(saltlen != 20); - pss->saltLength = ASN1_INTEGER_new(); - if (!pss->saltLength || // - !ASN1_INTEGER_set_int64(pss->saltLength, saltlen)) { - goto err; + rsa_pss_params_t params; + switch (EVP_MD_type(sigmd)) { + case NID_sha256: + params = rsa_pss_sha256; + break; + case NID_sha384: + params = rsa_pss_sha384; + break; + case NID_sha512: + params = rsa_pss_sha512; + break; + default: + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || - !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { - goto err; + // Encode |params| to an |ASN1_STRING|. + uint8_t buf[128]; // The largest param fits comfortably in 128 bytes. + CBB cbb; + CBB_init_fixed(&cbb, buf, sizeof(buf)); + if (!rsa_marshal_pss_params(&cbb, params)) { + return 0; } - - // Finally create string with pss parameter encoding. - if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { - goto err; + bssl::UniquePtr params_str( + ASN1_STRING_type_new(V_ASN1_SEQUENCE)); + if (params_str == nullptr || + !ASN1_STRING_set(params_str.get(), CBB_data(&cbb), CBB_len(&cbb))) { + return 0; } if (!X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, - os)) { - goto err; + params_str.get())) { + return 0; } - os = NULL; - ret = 1; - -err: - RSA_PSS_PARAMS_free(pss); - ASN1_STRING_free(os); - return ret; + params_str.release(); // |X509_ALGOR_set0| took ownership. + return 1; } int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + rsa_pss_params_t params; + if (!rsa_pss_decode(sigalg, ¶ms)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; + } - // Decode PSS parameters - int ret = 0; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); - - { - if (pss == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm); - const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); - if (mgf1md == NULL || md == NULL) { - goto err; - } - - // We require the MGF-1 and signing hashes to match. - if (mgf1md != md) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - // We require the salt length be the hash length. The DEFAULT value is 20, - // but this does not match any supported salt length. - uint64_t salt_len = 0; - if (pss->saltLength == NULL || - !ASN1_INTEGER_get_uint64(&salt_len, pss->saltLength) || - salt_len != EVP_MD_size(md)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - assert(salt_len <= INT_MAX); - - // The trailer field must be 1 (0xbc). This value is DEFAULT, so the - // structure is required to omit it in DER. Although a syntax error, we also - // tolerate an explicitly-encoded value. See the certificates in - // cl/362617931. - if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - EVP_PKEY_CTX *pctx; - if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || - !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || - !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, (int)salt_len) || - !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { - goto err; - } - - ret = 1; + const EVP_MD *md = rsa_pss_params_get_md(params); + EVP_PKEY_CTX *pctx; + if (!EVP_DigestVerifyInit(ctx, &pctx, md, nullptr, pkey) || + !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, md)) { + return 0; } -err: - RSA_PSS_PARAMS_free(pss); - return ret; + return 1; } int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, ASN1_PCTX *pctx) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); - - int rv = 0; - X509_ALGOR *maskHash = NULL; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); - if (!pss) { - if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { - goto err; - } - rv = 1; - goto err; + rsa_pss_params_t params; + if (!rsa_pss_decode(sigalg, ¶ms)) { + return BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0; + } + + const char *hash_str = nullptr; + uint32_t salt_len = 0; + switch (params) { + case rsa_pss_sha256: + hash_str = "sha256"; + salt_len = 32; + break; + case rsa_pss_sha384: + hash_str = "sha384"; + salt_len = 48; + break; + case rsa_pss_sha512: + hash_str = "sha512"; + salt_len = 64; + break; } if (BIO_puts(bp, "\n") <= 0 || // !BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Hash Algorithm: ") <= 0) { - goto err; - } - - if (pss->hashAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "sha1 (default)") <= 0) { - goto err; - } - - if (BIO_puts(bp, "\n") <= 0 || // + BIO_printf(bp, "Hash Algorithm: %s\n", hash_str) <= 0 || !BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Mask Algorithm: ") <= 0) { - goto err; - } - - if (pss->maskGenAlgorithm) { - maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - if (maskHash == NULL) { - if (BIO_puts(bp, "INVALID") <= 0) { - goto err; - } - } else { - if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || - BIO_puts(bp, " with ") <= 0 || - i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { - goto err; - } - } - } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Salt Length: 0x") <= 0) { - goto err; - } - - if (pss->saltLength) { - if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "14 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Trailer Field: 0x") <= 0) { - goto err; - } - - if (pss->trailerField) { - if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "BC (default)") <= 0) { - goto err; + BIO_printf(bp, "Mask Algorithm: mgf1 with %s\n", hash_str) <= 0 || + !BIO_indent(bp, indent, 128) || // + BIO_printf(bp, "Salt Length: 0x%x\n", salt_len) <= 0 || + !BIO_indent(bp, indent, 128) || // + BIO_puts(bp, "Trailer Field: 0xBC (default)\n") <= 0) { + return 0; } - BIO_puts(bp, "\n"); - rv = 1; - -err: - RSA_PSS_PARAMS_free(pss); - X509_ALGOR_free(maskHash); - return rv; + return 1; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc b/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc index a7c62e019..8a778ba69 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc @@ -79,7 +79,7 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, if (!(cflag & X509_FLAG_NO_PUBKEY)) { if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || - i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || + i2a_ASN1_OBJECT(bio, ri->pubkey->algor.algorithm) <= 0 || BIO_puts(bio, "\n") <= 0) { goto err; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc b/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc index 6f8be6c22..97fb41435 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc @@ -60,7 +60,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, nmindent = 16; } - const X509_CINF *ci = x->cert_info; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate:\n", 13) <= 0) { return 0; @@ -108,7 +107,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_SIGNAME)) { - if (X509_signature_print(bp, ci->signature, NULL) <= 0) { + if (X509_signature_print(bp, &x->tbs_sig_alg, NULL) <= 0) { return 0; } } @@ -164,7 +163,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) { return 0; } - if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) { + if (i2a_ASN1_OBJECT(bp, x->key.algor.algorithm) <= 0) { return 0; } if (BIO_puts(bp, "\n") <= 0) { @@ -181,30 +180,30 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_IDS)) { - if (ci->issuerUID) { + if (x->issuerUID) { if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) { return 0; } - if (!X509_signature_dump(bp, ci->issuerUID, 12)) { + if (!X509_signature_dump(bp, x->issuerUID, 12)) { return 0; } } - if (ci->subjectUID) { + if (x->subjectUID) { if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) { return 0; } - if (!X509_signature_dump(bp, ci->subjectUID, 12)) { + if (!X509_signature_dump(bp, x->subjectUID, 12)) { return 0; } } } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { - X509V3_extensions_print(bp, "X509v3 extensions", ci->extensions, cflag, 8); + X509V3_extensions_print(bp, "X509v3 extensions", x->extensions, cflag, 8); } if (!(cflag & X509_FLAG_NO_SIGDUMP)) { - if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) { + if (X509_signature_print(bp, &x->sig_alg, &x->signature) <= 0) { return 0; } } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc index 80588dad7..1e8c47703 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc @@ -308,7 +308,7 @@ int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, const char *section, X509 *cert) { STACK_OF(X509_EXTENSION) **sk = NULL; if (cert) { - sk = &cert->cert_info->extensions; + sk = &cert->extensions; } return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc index 4ab83a75e..fbe08767b 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc @@ -105,18 +105,18 @@ int X509_check_purpose(X509 *x, int id, int ca) { } const X509_PURPOSE *X509_PURPOSE_get0(int id) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { - if (xstandard[i].purpose == id) { - return &xstandard[i]; + for (const auto &p : xstandard) { + if (p.purpose == id) { + return &p; } } return NULL; } int X509_PURPOSE_get_by_sname(const char *sname) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { - if (strcmp(xstandard[i].sname, sname) == 0) { - return xstandard[i].purpose; + for (const auto &p : xstandard) { + if (strcmp(p.sname, sname) == 0) { + return p.purpose; } } return -1; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc index 3dd128908..704c0613f 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc @@ -65,7 +65,7 @@ static char *i2s_ASN1_OCTET_STRING_cb(const X509V3_EXT_METHOD *method, static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str) { ASN1_OCTET_STRING *oct; - ASN1_BIT_STRING *pk; + const ASN1_BIT_STRING *pk; unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; @@ -87,14 +87,9 @@ static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, } if (ctx->subject_req) { - pk = ctx->subject_req->req_info->pubkey->public_key; + pk = &ctx->subject_req->req_info->pubkey->public_key; } else { - pk = ctx->subject_cert->cert_info->key->public_key; - } - - if (!pk) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; + pk = &ctx->subject_cert->key.public_key; } if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc index a857d0f7e..fcfdf81fa 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc @@ -29,15 +29,15 @@ int X509_issuer_name_cmp(const X509 *a, const X509 *b) { - return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); + return X509_NAME_cmp(a->issuer, b->issuer); } int X509_subject_name_cmp(const X509 *a, const X509 *b) { - return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); + return X509_NAME_cmp(a->subject, b->subject); } int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) { - return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); + return X509_NAME_cmp(a->crl->issuer, b->crl->issuer); } int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { @@ -45,35 +45,31 @@ int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { } X509_NAME *X509_get_issuer_name(const X509 *a) { - return a->cert_info->issuer; + // This function is not const-correct for OpenSSL compatibility. + return a->issuer; } -uint32_t X509_issuer_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info->issuer); -} +uint32_t X509_issuer_name_hash(X509 *x) { return X509_NAME_hash(x->issuer); } uint32_t X509_issuer_name_hash_old(X509 *x) { - return (X509_NAME_hash_old(x->cert_info->issuer)); + return X509_NAME_hash_old(x->issuer); } X509_NAME *X509_get_subject_name(const X509 *a) { - return a->cert_info->subject; + // This function is not const-correct for OpenSSL compatibility. + return a->subject; } -ASN1_INTEGER *X509_get_serialNumber(X509 *a) { - return a->cert_info->serialNumber; -} +ASN1_INTEGER *X509_get_serialNumber(X509 *a) { return &a->serialNumber; } const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) { - return x509->cert_info->serialNumber; + return &x509->serialNumber; } -uint32_t X509_subject_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info->subject); -} +uint32_t X509_subject_name_hash(X509 *x) { return X509_NAME_hash(x->subject); } uint32_t X509_subject_name_hash_old(X509 *x) { - return X509_NAME_hash_old(x->cert_info->subject); + return X509_NAME_hash_old(x->subject); } // Compare two certificates: they must be identical for this to work. NB: @@ -180,21 +176,22 @@ EVP_PKEY *X509_get0_pubkey(const X509 *x) { if (x == NULL) { return NULL; } - return X509_PUBKEY_get0(x->cert_info->key); + return X509_PUBKEY_get0(&x->key); } EVP_PKEY *X509_get_pubkey(const X509 *x) { if (x == NULL) { return NULL; } - return X509_PUBKEY_get(x->cert_info->key); + return X509_PUBKEY_get(&x->key); } ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) { if (!x) { return NULL; } - return x->cert_info->key->public_key; + // This function is not const-correct for OpenSSL compatibility. + return const_cast(&x->key.public_key); } int X509_check_private_key(const X509 *x, const EVP_PKEY *k) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc index 76f8591ce..8de88f08c 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc @@ -21,28 +21,38 @@ #include "internal.h" int X509_CRL_get_ext_count(const X509_CRL *x) { - return (X509v3_get_ext_count(x->crl->extensions)); + return X509v3_get_ext_count(x->crl->extensions); } int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos); } int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos); } int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos); } X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) { - return (X509v3_get_ext(x->crl->extensions, loc)); + return X509v3_get_ext(x->crl->extensions, loc); +} + +static X509_EXTENSION *delete_ext(STACK_OF(X509_EXTENSION) **exts, int loc) { + X509_EXTENSION *ext = X509v3_delete_ext(*exts, loc); + // Empty extension lists are omitted. + if (*exts != nullptr && sk_X509_EXTENSION_num(*exts) == 0) { + sk_X509_EXTENSION_pop_free(*exts, X509_EXTENSION_free); + *exts = nullptr; + } + return ext; } X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) { - return (X509v3_delete_ext(x->crl->extensions, loc)); + return delete_ext(&x->crl->extensions, loc); } void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, int *out_critical, @@ -56,76 +66,75 @@ int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, } int X509_CRL_add_ext(X509_CRL *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->crl->extensions, ex, loc) != NULL; } int X509_get_ext_count(const X509 *x) { - return (X509v3_get_ext_count(x->cert_info->extensions)); + return X509v3_get_ext_count(x->extensions); } int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->extensions, nid, lastpos); } int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos); } int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->extensions, crit, lastpos); } X509_EXTENSION *X509_get_ext(const X509 *x, int loc) { - return (X509v3_get_ext(x->cert_info->extensions, loc)); + return X509v3_get_ext(x->extensions, loc); } X509_EXTENSION *X509_delete_ext(X509 *x, int loc) { - return (X509v3_delete_ext(x->cert_info->extensions, loc)); + return delete_ext(&x->extensions, loc); } int X509_add_ext(X509 *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->extensions, ex, loc) != NULL; } void *X509_get_ext_d2i(const X509 *x509, int nid, int *out_critical, int *out_idx) { - return X509V3_get_d2i(x509->cert_info->extensions, nid, out_critical, - out_idx); + return X509V3_get_d2i(x509->extensions, nid, out_critical, out_idx); } int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags) { - return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, flags); + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); } int X509_REVOKED_get_ext_count(const X509_REVOKED *x) { - return (X509v3_get_ext_count(x->extensions)); + return X509v3_get_ext_count(x->extensions); } int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->extensions, nid, lastpos); } int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos); } int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->extensions, crit, lastpos); } X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) { - return (X509v3_get_ext(x->extensions, loc)); + return X509v3_get_ext(x->extensions, loc); } X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) { - return (X509v3_delete_ext(x->extensions, loc)); + return delete_ext(&x->extensions, loc); } int X509_REVOKED_add_ext(X509_REVOKED *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->extensions, ex, loc) != NULL; } void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, int nid, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc index d8761324a..6a9173b1b 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc @@ -287,7 +287,6 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name, int *pnmatch) { X509_OBJECT stmp; X509 x509_s; - X509_CINF cinf_s; X509_CRL crl_s; X509_CRL_INFO crl_info_s; @@ -295,8 +294,7 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, switch (type) { case X509_LU_X509: stmp.data.x509 = &x509_s; - x509_s.cert_info = &cinf_s; - cinf_s.subject = name; + x509_s.subject = name; break; case X509_LU_CRL: stmp.data.crl = &crl_s; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc index eb35621fd..22679acf0 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc @@ -21,13 +21,7 @@ #include "internal.h" -long X509_get_version(const X509 *x509) { - // The default version is v1(0). - if (x509->cert_info->version == NULL) { - return X509_VERSION_1; - } - return ASN1_INTEGER_get(x509->cert_info->version); -} +long X509_get_version(const X509 *x509) { return x509->version; } int X509_set_version(X509 *x, long version) { if (x == NULL) { @@ -39,20 +33,8 @@ int X509_set_version(X509 *x, long version) { return 0; } - // v1(0) is default and is represented by omitting the version. - if (version == X509_VERSION_1) { - ASN1_INTEGER_free(x->cert_info->version); - x->cert_info->version = NULL; - return 1; - } - - if (x->cert_info->version == NULL) { - x->cert_info->version = ASN1_INTEGER_new(); - if (x->cert_info->version == NULL) { - return 0; - } - } - return ASN1_INTEGER_set_int64(x->cert_info->version, version); + x->version = static_cast(version); + return 1; } int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) { @@ -61,138 +43,99 @@ int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) { return 0; } - ASN1_INTEGER *in; - if (x == NULL) { - return 0; - } - in = x->cert_info->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - ASN1_INTEGER_free(x->cert_info->serialNumber); - x->cert_info->serialNumber = in; - } - } - return in != NULL; + return ASN1_STRING_copy(&x->serialNumber, serial); } int X509_set_issuer_name(X509 *x, X509_NAME *name) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == NULL) { return 0; } - return (X509_NAME_set(&x->cert_info->issuer, name)); + return (X509_NAME_set(&x->issuer, name)); } int X509_set_subject_name(X509 *x, X509_NAME *name) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == NULL) { return 0; } - return (X509_NAME_set(&x->cert_info->subject, name)); + return (X509_NAME_set(&x->subject, name)); } int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) { - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) { - return 0; - } - in = x->cert_info->validity->notBefore; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notBefore); - x->cert_info->validity->notBefore = in; - } - } - return in != NULL; + // TODO(crbug.com/42290309): Check that |tm->type| is correct. + return ASN1_STRING_copy(&x->notBefore, tm); } int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) { return X509_set1_notBefore(x, tm); } -const ASN1_TIME *X509_get0_notBefore(const X509 *x) { - return x->cert_info->validity->notBefore; -} +const ASN1_TIME *X509_get0_notBefore(const X509 *x) { return &x->notBefore; } ASN1_TIME *X509_getm_notBefore(X509 *x) { // Note this function takes a const |X509| pointer in OpenSSL. We require // non-const as this allows mutating |x|. If it comes up for compatibility, // we can relax this. - return x->cert_info->validity->notBefore; + return &x->notBefore; } ASN1_TIME *X509_get_notBefore(const X509 *x509) { // In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our // |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notBefore; + return const_cast(&x509->notBefore); } int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) { - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) { - return 0; - } - in = x->cert_info->validity->notAfter; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notAfter); - x->cert_info->validity->notAfter = in; - } - } - return in != NULL; + // TODO(crbug.com/42290309): Check that |tm->type| is correct. + return ASN1_STRING_copy(&x->notAfter, tm); } int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) { return X509_set1_notAfter(x, tm); } -const ASN1_TIME *X509_get0_notAfter(const X509 *x) { - return x->cert_info->validity->notAfter; -} +const ASN1_TIME *X509_get0_notAfter(const X509 *x) { return &x->notAfter; } ASN1_TIME *X509_getm_notAfter(X509 *x) { // Note this function takes a const |X509| pointer in OpenSSL. We require // non-const as this allows mutating |x|. If it comes up for compatibility, // we can relax this. - return x->cert_info->validity->notAfter; + return &x->notAfter; } ASN1_TIME *X509_get_notAfter(const X509 *x509) { // In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our // |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notAfter; -} + return const_cast(&x509->notAfter); + } void X509_get0_uids(const X509 *x509, const ASN1_BIT_STRING **out_issuer_uid, const ASN1_BIT_STRING **out_subject_uid) { if (out_issuer_uid != NULL) { - *out_issuer_uid = x509->cert_info->issuerUID; + *out_issuer_uid = x509->issuerUID; } if (out_subject_uid != NULL) { - *out_subject_uid = x509->cert_info->subjectUID; + *out_subject_uid = x509->subjectUID; } } int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == nullptr) { return 0; } - return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); + return x509_pubkey_set1(&x->key, pkey); } const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) { - return x->cert_info->extensions; + return x->extensions; } const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) { - return x->cert_info->signature; + return &x->tbs_sig_alg; } X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) { - return x509->cert_info->key; + // This function is not const-correct for OpenSSL compatibility. + return const_cast(&x509->key); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc index 0539d14db..3ac5b692d 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc @@ -43,9 +43,9 @@ static const X509_TRUST trstandard[] = { {X509_TRUST_TSA, trust_1oidany, NID_time_stamp}}; static const X509_TRUST *X509_TRUST_get0(int id) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(trstandard); i++) { - if (trstandard[i].trust == id) { - return &trstandard[i]; + for (const auto &t : trstandard) { + if (t.trust == id) { + return &t; } } return NULL; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc index 509705f18..7a3a5f1bb 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc @@ -209,19 +209,8 @@ int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) { } int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo) { - X509_ALGOR *copy1 = X509_ALGOR_dup(algo); - X509_ALGOR *copy2 = X509_ALGOR_dup(algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } - - X509_ALGOR_free(crl->sig_alg); - crl->sig_alg = copy1; - X509_ALGOR_free(crl->crl->sig_alg); - crl->crl->sig_alg = copy2; - return 1; + return X509_ALGOR_copy(crl->sig_alg, algo) && + X509_ALGOR_copy(crl->crl->sig_alg, algo); } int X509_CRL_set1_signature_value(X509_CRL *crl, const uint8_t *sig, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc index 49837e740..616e5ada4 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc @@ -46,14 +46,7 @@ int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) { } int X509_REQ_set1_signature_algo(X509_REQ *req, const X509_ALGOR *algo) { - X509_ALGOR *copy = X509_ALGOR_dup(algo); - if (copy == NULL) { - return 0; - } - - X509_ALGOR_free(req->sig_alg); - req->sig_alg = copy; - return 1; + return X509_ALGOR_copy(req->sig_alg, algo); } int X509_REQ_set1_signature_value(X509_REQ *req, const uint8_t *sig, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc index f4d8ec38a..0d0623c1e 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc @@ -17,19 +17,131 @@ #include #include #include +#include #include +#include #include "../asn1/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" +#include "../mem_internal.h" #include "internal.h" -ASN1_SEQUENCE(X509_ALGOR) = { - ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), - ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY), -} ASN1_SEQUENCE_END(X509_ALGOR) +void x509_algor_init(X509_ALGOR *alg) { + OPENSSL_memset(alg, 0, sizeof(X509_ALGOR)); + alg->algorithm = const_cast(OBJ_get_undef()); +} + +void x509_algor_cleanup(X509_ALGOR *alg) { + ASN1_OBJECT_free(alg->algorithm); + ASN1_TYPE_free(alg->parameter); +} + +X509_ALGOR *X509_ALGOR_new(void) { + bssl::UniquePtr ret = bssl::MakeUnique(); + if (ret == nullptr) { + return nullptr; + } + x509_algor_init(ret.get()); + return ret.release(); +} + +void X509_ALGOR_free(X509_ALGOR *alg) { + if (alg != nullptr) { + x509_algor_cleanup(alg); + OPENSSL_free(alg); + } +} + +int x509_parse_algorithm(CBS *cbs, X509_ALGOR *out) { + CBS seq; + if (!CBS_get_asn1(cbs, &seq, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } -IMPLEMENT_ASN1_FUNCTIONS_const(X509_ALGOR) -IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_ALGOR) + bssl::UniquePtr obj(asn1_parse_object(&seq, /*tag=*/0)); + if (obj == nullptr) { + return 0; + } + ASN1_OBJECT_free(out->algorithm); + out->algorithm = obj.release(); + if (CBS_len(&seq) == 0) { + ASN1_TYPE_free(out->parameter); + out->parameter = nullptr; + } else { + if (out->parameter == nullptr) { + out->parameter = ASN1_TYPE_new(); + } + if (out->parameter == nullptr || // + !asn1_parse_any(&seq, out->parameter)) { + return 0; + } + } + if (CBS_len(&seq) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return 1; +} + +int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in) { + CBB seq; + return CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) && + asn1_marshal_object(&seq, in->algorithm, /*tag=*/0) && + (in->parameter == nullptr || asn1_marshal_any(&seq, in->parameter)) && + CBB_flush(out); +} + +X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(X509_ALGOR_new()); + if (ret == nullptr || !x509_parse_algorithm(cbs, ret.get())) { + return nullptr; + } + return ret; + }); +} + +int i2d_X509_ALGOR(const X509_ALGOR *in, uint8_t **outp) { + return bssl::I2DFromCBB(/*initial_capacity=*/32, outp, [&](CBB *cbb) -> bool { + return x509_marshal_algorithm(cbb, in); + }); +} + +IMPLEMENT_EXTERN_ASN1_SIMPLE(X509_ALGOR, X509_ALGOR_new, X509_ALGOR_free, + x509_parse_algorithm, i2d_X509_ALGOR) + +X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg) { + bssl::UniquePtr copy(X509_ALGOR_new()); + if (copy == nullptr || !X509_ALGOR_copy(copy.get(), alg)) { + return nullptr; + } + return copy.release(); +} + +int X509_ALGOR_copy(X509_ALGOR *dst, const X509_ALGOR *src) { + bssl::UniquePtr algorithm(OBJ_dup(src->algorithm)); + if (algorithm == nullptr) { + return 0; + } + bssl::UniquePtr parameter; + if (src->parameter != nullptr) { + parameter.reset(ASN1_TYPE_new()); + if (parameter == nullptr || + !ASN1_TYPE_set1(parameter.get(), src->parameter->type, + asn1_type_value_as_pointer(src->parameter))) { + return 0; + } + } + ASN1_OBJECT_free(dst->algorithm); + dst->algorithm = algorithm.release(); + ASN1_TYPE_free(dst->parameter); + dst->parameter = parameter.release(); + return 1; +} int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) { if (!alg) { @@ -106,11 +218,3 @@ int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) { } return ASN1_TYPE_cmp(a->parameter, b->parameter); } - -int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in) { - uint8_t *ptr; - int len = i2d_X509_ALGOR(in, NULL); - return len > 0 && // - CBB_add_space(out, &ptr, static_cast(len)) && - i2d_X509_ALGOR(in, &ptr) == len; -} diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc index d4dd7a4a4..ee6f7ae9a 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc @@ -17,24 +17,33 @@ #include #include +#include #include #include #include #include #include +#include #include #include "../asn1/internal.h" +#include "../internal.h" #include "internal.h" int X509_verify(X509 *x509, EVP_PKEY *pkey) { - if (X509_ALGOR_cmp(x509->sig_alg, x509->cert_info->signature)) { + if (X509_ALGOR_cmp(&x509->sig_alg, &x509->tbs_sig_alg)) { OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); return 0; } - return ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), x509->sig_alg, - x509->signature, x509->cert_info, pkey); + // This uses the cached TBSCertificate encoding, if any. + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x509)) { + return 0; + } + return x509_verify_signature( + &x509->sig_alg, &x509->signature, + bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())), pkey); } int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { @@ -43,21 +52,41 @@ int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { } int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) { - asn1_encoding_clear(&x->cert_info->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, pkey, md)); + bssl::ScopedEVP_MD_CTX ctx; + if (!EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey)) { + return 0; + } + return X509_sign_ctx(x, ctx.get()); } int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) { - asn1_encoding_clear(&x->cert_info->enc); - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, ctx); + // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some + // callers rely on this to avoid memory leaks. + bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); }; + + // Fill in the two copies of AlgorithmIdentifier. Note one of these modifies + // the TBSCertificate. + if (!x509_digest_sign_algorithm(ctx, &x->tbs_sig_alg) || + !x509_digest_sign_algorithm(ctx, &x->sig_alg)) { + return 0; + } + + // Discard the cached encoding. (We just modified it.) + CRYPTO_BUFFER_free(x->buf); + x->buf = nullptr; + + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x)) { + return 0; + } + return x509_sign_to_bit_string( + ctx, &x->signature, bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get()))); } int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { asn1_encoding_clear(&x->req_info->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, - x->signature, x->req_info, pkey, md)); + 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) { @@ -68,8 +97,8 @@ int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) { asn1_encoding_clear(&x->crl->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, - x->sig_alg, x->signature, x->crl, pkey, md)); + return ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md); } int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { @@ -79,13 +108,13 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { } int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { - return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, - x->signature, x->spkac, pkey, md)); + return ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md); } int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) { - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, - spki->signature, spki->spkac, pkey)); + return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, + spki->signature, spki->spkac, pkey); } X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc index a5fae0458..5f6da5ae7 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc @@ -38,15 +38,6 @@ DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) #define X509_NAME_MAX (1024 * 1024) -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, - long len, const ASN1_ITEM *it, int opt, - ASN1_TLC *ctx); - -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it); -static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); -static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); - static int x509_name_encode(X509_NAME *a); static int x509_name_canon(X509_NAME *a); static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); @@ -77,19 +68,8 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) // representing the ASN1. Unfortunately X509_NAME uses a completely different // form and caches encodings so we have to process the internal form and // convert to the external form. - -static const ASN1_EXTERN_FUNCS x509_name_ff = { - x509_name_ex_new, - x509_name_ex_free, - x509_name_ex_d2i, - x509_name_ex_i2d, -}; - -IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) - -IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) +// +// TODO(crbug.com/42290417): Rewrite all this with |CBS| and |CBB|. static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { X509_NAME *ret = NULL; @@ -143,29 +123,37 @@ static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) { sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); } -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, - long len, const ASN1_ITEM *it, int opt, - ASN1_TLC *ctx) { - const unsigned char *p = *in, *q; +static int x509_name_ex_parse(ASN1_VALUE **val, CBS *cbs, const ASN1_ITEM *it, + int opt) { + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return 1; + } + + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE) || + // Bound the size of an X509_NAME we are willing to parse. + CBS_len(&elem) > X509_NAME_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // TODO(crbug.com/42290417): Rewrite the parser and canonicalization code with + // CBS and CBB. For now this calls into the original two-layer d2i code. + long len = static_cast(CBS_len(&elem)); + const unsigned char *p = CBS_data(&elem), *q; STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; X509_NAME *nm = NULL; size_t i, j; - int ret; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; - // Bound the size of an X509_NAME we are willing to parse. - if (len > X509_NAME_MAX) { - len = X509_NAME_MAX; - } q = p; // Get internal representation of Name ASN1_VALUE *intname_val = NULL; - ret = ASN1_item_ex_d2i(&intname_val, &p, len, - ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, - /*aclass=*/0, opt, /*buf=*/NULL); - if (ret <= 0) { - return ret; + if (ASN1_item_ex_d2i(&intname_val, &p, len, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, + /*aclass=*/0, /*opt=*/0) <= 0) { + return 0; } intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val; @@ -195,15 +183,13 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); } } - ret = x509_name_canon(nm); - if (!ret) { + if (!x509_name_canon(nm)) { goto err; } sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); nm->modified = 0; *val = (ASN1_VALUE *)nm; - *in = p; - return ret; + return 1; err: X509_NAME_free(nm); sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, @@ -226,6 +212,12 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, return ret; } +static const ASN1_EXTERN_FUNCS x509_name_ff = { + x509_name_ex_new, x509_name_ex_free, x509_name_ex_parse, x509_name_ex_i2d}; +IMPLEMENT_EXTERN_ASN1(X509_NAME, x509_name_ff) +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) + static int x509_name_encode(X509_NAME *a) { int len; unsigned char *p; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc index 07dc78157..ca19d9a32 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc @@ -23,94 +23,139 @@ #include #include #include +#include +#include "../asn1/internal.h" +#include "../bytestring/internal.h" +#include "../evp/internal.h" #include "../internal.h" +#include "../mem_internal.h" #include "internal.h" -static void x509_pubkey_changed(X509_PUBKEY *pub) { - EVP_PKEY_free(pub->pkey); - pub->pkey = NULL; - - // Re-encode the |X509_PUBKEY| to DER and parse it with EVP's APIs. - uint8_t *spki = NULL; - int spki_len = i2d_X509_PUBKEY(pub, &spki); - EVP_PKEY *pkey; - if (spki_len < 0) { - goto err; +void x509_pubkey_init(X509_PUBKEY *key) { + OPENSSL_memset(key, 0, sizeof(X509_PUBKEY)); + x509_algor_init(&key->algor); + asn1_string_init(&key->public_key, V_ASN1_BIT_STRING); +} + +X509_PUBKEY *X509_PUBKEY_new(void) { + bssl::UniquePtr ret = bssl::MakeUnique(); + if (ret == nullptr) { + return nullptr; } + x509_pubkey_init(ret.get()); + return ret.release(); +} - CBS cbs; - CBS_init(&cbs, spki, (size_t)spki_len); - pkey = EVP_parse_public_key(&cbs); - if (pkey == NULL || CBS_len(&cbs) != 0) { - EVP_PKEY_free(pkey); - goto err; +void x509_pubkey_cleanup(X509_PUBKEY *key) { + x509_algor_cleanup(&key->algor); + asn1_string_cleanup(&key->public_key); + EVP_PKEY_free(key->pkey); +} + +void X509_PUBKEY_free(X509_PUBKEY *key) { + if (key != nullptr) { + x509_pubkey_cleanup(key); + OPENSSL_free(key); } +} - pub->pkey = pkey; +static void x509_pubkey_changed(X509_PUBKEY *pub, + bssl::Span algs) { + EVP_PKEY_free(pub->pkey); + pub->pkey = nullptr; + + // Re-encode the |X509_PUBKEY| to DER and parse it with EVP's APIs. If the + // operation fails, clear errors. An |X509_PUBKEY| whose key we cannot parse + // is still a valid SPKI. It just cannot be converted to an |EVP_PKEY|. + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64) || !x509_marshal_public_key(cbb.get(), pub)) { + ERR_clear_error(); + return; + } + bssl::UniquePtr pkey(EVP_PKEY_from_subject_public_key_info( + CBB_data(cbb.get()), CBB_len(cbb.get()), algs.data(), algs.size())); + if (pkey == nullptr) { + ERR_clear_error(); + return; + } -err: - OPENSSL_free(spki); - // If the operation failed, clear errors. An |X509_PUBKEY| whose key we cannot - // parse is still a valid SPKI. It just cannot be converted to an |EVP_PKEY|. - ERR_clear_error(); + pub->pkey = pkey.release(); } -static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - if (operation == ASN1_OP_FREE_POST) { - EVP_PKEY_free(pubkey->pkey); - } else if (operation == ASN1_OP_D2I_POST) { - x509_pubkey_changed(pubkey); +int x509_parse_public_key(CBS *cbs, X509_PUBKEY *out, + bssl::Span algs) { + CBS seq; + if (!CBS_get_asn1(cbs, &seq, CBS_ASN1_SEQUENCE) || + !x509_parse_algorithm(&seq, &out->algor) || + !asn1_parse_bit_string(&seq, &out->public_key, /*tag=*/0) || + CBS_len(&seq) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } + x509_pubkey_changed(out, algs); return 1; } -ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { - ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), - ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING), -} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) +static int x509_parse_public_key_default(CBS *cbs, X509_PUBKEY *out) { + return x509_parse_public_key(cbs, out, bssl::GetDefaultEVPAlgorithms()); +} -IMPLEMENT_ASN1_FUNCTIONS_const(X509_PUBKEY) +int x509_marshal_public_key(CBB *cbb, const X509_PUBKEY *in) { + CBB seq; + return CBB_add_asn1(cbb, &seq, CBS_ASN1_SEQUENCE) && + x509_marshal_algorithm(&seq, &in->algor) && + asn1_marshal_bit_string(&seq, &in->public_key, /*tag=*/0) && + CBB_flush(cbb); +} -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { - X509_PUBKEY *pk = NULL; - uint8_t *spki = NULL; - size_t spki_len; +X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(X509_PUBKEY_new()); + if (ret == nullptr || !x509_parse_public_key_default(cbs, ret.get())) { + return nullptr; + } + return ret; + }); +} - if (x == NULL) { - return 0; - } +int i2d_X509_PUBKEY(const X509_PUBKEY *key, uint8_t **outp) { + return bssl::I2DFromCBB(/*initial_capacity=*/32, outp, [&](CBB *cbb) -> bool { + return x509_marshal_public_key(cbb, key); + }); +} - CBB cbb; - const uint8_t *p; - if (!CBB_init(&cbb, 0) || // - !EVP_marshal_public_key(&cbb, pkey) || - !CBB_finish(&cbb, &spki, &spki_len) || // - spki_len > LONG_MAX) { - CBB_cleanup(&cbb); +// TODO(crbug.com/42290417): Remove this when |X509| and |X509_REQ| no longer +// depend on the tables. +IMPLEMENT_EXTERN_ASN1_SIMPLE(X509_PUBKEY, X509_PUBKEY_new, X509_PUBKEY_free, + x509_parse_public_key_default, i2d_X509_PUBKEY) + +int x509_pubkey_set1(X509_PUBKEY *key, EVP_PKEY *pkey) { + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64) || + !EVP_marshal_public_key(cbb.get(), pkey)) { OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); - goto error; + return 0; } - p = spki; - pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); - if (pk == NULL || p != spki + spki_len) { - OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); - goto error; - } + CBS cbs; + CBS_init(&cbs, CBB_data(cbb.get()), CBB_len(cbb.get())); + // TODO(crbug.com/42290364): Use an |EVP_PKEY_ALG| derived from |pkey|. + // |X509_PUBKEY_get0| does not currently work when setting, say, an + // |EVP_PKEY_RSA_PSS| key. + return x509_parse_public_key(&cbs, key, bssl::GetDefaultEVPAlgorithms()); +} - OPENSSL_free(spki); +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { + bssl::UniquePtr new_key(X509_PUBKEY_new()); + if (new_key == nullptr || !x509_pubkey_set1(new_key.get(), pkey)) { + return 0; + } X509_PUBKEY_free(*x); - *x = pk; - + *x = new_key.release(); return 1; -error: - X509_PUBKEY_free(pk); - OPENSSL_free(spki); - return 0; } EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) { @@ -136,16 +181,16 @@ EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) { int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, int param_type, void *param_value, uint8_t *key, int key_len) { - if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) { + if (!X509_ALGOR_set0(&pub->algor, obj, param_type, param_value)) { return 0; } - ASN1_STRING_set0(pub->public_key, key, key_len); + ASN1_STRING_set0(&pub->public_key, key, key_len); // Set the number of unused bits to zero. - pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + pub->public_key.flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key.flags |= ASN1_STRING_FLAG_BITS_LEFT; - x509_pubkey_changed(pub); + x509_pubkey_changed(pub, bssl::GetDefaultEVPAlgorithms()); return 1; } @@ -153,18 +198,18 @@ int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key, int *out_key_len, X509_ALGOR **out_alg, X509_PUBKEY *pub) { if (out_obj != NULL) { - *out_obj = pub->algor->algorithm; + *out_obj = pub->algor.algorithm; } if (out_key != NULL) { - *out_key = pub->public_key->data; - *out_key_len = pub->public_key->length; + *out_key = pub->public_key.data; + *out_key_len = pub->public_key.length; } if (out_alg != NULL) { - *out_alg = pub->algor; + *out_alg = &pub->algor; } return 1; } const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key(const X509_PUBKEY *pub) { - return pub->public_key; + return &pub->public_key; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc deleted file mode 100644 index 188df6977..000000000 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include -#include - -#include "internal.h" - - -ASN1_SEQUENCE(X509_VAL) = { - ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), - ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME), -} ASN1_SEQUENCE_END(X509_VAL) - -IMPLEMENT_ASN1_FUNCTIONS_const(X509_VAL) diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc index ec1037cc4..0e570801c 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc @@ -27,57 +27,57 @@ #include "../asn1/internal.h" #include "../bytestring/internal.h" +#include "../evp/internal.h" #include "../internal.h" #include "internal.h" static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; -ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { - ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), - ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), - ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), - ASN1_SIMPLE(X509_CINF, validity, X509_VAL), - ASN1_SIMPLE(X509_CINF, subject, X509_NAME), - ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), - ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), - ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3), -} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) - -// x509_new_null returns a new |X509| object where the |cert_info|, |sig_alg|, -// and |signature| fields are not yet filled in. -static X509 *x509_new_null(void) { - X509 *ret = reinterpret_cast(OPENSSL_zalloc(sizeof(X509))); - if (ret == NULL) { - return NULL; +static constexpr CBS_ASN1_TAG kVersionTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; +static constexpr CBS_ASN1_TAG kIssuerUIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 1; +static constexpr CBS_ASN1_TAG kSubjectUIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 2; +static constexpr CBS_ASN1_TAG kExtensionsTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; + +// x509_new_null returns a new |X509| object where the |issuer| and |subject| +// fields are not yet filled in. +static bssl::UniquePtr x509_new_null(void) { + bssl::UniquePtr ret( + reinterpret_cast(OPENSSL_zalloc(sizeof(X509)))); + if (ret == nullptr) { + return nullptr; } ret->references = 1; ret->ex_pathlen = -1; + ret->version = X509_VERSION_1; + asn1_string_init(&ret->serialNumber, V_ASN1_INTEGER); + x509_algor_init(&ret->tbs_sig_alg); + asn1_string_init(&ret->notBefore, -1); + asn1_string_init(&ret->notAfter, -1); + x509_pubkey_init(&ret->key); + x509_algor_init(&ret->sig_alg); + asn1_string_init(&ret->signature, V_ASN1_BIT_STRING); CRYPTO_new_ex_data(&ret->ex_data); CRYPTO_MUTEX_init(&ret->lock); return ret; } X509 *X509_new(void) { - X509 *ret = x509_new_null(); - if (ret == NULL) { - return NULL; + bssl::UniquePtr ret = x509_new_null(); + if (ret == nullptr) { + return nullptr; } - - ret->cert_info = X509_CINF_new(); - ret->sig_alg = X509_ALGOR_new(); - ret->signature = ASN1_BIT_STRING_new(); - if (ret->cert_info == NULL || ret->sig_alg == NULL || - ret->signature == NULL) { - X509_free(ret); - return NULL; + // TODO(crbug.com/42290417): When the |X509_NAME| parser is CBS-based and + // writes into a pre-existing |X509_NAME|, we will no longer need the + // |X509_new| and |x509_new_null| split. + ret->issuer = X509_NAME_new(); + ret->subject = X509_NAME_new(); + if (ret->issuer == nullptr || ret->subject == nullptr) { + return nullptr; } - - return ret; + return ret.release(); } void X509_free(X509 *x509) { @@ -87,9 +87,19 @@ void X509_free(X509 *x509) { CRYPTO_free_ex_data(&g_ex_data_class, &x509->ex_data); - X509_CINF_free(x509->cert_info); - X509_ALGOR_free(x509->sig_alg); - ASN1_BIT_STRING_free(x509->signature); + asn1_string_cleanup(&x509->serialNumber); + x509_algor_cleanup(&x509->tbs_sig_alg); + X509_NAME_free(x509->issuer); + asn1_string_cleanup(&x509->notBefore); + asn1_string_cleanup(&x509->notAfter); + X509_NAME_free(x509->subject); + x509_pubkey_cleanup(&x509->key); + ASN1_BIT_STRING_free(x509->issuerUID); + ASN1_BIT_STRING_free(x509->subjectUID); + sk_X509_EXTENSION_pop_free(x509->extensions, X509_EXTENSION_free); + x509_algor_cleanup(&x509->sig_alg); + asn1_string_cleanup(&x509->signature); + CRYPTO_BUFFER_free(x509->buf); ASN1_OCTET_STRING_free(x509->skid); AUTHORITY_KEYID_free(x509->akid); CRL_DIST_POINTS_free(x509->crldp); @@ -101,115 +111,216 @@ void X509_free(X509 *x509) { OPENSSL_free(x509); } -static X509 *x509_parse(CBS *cbs, CRYPTO_BUFFER *buf) { - CBS cert, tbs, sigalg, sig; - if (!CBS_get_asn1(cbs, &cert, CBS_ASN1_SEQUENCE) || - // Bound the length to comfortably fit in an int. Lengths in this - // module often omit overflow checks. - CBS_len(&cert) > INT_MAX / 2 || - !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1_element(&cert, &sigalg, CBS_ASN1_SEQUENCE)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return nullptr; - } - - // For just the signature field, we accept non-minimal BER lengths, though not - // indefinite-length encoding. See b/18228011. - // - // TODO(crbug.com/boringssl/354): Switch the affected callers to convert the - // certificate before parsing and then remove this workaround. - CBS_ASN1_TAG tag; - size_t header_len; - int indefinite; - if (!CBS_get_any_ber_asn1_element(&cert, &sig, &tag, &header_len, - /*out_ber_found=*/nullptr, - &indefinite) || - tag != CBS_ASN1_BITSTRING || indefinite || // - !CBS_skip(&sig, header_len) || // - CBS_len(&cert) != 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return nullptr; +static int parse_name(CBS *cbs, X509_NAME **out) { + // TODO(crbug.com/42290417): Make the |X509_NAME| parser CBS-based and avoid + // this awkward conversion. + const uint8_t *p = CBS_data(cbs); + X509_NAME_free(*out); + *out = d2i_X509_NAME(nullptr, &p, CBS_len(cbs)); + if (*out == nullptr) { + return 0; } + BSSL_CHECK(CBS_skip(cbs, p - CBS_data(cbs))); + return 1; +} +X509 *X509_parse_with_algorithms(CRYPTO_BUFFER *buf, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { bssl::UniquePtr ret(x509_new_null()); if (ret == nullptr) { return nullptr; } - // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled - // from the tasn_*.c implementation, replace this with |CBS|-based - // functions. - const uint8_t *inp = CBS_data(&tbs); - if (ASN1_item_ex_d2i((ASN1_VALUE **)&ret->cert_info, &inp, CBS_len(&tbs), - ASN1_ITEM_rptr(X509_CINF), /*tag=*/-1, - /*aclass=*/0, /*opt=*/0, buf) <= 0 || - inp != CBS_data(&tbs) + CBS_len(&tbs)) { - return nullptr; - } + // Save the buffer to cache the original encoding. + ret->buf = bssl::UpRef(buf).release(); - inp = CBS_data(&sigalg); - ret->sig_alg = d2i_X509_ALGOR(nullptr, &inp, CBS_len(&sigalg)); - if (ret->sig_alg == nullptr || inp != CBS_data(&sigalg) + CBS_len(&sigalg)) { + // Parse the Certificate. + CBS cbs, cert, tbs; + CRYPTO_BUFFER_init_CBS(buf, &cbs); + if (!CBS_get_asn1(&cbs, &cert, CBS_ASN1_SEQUENCE) || // + CBS_len(&cbs) != 0 || + // Bound the length to comfortably fit in an int. Lengths in this + // module often omit overflow checks. + CBS_len(&cert) > INT_MAX / 2 || + !CBS_get_asn1(&cert, &tbs, CBS_ASN1_SEQUENCE) || + !x509_parse_algorithm(&cert, &ret->sig_alg) || + // For just the signature field, we accept non-minimal BER lengths, though + // not indefinite-length encoding. See b/18228011. + // + // TODO(crbug.com/boringssl/354): Switch the affected callers to convert + // the certificate before parsing and then remove this workaround. + !asn1_parse_bit_string_with_bad_length(&cert, &ret->signature) || + CBS_len(&cert) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } - inp = CBS_data(&sig); - ret->signature = c2i_ASN1_BIT_STRING(nullptr, &inp, CBS_len(&sig)); - if (ret->signature == nullptr || inp != CBS_data(&sig) + CBS_len(&sig)) { + // Parse the TBSCertificate. + if (CBS_peek_asn1_tag(&tbs, kVersionTag)) { + CBS wrapper; + uint64_t version; + if (!CBS_get_asn1(&tbs, &wrapper, kVersionTag) || + !CBS_get_asn1_uint64(&wrapper, &version) || // + CBS_len(&wrapper) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + // The version must be one of v1(0), v2(1), or v3(2). + // TODO(https://crbug.com/42290225): Also reject |X509_VERSION_1|. v1 is + // DEFAULT, so DER requires it be omitted. + if (version != X509_VERSION_1 && version != X509_VERSION_2 && + version != X509_VERSION_3) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return nullptr; + } + ret->version = static_cast(version); + } else { + ret->version = X509_VERSION_1; + } + CBS validity; + if (!asn1_parse_integer(&tbs, &ret->serialNumber, /*tag=*/0) || + !x509_parse_algorithm(&tbs, &ret->tbs_sig_alg) || + !parse_name(&tbs, &ret->issuer) || + !CBS_get_asn1(&tbs, &validity, CBS_ASN1_SEQUENCE) || + !asn1_parse_time(&validity, &ret->notBefore, + /*allow_utc_timezone_offset=*/1) || + !asn1_parse_time(&validity, &ret->notAfter, + /*allow_utc_timezone_offset=*/1) || + CBS_len(&validity) != 0 || // + !parse_name(&tbs, &ret->subject) || + !x509_parse_public_key(&tbs, &ret->key, bssl::Span(algs, num_algs))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } - - // The version must be one of v1(0), v2(1), or v3(2). - long version = X509_VERSION_1; - if (ret->cert_info->version != nullptr) { - version = ASN1_INTEGER_get(ret->cert_info->version); - // TODO(https://crbug.com/boringssl/364): |X509_VERSION_1| should - // also be rejected here. This means an explicitly-encoded X.509v1 - // version. v1 is DEFAULT, so DER requires it be omitted. - if (version < X509_VERSION_1 || version > X509_VERSION_3) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3: + if (ret->version >= X509_VERSION_2 && + CBS_peek_asn1_tag(&tbs, kIssuerUIDTag)) { + ret->issuerUID = ASN1_BIT_STRING_new(); + if (ret->issuerUID == nullptr || + !asn1_parse_bit_string(&tbs, ret->issuerUID, kIssuerUIDTag)) { return nullptr; } } - - // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. - if (version == X509_VERSION_1 && (ret->cert_info->issuerUID != nullptr || - ret->cert_info->subjectUID != nullptr)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return nullptr; + if (ret->version >= X509_VERSION_2 && + CBS_peek_asn1_tag(&tbs, kSubjectUIDTag)) { + ret->subjectUID = ASN1_BIT_STRING_new(); + if (ret->subjectUID == nullptr || + !asn1_parse_bit_string(&tbs, ret->subjectUID, kSubjectUIDTag)) { + return nullptr; + } } - - // Per RFC 5280, section 4.1.2.9, extensions require v3. - if (version != X509_VERSION_3 && ret->cert_info->extensions != nullptr) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + // Per RFC 5280, section 4.1.2.9, extensions require v3: + if (ret->version >= X509_VERSION_3 && + CBS_peek_asn1_tag(&tbs, kExtensionsTag)) { + CBS wrapper; + if (!CBS_get_asn1(&tbs, &wrapper, kExtensionsTag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + // TODO(crbug.com/42290219): Empty extension lists should be rejected. An + // empty extensions list is encoded by omitting the field altogether. libpki + // already rejects this. + const uint8_t *p = CBS_data(&wrapper); + ret->extensions = d2i_X509_EXTENSIONS(nullptr, &p, CBS_len(&wrapper)); + if (ret->extensions == nullptr || + p != CBS_data(&wrapper) + CBS_len(&wrapper)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + } + if (CBS_len(&tbs) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } return ret.release(); } -X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { - X509 *ret = NULL; - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); - goto err; +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + auto algs = bssl::GetDefaultEVPAlgorithms(); + return X509_parse_with_algorithms(buf, algs.data(), algs.size()); +} + +static bssl::UniquePtr x509_parse(CBS *cbs) { + CBS cert; + if (!CBS_get_asn1_element(cbs, &cert, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - ret = x509_parse(&cbs, NULL); - if (ret == NULL) { - goto err; + bssl::UniquePtr buf(CRYPTO_BUFFER_new_from_CBS(&cert, nullptr)); + if (buf == nullptr) { + return nullptr; } + return bssl::UniquePtr(X509_parse_from_buffer(buf.get())); +} - *inp = CBS_data(&cbs); +int x509_marshal_tbs_cert(CBB *cbb, X509 *x509) { + if (x509->buf != nullptr) { + // Replay the saved TBSCertificate from the |CRYPTO_BUFFER|, to verify + // exactly what we parsed. The |CRYPTO_BUFFER| contains the full + // Certificate, so we need to find the TBSCertificate portion. + CBS cbs, cert, tbs; + CRYPTO_BUFFER_init_CBS(x509->buf, &cbs); + if (!CBS_get_asn1(&cbs, &cert, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE)) { + // This should be impossible. + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + return CBB_add_bytes(cbb, CBS_data(&tbs), CBS_len(&tbs)); + } -err: - if (out != NULL) { - X509_free(*out); - *out = ret; + // No saved TBSCertificate encoding. Encode it anew. + CBB tbs, version, validity, extensions; + if (!CBB_add_asn1(cbb, &tbs, CBS_ASN1_SEQUENCE)) { + return 0; } - return ret; + if (x509->version != X509_VERSION_1) { + if (!CBB_add_asn1(&tbs, &version, kVersionTag) || + !CBB_add_asn1_uint64(&version, x509->version)) { + return 0; + } + } + if (!asn1_marshal_integer(&tbs, &x509->serialNumber, /*tag=*/0) || + !x509_marshal_algorithm(&tbs, &x509->tbs_sig_alg) || + !x509_marshal_name(&tbs, x509->issuer) || + !CBB_add_asn1(&tbs, &validity, CBS_ASN1_SEQUENCE) || + !asn1_marshal_time(&validity, &x509->notBefore) || + !asn1_marshal_time(&validity, &x509->notAfter) || + !x509_marshal_name(&tbs, x509->subject) || + !x509_marshal_public_key(&tbs, &x509->key) || + (x509->issuerUID != nullptr && + !asn1_marshal_bit_string(&tbs, x509->issuerUID, kIssuerUIDTag)) || + (x509->subjectUID != nullptr && + !asn1_marshal_bit_string(&tbs, x509->subjectUID, kSubjectUIDTag))) { + return 0; + } + if (x509->extensions != nullptr) { + int len = i2d_X509_EXTENSIONS(x509->extensions, nullptr); + uint8_t *out; + if (len <= 0 || // + !CBB_add_asn1(&tbs, &extensions, kExtensionsTag) || + !CBB_add_space(&extensions, &out, len) || + i2d_X509_EXTENSIONS(x509->extensions, &out) != len) { + return 0; + } + } + return CBB_flush(cbb); +} + +static int x509_marshal(CBB *cbb, X509 *x509) { + CBB cert; + return CBB_add_asn1(cbb, &cert, CBS_ASN1_SEQUENCE) && + x509_marshal_tbs_cert(&cert, x509) && + x509_marshal_algorithm(&cert, &x509->sig_alg) && + asn1_marshal_bit_string(&cert, &x509->signature, /*tag=*/0) && + CBB_flush(cbb); +} + +X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS(out, inp, len, x509_parse); } int i2d_X509(X509 *x509, uint8_t **outp) { @@ -218,26 +329,9 @@ int i2d_X509(X509 *x509, uint8_t **outp) { return -1; } - bssl::ScopedCBB cbb; - CBB cert; - if (!CBB_init(cbb.get(), 64) || // - !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE)) { - return -1; - } - - // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled - // from the tasn_*.c implementation, replace this with |CBS|-based functions. - uint8_t *out; - int len = i2d_X509_CINF(x509->cert_info, NULL); - if (len < 0 || // - !CBB_add_space(&cert, &out, static_cast(len)) || - i2d_X509_CINF(x509->cert_info, &out) != len || - !x509_marshal_algorithm(&cert, x509->sig_alg) || - !asn1_marshal_bit_string(&cert, x509->signature, /*tag=*/0)) { - return -1; - } - - return CBB_finish_i2d(cbb.get(), outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return x509_marshal(cbb, x509); }); } static int x509_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { @@ -250,27 +344,19 @@ static void x509_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { *pval = NULL; } -static int x509_d2i_cb(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int opt, ASN1_TLC *ctx) { - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); - return 0; - } - - CBS cbs; - CBS_init(&cbs, *in, len); - if (opt && !CBS_peek_asn1_tag(&cbs, CBS_ASN1_SEQUENCE)) { - return -1; +static int x509_parse_cb(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, + int opt) { + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return 1; } - X509 *ret = x509_parse(&cbs, NULL); - if (ret == NULL) { + bssl::UniquePtr ret = x509_parse(cbs); + if (ret == nullptr) { return 0; } - *in = CBS_data(&cbs); X509_free((X509 *)*pval); - *pval = (ASN1_VALUE *)ret; + *pval = (ASN1_VALUE *)ret.release(); return 1; } @@ -279,14 +365,9 @@ static int x509_i2d_cb(ASN1_VALUE **pval, unsigned char **out, return i2d_X509((X509 *)*pval, out); } -static const ASN1_EXTERN_FUNCS x509_extern_funcs = { - x509_new_cb, - x509_free_cb, - x509_d2i_cb, - x509_i2d_cb, -}; - -IMPLEMENT_EXTERN_ASN1(X509, V_ASN1_SEQUENCE, x509_extern_funcs) +static const ASN1_EXTERN_FUNCS x509_extern_funcs = {x509_new_cb, x509_free_cb, + x509_parse_cb, x509_i2d_cb}; +IMPLEMENT_EXTERN_ASN1(X509, x509_extern_funcs) X509 *X509_dup(X509 *x509) { uint8_t *der = NULL; @@ -301,18 +382,6 @@ X509 *X509_dup(X509 *x509) { return ret; } -X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { - CBS cbs; - CBS_init(&cbs, CRYPTO_BUFFER_data(buf), CRYPTO_BUFFER_len(buf)); - X509 *ret = x509_parse(&cbs, buf); - if (ret == NULL || CBS_len(&cbs) != 0) { - X509_free(ret); - return NULL; - } - - return ret; -} - int X509_up_ref(X509 *x) { CRYPTO_refcount_inc(&x->references); return 1; @@ -437,49 +506,41 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp) { } int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) { - asn1_encoding_clear(&x509->cert_info->enc); - return i2d_X509_CINF(x509->cert_info, outp); + CRYPTO_BUFFER_free(x509->buf); + x509->buf = nullptr; + return i2d_X509_tbs(x509, outp); } int i2d_X509_tbs(X509 *x509, unsigned char **outp) { - return i2d_X509_CINF(x509->cert_info, outp); + return bssl::I2DFromCBB(/*initial_capacity=*/128, outp, [&](CBB *cbb) -> bool { + return x509_marshal_tbs_cert(cbb, x509); + }); } int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo) { - X509_ALGOR *copy1 = X509_ALGOR_dup(algo); - X509_ALGOR *copy2 = X509_ALGOR_dup(algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } - - X509_ALGOR_free(x509->sig_alg); - x509->sig_alg = copy1; - X509_ALGOR_free(x509->cert_info->signature); - x509->cert_info->signature = copy2; - return 1; + return X509_ALGOR_copy(&x509->sig_alg, algo) && + X509_ALGOR_copy(&x509->tbs_sig_alg, algo); } int X509_set1_signature_value(X509 *x509, const uint8_t *sig, size_t sig_len) { - if (!ASN1_STRING_set(x509->signature, sig, sig_len)) { + if (!ASN1_STRING_set(&x509->signature, sig, sig_len)) { return 0; } - x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + x509->signature.flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + x509->signature.flags |= ASN1_STRING_FLAG_BITS_LEFT; return 1; } void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, const X509 *x) { if (psig) { - *psig = x->signature; + *psig = &x->signature; } if (palg) { - *palg = x->sig_alg; + *palg = &x->sig_alg; } } int X509_get_signature_nid(const X509 *x) { - return OBJ_obj2nid(x->sig_alg->algorithm); + return OBJ_obj2nid(x->sig_alg.algorithm); } diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S index a79430850..2131b9006 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S @@ -7,11 +7,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(__APPLE__) .text -.globl _bn_mul_mont -.private_extern _bn_mul_mont +.globl _bn_mul_mont_words +.private_extern _bn_mul_mont_words .align 5 -_bn_mul_mont: +_bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -217,7 +217,7 @@ Lcond_copy: .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont Lsqr8x_mont: @@ -979,7 +979,7 @@ Lsqr8x_done: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S index ab46c5b69..49281dbcf 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S @@ -7,11 +7,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(__ELF__) .text -.globl bn_mul_mont -.hidden bn_mul_mont -.type bn_mul_mont,%function +.globl bn_mul_mont_words +.hidden bn_mul_mont_words +.type bn_mul_mont_words,%function .align 5 -bn_mul_mont: +bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -212,12 +212,12 @@ bn_mul_mont: ldr x29,[sp],#64 AARCH64_VALIDATE_LINK_REGISTER ret -.size bn_mul_mont,.-bn_mul_mont +.size bn_mul_mont_words,.-bn_mul_mont_words .type __bn_sqr8x_mont,%function .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont .Lsqr8x_mont: @@ -979,7 +979,7 @@ __bn_sqr8x_mont: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S index def7a92d9..c2b45f137 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S @@ -7,13 +7,13 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(_WIN32) .text -.globl bn_mul_mont +.globl bn_mul_mont_words -.def bn_mul_mont +.def bn_mul_mont_words .type 32 .endef .align 5 -bn_mul_mont: +bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -221,7 +221,7 @@ Lcond_copy: .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont Lsqr8x_mont: @@ -985,7 +985,7 @@ Lsqr8x_done: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S index 03b00eee5..8a05634e6 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S @@ -6,11 +6,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__APPLE__) .text -.globl _bn_mul_mont -.private_extern _bn_mul_mont +.globl _bn_mul_mont_words +.private_extern _bn_mul_mont_words .align 4 -_bn_mul_mont: -L_bn_mul_mont_begin: +_bn_mul_mont_words: +L_bn_mul_mont_words_begin: pushl %ebp pushl %ebx pushl %esi diff --git a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S index 81cc896dc..37d96f457 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S @@ -6,12 +6,12 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__ELF__) .text -.globl bn_mul_mont -.hidden bn_mul_mont -.type bn_mul_mont,@function +.globl bn_mul_mont_words +.hidden bn_mul_mont_words +.type bn_mul_mont_words,@function .align 16 -bn_mul_mont: -.L_bn_mul_mont_begin: +bn_mul_mont_words: +.L_bn_mul_mont_words_begin: pushl %ebp pushl %ebx pushl %esi @@ -210,7 +210,7 @@ bn_mul_mont: popl %ebx popl %ebp ret -.size bn_mul_mont,.-.L_bn_mul_mont_begin +.size bn_mul_mont_words,.-.L_bn_mul_mont_words_begin .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 .byte 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 .byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 diff --git a/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc b/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc index 2e00d9193..f14c40fc8 100644 --- a/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc +++ b/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc @@ -78,54 +78,54 @@ const uint32_t kOpenSSLReasonValues[] = { 0xc3b00f7, 0xc3b8921, 0x10320892, - 0x103296b2, - 0x103316be, - 0x103396d7, - 0x103416ea, + 0x103296ad, + 0x103316b9, + 0x103396d2, + 0x103416e5, 0x10348fd3, 0x10350d1f, - 0x103596fd, - 0x10361727, - 0x1036973a, - 0x10371759, - 0x10379772, - 0x10381787, - 0x103897a5, - 0x103917b4, - 0x103997d0, - 0x103a17eb, - 0x103a97fa, - 0x103b1816, - 0x103b9831, - 0x103c1857, + 0x103596f8, + 0x10361722, + 0x10369735, + 0x10371754, + 0x1037976d, + 0x10381782, + 0x103897a0, + 0x103917af, + 0x103997cb, + 0x103a17e6, + 0x103a97f5, + 0x103b1811, + 0x103b982c, + 0x103c1852, 0x103c80f7, - 0x103d1868, - 0x103d987c, - 0x103e189b, - 0x103e98aa, - 0x103f18c1, - 0x103f98d4, + 0x103d1863, + 0x103d9877, + 0x103e1896, + 0x103e98a5, + 0x103f18bc, + 0x103f98cf, 0x10400ce3, - 0x104098e7, - 0x10411905, - 0x10419918, - 0x10421932, - 0x10429942, - 0x10431956, - 0x1043996c, - 0x10441984, - 0x10449999, - 0x104519ad, - 0x104599bf, + 0x104098e2, + 0x10411900, + 0x10419913, + 0x1042192d, + 0x1042993d, + 0x10431951, + 0x10439967, + 0x1044197f, + 0x10449994, + 0x104519a8, + 0x104599ba, 0x10460635, 0x1046899a, - 0x104719d4, - 0x104799eb, - 0x10481a00, - 0x10489a0e, + 0x104719cf, + 0x104799e6, + 0x104819fb, + 0x10489a09, 0x10490f1f, - 0x10499848, - 0x104a1712, + 0x10499843, + 0x104a170d, 0x14320cb3, 0x14328cd4, 0x14330ce3, @@ -139,57 +139,57 @@ const uint32_t kOpenSSLReasonValues[] = { 0x1833903f, 0x18341053, 0x183480f7, - 0x18351072, - 0x1835908a, - 0x183610b2, - 0x183690c6, - 0x183710fe, - 0x18379114, - 0x18381128, - 0x18389138, + 0x183510ae, + 0x18359072, + 0x1836109a, + 0x183690c1, + 0x183710f9, + 0x1837910f, + 0x18381123, + 0x18389133, 0x18390ac0, - 0x18399148, - 0x183a116e, - 0x183a9194, + 0x18399143, + 0x183a1169, + 0x183a918f, 0x183b0d2b, - 0x183b91e3, - 0x183c11f5, - 0x183c9200, - 0x183d1210, - 0x183d9221, - 0x183e1232, - 0x183e9244, - 0x183f126d, - 0x183f9286, - 0x1840129e, + 0x183b91de, + 0x183c11f0, + 0x183c91fb, + 0x183d120b, + 0x183d921c, + 0x183e122d, + 0x183e923f, + 0x183f1268, + 0x183f9281, + 0x18401299, 0x1840870d, - 0x184111b7, - 0x18419182, - 0x184211a1, + 0x184111b2, + 0x1841917d, + 0x1842119c, 0x18428cc1, - 0x1843115d, - 0x184391c9, + 0x18431158, + 0x184391c4, 0x18441068, - 0x184490ea, - 0x1845109f, - 0x203212d8, - 0x203292c5, - 0x243212e4, + 0x184490e5, + 0x18451087, + 0x203212d3, + 0x203292c0, + 0x243212df, 0x243289e0, - 0x243312f6, - 0x24339303, - 0x24341310, - 0x24349322, - 0x24351331, - 0x2435934e, - 0x2436135b, - 0x24369369, - 0x24371377, - 0x24379385, - 0x2438138e, - 0x2438939b, - 0x243913ae, - 0x243993c5, + 0x243312f1, + 0x243392fe, + 0x2434130b, + 0x2434931d, + 0x2435132c, + 0x24359349, + 0x24361356, + 0x24369364, + 0x24371372, + 0x24379380, + 0x24381389, + 0x24389396, + 0x243913a9, + 0x243993c0, 0x28320d13, 0x28328d2b, 0x28330ce3, @@ -199,51 +199,51 @@ const uint32_t kOpenSSLReasonValues[] = { 0x283500f7, 0x28358cc1, 0x2836099a, - 0x2c3233f9, - 0x2c3293e3, - 0x2c333407, - 0x2c33b419, - 0x2c34342d, - 0x2c34b43f, - 0x2c35345a, - 0x2c35b46c, - 0x2c36349c, + 0x2c3233f4, + 0x2c3293de, + 0x2c333402, + 0x2c33b414, + 0x2c343428, + 0x2c34b43a, + 0x2c353455, + 0x2c35b467, + 0x2c363497, 0x2c36833a, - 0x2c3734a9, - 0x2c37b4d5, - 0x2c383513, - 0x2c38b52a, - 0x2c393548, - 0x2c39b558, - 0x2c3a356a, - 0x2c3ab57e, - 0x2c3b358f, - 0x2c3bb5ae, - 0x2c3c13f5, - 0x2c3c940b, - 0x2c3d35f3, - 0x2c3d9424, - 0x2c3e361d, - 0x2c3eb62b, - 0x2c3f3643, - 0x2c3fb65b, - 0x2c403685, - 0x2c4092d8, - 0x2c413696, - 0x2c41b6a9, - 0x2c42129e, - 0x2c42b6ba, + 0x2c3734a4, + 0x2c37b4d0, + 0x2c38350e, + 0x2c38b525, + 0x2c393543, + 0x2c39b553, + 0x2c3a3565, + 0x2c3ab579, + 0x2c3b358a, + 0x2c3bb5a9, + 0x2c3c13f0, + 0x2c3c9406, + 0x2c3d35ee, + 0x2c3d941f, + 0x2c3e3618, + 0x2c3eb626, + 0x2c3f363e, + 0x2c3fb656, + 0x2c403680, + 0x2c4092d3, + 0x2c413691, + 0x2c41b6a4, + 0x2c421299, + 0x2c42b6b5, 0x2c43076d, - 0x2c43b5a0, - 0x2c4434e8, - 0x2c44b668, - 0x2c45347f, - 0x2c45b4bb, - 0x2c463538, - 0x2c46b5c2, - 0x2c4735d7, - 0x2c47b610, - 0x2c4834fa, + 0x2c43b59b, + 0x2c4434e3, + 0x2c44b663, + 0x2c45347a, + 0x2c45b4b6, + 0x2c463533, + 0x2c46b5bd, + 0x2c4735d2, + 0x2c47b60b, + 0x2c4834f5, 0x30320000, 0x30328015, 0x3033001f, @@ -383,268 +383,268 @@ const uint32_t kOpenSSLReasonValues[] = { 0x3c418e13, 0x3c420f1f, 0x3c428ea9, - 0x40321a7a, - 0x40329a90, - 0x40331abe, - 0x40339ac8, - 0x40341adf, - 0x40349afd, - 0x40351b0d, - 0x40359b1f, - 0x40361b2c, - 0x40369b38, - 0x40371b4d, - 0x40379b5f, - 0x40381b6a, - 0x40389b7c, + 0x40321a75, + 0x40329a8b, + 0x40331ab9, + 0x40339ac3, + 0x40341ada, + 0x40349af8, + 0x40351b08, + 0x40359b1a, + 0x40361b27, + 0x40369b33, + 0x40371b48, + 0x40379b5a, + 0x40381b65, + 0x40389b77, 0x40390fd3, - 0x40399b8c, - 0x403a1b9f, - 0x403a9bc0, - 0x403b1bd1, - 0x403b9be1, + 0x40399b87, + 0x403a1b9a, + 0x403a9bbb, + 0x403b1bcc, + 0x403b9bdc, 0x403c0071, 0x403c8090, - 0x403d1c42, - 0x403d9c58, - 0x403e1c67, - 0x403e9c9f, - 0x403f1cb9, - 0x403f9ce1, - 0x40401cf6, - 0x40409d0a, - 0x40411d45, - 0x40419d60, - 0x40421d79, - 0x40429d8c, - 0x40431da0, - 0x40439dce, - 0x40441de5, + 0x403d1c3d, + 0x403d9c53, + 0x403e1c62, + 0x403e9c9a, + 0x403f1cb4, + 0x403f9cdc, + 0x40401cf1, + 0x40409d05, + 0x40411d40, + 0x40419d5b, + 0x40421d74, + 0x40429d87, + 0x40431d9b, + 0x40439dc9, + 0x40441de0, 0x404480b9, - 0x40451dfa, - 0x40459e0c, - 0x40461e30, - 0x40469e50, - 0x40471e5e, - 0x40479e85, - 0x40481ef6, - 0x40489fb0, - 0x40491fc7, - 0x40499fe1, - 0x404a1ff8, - 0x404aa016, - 0x404b202e, - 0x404ba05b, - 0x404c2071, - 0x404ca083, - 0x404d20a4, - 0x404da0dd, - 0x404e20f1, - 0x404ea0fe, - 0x404f21af, - 0x404fa225, - 0x405022af, - 0x4050a2c3, - 0x405122f6, - 0x40522306, - 0x4052a32a, - 0x40532342, - 0x4053a355, - 0x4054236a, - 0x4054a38d, - 0x405523b8, - 0x4055a3f5, - 0x4056241a, - 0x4056a433, - 0x4057244b, - 0x4057a45e, - 0x40582473, - 0x4058a49a, - 0x405924c9, - 0x4059a509, - 0x405aa51d, - 0x405b2535, - 0x405ba546, - 0x405c2559, - 0x405ca598, - 0x405d25a5, - 0x405da5ca, - 0x405e2608, + 0x40451df5, + 0x40459e07, + 0x40461e2b, + 0x40469e4b, + 0x40471e59, + 0x40479e80, + 0x40481ef1, + 0x40489fab, + 0x40491fc2, + 0x40499fdc, + 0x404a1ff3, + 0x404aa011, + 0x404b2029, + 0x404ba056, + 0x404c206c, + 0x404ca07e, + 0x404d209f, + 0x404da0d8, + 0x404e20ec, + 0x404ea0f9, + 0x404f21aa, + 0x404fa220, + 0x405022aa, + 0x4050a2be, + 0x405122f1, + 0x40522301, + 0x4052a325, + 0x4053233d, + 0x4053a350, + 0x40542365, + 0x4054a388, + 0x405523b3, + 0x4055a3f0, + 0x40562415, + 0x4056a42e, + 0x40572446, + 0x4057a459, + 0x4058246e, + 0x4058a495, + 0x405924c4, + 0x4059a504, + 0x405aa518, + 0x405b2530, + 0x405ba541, + 0x405c2554, + 0x405ca593, + 0x405d25a0, + 0x405da5c5, + 0x405e2603, 0x405e8afe, - 0x405f2657, - 0x405fa664, - 0x40602672, - 0x4060a694, - 0x40612708, - 0x4061a740, - 0x40622757, - 0x4062a768, - 0x406327b5, - 0x4063a7ca, - 0x406427e1, - 0x4064a80d, - 0x40652828, - 0x4065a83f, - 0x40662857, - 0x4066a881, - 0x406728ac, - 0x4067a8f1, - 0x40682939, - 0x4068a95a, - 0x4069298c, - 0x4069a9ba, - 0x406a29db, - 0x406aa9fb, - 0x406b2b83, - 0x406baba6, - 0x406c2bbc, - 0x406caec6, - 0x406d2ef5, - 0x406daf1d, - 0x406e2f4b, - 0x406eaf98, - 0x406f2ff1, - 0x406fb029, - 0x4070303c, - 0x4070b059, + 0x405f2652, + 0x405fa65f, + 0x4060266d, + 0x4060a68f, + 0x40612703, + 0x4061a73b, + 0x40622752, + 0x4062a763, + 0x406327b0, + 0x4063a7c5, + 0x406427dc, + 0x4064a808, + 0x40652823, + 0x4065a83a, + 0x40662852, + 0x4066a87c, + 0x406728a7, + 0x4067a8ec, + 0x40682934, + 0x4068a955, + 0x40692987, + 0x4069a9b5, + 0x406a29d6, + 0x406aa9f6, + 0x406b2b7e, + 0x406baba1, + 0x406c2bb7, + 0x406caec1, + 0x406d2ef0, + 0x406daf18, + 0x406e2f46, + 0x406eaf93, + 0x406f2fec, + 0x406fb024, + 0x40703037, + 0x4070b054, 0x4071084d, - 0x4071b06b, - 0x4072307e, - 0x4072b0b4, - 0x407330cc, - 0x4073960d, - 0x407430e0, - 0x4074b0fa, - 0x4075310b, - 0x4075b11f, - 0x4076312d, - 0x4076939b, - 0x40773152, - 0x4077b1ea, - 0x40783205, - 0x4078b23e, - 0x40793255, - 0x4079b26b, - 0x407a3297, - 0x407ab2aa, - 0x407b32bf, - 0x407bb2d1, - 0x407c3302, - 0x407cb30b, - 0x407d2975, - 0x407da24d, - 0x407e321a, - 0x407ea4aa, - 0x407f1e72, - 0x407fa045, - 0x408021bf, - 0x40809e9a, - 0x40812318, - 0x4081a14c, - 0x40822f36, - 0x40829bed, - 0x40832485, - 0x4083a7f2, - 0x40841eae, - 0x4084a4e2, - 0x4085256a, - 0x4085a6cf, - 0x408625ea, - 0x4086a267, - 0x40872f7c, - 0x4087a71d, - 0x40881c2b, - 0x4088a904, - 0x40891c7a, - 0x40899c07, - 0x408a2bf4, - 0x408a9a25, - 0x408b32e6, - 0x408bb006, - 0x408c257a, - 0x408d1f96, - 0x408d9ee0, - 0x408e20c6, - 0x408ea3d5, - 0x408f2918, - 0x408fa6eb, - 0x409028cd, - 0x4090a5bc, - 0x40912bdc, - 0x40919a5d, - 0x40921cc7, - 0x4092afb7, - 0x40933097, - 0x4093a278, - 0x40941ec2, - 0x4094ac0d, - 0x40952779, - 0x4095b277, - 0x40962f63, - 0x4096a1d8, - 0x409722de, - 0x4097a115, - 0x40981d27, - 0x4098a78d, - 0x40992fd3, - 0x4099a402, - 0x409a239b, - 0x409a9a41, - 0x409b1f1c, - 0x409b9f47, - 0x409c31cc, - 0x409c9f6f, - 0x409d2194, - 0x409da162, - 0x409e1db8, - 0x409ea20d, - 0x409f21f5, - 0x409f9f0f, - 0x40a02235, - 0x40a0a12f, - 0x40a1217d, - 0x40a1a4f6, - 0x40a22294, - 0x40a2a648, - 0x40a326bc, - 0x40a3b174, - 0x40a43190, - 0x40a4b1aa, - 0x41f42aae, - 0x41f92b40, - 0x41fe2a33, - 0x41feace9, - 0x41ff2e17, - 0x42032ac7, - 0x42082ae9, - 0x4208ab25, - 0x42092a17, - 0x4209ab5f, - 0x420a2a6e, - 0x420aaa4e, - 0x420b2a8e, - 0x420bab07, - 0x420c2e33, - 0x420cac1d, - 0x420d2cd0, - 0x420dad07, - 0x42122d3a, - 0x42172dfa, - 0x4217ad7c, - 0x421c2d9e, - 0x421f2d59, - 0x42212eab, - 0x42262ddd, - 0x422b2e89, - 0x422bacab, - 0x422c2e6b, - 0x422cac5e, - 0x422d2c37, - 0x422dae4a, - 0x422e2c8a, - 0x42302db9, - 0x4230ad21, - 0x42312629, + 0x4071b066, + 0x40723079, + 0x4072b0af, + 0x407330c7, + 0x40739608, + 0x407430db, + 0x4074b0f5, + 0x40753106, + 0x4075b11a, + 0x40763128, + 0x40769396, + 0x4077314d, + 0x4077b1e5, + 0x40783200, + 0x4078b239, + 0x40793250, + 0x4079b266, + 0x407a3292, + 0x407ab2a5, + 0x407b32ba, + 0x407bb2cc, + 0x407c32fd, + 0x407cb306, + 0x407d2970, + 0x407da248, + 0x407e3215, + 0x407ea4a5, + 0x407f1e6d, + 0x407fa040, + 0x408021ba, + 0x40809e95, + 0x40812313, + 0x4081a147, + 0x40822f31, + 0x40829be8, + 0x40832480, + 0x4083a7ed, + 0x40841ea9, + 0x4084a4dd, + 0x40852565, + 0x4085a6ca, + 0x408625e5, + 0x4086a262, + 0x40872f77, + 0x4087a718, + 0x40881c26, + 0x4088a8ff, + 0x40891c75, + 0x40899c02, + 0x408a2bef, + 0x408a9a20, + 0x408b32e1, + 0x408bb001, + 0x408c2575, + 0x408d1f91, + 0x408d9edb, + 0x408e20c1, + 0x408ea3d0, + 0x408f2913, + 0x408fa6e6, + 0x409028c8, + 0x4090a5b7, + 0x40912bd7, + 0x40919a58, + 0x40921cc2, + 0x4092afb2, + 0x40933092, + 0x4093a273, + 0x40941ebd, + 0x4094ac08, + 0x40952774, + 0x4095b272, + 0x40962f5e, + 0x4096a1d3, + 0x409722d9, + 0x4097a110, + 0x40981d22, + 0x4098a788, + 0x40992fce, + 0x4099a3fd, + 0x409a2396, + 0x409a9a3c, + 0x409b1f17, + 0x409b9f42, + 0x409c31c7, + 0x409c9f6a, + 0x409d218f, + 0x409da15d, + 0x409e1db3, + 0x409ea208, + 0x409f21f0, + 0x409f9f0a, + 0x40a02230, + 0x40a0a12a, + 0x40a12178, + 0x40a1a4f1, + 0x40a2228f, + 0x40a2a643, + 0x40a326b7, + 0x40a3b16f, + 0x40a4318b, + 0x40a4b1a5, + 0x41f42aa9, + 0x41f92b3b, + 0x41fe2a2e, + 0x41feace4, + 0x41ff2e12, + 0x42032ac2, + 0x42082ae4, + 0x4208ab20, + 0x42092a12, + 0x4209ab5a, + 0x420a2a69, + 0x420aaa49, + 0x420b2a89, + 0x420bab02, + 0x420c2e2e, + 0x420cac18, + 0x420d2ccb, + 0x420dad02, + 0x42122d35, + 0x42172df5, + 0x4217ad77, + 0x421c2d99, + 0x421f2d54, + 0x42212ea6, + 0x42262dd8, + 0x422b2e84, + 0x422baca6, + 0x422c2e66, + 0x422cac59, + 0x422d2c32, + 0x422dae45, + 0x422e2c85, + 0x42302db4, + 0x4230ad1c, + 0x42312624, 0x44320778, 0x44328787, 0x44330793, @@ -662,109 +662,109 @@ const uint32_t kOpenSSLReasonValues[] = { 0x4439084d, 0x4439885b, 0x443a086e, - 0x483213e3, - 0x483293f5, - 0x4833140b, - 0x48339424, - 0x4c321461, - 0x4c329471, - 0x4c331484, - 0x4c3394a4, + 0x483213de, + 0x483293f0, + 0x48331406, + 0x4833941f, + 0x4c32145c, + 0x4c32946c, + 0x4c33147f, + 0x4c33949f, 0x4c3400b9, 0x4c3480f7, - 0x4c3514b0, - 0x4c3594be, - 0x4c3614da, - 0x4c369500, - 0x4c37150f, - 0x4c37951d, - 0x4c381532, - 0x4c38953e, - 0x4c39155e, - 0x4c399588, - 0x4c3a15a1, - 0x4c3a95ba, + 0x4c3514ab, + 0x4c3594b9, + 0x4c3614d5, + 0x4c3694fb, + 0x4c37150a, + 0x4c379518, + 0x4c38152d, + 0x4c389539, + 0x4c391559, + 0x4c399583, + 0x4c3a159c, + 0x4c3a95b5, 0x4c3b0635, - 0x4c3b95d3, - 0x4c3c15e5, - 0x4c3c95f4, - 0x4c3d160d, + 0x4c3b95ce, + 0x4c3c15e0, + 0x4c3c95ef, + 0x4c3d1608, 0x4c3d8d06, - 0x4c3e167a, - 0x4c3e961c, - 0x4c3f169c, - 0x4c3f939b, - 0x4c401632, - 0x4c40944d, - 0x4c41166a, - 0x4c4194ed, - 0x4c421656, - 0x4c429435, - 0x503236cc, - 0x5032b6db, - 0x503336e6, - 0x5033b6f6, - 0x5034370f, - 0x5034b729, - 0x50353737, - 0x5035b74d, - 0x5036375f, - 0x5036b775, - 0x5037378e, - 0x5037b7a1, - 0x503837b9, - 0x5038b7ca, - 0x503937df, - 0x5039b7f3, - 0x503a3813, - 0x503ab829, - 0x503b3841, - 0x503bb853, - 0x503c386f, - 0x503cb886, - 0x503d389f, - 0x503db8b5, - 0x503e38c2, - 0x503eb8d8, - 0x503f38ea, + 0x4c3e1675, + 0x4c3e9617, + 0x4c3f1697, + 0x4c3f9396, + 0x4c40162d, + 0x4c409448, + 0x4c411665, + 0x4c4194e8, + 0x4c421651, + 0x4c429430, + 0x503236c7, + 0x5032b6d6, + 0x503336e1, + 0x5033b6f1, + 0x5034370a, + 0x5034b724, + 0x50353732, + 0x5035b748, + 0x5036375a, + 0x5036b770, + 0x50373789, + 0x5037b79c, + 0x503837b4, + 0x5038b7c5, + 0x503937da, + 0x5039b7ee, + 0x503a380e, + 0x503ab824, + 0x503b383c, + 0x503bb84e, + 0x503c386a, + 0x503cb881, + 0x503d389a, + 0x503db8b0, + 0x503e38bd, + 0x503eb8d3, + 0x503f38e5, 0x503f83b3, - 0x504038fd, - 0x5040b90d, - 0x50413927, - 0x5041b936, - 0x50423950, - 0x5042b96d, - 0x5043397d, - 0x5043b98d, - 0x504439aa, + 0x504038f8, + 0x5040b908, + 0x50413922, + 0x5041b931, + 0x5042394b, + 0x5042b968, + 0x50433978, + 0x5043b988, + 0x504439a5, 0x50448469, - 0x504539be, - 0x5045b9dc, - 0x504639ef, - 0x5046ba05, - 0x50473a17, - 0x5047ba2c, - 0x50483a52, - 0x5048ba60, - 0x50493a73, - 0x5049ba88, - 0x504a3a9e, - 0x504abaae, - 0x504b3ace, - 0x504bbae1, - 0x504c3b04, - 0x504cbb32, - 0x504d3b5f, - 0x504dbb7c, - 0x504e3b97, - 0x504ebbb3, - 0x504f3bc5, - 0x504fbbdc, - 0x50503beb, + 0x504539b9, + 0x5045b9d7, + 0x504639ea, + 0x5046ba00, + 0x50473a12, + 0x5047ba27, + 0x50483a4d, + 0x5048ba5b, + 0x50493a6e, + 0x5049ba83, + 0x504a3a99, + 0x504abaa9, + 0x504b3ac9, + 0x504bbadc, + 0x504c3aff, + 0x504cbb2d, + 0x504d3b5a, + 0x504dbb77, + 0x504e3b92, + 0x504ebbae, + 0x504f3bc0, + 0x504fbbd7, + 0x50503be6, 0x50508729, - 0x50513bfe, - 0x5051b99c, - 0x50523b44, + 0x50513bf9, + 0x5051b997, + 0x50523b3f, 0x58321011, 0x68320fd3, 0x68328d2b, @@ -806,22 +806,22 @@ const uint32_t kOpenSSLReasonValues[] = { 0x783d8b97, 0x783e0aed, 0x783e8a9f, - 0x7c3212b4, - 0x80321500, + 0x7c3212af, + 0x803214fb, 0x80328090, - 0x803333c8, + 0x803333c3, 0x803380b9, - 0x803433d7, - 0x8034b33f, - 0x8035335d, - 0x8035b3eb, - 0x8036339f, - 0x8036b34e, - 0x80373391, - 0x8037b32c, - 0x803833b2, - 0x8038b36e, - 0x80393383, + 0x803433d2, + 0x8034b33a, + 0x80353358, + 0x8035b3e6, + 0x8036339a, + 0x8036b349, + 0x8037338c, + 0x8037b327, + 0x803833ad, + 0x8038b369, + 0x8039337e, 0x84320bb0, 0x84328bc9, }; @@ -1049,10 +1049,10 @@ const char kOpenSSLReasonStringData[] = "DIFFERENT_KEY_TYPES\0" "DIFFERENT_PARAMETERS\0" "EMPTY_PSK\0" - "EXPECTING_AN_EC_KEY_KEY\0" "EXPECTING_AN_RSA_KEY\0" "EXPECTING_A_DH_KEY\0" "EXPECTING_A_DSA_KEY\0" + "EXPECTING_A_EC_KEY\0" "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" "INVALID_BUFFER_SIZE\0" "INVALID_DIGEST_LENGTH\0" diff --git a/Sources/CCryptoBoringSSL/hash.txt b/Sources/CCryptoBoringSSL/hash.txt index 60ae1b489..d3430aebc 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 035e720641f385e82c72b7b0a9e1d89e58cb5ed5 +This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 0226f30467f540a3f62ef48d453f93927da199b6 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h index a5791995a..b9368dcc8 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h @@ -801,10 +801,6 @@ OPENSSL_EXPORT ASN1_STRING *d2i_DIRECTORYSTRING(ASN1_STRING **out, // 5280), as described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_DIRECTORYSTRING(const ASN1_STRING *in, uint8_t **outp); -// DIRECTORYSTRING is an |ASN1_ITEM| whose ASN.1 type is X.509 DirectoryString -// (RFC 5280) and C type is |ASN1_STRING*|. -DECLARE_ASN1_ITEM(DIRECTORYSTRING) - // B_ASN1_DISPLAYTEXT is a bitmask of types allowed in an X.509 DisplayText (RFC // 5280). #define B_ASN1_DISPLAYTEXT \ @@ -834,10 +830,6 @@ OPENSSL_EXPORT ASN1_STRING *d2i_DISPLAYTEXT(ASN1_STRING **out, // as described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_DISPLAYTEXT(const ASN1_STRING *in, uint8_t **outp); -// DISPLAYTEXT is an |ASN1_ITEM| whose ASN.1 type is X.509 DisplayText (RFC -// 5280) and C type is |ASN1_STRING*|. -DECLARE_ASN1_ITEM(DISPLAYTEXT) - // Bit strings. // @@ -1258,10 +1250,6 @@ OPENSSL_EXPORT ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **out, const uint8_t **inp, // described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_ASN1_TIME(const ASN1_TIME *in, uint8_t **outp); -// ASN1_TIME is an |ASN1_ITEM| whose ASN.1 type is X.509 Time (RFC 5280) and C -// type is |ASN1_TIME*|. -DECLARE_ASN1_ITEM(ASN1_TIME) - // ASN1_TIME_diff computes |to| - |from|. On success, it sets |*out_days| to the // difference in days, rounded towards zero, sets |*out_seconds| to the // remainder, and returns one. On error, it returns zero. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h index 92f1d66d6..24c7860b6 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h @@ -491,8 +491,8 @@ typedef struct ASN1_AUX_st { ASN1_ITEM_start(itname) ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, \ sizeof(ASN1_STRING), #itname ASN1_ITEM_end(itname) -#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ - ASN1_ITEM_start(sname) ASN1_ITYPE_EXTERN, tag, NULL, 0, &fptrs, 0, \ +#define IMPLEMENT_EXTERN_ASN1(sname, fptrs) \ + ASN1_ITEM_start(sname) ASN1_ITYPE_EXTERN, -1, NULL, 0, &fptrs, 0, \ #sname ASN1_ITEM_end(sname) /* Macro to implement standard functions in terms of ASN1_ITEM structures */ diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h index 66f2c2eae..676d7868e 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h @@ -335,6 +335,7 @@ typedef struct evp_hpke_ctx_st EVP_HPKE_CTX; typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; typedef struct evp_hpke_kem_st EVP_HPKE_KEM; typedef struct evp_hpke_key_st EVP_HPKE_KEY; +typedef struct evp_pkey_alg_st EVP_PKEY_ALG; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; typedef struct evp_pkey_st EVP_PKEY; typedef struct hmac_ctx_st HMAC_CTX; diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h index 0b0d62edd..4b6db8b8f 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_BCM_PUBLIC_H_ #define OPENSSL_HEADER_BCM_PUBLIC_H_ -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -69,9 +69,10 @@ struct sha256_state_st { struct sha512_state_st { uint64_t h[8]; - uint64_t Nl, Nh; + uint16_t num, md_len; + uint32_t bytes_so_far_high; + uint64_t bytes_so_far_low; uint8_t p[BCM_SHA512_CBLOCK]; - unsigned num, md_len; }; diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h index fa549e307..c0fe056cb 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_BLAKE2_H #define OPENSSL_HEADER_BLAKE2_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -27,9 +27,10 @@ extern "C" { struct blake2b_state_st { uint64_t h[8]; - uint64_t t_low, t_high; + uint64_t t_low; + uint32_t t_high; + uint32_t block_used; uint8_t block[BLAKE2B_CBLOCK]; - size_t block_used; }; // BLAKE2B256_Init initialises |b2b| to perform a BLAKE2b-256 hash. There are no diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h index b5a165860..87fc5f7f0 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h @@ -916,16 +916,6 @@ struct bignum_st { int flags; }; -struct bn_mont_ctx_st { - // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. It - // is guaranteed to have the same width as |N|. - BIGNUM RR; - // N is the modulus. It is always stored in minimal form, so |N.width| - // determines R. - BIGNUM N; - BN_ULONG n0[2]; // least significant words of (R*Ri-1)/N -}; - OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); #define BN_FLG_MALLOCED 0x01 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h index 8b97b726b..bda146a92 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h @@ -165,8 +165,12 @@ #define ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_sign_ctx) #define ASN1_item_unpack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_unpack) #define ASN1_item_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_verify) +#define asn1_marshal_any BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_any) #define asn1_marshal_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_bit_string) #define asn1_marshal_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_integer) +#define asn1_marshal_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_object) +#define asn1_marshal_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_octet_string) +#define asn1_marshal_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_time) #define ASN1_mbstring_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_copy) #define ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) #define ASN1_NULL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_NULL_free) @@ -183,6 +187,20 @@ #define ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) #define ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) #define ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define asn1_parse_any BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_any) +#define asn1_parse_any_as_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_any_as_string) +#define asn1_parse_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bit_string) +#define asn1_parse_bit_string_with_bad_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bit_string_with_bad_length) +#define asn1_parse_bmp_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bmp_string) +#define asn1_parse_enumerated BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_enumerated) +#define asn1_parse_generalized_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_generalized_time) +#define asn1_parse_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_integer) +#define asn1_parse_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_object) +#define asn1_parse_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_octet_string) +#define asn1_parse_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_time) +#define asn1_parse_universal_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_universal_string) +#define asn1_parse_utc_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_utc_time) +#define asn1_parse_utf8_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_utf8_string) #define ASN1_primitive_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_primitive_free) #define ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) #define ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) @@ -193,6 +211,7 @@ #define asn1_refcount_set_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_set_one) #define ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define asn1_set_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define asn1_string_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_string_cleanup) #define ASN1_STRING_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_cmp) #define ASN1_STRING_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_copy) #define ASN1_STRING_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_data) @@ -200,6 +219,7 @@ #define ASN1_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_free) #define ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) #define ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define asn1_string_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_string_init) #define ASN1_STRING_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_length) #define ASN1_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_new) #define ASN1_STRING_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_print) @@ -280,6 +300,26 @@ #define bcm_as_approved_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bcm_as_approved_status) #define bcm_as_not_approved_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bcm_as_not_approved_status) #define BCM_fips_186_2_prf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_fips_186_2_prf) +#define BCM_mldsa44_check_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_check_key_fips) +#define BCM_mldsa44_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key) +#define BCM_mldsa44_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy) +#define BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy_fips) +#define BCM_mldsa44_generate_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_fips) +#define BCM_mldsa44_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_marshal_private_key) +#define BCM_mldsa44_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_marshal_public_key) +#define BCM_mldsa44_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_parse_private_key) +#define BCM_mldsa44_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_parse_public_key) +#define BCM_mldsa44_prehash_finalize BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_finalize) +#define BCM_mldsa44_prehash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_init) +#define BCM_mldsa44_prehash_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_update) +#define BCM_mldsa44_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed) +#define BCM_mldsa44_private_key_from_seed_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed_fips) +#define BCM_mldsa44_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_public_from_private) +#define BCM_mldsa44_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign) +#define BCM_mldsa44_sign_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign_internal) +#define BCM_mldsa44_sign_message_representative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign_message_representative) +#define BCM_mldsa44_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_verify) +#define BCM_mldsa44_verify_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_verify_internal) #define BCM_mldsa65_check_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_check_key_fips) #define BCM_mldsa65_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_generate_key) #define BCM_mldsa65_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_generate_key_external_entropy) @@ -630,9 +670,9 @@ #define bn_mul_comba4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba4) #define bn_mul_comba8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba8) #define bn_mul_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_consttime) -#define bn_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont) #define bn_mul_mont_gather5_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_gather5_nohw) #define bn_mul_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_nohw) +#define bn_mul_mont_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_words) #define bn_mul_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_small) #define BN_mul_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mul_word) #define bn_mul_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_words) @@ -880,6 +920,7 @@ #define CMS_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMS_sign) #define CONF_modules_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_free) #define CONF_modules_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_load_file) +#define CONF_modules_unload BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_unload) #define CONF_parse_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_parse_list) #define CONF_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_VALUE_new) #define CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) @@ -1014,7 +1055,9 @@ #define CTR_DRBG_generate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_generate) #define CTR_DRBG_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_init) #define CTR_DRBG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_new) +#define CTR_DRBG_new_df BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_new_df) #define CTR_DRBG_reseed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define CTR_DRBG_reseed_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_reseed_ex) #define d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) #define d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) #define d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) @@ -1105,7 +1148,6 @@ #define d2i_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_AUX) #define d2i_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_bio) #define d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) -#define d2i_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CINF) #define d2i_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL) #define d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_bio) #define d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_fp) @@ -1121,7 +1163,6 @@ #define d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) #define d2i_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REVOKED) #define d2i_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_SIG) -#define d2i_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_VAL) #define DES_decrypt3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_decrypt3) #define DES_ecb_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb_encrypt) #define DES_ecb_encrypt_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb_encrypt_ex) @@ -1329,8 +1370,11 @@ #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_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_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_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) @@ -1465,6 +1509,7 @@ #define ED25519_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_verify) #define EDIPARTYNAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_free) #define EDIPARTYNAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define ENGINE_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_cleanup) #define ENGINE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_free) #define ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) #define ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_RSA_method) @@ -1477,6 +1522,7 @@ #define ERR_add_error_dataf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_dataf) #define ERR_clear_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_error) #define ERR_clear_system_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_system_error) +#define ERR_equals BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_equals) #define ERR_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string) #define ERR_error_string_n BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string_n) #define ERR_free_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_free_strings) @@ -1703,6 +1749,7 @@ #define EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) #define EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_p256_hkdf_sha256) #define EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define EVP_hpke_xwing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_xwing) #define EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) #define EVP_marshal_digest_algorithm_no_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm_no_params) #define EVP_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_private_key) @@ -1734,6 +1781,7 @@ #define EVP_md5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5) #define EVP_md5_sha1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5_sha1) #define EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define EVP_parse_digest_algorithm_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_digest_algorithm_nid) #define EVP_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_private_key) #define EVP_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_public_key) #define EVP_PBE_scrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PBE_scrypt) @@ -1786,9 +1834,21 @@ #define EVP_PKEY_derive BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive) #define EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_init) #define EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define EVP_pkey_dsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_dsa) +#define EVP_pkey_ec_p224 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p224) +#define EVP_pkey_ec_p256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p256) +#define EVP_pkey_ec_p384 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p384) +#define EVP_pkey_ec_p521 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p521) +#define EVP_pkey_ed25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ed25519) #define EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt) #define EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) #define EVP_PKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_free) +#define EVP_PKEY_from_private_key_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_private_key_info) +#define EVP_PKEY_from_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_raw_private_key) +#define EVP_PKEY_from_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_raw_public_key) +#define EVP_PKEY_from_subject_public_key_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_subject_public_key_info) +#define EVP_PKEY_get_ec_curve_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_ec_curve_nid) +#define EVP_PKEY_get_ec_point_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_ec_point_conv_form) #define EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) #define EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) #define EVP_PKEY_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0) @@ -1814,8 +1874,10 @@ #define EVP_PKEY_print_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_params) #define EVP_PKEY_print_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_private) #define EVP_PKEY_print_public BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_public) -#define evp_pkey_set_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_set_method) +#define EVP_pkey_rsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_rsa) +#define EVP_pkey_rsa_pss_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_rsa_pss_sha256) #define EVP_PKEY_set_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define evp_pkey_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_set0) #define EVP_PKEY_set1_DH BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_DH) #define EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) #define EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) @@ -1830,6 +1892,7 @@ #define EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_init) #define EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) #define EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define EVP_pkey_x25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_x25519) #define EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) #define EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_40_cbc) #define EVP_rc2_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_cbc) @@ -1866,6 +1929,8 @@ #define FIPS_module_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_module_name) #define FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_query_algorithm_status) #define FIPS_read_counter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_read_counter) +#define FIPS_service_indicator_after_call BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_service_indicator_after_call) +#define FIPS_service_indicator_before_call BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_service_indicator_before_call) #define FIPS_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_version) #define gcm_ghash_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_avx) #define gcm_ghash_clmul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_clmul) @@ -2041,7 +2106,6 @@ #define i2d_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_AUX) #define i2d_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_bio) #define i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) -#define i2d_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CINF) #define i2d_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL) #define i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_bio) #define i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_fp) @@ -2059,7 +2123,6 @@ #define i2d_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REVOKED) #define i2d_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_SIG) #define i2d_X509_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_tbs) -#define i2d_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_VAL) #define i2o_ECPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2o_ECPublicKey) #define i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) #define i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) @@ -2123,6 +2186,17 @@ #define MD5_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Update) #define METHOD_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_ref) #define METHOD_unref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_unref) +#define MLDSA44_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_generate_key) +#define MLDSA44_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_marshal_public_key) +#define MLDSA44_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_parse_public_key) +#define MLDSA44_prehash_finalize BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_finalize) +#define MLDSA44_prehash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_init) +#define MLDSA44_prehash_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_update) +#define MLDSA44_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_private_key_from_seed) +#define MLDSA44_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_public_from_private) +#define MLDSA44_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_sign) +#define MLDSA44_sign_message_representative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_sign_message_representative) +#define MLDSA44_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_verify) #define MLDSA65_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_generate_key) #define MLDSA65_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_marshal_public_key) #define MLDSA65_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_parse_public_key) @@ -2520,6 +2594,7 @@ #define rsa_invalidate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_invalidate_key) #define RSA_is_opaque BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_is_opaque) #define RSA_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define rsa_marshal_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_marshal_pss_params) #define RSA_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_public_key) #define RSA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new) #define RSA_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new_method) @@ -2537,6 +2612,7 @@ #define RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) #define RSA_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_private_key) +#define rsa_parse_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_parse_pss_params) #define RSA_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_public_key) #define rsa_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pkey_meth) #define RSA_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_print) @@ -2547,8 +2623,11 @@ #define rsa_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform) #define rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define rsa_pss_params_get_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_params_get_md) #define RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) #define RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define rsa_pss_sha256_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_sha256_asn1_meth) +#define rsa_pss_sha256_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_sha256_pkey_meth) #define RSA_public_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_decrypt) #define RSA_public_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_encrypt) #define RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -2998,10 +3077,13 @@ #define X509_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define X509_add1_reject_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_reject_object) #define X509_add1_trust_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_trust_object) +#define x509_algor_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_algor_cleanup) #define X509_ALGOR_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define X509_ALGOR_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_copy) #define X509_ALGOR_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_dup) #define X509_ALGOR_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_free) #define X509_ALGOR_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define x509_algor_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_algor_init) #define X509_ALGOR_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_it) #define X509_ALGOR_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_new) #define X509_ALGOR_set_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_set_md) @@ -3038,9 +3120,6 @@ #define X509_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_private_key) #define X509_check_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_purpose) #define X509_check_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_trust) -#define X509_CINF_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_free) -#define X509_CINF_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_it) -#define X509_CINF_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_new) #define X509_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp) #define X509_cmp_current_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_current_time) #define X509_cmp_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_time) @@ -3176,6 +3255,8 @@ #define X509_LOOKUP_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_load_file) #define x509_marshal_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_algorithm) #define x509_marshal_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_name) +#define x509_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_public_key) +#define x509_marshal_tbs_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_tbs_cert) #define X509_NAME_add_entry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry) #define X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) #define X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) @@ -3219,23 +3300,29 @@ #define X509_OBJECT_get_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get_type) #define X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) #define X509_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_new) +#define x509_parse_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_parse_algorithm) #define X509_parse_from_buffer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define x509_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_parse_public_key) +#define X509_parse_with_algorithms BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_with_algorithms) #define X509_policy_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_check) #define X509_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print) #define X509_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex) #define X509_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex_fp) #define X509_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_fp) #define x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define x509_pubkey_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_cleanup) #define X509_pubkey_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_pubkey_digest) #define X509_PUBKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_free) #define X509_PUBKEY_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get) #define X509_PUBKEY_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0) #define X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) #define X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define x509_pubkey_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_init) #define X509_PUBKEY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_it) #define X509_PUBKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_new) #define X509_PUBKEY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set) #define X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define x509_pubkey_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_set1) #define X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) #define X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_id) #define X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) @@ -3319,6 +3406,7 @@ #define X509_SIG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_new) #define X509_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign) #define X509_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign_ctx) +#define x509_sign_to_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_sign_to_bit_string) #define X509_signature_dump BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_dump) #define X509_signature_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_print) #define X509_STORE_add_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_add_cert) @@ -3383,9 +3471,6 @@ #define X509_time_adj_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_time_adj_ex) #define X509_trust_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_trust_clear) #define X509_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_up_ref) -#define X509_VAL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_free) -#define X509_VAL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_it) -#define X509_VAL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_new) #define X509_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify) #define X509_verify_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert) #define X509_verify_cert_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert_error_string) @@ -3411,6 +3496,7 @@ #define X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) #define X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) #define X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define x509_verify_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_verify_signature) #define x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define X509v3_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_add_ext) #define X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_standard_extensions) @@ -4373,3 +4459,5 @@ #define lh_CRYPTO_BUFFER_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_doall_arg) #define lh_CRYPTO_BUFFER_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall) #define lh_CRYPTO_BUFFER_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall_arg) +#define bignum_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bignum_ctx) +#define evp_pkey_ctx_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_ctx_st) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h index 8fc7f8451..b23a01e7c 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h @@ -170,8 +170,12 @@ #define _ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_sign_ctx) #define _ASN1_item_unpack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_unpack) #define _ASN1_item_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_verify) +#define _asn1_marshal_any BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_any) #define _asn1_marshal_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_bit_string) #define _asn1_marshal_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_integer) +#define _asn1_marshal_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_object) +#define _asn1_marshal_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_octet_string) +#define _asn1_marshal_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_time) #define _ASN1_mbstring_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_copy) #define _ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) #define _ASN1_NULL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_NULL_free) @@ -188,6 +192,20 @@ #define _ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) #define _ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) #define _ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define _asn1_parse_any BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_any) +#define _asn1_parse_any_as_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_any_as_string) +#define _asn1_parse_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bit_string) +#define _asn1_parse_bit_string_with_bad_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bit_string_with_bad_length) +#define _asn1_parse_bmp_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bmp_string) +#define _asn1_parse_enumerated BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_enumerated) +#define _asn1_parse_generalized_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_generalized_time) +#define _asn1_parse_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_integer) +#define _asn1_parse_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_object) +#define _asn1_parse_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_octet_string) +#define _asn1_parse_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_time) +#define _asn1_parse_universal_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_universal_string) +#define _asn1_parse_utc_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_utc_time) +#define _asn1_parse_utf8_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_utf8_string) #define _ASN1_primitive_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_primitive_free) #define _ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) #define _ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) @@ -198,6 +216,7 @@ #define _asn1_refcount_set_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_set_one) #define _ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define _asn1_set_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define _asn1_string_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_string_cleanup) #define _ASN1_STRING_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_cmp) #define _ASN1_STRING_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_copy) #define _ASN1_STRING_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_data) @@ -205,6 +224,7 @@ #define _ASN1_STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_free) #define _ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) #define _ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define _asn1_string_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_string_init) #define _ASN1_STRING_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_length) #define _ASN1_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_new) #define _ASN1_STRING_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_print) @@ -285,6 +305,26 @@ #define _bcm_as_approved_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bcm_as_approved_status) #define _bcm_as_not_approved_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bcm_as_not_approved_status) #define _BCM_fips_186_2_prf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_fips_186_2_prf) +#define _BCM_mldsa44_check_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_check_key_fips) +#define _BCM_mldsa44_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key) +#define _BCM_mldsa44_generate_key_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy) +#define _BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy_fips) +#define _BCM_mldsa44_generate_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_fips) +#define _BCM_mldsa44_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_marshal_private_key) +#define _BCM_mldsa44_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_marshal_public_key) +#define _BCM_mldsa44_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_parse_private_key) +#define _BCM_mldsa44_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_parse_public_key) +#define _BCM_mldsa44_prehash_finalize BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_finalize) +#define _BCM_mldsa44_prehash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_init) +#define _BCM_mldsa44_prehash_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_update) +#define _BCM_mldsa44_private_key_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed) +#define _BCM_mldsa44_private_key_from_seed_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed_fips) +#define _BCM_mldsa44_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_public_from_private) +#define _BCM_mldsa44_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign) +#define _BCM_mldsa44_sign_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign_internal) +#define _BCM_mldsa44_sign_message_representative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign_message_representative) +#define _BCM_mldsa44_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_verify) +#define _BCM_mldsa44_verify_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_verify_internal) #define _BCM_mldsa65_check_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_check_key_fips) #define _BCM_mldsa65_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_generate_key) #define _BCM_mldsa65_generate_key_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_generate_key_external_entropy) @@ -635,9 +675,9 @@ #define _bn_mul_comba4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba4) #define _bn_mul_comba8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba8) #define _bn_mul_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_consttime) -#define _bn_mul_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont) #define _bn_mul_mont_gather5_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_gather5_nohw) #define _bn_mul_mont_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_nohw) +#define _bn_mul_mont_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_words) #define _bn_mul_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_small) #define _BN_mul_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mul_word) #define _bn_mul_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_words) @@ -885,6 +925,7 @@ #define _CMS_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMS_sign) #define _CONF_modules_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_free) #define _CONF_modules_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_load_file) +#define _CONF_modules_unload BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_unload) #define _CONF_parse_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_parse_list) #define _CONF_VALUE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_VALUE_new) #define _CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) @@ -1019,7 +1060,9 @@ #define _CTR_DRBG_generate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_generate) #define _CTR_DRBG_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_init) #define _CTR_DRBG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_new) +#define _CTR_DRBG_new_df BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_new_df) #define _CTR_DRBG_reseed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define _CTR_DRBG_reseed_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_reseed_ex) #define _d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) #define _d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) #define _d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) @@ -1110,7 +1153,6 @@ #define _d2i_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_AUX) #define _d2i_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_bio) #define _d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) -#define _d2i_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CINF) #define _d2i_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL) #define _d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_bio) #define _d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_fp) @@ -1126,7 +1168,6 @@ #define _d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) #define _d2i_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REVOKED) #define _d2i_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_SIG) -#define _d2i_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_VAL) #define _DES_decrypt3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_decrypt3) #define _DES_ecb_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb_encrypt) #define _DES_ecb_encrypt_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb_encrypt_ex) @@ -1334,8 +1375,11 @@ #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_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_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_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) @@ -1470,6 +1514,7 @@ #define _ED25519_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_verify) #define _EDIPARTYNAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_free) #define _EDIPARTYNAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define _ENGINE_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_cleanup) #define _ENGINE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_free) #define _ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) #define _ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_RSA_method) @@ -1482,6 +1527,7 @@ #define _ERR_add_error_dataf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_dataf) #define _ERR_clear_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_error) #define _ERR_clear_system_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_system_error) +#define _ERR_equals BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_equals) #define _ERR_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string) #define _ERR_error_string_n BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string_n) #define _ERR_free_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_free_strings) @@ -1708,6 +1754,7 @@ #define _EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) #define _EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_p256_hkdf_sha256) #define _EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define _EVP_hpke_xwing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_xwing) #define _EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) #define _EVP_marshal_digest_algorithm_no_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm_no_params) #define _EVP_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_private_key) @@ -1739,6 +1786,7 @@ #define _EVP_md5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5) #define _EVP_md5_sha1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5_sha1) #define _EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define _EVP_parse_digest_algorithm_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_digest_algorithm_nid) #define _EVP_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_private_key) #define _EVP_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_public_key) #define _EVP_PBE_scrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PBE_scrypt) @@ -1791,9 +1839,21 @@ #define _EVP_PKEY_derive BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive) #define _EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_init) #define _EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define _EVP_pkey_dsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_dsa) +#define _EVP_pkey_ec_p224 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p224) +#define _EVP_pkey_ec_p256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p256) +#define _EVP_pkey_ec_p384 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p384) +#define _EVP_pkey_ec_p521 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p521) +#define _EVP_pkey_ed25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ed25519) #define _EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt) #define _EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) #define _EVP_PKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_free) +#define _EVP_PKEY_from_private_key_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_private_key_info) +#define _EVP_PKEY_from_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_raw_private_key) +#define _EVP_PKEY_from_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_raw_public_key) +#define _EVP_PKEY_from_subject_public_key_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_subject_public_key_info) +#define _EVP_PKEY_get_ec_curve_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_ec_curve_nid) +#define _EVP_PKEY_get_ec_point_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_ec_point_conv_form) #define _EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) #define _EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) #define _EVP_PKEY_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0) @@ -1819,8 +1879,10 @@ #define _EVP_PKEY_print_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_params) #define _EVP_PKEY_print_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_private) #define _EVP_PKEY_print_public BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_public) -#define _evp_pkey_set_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, evp_pkey_set_method) +#define _EVP_pkey_rsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_rsa) +#define _EVP_pkey_rsa_pss_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_rsa_pss_sha256) #define _EVP_PKEY_set_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define _evp_pkey_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, evp_pkey_set0) #define _EVP_PKEY_set1_DH BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_DH) #define _EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) #define _EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) @@ -1835,6 +1897,7 @@ #define _EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_init) #define _EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) #define _EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define _EVP_pkey_x25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_x25519) #define _EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) #define _EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_40_cbc) #define _EVP_rc2_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_cbc) @@ -1871,6 +1934,8 @@ #define _FIPS_module_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_module_name) #define _FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_query_algorithm_status) #define _FIPS_read_counter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_read_counter) +#define _FIPS_service_indicator_after_call BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_service_indicator_after_call) +#define _FIPS_service_indicator_before_call BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_service_indicator_before_call) #define _FIPS_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_version) #define _gcm_ghash_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_avx) #define _gcm_ghash_clmul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_clmul) @@ -2046,7 +2111,6 @@ #define _i2d_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_AUX) #define _i2d_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_bio) #define _i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) -#define _i2d_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CINF) #define _i2d_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL) #define _i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_bio) #define _i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_fp) @@ -2064,7 +2128,6 @@ #define _i2d_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REVOKED) #define _i2d_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_SIG) #define _i2d_X509_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_tbs) -#define _i2d_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_VAL) #define _i2o_ECPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2o_ECPublicKey) #define _i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) #define _i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) @@ -2128,6 +2191,17 @@ #define _MD5_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Update) #define _METHOD_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_ref) #define _METHOD_unref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_unref) +#define _MLDSA44_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_generate_key) +#define _MLDSA44_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_marshal_public_key) +#define _MLDSA44_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_parse_public_key) +#define _MLDSA44_prehash_finalize BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_finalize) +#define _MLDSA44_prehash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_init) +#define _MLDSA44_prehash_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_update) +#define _MLDSA44_private_key_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_private_key_from_seed) +#define _MLDSA44_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_public_from_private) +#define _MLDSA44_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_sign) +#define _MLDSA44_sign_message_representative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_sign_message_representative) +#define _MLDSA44_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_verify) #define _MLDSA65_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_generate_key) #define _MLDSA65_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_marshal_public_key) #define _MLDSA65_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_parse_public_key) @@ -2525,6 +2599,7 @@ #define _rsa_invalidate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_invalidate_key) #define _RSA_is_opaque BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_is_opaque) #define _RSA_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define _rsa_marshal_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_marshal_pss_params) #define _RSA_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_public_key) #define _RSA_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new) #define _RSA_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new_method) @@ -2542,6 +2617,7 @@ #define _RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define _RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) #define _RSA_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_private_key) +#define _rsa_parse_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_parse_pss_params) #define _RSA_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_public_key) #define _rsa_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pkey_meth) #define _RSA_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_print) @@ -2552,8 +2628,11 @@ #define _rsa_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform) #define _rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define _RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define _rsa_pss_params_get_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_params_get_md) #define _RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) #define _RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define _rsa_pss_sha256_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_sha256_asn1_meth) +#define _rsa_pss_sha256_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_sha256_pkey_meth) #define _RSA_public_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_decrypt) #define _RSA_public_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_encrypt) #define _RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -3003,10 +3082,13 @@ #define _X509_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define _X509_add1_reject_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_reject_object) #define _X509_add1_trust_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_trust_object) +#define _x509_algor_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_algor_cleanup) #define _X509_ALGOR_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define _X509_ALGOR_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_copy) #define _X509_ALGOR_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_dup) #define _X509_ALGOR_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_free) #define _X509_ALGOR_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define _x509_algor_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_algor_init) #define _X509_ALGOR_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_it) #define _X509_ALGOR_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_new) #define _X509_ALGOR_set_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_set_md) @@ -3043,9 +3125,6 @@ #define _X509_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_private_key) #define _X509_check_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_purpose) #define _X509_check_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_trust) -#define _X509_CINF_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_free) -#define _X509_CINF_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_it) -#define _X509_CINF_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_new) #define _X509_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp) #define _X509_cmp_current_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_current_time) #define _X509_cmp_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_time) @@ -3181,6 +3260,8 @@ #define _X509_LOOKUP_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_load_file) #define _x509_marshal_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_algorithm) #define _x509_marshal_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_name) +#define _x509_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_public_key) +#define _x509_marshal_tbs_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_tbs_cert) #define _X509_NAME_add_entry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry) #define _X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) #define _X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) @@ -3224,23 +3305,29 @@ #define _X509_OBJECT_get_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get_type) #define _X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) #define _X509_OBJECT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_new) +#define _x509_parse_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_parse_algorithm) #define _X509_parse_from_buffer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define _x509_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_parse_public_key) +#define _X509_parse_with_algorithms BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_with_algorithms) #define _X509_policy_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_check) #define _X509_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print) #define _X509_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex) #define _X509_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex_fp) #define _X509_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_fp) #define _x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define _x509_pubkey_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_cleanup) #define _X509_pubkey_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_pubkey_digest) #define _X509_PUBKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_free) #define _X509_PUBKEY_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get) #define _X509_PUBKEY_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0) #define _X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) #define _X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define _x509_pubkey_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_init) #define _X509_PUBKEY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_it) #define _X509_PUBKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_new) #define _X509_PUBKEY_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set) #define _X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define _x509_pubkey_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_set1) #define _X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) #define _X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_id) #define _X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) @@ -3324,6 +3411,7 @@ #define _X509_SIG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_new) #define _X509_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign) #define _X509_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign_ctx) +#define _x509_sign_to_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_sign_to_bit_string) #define _X509_signature_dump BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_dump) #define _X509_signature_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_print) #define _X509_STORE_add_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_add_cert) @@ -3388,9 +3476,6 @@ #define _X509_time_adj_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_time_adj_ex) #define _X509_trust_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_trust_clear) #define _X509_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_up_ref) -#define _X509_VAL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_free) -#define _X509_VAL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_it) -#define _X509_VAL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_new) #define _X509_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify) #define _X509_verify_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert) #define _X509_verify_cert_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert_error_string) @@ -3416,6 +3501,7 @@ #define _X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) #define _X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) #define _X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define _x509_verify_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_verify_signature) #define _x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define _X509v3_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_add_ext) #define _X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_standard_extensions) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h index 3be4e1de6..c5f0af94f 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h @@ -96,6 +96,9 @@ OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, const char *appname, unsigned long flags); +// CONF_modules_unload does nothing. +OPENSSL_EXPORT void CONF_modules_unload(int all); + // CONF_modules_free does nothing. OPENSSL_EXPORT void CONF_modules_free(void); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h index 81a8a8a3c..f7931bd35 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_CRYPTO_H #define OPENSSL_HEADER_CRYPTO_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #include "CCryptoBoringSSL_sha.h" // Upstream OpenSSL defines |OPENSSL_malloc|, etc., in crypto.h rather than @@ -162,6 +162,9 @@ OPENSSL_EXPORT void ENGINE_load_builtin_engines(void); // ENGINE_register_all_complete returns one. OPENSSL_EXPORT int ENGINE_register_all_complete(void); +// ENGINE_cleanup does nothing. +OPENSSL_EXPORT void ENGINE_cleanup(void); + // OPENSSL_load_builtin_modules does nothing. OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); @@ -205,8 +208,7 @@ OPENSSL_EXPORT const uint8_t *FIPS_module_hash(void); // FIPS_version returns the version of the FIPS module, or zero if the build // isn't exactly at a verified version. The version, expressed in base 10, will -// be a date in the form yyyymmddXX where XX is often "00", but can be -// incremented if multiple versions are defined on a single day. +// be a date in the form yyyymmdd. // // (This format exceeds a |uint32_t| in the year 4294.) OPENSSL_EXPORT uint32_t FIPS_version(void); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h index fb3336d69..8aa56a983 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_CTRDRBG_H #define OPENSSL_HEADER_CTRDRBG_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -29,33 +29,67 @@ extern "C" { // // CTR_DRBG_STATE contains the state of a FIPS AES-CTR-based pseudo-random // number generator. If BoringSSL was built in FIPS mode then this is a FIPS -// Approved algorithm. +// Approved algorithm. BoringSSL supports CTR-DRBG both with, and without, a +// derivation function. -// CTR_DRBG_ENTROPY_LEN is the number of bytes of input entropy. See SP -// 800-90Ar1, table 3. +// CTR_DRBG_MIN_ENTROPY_LEN is the minimum number of bytes of input entropy +// when using a derivation function. See SP 800-90Ar1, table 3. +#define CTR_DRBG_MIN_ENTROPY_LEN 32 + +// CTR_DRBG_MAX_ENTROPY_LEN is the maximum number of bytes of input entropy +// when using a derivation function. This is an implementation limitation. +#define CTR_DRBG_MAX_ENTROPY_LEN 64 + +// CTR_DRBG_ENTROPY_LEN is a fixed amount of entropy required when not using a +// derivation function. #define CTR_DRBG_ENTROPY_LEN 48 +// The length of a seed, when using a derivation function. See SP 800-90Ar1, +// table 3. +#define CTR_DRBG_SEED_LEN (32 + CTR_DRBG_NONCE_LEN) + +// CTR_DRBG_NONCE_LEN is the number of bytes of input nonce. This only applies +// when using a derivation function. +#define CTR_DRBG_NONCE_LEN 16 + // CTR_DRBG_MAX_GENERATE_LENGTH is the maximum number of bytes that can be // generated in a single call to |CTR_DRBG_generate|. #define CTR_DRBG_MAX_GENERATE_LENGTH 65536 // CTR_DRBG_new returns an initialized |CTR_DRBG_STATE|, or NULL if either -// allocation failed or if |personalization_len| is invalid. +// allocation failed or if |personalization_len| is invalid. This DRBG will not +// use a derivation function. OPENSSL_EXPORT CTR_DRBG_STATE *CTR_DRBG_new( const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, size_t personalization_len); +// CTR_DRBG_new_df returns an initialized |CTR_DRBG_STATE|, or NULL if either +// allocation failed or if an argument is invalid. This DRBG will use a +// derivation function. +OPENSSL_EXPORT CTR_DRBG_STATE *CTR_DRBG_new_df( + const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, + size_t personalization_len); + // CTR_DRBG_free frees |state| if non-NULL, or else does nothing. -OPENSSL_EXPORT void CTR_DRBG_free(CTR_DRBG_STATE* state); +OPENSSL_EXPORT void CTR_DRBG_free(CTR_DRBG_STATE *state); // CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy -// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// in |entropy| and, optionally, up to |CTR_DRBG_SEED_LEN| bytes of // additional data. It returns one on success or zero on error. OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *additional_data, size_t additional_data_len); +// CTR_DRBG_reseed_ex acts like `CTR_DRBG_reseed` but with variable-length +// entropy input, up to |CTR_DRBG_MAX_ENTROPY_LEN|. +OPENSSL_EXPORT int CTR_DRBG_reseed_ex(CTR_DRBG_STATE *drbg, + const uint8_t *entropy, + size_t entropy_len, + const uint8_t *additional_data, + size_t additional_data_len); + // CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional // data (if any) and then writes |out_len| random bytes to |out|, where // |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h index f7db3d8e9..ce6057ed6 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h @@ -54,7 +54,7 @@ OPENSSL_EXPORT int DH_up_ref(DH *dh); // OPENSSL_DH_MAX_MODULUS_BITS is the maximum supported Diffie-Hellman group // modulus, in bits. -#define OPENSSL_DH_MAX_MODULUS_BITS 10000 +#define OPENSSL_DH_MAX_MODULUS_BITS 8192 // DH_bits returns the size of |dh|'s group modulus, in bits. OPENSSL_EXPORT unsigned DH_bits(const DH *dh); @@ -111,32 +111,38 @@ OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void); // BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); // BN_get_rfc3526_prime_2048 sets |*ret| to the 2048-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret); // BN_get_rfc3526_prime_3072 sets |*ret| to the 3072-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret); // BN_get_rfc3526_prime_4096 sets |*ret| to the 4096-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret); // BN_get_rfc3526_prime_6144 sets |*ret| to the 6144-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret); // BN_get_rfc3526_prime_8192 sets |*ret| to the 8192-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h index 7fb79e1a6..179f92a7d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h @@ -213,6 +213,11 @@ OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx); // returns the digest function or NULL on error. OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); +// EVP_parse_digest_algorithm_nid behaves like |EVP_parse_digest_algorithm| +// except it returns |NID_undef| on error and some other value on success. This +// may be used to avoid depending on every digest algorithm in the library. +OPENSSL_EXPORT int EVP_parse_digest_algorithm_nid(CBS *cbs); + // EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier // structure and appends the result to |cbb|. It returns one on success and zero // on error. It sets the parameters field to NULL. Use @@ -283,17 +288,27 @@ OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); OPENSSL_EXPORT int EVP_MD_nid(const EVP_MD *md); +// Internal constants and structures (hidden). + struct evp_md_pctx_ops; +// EVP_MAX_MD_DATA_SIZE is a private constant which specifies the size of the +// largest digest state. SHA-512 and BLAKE2b are joint-largest. Consuming code +// only uses this via the `EVP_MD_CTX` type. +#define EVP_MAX_MD_DATA_SIZE 208 + // env_md_ctx_st is typoed ("evp" -> "env"), but the typo comes from OpenSSL // and some consumers forward-declare these structures so we're leaving it // alone. struct env_md_ctx_st { + // md_data contains the hash-specific context. + union { + uint8_t md_data[EVP_MAX_MD_DATA_SIZE]; + uint64_t alignment; + }; + // digest is the underlying digest function, or NULL if not set. const EVP_MD *digest; - // md_data points to a block of memory that contains the hash-specific - // context. - void *md_data; // pctx is an opaque (at this layer) pointer to additional context that // EVP_PKEY functions may store in this object. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h index e7e0e3b7a..07c716975 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h @@ -56,7 +56,7 @@ OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); // OPENSSL_DSA_MAX_MODULUS_BITS is the maximum supported DSA group modulus, in // bits. -#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#define OPENSSL_DSA_MAX_MODULUS_BITS 8192 // DSA_bits returns the size of |dsa|'s group modulus, in bits. OPENSSL_EXPORT unsigned DSA_bits(const DSA *dsa); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h index e1f997101..e43aefd97 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h @@ -107,8 +107,8 @@ OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); // EC_GROUP_order_bits returns the number of bits of the order of |group|. OPENSSL_EXPORT int EC_GROUP_order_bits(const EC_GROUP *group); -// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using -// |ctx|, if it's not NULL. It returns one on success and zero otherwise. +// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group|. It returns +// one on success and zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); @@ -116,7 +116,7 @@ OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, // |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to // the parameters of the curve when expressed as y² = x³ + ax + b. Any of the // output parameters can be NULL. It returns one on success and zero on -// error. +// error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, BIGNUM *out_b, BN_CTX *ctx); @@ -169,12 +169,12 @@ OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group, // EC_POINT_is_on_curve returns one if |point| is an element of |group| and // and zero otherwise or when an error occurs. This is different from OpenSSL, -// which returns -1 on error. If |ctx| is non-NULL, it may be used. +// which returns -1 on error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); // EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if -// not equal and -1 on error. If |ctx| is not NULL, it may be used. +// not equal and -1 on error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); @@ -182,8 +182,8 @@ OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, // Point conversion. // EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of -// |point| using |ctx|, if it's not NULL. It returns one on success and zero -// otherwise. +// |point|. It returns one on success and zero otherwise. |ctx| is ignored and +// may be NULL. // // Either |x| or |y| may be NULL to skip computing that coordinate. This is // slightly faster in the common case where only the x-coordinate is needed. @@ -200,9 +200,8 @@ OPENSSL_EXPORT int EC_POINT_get_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx); // EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be -// (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one -// on success or zero on error. It's considered an error if the point is not on -// the curve. +// (|x|, |y|). |ctx| is ignored and may be NULL. It returns one on success or +// zero on error. It's considered an error if the point is not on the curve. // // Note that the corresponding function in OpenSSL versions prior to 1.0.2s does // not check if the point is on the curve. This is a security-critical check, so @@ -226,7 +225,7 @@ OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, // EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| // 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. +// needed. |ctx| is ignored and may be NULL. OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, @@ -236,30 +235,31 @@ OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, // 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. +// |*out_buf| with |OPENSSL_free| when done. |ctx| is ignored and may be NULL. 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. +// serialised point to |cbb|. It returns one on success and zero on error. |ctx| +// is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, BN_CTX *ctx); // EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format -// serialisation in |buf|. It returns one on success and zero on error. The -// |ctx| argument may be used if not NULL. It's considered an error if |buf| -// does not represent a point on the curve. +// serialisation in |buf|. It returns one on success and zero on error. |ctx| +// may be NULL. It's considered an error if |buf| does not represent a point on +// the curve. OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, const uint8_t *buf, size_t len, BN_CTX *ctx); // EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with // the given |x| coordinate and the y coordinate specified by |y_bit| (see -// X9.62). It returns one on success and zero otherwise. +// X9.62). It returns one on success and zero otherwise. |ctx| may be NULL. OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, BN_CTX *ctx); @@ -268,23 +268,23 @@ OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( // Group operations. // EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); // EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx); // EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); // EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero -// otherwise. If |ctx| is not NULL, it may be used. +// otherwise. |ctx| may be NULL. OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); @@ -368,8 +368,8 @@ OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group, const BIGNUM *cofactor); // EC_GROUP_get_order sets |*order| to the order of |group|, if it's not -// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use -// |EC_GROUP_get0_order| instead. +// NULL. It returns one on success and zero otherwise. |ctx| is ignored and may +// be NULL. Use |EC_GROUP_get0_order| instead. OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h index 8dc963143..45a1c2216 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h @@ -130,12 +130,12 @@ OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, // 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. +// zero. |ctx| may be NULL. 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|. +// public key in |key|. |ctx| is ignored and may be NULL. OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, uint8_t **out_buf, BN_CTX *ctx); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h index b58ba1c4e..26d802b93 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h @@ -80,6 +80,13 @@ OPENSSL_INLINE int ERR_GET_REASON(uint32_t packed_error) { return (int)(packed_error & 0xfff); } +// ERR_equals returns one if |packed_error|'s library and reason code are |lib| +// and |reason|, respectively, and zero otherwise. +OPENSSL_INLINE int ERR_equals(uint32_t packed_error, int lib, int reason) { + return ERR_GET_LIB(packed_error) == lib && + ERR_GET_REASON(packed_error) == reason; +} + // ERR_get_error gets the packed error code for the least recent error and // removes that error from the queue. If there are no errors in the queue then // it returns zero. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h index 115185a64..48ebc93dd 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h @@ -21,8 +21,6 @@ // OpenSSL included digest and cipher functions in this header so we include // them for users that still expect that. -// -// TODO(fork): clean up callers so that they include what they use. #include "CCryptoBoringSSL_aead.h" #include "CCryptoBoringSSL_base64.h" #include "CCryptoBoringSSL_cipher.h" @@ -37,7 +35,7 @@ extern "C" { // EVP abstracts over public/private key algorithms. -// Public key objects. +// Public/private key objects. // // An |EVP_PKEY| object represents a public or private key. A given object may // be used concurrently on multiple threads by non-mutating functions, provided @@ -78,6 +76,13 @@ OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); // parameters or zero if not, or if the algorithm doesn't take parameters. OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns +// one if they match, zero if not, or a negative number on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, + const EVP_PKEY *b); + // EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by // |pkey|. For an RSA key, this returns the number of bytes needed to represent // the modulus. For an EC key, this returns the maximum size of a DER-encoded @@ -89,14 +94,125 @@ OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey); // length of the group order. OPENSSL_EXPORT int EVP_PKEY_bits(const EVP_PKEY *pkey); +// The following constants are returned by |EVP_PKEY_id| and specify the type of +// key. +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA_PSS NID_rsassaPss +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_ED25519 NID_ED25519 +#define EVP_PKEY_X25519 NID_X25519 +#define EVP_PKEY_HKDF NID_hkdf +#define EVP_PKEY_DH NID_dhKeyAgreement + // EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*| -// values. +// values above. These type values generally corresond to the algorithm OID, but +// not the parameters, of a SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo +// (RFC 5208) AlgorithmIdentifier. Algorithm parameters can be inspected with +// algorithm-specific accessors, e.g. |EVP_PKEY_get_ec_curve_nid|. OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); -// Getting and setting concrete public key types. -// -// The following functions get and set the underlying public key in an +// Algorithms. +// +// An |EVP_PKEY| may carry a key from one of several algorithms, represented by +// |EVP_PKEY_ALG|. |EVP_PKEY_ALG|s are used by functions that construct +// |EVP_PKEY|s, such as parsing, so that callers can specify the algorithm(s) to +// use. +// +// Each |EVP_PKEY_ALG| generally corresponds to the AlgorithmIdentifier of a +// SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo (RFC 5208), but some may +// support multiple sets of AlgorithmIdentifier parameters, while others may be +// specific to one parameter. + +// EVP_pkey_rsa implements RSA keys (RFC 8017), encoded as rsaEncryption (RFC +// 3279, Section 2.3.1). The rsaEncryption encoding is confusingly named: these +// keys are used for all RSA operations, including signing. The |EVP_PKEY_id| +// value is |EVP_PKEY_RSA|. +// +// WARNING: This |EVP_PKEY_ALG| accepts all RSA key sizes supported by +// BoringSSL. When parsing RSA keys, callers should check the size is within +// their desired bounds with |EVP_PKEY_bits|. RSA public key operations scale +// quadratically and RSA private key operations scale cubicly, so key sizes may +// be a DoS vector. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_rsa(void); + +// EVP_pkey_ec_* implement EC keys, encoded as id-ecPublicKey (RFC 5480, +// Section 2.1.1). The id-ecPublicKey encoding is confusingly named: it is also +// used for private keys (RFC 5915). The |EVP_PKEY_id| value is |EVP_PKEY_EC|. +// +// Each function only supports the specified curve, but curves are not reflected +// in |EVP_PKEY_id|. The curve can be inspected with +// |EVP_PKEY_get_ec_curve_nid|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p224(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p256(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p384(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p521(void); + +// EVP_pkey_x25519 implements X25519 keys (RFC 7748), encoded as in RFC 8410. +// The |EVP_PKEY_id| value is |EVP_PKEY_X25519|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_x25519(void); + +// EVP_pkey_ed25519 implements Ed25519 keys (RFC 8032), encoded as in RFC 8410. +// The |EVP_PKEY_id| value is |EVP_PKEY_ED25519|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ed25519(void); + +// EVP_pkey_dsa implements DSA keys, encoded as in RFC 3279, Section 2.3.2. The +// |EVP_PKEY_id| value is |EVP_PKEY_DSA|. This |EVP_PKEY_ALG| accepts all DSA +// parameters supported by BoringSSL. +// +// Keys of this type are not usable with any operations, though the underlying +// |DSA| object can be extracted with |EVP_PKEY_get0_DSA|. This key type is +// deprecated and only implemented for compatibility with legacy applications. +// +// TODO(crbug.com/42290364): We didn't wire up |EVP_PKEY_sign| and +// |EVP_PKEY_verify| just so it was auditable which callers used DSA. Once DSA +// is removed from the default SPKI and PKCS#8 parser and DSA users explicitly +// request |EVP_pkey_dsa|, we could change that. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_dsa(void); + +// EVP_pkey_rsa_pss_sha256 implements RSASSA-PSS keys, encoded as id-RSASSA-PSS +// (RFC 4055, Section 3.1). The |EVP_PKEY_id| value is |EVP_PKEY_RSA_PSS|. This +// |EVP_PKEY_ALG| only accepts keys whose parameters specify: +// +// - A hashAlgorithm of SHA-256 +// - A maskGenAlgorithm of MGF1 with SHA-256 +// - A minimum saltLength of 32 +// - A trailerField of one (must be omitted in the encoding) +// +// Keys of this type will only be usable with RSASSA-PSS with matching signature +// parameters. +// +// This algorithm type is not recommended. The id-RSASSA-PSS key type is not +// widely implemented. Using it negates any compatibility benefits of using RSA. +// More modern algorithms like ECDSA are more performant and more compatible +// than id-RSASSA-PSS keys. This key type also adds significant complexity to a +// system. It has a wide range of possible parameter sets, so any uses must +// ensure all components not only support id-RSASSA-PSS, but also the specific +// parameters chosen. +// +// Note the id-RSASSA-PSS key type is distinct from the RSASSA-PSS signature +// algorithm. The widely implemented id-rsaEncryption key type (|EVP_pkey_rsa| +// and |EVP_PKEY_RSA|) also supports RSASSA-PSS signatures. +// +// WARNING: Any |EVP_PKEY|s produced by this algorithm will return a non-NULL +// |RSA| object through |EVP_PKEY_get1_RSA| and |EVP_PKEY_get0_RSA|. This is +// dangerous as existing code may assume a non-NULL return implies the more +// common id-rsaEncryption key. Additionally, the operations on the underlying +// |RSA| object will not capture the RSA-PSS constraints, so callers risk +// misusing the key by calling these functions. Callers using this algorithm +// must use |EVP_PKEY_id| to distinguish |EVP_PKEY_RSA| and |EVP_PKEY_RSA_PSS|. +// +// WARNING: BoringSSL does not currently implement |RSA_get0_pss_params| with +// these keys. Callers that require this functionality should contact the +// BoringSSL team. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_rsa_pss_sha256(void); + + +// Getting and setting concrete key types. +// +// The following functions get and set the underlying key representation in an // |EVP_PKEY| object. The |set1| functions take an additional reference to the // underlying key and return one on success or zero if |key| is NULL. The // |assign| functions adopt the caller's reference and return one on success or @@ -108,6 +224,18 @@ OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); // non-mutating for thread-safety purposes, but mutating functions on the // returned lower-level objects are considered to also mutate the |EVP_PKEY| and // may not be called concurrently with other operations on the |EVP_PKEY|. +// +// WARNING: Matching OpenSSL, the RSA functions behave non-uniformly. +// |EVP_PKEY_set1_RSA| and |EVP_PKEY_assign_RSA| construct an |EVP_PKEY_RSA| +// key, while the |EVP_PKEY_get0_RSA| and |EVP_PKEY_get1_RSA| will return +// non-NULL for both |EVP_PKEY_RSA| and |EVP_PKEY_RSA_PSS|. +// +// This means callers risk misusing a key if they assume a non-NULL return from +// |EVP_PKEY_get0_RSA| or |EVP_PKEY_get1_RSA| implies |EVP_PKEY_RSA|. Prefer +// |EVP_PKEY_id| to check the type of a key. To reduce this risk, BoringSSL does +// not make |EVP_PKEY_RSA_PSS| available by default, only when callers opt in +// via |EVP_pkey_rsa_pss_sha256|. This differs from upstream OpenSSL, where +// callers are exposed to |EVP_PKEY_RSA_PSS| by default. OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); @@ -129,39 +257,36 @@ OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey); -#define EVP_PKEY_NONE NID_undef -#define EVP_PKEY_RSA NID_rsaEncryption -#define EVP_PKEY_RSA_PSS NID_rsassaPss -#define EVP_PKEY_DSA NID_dsa -#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey -#define EVP_PKEY_ED25519 NID_ED25519 -#define EVP_PKEY_X25519 NID_X25519 -#define EVP_PKEY_HKDF NID_hkdf -#define EVP_PKEY_DH NID_dhKeyAgreement - -// EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if -// successful or zero if the |type| argument is not one of the |EVP_PKEY_*| -// values. If |pkey| is NULL, it simply reports whether the type is known. -OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); - -// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns -// one if they match, zero if not, or a negative number of on error. -// -// WARNING: the return value differs from the usual return value convention. -OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, - const EVP_PKEY *b); - // ASN.1 functions +// EVP_PKEY_from_subject_public_key_info decodes a DER-encoded +// SubjectPublicKeyInfo structure (RFC 5280) from |in|. It returns a +// newly-allocated |EVP_PKEY| or NULL on error. Only the |num_algs| algorithms +// in |algs| will be considered when parsing. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_subject_public_key_info( + const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs, + size_t num_algs); + // EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure // (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated -// |EVP_PKEY| or NULL on error. If the key is an EC key, the curve is guaranteed -// to be set. +// |EVP_PKEY| or NULL on error. +// +// Prefer |EVP_PKEY_from_subject_public_key_info| instead. This function has +// several pitfalls: +// +// Callers are expected to handle trailing data retuned from |cbs|, making more +// common cases error-prone. // -// The caller must check the type of the parsed public key to ensure it is -// suitable and validate other desired key properties such as RSA modulus size -// or EC curve. +// There is also no way to pass in supported algorithms. This function instead +// supports some default set of algorithms. Future versions of BoringSSL may add +// to this list, based on the needs of the other callers. Conversely, some +// algorithms may be intentionally omitted, if they cause too much risk to +// existing callers. +// +// This means callers must check the type of the parsed public key to ensure it +// is suitable and validate other desired key properties such as RSA modulus +// size or EC curve. OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); // EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo @@ -169,19 +294,41 @@ OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); // success and zero on error. OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key); +// EVP_PKEY_from_private_key_info decodes a DER-encoded PrivateKeyInfo structure +// (RFC 5208) from |in|. It returns a newly-allocated |EVP_PKEY| or NULL on +// error. Only the |num_algs| algorithms in |algs| will be considered when +// parsing. +// +// A PrivateKeyInfo ends with an optional set of attributes. These are silently +// ignored. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_private_key_info( + const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs, + size_t num_algs); + // EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC // 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY| // or NULL on error. // -// The caller must check the type of the parsed private key to ensure it is -// suitable and validate other desired key properties such as RSA modulus size -// or EC curve. In particular, RSA private key operations scale cubicly, so +// Prefer |EVP_PKEY_from_private_key_info| instead. This function has +// several pitfalls: +// +// Callers are expected to handle trailing data retuned from |cbs|, making more +// common cases error-prone. +// +// There is also no way to pass in supported algorithms. This function instead +// supports some default set of algorithms. Future versions of BoringSSL may add +// to this list, based on the needs of the other callers. Conversely, some +// algorithms may be intentionally omitted, if they cause too much risk to +// existing callers. +// +// This means the caller must check the type of the parsed private key to ensure +// it is suitable and validate other desired key properties such as RSA modulus +// size or EC curve. In particular, RSA private key operations scale cubicly, so // applications accepting RSA private keys from external sources may need to // bound key sizes (use |EVP_PKEY_bits| or |RSA_bits|) to avoid a DoS vector. // -// A PrivateKeyInfo ends with an optional set of attributes. These are not -// processed and so this function will silently ignore any trailing data in the -// structure. +// A PrivateKeyInfo ends with an optional set of attributes. These are silently +// ignored. OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs); // EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo @@ -197,20 +344,18 @@ OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); // RFC 7748 and RFC 8032, respectively. Note the RFC 8032 private key format is // the 32-byte prefix of |ED25519_sign|'s 64-byte private key. -// EVP_PKEY_new_raw_private_key returns a newly allocated |EVP_PKEY| wrapping a -// private key of the specified type. It returns one on success and zero on -// error. -OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, +// EVP_PKEY_from_raw_private_key interprets |in| as a raw private key of type +// |alg| and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_raw_private_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, + size_t len); + +// EVP_PKEY_from_raw_public_key interprets |in| as a raw public key of type +// |alg| and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_raw_public_key(const EVP_PKEY_ALG *alg, const uint8_t *in, size_t len); -// EVP_PKEY_new_raw_public_key returns a newly allocated |EVP_PKEY| wrapping a -// public key of the specified type. It returns one on success and zero on -// error. -OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, - const uint8_t *in, - size_t len); - // EVP_PKEY_get_raw_private_key outputs the private key for |pkey| in raw form. // If |out| is NULL, it sets |*out_len| to the size of the raw private key. // Otherwise, it writes at most |*out_len| bytes to |out| and sets |*out_len| to @@ -468,10 +613,33 @@ OPENSSL_EXPORT int EVP_PBE_scrypt(const char *password, size_t password_len, size_t key_len); -// Public key contexts. +// Operations. +// +// |EVP_PKEY_CTX| objects hold the context for an operation (e.g. signing or +// encrypting) that uses an |EVP_PKEY|. They are used to configure +// algorithm-specific parameters for the operation before performing the +// operation. The general pattern for performing an operation in EVP is: +// +// 1. Construct an |EVP_PKEY_CTX|, either with |EVP_PKEY_CTX_new| (operations +// using a key, like signing) or |EVP_PKEY_CTX_new_id| (operations not using +// an existing key, like key generation). +// +// 2. Initialize it for an operation. For example, |EVP_PKEY_sign_init| +// initializes an |EVP_PKEY_CTX| for signing. // -// |EVP_PKEY_CTX| objects hold the context of an operation (e.g. signing or -// encrypting) that uses a public key. +// 3. Configure algorithm-specific parameters for the operation by calling +// control functions on the |EVP_PKEY_CTX|. Some functions are generic, such +// as |EVP_PKEY_CTX_set_signature_md|, and some are specific to an algorithm, +// such as |EVP_PKEY_CTX_set_rsa_padding|. +// +// 4. Perform the operation. For example, |EVP_PKEY_sign| signs with the +// corresponding parameters. +// +// 5. Release the |EVP_PKEY_CTX| with |EVP_PKEY_CTX_free|. +// +// Each |EVP_PKEY| algorithm interprets operations and parameters differently. +// Not all algorithms support all operations. Functions will fail if the +// algorithm does not support the parameter or operation. // EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It // returns the context or NULL on error. @@ -686,16 +854,16 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding); // EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded -// signature. A value of -1 cause the salt to be the same length as the digest -// in the signature. A value of -2 causes the salt to be the maximum length -// that will fit when signing and recovered from the signature when verifying. -// Otherwise the value gives the size of the salt in bytes. +// signature. A value of |RSA_PSS_SALTLEN_DIGEST| causes the salt to be the same +// length as the digest in the signature. A value of |RSA_PSS_SALTLEN_AUTO| +// causes the salt to be the maximum length that will fit when signing and +// recovered from the signature when verifying. Otherwise the value gives the +// size of the salt in bytes. // -// If unsure, use -1. +// If unsure, use |RSA_PSS_SALTLEN_DIGEST|, which is the default. Note this +// differs from OpenSSL, which defaults to |RSA_PSS_SALTLEN_AUTO|. // // Returns one on success or zero on error. -// -// TODO(davidben): The default is currently -2. Switch it to -1. OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len); @@ -715,7 +883,9 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits); // EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key -// generation. Returns one on success or zero on error. +// generation. Returns one on success or zero on error. On success, |ctx| takes +// ownership of |e|. The library will then call |BN_free| on |e| when |ctx| is +// destroyed. OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e); @@ -766,6 +936,14 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, // EC specific control functions. +// EVP_PKEY_get_ec_curve_nid returns |pkey|'s curve as a NID constant, such as +// |NID_X9_62_prime256v1|, or |NID_undef| if |pkey| is not an EC key. +OPENSSL_EXPORT int EVP_PKEY_get_ec_curve_nid(const EVP_PKEY *pkey); + +// EVP_PKEY_get_ec_point_conv_form returns |pkey|'s point conversion form as a +// |POINT_CONVERSION_*| constant, or zero if |pkey| is not an EC key. +OPENSSL_EXPORT int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey); + // EVP_PKEY_CTX_set_ec_paramgen_curve_nid sets the curve used for // |EVP_PKEY_keygen| or |EVP_PKEY_paramgen| operations to |nid|. It returns one // on success and zero on error. @@ -893,6 +1071,25 @@ OPENSSL_EXPORT EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int encoding); +// EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if +// successful or zero if the |type| argument is not one of the |EVP_PKEY_*| +// values supported for use with this function. If |pkey| is NULL, it simply +// reports whether the type is known. +// +// There are very few cases where this function is useful. Changing |pkey|'s +// type clears any previously stored keys, so there is no benefit to loading a +// key and then changing its type. Although |pkey| is left with a type +// configured, it has no key, and functions which set a key, such as +// |EVP_PKEY_set1_RSA|, will configure a type anyway. If writing unit tests that +// are only sensitive to the type of a key, it is preferable to construct a real +// key, so that tests are more representative of production code. +// +// The only API pattern which requires this function is +// |EVP_PKEY_set1_tls_encodedpoint| with X25519, which requires a half-empty +// |EVP_PKEY| that was first configured with |EVP_PKEY_X25519|. Currently, all +// other values of |type| will result in an error. +OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); + // EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by // |in|. It returns one on success and zero on error. // @@ -1004,6 +1201,26 @@ OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); // EVP_PKEY_type returns |nid|. OPENSSL_EXPORT int EVP_PKEY_type(int nid); +// EVP_PKEY_new_raw_private_key interprets |in| as a raw private key of type +// |type|, which must be an |EVP_PKEY_*| constant, such as |EVP_PKEY_X25519|, +// and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +// +// Prefer |EVP_PKEY_from_raw_private_key|, which allows dead code elimination to +// discard algorithms that aren't reachable from the caller. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + +// EVP_PKEY_new_raw_public_key interprets |in| as a raw public key of type +// |type|, which must be an |EVP_PKEY_*| constant, such as |EVP_PKEY_X25519|, +// and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +// +// Prefer |EVP_PKEY_from_raw_private_key|, which allows dead code elimination to +// discard algorithms that aren't reachable from the caller. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + // Preprocessor compatibility section (hidden). // diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h index c7fa18055..9626caff0 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h @@ -21,7 +21,7 @@ #define EVP_R_DIFFERENT_KEY_TYPES 103 #define EVP_R_DIFFERENT_PARAMETERS 104 #define EVP_R_ENCODE_ERROR 105 -#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106 +#define EVP_R_EXPECTING_A_EC_KEY 106 #define EVP_R_EXPECTING_AN_RSA_KEY 107 #define EVP_R_EXPECTING_A_DSA_KEY 108 #define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h index ae7db6db5..739653015 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h @@ -16,7 +16,7 @@ #define OPENSSL_HEADER_HPKE_H #include "CCryptoBoringSSL_aead.h" -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #include "CCryptoBoringSSL_curve25519.h" #include "CCryptoBoringSSL_digest.h" @@ -42,12 +42,14 @@ extern "C" { // The following constants are KEM identifiers. #define EVP_HPKE_DHKEM_P256_HKDF_SHA256 0x0010 #define EVP_HPKE_DHKEM_X25519_HKDF_SHA256 0x0020 +#define EVP_HPKE_XWING 0x647a // The following functions are KEM algorithms which may be used with HPKE. Note // that, while some HPKE KEMs use KDFs internally, this is separate from the // |EVP_HPKE_KDF| selection. OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void); OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_p256_hkdf_sha256(void); +OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_xwing(void); // EVP_HPKE_KEM_id returns the HPKE KEM identifier for |kem|, which // will be one of the |EVP_HPKE_KEM_*| constants. @@ -55,7 +57,7 @@ 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 65 +#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 1216 // 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|. @@ -71,7 +73,7 @@ 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 KEMs currently supported by this library. -#define EVP_HPKE_MAX_ENC_LENGTH 65 +#define EVP_HPKE_MAX_ENC_LENGTH 1120 // EVP_HPKE_KEM_enc_len returns the length of the "enc", the encapsulated shared // secret, for |kem|. This value will be at most |EVP_HPKE_MAX_ENC_LENGTH|. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h index 88b12927d..f2b906741 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h @@ -318,6 +318,146 @@ OPENSSL_EXPORT int MLDSA87_parse_public_key( struct MLDSA87_public_key *public_key, CBS *in); +// ML-DSA-44. + +// MLDSA44_private_key contains an ML-DSA-44 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct MLDSA44_private_key { + union { + uint8_t bytes[32 + 32 + 64 + 256 * 4 * (4 + 4 + 4)]; + uint32_t alignment; + } opaque; +}; + +// MLDSA44_public_key contains an ML-DSA-44 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct MLDSA44_public_key { + union { + uint8_t bytes[32 + 64 + 256 * 4 * 4]; + uint32_t alignment; + } opaque; +}; + +// MLDSA44_prehash contains a pre-hash context for ML-DSA-44. The contents of +// this object should never leave the address space since the format is +// unstable. +struct MLDSA44_prehash { + union { + uint8_t bytes[200 + 4 + 4 + 4 * sizeof(size_t)]; + uint64_t alignment; + } opaque; +}; + +// MLDSA44_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// private key. +#define MLDSA44_PRIVATE_KEY_BYTES 2560 + +// MLDSA44_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// public key. +#define MLDSA44_PUBLIC_KEY_BYTES 1312 + +// MLDSA44_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-44 +// signature. +#define MLDSA44_SIGNATURE_BYTES 2420 + +// MLDSA44_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key|, writes the seed to +// |out_seed|, and sets |out_private_key| to the private key. Returns 1 on +// success and 0 on allocation failure. +OPENSSL_EXPORT int MLDSA44_generate_key( + uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[MLDSA_SEED_BYTES], + struct MLDSA44_private_key *out_private_key); + +// MLDSA44_private_key_from_seed regenerates a private key from a seed value +// that was generated by |MLDSA44_generate_key|. Returns 1 on success and 0 on +// allocation failure or if |seed_len| is incorrect. +OPENSSL_EXPORT int MLDSA44_private_key_from_seed( + struct MLDSA44_private_key *out_private_key, const uint8_t *seed, + size_t seed_len); + +// MLDSA44_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. Returns 1 on success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_public_from_private( + struct MLDSA44_public_key *out_public_key, + const struct MLDSA44_private_key *private_key); + +// MLDSA44_sign generates a signature for the message |msg| of length +// |msg_len| using |private_key| (following the randomized algorithm), and +// writes the encoded signature to |out_encoded_signature|. The |context| +// argument is also signed over and can be used to include implicit contextual +// information that isn't included in |msg|. The same value of |context| must be +// presented to |MLDSA44_verify| in order for the generated signature to be +// considered valid. |context| and |context_len| may be |NULL| and 0 to use an +// empty context (this is common). Returns 1 on success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_sign( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len); + +// MLDSA44_verify verifies that |signature| constitutes a valid +// signature for the message |msg| of length |msg_len| using |public_key|. The +// value of |context| must equal the value that was passed to |MLDSA44_sign| +// when the signature was generated. Returns 1 on success or 0 on error. +OPENSSL_EXPORT int MLDSA44_verify(const struct MLDSA44_public_key *public_key, + const uint8_t *signature, + size_t signature_len, const uint8_t *msg, + size_t msg_len, const uint8_t *context, + size_t context_len); + +// MLDSA44_prehash_init initializes a pre-hashing state using |public_key|. The +// |context| argument can be used to include implicit contextual information +// that isn't included in the message. The same value of |context| must be +// presented to |MLDSA44_verify| in order for the generated signature to be +// considered valid. |context| and |context_len| may be |NULL| and 0 to use an +// empty context (this is common). Returns 1 on success and 0 on failure (if the +// context is too long). +OPENSSL_EXPORT int MLDSA44_prehash_init( + struct MLDSA44_prehash *out_state, + const struct MLDSA44_public_key *public_key, const uint8_t *context, + size_t context_len); + +// MLDSA44_prehash_update incorporates the given |msg| of length |msg_len| into +// the pre-hashing state. This can be called multiple times on successive chunks +// of the message. This should be called after |MLDSA44_prehash_init| and before +// |MLDSA44_prehash_finalize|. +OPENSSL_EXPORT void MLDSA44_prehash_update(struct MLDSA44_prehash *inout_state, + const uint8_t *msg, size_t msg_len); + +// MLDSA44_prehash_finalize extracts a pre-hashed message representative from +// the given pre-hashing state. This should be called after +// |MLDSA44_prehash_init| and |MLDSA44_prehash_update|. The resulting +// |out_msg_rep| should then be passed to |MLDSA44_sign_message_representative| +// to obtain a signature. +OPENSSL_EXPORT void MLDSA44_prehash_finalize( + uint8_t out_msg_rep[MLDSA_MU_BYTES], struct MLDSA44_prehash *inout_state); + +// MLDSA44_sign_message_representative generates a signature for the pre-hashed +// message |msg_rep| using |private_key| (following the randomized algorithm), +// and writes the encoded signature to |out_encoded_signature|. The |msg_rep| +// should be obtained via calls to |MLDSA44_prehash_init|, +// |MLDSA44_prehash_update| and |MLDSA44_prehash_finalize| using the public key +// from the same key pair, otherwise the signature will not verify. Returns 1 on +// success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_sign_message_representative( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t msg_rep[MLDSA_MU_BYTES]); + +// MLDSA44_marshal_public_key serializes |public_key| to |out| in the standard +// format for ML-DSA-44 public keys. It returns 1 on success or 0 on +// allocation error. +OPENSSL_EXPORT int MLDSA44_marshal_public_key( + CBB *out, const struct MLDSA44_public_key *public_key); + +// MLDSA44_parse_public_key parses a public key, in the format generated by +// |MLDSA44_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns 1 on success or 0 on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int MLDSA44_parse_public_key( + struct MLDSA44_public_key *public_key, CBS *in); + + #if defined(__cplusplus) } // extern C #endif diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h index 415556daf..f7fc5ab29 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h @@ -17,7 +17,7 @@ #ifndef OPENSSL_HEADER_NID_H #define OPENSSL_HEADER_NID_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -4216,6 +4216,9 @@ extern "C" { #define SN_X25519MLKEM768 "X25519MLKEM768" #define NID_X25519MLKEM768 965 +#define SN_MLKEM1024 "MLKEM1024" +#define NID_MLKEM1024 966 + #if defined(__cplusplus) } /* extern C */ diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h index e7516e0f7..a6f8425d8 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h @@ -69,9 +69,7 @@ OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); // Properties. // OPENSSL_RSA_MAX_MODULUS_BITS is the maximum supported RSA modulus, in bits. -// -// TODO(crbug.com/402677800): Reduce this to 8192. -#define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#define OPENSSL_RSA_MAX_MODULUS_BITS 8192 // RSA_bits returns the size of |rsa|, in bits. OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); @@ -225,7 +223,11 @@ OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); // It returns 1 on success or zero on error. // // The |padding| argument must be one of the |RSA_*_PADDING| values. If in -// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. When |padding| is +// |RSA_PKCS1_OAEP_PADDING|, this function has no way to set the OAEP or MGF-1 +// digest, so it is always SHA-1. For other OAEP parameters, wrap |rsa| in an +// |EVP_PKEY| and use |EVP_PKEY_encrypt| with |EVP_PKEY_CTX_set_rsa_padding| and +// related functions. OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -237,7 +239,11 @@ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, // It returns 1 on success or zero on error. // // The |padding| argument must be one of the |RSA_*_PADDING| values. If in -// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. When |padding| is +// |RSA_PKCS1_OAEP_PADDING|, this function has no way to set the OAEP or MGF-1 +// digest, so it is always SHA-1. For other OAEP parameters, wrap |rsa| in an +// |EVP_PKEY| and use |EVP_PKEY_decrypt| with |EVP_PKEY_CTX_set_rsa_padding| and +// related functions. // // WARNING: Passing |RSA_PKCS1_PADDING| into this function is deprecated and // insecure. RSAES-PKCS1-v1_5 is vulnerable to a chosen-ciphertext attack. @@ -259,6 +265,11 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, // -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| // values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. // +// When |padding| is |RSA_PKCS1_OAEP_PADDING|, this function has no way to set +// the OAEP or MGF-1 digest, so it is always SHA-1. For other OAEP parameters, +// wrap |rsa| in an |EVP_PKEY| and use |EVP_PKEY_encrypt| with +// |EVP_PKEY_CTX_set_rsa_padding| and related functions. +// // WARNING: this function is dangerous because it breaks the usual return value // convention. Use |RSA_encrypt| instead. OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, @@ -272,6 +283,11 @@ OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, // |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See // |RSA_decrypt|. // +// When |padding| is |RSA_PKCS1_OAEP_PADDING|, this function has no way to set +// the OAEP or MGF-1 digest, so it is always SHA-1. For other OAEP parameters, +// wrap |rsa| in an |EVP_PKEY| and use |EVP_PKEY_decrypt| with +// |EVP_PKEY_CTX_set_rsa_padding| and related functions. +// // WARNING: this function is dangerous because it breaks the usual return value // convention. Use |RSA_decrypt| instead. OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, @@ -301,6 +317,15 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa); +// RSA_PSS_SALTLEN_DIGEST indicates a PSS salt length that matches the digest +// length. This is recommended. +#define RSA_PSS_SALTLEN_DIGEST (-1) +// RSA_PSS_SALTLEN_AUTO indicates a maximum possible PSS salt length when +// signing, and automatically detecting the salt length when verifying. This is +// not recommended. Neither the signing nor verifying behaviors are compliant +// with FIPS 186-5. +#define RSA_PSS_SALTLEN_AUTO (-2) + // 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 // writes, at most, |max_out| bytes of signature data to |out|. The |max_out| @@ -311,9 +336,10 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, // and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is // used. // -// |salt_len| specifies the expected salt length in bytes. If |salt_len| is -1, -// then the salt length is the same as the hash length. If -2, then the salt -// length is maximal given the size of |rsa|. If unsure, use -1. +// |salt_len| specifies the expected salt length in bytes. If |salt_len| is +// |RSA_PSS_SALTLEN_DIGEST|, then the salt length is the same as the hash +// length. If |RSA_PSS_SALTLEN_AUTO|, then the salt length is maximal given the +// size of |rsa|. If unsure, use |RSA_PSS_SALTLEN_DIGEST|. // // WARNING: |digest| must be the result of hashing the data to be signed with // |md|. Passing unhashed inputs will not result in a secure signature scheme. @@ -373,9 +399,9 @@ OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *digest, // and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is // used. |salt_len| specifies the expected salt length in bytes. // -// If |salt_len| is -1, then the salt length is the same as the hash length. If -// -2, then the salt length is recovered and all values accepted. If unsure, use -// -1. +// If |salt_len| is |RSA_PSS_SALTLEN_DIGEST|, then the salt length is the same +// as the hash length. If |RSA_PSS_SALTLEN_AUTO|, then the salt length is +// recovered and all values accepted. If unsure, use |RSA_PSS_SALTLEN_DIGEST|. // // WARNING: |digest| must be the result of hashing the data to be verified with // |md|. Passing unhashed input will not result in a secure signature scheme. @@ -737,8 +763,13 @@ OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, OPENSSL_EXPORT int RSA_print(BIO *bio, const RSA *rsa, int indent); // RSA_get0_pss_params returns NULL. In OpenSSL, this function retries RSA-PSS -// parameters associated with |RSA| objects, but BoringSSL does not support -// the id-RSASSA-PSS key encoding. +// parameters associated with |RSA| objects, but BoringSSL does not enable the +// id-RSASSA-PSS key encoding by default. +// +// WARNING: BoringSSL does support id-RSASSA-PSS parameters when callers opt in +// (see |EVP_pkey_rsa_pss_sha256|). We currently assume such callers do not need +// this function. Callers that opt into id-RSASSA-PSS support and require this +// functionality should contact the BoringSSL team. OPENSSL_EXPORT const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa); // RSA_new_method_no_e returns a newly-allocated |RSA| object backed by diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h index 33a8a76ca..2b1f6b40d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h @@ -15,8 +15,13 @@ #ifndef OPENSSL_HEADER_SHA_H #define OPENSSL_HEADER_SHA_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export -#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export + +// `sha.h` historically included SHA-1 and SHA-2 hash functions. So, for +// backward compatibility `sha2.h` is included here. New uses of this header +// should include sha2.h unless SHA-1 family functions are required. +#include "CCryptoBoringSSL_sha2.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -74,160 +79,6 @@ OPENSSL_EXPORT void CRYPTO_fips_186_2_prf( uint8_t *out, size_t out_len, const uint8_t xkey[SHA_DIGEST_LENGTH]); -// SHA-224. - -// SHA224_CBLOCK is the block size of SHA-224. -#define SHA224_CBLOCK 64 - -// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. -#define SHA224_DIGEST_LENGTH 28 - -// SHA224_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); - -// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); - -// SHA224_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It -// returns 1. -OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], - SHA256_CTX *sha); - -// SHA224 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, - uint8_t out[SHA224_DIGEST_LENGTH]); - - -// SHA-256. - -// SHA256_CBLOCK is the block size of SHA-256. -#define SHA256_CBLOCK 64 - -// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. -#define SHA256_DIGEST_LENGTH 32 - -// SHA256_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); - -// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); - -// SHA256_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], - SHA256_CTX *sha); - -// SHA256 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, - uint8_t out[SHA256_DIGEST_LENGTH]); - -// SHA256_Transform is a low-level function that performs a single, SHA-256 -// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes -// from |block|. -OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, - const uint8_t block[SHA256_CBLOCK]); - -// SHA256_TransformBlocks is a low-level function that takes |num_blocks| * -// |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update -// |state|. You should not use this function unless you are implementing a -// derivative of SHA-256. -OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], - const uint8_t *data, - size_t num_blocks); - - -// SHA-384. - -// SHA384_CBLOCK is the block size of SHA-384. -#define SHA384_CBLOCK 128 - -// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. -#define SHA384_DIGEST_LENGTH 48 - -// SHA384_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); - -// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); - -// SHA384_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA384 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, - uint8_t out[SHA384_DIGEST_LENGTH]); - - -// SHA-512. - -// SHA512_CBLOCK is the block size of SHA-512. -#define SHA512_CBLOCK 128 - -// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. -#define SHA512_DIGEST_LENGTH 64 - -// SHA512_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); - -// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); - -// SHA512_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA512 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, - uint8_t out[SHA512_DIGEST_LENGTH]); - -// SHA512_Transform is a low-level function that performs a single, SHA-512 -// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes -// from |block|. -OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, - const uint8_t block[SHA512_CBLOCK]); - - -// SHA-512-256 -// -// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 - -#define SHA512_256_DIGEST_LENGTH 32 - -// SHA512_256_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha); - -// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data, - size_t len); - -// SHA512_256_Final adds the final padding to |sha| and writes the resulting -// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of -// space. It returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len, - uint8_t out[SHA512_256_DIGEST_LENGTH]); - - #if defined(__cplusplus) } // extern C #endif diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h new file mode 100644 index 000000000..e05626055 --- /dev/null +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h @@ -0,0 +1,184 @@ +// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OPENSSL_HEADER_SHA2_H +#define OPENSSL_HEADER_SHA2_H + +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SHA-224. + +// SHA224_CBLOCK is the block size of SHA-224. +#define SHA224_CBLOCK 64 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define SHA224_DIGEST_LENGTH 28 + +// SHA224_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); + +// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA224_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It +// returns 1. +OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA224 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, + uint8_t out[SHA224_DIGEST_LENGTH]); + + +// SHA-256. + +// SHA256_CBLOCK is the block size of SHA-256. +#define SHA256_CBLOCK 64 + +// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define SHA256_DIGEST_LENGTH 32 + +// SHA256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); + +// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA256_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, + uint8_t out[SHA256_DIGEST_LENGTH]); + +// SHA256_Transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, + const uint8_t block[SHA256_CBLOCK]); + +// SHA256_TransformBlocks is a low-level function that takes |num_blocks| * +// |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update +// |state|. You should not use this function unless you are implementing a +// derivative of SHA-256. +OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], + const uint8_t *data, + size_t num_blocks); + + +// SHA-384. + +// SHA384_CBLOCK is the block size of SHA-384. +#define SHA384_CBLOCK 128 + +// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define SHA384_DIGEST_LENGTH 48 + +// SHA384_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); + +// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA384_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA384 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, + uint8_t out[SHA384_DIGEST_LENGTH]); + + +// SHA-512. + +// SHA512_CBLOCK is the block size of SHA-512. +#define SHA512_CBLOCK 128 + +// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define SHA512_DIGEST_LENGTH 64 + +// SHA512_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); + +// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA512_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, + uint8_t out[SHA512_DIGEST_LENGTH]); + +// SHA512_Transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, + const uint8_t block[SHA512_CBLOCK]); + + +// SHA-512-256 +// +// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 + +#define SHA512_256_DIGEST_LENGTH 32 + +// SHA512_256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha); + +// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data, + size_t len); + +// SHA512_256_Final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of +// space. It returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len, + uint8_t out[SHA512_256_DIGEST_LENGTH]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SHA2_H diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h index 42f385cab..21cba29e1 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h @@ -34,7 +34,7 @@ #include "CCryptoBoringSSL_pkcs7.h" #include "CCryptoBoringSSL_pool.h" #include "CCryptoBoringSSL_rsa.h" -#include "CCryptoBoringSSL_sha.h" +#include "CCryptoBoringSSL_sha2.h" #include "CCryptoBoringSSL_stack.h" #include "CCryptoBoringSSL_x509v3_errors.h" // IWYU pragma: export @@ -88,9 +88,8 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); // |i2d_X509_AUX|) are not preserved. Additionally, if |x509| is incomplete, // this function may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT X509 *X509_dup(X509 *x509); // X509_free decrements |x509|'s reference count and, if zero, releases memory @@ -101,18 +100,27 @@ OPENSSL_EXPORT void X509_free(X509 *x509); // Certificate (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509 *d2i_X509(X509 **out, const uint8_t **inp, long len); -// X509_parse_from_buffer parses an X.509 structure from |buf| and returns a +// X509_parse_with_algorithms parses an X.509 structure from |buf| and returns a // fresh X509 or NULL on error. There must not be any trailing data in |buf|. -// The returned structure (if any) holds a reference to |buf| rather than -// copying parts of it as a normal |d2i_X509| call would do. +// The returned structure (if any) increment's |buf|'s reference count and +// retains a reference to it. +// +// Only the |num_algs| algorithms from |algs| will be considered when parsing +// the certificate's public key. If the certificate uses a different algorithm, +// it will still be parsed, but |X509_get0_pubkey| will return NULL. +OPENSSL_EXPORT X509 *X509_parse_with_algorithms(CRYPTO_BUFFER *buf, + const EVP_PKEY_ALG *const *algs, + size_t num_algs); + +// X509_parse_from_buffer behaves like |X509_parse_with_algorithms| but uses a +// default algorithm list. OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); // i2d_X509 marshals |x509| as a DER-encoded X.509 Certificate (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |x509| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |x509| was mutated. OPENSSL_EXPORT int i2d_X509(X509 *x509, uint8_t **outp); // X509_VERSION_* are X.509 version numbers. Note the numerical values of all @@ -429,8 +437,8 @@ OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); // as equal. This function should only be used with |X509| objects that were // parsed from bytes and never mutated. // -// TODO(https://crbug.com/boringssl/407): This function is const, but it is not -// always thread-safe, notably if |a| and |b| were mutated. +// TODO(crbug.com/42290269): This function is const, but it is not always +// thread-safe, notably if |a| and |b| were mutated. OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); @@ -564,7 +572,7 @@ OPENSSL_EXPORT int X509_set1_signature_value(X509 *x509, const uint8_t *sig, // ASN.1 element. Directly embedding the output in a larger ASN.1 structure will // not behave correctly. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int i2d_X509_AUX(X509 *x509, uint8_t **outp); // d2i_X509_AUX parses up to |length| bytes from |*inp| as a DER-encoded X.509 @@ -675,9 +683,8 @@ OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); // function works by serializing the structure, so if |crl| is incomplete, it // may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); // X509_CRL_free decrements |crl|'s reference count and, if zero, releases @@ -692,9 +699,8 @@ OPENSSL_EXPORT X509_CRL *d2i_X509_CRL(X509_CRL **out, const uint8_t **inp, // i2d_X509_CRL marshals |crl| as a X.509 CertificateList (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT int i2d_X509_CRL(X509_CRL *crl, uint8_t **outp); // X509_CRL_match compares |a| and |b| and returns zero if they are equal, a @@ -1068,9 +1074,8 @@ OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, // function works by serializing the structure, so if |req| is incomplete, it // may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |req| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |req| was mutated. OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); // X509_REQ_free releases memory associated with |req|. @@ -1084,9 +1089,8 @@ OPENSSL_EXPORT X509_REQ *d2i_X509_REQ(X509_REQ **out, const uint8_t **inp, // i2d_X509_REQ marshals |req| as a CertificateRequest (RFC 2986), as described // in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |req| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |req| was mutated. OPENSSL_EXPORT int i2d_X509_REQ(X509_REQ *req, uint8_t **outp); // X509_REQ_VERSION_1 is the version constant for |X509_REQ| objects. No other @@ -1352,24 +1356,22 @@ OPENSSL_EXPORT X509_NAME *d2i_X509_NAME(X509_NAME **out, const uint8_t **inp, // i2d_X509_NAME marshals |in| as a DER-encoded X.509 Name (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |in| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |in| was mutated. OPENSSL_EXPORT int i2d_X509_NAME(X509_NAME *in, uint8_t **outp); // X509_NAME_dup returns a newly-allocated copy of |name|, or NULL on error. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |name| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |name| was mutated. OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *name); // X509_NAME_cmp compares |a| and |b|'s canonicalized forms. It returns zero if // they are equal, one if |a| sorts after |b|, -1 if |b| sorts after |a|, and -2 // on error. // -// TODO(https://crbug.com/boringssl/407): This function is const, but it is not -// always thread-safe, notably if |name| was mutated. +// TODO(crbug.com/42290269): This function is const, but it is not always +// thread-safe, notably if |name| was mutated. // // TODO(https://crbug.com/boringssl/355): The -2 return is very inconvenient to // pass to a sorting function. Can we make this infallible? In the meantime, @@ -1386,17 +1388,15 @@ OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); // Avoid this function and prefer |i2d_X509_NAME|. It is one of the reasons // |X509_NAME| functions, including this one, are not consistently thread-safe // or const-correct. Depending on the resolution of -// https://crbug.com/boringssl/407, this function may be removed or cause poor -// performance. +// crbug.com/42290269, this function may be removed or cause poor performance. OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *name, const uint8_t **out_der, size_t *out_der_len); // X509_NAME_set makes a copy of |name|. On success, it frees |*xn|, sets |*xn| // to the copy, and returns one. Otherwise, it returns zero. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |name| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |name| was mutated. OPENSSL_EXPORT int X509_NAME_set(X509_NAME **xn, X509_NAME *name); // X509_NAME_entry_count returns the number of entries in |name|. @@ -2093,18 +2093,18 @@ OPENSSL_EXPORT GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **out, // i2d_GENERAL_NAME marshals |in| as a DER-encoded X.509 GeneralName (RFC 5280), // as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |in| is an -// directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |in| is an directoryName and +// the |X509_NAME| has been modified. OPENSSL_EXPORT int i2d_GENERAL_NAME(GENERAL_NAME *in, uint8_t **outp); // GENERAL_NAME_dup returns a newly-allocated copy of |gen|, or NULL on error. // This function works by serializing the structure, so it will fail if |gen| is // empty. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |gen| is an -// directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |gen| is an directoryName and +// the |X509_NAME| has been modified. OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *gen); // GENERAL_NAMES_new returns a new, empty |GENERAL_NAMES|, or NULL on error. @@ -2121,9 +2121,9 @@ OPENSSL_EXPORT GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **out, // i2d_GENERAL_NAMES marshals |in| as a DER-encoded SEQUENCE OF GeneralName, as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if some element -// of |in| is an directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if some element of |in| is an +// directoryName and the |X509_NAME| has been modified. OPENSSL_EXPORT int i2d_GENERAL_NAMES(GENERAL_NAMES *in, uint8_t **outp); // OTHERNAME_new returns a new, empty |OTHERNAME|, or NULL on error. @@ -2229,8 +2229,8 @@ OPENSSL_EXPORT AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **out, // i2d_AUTHORITY_KEYID marshals |akid| as a DER-encoded AuthorityKeyIdentifier // (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |akid| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |akid| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *akid, uint8_t **outp); @@ -2322,8 +2322,8 @@ OPENSSL_EXPORT AUTHORITY_INFO_ACCESS *d2i_AUTHORITY_INFO_ACCESS( // i2d_AUTHORITY_INFO_ACCESS marshals |aia| as a DER-encoded // AuthorityInfoAccessSyntax (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |aia| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |aia| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *aia, uint8_t **outp); @@ -2397,8 +2397,8 @@ OPENSSL_EXPORT CRL_DIST_POINTS *d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **out, // i2d_CRL_DIST_POINTS marshals |crldp| as a DER-encoded CRLDistributionPoints // (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |crldp| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |crldp| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *crldp, uint8_t **outp); // A ISSUING_DIST_POINT_st, aka |ISSUING_DIST_POINT|, represents a @@ -2431,8 +2431,8 @@ OPENSSL_EXPORT ISSUING_DIST_POINT *d2i_ISSUING_DIST_POINT( // i2d_ISSUING_DIST_POINT marshals |idp| as a DER-encoded // IssuingDistributionPoint (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |idp| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |idp| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *idp, uint8_t **outp); @@ -2597,6 +2597,10 @@ OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_new(void); // it may fail. OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg); +// X509_ALGOR_copy sets |dst| to a copy of the contents of |src|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_ALGOR_copy(X509_ALGOR *dst, const X509_ALGOR *src); + // X509_ALGOR_free releases memory associated with |alg|. OPENSSL_EXPORT void X509_ALGOR_free(X509_ALGOR *alg); @@ -3705,9 +3709,8 @@ OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *lookup, // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. // -// TODO(https://crbug.com/boringssl/407): This should be const and thread-safe -// but currently is neither, notably if |name| was modified from its parsed -// value. +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |name| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_NAME_hash(X509_NAME *name); // X509_NAME_hash_old returns a hash of |name|, or zero on error. This is the @@ -3718,9 +3721,8 @@ OPENSSL_EXPORT uint32_t X509_NAME_hash(X509_NAME *name); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. // -// TODO(https://crbug.com/boringssl/407): This should be const and thread-safe -// but currently is neither, notably if |name| was modified from its parsed -// value. +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |name| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_NAME_hash_old(X509_NAME *name); // X509_STORE_set_default_paths configures |store| to read from some "default" @@ -4439,6 +4441,9 @@ OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_issuer_name_hash(X509 *x509); // X509_subject_name_hash returns the hash of |x509|'s subject name with @@ -4448,6 +4453,9 @@ OPENSSL_EXPORT uint32_t X509_issuer_name_hash(X509 *x509); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_subject_name_hash(X509 *x509); // X509_issuer_name_hash_old returns the hash of |x509|'s issuer name with @@ -4456,6 +4464,9 @@ OPENSSL_EXPORT uint32_t X509_subject_name_hash(X509 *x509); // This hash is specific to the |X509_LOOKUP_add_dir| filesystem format and is // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_issuer_name_hash_old(X509 *x509); // X509_subject_name_hash_old returns the hash of |x509|'s usjbect name with @@ -4464,6 +4475,9 @@ OPENSSL_EXPORT uint32_t X509_issuer_name_hash_old(X509 *x509); // This hash is specific to the |X509_LOOKUP_add_dir| filesystem format and is // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_subject_name_hash_old(X509 *x509); @@ -4535,6 +4549,9 @@ OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, // |md|, or |pkey|'s default if NULL. Other signing parameters use |pkey|'s // defaults. To customize them, use |ASN1_item_sign_ctx|. // +// |algor1| and |algor2| may point into part of |asn| and will be updated before +// |asn| is serialized. +// // WARNING: |data| must be a pointer with the same type as |it|'s corresponding // C type. Using the wrong type is a potentially exploitable memory error. OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, @@ -4550,6 +4567,9 @@ OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, // On success or failure, this function mutates |ctx| and resets it to the empty // state. Caller should not rely on its contents after the function returns. // +// |algor1| and |algor2| may point into part of |asn| and will be updated before +// |asn| is serialized. +// // WARNING: |data| must be a pointer with the same type as |it|'s corresponding // C type. Using the wrong type is a potentially exploitable memory error. OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, @@ -4582,7 +4602,7 @@ OPENSSL_EXPORT int X509_supported_extension(const X509_EXTENSION *ex); // This function returning one does not indicate that |x509| is trusted, only // that it is eligible to be a CA. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int X509_check_ca(X509 *x509); // X509_check_issued checks if |issuer| and |subject|'s name, authority key @@ -4593,13 +4613,13 @@ OPENSSL_EXPORT int X509_check_ca(X509 *x509); // intended to prune the set of possible issuer certificates during // path-building. // -// TODO(crbug.com/boringssl/407): Both parameters should be const. +// TODO(crbug.com/42290269): Both parameters should be const. OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); // NAME_CONSTRAINTS_check checks if |x509| satisfies name constraints in |nc|. // It returns |X509_V_OK| on success and some |X509_V_ERR_*| constant on error. // -// TODO(crbug.com/boringssl/407): Both parameters should be const. +// TODO(crbug.com/42290269): Both parameters should be const. OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x509, NAME_CONSTRAINTS *nc); // X509_check_host checks if |x509| matches the DNS name |chk|. It returns one @@ -4679,7 +4699,7 @@ OPENSSL_EXPORT int X509_check_ip_asc(const X509 *x509, const char *ipasc, // This function only searches for trusted issuers. It does not consider // untrusted intermediates passed in to |X509_STORE_CTX_init|. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x509); @@ -4713,7 +4733,7 @@ OPENSSL_EXPORT int X509_check_trust(X509 *x509, int id, int flags); // NULL on error. The caller must release the result with |sk_X509_pop_free| and // |X509_free| when done. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name); @@ -4722,7 +4742,7 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, // The caller must release the result with |sk_X509_CRL_pop_free| and // |X509_CRL_free| when done. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name); @@ -4740,7 +4760,7 @@ OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, // case, this function returns an arbitrary match. Use // |X509_STORE_CTX_get1_certs| or |X509_STORE_CTX_get1_crls| instead. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *ctx, int type, X509_NAME *name, X509_OBJECT *ret); diff --git a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc index cf0a13e6f..5368abb76 100644 --- a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -162,8 +162,12 @@ %xdefine _ASN1_item_sign_ctx _ %+ BORINGSSL_PREFIX %+ _ASN1_item_sign_ctx %xdefine _ASN1_item_unpack _ %+ BORINGSSL_PREFIX %+ _ASN1_item_unpack %xdefine _ASN1_item_verify _ %+ BORINGSSL_PREFIX %+ _ASN1_item_verify +%xdefine _asn1_marshal_any _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_any %xdefine _asn1_marshal_bit_string _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_bit_string %xdefine _asn1_marshal_integer _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_integer +%xdefine _asn1_marshal_object _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_object +%xdefine _asn1_marshal_octet_string _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_octet_string +%xdefine _asn1_marshal_time _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_time %xdefine _ASN1_mbstring_copy _ %+ BORINGSSL_PREFIX %+ _ASN1_mbstring_copy %xdefine _ASN1_mbstring_ncopy _ %+ BORINGSSL_PREFIX %+ _ASN1_mbstring_ncopy %xdefine _ASN1_NULL_free _ %+ BORINGSSL_PREFIX %+ _ASN1_NULL_free @@ -180,6 +184,20 @@ %xdefine _ASN1_OCTET_STRING_it _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_it %xdefine _ASN1_OCTET_STRING_new _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_new %xdefine _ASN1_OCTET_STRING_set _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_set +%xdefine _asn1_parse_any _ %+ BORINGSSL_PREFIX %+ _asn1_parse_any +%xdefine _asn1_parse_any_as_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_any_as_string +%xdefine _asn1_parse_bit_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bit_string +%xdefine _asn1_parse_bit_string_with_bad_length _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bit_string_with_bad_length +%xdefine _asn1_parse_bmp_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bmp_string +%xdefine _asn1_parse_enumerated _ %+ BORINGSSL_PREFIX %+ _asn1_parse_enumerated +%xdefine _asn1_parse_generalized_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_generalized_time +%xdefine _asn1_parse_integer _ %+ BORINGSSL_PREFIX %+ _asn1_parse_integer +%xdefine _asn1_parse_object _ %+ BORINGSSL_PREFIX %+ _asn1_parse_object +%xdefine _asn1_parse_octet_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_octet_string +%xdefine _asn1_parse_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_time +%xdefine _asn1_parse_universal_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_universal_string +%xdefine _asn1_parse_utc_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_utc_time +%xdefine _asn1_parse_utf8_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_utf8_string %xdefine _ASN1_primitive_free _ %+ BORINGSSL_PREFIX %+ _ASN1_primitive_free %xdefine _ASN1_PRINTABLESTRING_free _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_free %xdefine _ASN1_PRINTABLESTRING_it _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_it @@ -190,6 +208,7 @@ %xdefine _asn1_refcount_set_one _ %+ BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine _ASN1_SEQUENCE_it _ %+ BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine _asn1_set_choice_selector _ %+ BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine _asn1_string_cleanup _ %+ BORINGSSL_PREFIX %+ _asn1_string_cleanup %xdefine _ASN1_STRING_cmp _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_cmp %xdefine _ASN1_STRING_copy _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_copy %xdefine _ASN1_STRING_data _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_data @@ -197,6 +216,7 @@ %xdefine _ASN1_STRING_free _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_free %xdefine _ASN1_STRING_get_default_mask _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_get_default_mask %xdefine _ASN1_STRING_get0_data _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_get0_data +%xdefine _asn1_string_init _ %+ BORINGSSL_PREFIX %+ _asn1_string_init %xdefine _ASN1_STRING_length _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_length %xdefine _ASN1_STRING_new _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_new %xdefine _ASN1_STRING_print _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_print @@ -277,6 +297,26 @@ %xdefine _bcm_as_approved_status _ %+ BORINGSSL_PREFIX %+ _bcm_as_approved_status %xdefine _bcm_as_not_approved_status _ %+ BORINGSSL_PREFIX %+ _bcm_as_not_approved_status %xdefine _BCM_fips_186_2_prf _ %+ BORINGSSL_PREFIX %+ _BCM_fips_186_2_prf +%xdefine _BCM_mldsa44_check_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_check_key_fips +%xdefine _BCM_mldsa44_generate_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key +%xdefine _BCM_mldsa44_generate_key_external_entropy _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy +%xdefine _BCM_mldsa44_generate_key_external_entropy_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy_fips +%xdefine _BCM_mldsa44_generate_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_fips +%xdefine _BCM_mldsa44_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_private_key +%xdefine _BCM_mldsa44_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_public_key +%xdefine _BCM_mldsa44_parse_private_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_private_key +%xdefine _BCM_mldsa44_parse_public_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_public_key +%xdefine _BCM_mldsa44_prehash_finalize _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_finalize +%xdefine _BCM_mldsa44_prehash_init _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_init +%xdefine _BCM_mldsa44_prehash_update _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_update +%xdefine _BCM_mldsa44_private_key_from_seed _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed +%xdefine _BCM_mldsa44_private_key_from_seed_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed_fips +%xdefine _BCM_mldsa44_public_from_private _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_public_from_private +%xdefine _BCM_mldsa44_sign _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign +%xdefine _BCM_mldsa44_sign_internal _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_internal +%xdefine _BCM_mldsa44_sign_message_representative _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_message_representative +%xdefine _BCM_mldsa44_verify _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_verify +%xdefine _BCM_mldsa44_verify_internal _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_verify_internal %xdefine _BCM_mldsa65_check_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_check_key_fips %xdefine _BCM_mldsa65_generate_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key %xdefine _BCM_mldsa65_generate_key_external_entropy _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key_external_entropy @@ -627,9 +667,9 @@ %xdefine _bn_mul_comba4 _ %+ BORINGSSL_PREFIX %+ _bn_mul_comba4 %xdefine _bn_mul_comba8 _ %+ BORINGSSL_PREFIX %+ _bn_mul_comba8 %xdefine _bn_mul_consttime _ %+ BORINGSSL_PREFIX %+ _bn_mul_consttime -%xdefine _bn_mul_mont _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont %xdefine _bn_mul_mont_gather5_nohw _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_gather5_nohw %xdefine _bn_mul_mont_nohw _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_nohw +%xdefine _bn_mul_mont_words _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_words %xdefine _bn_mul_small _ %+ BORINGSSL_PREFIX %+ _bn_mul_small %xdefine _BN_mul_word _ %+ BORINGSSL_PREFIX %+ _BN_mul_word %xdefine _bn_mul_words _ %+ BORINGSSL_PREFIX %+ _bn_mul_words @@ -877,6 +917,7 @@ %xdefine _CMS_sign _ %+ BORINGSSL_PREFIX %+ _CMS_sign %xdefine _CONF_modules_free _ %+ BORINGSSL_PREFIX %+ _CONF_modules_free %xdefine _CONF_modules_load_file _ %+ BORINGSSL_PREFIX %+ _CONF_modules_load_file +%xdefine _CONF_modules_unload _ %+ BORINGSSL_PREFIX %+ _CONF_modules_unload %xdefine _CONF_parse_list _ %+ BORINGSSL_PREFIX %+ _CONF_parse_list %xdefine _CONF_VALUE_new _ %+ BORINGSSL_PREFIX %+ _CONF_VALUE_new %xdefine _CRL_DIST_POINTS_free _ %+ BORINGSSL_PREFIX %+ _CRL_DIST_POINTS_free @@ -1011,7 +1052,9 @@ %xdefine _CTR_DRBG_generate _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_generate %xdefine _CTR_DRBG_init _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_init %xdefine _CTR_DRBG_new _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_new +%xdefine _CTR_DRBG_new_df _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_new_df %xdefine _CTR_DRBG_reseed _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_reseed +%xdefine _CTR_DRBG_reseed_ex _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_reseed_ex %xdefine _d2i_ASN1_BIT_STRING _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BIT_STRING %xdefine _d2i_ASN1_BMPSTRING _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BMPSTRING %xdefine _d2i_ASN1_BOOLEAN _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BOOLEAN @@ -1102,7 +1145,6 @@ %xdefine _d2i_X509_AUX _ %+ BORINGSSL_PREFIX %+ _d2i_X509_AUX %xdefine _d2i_X509_bio _ %+ BORINGSSL_PREFIX %+ _d2i_X509_bio %xdefine _d2i_X509_CERT_AUX _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CERT_AUX -%xdefine _d2i_X509_CINF _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CINF %xdefine _d2i_X509_CRL _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL %xdefine _d2i_X509_CRL_bio _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL_bio %xdefine _d2i_X509_CRL_fp _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL_fp @@ -1118,7 +1160,6 @@ %xdefine _d2i_X509_REQ_INFO _ %+ BORINGSSL_PREFIX %+ _d2i_X509_REQ_INFO %xdefine _d2i_X509_REVOKED _ %+ BORINGSSL_PREFIX %+ _d2i_X509_REVOKED %xdefine _d2i_X509_SIG _ %+ BORINGSSL_PREFIX %+ _d2i_X509_SIG -%xdefine _d2i_X509_VAL _ %+ BORINGSSL_PREFIX %+ _d2i_X509_VAL %xdefine _DES_decrypt3 _ %+ BORINGSSL_PREFIX %+ _DES_decrypt3 %xdefine _DES_ecb_encrypt _ %+ BORINGSSL_PREFIX %+ _DES_ecb_encrypt %xdefine _DES_ecb_encrypt_ex _ %+ BORINGSSL_PREFIX %+ _DES_ecb_encrypt_ex @@ -1326,8 +1367,11 @@ %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_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name +%xdefine _ec_key_parse_parameters _ %+ BORINGSSL_PREFIX %+ _ec_key_parse_parameters %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_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 @@ -1462,6 +1506,7 @@ %xdefine _ED25519_verify _ %+ BORINGSSL_PREFIX %+ _ED25519_verify %xdefine _EDIPARTYNAME_free _ %+ BORINGSSL_PREFIX %+ _EDIPARTYNAME_free %xdefine _EDIPARTYNAME_new _ %+ BORINGSSL_PREFIX %+ _EDIPARTYNAME_new +%xdefine _ENGINE_cleanup _ %+ BORINGSSL_PREFIX %+ _ENGINE_cleanup %xdefine _ENGINE_free _ %+ BORINGSSL_PREFIX %+ _ENGINE_free %xdefine _ENGINE_get_ECDSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_get_ECDSA_method %xdefine _ENGINE_get_RSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_get_RSA_method @@ -1474,6 +1519,7 @@ %xdefine _ERR_add_error_dataf _ %+ BORINGSSL_PREFIX %+ _ERR_add_error_dataf %xdefine _ERR_clear_error _ %+ BORINGSSL_PREFIX %+ _ERR_clear_error %xdefine _ERR_clear_system_error _ %+ BORINGSSL_PREFIX %+ _ERR_clear_system_error +%xdefine _ERR_equals _ %+ BORINGSSL_PREFIX %+ _ERR_equals %xdefine _ERR_error_string _ %+ BORINGSSL_PREFIX %+ _ERR_error_string %xdefine _ERR_error_string_n _ %+ BORINGSSL_PREFIX %+ _ERR_error_string_n %xdefine _ERR_free_strings _ %+ BORINGSSL_PREFIX %+ _ERR_free_strings @@ -1700,6 +1746,7 @@ %xdefine _EVP_HPKE_KEY_zero _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_zero %xdefine _EVP_hpke_p256_hkdf_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_p256_hkdf_sha256 %xdefine _EVP_hpke_x25519_hkdf_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_x25519_hkdf_sha256 +%xdefine _EVP_hpke_xwing _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_xwing %xdefine _EVP_marshal_digest_algorithm _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm %xdefine _EVP_marshal_digest_algorithm_no_params _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm_no_params %xdefine _EVP_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_private_key @@ -1731,6 +1778,7 @@ %xdefine _EVP_md5 _ %+ BORINGSSL_PREFIX %+ _EVP_md5 %xdefine _EVP_md5_sha1 _ %+ BORINGSSL_PREFIX %+ _EVP_md5_sha1 %xdefine _EVP_parse_digest_algorithm _ %+ BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm +%xdefine _EVP_parse_digest_algorithm_nid _ %+ BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm_nid %xdefine _EVP_parse_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_parse_private_key %xdefine _EVP_parse_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_parse_public_key %xdefine _EVP_PBE_scrypt _ %+ BORINGSSL_PREFIX %+ _EVP_PBE_scrypt @@ -1783,9 +1831,21 @@ %xdefine _EVP_PKEY_derive _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive %xdefine _EVP_PKEY_derive_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive_init %xdefine _EVP_PKEY_derive_set_peer _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive_set_peer +%xdefine _EVP_pkey_dsa _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_dsa +%xdefine _EVP_pkey_ec_p224 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p224 +%xdefine _EVP_pkey_ec_p256 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p256 +%xdefine _EVP_pkey_ec_p384 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p384 +%xdefine _EVP_pkey_ec_p521 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p521 +%xdefine _EVP_pkey_ed25519 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ed25519 %xdefine _EVP_PKEY_encrypt _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt %xdefine _EVP_PKEY_encrypt_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt_init %xdefine _EVP_PKEY_free _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_free +%xdefine _EVP_PKEY_from_private_key_info _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_private_key_info +%xdefine _EVP_PKEY_from_raw_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_private_key +%xdefine _EVP_PKEY_from_raw_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_public_key +%xdefine _EVP_PKEY_from_subject_public_key_info _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_subject_public_key_info +%xdefine _EVP_PKEY_get_ec_curve_nid _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_curve_nid +%xdefine _EVP_PKEY_get_ec_point_conv_form _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_point_conv_form %xdefine _EVP_PKEY_get_raw_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_private_key %xdefine _EVP_PKEY_get_raw_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_public_key %xdefine _EVP_PKEY_get0 _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get0 @@ -1811,8 +1871,10 @@ %xdefine _EVP_PKEY_print_params _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_params %xdefine _EVP_PKEY_print_private _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_private %xdefine _EVP_PKEY_print_public _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_public -%xdefine _evp_pkey_set_method _ %+ BORINGSSL_PREFIX %+ _evp_pkey_set_method +%xdefine _EVP_pkey_rsa _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_rsa +%xdefine _EVP_pkey_rsa_pss_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_rsa_pss_sha256 %xdefine _EVP_PKEY_set_type _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set_type +%xdefine _evp_pkey_set0 _ %+ BORINGSSL_PREFIX %+ _evp_pkey_set0 %xdefine _EVP_PKEY_set1_DH _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DH %xdefine _EVP_PKEY_set1_DSA _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DSA %xdefine _EVP_PKEY_set1_EC_KEY _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_EC_KEY @@ -1827,6 +1889,7 @@ %xdefine _EVP_PKEY_verify_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_init %xdefine _EVP_PKEY_verify_recover _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover %xdefine _EVP_PKEY_verify_recover_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover_init +%xdefine _EVP_pkey_x25519 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_x25519 %xdefine _EVP_PKEY2PKCS8 _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY2PKCS8 %xdefine _EVP_rc2_40_cbc _ %+ BORINGSSL_PREFIX %+ _EVP_rc2_40_cbc %xdefine _EVP_rc2_cbc _ %+ BORINGSSL_PREFIX %+ _EVP_rc2_cbc @@ -1863,6 +1926,8 @@ %xdefine _FIPS_module_name _ %+ BORINGSSL_PREFIX %+ _FIPS_module_name %xdefine _FIPS_query_algorithm_status _ %+ BORINGSSL_PREFIX %+ _FIPS_query_algorithm_status %xdefine _FIPS_read_counter _ %+ BORINGSSL_PREFIX %+ _FIPS_read_counter +%xdefine _FIPS_service_indicator_after_call _ %+ BORINGSSL_PREFIX %+ _FIPS_service_indicator_after_call +%xdefine _FIPS_service_indicator_before_call _ %+ BORINGSSL_PREFIX %+ _FIPS_service_indicator_before_call %xdefine _FIPS_version _ %+ BORINGSSL_PREFIX %+ _FIPS_version %xdefine _gcm_ghash_avx _ %+ BORINGSSL_PREFIX %+ _gcm_ghash_avx %xdefine _gcm_ghash_clmul _ %+ BORINGSSL_PREFIX %+ _gcm_ghash_clmul @@ -2038,7 +2103,6 @@ %xdefine _i2d_X509_AUX _ %+ BORINGSSL_PREFIX %+ _i2d_X509_AUX %xdefine _i2d_X509_bio _ %+ BORINGSSL_PREFIX %+ _i2d_X509_bio %xdefine _i2d_X509_CERT_AUX _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CERT_AUX -%xdefine _i2d_X509_CINF _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CINF %xdefine _i2d_X509_CRL _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL %xdefine _i2d_X509_CRL_bio _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL_bio %xdefine _i2d_X509_CRL_fp _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL_fp @@ -2056,7 +2120,6 @@ %xdefine _i2d_X509_REVOKED _ %+ BORINGSSL_PREFIX %+ _i2d_X509_REVOKED %xdefine _i2d_X509_SIG _ %+ BORINGSSL_PREFIX %+ _i2d_X509_SIG %xdefine _i2d_X509_tbs _ %+ BORINGSSL_PREFIX %+ _i2d_X509_tbs -%xdefine _i2d_X509_VAL _ %+ BORINGSSL_PREFIX %+ _i2d_X509_VAL %xdefine _i2o_ECPublicKey _ %+ BORINGSSL_PREFIX %+ _i2o_ECPublicKey %xdefine _i2s_ASN1_ENUMERATED _ %+ BORINGSSL_PREFIX %+ _i2s_ASN1_ENUMERATED %xdefine _i2s_ASN1_INTEGER _ %+ BORINGSSL_PREFIX %+ _i2s_ASN1_INTEGER @@ -2120,6 +2183,17 @@ %xdefine _MD5_Update _ %+ BORINGSSL_PREFIX %+ _MD5_Update %xdefine _METHOD_ref _ %+ BORINGSSL_PREFIX %+ _METHOD_ref %xdefine _METHOD_unref _ %+ BORINGSSL_PREFIX %+ _METHOD_unref +%xdefine _MLDSA44_generate_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_generate_key +%xdefine _MLDSA44_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_marshal_public_key +%xdefine _MLDSA44_parse_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_parse_public_key +%xdefine _MLDSA44_prehash_finalize _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_finalize +%xdefine _MLDSA44_prehash_init _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_init +%xdefine _MLDSA44_prehash_update _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_update +%xdefine _MLDSA44_private_key_from_seed _ %+ BORINGSSL_PREFIX %+ _MLDSA44_private_key_from_seed +%xdefine _MLDSA44_public_from_private _ %+ BORINGSSL_PREFIX %+ _MLDSA44_public_from_private +%xdefine _MLDSA44_sign _ %+ BORINGSSL_PREFIX %+ _MLDSA44_sign +%xdefine _MLDSA44_sign_message_representative _ %+ BORINGSSL_PREFIX %+ _MLDSA44_sign_message_representative +%xdefine _MLDSA44_verify _ %+ BORINGSSL_PREFIX %+ _MLDSA44_verify %xdefine _MLDSA65_generate_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_generate_key %xdefine _MLDSA65_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_marshal_public_key %xdefine _MLDSA65_parse_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_parse_public_key @@ -2517,6 +2591,7 @@ %xdefine _rsa_invalidate_key _ %+ BORINGSSL_PREFIX %+ _rsa_invalidate_key %xdefine _RSA_is_opaque _ %+ BORINGSSL_PREFIX %+ _RSA_is_opaque %xdefine _RSA_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _RSA_marshal_private_key +%xdefine _rsa_marshal_pss_params _ %+ BORINGSSL_PREFIX %+ _rsa_marshal_pss_params %xdefine _RSA_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _RSA_marshal_public_key %xdefine _RSA_new _ %+ BORINGSSL_PREFIX %+ _RSA_new %xdefine _RSA_new_method _ %+ BORINGSSL_PREFIX %+ _RSA_new_method @@ -2534,6 +2609,7 @@ %xdefine _RSA_padding_check_PKCS1_OAEP_mgf1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine _RSA_padding_check_PKCS1_type_1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 %xdefine _RSA_parse_private_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_private_key +%xdefine _rsa_parse_pss_params _ %+ BORINGSSL_PREFIX %+ _rsa_parse_pss_params %xdefine _RSA_parse_public_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine _rsa_pkey_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pkey_meth %xdefine _RSA_print _ %+ BORINGSSL_PREFIX %+ _RSA_print @@ -2544,8 +2620,11 @@ %xdefine _rsa_private_transform _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform %xdefine _rsa_private_transform_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine _RSA_PSS_PARAMS_free _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_free +%xdefine _rsa_pss_params_get_md _ %+ BORINGSSL_PREFIX %+ _rsa_pss_params_get_md %xdefine _RSA_PSS_PARAMS_it _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_it %xdefine _RSA_PSS_PARAMS_new _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new +%xdefine _rsa_pss_sha256_asn1_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pss_sha256_asn1_meth +%xdefine _rsa_pss_sha256_pkey_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pss_sha256_pkey_meth %xdefine _RSA_public_decrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine _RSA_public_encrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine _RSA_public_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -2995,10 +3074,13 @@ %xdefine _X509_add1_ext_i2d _ %+ BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine _X509_add1_reject_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine _X509_add1_trust_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_trust_object +%xdefine _x509_algor_cleanup _ %+ BORINGSSL_PREFIX %+ _x509_algor_cleanup %xdefine _X509_ALGOR_cmp _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_cmp +%xdefine _X509_ALGOR_copy _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_copy %xdefine _X509_ALGOR_dup _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine _X509_ALGOR_free _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_free %xdefine _X509_ALGOR_get0 _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_get0 +%xdefine _x509_algor_init _ %+ BORINGSSL_PREFIX %+ _x509_algor_init %xdefine _X509_ALGOR_it _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_it %xdefine _X509_ALGOR_new _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_new %xdefine _X509_ALGOR_set_md _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_set_md @@ -3035,9 +3117,6 @@ %xdefine _X509_check_private_key _ %+ BORINGSSL_PREFIX %+ _X509_check_private_key %xdefine _X509_check_purpose _ %+ BORINGSSL_PREFIX %+ _X509_check_purpose %xdefine _X509_check_trust _ %+ BORINGSSL_PREFIX %+ _X509_check_trust -%xdefine _X509_CINF_free _ %+ BORINGSSL_PREFIX %+ _X509_CINF_free -%xdefine _X509_CINF_it _ %+ BORINGSSL_PREFIX %+ _X509_CINF_it -%xdefine _X509_CINF_new _ %+ BORINGSSL_PREFIX %+ _X509_CINF_new %xdefine _X509_cmp _ %+ BORINGSSL_PREFIX %+ _X509_cmp %xdefine _X509_cmp_current_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine _X509_cmp_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_time @@ -3173,6 +3252,8 @@ %xdefine _X509_LOOKUP_load_file _ %+ BORINGSSL_PREFIX %+ _X509_LOOKUP_load_file %xdefine _x509_marshal_algorithm _ %+ BORINGSSL_PREFIX %+ _x509_marshal_algorithm %xdefine _x509_marshal_name _ %+ BORINGSSL_PREFIX %+ _x509_marshal_name +%xdefine _x509_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _x509_marshal_public_key +%xdefine _x509_marshal_tbs_cert _ %+ BORINGSSL_PREFIX %+ _x509_marshal_tbs_cert %xdefine _X509_NAME_add_entry _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry %xdefine _X509_NAME_add_entry_by_NID _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_NID %xdefine _X509_NAME_add_entry_by_OBJ _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_OBJ @@ -3216,23 +3297,29 @@ %xdefine _X509_OBJECT_get_type _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_get_type %xdefine _X509_OBJECT_get0_X509 _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_get0_X509 %xdefine _X509_OBJECT_new _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_new +%xdefine _x509_parse_algorithm _ %+ BORINGSSL_PREFIX %+ _x509_parse_algorithm %xdefine _X509_parse_from_buffer _ %+ BORINGSSL_PREFIX %+ _X509_parse_from_buffer +%xdefine _x509_parse_public_key _ %+ BORINGSSL_PREFIX %+ _x509_parse_public_key +%xdefine _X509_parse_with_algorithms _ %+ BORINGSSL_PREFIX %+ _X509_parse_with_algorithms %xdefine _X509_policy_check _ %+ BORINGSSL_PREFIX %+ _X509_policy_check %xdefine _X509_print _ %+ BORINGSSL_PREFIX %+ _X509_print %xdefine _X509_print_ex _ %+ BORINGSSL_PREFIX %+ _X509_print_ex %xdefine _X509_print_ex_fp _ %+ BORINGSSL_PREFIX %+ _X509_print_ex_fp %xdefine _X509_print_fp _ %+ BORINGSSL_PREFIX %+ _X509_print_fp %xdefine _x509_print_rsa_pss_params _ %+ BORINGSSL_PREFIX %+ _x509_print_rsa_pss_params +%xdefine _x509_pubkey_cleanup _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_cleanup %xdefine _X509_pubkey_digest _ %+ BORINGSSL_PREFIX %+ _X509_pubkey_digest %xdefine _X509_PUBKEY_free _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine _X509_PUBKEY_get _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine _X509_PUBKEY_get0 _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0 %xdefine _X509_PUBKEY_get0_param _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param %xdefine _X509_PUBKEY_get0_public_key _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_public_key +%xdefine _x509_pubkey_init _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_init %xdefine _X509_PUBKEY_it _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_it %xdefine _X509_PUBKEY_new _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_new %xdefine _X509_PUBKEY_set _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_set %xdefine _X509_PUBKEY_set0_param _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_set0_param +%xdefine _x509_pubkey_set1 _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_set1 %xdefine _X509_PURPOSE_get_by_sname _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_by_sname %xdefine _X509_PURPOSE_get_id _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_id %xdefine _X509_PURPOSE_get_trust _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_trust @@ -3316,6 +3403,7 @@ %xdefine _X509_SIG_new _ %+ BORINGSSL_PREFIX %+ _X509_SIG_new %xdefine _X509_sign _ %+ BORINGSSL_PREFIX %+ _X509_sign %xdefine _X509_sign_ctx _ %+ BORINGSSL_PREFIX %+ _X509_sign_ctx +%xdefine _x509_sign_to_bit_string _ %+ BORINGSSL_PREFIX %+ _x509_sign_to_bit_string %xdefine _X509_signature_dump _ %+ BORINGSSL_PREFIX %+ _X509_signature_dump %xdefine _X509_signature_print _ %+ BORINGSSL_PREFIX %+ _X509_signature_print %xdefine _X509_STORE_add_cert _ %+ BORINGSSL_PREFIX %+ _X509_STORE_add_cert @@ -3380,9 +3468,6 @@ %xdefine _X509_time_adj_ex _ %+ BORINGSSL_PREFIX %+ _X509_time_adj_ex %xdefine _X509_trust_clear _ %+ BORINGSSL_PREFIX %+ _X509_trust_clear %xdefine _X509_up_ref _ %+ BORINGSSL_PREFIX %+ _X509_up_ref -%xdefine _X509_VAL_free _ %+ BORINGSSL_PREFIX %+ _X509_VAL_free -%xdefine _X509_VAL_it _ %+ BORINGSSL_PREFIX %+ _X509_VAL_it -%xdefine _X509_VAL_new _ %+ BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine _X509_verify _ %+ BORINGSSL_PREFIX %+ _X509_verify %xdefine _X509_verify_cert _ %+ BORINGSSL_PREFIX %+ _X509_verify_cert %xdefine _X509_verify_cert_error_string _ %+ BORINGSSL_PREFIX %+ _X509_verify_cert_error_string @@ -3408,6 +3493,7 @@ %xdefine _X509_VERIFY_PARAM_set1_ip _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip %xdefine _X509_VERIFY_PARAM_set1_ip_asc _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip_asc %xdefine _X509_VERIFY_PARAM_set1_policies _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_policies +%xdefine _x509_verify_signature _ %+ BORINGSSL_PREFIX %+ _x509_verify_signature %xdefine _x509v3_a2i_ipadd _ %+ BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine _X509v3_add_ext _ %+ BORINGSSL_PREFIX %+ _X509v3_add_ext %xdefine _X509V3_add_standard_extensions _ %+ BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions @@ -3609,8 +3695,12 @@ %xdefine ASN1_item_sign_ctx BORINGSSL_PREFIX %+ _ASN1_item_sign_ctx %xdefine ASN1_item_unpack BORINGSSL_PREFIX %+ _ASN1_item_unpack %xdefine ASN1_item_verify BORINGSSL_PREFIX %+ _ASN1_item_verify +%xdefine asn1_marshal_any BORINGSSL_PREFIX %+ _asn1_marshal_any %xdefine asn1_marshal_bit_string BORINGSSL_PREFIX %+ _asn1_marshal_bit_string %xdefine asn1_marshal_integer BORINGSSL_PREFIX %+ _asn1_marshal_integer +%xdefine asn1_marshal_object BORINGSSL_PREFIX %+ _asn1_marshal_object +%xdefine asn1_marshal_octet_string BORINGSSL_PREFIX %+ _asn1_marshal_octet_string +%xdefine asn1_marshal_time BORINGSSL_PREFIX %+ _asn1_marshal_time %xdefine ASN1_mbstring_copy BORINGSSL_PREFIX %+ _ASN1_mbstring_copy %xdefine ASN1_mbstring_ncopy BORINGSSL_PREFIX %+ _ASN1_mbstring_ncopy %xdefine ASN1_NULL_free BORINGSSL_PREFIX %+ _ASN1_NULL_free @@ -3627,6 +3717,20 @@ %xdefine ASN1_OCTET_STRING_it BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_it %xdefine ASN1_OCTET_STRING_new BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_new %xdefine ASN1_OCTET_STRING_set BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_set +%xdefine asn1_parse_any BORINGSSL_PREFIX %+ _asn1_parse_any +%xdefine asn1_parse_any_as_string BORINGSSL_PREFIX %+ _asn1_parse_any_as_string +%xdefine asn1_parse_bit_string BORINGSSL_PREFIX %+ _asn1_parse_bit_string +%xdefine asn1_parse_bit_string_with_bad_length BORINGSSL_PREFIX %+ _asn1_parse_bit_string_with_bad_length +%xdefine asn1_parse_bmp_string BORINGSSL_PREFIX %+ _asn1_parse_bmp_string +%xdefine asn1_parse_enumerated BORINGSSL_PREFIX %+ _asn1_parse_enumerated +%xdefine asn1_parse_generalized_time BORINGSSL_PREFIX %+ _asn1_parse_generalized_time +%xdefine asn1_parse_integer BORINGSSL_PREFIX %+ _asn1_parse_integer +%xdefine asn1_parse_object BORINGSSL_PREFIX %+ _asn1_parse_object +%xdefine asn1_parse_octet_string BORINGSSL_PREFIX %+ _asn1_parse_octet_string +%xdefine asn1_parse_time BORINGSSL_PREFIX %+ _asn1_parse_time +%xdefine asn1_parse_universal_string BORINGSSL_PREFIX %+ _asn1_parse_universal_string +%xdefine asn1_parse_utc_time BORINGSSL_PREFIX %+ _asn1_parse_utc_time +%xdefine asn1_parse_utf8_string BORINGSSL_PREFIX %+ _asn1_parse_utf8_string %xdefine ASN1_primitive_free BORINGSSL_PREFIX %+ _ASN1_primitive_free %xdefine ASN1_PRINTABLESTRING_free BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_free %xdefine ASN1_PRINTABLESTRING_it BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_it @@ -3637,6 +3741,7 @@ %xdefine asn1_refcount_set_one BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine ASN1_SEQUENCE_it BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine asn1_set_choice_selector BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine asn1_string_cleanup BORINGSSL_PREFIX %+ _asn1_string_cleanup %xdefine ASN1_STRING_cmp BORINGSSL_PREFIX %+ _ASN1_STRING_cmp %xdefine ASN1_STRING_copy BORINGSSL_PREFIX %+ _ASN1_STRING_copy %xdefine ASN1_STRING_data BORINGSSL_PREFIX %+ _ASN1_STRING_data @@ -3644,6 +3749,7 @@ %xdefine ASN1_STRING_free BORINGSSL_PREFIX %+ _ASN1_STRING_free %xdefine ASN1_STRING_get_default_mask BORINGSSL_PREFIX %+ _ASN1_STRING_get_default_mask %xdefine ASN1_STRING_get0_data BORINGSSL_PREFIX %+ _ASN1_STRING_get0_data +%xdefine asn1_string_init BORINGSSL_PREFIX %+ _asn1_string_init %xdefine ASN1_STRING_length BORINGSSL_PREFIX %+ _ASN1_STRING_length %xdefine ASN1_STRING_new BORINGSSL_PREFIX %+ _ASN1_STRING_new %xdefine ASN1_STRING_print BORINGSSL_PREFIX %+ _ASN1_STRING_print @@ -3724,6 +3830,26 @@ %xdefine bcm_as_approved_status BORINGSSL_PREFIX %+ _bcm_as_approved_status %xdefine bcm_as_not_approved_status BORINGSSL_PREFIX %+ _bcm_as_not_approved_status %xdefine BCM_fips_186_2_prf BORINGSSL_PREFIX %+ _BCM_fips_186_2_prf +%xdefine BCM_mldsa44_check_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_check_key_fips +%xdefine BCM_mldsa44_generate_key BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key +%xdefine BCM_mldsa44_generate_key_external_entropy BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy +%xdefine BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy_fips +%xdefine BCM_mldsa44_generate_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_fips +%xdefine BCM_mldsa44_marshal_private_key BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_private_key +%xdefine BCM_mldsa44_marshal_public_key BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_public_key +%xdefine BCM_mldsa44_parse_private_key BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_private_key +%xdefine BCM_mldsa44_parse_public_key BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_public_key +%xdefine BCM_mldsa44_prehash_finalize BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_finalize +%xdefine BCM_mldsa44_prehash_init BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_init +%xdefine BCM_mldsa44_prehash_update BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_update +%xdefine BCM_mldsa44_private_key_from_seed BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed +%xdefine BCM_mldsa44_private_key_from_seed_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed_fips +%xdefine BCM_mldsa44_public_from_private BORINGSSL_PREFIX %+ _BCM_mldsa44_public_from_private +%xdefine BCM_mldsa44_sign BORINGSSL_PREFIX %+ _BCM_mldsa44_sign +%xdefine BCM_mldsa44_sign_internal BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_internal +%xdefine BCM_mldsa44_sign_message_representative BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_message_representative +%xdefine BCM_mldsa44_verify BORINGSSL_PREFIX %+ _BCM_mldsa44_verify +%xdefine BCM_mldsa44_verify_internal BORINGSSL_PREFIX %+ _BCM_mldsa44_verify_internal %xdefine BCM_mldsa65_check_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa65_check_key_fips %xdefine BCM_mldsa65_generate_key BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key %xdefine BCM_mldsa65_generate_key_external_entropy BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key_external_entropy @@ -4074,9 +4200,9 @@ %xdefine bn_mul_comba4 BORINGSSL_PREFIX %+ _bn_mul_comba4 %xdefine bn_mul_comba8 BORINGSSL_PREFIX %+ _bn_mul_comba8 %xdefine bn_mul_consttime BORINGSSL_PREFIX %+ _bn_mul_consttime -%xdefine bn_mul_mont BORINGSSL_PREFIX %+ _bn_mul_mont %xdefine bn_mul_mont_gather5_nohw BORINGSSL_PREFIX %+ _bn_mul_mont_gather5_nohw %xdefine bn_mul_mont_nohw BORINGSSL_PREFIX %+ _bn_mul_mont_nohw +%xdefine bn_mul_mont_words BORINGSSL_PREFIX %+ _bn_mul_mont_words %xdefine bn_mul_small BORINGSSL_PREFIX %+ _bn_mul_small %xdefine BN_mul_word BORINGSSL_PREFIX %+ _BN_mul_word %xdefine bn_mul_words BORINGSSL_PREFIX %+ _bn_mul_words @@ -4324,6 +4450,7 @@ %xdefine CMS_sign BORINGSSL_PREFIX %+ _CMS_sign %xdefine CONF_modules_free BORINGSSL_PREFIX %+ _CONF_modules_free %xdefine CONF_modules_load_file BORINGSSL_PREFIX %+ _CONF_modules_load_file +%xdefine CONF_modules_unload BORINGSSL_PREFIX %+ _CONF_modules_unload %xdefine CONF_parse_list BORINGSSL_PREFIX %+ _CONF_parse_list %xdefine CONF_VALUE_new BORINGSSL_PREFIX %+ _CONF_VALUE_new %xdefine CRL_DIST_POINTS_free BORINGSSL_PREFIX %+ _CRL_DIST_POINTS_free @@ -4458,7 +4585,9 @@ %xdefine CTR_DRBG_generate BORINGSSL_PREFIX %+ _CTR_DRBG_generate %xdefine CTR_DRBG_init BORINGSSL_PREFIX %+ _CTR_DRBG_init %xdefine CTR_DRBG_new BORINGSSL_PREFIX %+ _CTR_DRBG_new +%xdefine CTR_DRBG_new_df BORINGSSL_PREFIX %+ _CTR_DRBG_new_df %xdefine CTR_DRBG_reseed BORINGSSL_PREFIX %+ _CTR_DRBG_reseed +%xdefine CTR_DRBG_reseed_ex BORINGSSL_PREFIX %+ _CTR_DRBG_reseed_ex %xdefine d2i_ASN1_BIT_STRING BORINGSSL_PREFIX %+ _d2i_ASN1_BIT_STRING %xdefine d2i_ASN1_BMPSTRING BORINGSSL_PREFIX %+ _d2i_ASN1_BMPSTRING %xdefine d2i_ASN1_BOOLEAN BORINGSSL_PREFIX %+ _d2i_ASN1_BOOLEAN @@ -4549,7 +4678,6 @@ %xdefine d2i_X509_AUX BORINGSSL_PREFIX %+ _d2i_X509_AUX %xdefine d2i_X509_bio BORINGSSL_PREFIX %+ _d2i_X509_bio %xdefine d2i_X509_CERT_AUX BORINGSSL_PREFIX %+ _d2i_X509_CERT_AUX -%xdefine d2i_X509_CINF BORINGSSL_PREFIX %+ _d2i_X509_CINF %xdefine d2i_X509_CRL BORINGSSL_PREFIX %+ _d2i_X509_CRL %xdefine d2i_X509_CRL_bio BORINGSSL_PREFIX %+ _d2i_X509_CRL_bio %xdefine d2i_X509_CRL_fp BORINGSSL_PREFIX %+ _d2i_X509_CRL_fp @@ -4565,7 +4693,6 @@ %xdefine d2i_X509_REQ_INFO BORINGSSL_PREFIX %+ _d2i_X509_REQ_INFO %xdefine d2i_X509_REVOKED BORINGSSL_PREFIX %+ _d2i_X509_REVOKED %xdefine d2i_X509_SIG BORINGSSL_PREFIX %+ _d2i_X509_SIG -%xdefine d2i_X509_VAL BORINGSSL_PREFIX %+ _d2i_X509_VAL %xdefine DES_decrypt3 BORINGSSL_PREFIX %+ _DES_decrypt3 %xdefine DES_ecb_encrypt BORINGSSL_PREFIX %+ _DES_ecb_encrypt %xdefine DES_ecb_encrypt_ex BORINGSSL_PREFIX %+ _DES_ecb_encrypt_ex @@ -4773,8 +4900,11 @@ %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_curve_name BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name +%xdefine ec_key_parse_parameters BORINGSSL_PREFIX %+ _ec_key_parse_parameters %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_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 @@ -4909,6 +5039,7 @@ %xdefine ED25519_verify BORINGSSL_PREFIX %+ _ED25519_verify %xdefine EDIPARTYNAME_free BORINGSSL_PREFIX %+ _EDIPARTYNAME_free %xdefine EDIPARTYNAME_new BORINGSSL_PREFIX %+ _EDIPARTYNAME_new +%xdefine ENGINE_cleanup BORINGSSL_PREFIX %+ _ENGINE_cleanup %xdefine ENGINE_free BORINGSSL_PREFIX %+ _ENGINE_free %xdefine ENGINE_get_ECDSA_method BORINGSSL_PREFIX %+ _ENGINE_get_ECDSA_method %xdefine ENGINE_get_RSA_method BORINGSSL_PREFIX %+ _ENGINE_get_RSA_method @@ -4921,6 +5052,7 @@ %xdefine ERR_add_error_dataf BORINGSSL_PREFIX %+ _ERR_add_error_dataf %xdefine ERR_clear_error BORINGSSL_PREFIX %+ _ERR_clear_error %xdefine ERR_clear_system_error BORINGSSL_PREFIX %+ _ERR_clear_system_error +%xdefine ERR_equals BORINGSSL_PREFIX %+ _ERR_equals %xdefine ERR_error_string BORINGSSL_PREFIX %+ _ERR_error_string %xdefine ERR_error_string_n BORINGSSL_PREFIX %+ _ERR_error_string_n %xdefine ERR_free_strings BORINGSSL_PREFIX %+ _ERR_free_strings @@ -5147,6 +5279,7 @@ %xdefine EVP_HPKE_KEY_zero BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_zero %xdefine EVP_hpke_p256_hkdf_sha256 BORINGSSL_PREFIX %+ _EVP_hpke_p256_hkdf_sha256 %xdefine EVP_hpke_x25519_hkdf_sha256 BORINGSSL_PREFIX %+ _EVP_hpke_x25519_hkdf_sha256 +%xdefine EVP_hpke_xwing BORINGSSL_PREFIX %+ _EVP_hpke_xwing %xdefine EVP_marshal_digest_algorithm BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm %xdefine EVP_marshal_digest_algorithm_no_params BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm_no_params %xdefine EVP_marshal_private_key BORINGSSL_PREFIX %+ _EVP_marshal_private_key @@ -5178,6 +5311,7 @@ %xdefine EVP_md5 BORINGSSL_PREFIX %+ _EVP_md5 %xdefine EVP_md5_sha1 BORINGSSL_PREFIX %+ _EVP_md5_sha1 %xdefine EVP_parse_digest_algorithm BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm +%xdefine EVP_parse_digest_algorithm_nid BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm_nid %xdefine EVP_parse_private_key BORINGSSL_PREFIX %+ _EVP_parse_private_key %xdefine EVP_parse_public_key BORINGSSL_PREFIX %+ _EVP_parse_public_key %xdefine EVP_PBE_scrypt BORINGSSL_PREFIX %+ _EVP_PBE_scrypt @@ -5230,9 +5364,21 @@ %xdefine EVP_PKEY_derive BORINGSSL_PREFIX %+ _EVP_PKEY_derive %xdefine EVP_PKEY_derive_init BORINGSSL_PREFIX %+ _EVP_PKEY_derive_init %xdefine EVP_PKEY_derive_set_peer BORINGSSL_PREFIX %+ _EVP_PKEY_derive_set_peer +%xdefine EVP_pkey_dsa BORINGSSL_PREFIX %+ _EVP_pkey_dsa +%xdefine EVP_pkey_ec_p224 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p224 +%xdefine EVP_pkey_ec_p256 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p256 +%xdefine EVP_pkey_ec_p384 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p384 +%xdefine EVP_pkey_ec_p521 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p521 +%xdefine EVP_pkey_ed25519 BORINGSSL_PREFIX %+ _EVP_pkey_ed25519 %xdefine EVP_PKEY_encrypt BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt %xdefine EVP_PKEY_encrypt_init BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt_init %xdefine EVP_PKEY_free BORINGSSL_PREFIX %+ _EVP_PKEY_free +%xdefine EVP_PKEY_from_private_key_info BORINGSSL_PREFIX %+ _EVP_PKEY_from_private_key_info +%xdefine EVP_PKEY_from_raw_private_key BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_private_key +%xdefine EVP_PKEY_from_raw_public_key BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_public_key +%xdefine EVP_PKEY_from_subject_public_key_info BORINGSSL_PREFIX %+ _EVP_PKEY_from_subject_public_key_info +%xdefine EVP_PKEY_get_ec_curve_nid BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_curve_nid +%xdefine EVP_PKEY_get_ec_point_conv_form BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_point_conv_form %xdefine EVP_PKEY_get_raw_private_key BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_private_key %xdefine EVP_PKEY_get_raw_public_key BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_public_key %xdefine EVP_PKEY_get0 BORINGSSL_PREFIX %+ _EVP_PKEY_get0 @@ -5258,8 +5404,10 @@ %xdefine EVP_PKEY_print_params BORINGSSL_PREFIX %+ _EVP_PKEY_print_params %xdefine EVP_PKEY_print_private BORINGSSL_PREFIX %+ _EVP_PKEY_print_private %xdefine EVP_PKEY_print_public BORINGSSL_PREFIX %+ _EVP_PKEY_print_public -%xdefine evp_pkey_set_method BORINGSSL_PREFIX %+ _evp_pkey_set_method +%xdefine EVP_pkey_rsa BORINGSSL_PREFIX %+ _EVP_pkey_rsa +%xdefine EVP_pkey_rsa_pss_sha256 BORINGSSL_PREFIX %+ _EVP_pkey_rsa_pss_sha256 %xdefine EVP_PKEY_set_type BORINGSSL_PREFIX %+ _EVP_PKEY_set_type +%xdefine evp_pkey_set0 BORINGSSL_PREFIX %+ _evp_pkey_set0 %xdefine EVP_PKEY_set1_DH BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DH %xdefine EVP_PKEY_set1_DSA BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DSA %xdefine EVP_PKEY_set1_EC_KEY BORINGSSL_PREFIX %+ _EVP_PKEY_set1_EC_KEY @@ -5274,6 +5422,7 @@ %xdefine EVP_PKEY_verify_init BORINGSSL_PREFIX %+ _EVP_PKEY_verify_init %xdefine EVP_PKEY_verify_recover BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover %xdefine EVP_PKEY_verify_recover_init BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover_init +%xdefine EVP_pkey_x25519 BORINGSSL_PREFIX %+ _EVP_pkey_x25519 %xdefine EVP_PKEY2PKCS8 BORINGSSL_PREFIX %+ _EVP_PKEY2PKCS8 %xdefine EVP_rc2_40_cbc BORINGSSL_PREFIX %+ _EVP_rc2_40_cbc %xdefine EVP_rc2_cbc BORINGSSL_PREFIX %+ _EVP_rc2_cbc @@ -5310,6 +5459,8 @@ %xdefine FIPS_module_name BORINGSSL_PREFIX %+ _FIPS_module_name %xdefine FIPS_query_algorithm_status BORINGSSL_PREFIX %+ _FIPS_query_algorithm_status %xdefine FIPS_read_counter BORINGSSL_PREFIX %+ _FIPS_read_counter +%xdefine FIPS_service_indicator_after_call BORINGSSL_PREFIX %+ _FIPS_service_indicator_after_call +%xdefine FIPS_service_indicator_before_call BORINGSSL_PREFIX %+ _FIPS_service_indicator_before_call %xdefine FIPS_version BORINGSSL_PREFIX %+ _FIPS_version %xdefine gcm_ghash_avx BORINGSSL_PREFIX %+ _gcm_ghash_avx %xdefine gcm_ghash_clmul BORINGSSL_PREFIX %+ _gcm_ghash_clmul @@ -5485,7 +5636,6 @@ %xdefine i2d_X509_AUX BORINGSSL_PREFIX %+ _i2d_X509_AUX %xdefine i2d_X509_bio BORINGSSL_PREFIX %+ _i2d_X509_bio %xdefine i2d_X509_CERT_AUX BORINGSSL_PREFIX %+ _i2d_X509_CERT_AUX -%xdefine i2d_X509_CINF BORINGSSL_PREFIX %+ _i2d_X509_CINF %xdefine i2d_X509_CRL BORINGSSL_PREFIX %+ _i2d_X509_CRL %xdefine i2d_X509_CRL_bio BORINGSSL_PREFIX %+ _i2d_X509_CRL_bio %xdefine i2d_X509_CRL_fp BORINGSSL_PREFIX %+ _i2d_X509_CRL_fp @@ -5503,7 +5653,6 @@ %xdefine i2d_X509_REVOKED BORINGSSL_PREFIX %+ _i2d_X509_REVOKED %xdefine i2d_X509_SIG BORINGSSL_PREFIX %+ _i2d_X509_SIG %xdefine i2d_X509_tbs BORINGSSL_PREFIX %+ _i2d_X509_tbs -%xdefine i2d_X509_VAL BORINGSSL_PREFIX %+ _i2d_X509_VAL %xdefine i2o_ECPublicKey BORINGSSL_PREFIX %+ _i2o_ECPublicKey %xdefine i2s_ASN1_ENUMERATED BORINGSSL_PREFIX %+ _i2s_ASN1_ENUMERATED %xdefine i2s_ASN1_INTEGER BORINGSSL_PREFIX %+ _i2s_ASN1_INTEGER @@ -5567,6 +5716,17 @@ %xdefine MD5_Update BORINGSSL_PREFIX %+ _MD5_Update %xdefine METHOD_ref BORINGSSL_PREFIX %+ _METHOD_ref %xdefine METHOD_unref BORINGSSL_PREFIX %+ _METHOD_unref +%xdefine MLDSA44_generate_key BORINGSSL_PREFIX %+ _MLDSA44_generate_key +%xdefine MLDSA44_marshal_public_key BORINGSSL_PREFIX %+ _MLDSA44_marshal_public_key +%xdefine MLDSA44_parse_public_key BORINGSSL_PREFIX %+ _MLDSA44_parse_public_key +%xdefine MLDSA44_prehash_finalize BORINGSSL_PREFIX %+ _MLDSA44_prehash_finalize +%xdefine MLDSA44_prehash_init BORINGSSL_PREFIX %+ _MLDSA44_prehash_init +%xdefine MLDSA44_prehash_update BORINGSSL_PREFIX %+ _MLDSA44_prehash_update +%xdefine MLDSA44_private_key_from_seed BORINGSSL_PREFIX %+ _MLDSA44_private_key_from_seed +%xdefine MLDSA44_public_from_private BORINGSSL_PREFIX %+ _MLDSA44_public_from_private +%xdefine MLDSA44_sign BORINGSSL_PREFIX %+ _MLDSA44_sign +%xdefine MLDSA44_sign_message_representative BORINGSSL_PREFIX %+ _MLDSA44_sign_message_representative +%xdefine MLDSA44_verify BORINGSSL_PREFIX %+ _MLDSA44_verify %xdefine MLDSA65_generate_key BORINGSSL_PREFIX %+ _MLDSA65_generate_key %xdefine MLDSA65_marshal_public_key BORINGSSL_PREFIX %+ _MLDSA65_marshal_public_key %xdefine MLDSA65_parse_public_key BORINGSSL_PREFIX %+ _MLDSA65_parse_public_key @@ -5964,6 +6124,7 @@ %xdefine rsa_invalidate_key BORINGSSL_PREFIX %+ _rsa_invalidate_key %xdefine RSA_is_opaque BORINGSSL_PREFIX %+ _RSA_is_opaque %xdefine RSA_marshal_private_key BORINGSSL_PREFIX %+ _RSA_marshal_private_key +%xdefine rsa_marshal_pss_params BORINGSSL_PREFIX %+ _rsa_marshal_pss_params %xdefine RSA_marshal_public_key BORINGSSL_PREFIX %+ _RSA_marshal_public_key %xdefine RSA_new BORINGSSL_PREFIX %+ _RSA_new %xdefine RSA_new_method BORINGSSL_PREFIX %+ _RSA_new_method @@ -5981,6 +6142,7 @@ %xdefine RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine RSA_padding_check_PKCS1_type_1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 %xdefine RSA_parse_private_key BORINGSSL_PREFIX %+ _RSA_parse_private_key +%xdefine rsa_parse_pss_params BORINGSSL_PREFIX %+ _rsa_parse_pss_params %xdefine RSA_parse_public_key BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine rsa_pkey_meth BORINGSSL_PREFIX %+ _rsa_pkey_meth %xdefine RSA_print BORINGSSL_PREFIX %+ _RSA_print @@ -5991,8 +6153,11 @@ %xdefine rsa_private_transform BORINGSSL_PREFIX %+ _rsa_private_transform %xdefine rsa_private_transform_no_self_test BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine RSA_PSS_PARAMS_free BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_free +%xdefine rsa_pss_params_get_md BORINGSSL_PREFIX %+ _rsa_pss_params_get_md %xdefine RSA_PSS_PARAMS_it BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_it %xdefine RSA_PSS_PARAMS_new BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new +%xdefine rsa_pss_sha256_asn1_meth BORINGSSL_PREFIX %+ _rsa_pss_sha256_asn1_meth +%xdefine rsa_pss_sha256_pkey_meth BORINGSSL_PREFIX %+ _rsa_pss_sha256_pkey_meth %xdefine RSA_public_decrypt BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine RSA_public_encrypt BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine RSA_public_key_from_bytes BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -6442,10 +6607,13 @@ %xdefine X509_add1_ext_i2d BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine X509_add1_reject_object BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine X509_add1_trust_object BORINGSSL_PREFIX %+ _X509_add1_trust_object +%xdefine x509_algor_cleanup BORINGSSL_PREFIX %+ _x509_algor_cleanup %xdefine X509_ALGOR_cmp BORINGSSL_PREFIX %+ _X509_ALGOR_cmp +%xdefine X509_ALGOR_copy BORINGSSL_PREFIX %+ _X509_ALGOR_copy %xdefine X509_ALGOR_dup BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine X509_ALGOR_free BORINGSSL_PREFIX %+ _X509_ALGOR_free %xdefine X509_ALGOR_get0 BORINGSSL_PREFIX %+ _X509_ALGOR_get0 +%xdefine x509_algor_init BORINGSSL_PREFIX %+ _x509_algor_init %xdefine X509_ALGOR_it BORINGSSL_PREFIX %+ _X509_ALGOR_it %xdefine X509_ALGOR_new BORINGSSL_PREFIX %+ _X509_ALGOR_new %xdefine X509_ALGOR_set_md BORINGSSL_PREFIX %+ _X509_ALGOR_set_md @@ -6482,9 +6650,6 @@ %xdefine X509_check_private_key BORINGSSL_PREFIX %+ _X509_check_private_key %xdefine X509_check_purpose BORINGSSL_PREFIX %+ _X509_check_purpose %xdefine X509_check_trust BORINGSSL_PREFIX %+ _X509_check_trust -%xdefine X509_CINF_free BORINGSSL_PREFIX %+ _X509_CINF_free -%xdefine X509_CINF_it BORINGSSL_PREFIX %+ _X509_CINF_it -%xdefine X509_CINF_new BORINGSSL_PREFIX %+ _X509_CINF_new %xdefine X509_cmp BORINGSSL_PREFIX %+ _X509_cmp %xdefine X509_cmp_current_time BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine X509_cmp_time BORINGSSL_PREFIX %+ _X509_cmp_time @@ -6620,6 +6785,8 @@ %xdefine X509_LOOKUP_load_file BORINGSSL_PREFIX %+ _X509_LOOKUP_load_file %xdefine x509_marshal_algorithm BORINGSSL_PREFIX %+ _x509_marshal_algorithm %xdefine x509_marshal_name BORINGSSL_PREFIX %+ _x509_marshal_name +%xdefine x509_marshal_public_key BORINGSSL_PREFIX %+ _x509_marshal_public_key +%xdefine x509_marshal_tbs_cert BORINGSSL_PREFIX %+ _x509_marshal_tbs_cert %xdefine X509_NAME_add_entry BORINGSSL_PREFIX %+ _X509_NAME_add_entry %xdefine X509_NAME_add_entry_by_NID BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_NID %xdefine X509_NAME_add_entry_by_OBJ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_OBJ @@ -6663,23 +6830,29 @@ %xdefine X509_OBJECT_get_type BORINGSSL_PREFIX %+ _X509_OBJECT_get_type %xdefine X509_OBJECT_get0_X509 BORINGSSL_PREFIX %+ _X509_OBJECT_get0_X509 %xdefine X509_OBJECT_new BORINGSSL_PREFIX %+ _X509_OBJECT_new +%xdefine x509_parse_algorithm BORINGSSL_PREFIX %+ _x509_parse_algorithm %xdefine X509_parse_from_buffer BORINGSSL_PREFIX %+ _X509_parse_from_buffer +%xdefine x509_parse_public_key BORINGSSL_PREFIX %+ _x509_parse_public_key +%xdefine X509_parse_with_algorithms BORINGSSL_PREFIX %+ _X509_parse_with_algorithms %xdefine X509_policy_check BORINGSSL_PREFIX %+ _X509_policy_check %xdefine X509_print BORINGSSL_PREFIX %+ _X509_print %xdefine X509_print_ex BORINGSSL_PREFIX %+ _X509_print_ex %xdefine X509_print_ex_fp BORINGSSL_PREFIX %+ _X509_print_ex_fp %xdefine X509_print_fp BORINGSSL_PREFIX %+ _X509_print_fp %xdefine x509_print_rsa_pss_params BORINGSSL_PREFIX %+ _x509_print_rsa_pss_params +%xdefine x509_pubkey_cleanup BORINGSSL_PREFIX %+ _x509_pubkey_cleanup %xdefine X509_pubkey_digest BORINGSSL_PREFIX %+ _X509_pubkey_digest %xdefine X509_PUBKEY_free BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine X509_PUBKEY_get BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine X509_PUBKEY_get0 BORINGSSL_PREFIX %+ _X509_PUBKEY_get0 %xdefine X509_PUBKEY_get0_param BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param %xdefine X509_PUBKEY_get0_public_key BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_public_key +%xdefine x509_pubkey_init BORINGSSL_PREFIX %+ _x509_pubkey_init %xdefine X509_PUBKEY_it BORINGSSL_PREFIX %+ _X509_PUBKEY_it %xdefine X509_PUBKEY_new BORINGSSL_PREFIX %+ _X509_PUBKEY_new %xdefine X509_PUBKEY_set BORINGSSL_PREFIX %+ _X509_PUBKEY_set %xdefine X509_PUBKEY_set0_param BORINGSSL_PREFIX %+ _X509_PUBKEY_set0_param +%xdefine x509_pubkey_set1 BORINGSSL_PREFIX %+ _x509_pubkey_set1 %xdefine X509_PURPOSE_get_by_sname BORINGSSL_PREFIX %+ _X509_PURPOSE_get_by_sname %xdefine X509_PURPOSE_get_id BORINGSSL_PREFIX %+ _X509_PURPOSE_get_id %xdefine X509_PURPOSE_get_trust BORINGSSL_PREFIX %+ _X509_PURPOSE_get_trust @@ -6763,6 +6936,7 @@ %xdefine X509_SIG_new BORINGSSL_PREFIX %+ _X509_SIG_new %xdefine X509_sign BORINGSSL_PREFIX %+ _X509_sign %xdefine X509_sign_ctx BORINGSSL_PREFIX %+ _X509_sign_ctx +%xdefine x509_sign_to_bit_string BORINGSSL_PREFIX %+ _x509_sign_to_bit_string %xdefine X509_signature_dump BORINGSSL_PREFIX %+ _X509_signature_dump %xdefine X509_signature_print BORINGSSL_PREFIX %+ _X509_signature_print %xdefine X509_STORE_add_cert BORINGSSL_PREFIX %+ _X509_STORE_add_cert @@ -6827,9 +7001,6 @@ %xdefine X509_time_adj_ex BORINGSSL_PREFIX %+ _X509_time_adj_ex %xdefine X509_trust_clear BORINGSSL_PREFIX %+ _X509_trust_clear %xdefine X509_up_ref BORINGSSL_PREFIX %+ _X509_up_ref -%xdefine X509_VAL_free BORINGSSL_PREFIX %+ _X509_VAL_free -%xdefine X509_VAL_it BORINGSSL_PREFIX %+ _X509_VAL_it -%xdefine X509_VAL_new BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine X509_verify BORINGSSL_PREFIX %+ _X509_verify %xdefine X509_verify_cert BORINGSSL_PREFIX %+ _X509_verify_cert %xdefine X509_verify_cert_error_string BORINGSSL_PREFIX %+ _X509_verify_cert_error_string @@ -6855,6 +7026,7 @@ %xdefine X509_VERIFY_PARAM_set1_ip BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip %xdefine X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip_asc %xdefine X509_VERIFY_PARAM_set1_policies BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_policies +%xdefine x509_verify_signature BORINGSSL_PREFIX %+ _x509_verify_signature %xdefine x509v3_a2i_ipadd BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine X509v3_add_ext BORINGSSL_PREFIX %+ _X509v3_add_ext %xdefine X509V3_add_standard_extensions BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions diff --git a/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h b/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h deleted file mode 100644 index 43aaaa4de..000000000 --- a/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2023 The BoringSSL Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef OPENSSL_HEADER_KYBER_H -#define OPENSSL_HEADER_KYBER_H - -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export - -#if defined(__cplusplus) -extern "C" { -#endif - - -#if defined(OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER) -// This header implements experimental, draft versions of not-yet-standardized -// primitives. When the standard is complete, these functions will be removed -// and replaced with the final, incompatible standard version. They are -// available now for short-lived experiments, but must not be deployed anywhere -// durable, such as a long-lived key store. To use these functions define -// OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER - -// Kyber768. -// -// This implements the round-3 specification of Kyber, defined at -// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf - - -// KYBER_public_key contains a Kyber768 public key. The contents of this -// object should never leave the address space since the format is unstable. -struct KYBER_public_key { - union { - uint8_t bytes[512 * (3 + 9) + 32 + 32]; - uint16_t alignment; - } opaque; -}; - -// KYBER_private_key contains a Kyber768 private key. The contents of this -// object should never leave the address space since the format is unstable. -struct KYBER_private_key { - union { - uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; - uint16_t alignment; - } opaque; -}; - -// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public -// key. -#define KYBER_PUBLIC_KEY_BYTES 1184 - -// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared -// secret. Although the round-3 specification has a variable-length output, the -// final ML-KEM construction is expected to use a fixed 32-byte output. To -// simplify the future transition, we apply the same restriction. -#define KYBER_SHARED_SECRET_BYTES 32 - -// KYBER_generate_key generates a random public/private key pair, writes the -// encoded public key to |out_encoded_public_key| and sets |out_private_key| to -// the private key. -OPENSSL_EXPORT void KYBER_generate_key( - uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], - struct KYBER_private_key *out_private_key); - -// KYBER_public_from_private sets |*out_public_key| to the public key that -// corresponds to |private_key|. (This is faster than parsing the output of -// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key -// that was just generated.) -OPENSSL_EXPORT void KYBER_public_from_private( - struct KYBER_public_key *out_public_key, - const struct KYBER_private_key *private_key); - -// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. -#define KYBER_CIPHERTEXT_BYTES 1088 - -// KYBER_encap encrypts a random shared secret for |public_key|, writes the -// ciphertext to |out_ciphertext|, and writes the random shared secret to -// |out_shared_secret|. -OPENSSL_EXPORT void KYBER_encap( - uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], - uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], - const struct KYBER_public_key *public_key); - -// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key| -// and writes it to |out_shared_secret|. If |ciphertext| is invalid, -// |out_shared_secret| is filled with a key that will always be the same for the -// same |ciphertext| and |private_key|, but which appears to be random unless -// one has access to |private_key|. These alternatives occur in constant time. -// Any subsequent symmetric encryption using |out_shared_secret| must use an -// authenticated encryption scheme in order to discover the decapsulation -// failure. -OPENSSL_EXPORT void KYBER_decap( - uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], - const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], - const struct KYBER_private_key *private_key); - - -// Serialisation of keys. - -// KYBER_marshal_public_key serializes |public_key| to |out| in the standard -// format for Kyber public keys. It returns one on success or zero on allocation -// error. -OPENSSL_EXPORT int KYBER_marshal_public_key( - CBB *out, const struct KYBER_public_key *public_key); - -// KYBER_parse_public_key parses a public key, in the format generated by -// |KYBER_marshal_public_key|, from |in| and writes the result to -// |out_public_key|. It returns one on success or zero on parse error or if -// there are trailing bytes in |in|. -OPENSSL_EXPORT int KYBER_parse_public_key( - struct KYBER_public_key *out_public_key, CBS *in); - -// KYBER_marshal_private_key serializes |private_key| to |out| in the standard -// format for Kyber private keys. It returns one on success or zero on -// allocation error. -OPENSSL_EXPORT int KYBER_marshal_private_key( - CBB *out, const struct KYBER_private_key *private_key); - -// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by -// |KYBER_marshal_private_key|. -#define KYBER_PRIVATE_KEY_BYTES 2400 - -// KYBER_parse_private_key parses a private key, in the format generated by -// |KYBER_marshal_private_key|, from |in| and writes the result to -// |out_private_key|. It returns one on success or zero on parse error or if -// there are trailing bytes in |in|. -OPENSSL_EXPORT int KYBER_parse_private_key( - struct KYBER_private_key *out_private_key, CBS *in); - -#endif // OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER - - -#if defined(__cplusplus) -} // extern C -#endif - -#endif // OPENSSL_HEADER_KYBER_H diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc new file mode 100644 index 000000000..ec6c3a55d --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc @@ -0,0 +1,66 @@ +// Generated from Bedrock code in Fiat Cryptogrpahy. Avoid editing directly. + +static inline br_word_t br_full_add(br_word_t x, br_word_t y, br_word_t carry, br_word_t* _sum) { + br_word_t carry_out, sum; + x = x+carry; + carry_out = (br_word_t)(x>27)&63)+1)>>1; + M = ((br_word_t)1<<(n&(sizeof(br_word_t)*8-1)))-1; + ll = (a&M)*(b&M); + lh = (a&M)*(b>>(n&(sizeof(br_word_t)*8-1))); + hl = (a>>(n&(sizeof(br_word_t)*8-1)))*(b&M); + hh = (a>>(n&(sizeof(br_word_t)*8-1)))*(b>>(n&(sizeof(br_word_t)*8-1))); + second_halfword_w_oflow = ((ll>>(n&(sizeof(br_word_t)*8-1)))+(lh&M))+(hl&M); + high = ((hh+(lh>>(n&(sizeof(br_word_t)*8-1))))+(hl>>(n&(sizeof(br_word_t)*8-1))))+(second_halfword_w_oflow>>(n&(sizeof(br_word_t)*8-1))); + low = (second_halfword_w_oflow<<(n&(sizeof(br_word_t)*8-1)))+(ll&M); + *_low = low; + return high; +} + +static inline br_word_t br_value_barrier(br_word_t a) { + /*skip*/ + return a; +} + +static inline br_word_t br_declassify(br_word_t a) { + /*skip*/ + return a; +} + +static inline br_word_t br_broadcast_negative(br_word_t x) { + br_word_t y; + y = (br_word_t)((br_signed_t)x>>((((0u-(br_word_t)1)>>27)&63)&(sizeof(br_word_t)*8-1))); + y = br_value_barrier(y); + return y; +} + +static inline br_word_t br_broadcast_nonzero(br_word_t x) { + br_word_t y; + y = br_broadcast_negative(x|(0u-x)); + return y; +} + +static inline br_word_t br_cmov(br_word_t c, br_word_t vnz, br_word_t vz) { + br_word_t r, m; + m = br_broadcast_nonzero(c); + r = (m&vnz)|((~m)&vz); + return r; +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc new file mode 100644 index 000000000..a03388bd0 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc @@ -0,0 +1,47 @@ +#ifndef BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ +#define BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ + +static_assert(sizeof(br_word_t) == sizeof(br_signed_t), ""); +static_assert(UINTPTR_MAX <= BR_WORD_MAX, ""); + +// "An object shall have its stored value accessed only ... a character type." + +static inline br_word_t _br_load1(br_word_t a) { + return *((uint8_t *)a); +} + +static inline br_word_t _br_load2(br_word_t a) { + uint16_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline br_word_t _br_load4(br_word_t a) { + uint32_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline br_word_t _br_load(br_word_t a) { + br_word_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline void _br_store1(br_word_t a, uint8_t v) { + *((uint8_t *)a) = v; +} + +static inline void _br_store2(br_word_t a, uint16_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +static inline void _br_store4(br_word_t a, uint32_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +static inline void _br_store(br_word_t a, br_word_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +#endif // BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc new file mode 100644 index 000000000..89fe7d05d --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc @@ -0,0 +1,125 @@ +#ifndef BEDROCK_UNVERIFIED_PLATFORM_INC_H_ +#define BEDROCK_UNVERIFIED_PLATFORM_INC_H_ + +// This file is a manually maintained and audited replacement for +// bedrock_polyfill_platform.c.inc with tests in bedrock_platform_test.cc + +#include "../../crypto/internal.h" + +#if defined(OPENSSL_64_BIT) +#define BR_WORD_MAX UINT64_MAX +typedef uint64_t br_word_t; +typedef int64_t br_signed_t; +#elif defined(OPENSSL_32_BIT) +#define BR_WORD_MAX UINT32_MAX +typedef uint32_t br_word_t; +typedef int32_t br_signed_t; +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + +// Scalar memory operations + +#include "../../third_party/fiat/bedrock_unverified_bareminimum.c.inc" + +// Bulk memory operations + +static inline void br_memcpy(br_word_t d, br_word_t s, br_word_t n) { + OPENSSL_memcpy((void *)d, (const void *)s, n); +} + +static inline void br_memset(br_word_t d, br_word_t v, br_word_t n) { + OPENSSL_memset((void *)d, v, n); +} + +static inline void br_memcxor(uintptr_t d, uintptr_t s, uintptr_t n, uintptr_t mask) { + constant_time_conditional_memxor((void*)d, (void*)s, n, mask); +} + +// CPU Arithmetic + +static inline br_word_t br_full_add(br_word_t x, br_word_t y, br_word_t carry, + br_word_t *_sum) { + br_word_t carry_out = 0; + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + *_sum = CRYPTO_addc_w(x, y, carry, &carry_out); + return carry_out; +} + +static inline br_word_t br_full_sub(br_word_t x, br_word_t y, br_word_t borrow, + br_word_t *_diff) { + br_word_t borrow_out = 0; + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + *_diff = CRYPTO_subc_w(x, y, borrow, &borrow_out); + return borrow_out; +} + +static inline br_word_t br_full_mul(br_word_t a, br_word_t b, br_word_t *_low) { +#if BR_WORD_MAX == UINT32_MAX + uint64_t r = (uint64_t)a * b; + *_low = r; + return r >> 32; +#elif defined(BORINGSSL_HAS_UINT128) + uint128_t r = (uint128_t)a * b; + *_low = r; + return r >> 64; +#elif defined(_M_X64) + uint64_t hi; + *_low = _umul128(a, b, &hi); + return hi; +#elif defined(_M_ARM64) + *_low = a * b; + return __umulh(a, b); +#else +#error "need 64 x 64 -> 128 multiplication" +#endif +} + +// Constant-time computations + +static inline br_word_t br_value_barrier(br_word_t a) { + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + return value_barrier_w(a); +} + +static inline br_word_t br_declassify(br_word_t a) { + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + return constant_time_declassify_w(a); +} + +static inline br_word_t br_broadcast_negative(br_word_t x) { + return br_value_barrier((br_signed_t)x >> (sizeof(br_word_t) * 8 - 1)); +} + +static inline br_word_t br_broadcast_nonzero(br_word_t x) { + return br_broadcast_negative(x | (0u - x)); +} + +static inline br_word_t br_cmov(br_word_t c, br_word_t vnz, br_word_t vz) { +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ + defined(__x86_64__) + __asm__( + "testq %[c], %[c]\n" + "cmovzq %[vz], %[vnz]" + : [vnz] "+r"(vnz) + : [vz] "r"(vz), [c] "r"(c) + : "cc"); + return vnz; +#elif !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ + defined(__i386__) + __asm__( + "testl %[c], %[c]\n" // test%z[c] gives "invalid operand" on clang 16.0.6 + "cmovzl %[vz], %[vnz]" + : [vnz] "+r"(vnz) + : [vz] "r"(vz), [c] "r"(c) + : "cc"); + return vnz; +#else + br_word_t m = br_broadcast_nonzero(c); + return (m & vnz) | (~m & vz); +#endif +} + +#endif // BEDROCK_UNVERIFIED_PLATFORM_INC_H_ diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h index 0aaac28c5..ddb73ae70 100644 --- a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h @@ -1,4 +1,6 @@ #include +#include "bedrock_unverified_platform.c.inc" +#include "p256_field_64.br.c.inc" #include "../../crypto/internal.h" #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) @@ -175,6 +177,7 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p25 * */ static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + // NOTE: edited by hand, see third_party/fiat/README.md #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable()) { @@ -489,6 +492,7 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + // NOTE: edited by hand, see third_party/fiat/README.md #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable()) { @@ -804,45 +808,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_f * */ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - fiat_p256_uint1 x10; - uint64_t x11; - fiat_p256_uint1 x12; - uint64_t x13; - fiat_p256_uint1 x14; - uint64_t x15; - fiat_p256_uint1 x16; - uint64_t x17; - fiat_p256_uint1 x18; - uint64_t x19; - uint64_t x20; - uint64_t x21; - uint64_t x22; - fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); - fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); - fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); - fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); - fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); - fiat_p256_cmovznz_u64(&x19, x18, x9, x1); - fiat_p256_cmovznz_u64(&x20, x18, x11, x3); - fiat_p256_cmovznz_u64(&x21, x18, x13, x5); - fiat_p256_cmovznz_u64(&x22, x18, x15, x7); - out1[0] = x19; - out1[1] = x20; - out1[2] = x21; - out1[3] = x22; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_add((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* @@ -857,36 +824,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - uint64_t x10; - fiat_p256_uint1 x11; - uint64_t x12; - fiat_p256_uint1 x13; - uint64_t x14; - fiat_p256_uint1 x15; - uint64_t x16; - fiat_p256_uint1 x17; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); - fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); - out1[0] = x10; - out1[1] = x12; - out1[2] = x14; - out1[3] = x16; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_sub((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h index 8b65a3734..aff43d359 100644 --- a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h @@ -17,6 +17,8 @@ /* twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in */ /* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ +#include "bedrock_unverified_platform.c.inc" +#include "p256_field_64.br.c.inc" #include #include #if defined(_M_X64) @@ -771,45 +773,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_f * */ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - fiat_p256_uint1 x10; - uint64_t x11; - fiat_p256_uint1 x12; - uint64_t x13; - fiat_p256_uint1 x14; - uint64_t x15; - fiat_p256_uint1 x16; - uint64_t x17; - fiat_p256_uint1 x18; - uint64_t x19; - uint64_t x20; - uint64_t x21; - uint64_t x22; - fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); - fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); - fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); - fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); - fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); - fiat_p256_cmovznz_u64(&x19, x18, x9, x1); - fiat_p256_cmovznz_u64(&x20, x18, x11, x3); - fiat_p256_cmovznz_u64(&x21, x18, x13, x5); - fiat_p256_cmovznz_u64(&x22, x18, x15, x7); - out1[0] = x19; - out1[1] = x20; - out1[2] = x21; - out1[3] = x22; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_add((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* @@ -824,36 +789,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - uint64_t x10; - fiat_p256_uint1 x11; - uint64_t x12; - fiat_p256_uint1 x13; - uint64_t x14; - fiat_p256_uint1 x15; - uint64_t x16; - fiat_p256_uint1 x17; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); - fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); - out1[0] = x10; - out1[1] = x12; - out1[2] = x14; - out1[3] = x16; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_sub((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc new file mode 100644 index 000000000..047d61bf7 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc @@ -0,0 +1,26 @@ +#include +#include "bedrock_unverified_platform.c.inc" + +#if defined(BORINGSSL_HAS_UINT128) +#include "p256_64.h" +#elif defined(OPENSSL_64_BIT) +#include "p256_64_msvc.h" +#else +#include "p256_field_32.br.c.inc" +#include "p256_32.h" +// the 32-bit Bedrock-generated field halving calls Fiat-C code for add, sub +static inline void p256_coord_add(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_add((uint32_t*)out, (const uint32_t*)x, (const uint32_t*)y); +} +static inline void p256_coord_sub(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_sub((uint32_t*)out, (const uint32_t*)x, (const uint32_t*)y); +} +#endif + +// the Bedrock-generated point operations call Fiat-C or Fiat-x86 mul, sqr +static inline void p256_coord_mul(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_mul((br_word_t*)out, (const br_word_t*)x, (const br_word_t*)y); +} +static inline void p256_coord_sqr(br_word_t out, br_word_t x) { + fiat_p256_square((br_word_t*)out, (const br_word_t*)x); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc new file mode 100644 index 000000000..e681dcb55 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc @@ -0,0 +1,71 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t shrd(br_word_t lo, br_word_t hi, br_word_t n) { + br_word_t res; + res = lo>>(n&(sizeof(br_word_t)*8-1)); + if (n) { + res = (hi<<((((((0u-(br_word_t)1)>>27)&63)+1)-n)&(sizeof(br_word_t)*8-1)))|res; + } else { + /*skip*/ + } + return res; +} + +static inline br_word_t p256_coord_nonzero(br_word_t p_x) { + br_word_t nz; + nz = (((_br_load(p_x))|(_br_load(p_x+4)))|(_br_load((p_x+4)+4)))|(_br_load(((p_x+4)+4)+4)); + nz = nz|(_br_load((((p_x+4)+4)+4)+4)); + nz = nz|(_br_load(((((p_x+4)+4)+4)+4)+4)); + nz = nz|(_br_load((((((p_x+4)+4)+4)+4)+4)+4)); + nz = nz|(_br_load(((((((p_x+4)+4)+4)+4)+4)+4)+4)); + nz = br_broadcast_nonzero(nz); + return nz; +} + +static inline void u256_shr(br_word_t p_out, br_word_t p_x, br_word_t n) { + br_word_t x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7; + x0 = _br_load(p_x); + x1 = _br_load(p_x+4); + x2 = _br_load((p_x+4)+4); + x3 = _br_load(((p_x+4)+4)+4); + x4 = _br_load((((p_x+4)+4)+4)+4); + x5 = _br_load(((((p_x+4)+4)+4)+4)+4); + x6 = _br_load((((((p_x+4)+4)+4)+4)+4)+4); + x7 = _br_load(((((((p_x+4)+4)+4)+4)+4)+4)+4); + y0 = shrd(x0, x1, n); + y1 = shrd(x1, x2, n); + y2 = shrd(x2, x3, n); + y3 = shrd(x3, x4, n); + y4 = shrd(x4, x5, n); + y5 = shrd(x5, x6, n); + y6 = shrd(x6, x7, n); + y7 = x7>>(n&(sizeof(br_word_t)*8-1)); + _br_store(p_out, y0); + _br_store(p_out+4, y1); + _br_store((p_out+4)+4, y2); + _br_store(((p_out+4)+4)+4, y3); + _br_store((((p_out+4)+4)+4)+4, y4); + _br_store(((((p_out+4)+4)+4)+4)+4, y5); + _br_store((((((p_out+4)+4)+4)+4)+4)+4, y6); + _br_store(((((((p_out+4)+4)+4)+4)+4)+4)+4, y7); +} + +static inline void u256_set_p256_minushalf_conditional(br_word_t p_out, br_word_t mask) { + br_word_t mh0, mh1, mh2, mh3, mh4, mh5, mh6, mh7; + mh0 = 0u-(br_word_t)1; + mh1 = mh0; + mh2 = mh0>>1; + mh3 = (br_word_t)0; + mh4 = (br_word_t)0; + mh5 = (br_word_t)1<<31; + mh6 = mh5; + mh7 = mh2; + _br_store(p_out, mask&mh0); + _br_store(p_out+4, mask&mh1); + _br_store((p_out+4)+4, mask&mh2); + _br_store(((p_out+4)+4)+4, mask&mh3); + _br_store((((p_out+4)+4)+4)+4, mask&mh4); + _br_store(((((p_out+4)+4)+4)+4)+4, mask&mh5); + _br_store((((((p_out+4)+4)+4)+4)+4)+4, mask&mh6); + _br_store(((((((p_out+4)+4)+4)+4)+4)+4)+4, mask&mh7); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc new file mode 100644 index 000000000..b23246b1c --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc @@ -0,0 +1,84 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t shrd(br_word_t lo, br_word_t hi, br_word_t n) { + br_word_t res; + res = lo>>(n&(sizeof(br_word_t)*8-1)); + if (n) { + res = (hi<<((((((0u-(br_word_t)1)>>27)&63)+1)-n)&(sizeof(br_word_t)*8-1)))|res; + } else { + /*skip*/ + } + return res; +} + +static inline void p256_coord_add(br_word_t p_out, br_word_t p_x, br_word_t p_y) { + br_word_t r4, carry, t0, t1, t2, borrow, t3, r0, r1, r2, r3; + carry = br_full_add(_br_load(p_x), _br_load(p_y), (br_word_t)0, &t0); + carry = br_full_add(_br_load(p_x+8), _br_load(p_y+8), carry, &t1); + carry = br_full_add(_br_load((p_x+8)+8), _br_load((p_y+8)+8), carry, &t2); + carry = br_full_add(_br_load(((p_x+8)+8)+8), _br_load(((p_y+8)+8)+8), carry, &t3); + borrow = br_full_sub(t0, (br_word_t)0xffffffffffffffff, (br_word_t)0, &r0); + borrow = br_full_sub(t1, (br_word_t)0xffffffff, borrow, &r1); + borrow = br_full_sub(t2, (br_word_t)0, borrow, &r2); + borrow = br_full_sub(t3, (br_word_t)0xffffffff00000001, borrow, &r3); + borrow = br_full_sub(carry, (br_word_t)0, borrow, &r4); + r0 = br_cmov(borrow, t0, r0); + r1 = br_cmov(borrow, t1, r1); + r2 = br_cmov(borrow, t2, r2); + r3 = br_cmov(borrow, t3, r3); + _br_store(p_out, r0); + _br_store(p_out+8, r1); + _br_store((p_out+8)+8, r2); + _br_store(((p_out+8)+8)+8, r3); +} + +static inline void p256_coord_sub(br_word_t out, br_word_t x, br_word_t y) { + br_word_t borrow, t0, t1, t2, t3, mask, carry, r0, r1, r2, r3; + borrow = br_full_sub(_br_load(x), _br_load(y), (br_word_t)0, &t0); + borrow = br_full_sub(_br_load(x+8), _br_load(y+8), borrow, &t1); + borrow = br_full_sub(_br_load((x+8)+8), _br_load((y+8)+8), borrow, &t2); + borrow = br_full_sub(_br_load(((x+8)+8)+8), _br_load(((y+8)+8)+8), borrow, &t3); + mask = br_value_barrier(0u-borrow); + carry = br_full_add(t0, mask, (br_word_t)0, &r0); + carry = br_full_add(t1, mask&0xffffffff, carry, &r1); + carry = br_full_add(t2, (br_word_t)0, carry, &r2); + carry = br_full_add(t3, mask&0xffffffff00000001, carry, &r3); + _br_store(out, r0); + _br_store(out+8, r1); + _br_store((out+8)+8, r2); + _br_store(((out+8)+8)+8, r3); +} + +static inline br_word_t p256_coord_nonzero(br_word_t p_x) { + br_word_t nz; + nz = br_broadcast_nonzero((((_br_load(p_x))|(_br_load(p_x+8)))|(_br_load((p_x+8)+8)))|(_br_load(((p_x+8)+8)+8))); + return nz; +} + +static inline void u256_shr(br_word_t p_out, br_word_t p_x, br_word_t n) { + br_word_t x0, x1, x2, x3, y0, y1, y2, y3; + x0 = _br_load(p_x); + x1 = _br_load(p_x+8); + x2 = _br_load((p_x+8)+8); + x3 = _br_load(((p_x+8)+8)+8); + y0 = shrd(x0, x1, n); + y1 = shrd(x1, x2, n); + y2 = shrd(x2, x3, n); + y3 = x3>>(n&(sizeof(br_word_t)*8-1)); + _br_store(p_out, y0); + _br_store(p_out+8, y1); + _br_store((p_out+8)+8, y2); + _br_store(((p_out+8)+8)+8, y3); +} + +static inline void u256_set_p256_minushalf_conditional(br_word_t p_out, br_word_t mask) { + br_word_t mh0, mh1, mh2, mh3; + mh0 = 0u-(br_word_t)1; + mh1 = mh0>>((br_word_t)33&(sizeof(br_word_t)*8-1)); + mh2 = mh0<<((br_word_t)63&(sizeof(br_word_t)*8-1)); + mh3 = (mh0<<((br_word_t)32&(sizeof(br_word_t)*8-1)))>>1; + _br_store(p_out, mask&mh0); + _br_store(p_out+8, mask&mh1); + _br_store((p_out+8)+8, mask&mh2); + _br_store(((p_out+8)+8)+8, mask&mh3); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc new file mode 100644 index 000000000..117547bdf --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc @@ -0,0 +1,112 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t br_broadcast_odd(br_word_t x) { + br_word_t y; + x = br_value_barrier(x&1); + y = 0u-x; + return y; +} + +static inline void p256_coord_halve(br_word_t y, br_word_t x) { + br_word_t m, mmh; + uint8_t _br_stackalloc_mmh[32] = {0}; mmh = (br_word_t)&_br_stackalloc_mmh; + m = br_broadcast_odd(_br_load(x)); + u256_set_p256_minushalf_conditional(mmh, m); + u256_shr(y, x, (br_word_t)1); + p256_coord_sub(y, y, mmh); +} + +static inline br_word_t p256_point_iszero(br_word_t p_P) { + br_word_t z, nz; + nz = p256_coord_nonzero((p_P+32)+32); + z = ~nz; + return z; +} + +static inline void p256_point_double(br_word_t out, br_word_t in1) { + br_word_t t2, tmp, A, D; + uint8_t _br_stackalloc_D[32] = {0}; D = (br_word_t)&_br_stackalloc_D; + uint8_t _br_stackalloc_A[32] = {0}; A = (br_word_t)&_br_stackalloc_A; + uint8_t _br_stackalloc_tmp[32] = {0}; tmp = (br_word_t)&_br_stackalloc_tmp; + p256_coord_add(D, in1+32, in1+32); + p256_coord_sqr(tmp, (in1+32)+32); + p256_coord_sqr(D, D); + p256_coord_mul((out+32)+32, (in1+32)+32, in1+32); + p256_coord_add((out+32)+32, (out+32)+32, (out+32)+32); + p256_coord_add(A, in1, tmp); + p256_coord_sub(tmp, in1, tmp); + uint8_t _br_stackalloc_t2[32] = {0}; t2 = (br_word_t)&_br_stackalloc_t2; + p256_coord_add(t2, tmp, tmp); + p256_coord_add(tmp, t2, tmp); + p256_coord_sqr(out+32, D); + p256_coord_mul(A, A, tmp); + p256_coord_mul(D, D, in1); + p256_coord_sqr(out, A); + p256_coord_add(tmp, D, D); + p256_coord_sub(out, out, tmp); + p256_coord_sub(D, D, out); + p256_coord_mul(D, D, A); + p256_coord_halve(out+32, out+32); + p256_coord_sub(out+32, D, out+32); +} + +static inline br_word_t p256_point_add_nz_nz_neq(br_word_t p_out, br_word_t p_P, br_word_t p_Q) { + br_word_t z1z1, z2z2, u1, Hsqr, ok, different_x, different_y, u2, Hcub, s1, r, h, s2; + uint8_t _br_stackalloc_z1z1[32] = {0}; z1z1 = (br_word_t)&_br_stackalloc_z1z1; + uint8_t _br_stackalloc_z2z2[32] = {0}; z2z2 = (br_word_t)&_br_stackalloc_z2z2; + uint8_t _br_stackalloc_u1[32] = {0}; u1 = (br_word_t)&_br_stackalloc_u1; + uint8_t _br_stackalloc_u2[32] = {0}; u2 = (br_word_t)&_br_stackalloc_u2; + uint8_t _br_stackalloc_h[32] = {0}; h = (br_word_t)&_br_stackalloc_h; + uint8_t _br_stackalloc_s1[32] = {0}; s1 = (br_word_t)&_br_stackalloc_s1; + uint8_t _br_stackalloc_s2[32] = {0}; s2 = (br_word_t)&_br_stackalloc_s2; + uint8_t _br_stackalloc_r[32] = {0}; r = (br_word_t)&_br_stackalloc_r; + uint8_t _br_stackalloc_Hsqr[32] = {0}; Hsqr = (br_word_t)&_br_stackalloc_Hsqr; + uint8_t _br_stackalloc_Hcub[32] = {0}; Hcub = (br_word_t)&_br_stackalloc_Hcub; + p256_coord_sqr(z1z1, (p_P+32)+32); + p256_coord_mul(u2, p_Q, z1z1); + p256_coord_sqr(z2z2, (p_Q+32)+32); + p256_coord_mul(u1, p_P, z2z2); + p256_coord_sub(h, u2, u1); + p256_coord_mul(s2, (p_P+32)+32, z1z1); + p256_coord_mul((p_out+32)+32, h, (p_P+32)+32); + p256_coord_mul((p_out+32)+32, (p_out+32)+32, (p_Q+32)+32); + p256_coord_mul(s2, s2, p_Q+32); + p256_coord_mul(s1, (p_Q+32)+32, z2z2); + p256_coord_mul(s1, s1, p_P+32); + p256_coord_sub(r, s2, s1); + p256_coord_sqr(Hsqr, h); + p256_coord_sqr(p_out, r); + p256_coord_mul(Hcub, Hsqr, h); + p256_coord_mul(u2, u1, Hsqr); + different_x = p256_coord_nonzero(Hcub); + different_y = p256_coord_nonzero(p_out); + ok = br_value_barrier(different_x|different_y); + p256_coord_sub(p_out, p_out, Hcub); + p256_coord_sub(p_out, p_out, u2); + p256_coord_sub(p_out, p_out, u2); + p256_coord_sub(h, u2, p_out); + p256_coord_mul(s2, Hcub, s1); + p256_coord_mul(h, h, r); + p256_coord_sub(p_out+32, h, s2); + return ok; +} + +static inline void p256_point_add_vartime_if_doubling(br_word_t p_out, br_word_t p_P, br_word_t p_Q) { + br_word_t p_tmp, zeroP, zeroQ, ok, p_sel; + zeroP = p256_point_iszero(p_P); + zeroQ = p256_point_iszero(p_Q); + uint8_t _br_stackalloc_p_tmp[96] = {0}; p_tmp = (br_word_t)&_br_stackalloc_p_tmp; + ok = p256_point_add_nz_nz_neq(p_tmp, p_P, p_Q); + ok = br_declassify((zeroP|zeroQ)|ok); + uint8_t _br_stackalloc_p_sel[96] = {0}; p_sel = (br_word_t)&_br_stackalloc_p_sel; + br_memset(p_sel, (br_word_t)0, (br_word_t)96); + br_memcxor(p_sel, p_tmp, (br_word_t)96, (~zeroP)&(~zeroQ)); + br_memcxor(p_sel, p_P, (br_word_t)96, (~zeroP)&zeroQ); + br_memcxor(p_sel, p_Q, (br_word_t)96, zeroP&(~zeroQ)); + if (ok) { + /*skip*/ + } else { + p256_point_double(p_sel, p_P); + } + br_memcpy(p_out, p_sel, (br_word_t)96); +} diff --git a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift index 39e62b2d9..825932382 100644 --- a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift +++ b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift @@ -276,7 +276,7 @@ extension FiniteFieldArithmeticContext { _ p: UnsafePointer?, _ m: UnsafePointer?, _ ctx: OpaquePointer?, - _ mont: UnsafePointer? + _ mont: OpaquePointer? ) -> Int32 ) throws -> ArbitraryPrecisionInteger { var result = ArbitraryPrecisionInteger() @@ -302,7 +302,7 @@ extension FiniteFieldArithmeticContext { /// Some functions require a `BN_MONT_CTX` parameter: this obtains one for the field modulus with a scoped lifetime. fileprivate func withUnsafeBN_MONT_CTX( - _ body: (UnsafePointer) throws -> T + _ body: (OpaquePointer) throws -> T ) rethrows -> T { diff --git a/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift index 10c7a6e2a..3f14da321 100644 --- a/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift +++ b/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift @@ -136,7 +136,7 @@ extension _RSA.BlindSigning { } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } diff --git a/Sources/CryptoExtras/RSA/RSA.swift b/Sources/CryptoExtras/RSA/RSA.swift index 8942fcebb..180cecabc 100644 --- a/Sources/CryptoExtras/RSA/RSA.swift +++ b/Sources/CryptoExtras/RSA/RSA.swift @@ -146,7 +146,7 @@ extension _RSA.Signing { } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } @@ -543,7 +543,7 @@ extension _RSA.Encryption { fileprivate init(_ backing: BackingPublicKey) { self.backing = backing } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } diff --git a/Sources/CryptoExtras/RSA/RSA_boring.swift b/Sources/CryptoExtras/RSA/RSA_boring.swift index 48d6d3c25..c0f3be1ac 100644 --- a/Sources/CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/CryptoExtras/RSA/RSA_boring.swift @@ -81,8 +81,8 @@ internal struct BoringSSLRSAPublicKey: Sendable { self.backing = backing } - func getKeyPrimitives() throws -> (n: Data, e: Data) { - try self.backing.getKeyPrimitives() + func getKeyPrimitives() -> (n: Data, e: Data) { + self.backing.getKeyPrimitives() } } diff --git a/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift index 6b2ccdf09..07051a672 100644 --- a/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift +++ b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift @@ -25,7 +25,7 @@ // //===----------------------------------------------------------------------===// -#if os(Linux) || os(Android) || os(FreeBSD) || canImport(Darwin) +#if os(Linux) || os(Android) || os(FreeBSD) || os(OpenBSD) || canImport(Darwin) #if canImport(Glibc) @preconcurrency import Glibc #elseif canImport(Bionic) diff --git a/scripts/generate-linux-sdks.sh b/scripts/generate-linux-sdks.sh index 65cd7bfcb..959bc1197 100755 --- a/scripts/generate-linux-sdks.sh +++ b/scripts/generate-linux-sdks.sh @@ -25,10 +25,10 @@ set -e -SWIFT_VERSION=5.10 +SWIFT_VERSION=6.1.2 DISTRO_NAME=ubuntu -DISTRO_VERSION=jammy -DISTRO_VERSION_GENERATOR=22.04 +DISTRO_VERSION=noble +DISTRO_VERSION_GENERATOR=24.04 TMPDIR=$(mktemp -d /tmp/.workingXXXXXX) function generate_swift_sdk { diff --git a/scripts/patch-3-missing-extern-c.patch b/scripts/patch-3-missing-extern-c.patch new file mode 100644 index 000000000..aeda6890e --- /dev/null +++ b/scripts/patch-3-missing-extern-c.patch @@ -0,0 +1,25 @@ +diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +index c5a8113..27f8060 100644 +--- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h ++++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +@@ -17,6 +17,9 @@ + + #include + ++#if defined(__cplusplus) ++extern "C" { ++#endif + + // FIPS_service_indicator_before_call and |FIPS_service_indicator_after_call| + // both currently return the same local thread counter which is slowly +@@ -37,6 +40,10 @@ + OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(void); + OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void); + ++#if defined(__cplusplus) ++} ++#endif ++ + #if defined(BORINGSSL_FIPS) + + // FIPS_service_indicator_update_state records that an approved service has been diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index 5727749ad..324099fe8 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -87,8 +87,8 @@ function mangle_symbols { # Begin by building for macOS. We build for two target triples, Intel # and Apple Silicon. - swift build --triple "x86_64-apple-macosx" --product CCryptoBoringSSL --enable-test-discovery - swift build --triple "arm64-apple-macosx" --product CCryptoBoringSSL --enable-test-discovery + swift build --triple "x86_64-apple-macosx" --product CCryptoBoringSSL + swift build --triple "arm64-apple-macosx" --product CCryptoBoringSSL ( cd "${SRCROOT}" go mod tidy -modcacherw @@ -107,9 +107,9 @@ function mangle_symbols { # Now cross compile for our targets. # NOTE: This requires running the `generate-linux-sdks.sh` script first to generate the Swift SDKs. - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_x86_64 --product CCryptoBoringSSL - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_aarch64 --product CCryptoBoringSSL - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_armv7 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_x86_64 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_aarch64 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_armv7 --product CCryptoBoringSSL # Now we need to generate symbol mangles for Linux. We can do this in # one go for all of them. @@ -147,6 +147,34 @@ function mangle_symbols { namespace_inlines "$DSTROOT" } +function mangle_cpp_structures { + echo "MANGLING C++ structures" + ( + # We need a .a: may as well get SwiftPM to give it to us. + # Temporarily enable the product we need. + $sed -i -e 's/MANGLE_START/MANGLE_START*\//' -e 's/MANGLE_END/\/*MANGLE_END/' "${HERE}/Package.swift" + + # Build for macOS. + swift build --product CCryptoBoringSSL + + # Woah, this is a hell of a command! What does it do? + # + # The nm command grabs all global defined symbols. We then run the C++ demangler over them and look for methods with '::' in them: + # these are C++ methods. We then exclude any that contain CCryptoBoringSSL (as those are already namespaced!) and any that contain swift + # (as those were put there by the Swift runtime, not us). This gives us a list of symbols. The following cut command + # grabs the type name from each of those (the bit preceding the '::'). Then, we sort and uniqify that list. + # Finally, we remove any symbol that ends in std. This gives us all the structures that need to be renamed. + structures=$(nm -gUj "$(swift build --show-bin-path)/libCCryptoBoringSSL.a" | c++filt | grep "::" | grep -v -e "CCryptoBoringSSL" -e "swift" | cut -d : -f1 | grep -v "std$" | $sed -E -e 's/([^<>]*)(<[^<>]*>)?/\1/' | sort | uniq) + + for struct in ${structures}; do + echo "#define ${struct} BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ${struct})" >> "${DSTROOT}/include/CCryptoBoringSSL_boringssl_prefix_symbols.h" + done + + # Remove the product, as we no longer need it. + $sed -i -e 's/MANGLE_START\*\//MANGLE_START/' -e 's/\/\*MANGLE_END/MANGLE_END/' "${HERE}/Package.swift" + ) +} + case "$(uname -s)" in Darwin) sed=gsed @@ -175,10 +203,10 @@ echo "CLONING boringssl" mkdir -p "$SRCROOT" git clone https://boringssl.googlesource.com/boringssl "$SRCROOT" cd "$SRCROOT" -if [ "$BORINGSSL_REVISION" ]; then +if [ "${BORINGSSL_REVISION:-}" ]; then echo "CHECKING OUT boringssl@${BORINGSSL_REVISION}" git checkout "$BORINGSSL_REVISION" -else +else BORINGSSL_REVISION=$(git rev-parse HEAD) echo "CLONED boringssl@${BORINGSSL_REVISION}" fi @@ -200,7 +228,6 @@ echo "GENERATING assembly helpers" PATTERNS=( 'include/openssl/*.h' -'include/openssl/experimental/*.h' 'ssl/*.h' 'ssl/*.cc' 'crypto/*.h' @@ -218,7 +245,7 @@ PATTERNS=( 'gen/bcm/*.S' 'third_party/fiat/*.h' 'third_party/fiat/asm/*.S' -#'third_party/fiat/*.c' +'third_party/fiat/*.c.inc' ) EXCLUDES=( @@ -262,6 +289,11 @@ echo "DISABLING assembly on x86 Windows" ) +# Unfortunately, this patch for an upstream bug which incorrectly leaves C symbol using C++ mangling must be +# applied before we mangle symbols, so we can't place it with the others below. +echo "PATCHING BoringSSL (early)" +git apply "${HERE}/scripts/patch-3-missing-extern-c.patch" + mangle_symbols echo "RENAMING header files" @@ -295,6 +327,10 @@ echo "RENAMING header files" popd ) +echo "PATCHING BoringSSL" +git apply "${HERE}/scripts/patch-1-inttypes.patch" +git apply "${HERE}/scripts/patch-2-more-inttypes.patch" + # We need to avoid having the stack be executable. BoringSSL does this in its build system, but we can't. echo "PROTECTING against executable stacks" ( @@ -303,9 +339,7 @@ echo "PROTECTING against executable stacks" find . -name "*.S" | xargs $sed -i '$ a #if defined(__linux__) && defined(__ELF__)\n.section .note.GNU-stack,"",%progbits\n#endif\n' ) -echo "PATCHING BoringSSL" -git apply "${HERE}/scripts/patch-1-inttypes.patch" -git apply "${HERE}/scripts/patch-2-more-inttypes.patch" +mangle_cpp_structures # We need BoringSSL to be modularised echo "MODULARISING BoringSSL" @@ -357,6 +391,8 @@ cat << EOF > "$DSTROOT/include/CCryptoBoringSSL.h" #include "CCryptoBoringSSL_hrss.h" #include "CCryptoBoringSSL_md4.h" #include "CCryptoBoringSSL_md5.h" +#include "CCryptoBoringSSL_mldsa.h" +#include "CCryptoBoringSSL_mlkem.h" #include "CCryptoBoringSSL_obj_mac.h" #include "CCryptoBoringSSL_objects.h" #include "CCryptoBoringSSL_opensslv.h"