diff --git a/openssl/cmake/linux_riscv64.cmake b/openssl/cmake/linux_riscv64.cmake index ef0e7d2c6..a75b6c643 100644 --- a/openssl/cmake/linux_riscv64.cmake +++ b/openssl/cmake/linux_riscv64.cmake @@ -166,7 +166,7 @@ set(src_list ${PROJECT_SOURCE_DIR}/src/crypto/cast/c_skey.c ${PROJECT_SOURCE_DIR}/src/crypto/chacha/chacha_enc.c ${PROJECT_SOURCE_DIR}/src/crypto/chacha/chacha_riscv.c - ${PROJECT_SOURCE_DIR}/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zvkb.s + ${PROJECT_SOURCE_DIR}/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zbb-zvkb.s ${PROJECT_SOURCE_DIR}/src/crypto/cmac/cmac.c ${PROJECT_SOURCE_DIR}/src/crypto/cmp/cmp_asn.c ${PROJECT_SOURCE_DIR}/src/crypto/cmp/cmp_client.c diff --git a/openssl/include/crypto/bn.h b/openssl/include/crypto/bn.h index f5d8683eb..9a988a467 100644 --- a/openssl/include/crypto/bn.h +++ b/openssl/include/crypto/bn.h @@ -87,6 +87,14 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n); int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n); int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int ossl_bn_mask_bits_fixed_top(BIGNUM *a, int n); +int ossl_bn_is_word_fixed_top(const BIGNUM *a, BN_ULONG w); +int ossl_bn_priv_rand_range_fixed_top(BIGNUM *r, const BIGNUM *range, + unsigned int strength, BN_CTX *ctx); +int ossl_bn_gen_dsa_nonce_fixed_top(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, + const unsigned char *message, + size_t message_len, BN_CTX *ctx); #define BN_PRIMETEST_COMPOSITE 0 #define BN_PRIMETEST_COMPOSITE_WITH_FACTOR 1 diff --git a/openssl/include/internal/constant_time.h b/openssl/include/internal/constant_time.h index 0ed6f823c..2b49afe1e 100644 --- a/openssl/include/internal/constant_time.h +++ b/openssl/include/internal/constant_time.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -140,6 +140,29 @@ static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b) return constant_time_msb_64(a ^ ((a ^ b) | ((a - b) ^ b))); } +#ifdef BN_ULONG +static ossl_inline BN_ULONG constant_time_msb_bn(BN_ULONG a) +{ + return 0 - (a >> (sizeof(a) * 8 - 1)); +} + +static ossl_inline BN_ULONG constant_time_lt_bn(BN_ULONG a, BN_ULONG b) +{ + return constant_time_msb_bn(a ^ ((a ^ b) | ((a - b) ^ b))); +} + +static ossl_inline BN_ULONG constant_time_is_zero_bn(BN_ULONG a) +{ + return constant_time_msb_bn(~a & (a - 1)); +} + +static ossl_inline BN_ULONG constant_time_eq_bn(BN_ULONG a, + BN_ULONG b) +{ + return constant_time_is_zero_bn(a ^ b); +} +#endif + static ossl_inline unsigned int constant_time_ge(unsigned int a, unsigned int b) { diff --git a/openssl/include/internal/quic_stream_map.h b/openssl/include/internal/quic_stream_map.h index 5c1e1b35b..745d9c03d 100644 --- a/openssl/include/internal/quic_stream_map.h +++ b/openssl/include/internal/quic_stream_map.h @@ -503,6 +503,41 @@ static ossl_inline ossl_unused int ossl_quic_stream_recv_get_final_size(const QU } } +/* + * Determines the number of bytes available still to be read, and (if + * include_fin is 1) whether a FIN or reset has yet to be read. + */ +static ossl_inline ossl_unused int ossl_quic_stream_recv_pending(const QUIC_STREAM *s, + int include_fin) +{ + size_t avail; + int fin = 0; + + switch (s->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + return 0; + + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + if (!ossl_quic_rstream_available(s->rstream, &avail, &fin)) + avail = 0; + + if (avail == 0 && include_fin && fin) + avail = 1; + + return avail; + + case QUIC_RSTREAM_STATE_RESET_RECVD: + return include_fin; + + case QUIC_RSTREAM_STATE_DATA_READ: + case QUIC_RSTREAM_STATE_RESET_READ: + return 0; + } +} + /* * QUIC Stream Map * =============== diff --git a/openssl/include/internal/sockets.h b/openssl/include/internal/sockets.h index 2550c56bd..f51c1b075 100644 --- a/openssl/include/internal/sockets.h +++ b/openssl/include/internal/sockets.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -190,14 +190,8 @@ typedef size_t socklen_t; /* Currently appears to be missing on VMS */ # define readsocket(s,b,n) read((s),(b),(n)) # define writesocket(s,b,n) write((s),(char *)(b),(n)) # elif defined(OPENSSL_SYS_TANDEM) -# if defined(OPENSSL_TANDEM_FLOSS) -# include -# define readsocket(s,b,n) floss_read((s),(b),(n)) -# define writesocket(s,b,n) floss_write((s),(b),(n)) -# else -# define readsocket(s,b,n) read((s),(b),(n)) -# define writesocket(s,b,n) write((s),(b),(n)) -# endif +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(b),(n)) # define ioctlsocket(a,b,c) ioctl(a,b,c) # define closesocket(s) close(s) # else diff --git a/openssl/include/openssl/e_os2.h b/openssl/include/openssl/e_os2.h index e01f62751..f1e17958a 100644 --- a/openssl/include/openssl/e_os2.h +++ b/openssl/include/openssl/e_os2.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -228,6 +228,7 @@ typedef INT32 int32_t; typedef UINT32 uint32_t; typedef INT64 int64_t; typedef UINT64 uint64_t; +typedef UINTN uintptr_t; # elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ defined(__osf__) || defined(__sgi) || defined(__hpux) || \ defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__) diff --git a/openssl/include/openssl/opensslv.h b/openssl/include/openssl/opensslv.h index 05633acd1..274a65ff0 100644 --- a/openssl/include/openssl/opensslv.h +++ b/openssl/include/openssl/opensslv.h @@ -29,7 +29,7 @@ extern "C" { */ # define OPENSSL_VERSION_MAJOR 3 # define OPENSSL_VERSION_MINOR 3 -# define OPENSSL_VERSION_PATCH 0 +# define OPENSSL_VERSION_PATCH 1 /* * Additional version information @@ -74,21 +74,21 @@ extern "C" { * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and * OPENSSL_VERSION_BUILD_METADATA_STR appended. */ -# define OPENSSL_VERSION_STR "3.3.0" -# define OPENSSL_FULL_VERSION_STR "3.3.0" +# define OPENSSL_VERSION_STR "3.3.1" +# define OPENSSL_FULL_VERSION_STR "3.3.1" /* * SECTION 3: ADDITIONAL METADATA * * These strings are defined separately to allow them to be parsable. */ -# define OPENSSL_RELEASE_DATE "9 Apr 2024" +# define OPENSSL_RELEASE_DATE "4 Jun 2024" /* * SECTION 4: BACKWARD COMPATIBILITY */ -# define OPENSSL_VERSION_TEXT "OpenSSL 3.3.0 9 Apr 2024" +# define OPENSSL_VERSION_TEXT "OpenSSL 3.3.1 4 Jun 2024" /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */ # ifdef OPENSSL_VERSION_PRE_RELEASE diff --git a/openssl/include/openssl/sslerr.h b/openssl/include/openssl/sslerr.h index 980a6c7b2..ec35df64e 100644 --- a/openssl/include/openssl/sslerr.h +++ b/openssl/include/openssl/sslerr.h @@ -308,10 +308,12 @@ # define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 # define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 # define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL 1120 # define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 # define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 # define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 # define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY 1115 # define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 # define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 # define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 diff --git a/openssl/src/crypto/aes/gen/darwin_arm64/bsaes-armv8.S b/openssl/src/crypto/aes/gen/darwin_arm64/bsaes-armv8.S index e87fa9ccd..6b972f5fc 100644 --- a/openssl/src/crypto/aes/gen/darwin_arm64/bsaes-armv8.S +++ b/openssl/src/crypto/aes/gen/darwin_arm64/bsaes-armv8.S @@ -1,4 +1,4 @@ -// Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -984,6 +984,7 @@ Lkey_loop: // Initialisation vector overwritten with last quadword of ciphertext // No output registers, usual AAPCS64 register preservation _ossl_bsaes_cbc_encrypt: + AARCH64_VALID_CALL_TARGET cmp x2, #128 bhs Lcbc_do_bsaes b _AES_cbc_encrypt @@ -1236,7 +1237,7 @@ Lcbc_dec_bzero: // wipe key schedule [if any] // Output text filled in // No output registers, usual AAPCS64 register preservation _ossl_bsaes_ctr32_encrypt_blocks: - + AARCH64_VALID_CALL_TARGET cmp x2, #8 // use plain AES for blo Lctr_enc_short // small sizes @@ -1442,6 +1443,7 @@ Lctr_enc_short_loop: // Output ciphertext filled in // No output registers, usual AAPCS64 register preservation _ossl_bsaes_xts_encrypt: + AARCH64_VALID_CALL_TARGET // Stack layout: // sp -> // nrounds*128-96 bytes: key schedule @@ -1887,6 +1889,7 @@ Lxts_magic: // Output plaintext filled in // No output registers, usual AAPCS64 register preservation _ossl_bsaes_xts_decrypt: + AARCH64_VALID_CALL_TARGET // Stack layout: // sp -> // nrounds*128-96 bytes: key schedule diff --git a/openssl/src/crypto/aes/gen/linux_arm64/bsaes-armv8.S b/openssl/src/crypto/aes/gen/linux_arm64/bsaes-armv8.S index 905d52476..c550525fd 100644 --- a/openssl/src/crypto/aes/gen/linux_arm64/bsaes-armv8.S +++ b/openssl/src/crypto/aes/gen/linux_arm64/bsaes-armv8.S @@ -1,4 +1,4 @@ -// Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -984,6 +984,7 @@ _bsaes_key_convert: // Initialisation vector overwritten with last quadword of ciphertext // No output registers, usual AAPCS64 register preservation ossl_bsaes_cbc_encrypt: + AARCH64_VALID_CALL_TARGET cmp x2, #128 bhs .Lcbc_do_bsaes b AES_cbc_encrypt @@ -1236,7 +1237,7 @@ ossl_bsaes_cbc_encrypt: // Output text filled in // No output registers, usual AAPCS64 register preservation ossl_bsaes_ctr32_encrypt_blocks: - + AARCH64_VALID_CALL_TARGET cmp x2, #8 // use plain AES for blo .Lctr_enc_short // small sizes @@ -1442,6 +1443,7 @@ ossl_bsaes_ctr32_encrypt_blocks: // Output ciphertext filled in // No output registers, usual AAPCS64 register preservation ossl_bsaes_xts_encrypt: + AARCH64_VALID_CALL_TARGET // Stack layout: // sp -> // nrounds*128-96 bytes: key schedule @@ -1887,6 +1889,7 @@ ossl_bsaes_xts_encrypt: // Output plaintext filled in // No output registers, usual AAPCS64 register preservation ossl_bsaes_xts_decrypt: + AARCH64_VALID_CALL_TARGET // Stack layout: // sp -> // nrounds*128-96 bytes: key schedule diff --git a/openssl/src/crypto/asn1/a_time.c b/openssl/src/crypto/asn1/a_time.c index 49548235a..96ee63d31 100644 --- a/openssl/src/crypto/asn1/a_time.c +++ b/openssl/src/crypto/asn1/a_time.c @@ -14,8 +14,6 @@ * generalTime GeneralizedTime } */ -#define _XOPEN_SOURCE /* To get a definition of timezone */ - #include #include #include "crypto/asn1.h" diff --git a/openssl/src/crypto/bio/bio_lib.c b/openssl/src/crypto/bio/bio_lib.c index bb3c12ddb..272189a9a 100644 --- a/openssl/src/crypto/bio/bio_lib.c +++ b/openssl/src/crypto/bio/bio_lib.c @@ -965,8 +965,12 @@ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) return 1; #ifndef OPENSSL_NO_SOCK - if (BIO_get_fd(bio, &fd) > 0 && fd < FD_SETSIZE) - return BIO_socket_wait(fd, BIO_should_read(bio), max_time); + if (BIO_get_fd(bio, &fd) > 0) { + int ret = BIO_socket_wait(fd, BIO_should_read(bio), max_time); + + if (ret != -1) + return ret; + } #endif /* fall back to polling since no sockets are available */ diff --git a/openssl/src/crypto/bio/bio_sock.c b/openssl/src/crypto/bio/bio_sock.c index 7aa7bdc65..ea28fd282 100644 --- a/openssl/src/crypto/bio/bio_sock.c +++ b/openssl/src/crypto/bio/bio_sock.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,9 +26,6 @@ static int wsa_init_done = 0; # if defined __TANDEM # include # include /* select */ -# if defined(OPENSSL_TANDEM_FLOSS) -# include -# endif # elif defined _WIN32 # include /* for type fd_set */ # else @@ -435,7 +432,11 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time) struct timeval tv; time_t now; +#ifdef _WIN32 + if ((SOCKET)fd == INVALID_SOCKET) +#else if (fd < 0 || fd >= FD_SETSIZE) +#endif return -1; if (max_time == 0) return 1; diff --git a/openssl/src/crypto/bio/bss_dgram.c b/openssl/src/crypto/bio/bss_dgram.c index 7dbdfe181..f6d688b35 100644 --- a/openssl/src/crypto/bio/bss_dgram.c +++ b/openssl/src/crypto/bio/bss_dgram.c @@ -560,6 +560,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) socklen_t addr_len; BIO_ADDR addr; # endif + struct sockaddr_storage ss; + socklen_t ss_len = sizeof(ss); data = (bio_dgram_data *)b->ptr; @@ -577,6 +579,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) b->shutdown = (int)num; b->init = 1; dgram_update_local_addr(b); + if (getpeername(b->num, (struct sockaddr *)&ss, &ss_len) == 0) { + BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)&ss)); + data->connected = 1; + } # if defined(SUPPORT_LOCAL_ADDR) if (data->local_addr_enabled) { if (enable_local_addr(b, 1) < 1) @@ -1067,19 +1073,27 @@ static void translate_msg_win(BIO *b, WSAMSG *mh, WSABUF *iov, static void translate_msg(BIO *b, struct msghdr *mh, struct iovec *iov, unsigned char *control, BIO_MSG *msg) { + bio_dgram_data *data; + iov->iov_base = msg->data; iov->iov_len = msg->data_len; - /* macOS requires msg_namelen be 0 if msg_name is NULL */ - mh->msg_name = msg->peer != NULL ? &msg->peer->sa : NULL; - if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET) - mh->msg_namelen = sizeof(struct sockaddr_in); + data = (bio_dgram_data *)b->ptr; + if (data->connected == 0) { + /* macOS requires msg_namelen be 0 if msg_name is NULL */ + mh->msg_name = msg->peer != NULL ? &msg->peer->sa : NULL; + if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET) + mh->msg_namelen = sizeof(struct sockaddr_in); # if OPENSSL_USE_IPV6 - else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6) - mh->msg_namelen = sizeof(struct sockaddr_in6); + else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6) + mh->msg_namelen = sizeof(struct sockaddr_in6); # endif - else + else + mh->msg_namelen = 0; + } else { + mh->msg_name = NULL; mh->msg_namelen = 0; + } mh->msg_iov = iov; mh->msg_iovlen = 1; diff --git a/openssl/src/crypto/bn/bn_lib.c b/openssl/src/crypto/bn/bn_lib.c index 9070647b3..18c9d54f6 100644 --- a/openssl/src/crypto/bn/bn_lib.c +++ b/openssl/src/crypto/bn/bn_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -708,14 +708,29 @@ int BN_ucmp(const BIGNUM *a, const BIGNUM *b) int i; BN_ULONG t1, t2, *ap, *bp; + ap = a->d; + bp = b->d; + + if (BN_get_flags(a, BN_FLG_CONSTTIME) + && a->top == b->top) { + int res = 0; + + for (i = 0; i < b->top; i++) { + res = constant_time_select_int(constant_time_lt_bn(ap[i], bp[i]), + -1, res); + res = constant_time_select_int(constant_time_lt_bn(bp[i], ap[i]), + 1, res); + } + return res; + } + bn_check_top(a); bn_check_top(b); i = a->top - b->top; if (i != 0) return i; - ap = a->d; - bp = b->d; + for (i = a->top - 1; i >= 0; i--) { t1 = ap[i]; t2 = bp[i]; @@ -827,11 +842,10 @@ int BN_is_bit_set(const BIGNUM *a, int n) return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); } -int BN_mask_bits(BIGNUM *a, int n) +int ossl_bn_mask_bits_fixed_top(BIGNUM *a, int n) { int b, w; - bn_check_top(a); if (n < 0) return 0; @@ -845,10 +859,21 @@ int BN_mask_bits(BIGNUM *a, int n) a->top = w + 1; a->d[w] &= ~(BN_MASK2 << b); } - bn_correct_top(a); + a->flags |= BN_FLG_FIXED_TOP; return 1; } +int BN_mask_bits(BIGNUM *a, int n) +{ + int ret; + + bn_check_top(a); + ret = ossl_bn_mask_bits_fixed_top(a, n); + if (ret) + bn_correct_top(a); + return ret; +} + void BN_set_negative(BIGNUM *a, int b) { if (b && !BN_is_zero(a)) @@ -1022,6 +1047,22 @@ int BN_is_word(const BIGNUM *a, const BN_ULONG w) return BN_abs_is_word(a, w) && (!w || !a->neg); } +int ossl_bn_is_word_fixed_top(const BIGNUM *a, const BN_ULONG w) +{ + int res, i; + const BN_ULONG *ap = a->d; + + if (a->neg || a->top == 0) + return 0; + + res = constant_time_select_int(constant_time_eq_bn(ap[0], w), 1, 0); + + for (i = 1; i < a->top; i++) + res = constant_time_select_int(constant_time_is_zero_bn(ap[i]), + res, 0); + return res; +} + int BN_is_odd(const BIGNUM *a) { return (a->top > 0) && (a->d[0] & 1); diff --git a/openssl/src/crypto/bn/bn_rand.c b/openssl/src/crypto/bn/bn_rand.c index a94dfcecd..da537a07a 100644 --- a/openssl/src/crypto/bn/bn_rand.c +++ b/openssl/src/crypto/bn/bn_rand.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -184,8 +184,8 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range, } else { do { /* range = 11..._2 or range = 101..._2 */ - if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, - ctx)) + if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, + strength, ctx)) return 0; if (!--count) { @@ -238,17 +238,63 @@ int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) # endif #endif +int ossl_bn_priv_rand_range_fixed_top(BIGNUM *r, const BIGNUM *range, + unsigned int strength, BN_CTX *ctx) +{ + int n; + int count = 100; + + if (r == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (range->neg || BN_is_zero(range)) { + ERR_raise(ERR_LIB_BN, BN_R_INVALID_RANGE); + return 0; + } + + n = BN_num_bits(range); /* n > 0 */ + + /* BN_is_bit_set(range, n - 1) always holds */ + + if (n == 1) { + BN_zero(r); + } else { + BN_set_flags(r, BN_FLG_CONSTTIME); + do { + if (!bnrand(PRIVATE, r, n + 1, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, + strength, ctx)) + return 0; + + if (!--count) { + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + ossl_bn_mask_bits_fixed_top(r, n); + } + while (BN_ucmp(r, range) >= 0); +#ifdef BN_DEBUG + /* With BN_DEBUG on a fixed top number cannot be returned */ + bn_correct_top(r); +#endif + } + + return 1; +} + /* - * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike - * BN_rand_range, it also includes the contents of |priv| and |message| in - * the generation so that an RNG failure isn't fatal as long as |priv| + * ossl_bn_gen_dsa_nonce_fixed_top generates a random number 0 <= out < range. + * Unlike BN_rand_range, it also includes the contents of |priv| and |message| + * in the generation so that an RNG failure isn't fatal as long as |priv| * remains secret. This is intended for use in DSA and ECDSA where an RNG * weakness leads directly to private key exposure unless this function is * used. */ -int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, - const BIGNUM *priv, const unsigned char *message, - size_t message_len, BN_CTX *ctx) +int ossl_bn_gen_dsa_nonce_fixed_top(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, + const unsigned char *message, + size_t message_len, BN_CTX *ctx) { EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); /* @@ -258,20 +304,24 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, unsigned char random_bytes[64]; unsigned char digest[SHA512_DIGEST_LENGTH]; unsigned done, todo; - /* We generate |range|+8 bytes of random output. */ - const unsigned num_k_bytes = BN_num_bytes(range) + 8; + /* We generate |range|+1 bytes of random output. */ + const unsigned num_k_bytes = BN_num_bytes(range) + 1; unsigned char private_bytes[96]; unsigned char *k_bytes = NULL; + const int max_n = 64; /* Pr(failure to generate) < 2^max_n */ + int n; int ret = 0; EVP_MD *md = NULL; OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); if (mdctx == NULL) - goto err; + goto end; k_bytes = OPENSSL_malloc(num_k_bytes); if (k_bytes == NULL) - goto err; + goto end; + /* Ensure top byte is set to avoid non-constant time in bin2bn */ + k_bytes[0] = 0xff; /* We copy |priv| into a local buffer to avoid exposing its length. */ if (BN_bn2binpad(priv, private_bytes, sizeof(private_bytes)) < 0) { @@ -281,41 +331,60 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, * length of the private key. */ ERR_raise(ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE); - goto err; + goto end; } md = EVP_MD_fetch(libctx, "SHA512", NULL); if (md == NULL) { ERR_raise(ERR_LIB_BN, BN_R_NO_SUITABLE_DIGEST); - goto err; - } - for (done = 0; done < num_k_bytes;) { - if (RAND_priv_bytes_ex(libctx, random_bytes, sizeof(random_bytes), 0) <= 0) - goto err; - - if (!EVP_DigestInit_ex(mdctx, md, NULL) - || !EVP_DigestUpdate(mdctx, &done, sizeof(done)) - || !EVP_DigestUpdate(mdctx, private_bytes, - sizeof(private_bytes)) - || !EVP_DigestUpdate(mdctx, message, message_len) - || !EVP_DigestUpdate(mdctx, random_bytes, sizeof(random_bytes)) - || !EVP_DigestFinal_ex(mdctx, digest, NULL)) - goto err; - - todo = num_k_bytes - done; - if (todo > SHA512_DIGEST_LENGTH) - todo = SHA512_DIGEST_LENGTH; - memcpy(k_bytes + done, digest, todo); - done += todo; + goto end; } + for (n = 0; n < max_n; n++) { + unsigned char i = 0; + + for (done = 1; done < num_k_bytes;) { + if (RAND_priv_bytes_ex(libctx, random_bytes, sizeof(random_bytes), + 0) <= 0) + goto end; + + if (!EVP_DigestInit_ex(mdctx, md, NULL) + || !EVP_DigestUpdate(mdctx, &i, sizeof(i)) + || !EVP_DigestUpdate(mdctx, private_bytes, + sizeof(private_bytes)) + || !EVP_DigestUpdate(mdctx, message, message_len) + || !EVP_DigestUpdate(mdctx, random_bytes, + sizeof(random_bytes)) + || !EVP_DigestFinal_ex(mdctx, digest, NULL)) + goto end; + + todo = num_k_bytes - done; + if (todo > SHA512_DIGEST_LENGTH) + todo = SHA512_DIGEST_LENGTH; + memcpy(k_bytes + done, digest, todo); + done += todo; + ++i; + } - if (!BN_bin2bn(k_bytes, num_k_bytes, out)) - goto err; - if (BN_mod(out, out, range, ctx) != 1) - goto err; - ret = 1; + if (!BN_bin2bn(k_bytes, num_k_bytes, out)) + goto end; - err: + /* Clear out the top bits and rejection filter into range */ + BN_set_flags(out, BN_FLG_CONSTTIME); + ossl_bn_mask_bits_fixed_top(out, BN_num_bits(range)); + + if (BN_ucmp(out, range) < 0) { + ret = 1; +#ifdef BN_DEBUG + /* With BN_DEBUG on a fixed top number cannot be returned */ + bn_correct_top(out); +#endif + goto end; + } + } + /* Failed to generate anything */ + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); + + end: EVP_MD_CTX_free(mdctx); EVP_MD_free(md); OPENSSL_clear_free(k_bytes, num_k_bytes); @@ -324,3 +393,20 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, OPENSSL_cleanse(private_bytes, sizeof(private_bytes)); return ret; } + +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, const unsigned char *message, + size_t message_len, BN_CTX *ctx) +{ + int ret; + + ret = ossl_bn_gen_dsa_nonce_fixed_top(out, range, priv, message, + message_len, ctx); + /* + * This call makes the BN_generate_dsa_nonce non-const-time, thus we + * do not use it internally. But fixed_top BNs currently cannot be returned + * from public API calls. + */ + bn_correct_top(out); + return ret; +} diff --git a/openssl/src/crypto/bn/bn_shift.c b/openssl/src/crypto/bn/bn_shift.c index 8fcb04324..d67331f1f 100644 --- a/openssl/src/crypto/bn/bn_shift.c +++ b/openssl/src/crypto/bn/bn_shift.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -156,6 +156,9 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) return 0; } + bn_check_top(r); + bn_check_top(a); + ret = bn_rshift_fixed_top(r, a, n); bn_correct_top(r); @@ -177,9 +180,6 @@ int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n) BN_ULONG *t, *f; BN_ULONG l, m, mask; - bn_check_top(r); - bn_check_top(a); - assert(n >= 0); nw = n / BN_BITS2; diff --git a/openssl/src/crypto/chacha/chacha_riscv.c b/openssl/src/crypto/chacha/chacha_riscv.c index 729a6282d..06e0400ba 100644 --- a/openssl/src/crypto/chacha/chacha_riscv.c +++ b/openssl/src/crypto/chacha/chacha_riscv.c @@ -2,7 +2,7 @@ * This file is dual-licensed, meaning that you can use it under your * choice of either of the following two licenses: * - * Copyright 2023-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,15 +40,16 @@ #include "crypto/chacha.h" #include "crypto/riscv_arch.h" -void ChaCha20_ctr32_zvkb(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]); +void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]) { - if (RISCV_HAS_ZVKB() && riscv_vlen() >= 128) { - ChaCha20_ctr32_zvkb(out, inp, len, key, counter); + if (len > CHACHA_BLK_SIZE && RISCV_HAS_ZVKB() && RISCV_HAS_ZBB() && + riscv_vlen() >= 128) { + ChaCha20_ctr32_zbb_zvkb(out, inp, len, key, counter); } else { ChaCha20_ctr32_c(out, inp, len, key, counter); } diff --git a/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zbb-zvkb.s b/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zbb-zvkb.s new file mode 100644 index 000000000..2e38d893a --- /dev/null +++ b/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zbb-zvkb.s @@ -0,0 +1,444 @@ +.text +.p2align 3 +.globl ChaCha20_ctr32_zbb_zvkb +.type ChaCha20_ctr32_zbb_zvkb,@function +ChaCha20_ctr32_zbb_zvkb: + addi sp, sp, -96 + sd s0, 0(sp) + sd s1, 8(sp) + sd s2, 16(sp) + sd s3, 24(sp) + sd s4, 32(sp) + sd s5, 40(sp) + sd s6, 48(sp) + sd s7, 56(sp) + sd s8, 64(sp) + sd s9, 72(sp) + sd s10, 80(sp) + sd s11, 88(sp) + addi sp, sp, -64 + + lw t2, 0(a4) + +.Lblock_loop: + # We will use the scalar ALU for 1 chacha block. + srli t3, a2, 6 + .word 219050839 + slli t4, t1, 6 + bltu t4, a2, 1f + # Since there is no more chacha block existed, we need to split 1 block + # from vector ALU. + addi t4, t1, -1 + .word 219083607 +1: + + #### chacha block data + # init chacha const states + # "expa" little endian + li a5, 0x61707865 + .word 1577566295 + # "nd 3" little endian + li a6, 0x3320646e + .word 1577599191 + # "2-by" little endian + li a7, 0x79622d32 + .word 1577632087 + # "te k" little endian + li s0, 0x6b206574 + lw s1, 0(a3) + .word 1577337303 + + # init chacha key states + lw s2, 4(a3) + .word 1577370199 + lw s3, 8(a3) + .word 1577665239 + lw s4, 12(a3) + .word 1577698135 + lw s5, 16(a3) + .word 1577731031 + lw s6, 20(a3) + .word 1577763927 + lw s7, 24(a3) + .word 1577796823 + lw s8, 28(a3) + .word 1577829719 + .word 1577862615 + + # init chacha key states + lw s10, 4(a4) + .word 1376298583 + lw s11, 8(a4) + .word 46384727 + lw t0, 12(a4) + .word 1577928407 + add s9, t2, t1 + + # init chacha nonce states + .word 1577961303 + .word 1577240535 + + li t3, 64 + # load the top-half of input data + .word 3955615751 + + # 20 round groups + li t3, 10 +.Lround_loop: + addi t3, t3, -1 + # a += b; d ^= a; d <<<= 16; + .word 33685591 + add a5, a5, s1 + .word 34767063 + add a6, a6, s2 + .word 35848535 + add a7, a7, s3 + .word 36930007 + add s0, s0, s4 + .word 784336471 + xor s9, s9, a5 + .word 785417943 + xor s10, s10, a6 + .word 786499415 + xor s11, s11, a7 + .word 787580887 + xor t0, t0, s0 + .word 1388852823 + .word 1628232859 + .word 1389901527 + .word 1628265755 + .word 1390950231 + .word 1628298651 + .word 1391998935 + .word 1627574939 + # c += d; b ^= c; b <<<= 12; + .word 42337367 + add s5, s5, s9 + .word 43418839 + add s6, s6, s10 + .word 44500311 + add s7, s7, s11 + .word 45581783 + add s8, s8, t0 + .word 776208983 + xor s1, s1, s5 + .word 777290455 + xor s2, s2, s6 + .word 778371927 + xor s3, s3, s7 + .word 779453399 + xor s4, s4, s8 + .word 1380594263 + .word 1631900827 + .word 1381642967 + .word 1632196891 + .word 1382691671 + .word 1632229787 + .word 1383740375 + .word 1632262683 + # a += b; d ^= a; d <<<= 8; + .word 33685591 + add a5, a5, s1 + .word 34767063 + add a6, a6, s2 + .word 35848535 + add a7, a7, s3 + .word 36930007 + add s0, s0, s4 + .word 784336471 + xor s9, s9, a5 + .word 785417943 + xor s10, s10, a6 + .word 786499415 + xor s11, s11, a7 + .word 787580887 + xor t0, t0, s0 + .word 1389114967 + .word 1636621467 + .word 1390163671 + .word 1636654363 + .word 1391212375 + .word 1636687259 + .word 1392261079 + .word 1635963547 + # c += d; b ^= c; b <<<= 7; + .word 42337367 + add s5, s5, s9 + .word 43418839 + add s6, s6, s10 + .word 44500311 + add s7, s7, s11 + .word 45581783 + add s8, s8, t0 + .word 776208983 + xor s1, s1, s5 + .word 777290455 + xor s2, s2, s6 + .word 778371927 + xor s3, s3, s7 + .word 779453399 + xor s4, s4, s8 + .word 1380758103 + .word 1637143707 + .word 1381806807 + .word 1637439771 + .word 1382855511 + .word 1637472667 + .word 1383904215 + .word 1637505563 + + # a += b; d ^= a; d <<<= 16; + .word 36831703 + add s0, s0, s1 + .word 33718359 + add a5, a5, s2 + .word 34799831 + add a6, a6, s3 + .word 35881303 + add a7, a7, s4 + .word 786532183 + xor s11, s11, s0 + .word 787482583 + xor t0, t0, a5 + .word 784369239 + xor s9, s9, a6 + .word 785450711 + xor s10, s10, a7 + .word 1390950231 + .word 1628298651 + .word 1391998935 + .word 1627574939 + .word 1388852823 + .word 1628232859 + .word 1389901527 + .word 1628265755 + # c += d; b ^= c; b <<<= 12; + .word 43451607 + add s6, s6, s11 + .word 44533079 + add s7, s7, t0 + .word 45483479 + add s8, s8, s9 + .word 42370135 + add s5, s5, s10 + .word 776241751 + xor s1, s1, s6 + .word 777323223 + xor s2, s2, s7 + .word 778404695 + xor s3, s3, s8 + .word 779355095 + xor s4, s4, s5 + .word 1380594263 + .word 1631900827 + .word 1381642967 + .word 1632196891 + .word 1382691671 + .word 1632229787 + .word 1383740375 + .word 1632262683 + # a += b; d ^= a; d <<<= 8; + .word 36831703 + add s0, s0, s1 + .word 33718359 + add a5, a5, s2 + .word 34799831 + add a6, a6, s3 + .word 35881303 + add a7, a7, s4 + .word 786532183 + xor s11, s11, s0 + .word 787482583 + xor t0, t0, a5 + .word 784369239 + xor s9, s9, a6 + .word 785450711 + xor s10, s10, a7 + .word 1391212375 + .word 1636687259 + .word 1392261079 + .word 1635963547 + .word 1389114967 + .word 1636621467 + .word 1390163671 + .word 1636654363 + # c += d; b ^= c; b <<<= 7; + .word 43451607 + add s6, s6, s11 + .word 44533079 + add s7, s7, t0 + .word 45483479 + add s8, s8, s9 + .word 42370135 + add s5, s5, s10 + .word 776241751 + xor s1, s1, s6 + .word 777323223 + xor s2, s2, s7 + .word 778404695 + xor s3, s3, s8 + .word 779355095 + xor s4, s4, s5 + .word 1380758103 + .word 1637143707 + .word 1381806807 + .word 1637439771 + .word 1382855511 + .word 1637472667 + .word 1383904215 + .word 1637505563 + + bnez t3, .Lround_loop + + li t3, 64 + # load the bottom-half of input data + addi t4, a1, 32 + .word 3956206599 + + # add chacha top-half initial block states + # "expa" little endian + li t3, 0x61707865 + .word 34488407 + add a5, a5, t3 + # "nd 3" little endian + li t4, 0x3320646e + .word 35569879 + add a6, a6, t4 + lw t3, 0(a3) + # "2-by" little endian + li t5, 0x79622d32 + .word 36651351 + add a7, a7, t5 + lw t4, 4(a3) + # "te k" little endian + li t6, 0x6b206574 + .word 37732823 + add s0, s0, t6 + lw t5, 8(a3) + .word 38683223 + add s1, s1, t3 + lw t6, 12(a3) + .word 39764695 + add s2, s2, t4 + .word 40846167 + add s3, s3, t5 + .word 41927639 + add s4, s4, t6 + + # xor with the top-half input + .word 788531287 + sw a5, 0(sp) + sw a6, 4(sp) + .word 789612759 + sw a7, 8(sp) + sw s0, 12(sp) + .word 790694231 + sw s1, 16(sp) + sw s2, 20(sp) + .word 791775703 + sw s3, 24(sp) + sw s4, 28(sp) + .word 792857175 + lw t3, 16(a3) + .word 793938647 + lw t4, 20(a3) + .word 795020119 + lw t5, 24(a3) + .word 796101591 + + # save the top-half of output + li t6, 64 + .word 3958728743 + + # add chacha bottom-half initial block states + .word 42878039 + add s5, s5, t3 + lw t6, 28(a3) + .word 43959511 + add s6, s6, t4 + lw t3, 4(a4) + .word 45040983 + add s7, s7, t5 + lw t4, 8(a4) + .word 46122455 + add s8, s8, t6 + lw t5, 12(a4) + .word 1376297047 + add s9, s9, t2 + .word 46384727 + add s9, s9, t1 + .word 48121559 + add s10, s10, t3 + .word 49203031 + add s11, s11, t4 + .word 50284503 + add t0, t0, t5 + .word 46138967 + # xor with the bottom-half input + .word 797183063 + sw s5, 32(sp) + .word 798264535 + sw s6, 36(sp) + .word 799346007 + sw s7, 40(sp) + .word 800427479 + sw s8, 44(sp) + .word 802590423 + sw s9, 48(sp) + .word 801508951 + sw s10, 52(sp) + .word 803671895 + sw s11, 56(sp) + .word 804753367 + sw t0, 60(sp) + + # save the bottom-half of output + li t3, 64 + addi t4, a0, 32 + .word 3956206631 + + # the computed vector parts: `64 * VL` + slli t3, t1, 6 + + add a1, a1, t3 + add a0, a0, t3 + sub a2, a2, t3 + add t2, t2, t1 + + # process the scalar data block + addi t2, t2, 1 + li t3, 64 + .word 197549747 + sub a2, a2, t4 + mv t5, sp +.Lscalar_data_loop: + .word 205452119 + .word 33915911 + .word 34539527 + .word 780665943 + .word 33883175 + add a1, a1, t1 + add a0, a0, t1 + add t5, t5, t1 + sub t4, t4, t1 + bnez t4, .Lscalar_data_loop + + bnez a2, .Lblock_loop + + addi sp, sp, 64 + ld s0, 0(sp) + ld s1, 8(sp) + ld s2, 16(sp) + ld s3, 24(sp) + ld s4, 32(sp) + ld s5, 40(sp) + ld s6, 48(sp) + ld s7, 56(sp) + ld s8, 64(sp) + ld s9, 72(sp) + ld s10, 80(sp) + ld s11, 88(sp) + addi sp, sp, 96 + + ret +.size ChaCha20_ctr32_zbb_zvkb,.-ChaCha20_ctr32_zbb_zvkb diff --git a/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zvkb.s b/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zvkb.s deleted file mode 100644 index df5ec6870..000000000 --- a/openssl/src/crypto/chacha/gen/linux_riscv64/chacha-riscv64-zvkb.s +++ /dev/null @@ -1,267 +0,0 @@ -.text -.p2align 3 -.globl ChaCha20_ctr32_zvkb -.type ChaCha20_ctr32_zvkb,@function -ChaCha20_ctr32_zvkb: - srli a2, a2, 6 - beqz a2, .Lend - - addi sp, sp, -96 - sd s0, 0(sp) - sd s1, 8(sp) - sd s2, 16(sp) - sd s3, 24(sp) - sd s4, 32(sp) - sd s5, 40(sp) - sd s6, 48(sp) - sd s7, 56(sp) - sd s8, 64(sp) - sd s9, 72(sp) - sd s10, 80(sp) - sd s11, 88(sp) - - li t3, 64 - - #### chacha block data - # "expa" little endian - li a5, 0x61707865 - # "nd 3" little endian - li a6, 0x3320646e - # "2-by" little endian - li a7, 0x79622d32 - # "te k" little endian - li t1, 0x6b206574 - - lw s0, 0(a3) - lw s1, 4(a3) - lw s2, 8(a3) - lw s3, 12(a3) - lw s4, 16(a3) - lw s5, 20(a3) - lw s6, 24(a3) - lw s7, 28(a3) - - lw s8, 0(a4) - lw s9, 4(a4) - lw s10, 8(a4) - lw s11, 12(a4) - -.Lblock_loop: - .word 218526679 - - # init chacha const states - .word 1577566295 - .word 1577599191 - .word 1577632087 - .word 1577271767 - - # init chacha key states - .word 1577337431 - .word 1577370327 - .word 1577665367 - .word 1577698263 - .word 1577731159 - .word 1577764055 - .word 1577796951 - .word 1577829847 - - # init chacha key states - .word 1376298583 - .word 46941783 - .word 1577895639 - - # init chacha nonce states - .word 1577928535 - .word 1577961431 - - # load the top-half of input data - .word 3955615751 - - li t4, 10 -.Lround_loop: - addi t4, t4, -1 - # a += b; d ^= a; d <<<= 16; - .word 33685591 - .word 34767063 - .word 35848535 - .word 36930007 - .word 784336471 - .word 785417943 - .word 786499415 - .word 787580887 - .word 1388852823 - .word 1389901527 - .word 1390950231 - .word 1391998935 - # c += d; b ^= c; b <<<= 12; - .word 42337367 - .word 43418839 - .word 44500311 - .word 45581783 - .word 776208983 - .word 777290455 - .word 778371927 - .word 779453399 - .word 1380594263 - .word 1381642967 - .word 1382691671 - .word 1383740375 - # a += b; d ^= a; d <<<= 8; - .word 33685591 - .word 34767063 - .word 35848535 - .word 36930007 - .word 784336471 - .word 785417943 - .word 786499415 - .word 787580887 - .word 1389114967 - .word 1390163671 - .word 1391212375 - .word 1392261079 - # c += d; b ^= c; b <<<= 7; - .word 42337367 - .word 43418839 - .word 44500311 - .word 45581783 - .word 776208983 - .word 777290455 - .word 778371927 - .word 779453399 - .word 1380758103 - .word 1381806807 - .word 1382855511 - .word 1383904215 - - # a += b; d ^= a; d <<<= 16; - .word 33718359 - .word 34799831 - .word 35881303 - .word 36831703 - .word 787482583 - .word 784369239 - .word 785450711 - .word 786532183 - .word 1391998935 - .word 1388852823 - .word 1389901527 - .word 1390950231 - # c += d; b ^= c; b <<<= 12; - .word 44533079 - .word 45483479 - .word 42370135 - .word 43451607 - .word 777323223 - .word 778404695 - .word 779355095 - .word 776241751 - .word 1381642967 - .word 1382691671 - .word 1383740375 - .word 1380594263 - # a += b; d ^= a; d <<<= 8; - .word 33718359 - .word 34799831 - .word 35881303 - .word 36831703 - .word 787482583 - .word 784369239 - .word 785450711 - .word 786532183 - .word 1392261079 - .word 1389114967 - .word 1390163671 - .word 1391212375 - # c += d; b ^= c; b <<<= 7; - .word 44533079 - .word 45483479 - .word 42370135 - .word 43451607 - .word 777323223 - .word 778404695 - .word 779355095 - .word 776241751 - .word 1381806807 - .word 1382855511 - .word 1383904215 - .word 1380758103 - - bnez t4, .Lround_loop - - # load the bottom-half of input data - addi t0, a1, 32 - .word 3955420167 - - # add chacha top-half initial block states - .word 34062423 - .word 35143895 - .word 36225367 - .word 36913623 - .word 38027863 - .word 39109335 - .word 40452951 - .word 41534423 - # xor with the top-half input - .word 788531287 - .word 789612759 - .word 790694231 - .word 791775703 - .word 792857175 - .word 793938647 - .word 795020119 - .word 796101591 - - # save the top-half of output - .word 3955583015 - - # add chacha bottom-half initial block states - .word 42615895 - .word 43697367 - .word 44778839 - .word 45860311 - .word 1376297047 - .word 46941783 - .word 48023255 - .word 49104727 - .word 50186199 - .word 46138967 - # xor with the bottom-half input - .word 797183063 - .word 798264535 - .word 799346007 - .word 800427479 - .word 802590423 - .word 801508951 - .word 803671895 - .word 804753367 - - # save the bottom-half of output - addi t0, a0, 32 - .word 3955420199 - - # update counter - add s8, s8, t2 - sub a2, a2, t2 - # increase offset for `4 * 16 * VL = 64 * VL` - slli t0, t2, 6 - add a1, a1, t0 - add a0, a0, t0 - bnez a2, .Lblock_loop - - ld s0, 0(sp) - ld s1, 8(sp) - ld s2, 16(sp) - ld s3, 24(sp) - ld s4, 32(sp) - ld s5, 40(sp) - ld s6, 48(sp) - ld s7, 56(sp) - ld s8, 64(sp) - ld s9, 72(sp) - ld s10, 80(sp) - ld s11, 88(sp) - addi sp, sp, 96 - -.Lend: - ret -.size ChaCha20_ctr32_zvkb,.-ChaCha20_ctr32_zvkb diff --git a/openssl/src/crypto/cmp/cmp_asn.c b/openssl/src/crypto/cmp/cmp_asn.c index 3049d4f08..3285cbf42 100644 --- a/openssl/src/crypto/cmp/cmp_asn.c +++ b/openssl/src/crypto/cmp/cmp_asn.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -287,23 +287,30 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, const X509 *oldWithNew) { OSSL_CMP_ITAV *itav; - OSSL_CMP_ROOTCAKEYUPDATE *upd = OSSL_CMP_ROOTCAKEYUPDATE_new(); + OSSL_CMP_ROOTCAKEYUPDATE *upd = NULL; + + if (newWithNew != NULL) { + upd = OSSL_CMP_ROOTCAKEYUPDATE_new(); + if (upd == NULL) + return NULL; + + if ((upd->newWithNew = X509_dup(newWithNew)) == NULL) + goto err; + if (newWithOld != NULL + && (upd->newWithOld = X509_dup(newWithOld)) == NULL) + goto err; + if (oldWithNew != NULL + && (upd->oldWithNew = X509_dup(oldWithNew)) == NULL) + goto err; + } - if (upd == NULL) - return NULL; - if (newWithNew != NULL && (upd->newWithNew = X509_dup(newWithNew)) == NULL) - goto err; - if (newWithOld != NULL && (upd->newWithOld = X509_dup(newWithOld)) == NULL) - goto err; - if (oldWithNew != NULL && (upd->oldWithNew = X509_dup(oldWithNew)) == NULL) - goto err; if ((itav = OSSL_CMP_ITAV_new()) == NULL) goto err; itav->infoType = OBJ_nid2obj(NID_id_it_rootCaKeyUpdate); itav->infoValue.rootCaKeyUpdate = upd; return itav; - err: + err: OSSL_CMP_ROOTCAKEYUPDATE_free(upd); return NULL; } @@ -324,11 +331,11 @@ int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, return 0; } upd = itav->infoValue.rootCaKeyUpdate; - *newWithNew = upd->newWithNew; + *newWithNew = upd != NULL ? upd->newWithNew : NULL; if (newWithOld != NULL) - *newWithOld = upd->newWithOld; + *newWithOld = upd != NULL ? upd->newWithOld : NULL; if (oldWithNew != NULL) - *oldWithNew = upd->oldWithNew; + *oldWithNew = upd != NULL ? upd->oldWithNew : NULL; return 1; } diff --git a/openssl/src/crypto/cmp/cmp_genm.c b/openssl/src/crypto/cmp/cmp_genm.c index dad6ef118..5986036f5 100644 --- a/openssl/src/crypto/cmp/cmp_genm.c +++ b/openssl/src/crypto/cmp/cmp_genm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2022 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -307,9 +307,11 @@ int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, if (!OSSL_CMP_ITAV_get0_rootCaKeyUpdate(itav, newWithNew, &my_newWithOld, &my_oldWithNew)) goto end; - - if (*newWithNew == NULL) /* no root CA cert update available */ + /* no root CA cert update available */ + if (*newWithNew == NULL) { + res = 1; goto end; + } if ((oldWithOld_copy = X509_dup(oldWithOld)) == NULL && oldWithOld != NULL) goto end; if (!verify_ss_cert_trans(ctx, oldWithOld_copy, my_newWithOld, diff --git a/openssl/src/crypto/cms/cms_asn1.c b/openssl/src/crypto/cms/cms_asn1.c index bc6b2769f..ecf5a4479 100644 --- a/openssl/src/crypto/cms/cms_asn1.c +++ b/openssl/src/crypto/cms/cms_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -51,6 +51,7 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, EVP_PKEY_free(si->pkey); X509_free(si->signer); EVP_MD_CTX_free(si->mctx); + EVP_PKEY_CTX_free(si->pctx); } return 1; } @@ -90,11 +91,21 @@ ASN1_SEQUENCE(CMS_OriginatorInfo) = { ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) } static_ASN1_SEQUENCE_END(CMS_OriginatorInfo) -ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { +static int cms_ec_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + CMS_EncryptedContentInfo *ec = (CMS_EncryptedContentInfo *)*pval; + + if (operation == ASN1_OP_FREE_POST) + OPENSSL_clear_free(ec->key, ec->keylen); + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(CMS_EncryptedContentInfo, cms_ec_cb) = { ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) -} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) +} ASN1_NDEF_SEQUENCE_END_cb(CMS_EncryptedContentInfo, CMS_EncryptedContentInfo) ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { ASN1_EMBED(CMS_KeyTransRecipientInfo, version, INT32), @@ -318,6 +329,10 @@ static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; break; + case ASN1_OP_FREE_POST: + OPENSSL_free(cms->ctx.propq); + break; + } return 1; } diff --git a/openssl/src/crypto/cms/cms_env.c b/openssl/src/crypto/cms/cms_env.c index b877e1061..2d87738ee 100644 --- a/openssl/src/crypto/cms/cms_env.c +++ b/openssl/src/crypto/cms/cms_env.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -51,15 +51,6 @@ static int cms_get_enveloped_type(const CMS_ContentInfo *cms) return ret; } -void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf) -{ - if (cms_get_enveloped_type_simple(cinf) != 0) { - CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cinf); - if (ec != NULL) - OPENSSL_clear_free(ec->key, ec->keylen); - } -} - CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms) { if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { @@ -289,8 +280,10 @@ BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, secret == NULL ? cert : NULL, detached_data, bio, flags); end: - if (ci != NULL) + if (ci != NULL) { ci->d.envelopedData = NULL; /* do not indirectly free |env| */ + ci->contentType = NULL; + } CMS_ContentInfo_free(ci); if (!res) { BIO_free(bio); diff --git a/openssl/src/crypto/cms/cms_lib.c b/openssl/src/crypto/cms/cms_lib.c index afc210c9d..4ef614162 100644 --- a/openssl/src/crypto/cms/cms_lib.c +++ b/openssl/src/crypto/cms/cms_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,6 +21,7 @@ static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms); +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_ContentInfo) IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, @@ -66,20 +67,6 @@ CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) return ci; } -CMS_ContentInfo *CMS_ContentInfo_new(void) -{ - return CMS_ContentInfo_new_ex(NULL, NULL); -} - -void CMS_ContentInfo_free(CMS_ContentInfo *cms) -{ - if (cms != NULL) { - ossl_cms_env_enc_content_free(cms); - OPENSSL_free(cms->ctx.propq); - ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo)); - } -} - const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms) { return cms != NULL ? &cms->ctx : NULL; diff --git a/openssl/src/crypto/cms/cms_local.h b/openssl/src/crypto/cms/cms_local.h index 706902126..fd5c7c9a6 100644 --- a/openssl/src/crypto/cms/cms_local.h +++ b/openssl/src/crypto/cms/cms_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -366,6 +366,7 @@ struct CMS_Receipt_st { DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_ITEM(CMS_SignerInfo) +DECLARE_ASN1_ITEM(CMS_EncryptedContentInfo) DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) DECLARE_ASN1_ITEM(CMS_Attributes_Sign) DECLARE_ASN1_ITEM(CMS_Attributes_Verify) @@ -447,7 +448,6 @@ BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms); int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio); -void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf); CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms); CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms); CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms); diff --git a/openssl/src/crypto/cms/cms_sd.c b/openssl/src/crypto/cms/cms_sd.c index b41e3571b..8ad94a9ed 100644 --- a/openssl/src/crypto/cms/cms_sd.c +++ b/openssl/src/crypto/cms/cms_sd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -512,8 +512,12 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, ossl_cms_ctx_get0_libctx(ctx), ossl_cms_ctx_get0_propq(ctx), pk, NULL) <= 0) { + si->pctx = NULL; goto err; } + else { + EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } } if (sd->signerInfos == NULL) @@ -758,6 +762,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, unsigned char computed_md[EVP_MAX_MD_SIZE]; pctx = si->pctx; + si->pctx = NULL; if (md == NULL) { if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen)) goto err; @@ -851,6 +856,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) ossl_cms_ctx_get0_propq(ctx), si->pkey, NULL) <= 0) goto err; + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); si->pctx = pctx; } @@ -922,9 +928,16 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) goto err; } mctx = si->mctx; + if (si->pctx != NULL) { + EVP_PKEY_CTX_free(si->pctx); + si->pctx = NULL; + } if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx, - propq, si->pkey, NULL) <= 0) + propq, si->pkey, NULL) <= 0) { + si->pctx = NULL; goto err; + } + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); if (!cms_sd_asn1_ctrl(si, 1)) goto err; @@ -1040,8 +1053,11 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) goto err; si->pctx = pkctx; - if (!cms_sd_asn1_ctrl(si, 1)) + if (!cms_sd_asn1_ctrl(si, 1)) { + si->pctx = NULL; goto err; + } + si->pctx = NULL; r = EVP_PKEY_verify(pkctx, si->signature->data, si->signature->length, mval, mlen); if (r <= 0) { diff --git a/openssl/src/crypto/cms/cms_smime.c b/openssl/src/crypto/cms/cms_smime.c index 99a72f4df..3a8b13d6e 100644 --- a/openssl/src/crypto/cms/cms_smime.c +++ b/openssl/src/crypto/cms/cms_smime.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -236,7 +236,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, if (cms == NULL) return NULL; if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) - return NULL; + goto err; if (!(flags & CMS_DETACHED)) CMS_set_detached(cms, 0); @@ -245,6 +245,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, || CMS_final(cms, in, NULL, flags)) return cms; + err: CMS_ContentInfo_free(cms); return NULL; } diff --git a/openssl/src/crypto/conf/conf_lib.c b/openssl/src/crypto/conf/conf_lib.c index e82a07da5..601f49430 100644 --- a/openssl/src/crypto/conf/conf_lib.c +++ b/openssl/src/crypto/conf/conf_lib.c @@ -7,8 +7,6 @@ * https://www.openssl.org/source/license.html */ -#define _XOPEN_SOURCE_EXTENDED /* To get a definition of strdup() */ - #include "internal/e_os.h" #include #include diff --git a/openssl/src/crypto/conf/conf_mod.c b/openssl/src/crypto/conf/conf_mod.c index 7efb98205..a19575af3 100644 --- a/openssl/src/crypto/conf/conf_mod.c +++ b/openssl/src/crypto/conf/conf_mod.c @@ -368,6 +368,7 @@ static CONF_MODULE *module_add(DSO *dso, const char *name, err: ossl_rcu_write_unlock(module_list_lock); + sk_CONF_MODULE_free(new_modules); if (tmod != NULL) { OPENSSL_free(tmod->name); OPENSSL_free(tmod); @@ -466,6 +467,7 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value, if (!sk_CONF_IMODULE_push(new_modules, imod)) { ossl_rcu_write_unlock(module_list_lock); + sk_CONF_IMODULE_free(new_modules); ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); goto err; } diff --git a/openssl/src/crypto/conf/conf_sap.c b/openssl/src/crypto/conf/conf_sap.c index 15fd2f3f9..6b3defe0f 100644 --- a/openssl/src/crypto/conf/conf_sap.c +++ b/openssl/src/crypto/conf/conf_sap.c @@ -7,8 +7,6 @@ * https://www.openssl.org/source/license.html */ -#define _XOPEN_SOURCE_EXTENDED /* To get a definition of strdup() */ - #include #include #include "internal/cryptlib.h" diff --git a/openssl/src/crypto/deterministic_nonce.c b/openssl/src/crypto/deterministic_nonce.c index 60af7f6ab..3da9ba420 100644 --- a/openssl/src/crypto/deterministic_nonce.c +++ b/openssl/src/crypto/deterministic_nonce.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,11 +7,13 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include #include #include "internal/deterministic_nonce.h" +#include "crypto/bn.h" /* * Convert a Bit String to an Integer (See RFC 6979 Section 2.3.2) @@ -38,6 +40,36 @@ static int bits2int(BIGNUM *out, int qlen_bits, return 1; } +/* + * Convert as above a Bit String in const time to an Integer w fixed top + * + * Params: + * out The returned Integer as a BIGNUM + * qlen_bits The maximum size of the returned integer in bits. The returned + * Integer is shifted right if inlen is larger than qlen_bits.. + * in, inlen The input Bit String (in bytes). It has sizeof(BN_ULONG) bytes + * prefix with all bits set that needs to be cleared out after + * the conversion. + * Returns: 1 if successful, or 0 otherwise. + */ +static int bits2int_consttime(BIGNUM *out, int qlen_bits, + const unsigned char *in, size_t inlen) +{ + int blen_bits = (inlen - sizeof(BN_ULONG)) * 8; + int shift; + + if (BN_bin2bn(in, (int)inlen, out) == NULL) + return 0; + + BN_set_flags(out, BN_FLG_CONSTTIME); + ossl_bn_mask_bits_fixed_top(out, blen_bits); + + shift = blen_bits - qlen_bits; + if (shift > 0) + return bn_rshift_fixed_top(out, out, shift); + return 1; +} + /* * Convert an Integer to an Octet String (See RFC 6979 2.3.3). * The value is zero padded if required. @@ -155,8 +187,9 @@ int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, { EVP_KDF_CTX *kdfctx = NULL; int ret = 0, rlen = 0, qlen_bits = 0; - unsigned char *entropyx = NULL, *nonceh = NULL, *T = NULL; + unsigned char *entropyx = NULL, *nonceh = NULL, *rbits = NULL, *T = NULL; size_t allocsz = 0; + const size_t prefsz = sizeof(BN_ULONG); if (out == NULL) return 0; @@ -167,15 +200,18 @@ int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, /* Note rlen used here is in bytes since the input values are byte arrays */ rlen = (qlen_bits + 7) / 8; - allocsz = 3 * rlen; + allocsz = prefsz + 3 * rlen; /* Use a single alloc for the buffers T, nonceh and entropyx */ T = (unsigned char *)OPENSSL_zalloc(allocsz); if (T == NULL) return 0; - nonceh = T + rlen; + rbits = T + prefsz; + nonceh = rbits + rlen; entropyx = nonceh + rlen; + memset(T, 0xff, prefsz); + if (!int2octets(entropyx, priv, rlen) || !bits2octets(nonceh, q, qlen_bits, rlen, hm, hmlen)) goto end; @@ -185,10 +221,16 @@ int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, goto end; do { - if (!EVP_KDF_derive(kdfctx, T, rlen, NULL) - || !bits2int(out, qlen_bits, T, rlen)) + if (!EVP_KDF_derive(kdfctx, rbits, rlen, NULL) + || !bits2int_consttime(out, qlen_bits, T, rlen + prefsz)) goto end; - } while (BN_is_zero(out) || BN_is_one(out) || BN_cmp(out, q) >= 0); + } while (ossl_bn_is_word_fixed_top(out, 0) + || ossl_bn_is_word_fixed_top(out, 1) + || BN_ucmp(out, q) >= 0); +#ifdef BN_DEBUG + /* With BN_DEBUG on a fixed top number cannot be returned */ + bn_correct_top(out); +#endif ret = 1; end: diff --git a/openssl/src/crypto/dsa/dsa_check.c b/openssl/src/crypto/dsa/dsa_check.c index 7b6d7df88..e1375dfad 100644 --- a/openssl/src/crypto/dsa/dsa_check.c +++ b/openssl/src/crypto/dsa/dsa_check.c @@ -19,8 +19,34 @@ #include "dsa_local.h" #include "crypto/dsa.h" +static int dsa_precheck_params(const DSA *dsa, int *ret) +{ + if (dsa->params.p == NULL || dsa->params.q == NULL) { + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); + *ret = FFC_CHECK_INVALID_PQ; + return 0; + } + + if (BN_num_bits(dsa->params.p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE); + *ret = FFC_CHECK_INVALID_PQ; + return 0; + } + + if (BN_num_bits(dsa->params.q) >= BN_num_bits(dsa->params.p)) { + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_Q_VALUE); + *ret = FFC_CHECK_INVALID_PQ; + return 0; + } + + return 1; +} + int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret) { + if (!dsa_precheck_params(dsa, ret)) + return 0; + if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK) return ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, FFC_PARAM_TYPE_DSA, ret); @@ -39,6 +65,9 @@ int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret) */ int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) { + if (!dsa_precheck_params(dsa, ret)) + return 0; + return ossl_ffc_validate_public_key(&dsa->params, pub_key, ret) && *ret == 0; } @@ -50,6 +79,9 @@ int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) */ int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret) { + if (!dsa_precheck_params(dsa, ret)) + return 0; + return ossl_ffc_validate_public_key_partial(&dsa->params, pub_key, ret) && *ret == 0; } @@ -58,8 +90,10 @@ int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret) { *ret = 0; - return (dsa->params.q != NULL - && ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret)); + if (!dsa_precheck_params(dsa, ret)) + return 0; + + return ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret); } /* @@ -72,8 +106,10 @@ int ossl_dsa_check_pairwise(const DSA *dsa) BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL; - if (dsa->params.p == NULL - || dsa->params.g == NULL + if (!dsa_precheck_params(dsa, &ret)) + return 0; + + if (dsa->params.g == NULL || dsa->priv_key == NULL || dsa->pub_key == NULL) return 0; diff --git a/openssl/src/crypto/dsa/dsa_ossl.c b/openssl/src/crypto/dsa/dsa_ossl.c index 234362b6d..59b26d736 100644 --- a/openssl/src/crypto/dsa/dsa_ossl.c +++ b/openssl/src/crypto/dsa/dsa_ossl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -282,13 +282,14 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, * We calculate k from SHA512(private_key + H(message) + random). * This protects the private key from a weak PRNG. */ - if (!BN_generate_dsa_nonce(k, dsa->params.q, dsa->priv_key, dgst, - dlen, ctx)) + if (!ossl_bn_gen_dsa_nonce_fixed_top(k, dsa->params.q, + dsa->priv_key, dgst, + dlen, ctx)) goto err; } - } else if (!BN_priv_rand_range_ex(k, dsa->params.q, 0, ctx)) + } else if (!ossl_bn_priv_rand_range_fixed_top(k, dsa->params.q, 0, ctx)) goto err; - } while (BN_is_zero(k)); + } while (ossl_bn_is_word_fixed_top(k, 0)); BN_set_flags(k, BN_FLG_CONSTTIME); BN_set_flags(l, BN_FLG_CONSTTIME); diff --git a/openssl/src/crypto/ec/ecdsa_ossl.c b/openssl/src/crypto/ec/ecdsa_ossl.c index 78de835bb..8b4d25d59 100644 --- a/openssl/src/crypto/ec/ecdsa_ossl.c +++ b/openssl/src/crypto/ec/ecdsa_ossl.c @@ -198,17 +198,17 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, libctx, propq); #endif } else { - res = BN_generate_dsa_nonce(k, order, priv_key, dgst, dlen, - ctx); + res = ossl_bn_gen_dsa_nonce_fixed_top(k, order, priv_key, + dgst, dlen, ctx); } } else { - res = BN_priv_rand_range_ex(k, order, 0, ctx); + res = ossl_bn_priv_rand_range_fixed_top(k, order, 0, ctx); } if (!res) { ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } - } while (BN_is_zero(k)); + } while (ossl_bn_is_word_fixed_top(k, 0)); /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { diff --git a/openssl/src/crypto/ess/ess_lib.c b/openssl/src/crypto/ess/ess_lib.c index 0612e68ee..ff174470d 100644 --- a/openssl/src/crypto/ess/ess_lib.c +++ b/openssl/src/crypto/ess/ess_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -346,7 +346,7 @@ int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss, int i, ret; if (require_signing_cert && ss == NULL && ssv2 == NULL) { - ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); + ERR_raise(ERR_LIB_ESS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); return -1; } if (n_v1 == 0 || n_v2 == 0) { diff --git a/openssl/src/crypto/evp/pmeth_lib.c b/openssl/src/crypto/evp/pmeth_lib.c index c4b96156f..0a561323f 100644 --- a/openssl/src/crypto/evp/pmeth_lib.c +++ b/openssl/src/crypto/evp/pmeth_lib.c @@ -1002,6 +1002,71 @@ static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback, return EVP_PKEY_CTX_set_params(ctx, octet_string_params); } +static int evp_pkey_ctx_add1_octet_string(EVP_PKEY_CTX *ctx, int fallback, + const char *param, int op, int ctrl, + const unsigned char *data, + int datalen) +{ + OSSL_PARAM os_params[2]; + unsigned char *info = NULL; + size_t info_len = 0; + size_t info_alloc = 0; + int ret = 0; + + if (ctx == NULL || (ctx->operation & op) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* Code below to be removed when legacy support is dropped. */ + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, datalen, (void *)(data)); + /* end of legacy support */ + + if (datalen < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH); + return 0; + } else if (datalen == 0) { + return 1; + } + + /* Get the original value length */ + os_params[0] = OSSL_PARAM_construct_octet_string(param, NULL, 0); + os_params[1] = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, os_params)) + return 0; + + /* Older provider that doesn't support getting this parameter */ + if (os_params[0].return_size == OSSL_PARAM_UNMODIFIED) + return evp_pkey_ctx_set1_octet_string(ctx, fallback, param, op, ctrl, data, datalen); + + info_alloc = os_params[0].return_size + datalen; + if (info_alloc == 0) + return 0; + info = OPENSSL_zalloc(info_alloc); + if (info == NULL) + return 0; + info_len = os_params[0].return_size; + + os_params[0] = OSSL_PARAM_construct_octet_string(param, info, info_alloc); + + /* if we have data, then go get it */ + if (info_len > 0) { + if (!EVP_PKEY_CTX_get_params(ctx, os_params)) + goto error; + } + + /* Copy the input data */ + memcpy(&info[info_len], data, datalen); + ret = EVP_PKEY_CTX_set_params(ctx, os_params); + + error: + OPENSSL_clear_free(info, info_alloc); + return ret; +} + int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *ctx, const unsigned char *sec, int seclen) { @@ -1052,7 +1117,7 @@ int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const unsigned char *info, int infolen) { - return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + return evp_pkey_ctx_add1_octet_string(ctx, ctx->op.kex.algctx == NULL, OSSL_KDF_PARAM_INFO, EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_HKDF_INFO, diff --git a/openssl/src/crypto/params.c b/openssl/src/crypto/params.c index 0baf3fc17..c109cabd4 100644 --- a/openssl/src/crypto/params.c +++ b/openssl/src/crypto/params.c @@ -469,9 +469,6 @@ int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val) int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val) { - uint32_t u32; - unsigned int shift; - if (p == NULL) { err_null_argument; return 0; @@ -511,6 +508,9 @@ int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val) return general_set_int(p, &val, sizeof(val)); } else if (p->data_type == OSSL_PARAM_REAL) { #ifndef OPENSSL_SYS_UEFI + uint32_t u32; + unsigned int shift; + p->return_size = sizeof(double); if (p->data == NULL) return 1; @@ -624,8 +624,6 @@ int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val) int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val) { - unsigned int shift; - if (p == NULL) { err_null_argument; return 0; @@ -670,6 +668,8 @@ int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val) return general_set_uint(p, &val, sizeof(val)); } else if (p->data_type == OSSL_PARAM_REAL) { #ifndef OPENSSL_SYS_UEFI + unsigned int shift; + p->return_size = sizeof(double); if (p->data == NULL) return 1; diff --git a/openssl/src/crypto/provider_core.c b/openssl/src/crypto/provider_core.c index 57dacd76f..297b281a3 100644 --- a/openssl/src/crypto/provider_core.c +++ b/openssl/src/crypto/provider_core.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -446,13 +446,11 @@ static OSSL_PROVIDER *provider_new(const char *name, OPENSSL_free(prov); return NULL; } -#ifndef HAVE_ATOMICS if ((prov->activatecnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { ossl_provider_free(prov); ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return NULL; } -#endif if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL @@ -566,8 +564,10 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, if (params[i].data_type != OSSL_PARAM_UTF8_STRING) continue; if (ossl_provider_info_add_parameter(&template, params[i].key, - (char *)params[i].data) <= 0) + (char *)params[i].data) <= 0) { + sk_INFOPAIR_pop_free(template.parameters, infopair_free); return NULL; + } } } @@ -580,6 +580,11 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, if (prov == NULL) return NULL; + if (!ossl_provider_set_module_path(prov, template.path)) { + ossl_provider_free(prov); + return NULL; + } + prov->libctx = libctx; #ifndef FIPS_MODULE prov->error_lib = ERR_get_next_error_library(); @@ -742,9 +747,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov) sk_INFOPAIR_pop_free(prov->parameters, infopair_free); CRYPTO_THREAD_lock_free(prov->opbits_lock); CRYPTO_THREAD_lock_free(prov->flag_lock); -#ifndef HAVE_ATOMICS CRYPTO_THREAD_lock_free(prov->activatecnt_lock); -#endif CRYPTO_FREE_REF(&prov->refcnt); OPENSSL_free(prov); } diff --git a/openssl/src/crypto/sm2/sm2_crypt.c b/openssl/src/crypto/sm2/sm2_crypt.c index affa920ff..b7303af52 100644 --- a/openssl/src/crypto/sm2/sm2_crypt.c +++ b/openssl/src/crypto/sm2/sm2_crypt.c @@ -54,6 +54,18 @@ static size_t ec_field_size(const EC_GROUP *group) return BN_num_bytes(p); } +static int is_all_zeros(const unsigned char *msg, size_t msglen) +{ + unsigned char re = 0; + size_t i; + + for (i = 0; i < msglen; i++) { + re |= msg[i]; + } + + return re == 0 ? 1 : 0; +} + int ossl_sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size) { @@ -168,6 +180,11 @@ int ossl_sm2_encrypt(const EC_KEY *key, memset(ciphertext_buf, 0, *ciphertext_len); + msg_mask = OPENSSL_zalloc(msg_len); + if (msg_mask == NULL) + goto done; + +again: if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; @@ -187,10 +204,6 @@ int ossl_sm2_encrypt(const EC_KEY *key, goto done; } - msg_mask = OPENSSL_zalloc(msg_len); - if (msg_mask == NULL) - goto done; - /* X9.63 with no salt happens to match the KDF used in SM2 */ if (!ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest, libctx, propq)) { @@ -198,6 +211,11 @@ int ossl_sm2_encrypt(const EC_KEY *key, goto done; } + if (is_all_zeros(msg_mask, msg_len)) { + memset(x2y2, 0, 2 * field_size); + goto again; + } + for (i = 0; i != msg_len; ++i) msg_mask[i] ^= msg[i]; @@ -349,6 +367,11 @@ int ossl_sm2_decrypt(const EC_KEY *key, goto done; } + if (is_all_zeros(msg_mask, msg_len)) { + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); + goto done; + } + for (i = 0; i != msg_len; ++i) ptext_buf[i] = C2[i] ^ msg_mask[i]; diff --git a/openssl/src/crypto/sm2/sm2_sign.c b/openssl/src/crypto/sm2/sm2_sign.c index b4932e312..9ddf889ed 100644 --- a/openssl/src/crypto/sm2/sm2_sign.c +++ b/openssl/src/crypto/sm2/sm2_sign.c @@ -28,6 +28,7 @@ int ossl_sm2_compute_z_digest(uint8_t *out, { int rc = 0; const EC_GROUP *group = EC_KEY_get0_group(key); + const EC_POINT *pubkey = EC_KEY_get0_public_key(key); BN_CTX *ctx = NULL; EVP_MD_CTX *hash = NULL; BIGNUM *p = NULL; @@ -42,6 +43,12 @@ int ossl_sm2_compute_z_digest(uint8_t *out, uint16_t entl = 0; uint8_t e_byte = 0; + /* SM2 Signatures require a public key, check for it */ + if (pubkey == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); + goto done; + } + hash = EVP_MD_CTX_new(); if (hash == NULL) { ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); @@ -119,7 +126,7 @@ int ossl_sm2_compute_z_digest(uint8_t *out, || BN_bn2binpad(yG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, - EC_KEY_get0_public_key(key), + pubkey, xA, yA, ctx) || BN_bn2binpad(xA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) diff --git a/openssl/src/crypto/store/store_lib.c b/openssl/src/crypto/store/store_lib.c index 05a8044f8..0b55123d8 100644 --- a/openssl/src/crypto/store/store_lib.c +++ b/openssl/src/crypto/store/store_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -149,8 +149,8 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, ossl_pw_passphrase_callback_dec, &pwdata); } else { - loader_ctx = fetched_loader->p_open(provctx, uri); - if (loader_ctx != NULL && + if (fetched_loader->p_open != NULL && + (loader_ctx = fetched_loader->p_open(provctx, uri)) != NULL && !loader_set_params(fetched_loader, loader_ctx, params, propq)) { (void)fetched_loader->p_close(loader_ctx); @@ -1037,6 +1037,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp); if (cbio == NULL + || fetched_loader->p_attach == NULL || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) { OSSL_STORE_LOADER_free(fetched_loader); fetched_loader = NULL; diff --git a/openssl/src/crypto/threads_pthread.c b/openssl/src/crypto/threads_pthread.c index 5319121f9..92346e168 100644 --- a/openssl/src/crypto/threads_pthread.c +++ b/openssl/src/crypto/threads_pthread.c @@ -29,7 +29,7 @@ * * See: https://github.com/llvm/llvm-project/commit/a4c2602b714e6c6edb98164550a5ae829b2de760 */ -#define BROKEN_CLANG_ATOMICS +# define BROKEN_CLANG_ATOMICS #endif #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) @@ -37,7 +37,7 @@ # if defined(OPENSSL_SYS_UNIX) # include # include -#endif +# endif # include @@ -45,71 +45,140 @@ # define USE_RWLOCK # endif -# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) -# define ATOMIC_LOAD_N(p,o) __atomic_load_n(p, o) -# define ATOMIC_STORE_N(p, v, o) __atomic_store_n(p, v, o) -# define ATOMIC_STORE(p, v, o) __atomic_store(p, v, o) -# define ATOMIC_EXCHANGE_N(p, v, o) __atomic_exchange_n(p, v, o) -# define ATOMIC_ADD_FETCH(p, v, o) __atomic_add_fetch(p, v, o) -# define ATOMIC_FETCH_ADD(p, v, o) __atomic_fetch_add(p, v, o) -# define ATOMIC_SUB_FETCH(p, v, o) __atomic_sub_fetch(p, v, o) -# define ATOMIC_AND_FETCH(p, m, o) __atomic_and_fetch(p, m, o) -# define ATOMIC_OR_FETCH(p, m, o) __atomic_or_fetch(p, m, o) -#else -static pthread_mutex_t atomic_sim_lock = PTHREAD_MUTEX_INITIALIZER; - -static inline void *fallback_atomic_load_n(void **p) -{ - void *ret; +/* + * For all GNU/clang atomic builtins, we also need fallbacks, to cover all + * other compilers. - pthread_mutex_lock(&atomic_sim_lock); - ret = *(void **)p; - pthread_mutex_unlock(&atomic_sim_lock); - return ret; -} + * Unfortunately, we can't do that with some "generic type", because there's no + * guarantee that the chosen generic type is large enough to cover all cases. + * Therefore, we implement fallbacks for each applicable type, with composed + * names that include the type they handle. + * + * (an anecdote: we previously tried to use |void *| as the generic type, with + * the thought that the pointer itself is the largest type. However, this is + * not true on 32-bit pointer platforms, as a |uint64_t| is twice as large) + * + * All applicable ATOMIC_ macros take the intended type as first parameter, so + * they can map to the correct fallback function. In the GNU/clang case, that + * parameter is simply ignored. + */ -# define ATOMIC_LOAD_N(p, o) fallback_atomic_load_n((void **)p) +/* + * Internal types used with the ATOMIC_ macros, to make it possible to compose + * fallback function names. + */ +typedef void *pvoid; +typedef struct rcu_cb_item *prcu_cb_item; -static inline void *fallback_atomic_store_n(void **p, void *v) +# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) \ + && !defined(USE_ATOMIC_FALLBACKS) +# if defined(__APPLE__) && defined(__clang__) && defined(__aarch64__) +/* + * For pointers, Apple M1 virtualized cpu seems to have some problem using the + * ldapr instruction (see https://github.com/openssl/openssl/pull/23974) + * When using the native apple clang compiler, this instruction is emitted for + * atomic loads, which is bad. So, if + * 1) We are building on a target that defines __APPLE__ AND + * 2) We are building on a target using clang (__clang__) AND + * 3) We are building for an M1 processor (__aarch64__) + * Then we shold not use __atomic_load_n and instead implement our own + * function to issue the ldar instruction instead, which procuces the proper + * sequencing guarantees + */ +static inline void *apple_atomic_load_n_pvoid(void **p, + ossl_unused int memorder) { void *ret; - pthread_mutex_lock(&atomic_sim_lock); - ret = *p; - *p = v; - pthread_mutex_unlock(&atomic_sim_lock); + __asm volatile("ldar %0, [%1]" : "=r" (ret): "r" (p):); + return ret; } -# define ATOMIC_STORE_N(p, v, o) fallback_atomic_store_n((void **)p, (void *)v) +/* For uint64_t, we should be fine, though */ +# define apple_atomic_load_n_uint64_t(p, o) __atomic_load_n(p, o) -static inline void fallback_atomic_store(void **p, void **v) -{ - void *ret; +# define ATOMIC_LOAD_N(t, p, o) apple_atomic_load_n_##t(p, o) +# else +# define ATOMIC_LOAD_N(t, p, o) __atomic_load_n(p, o) +# endif +# define ATOMIC_STORE_N(t, p, v, o) __atomic_store_n(p, v, o) +# define ATOMIC_STORE(t, p, v, o) __atomic_store(p, v, o) +# define ATOMIC_EXCHANGE_N(t, p, v, o) __atomic_exchange_n(p, v, o) +# define ATOMIC_ADD_FETCH(p, v, o) __atomic_add_fetch(p, v, o) +# define ATOMIC_FETCH_ADD(p, v, o) __atomic_fetch_add(p, v, o) +# define ATOMIC_SUB_FETCH(p, v, o) __atomic_sub_fetch(p, v, o) +# define ATOMIC_AND_FETCH(p, m, o) __atomic_and_fetch(p, m, o) +# define ATOMIC_OR_FETCH(p, m, o) __atomic_or_fetch(p, m, o) +# else +static pthread_mutex_t atomic_sim_lock = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&atomic_sim_lock); - ret = *p; - *p = *v; - v = ret; - pthread_mutex_unlock(&atomic_sim_lock); -} +# define IMPL_fallback_atomic_load_n(t) \ + static ossl_inline t fallback_atomic_load_n_##t(t *p) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_load_n(uint64_t) +IMPL_fallback_atomic_load_n(pvoid) + +# define ATOMIC_LOAD_N(t, p, o) fallback_atomic_load_n_##t(p) + +# define IMPL_fallback_atomic_store_n(t) \ + static ossl_inline t fallback_atomic_store_n_##t(t *p, t v) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + *p = v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_store_n(uint64_t) -# define ATOMIC_STORE(p, v, o) fallback_atomic_store((void **)p, (void **)v) +# define ATOMIC_STORE_N(t, p, v, o) fallback_atomic_store_n_##t(p, v) -static inline void *fallback_atomic_exchange_n(void **p, void *v) -{ - void *ret; +# define IMPL_fallback_atomic_store(t) \ + static ossl_inline void fallback_atomic_store_##t(t *p, t *v) \ + { \ + pthread_mutex_lock(&atomic_sim_lock); \ + *p = *v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + } +IMPL_fallback_atomic_store(uint64_t) +IMPL_fallback_atomic_store(pvoid) + +# define ATOMIC_STORE(t, p, v, o) fallback_atomic_store_##t(p, v) + +# define IMPL_fallback_atomic_exchange_n(t) \ + static ossl_inline t fallback_atomic_exchange_n_##t(t *p, t v) \ + { \ + t ret; \ + \ + pthread_mutex_lock(&atomic_sim_lock); \ + ret = *p; \ + *p = v; \ + pthread_mutex_unlock(&atomic_sim_lock); \ + return ret; \ + } +IMPL_fallback_atomic_exchange_n(uint64_t) +IMPL_fallback_atomic_exchange_n(prcu_cb_item) - pthread_mutex_lock(&atomic_sim_lock); - ret = *p; - *p = v; - pthread_mutex_unlock(&atomic_sim_lock); - return ret; -} +# define ATOMIC_EXCHANGE_N(t, p, v, o) fallback_atomic_exchange_n_##t(p, v) -#define ATOMIC_EXCHANGE_N(p, v, o) fallback_atomic_exchange_n((void **)p, (void *)v) +/* + * The fallbacks that follow don't need any per type implementation, as + * they are designed for uint64_t only. If there comes a time when multiple + * types need to be covered, it's relatively easy to refactor them the same + * way as the fallbacks above. + */ -static inline uint64_t fallback_atomic_add_fetch(uint64_t *p, uint64_t v) +static ossl_inline uint64_t fallback_atomic_add_fetch(uint64_t *p, uint64_t v) { uint64_t ret; @@ -120,9 +189,9 @@ static inline uint64_t fallback_atomic_add_fetch(uint64_t *p, uint64_t v) return ret; } -# define ATOMIC_ADD_FETCH(p, v, o) fallback_atomic_add_fetch(p, v) +# define ATOMIC_ADD_FETCH(p, v, o) fallback_atomic_add_fetch(p, v) -static inline uint64_t fallback_atomic_fetch_add(uint64_t *p, uint64_t v) +static ossl_inline uint64_t fallback_atomic_fetch_add(uint64_t *p, uint64_t v) { uint64_t ret; @@ -133,9 +202,9 @@ static inline uint64_t fallback_atomic_fetch_add(uint64_t *p, uint64_t v) return ret; } -# define ATOMIC_FETCH_ADD(p, v, o) fallback_atomic_fetch_add(p, v) +# define ATOMIC_FETCH_ADD(p, v, o) fallback_atomic_fetch_add(p, v) -static inline uint64_t fallback_atomic_sub_fetch(uint64_t *p, uint64_t v) +static ossl_inline uint64_t fallback_atomic_sub_fetch(uint64_t *p, uint64_t v) { uint64_t ret; @@ -146,9 +215,9 @@ static inline uint64_t fallback_atomic_sub_fetch(uint64_t *p, uint64_t v) return ret; } -# define ATOMIC_SUB_FETCH(p, v, o) fallback_atomic_sub_fetch(p, v) +# define ATOMIC_SUB_FETCH(p, v, o) fallback_atomic_sub_fetch(p, v) -static inline uint64_t fallback_atomic_and_fetch(uint64_t *p, uint64_t m) +static ossl_inline uint64_t fallback_atomic_and_fetch(uint64_t *p, uint64_t m) { uint64_t ret; @@ -159,9 +228,9 @@ static inline uint64_t fallback_atomic_and_fetch(uint64_t *p, uint64_t m) return ret; } -# define ATOMIC_AND_FETCH(p, v, o) fallback_atomic_and_fetch(p, v) +# define ATOMIC_AND_FETCH(p, v, o) fallback_atomic_and_fetch(p, v) -static inline uint64_t fallback_atomic_or_fetch(uint64_t *p, uint64_t m) +static ossl_inline uint64_t fallback_atomic_or_fetch(uint64_t *p, uint64_t m) { uint64_t ret; @@ -172,8 +241,8 @@ static inline uint64_t fallback_atomic_or_fetch(uint64_t *p, uint64_t m) return ret; } -# define ATOMIC_OR_FETCH(p, v, o) fallback_atomic_or_fetch(p, v) -#endif +# define ATOMIC_OR_FETCH(p, v, o) fallback_atomic_or_fetch(p, v) +# endif static CRYPTO_THREAD_LOCAL rcu_thr_key; @@ -210,7 +279,7 @@ struct thread_qp { CRYPTO_RCU_LOCK *lock; }; -#define MAX_QPS 10 +# define MAX_QPS 10 /* * This is the per thread tracking data * that is assigned to each thread participating @@ -305,7 +374,7 @@ static struct rcu_qp *get_hold_current_qp(struct rcu_lock_st *lock) * systems like x86, but is relevant on other arches * Note: This applies to the reload below as well */ - qp_idx = (uint64_t)ATOMIC_LOAD_N(&lock->reader_idx, __ATOMIC_ACQUIRE); + qp_idx = ATOMIC_LOAD_N(uint64_t, &lock->reader_idx, __ATOMIC_ACQUIRE); /* * Notes of use of __ATOMIC_RELEASE @@ -318,7 +387,7 @@ static struct rcu_qp *get_hold_current_qp(struct rcu_lock_st *lock) __ATOMIC_RELEASE); /* if the idx hasn't changed, we're good, else try again */ - if (qp_idx == (uint64_t)ATOMIC_LOAD_N(&lock->reader_idx, __ATOMIC_ACQUIRE)) + if (qp_idx == ATOMIC_LOAD_N(uint64_t, &lock->reader_idx, __ATOMIC_ACQUIRE)) break; /* @@ -456,7 +525,7 @@ static struct rcu_qp *update_qp(CRYPTO_RCU_LOCK *lock) * of __ATOMIC_ACQUIRE in get_hold_current_qp, as we want any publication * of this value to be seen on the read side immediately after it happens */ - ATOMIC_STORE_N(&lock->reader_idx, lock->current_alloc_idx, + ATOMIC_STORE_N(uint64_t, &lock->reader_idx, lock->current_alloc_idx, __ATOMIC_RELEASE); /* wake up any waiters */ @@ -503,7 +572,8 @@ void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) * __ATOMIC_ACQ_REL is used here to ensure that we get any prior published * writes before we read, and publish our write immediately */ - cb_items = ATOMIC_EXCHANGE_N(&lock->cb_items, NULL, __ATOMIC_ACQ_REL); + cb_items = ATOMIC_EXCHANGE_N(prcu_cb_item, &lock->cb_items, NULL, + __ATOMIC_ACQ_REL); qp = update_qp(lock); @@ -514,7 +584,7 @@ void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) * is visible prior to our read */ do { - count = (uint64_t)ATOMIC_LOAD_N(&qp->users, __ATOMIC_ACQUIRE); + count = ATOMIC_LOAD_N(uint64_t, &qp->users, __ATOMIC_ACQUIRE); } while (READER_COUNT(count) != 0); /* retire in order */ @@ -551,19 +621,20 @@ int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data) * list are visible to us prior to reading, and publish the new value * immediately */ - new->next = ATOMIC_EXCHANGE_N(&lock->cb_items, new, __ATOMIC_ACQ_REL); + new->next = ATOMIC_EXCHANGE_N(prcu_cb_item, &lock->cb_items, new, + __ATOMIC_ACQ_REL); return 1; } void *ossl_rcu_uptr_deref(void **p) { - return (void *)ATOMIC_LOAD_N(p, __ATOMIC_ACQUIRE); + return ATOMIC_LOAD_N(pvoid, p, __ATOMIC_ACQUIRE); } void ossl_rcu_assign_uptr(void **p, void **v) { - ATOMIC_STORE(p, v, __ATOMIC_RELEASE); + ATOMIC_STORE(pvoid, p, v, __ATOMIC_RELEASE); } static CRYPTO_ONCE rcu_init_once = CRYPTO_ONCE_STATIC_INIT; diff --git a/openssl/src/crypto/threads_win.c b/openssl/src/crypto/threads_win.c index 842886996..64354dc42 100644 --- a/openssl/src/crypto/threads_win.c +++ b/openssl/src/crypto/threads_win.c @@ -158,7 +158,6 @@ CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers) new->prior_signal = ossl_crypto_condvar_new(); new->alloc_lock = ossl_crypto_mutex_new(); new->prior_lock = ossl_crypto_mutex_new(); - new->write_lock = ossl_crypto_mutex_new(); new->qp_group = allocate_new_qp_group(new, num_writers + 1); if (new->qp_group == NULL || new->alloc_signal == NULL @@ -190,7 +189,7 @@ void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock) OPENSSL_free(lock); } -static inline struct rcu_qp *get_hold_current_qp(CRYPTO_RCU_LOCK *lock) +static ossl_inline struct rcu_qp *get_hold_current_qp(CRYPTO_RCU_LOCK *lock) { uint32_t qp_idx; diff --git a/openssl/src/crypto/x509/by_dir.c b/openssl/src/crypto/x509/by_dir.c index 1d401d042..bdcdc4555 100644 --- a/openssl/src/crypto/x509/by_dir.c +++ b/openssl/src/crypto/x509/by_dir.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -420,11 +420,11 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, } finish: /* If we changed anything, resort the objects for faster lookup */ - if (!sk_X509_OBJECT_is_sorted(xl->store_ctx->objs)) { - if (X509_STORE_lock(xl->store_ctx)) { + if (X509_STORE_lock(xl->store_ctx)) { + if (!sk_X509_OBJECT_is_sorted(xl->store_ctx->objs)) { sk_X509_OBJECT_sort(xl->store_ctx->objs); - X509_STORE_unlock(xl->store_ctx); } + X509_STORE_unlock(xl->store_ctx); } BUF_MEM_free(b); diff --git a/openssl/src/crypto/x509/v3_addr.c b/openssl/src/crypto/x509/v3_addr.c index a37d4f2b9..d0e5f9efe 100644 --- a/openssl/src/crypto/x509/v3_addr.c +++ b/openssl/src/crypto/x509/v3_addr.c @@ -407,11 +407,11 @@ static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, const int prefixlen, const int afilen) { int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; - IPAddressOrRange *aor = IPAddressOrRange_new(); + IPAddressOrRange *aor; if (prefixlen < 0 || prefixlen > (afilen * 8)) return 0; - if (aor == NULL) + if ((aor = IPAddressOrRange_new()) == NULL) return 0; aor->type = IPAddressOrRange_addressPrefix; if (aor->u.addressPrefix == NULL && diff --git a/openssl/src/providers/fips/fipsprov.c b/openssl/src/providers/fips/fipsprov.c index 7ec409710..86c18de28 100644 --- a/openssl/src/providers/fips/fipsprov.c +++ b/openssl/src/providers/fips/fipsprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -695,6 +695,8 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, } } + OPENSSL_cpuid_setup(); + /* Create a context. */ if ((*provctx = ossl_prov_ctx_new()) == NULL || (libctx = OSSL_LIB_CTX_new()) == NULL) diff --git a/openssl/src/providers/fips/self_test_data.inc b/openssl/src/providers/fips/self_test_data.inc index 60efa3d35..d2a4778e9 100644 --- a/openssl/src/providers/fips/self_test_data.inc +++ b/openssl/src/providers/fips/self_test_data.inc @@ -1433,14 +1433,14 @@ static const unsigned char ecd_prime_pub[] = { 0x82 }; static const unsigned char ecdsa_prime_expected_sig[] = { - 0x30, 0x3d, 0x02, 0x1d, 0x00, 0xd2, 0x4a, 0xc9, - 0x4f, 0xaf, 0xdb, 0x62, 0xfc, 0x41, 0x4a, 0x81, - 0x2a, 0x9f, 0xcf, 0xa3, 0xda, 0xfe, 0xa3, 0x49, - 0xbd, 0xea, 0xbf, 0x2a, 0x51, 0xb4, 0x0b, 0xc3, - 0xbc, 0x02, 0x1c, 0x7f, 0x30, 0xb7, 0xad, 0xab, - 0x09, 0x6e, 0x3c, 0xad, 0x7f, 0xf9, 0x5e, 0xaa, - 0xe2, 0x38, 0xe5, 0x29, 0x16, 0xc4, 0xc8, 0x77, - 0xa1, 0xf8, 0x60, 0x77, 0x39, 0x7a, 0xec + 0x30, 0x3d, 0x02, 0x1c, 0x48, 0x4f, 0x3c, 0x97, + 0x5b, 0xfa, 0x40, 0x6c, 0xdb, 0xd6, 0x70, 0xb5, + 0xbd, 0x2d, 0xd0, 0xc6, 0x22, 0x93, 0x5a, 0x88, + 0x56, 0xd0, 0xaf, 0x0a, 0x94, 0x92, 0x20, 0x01, + 0x02, 0x1d, 0x00, 0xa4, 0x80, 0xe0, 0x47, 0x88, + 0x8a, 0xef, 0x2a, 0x47, 0x9d, 0x81, 0x9a, 0xbf, + 0x45, 0xc3, 0x6f, 0x9e, 0x2e, 0xc1, 0x44, 0x9f, + 0xfd, 0x79, 0xdb, 0x90, 0x3e, 0xb9, 0xb2 }; static const ST_KAT_PARAM ecdsa_prime_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name), @@ -1468,15 +1468,15 @@ static const unsigned char ecd_bin_pub[] = { 0x99, 0xb6, 0x8f, 0x80, 0x46 }; static const unsigned char ecdsa_bin_expected_sig[] = { - 0x30, 0x3f, 0x02, 0x1d, 0x08, 0x11, 0x7c, 0xcd, - 0xf4, 0xa1, 0x31, 0x9a, 0xc1, 0xfd, 0x50, 0x0e, - 0x5d, 0xa9, 0xb6, 0x0e, 0x95, 0x49, 0xe1, 0xbd, - 0x44, 0xe3, 0x5b, 0xa9, 0x35, 0x94, 0xa5, 0x2f, - 0xae, 0x02, 0x1e, 0x00, 0xe3, 0xba, 0xb8, 0x8f, - 0x4b, 0x05, 0x76, 0x88, 0x1e, 0x49, 0xd6, 0x62, - 0x76, 0xd3, 0x22, 0x4d, 0xa3, 0x7b, 0x04, 0xcc, - 0xfa, 0x7b, 0x41, 0x9b, 0x8c, 0xaf, 0x1b, 0x6d, - 0xbd + 0x30, 0x3f, 0x02, 0x1d, 0x58, 0xe9, 0xd0, 0x84, + 0x5c, 0xad, 0x29, 0x03, 0xf6, 0xa6, 0xbc, 0xe0, + 0x24, 0x6d, 0x9e, 0x79, 0x5d, 0x1e, 0xe8, 0x5a, + 0xc3, 0x31, 0x0a, 0xa9, 0xfb, 0xe3, 0x99, 0x54, + 0x11, 0x02, 0x1e, 0x00, 0xa3, 0x44, 0x28, 0xa3, + 0x70, 0x97, 0x98, 0x17, 0xd7, 0xa6, 0xad, 0x91, + 0xaf, 0x41, 0x69, 0xb6, 0x06, 0x99, 0x39, 0xc7, + 0x63, 0xa4, 0x6a, 0x81, 0xe4, 0x9a, 0x9d, 0x15, + 0x8b }; static const ST_KAT_PARAM ecdsa_bin_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_bin_curve_name), @@ -1604,14 +1604,14 @@ static const unsigned char dsa_priv[] = { 0x40, 0x7e, 0x5c, 0xb7 }; static const unsigned char dsa_expected_sig[] = { - 0x30, 0x3c, 0x02, 0x1c, 0x70, 0xa4, 0x77, 0xb6, - 0x02, 0xb5, 0xd3, 0x07, 0x21, 0x22, 0x2d, 0xe3, - 0x4f, 0x7d, 0xfd, 0xfd, 0x6b, 0x4f, 0x03, 0x27, - 0x4c, 0xd3, 0xb2, 0x8c, 0x7c, 0xc5, 0xc4, 0xdf, - 0x02, 0x1c, 0x11, 0x52, 0x65, 0x16, 0x9f, 0xbd, - 0x4c, 0xe5, 0xab, 0xb2, 0x01, 0xd0, 0x7a, 0x30, - 0x5c, 0xc5, 0xba, 0x22, 0xc6, 0x62, 0x7e, 0xa6, - 0x7d, 0x98, 0x96, 0xc9, 0x77, 0x00 + 0x30, 0x3c, 0x02, 0x1c, 0x69, 0xc6, 0xd6, 0x9e, + 0x2b, 0x91, 0xea, 0x72, 0xb3, 0x8b, 0x7c, 0x57, + 0x48, 0x75, 0xb7, 0x65, 0xc0, 0xb4, 0xf7, 0xbb, + 0x08, 0xa4, 0x95, 0x77, 0xfc, 0xa7, 0xed, 0x31, + 0x02, 0x1c, 0x4c, 0x2c, 0xff, 0xc6, 0x55, 0xeb, + 0x8f, 0xa7, 0x4f, 0x27, 0xd8, 0xec, 0xfd, 0x62, + 0x73, 0xf2, 0xd1, 0x55, 0xa5, 0xf0, 0x41, 0x68, + 0x34, 0x8d, 0x9e, 0x88, 0x08, 0x06 }; static const ST_KAT_PARAM dsa_key[] = { diff --git a/openssl/src/providers/implementations/exchange/kdf_exch.c b/openssl/src/providers/implementations/exchange/kdf_exch.c index 4aaf67339..340a2663c 100644 --- a/openssl/src/providers/implementations/exchange/kdf_exch.c +++ b/openssl/src/providers/implementations/exchange/kdf_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,9 +28,13 @@ static OSSL_FUNC_keyexch_derive_fn kdf_derive; static OSSL_FUNC_keyexch_freectx_fn kdf_freectx; static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx; static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params; +static OSSL_FUNC_keyexch_get_ctx_params_fn kdf_get_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params; +static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params; +static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params; +static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_scrypt_gettable_ctx_params; typedef struct { void *provctx; @@ -169,6 +173,13 @@ static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[]) return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params); } +static int kdf_get_ctx_params(void *vpkdfctx, OSSL_PARAM params[]) +{ + PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + + return EVP_KDF_CTX_get_params(pkdfctx->kdfctx, params); +} + static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx, void *provctx, const char *kdfname) @@ -197,6 +208,34 @@ KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF") KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF") KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT") +static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx, + void *provctx, + const char *kdfname) +{ + EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, + NULL); + const OSSL_PARAM *params; + + if (kdf == NULL) + return NULL; + + params = EVP_KDF_gettable_ctx_params(kdf); + EVP_KDF_free(kdf); + + return params; +} + +#define KDF_GETTABLE_CTX_PARAMS(funcname, kdfname) \ + static const OSSL_PARAM *kdf_##funcname##_gettable_ctx_params(void *vpkdfctx, \ + void *provctx) \ + { \ + return kdf_gettable_ctx_params(vpkdfctx, provctx, kdfname); \ + } + +KDF_GETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF") +KDF_GETTABLE_CTX_PARAMS(hkdf, "HKDF") +KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT") + #define KDF_KEYEXCH_FUNCTIONS(funcname) \ const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \ { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \ @@ -205,8 +244,11 @@ KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT") { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \ { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \ { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))kdf_get_ctx_params }, \ { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ (void (*)(void))kdf_##funcname##_settable_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \ + (void (*)(void))kdf_##funcname##_gettable_ctx_params }, \ OSSL_DISPATCH_END \ }; diff --git a/openssl/src/providers/implementations/kdfs/hkdf.c b/openssl/src/providers/implementations/kdfs/hkdf.c index a83e29822..4a24013bf 100644 --- a/openssl/src/providers/implementations/kdfs/hkdf.c +++ b/openssl/src/providers/implementations/kdfs/hkdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -316,6 +316,13 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return 0; return OSSL_PARAM_set_size_t(p, sz); } + if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) { + if (ctx->info == NULL || ctx->info_len == 0) { + p->return_size = 0; + return 1; + } + return OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len); + } return -2; } @@ -324,6 +331,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx, { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), OSSL_PARAM_END }; return known_gettable_ctx_params; diff --git a/openssl/src/ssl/quic/quic_impl.c b/openssl/src/ssl/quic/quic_impl.c index c4c332b20..c77230a19 100644 --- a/openssl/src/ssl/quic/quic_impl.c +++ b/openssl/src/ssl/quic/quic_impl.c @@ -25,7 +25,7 @@ static void aon_write_finish(QUIC_XSO *xso); static int create_channel(QUIC_CONNECTION *qc); static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs); static int qc_try_create_default_xso_for_write(QCTX *ctx); -static int qc_wait_for_default_xso_for_read(QCTX *ctx); +static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek); static void quic_lock(QUIC_CONNECTION *qc); static void quic_unlock(QUIC_CONNECTION *qc); static void quic_lock_for_io(QCTX *ctx); @@ -268,7 +268,7 @@ static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_ini if (!qc_try_create_default_xso_for_write(ctx)) goto err; } else { - if (!qc_wait_for_default_xso_for_read(ctx)) + if (!qc_wait_for_default_xso_for_read(ctx, /*peek=*/0)) goto err; } @@ -1851,7 +1851,7 @@ static int quic_wait_for_stream(void *arg) } QUIC_NEEDS_LOCK -static int qc_wait_for_default_xso_for_read(QCTX *ctx) +static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek) { /* Called on a QCSO and we don't currently have a default stream. */ uint64_t expect_id; @@ -1893,6 +1893,9 @@ static int qc_wait_for_default_xso_for_read(QCTX *ctx) } if (qs == NULL) { + if (peek) + return 0; + if (!qc_blocking_mode(qc)) /* Non-blocking mode, so just bail immediately. */ return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); @@ -2469,6 +2472,11 @@ static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len, quic_post_write(xso, *written > 0, *written == len, flags, qctx_should_autotick(ctx)); + + if (*written == 0) + /* SSL_write_ex returns 0 if it didn't read anything. */ + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); + return 1; } @@ -2524,10 +2532,19 @@ int ossl_quic_write_flags(SSL *s, const void *buf, size_t len, *written = 0; - if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx)) - return 0; + if (len == 0) { + /* Do not autocreate default XSO for zero-length writes. */ + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock_for_io(&ctx); + } else { + if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx)) + return 0; + } - partial_write = ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0); + partial_write = ((ctx.xso != NULL) + ? ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0) : 0); if ((flags & ~SSL_WRITE_FLAG_CONCLUDE) != 0) { ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_UNSUPPORTED_WRITE_FLAG, NULL); @@ -2549,7 +2566,7 @@ int ossl_quic_write_flags(SSL *s, const void *buf, size_t len, } /* Ensure correct stream state, stream send part not concluded, etc. */ - if (!quic_validate_for_write(ctx.xso, &err)) { + if (len > 0 && !quic_validate_for_write(ctx.xso, &err)) { ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); goto out; } @@ -2753,7 +2770,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek * Wait until we get a stream initiated by the peer (blocking mode) or * fail if we don't have one yet (non-blocking mode). */ - if (!qc_wait_for_default_xso_for_read(&ctx)) { + if (!qc_wait_for_default_xso_for_read(&ctx, /*peek=*/0)) { ret = 0; /* error already raised here */ goto out; } @@ -2840,8 +2857,6 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel) { QCTX ctx; size_t avail = 0; - int fin = 0; - if (!expect_quic(s, &ctx)) return 0; @@ -2849,21 +2864,28 @@ static size_t ossl_quic_pending_int(const SSL *s, int check_channel) quic_lock(ctx.qc); if (ctx.xso == NULL) { - QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL); - goto out; + /* No XSO yet, but there might be a default XSO eligible to be created. */ + if (qc_wait_for_default_xso_for_read(&ctx, /*peek=*/1)) { + ctx.xso = ctx.qc->default_xso; + } else { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL); + goto out; + } } - if (ctx.xso->stream == NULL - || !ossl_quic_stream_has_recv_buffer(ctx.xso->stream)) { + if (ctx.xso->stream == NULL) { QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); goto out; } - if (!ossl_quic_rstream_available(ctx.xso->stream->rstream, &avail, &fin)) - avail = 0; - - if (avail == 0 && check_channel && ossl_quic_channel_has_pending(ctx.qc->ch)) - avail = 1; + if (check_channel) + avail = ossl_quic_stream_recv_pending(ctx.xso->stream, + /*include_fin=*/1) + || ossl_quic_channel_has_pending(ctx.qc->ch) + || ossl_quic_channel_is_term_any(ctx.qc->ch); + else + avail = ossl_quic_stream_recv_pending(ctx.xso->stream, + /*include_fin=*/0); out: quic_unlock(ctx.qc); diff --git a/openssl/src/ssl/quic/quic_txp.c b/openssl/src/ssl/quic/quic_txp.c index eeec1486a..2532d1edc 100644 --- a/openssl/src/ssl/quic/quic_txp.c +++ b/openssl/src/ssl/quic/quic_txp.c @@ -1600,10 +1600,21 @@ static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, } } +static int txp_need_ping(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space, + const struct archetype_data *adata) +{ + return adata->allow_ping + && (adata->require_ack_eliciting + || (txp->force_ack_eliciting & (1UL << pn_space)) != 0); +} + static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level, uint32_t archetype, size_t running_total) { + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + if (!txp_determine_geometry(txp, archetype, enc_level, running_total, &pkt->phdr, &pkt->geom)) return 0; @@ -1614,7 +1625,7 @@ static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, */ if (!tx_helper_init(&pkt->h, txp, enc_level, pkt->geom.cmppl, - pkt->geom.adata.require_ack_eliciting ? 1 : 0)) + txp_need_ping(txp, pn_space, &pkt->geom.adata) ? 1 : 0)) return 0; pkt->h_valid = 1; @@ -2782,11 +2793,10 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, /* PING */ tx_helper_unrestrict(h); - if ((a.require_ack_eliciting - || (txp->force_ack_eliciting & (1UL << pn_space)) != 0) - && !have_ack_eliciting && a.allow_ping) { + if (!have_ack_eliciting && txp_need_ping(txp, pn_space, &a)) { WPACKET *wpkt; + assert(h->reserve > 0); wpkt = tx_helper_begin(h); if (wpkt == NULL) goto fatal_err; diff --git a/openssl/src/ssl/record/methods/tls_common.c b/openssl/src/ssl/record/methods/tls_common.c index b7481c071..6cb8e8870 100644 --- a/openssl/src/ssl/record/methods/tls_common.c +++ b/openssl/src/ssl/record/methods/tls_common.c @@ -283,6 +283,8 @@ static int tls_release_read_buffer(OSSL_RECORD_LAYER *rl) OPENSSL_cleanse(b->buf, b->len); OPENSSL_free(b->buf); b->buf = NULL; + rl->packet = NULL; + rl->packet_length = 0; return 1; } @@ -325,6 +327,12 @@ int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, /* ... now we can act as if 'extend' was set */ } + if (!ossl_assert(rl->packet != NULL)) { + /* does not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + len = rl->packet_length; pkt = rb->buf + align; /* @@ -2124,7 +2132,10 @@ int tls_free_buffers(OSSL_RECORD_LAYER *rl) /* Read direction */ /* If we have pending data to be read then fail */ - if (rl->curr_rec < rl->num_recs || TLS_BUFFER_get_left(&rl->rbuf) != 0) + if (rl->curr_rec < rl->num_recs + || rl->curr_rec != rl->num_released + || TLS_BUFFER_get_left(&rl->rbuf) != 0 + || rl->rstate == SSL_ST_READ_BODY) return 0; return tls_release_read_buffer(rl); diff --git a/openssl/src/ssl/ssl_err.c b/openssl/src/ssl/ssl_err.c index a1da9fde3..f5fb4107f 100644 --- a/openssl/src/ssl/ssl_err.c +++ b/openssl/src/ssl/ssl_err.c @@ -498,6 +498,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "tlsv1 alert insufficient security"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL), + "tlsv1 alert no application protocol"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), @@ -506,6 +508,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "tlsv1 alert record overflow"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY), + "tlsv1 alert unknown psk identity"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_USER_CANCELLED), "tlsv1 alert user cancelled"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), diff --git a/openssl/src/ssl/ssl_sess.c b/openssl/src/ssl/ssl_sess.c index eaa9595f8..3857e027e 100644 --- a/openssl/src/ssl/ssl_sess.c +++ b/openssl/src/ssl/ssl_sess.c @@ -907,8 +907,9 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, return 0; } s->session_id_length = sid_len; - if (sid != s->session_id) + if (sid != s->session_id && sid_len > 0) memcpy(s->session_id, sid, sid_len); + return 1; } diff --git a/openssl/src/ssl/statem/statem_srvr.c b/openssl/src/ssl/statem/statem_srvr.c index 47855da5b..5ff479a2e 100644 --- a/openssl/src/ssl/statem/statem_srvr.c +++ b/openssl/src/ssl/statem/statem_srvr.c @@ -1959,6 +1959,11 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } } + if (!s->hit && !tls1_set_server_sigalgs(s)) { + /* SSLfatal() already called */ + goto err; + } + if (!s->hit && s->version >= TLS1_VERSION && !SSL_CONNECTION_IS_TLS13(s) @@ -2110,10 +2115,6 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) #else s->session->compress_meth = (comp == NULL) ? 0 : comp->id; #endif - if (!tls1_set_server_sigalgs(s)) { - /* SSLfatal() already called */ - goto err; - } } sk_SSL_CIPHER_free(ciphers); @@ -3229,7 +3230,7 @@ static int tls_process_cke_gost(SSL_CONNECTION *s, PACKET *pkt) } if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + goto err; } /* * If client certificate is present and is of the same type, maybe