Skip to content

Commit cc6154c

Browse files
authored
Merge branch 'main' into secmem
2 parents a39f620 + e91524c commit cc6154c

15 files changed

+288
-7
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ if(BUILD_TESTING)
894894
set(MEM_SET_TEST_EXEC mem_set_test.so)
895895
set(INTEGRATION_TEST_EXEC integration_test.so)
896896
set(DYNAMIC_LOADING_TEST_EXEC dynamic_loading_test.so)
897+
set(RWLOCK_STATIC_INIT_TEST_EXEC rwlock_static_init.so)
897898
else()
898899
set(CRYPTO_TEST_EXEC crypto_test)
899900
set(RANDOM_TEST_EXEC urandom_test)
@@ -902,6 +903,7 @@ if(BUILD_TESTING)
902903
set(MEM_SET_TEST_EXEC mem_set_test)
903904
set(INTEGRATION_TEST_EXEC integration_test)
904905
set(DYNAMIC_LOADING_TEST_EXEC dynamic_loading_test)
906+
set(RWLOCK_STATIC_INIT_TEST_EXEC rwlock_static_init)
905907
endif()
906908

907909
add_subdirectory(util/fipstools/acvp/modulewrapper)

crypto/CMakeLists.txt

+14
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,20 @@ if(BUILD_TESTING)
806806
endif()
807807

808808
add_dependencies(all_tests ${DYNAMIC_LOADING_TEST_EXEC})
809+
810+
message(STATUS "Generating test executable ${RWLOCK_STATIC_INIT_TEST_EXEC}.")
811+
add_executable(${RWLOCK_STATIC_INIT_TEST_EXEC} rwlock_static_init.cc)
812+
add_dependencies(${RWLOCK_STATIC_INIT_TEST_EXEC} crypto)
813+
814+
target_link_libraries(${RWLOCK_STATIC_INIT_TEST_EXEC} crypto)
815+
target_include_directories(${RWLOCK_STATIC_INIT_TEST_EXEC} BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include)
816+
if(MSVC)
817+
target_link_libraries(${RWLOCK_STATIC_INIT_TEST_EXEC} ws2_32)
818+
else()
819+
target_compile_options(${RWLOCK_STATIC_INIT_TEST_EXEC} PUBLIC -Wno-deprecated-declarations)
820+
endif()
821+
add_dependencies(all_tests ${RWLOCK_STATIC_INIT_TEST_EXEC})
822+
809823
endif()
810824

811825
install(TARGETS crypto

crypto/endian_test.cc

+14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
#include "openssl/bn.h"
55
#include "test/test_util.h"
66

7+
TEST(EndianTest, u16Operations) {
8+
uint8_t buffer[2];
9+
uint16_t val = 0x1234;
10+
uint8_t expected_be[2] = {0x12, 0x34};
11+
uint8_t expected_le[2] = {0x34, 0x12};
12+
13+
CRYPTO_store_u16_le(buffer, val);
14+
EXPECT_EQ(Bytes(expected_le), Bytes(buffer));
15+
EXPECT_EQ(val, CRYPTO_load_u16_le(buffer));
16+
17+
CRYPTO_store_u16_be(buffer, val);
18+
EXPECT_EQ(Bytes(expected_be), Bytes(buffer));
19+
EXPECT_EQ(val, CRYPTO_load_u16_be(buffer));
20+
}
721

822
TEST(EndianTest, u32Operations) {
923
uint8_t buffer[4];

crypto/fipsmodule/service_indicator/service_indicator_test.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -4280,7 +4280,7 @@ TEST(ServiceIndicatorTest, DRBG) {
42804280
// Since this is running in FIPS mode it should end in FIPS
42814281
// Update this when the AWS-LC version number is modified
42824282
TEST(ServiceIndicatorTest, AWSLCVersionString) {
4283-
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.24.0");
4283+
ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.24.1");
42844284
}
42854285

42864286
#else
@@ -4323,6 +4323,6 @@ TEST(ServiceIndicatorTest, BasicTest) {
43234323
// Since this is not running in FIPS mode it shouldn't end in FIPS
43244324
// Update this when the AWS-LC version number is modified
43254325
TEST(ServiceIndicatorTest, AWSLCVersionString) {
4326-
ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.24.0");
4326+
ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.24.1");
43274327
}
43284328
#endif // AWSLC_FIPS

crypto/internal.h

+34
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,40 @@ static inline void *OPENSSL_memset(void *dst, int c, size_t n) {
894894
// endianness. They use |memcpy|, and so avoid alignment or strict aliasing
895895
// requirements on the input and output pointers.
896896

897+
static inline uint16_t CRYPTO_load_u16_le(const void *in) {
898+
uint16_t v;
899+
OPENSSL_memcpy(&v, in, sizeof(v));
900+
#if defined(OPENSSL_BIG_ENDIAN)
901+
return CRYPTO_bswap2(v);
902+
#else
903+
return v;
904+
#endif
905+
}
906+
907+
static inline void CRYPTO_store_u16_le(void *out, uint16_t v) {
908+
#if defined(OPENSSL_BIG_ENDIAN)
909+
v = CRYPTO_bswap2(v);
910+
#endif
911+
OPENSSL_memcpy(out, &v, sizeof(v));
912+
}
913+
914+
static inline uint16_t CRYPTO_load_u16_be(const void *in) {
915+
uint16_t v;
916+
OPENSSL_memcpy(&v, in, sizeof(v));
917+
#if defined(OPENSSL_BIG_ENDIAN)
918+
return v;
919+
#else
920+
return CRYPTO_bswap2(v);
921+
#endif
922+
}
923+
924+
static inline void CRYPTO_store_u16_be(void *out, uint16_t v) {
925+
#if !defined(OPENSSL_BIG_ENDIAN)
926+
v = CRYPTO_bswap2(v);
927+
#endif
928+
OPENSSL_memcpy(out, &v, sizeof(v));
929+
}
930+
897931
static inline uint32_t CRYPTO_load_u32_le(const void *in) {
898932
uint32_t v;
899933
OPENSSL_memcpy(&v, in, sizeof(v));

crypto/rand_extra/forkunsafe.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
#include "../fipsmodule/rand/internal.h"
2020

2121

22+
#if !defined(OPENSSL_WINDOWS)
2223
// g_buffering_enabled is true if fork-unsafe buffering has been enabled.
2324
static int g_buffering_enabled = 0;
2425

2526
// g_lock protects |g_buffering_enabled|.
2627
static struct CRYPTO_STATIC_MUTEX g_lock = CRYPTO_STATIC_MUTEX_INIT;
2728

28-
#if !defined(OPENSSL_WINDOWS)
2929
void RAND_enable_fork_unsafe_buffering(int fd) {
3030
// We no longer support setting the file-descriptor with this function.
3131
if (fd != -1) {
@@ -36,11 +36,15 @@ void RAND_enable_fork_unsafe_buffering(int fd) {
3636
g_buffering_enabled = 1;
3737
CRYPTO_STATIC_MUTEX_unlock_write(&g_lock);
3838
}
39-
#endif
4039

4140
int rand_fork_unsafe_buffering_enabled(void) {
4241
CRYPTO_STATIC_MUTEX_lock_read(&g_lock);
4342
const int ret = g_buffering_enabled;
4443
CRYPTO_STATIC_MUTEX_unlock_read(&g_lock);
4544
return ret;
4645
}
46+
#else
47+
int rand_fork_unsafe_buffering_enabled(void) {
48+
return 0;
49+
}
50+
#endif

crypto/rwlock_static_init.cc

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR ISC
3+
4+
// This test attempts to setup a potential race condition that can cause the
5+
// first use of an rwlock to fail when initialized using
6+
// PTHREAD_RWLOCK_INITIALIZER.
7+
// See: https://sourceforge.net/p/mingw-w64/bugs/883/
8+
9+
#include <openssl/rand.h>
10+
11+
#include <cstdint>
12+
#include <iostream>
13+
#include <thread>
14+
#include <cassert>
15+
#include <cstdlib>
16+
17+
static void thread_task_rand(bool *myFlag) {
18+
uint8_t buf[16];
19+
if(1 == RAND_bytes(buf, sizeof(buf))) {
20+
*myFlag = true;
21+
}
22+
}
23+
24+
int main(int _argc, char** _argv) {
25+
constexpr size_t kNumThreads = 16;
26+
bool myFlags[kNumThreads] = {};
27+
std::thread myThreads[kNumThreads];
28+
29+
for (size_t i = 0; i < kNumThreads; i++) {
30+
bool* myFlag = &myFlags[i];
31+
myThreads[i] = std::thread(thread_task_rand, myFlag);
32+
}
33+
for (size_t i = 0; i < kNumThreads; i++) {
34+
myThreads[i].join();
35+
if(!myFlags[i]) {
36+
std::cerr << "Thread " << i << " failed." << std::endl;
37+
exit(1);
38+
return 1;
39+
}
40+
}
41+
std::cout << "PASS" << std::endl;
42+
return 0;
43+
}

crypto/thread_pthread.c

+32-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
// Ensure we can't call OPENSSL_malloc circularly.
1616
#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC
17+
#include <errno.h>
18+
1719
#include "internal.h"
1820

1921
#if defined(OPENSSL_PTHREADS)
@@ -64,14 +66,42 @@ void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
6466
pthread_rwlock_destroy((pthread_rwlock_t *) lock);
6567
}
6668

69+
// Some MinGW pthreads implementations might fail on first use of
70+
// locks initialized using PTHREAD_RWLOCK_INITIALIZER.
71+
// See: https://sourceforge.net/p/mingw-w64/bugs/883/
72+
typedef int (*pthread_rwlock_func_ptr)(pthread_rwlock_t *);
73+
static int rwlock_EINVAL_fallback_retry(const pthread_rwlock_func_ptr func_ptr, pthread_rwlock_t* lock) {
74+
int result = EINVAL;
75+
#ifdef __MINGW32__
76+
const int MAX_ATTEMPTS = 10;
77+
int attempt_num = 0;
78+
do {
79+
sched_yield();
80+
attempt_num += 1;
81+
result = func_ptr(lock);
82+
} while(result == EINVAL && attempt_num < MAX_ATTEMPTS);
83+
#endif
84+
return result;
85+
}
86+
6787
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
68-
if (pthread_rwlock_rdlock(&lock->lock) != 0) {
88+
const int result = pthread_rwlock_rdlock(&lock->lock);
89+
if (result != 0) {
90+
if (result == EINVAL &&
91+
0 == rwlock_EINVAL_fallback_retry(pthread_rwlock_rdlock, &lock->lock)) {
92+
return;
93+
}
6994
abort();
7095
}
7196
}
7297

7398
void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {
74-
if (pthread_rwlock_wrlock(&lock->lock) != 0) {
99+
const int result = pthread_rwlock_wrlock(&lock->lock);
100+
if (result != 0) {
101+
if (result == EINVAL &&
102+
0 == rwlock_EINVAL_fallback_retry(pthread_rwlock_wrlock, &lock->lock)) {
103+
return;
104+
}
75105
abort();
76106
}
77107
}

include/openssl/base.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ extern "C" {
122122
// ServiceIndicatorTest.AWSLCVersionString
123123
// Note: there are two versions of this test. Only one test is compiled
124124
// depending on FIPS mode.
125-
#define AWSLC_VERSION_NUMBER_STRING "1.24.0"
125+
#define AWSLC_VERSION_NUMBER_STRING "1.24.1"
126126

127127
#if defined(BORINGSSL_SHARED_LIBRARY)
128128

include/openssl/ssl.h

+11
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,12 @@ DEFINE_CONST_STACK_OF(SSL_CIPHER)
14691469
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4.
14701470
OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
14711471

1472+
// SSL_CIPHER_find returns a SSL_CIPHER structure which has the cipher ID stored in ptr or
1473+
// NULL if unknown. The ptr parameter is a two element array of char, which stores the
1474+
// two-byte TLS cipher ID (as allocated by IANA) in network byte order. SSL_CIPHER_find re-casts
1475+
// |ptr| to uint16_t and calls |SSL_get_cipher_by_value| to get the SSL_CIPHER structure.
1476+
OPENSSL_EXPORT const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
1477+
14721478
// SSL_CIPHER_get_id returns |cipher|'s non-IANA id. This is not its
14731479
// IANA-assigned number, which is called the "value" here, although it may be
14741480
// cast to a |uint16_t| to get it.
@@ -1850,6 +1856,11 @@ OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
18501856
// performed a new handshake.
18511857
OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *ssl);
18521858

1859+
// SSL_client_hello_get0_ciphers provides access to the client ciphers field from the
1860+
// Client Hello, optionally writing the result to an out pointer. It returns the field
1861+
// length if successful, or 0 if |ssl| is a client or the handshake hasn't occurred yet.
1862+
OPENSSL_EXPORT size_t SSL_client_hello_get0_ciphers(SSL *ssl, const unsigned char **out);
1863+
18531864
// SSL_session_reused returns one if |ssl| performed an abbreviated handshake
18541865
// and zero otherwise.
18551866
//

ssl/internal.h

+5
Original file line numberDiff line numberDiff line change
@@ -4068,6 +4068,11 @@ struct ssl_st {
40684068
// serialized and is only populated if used in a server context.
40694069
bssl::UniquePtr<STACK_OF(SSL_CIPHER)> client_cipher_suites;
40704070

4071+
// client_cipher_suites_arr is initialized when |SSL_client_hello_get0_ciphers|
4072+
// is called with a valid |out| param. It holds the cipher suites offered by the
4073+
// client from |client_cipher_suites| in an array.
4074+
bssl::Array<uint16_t> client_cipher_suites_arr;
4075+
40714076
void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;
40724077

40734078
bssl::UniquePtr<SSL_CTX> ctx;

ssl/ssl_cipher.cc

+9
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,15 @@ const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
14701470
ssl_cipher_id_cmp));
14711471
}
14721472

1473+
const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) {
1474+
if (ssl != nullptr && ptr != nullptr) {
1475+
uint16_t cipher_id = CRYPTO_load_u16_be(ptr);
1476+
return SSL_get_cipher_by_value(cipher_id);
1477+
}
1478+
1479+
return NULL;
1480+
}
1481+
14731482
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
14741483

14751484
uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *cipher) {

ssl/ssl_lib.cc

+33
Original file line numberDiff line numberDiff line change
@@ -3096,6 +3096,7 @@ int SSL_clear(SSL *ssl) {
30963096
}
30973097

30983098
ssl->client_cipher_suites.reset();
3099+
ssl->client_cipher_suites_arr.Reset();
30993100

31003101
// In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously
31013102
// established session to be offered the next time around. wpa_supplicant
@@ -3319,3 +3320,35 @@ int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) {
33193320
int SSL_set1_curves_list(SSL *ssl, const char *curves) {
33203321
return SSL_set1_groups_list(ssl, curves);
33213322
}
3323+
3324+
size_t SSL_client_hello_get0_ciphers(SSL *ssl, const unsigned char **out) {
3325+
STACK_OF(SSL_CIPHER) *client_cipher_suites = SSL_get_client_ciphers(ssl);
3326+
if (client_cipher_suites == nullptr) {
3327+
return 0;
3328+
}
3329+
3330+
size_t num_ciphers = sk_SSL_CIPHER_num(client_cipher_suites);
3331+
if (out != nullptr) {
3332+
// Hasn't been called before
3333+
if(ssl->client_cipher_suites_arr.empty()) {
3334+
if (!ssl->client_cipher_suites_arr.Init(num_ciphers)) {
3335+
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
3336+
return 0;
3337+
}
3338+
3339+
// Construct list of cipherIDs
3340+
for (size_t i = 0; i < num_ciphers; i++) {
3341+
const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(client_cipher_suites, i);
3342+
uint16_t iana_id = SSL_CIPHER_get_protocol_id(cipher);
3343+
3344+
CRYPTO_store_u16_be(&ssl->client_cipher_suites_arr[i], iana_id);
3345+
}
3346+
}
3347+
3348+
assert(ssl->client_cipher_suites_arr.size() == num_ciphers);
3349+
*out = reinterpret_cast<unsigned char*>(ssl->client_cipher_suites_arr.data());
3350+
}
3351+
3352+
// Return the size
3353+
return num_ciphers;
3354+
}

0 commit comments

Comments
 (0)