diff --git a/PrivacyInfo.xcprivacy b/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..dc3a906b2f --- /dev/null +++ b/PrivacyInfo.xcprivacy @@ -0,0 +1,21 @@ + + + + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/crypto/bytestring/unicode.c b/crypto/bytestring/unicode.c index 6f9467f9c3..244839ea9e 100644 --- a/crypto/bytestring/unicode.c +++ b/crypto/bytestring/unicode.c @@ -18,11 +18,12 @@ static int is_valid_code_point(uint32_t v) { - // References in the following are to Unicode 9.0.0. + // References in the following are to Unicode 15.0.0. if (// The Unicode space runs from zero to 0x10ffff (3.4 D9). v > 0x10ffff || // Values 0x...fffe, 0x...ffff, and 0xfdd0-0xfdef are permanently reserved - // (3.4 D14) + // as noncharacters (3.4 D14). See also 23.7. As our APIs are intended for + // "open interchange", such as ASN.1, we reject them. (v & 0xfffe) == 0xfffe || (v >= 0xfdd0 && v <= 0xfdef) || // Surrogate code points are invalid (3.2 C1). diff --git a/crypto/cipher_extra/e_des.c b/crypto/cipher_extra/e_des.c index baf0be0b8e..62ac2a03a6 100644 --- a/crypto/cipher_extra/e_des.c +++ b/crypto/cipher_extra/e_des.c @@ -85,16 +85,14 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } static const EVP_CIPHER evp_des_cbc = { - /* nid = */ NID_des_cbc, - /* block_size = */ 8, - /* key_len = */ 8, - /* iv_len = */ 8, - /* ctx_size = */ sizeof(EVP_DES_KEY), - /* flags = */ EVP_CIPH_CBC_MODE, - /* init = */ des_init_key, - /* cipher = */ des_cbc_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_cbc, + .block_size = 8, + .key_len = 8, + .iv_len = 8, + .ctx_size = sizeof(EVP_DES_KEY), + .flags = EVP_CIPH_CBC_MODE, + .init = des_init_key, + .cipher = des_cbc_cipher, }; const EVP_CIPHER *EVP_des_cbc(void) { return &evp_des_cbc; } @@ -114,16 +112,14 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } static const EVP_CIPHER evp_des_ecb = { - /* nid = */ NID_des_ecb, - /* block_size = */ 8, - /* key_len = */ 8, - /* iv_len = */ 0, - /* ctx_size = */ sizeof(EVP_DES_KEY), - /* flags = */ EVP_CIPH_ECB_MODE, - /* init = */ des_init_key, - /* cipher = */ des_ecb_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_ecb, + .block_size = 8, + .key_len = 8, + .iv_len = 0, + .ctx_size = sizeof(EVP_DES_KEY), + .flags = EVP_CIPH_ECB_MODE, + .init = des_init_key, + .cipher = des_ecb_cipher, }; const EVP_CIPHER *EVP_des_ecb(void) { return &evp_des_ecb; } @@ -153,16 +149,14 @@ static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, } static const EVP_CIPHER evp_des_ede3_cbc = { - /* nid = */ NID_des_ede3_cbc, - /* block_size = */ 8, - /* key_len = */ 24, - /* iv_len = */ 8, - /* ctx_size = */ sizeof(DES_EDE_KEY), - /* flags = */ EVP_CIPH_CBC_MODE, - /* init = */ des_ede3_init_key, - /* cipher = */ des_ede3_cbc_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_ede3_cbc, + .block_size = 8, + .key_len = 24, + .iv_len = 8, + .ctx_size = sizeof(DES_EDE_KEY), + .flags = EVP_CIPH_CBC_MODE, + .init = des_ede3_init_key, + .cipher = des_ede3_cbc_cipher, }; const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &evp_des_ede3_cbc; } @@ -178,16 +172,14 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, } static const EVP_CIPHER evp_des_ede_cbc = { - /* nid = */ NID_des_ede_cbc, - /* block_size = */ 8, - /* key_len = */ 16, - /* iv_len = */ 8, - /* ctx_size = */ sizeof(DES_EDE_KEY), - /* flags = */ EVP_CIPH_CBC_MODE, - /* init = */ des_ede_init_key, - /* cipher = */ des_ede3_cbc_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_ede_cbc, + .block_size = 8, + .key_len = 16, + .iv_len = 8, + .ctx_size = sizeof(DES_EDE_KEY), + .flags = EVP_CIPH_CBC_MODE, + .init = des_ede_init_key, + .cipher = des_ede3_cbc_cipher, }; const EVP_CIPHER *EVP_des_ede_cbc(void) { return &evp_des_ede_cbc; } @@ -208,31 +200,27 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, } static const EVP_CIPHER evp_des_ede = { - /* nid = */ NID_des_ede_ecb, - /* block_size = */ 8, - /* key_len = */ 16, - /* iv_len = */ 0, - /* ctx_size = */ sizeof(DES_EDE_KEY), - /* flags = */ EVP_CIPH_ECB_MODE, - /* init = */ des_ede_init_key, - /* cipher = */ des_ede_ecb_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_ede_ecb, + .block_size = 8, + .key_len = 16, + .iv_len = 0, + .ctx_size = sizeof(DES_EDE_KEY), + .flags = EVP_CIPH_ECB_MODE, + .init = des_ede_init_key, + .cipher = des_ede_ecb_cipher, }; const EVP_CIPHER *EVP_des_ede(void) { return &evp_des_ede; } static const EVP_CIPHER evp_des_ede3 = { - /* nid = */ NID_des_ede3_ecb, - /* block_size = */ 8, - /* key_len = */ 24, - /* iv_len = */ 0, - /* ctx_size = */ sizeof(DES_EDE_KEY), - /* flags = */ EVP_CIPH_ECB_MODE, - /* init = */ des_ede3_init_key, - /* cipher = */ des_ede_ecb_cipher, - /* cleanup = */ NULL, - /* ctrl = */ NULL, + .nid = NID_des_ede3_ecb, + .block_size = 8, + .key_len = 24, + .iv_len = 0, + .ctx_size = sizeof(DES_EDE_KEY), + .flags = EVP_CIPH_ECB_MODE, + .init = des_ede3_init_key, + .cipher = des_ede_ecb_cipher, }; const EVP_CIPHER *EVP_des_ede3(void) { return &evp_des_ede3; } diff --git a/crypto/cipher_extra/e_null.c b/crypto/cipher_extra/e_null.c index 10a5c269e2..ad99df924c 100644 --- a/crypto/cipher_extra/e_null.c +++ b/crypto/cipher_extra/e_null.c @@ -78,9 +78,13 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, } static const EVP_CIPHER n_cipher = { - NID_undef, 1 /* block size */, 0 /* key_len */, 0 /* iv_len */, - 0 /* ctx_size */, 0 /* flags */, null_init_key, null_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_undef, + .block_size = 1, + .key_len = 0, + .iv_len = 0, + .ctx_size = 0, + .init = null_init_key, + .cipher = null_cipher, }; const EVP_CIPHER *EVP_enc_null(void) { return &n_cipher; } diff --git a/crypto/cipher_extra/e_rc2.c b/crypto/cipher_extra/e_rc2.c index acc99ad8c1..c2a143ebac 100644 --- a/crypto/cipher_extra/e_rc2.c +++ b/crypto/cipher_extra/e_rc2.c @@ -427,35 +427,29 @@ static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { } static const EVP_CIPHER rc2_40_cbc = { - NID_rc2_40_cbc, - 8 /* block size */, - 5 /* 40 bit */, - 8 /* iv len */, - sizeof(EVP_RC2_KEY), - EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - rc2_init_key, - rc2_cbc_cipher, - NULL, - rc2_ctrl, + .nid = NID_rc2_40_cbc, + .block_size = 8, + .key_len = 5 /* 40 bit */, + .iv_len = 8, + .ctx_size = sizeof(EVP_RC2_KEY), + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + .init = rc2_init_key, + .cipher = rc2_cbc_cipher, + .ctrl = rc2_ctrl, }; -const EVP_CIPHER *EVP_rc2_40_cbc(void) { - return &rc2_40_cbc; -} +const EVP_CIPHER *EVP_rc2_40_cbc(void) { return &rc2_40_cbc; } static const EVP_CIPHER rc2_cbc = { - NID_rc2_cbc, - 8 /* block size */, - 16 /* 128 bit */, - 8 /* iv len */, - sizeof(EVP_RC2_KEY), - EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - rc2_init_key, - rc2_cbc_cipher, - NULL, - rc2_ctrl, + .nid = NID_rc2_cbc, + .block_size = 8, + .key_len = 16 /* 128 bit */, + .iv_len = 8, + .ctx_size = sizeof(EVP_RC2_KEY), + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + .init = rc2_init_key, + .cipher = rc2_cbc_cipher, + .ctrl = rc2_ctrl, }; -const EVP_CIPHER *EVP_rc2_cbc(void) { - return &rc2_cbc; -} +const EVP_CIPHER *EVP_rc2_cbc(void) { return &rc2_cbc; } diff --git a/crypto/cipher_extra/e_rc4.c b/crypto/cipher_extra/e_rc4.c index e252ad8dcb..0c3404fd72 100644 --- a/crypto/cipher_extra/e_rc4.c +++ b/crypto/cipher_extra/e_rc4.c @@ -81,10 +81,14 @@ static int rc4_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } static const EVP_CIPHER rc4 = { - NID_rc4, 1 /* block_size */, 16 /* key_size */, - 0 /* iv_len */, sizeof(RC4_KEY), EVP_CIPH_VARIABLE_LENGTH, - rc4_init_key, rc4_cipher, NULL /* cleanup */, - NULL /* ctrl */, + .nid = NID_rc4, + .block_size = 1, + .key_len = 16, + .iv_len = 0, + .ctx_size = sizeof(RC4_KEY), + .flags = EVP_CIPH_VARIABLE_LENGTH, + .init = rc4_init_key, + .cipher = rc4_cipher, }; const EVP_CIPHER *EVP_rc4(void) { return &rc4; } diff --git a/crypto/decrepit/blowfish/blowfish.c b/crypto/decrepit/blowfish/blowfish.c index 4e5a00d533..124764e6a1 100644 --- a/crypto/decrepit/blowfish/blowfish.c +++ b/crypto/decrepit/blowfish/blowfish.c @@ -594,27 +594,36 @@ static int bf_cfb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } static const EVP_CIPHER bf_ecb = { - NID_bf_ecb, BF_BLOCK /* block_size */, - 16 /* key_size */, BF_BLOCK /* iv_len */, - sizeof(BF_KEY), EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH, - bf_init_key, bf_ecb_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_bf_ecb, + .block_size = BF_BLOCK, + .key_len = 16, + .iv_len = BF_BLOCK, + .ctx_size = sizeof(BF_KEY), + .flags = EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH, + .init = bf_init_key, + .cipher = bf_ecb_cipher, }; static const EVP_CIPHER bf_cbc = { - NID_bf_cbc, BF_BLOCK /* block_size */, - 16 /* key_size */, BF_BLOCK /* iv_len */, - sizeof(BF_KEY), EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH, - bf_init_key, bf_cbc_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_bf_cbc, + .block_size = BF_BLOCK, + .key_len = 16, + .iv_len = BF_BLOCK, + .ctx_size = sizeof(BF_KEY), + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH, + .init = bf_init_key, + .cipher = bf_cbc_cipher, }; static const EVP_CIPHER bf_cfb = { - NID_bf_cfb64, 1 /* block_size */, - 16 /* key_size */, BF_BLOCK /* iv_len */, - sizeof(BF_KEY), EVP_CIPH_CFB_MODE | EVP_CIPH_VARIABLE_LENGTH, - bf_init_key, bf_cfb_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_bf_cfb64, + .block_size = 1, + .key_len = 16, + .iv_len = BF_BLOCK, + .ctx_size = sizeof(BF_KEY), + .flags = EVP_CIPH_CFB_MODE | EVP_CIPH_VARIABLE_LENGTH, + .init = bf_init_key, + .cipher = bf_cfb_cipher, }; const EVP_CIPHER *EVP_bf_ecb(void) { return &bf_ecb; } diff --git a/crypto/decrepit/cast/cast.c b/crypto/decrepit/cast/cast.c index 012283ae27..1b80b8f386 100644 --- a/crypto/decrepit/cast/cast.c +++ b/crypto/decrepit/cast/cast.c @@ -384,19 +384,25 @@ static int cast_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } static const EVP_CIPHER cast5_ecb = { - NID_cast5_ecb, CAST_BLOCK, - CAST_KEY_LENGTH, CAST_BLOCK /* iv_len */, - sizeof(CAST_KEY), EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH, - cast_init_key, cast_ecb_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_cast5_ecb, + .block_size = CAST_BLOCK, + .key_len = CAST_KEY_LENGTH, + .iv_len = CAST_BLOCK, + .ctx_size = sizeof(CAST_KEY), + .flags = EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH, + .init = cast_init_key, + .cipher = cast_ecb_cipher, }; static const EVP_CIPHER cast5_cbc = { - NID_cast5_cbc, CAST_BLOCK, - CAST_KEY_LENGTH, CAST_BLOCK /* iv_len */, - sizeof(CAST_KEY), EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH, - cast_init_key, cast_cbc_cipher, - NULL /* cleanup */, NULL /* ctrl */, + .nid = NID_cast5_cbc, + .block_size = CAST_BLOCK, + .key_len = CAST_KEY_LENGTH, + .iv_len = CAST_BLOCK, + .ctx_size = sizeof(CAST_KEY), + .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH, + .init = cast_init_key, + .cipher = cast_cbc_cipher, }; const EVP_CIPHER *EVP_cast5_ecb(void) { return &cast5_ecb; } diff --git a/crypto/err/err.c b/crypto/err/err.c index 8741402818..8687c738de 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -178,6 +178,17 @@ extern const uint32_t kOpenSSLReasonValues[]; extern const size_t kOpenSSLReasonValuesLen; extern const char kOpenSSLReasonStringData[]; +static char *strdup_libc_malloc(const char *str) { + // |strdup| is not in C until C23, so MSVC triggers deprecation warnings, and + // glibc and musl gate it on a feature macro. Reimplementing it is easier. + size_t len = strlen(str); + char *ret = malloc(len + 1); + if (ret != NULL) { + memcpy(ret, str, len + 1); + } + return ret; +} + // err_clear clears the given queued error. static void err_clear(struct err_error_st *error) { free(error->data); @@ -188,13 +199,9 @@ static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { err_clear(dst); dst->file = src->file; if (src->data != NULL) { - // Disable deprecated functions on msvc so it doesn't complain about strdup. - OPENSSL_MSVC_PRAGMA(warning(push)) - OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) // We can't use OPENSSL_strdup because we don't want to call OPENSSL_malloc, // which can affect the error stack. - dst->data = strdup(src->data); - OPENSSL_MSVC_PRAGMA(warning(pop)) + dst->data = strdup_libc_malloc(src->data); } dst->packed = src->packed; dst->line = src->line; @@ -766,13 +773,9 @@ void ERR_set_error_data(char *data, int flags) { assert(0); return; } - // Disable deprecated functions on msvc so it doesn't complain about strdup. - OPENSSL_MSVC_PRAGMA(warning(push)) - OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) // We can not use OPENSSL_strdup because we don't want to call OPENSSL_malloc, // which can affect the error stack. - char *copy = strdup(data); - OPENSSL_MSVC_PRAGMA(warning(pop)) + char *copy = strdup_libc_malloc(data); if (copy != NULL) { err_set_error_data(copy); } diff --git a/crypto/mem.c b/crypto/mem.c index 6bf94151b3..2490358ce4 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -379,13 +379,8 @@ char *OPENSSL_strdup(const char *s) { if (s == NULL) { return NULL; } - const size_t len = strlen(s) + 1; - char *ret = OPENSSL_malloc(len); - if (ret == NULL) { - return NULL; - } - OPENSSL_memcpy(ret, s, len); - return ret; + // Copy the NUL terminator. + return OPENSSL_memdup(s, strlen(s) + 1); } int OPENSSL_isalpha(int c) { diff --git a/include/openssl/base.h b/include/openssl/base.h index d08bf1a95d..1d26ac9182 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -199,6 +199,13 @@ extern "C" { #define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) #endif +// OPENSSL_CLANG_PRAGMA emits a pragma on clang and nothing on other compilers. +#if defined(__clang__) +#define OPENSSL_CLANG_PRAGMA(arg) _Pragma(arg) +#else +#define OPENSSL_CLANG_PRAGMA(arg) +#endif + // OPENSSL_MSVC_PRAGMA emits a pragma on MSVC and nothing on other compilers. #if defined(_MSC_VER) #define OPENSSL_MSVC_PRAGMA(arg) __pragma(arg) diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h index c59bb82dc5..688593b5a3 100644 --- a/include/openssl/bytestring.h +++ b/include/openssl/bytestring.h @@ -645,6 +645,33 @@ OPENSSL_EXPORT int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, OPENSSL_EXPORT int CBB_flush_asn1_set_of(CBB *cbb); +// Unicode utilities. +// +// These functions consider noncharacters (see section 23.7 from Unicode 15.0.0) +// to be invalid code points and will treat them as an error condition. + +// The following functions read one Unicode code point from |cbs| with the +// corresponding encoding and store it in |*out|. They return one on success and +// zero on error. +OPENSSL_EXPORT int CBS_get_utf8(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int CBS_get_latin1(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int CBS_get_ucs2_be(CBS *cbs, uint32_t *out); +OPENSSL_EXPORT int CBS_get_utf32_be(CBS *cbs, uint32_t *out); + +// CBB_get_utf8_len returns the number of bytes needed to represent |u| in +// UTF-8. +OPENSSL_EXPORT size_t CBB_get_utf8_len(uint32_t u); + +// The following functions encode |u| to |cbb| with the corresponding +// encoding. They return one on success and zero on error. Error conditions +// include |u| being an invalid code point, or |u| being unencodable in the +// specified encoding. +OPENSSL_EXPORT int CBB_add_utf8(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int CBB_add_latin1(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int CBB_add_ucs2_be(CBB *cbb, uint32_t u); +OPENSSL_EXPORT int CBB_add_utf32_be(CBB *cbb, uint32_t u); + + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/rand.h b/include/openssl/rand.h index fddb890f0c..a450fb5f0e 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h @@ -37,15 +37,25 @@ OPENSSL_EXPORT int RAND_priv_bytes(uint8_t *buf, size_t len); // Obscure functions. #if !defined(OPENSSL_WINDOWS) -// RAND_enable_fork_unsafe_buffering enables efficient buffered reading of -// /dev/urandom. It adds an overhead of a few KB of memory per thread. It must -// be called before the first call to |RAND_bytes|. +// RAND_enable_fork_unsafe_buffering indicates that clones of the address space, +// e.g. via |fork|, will never call into BoringSSL. It may be used to disable +// BoringSSL's more expensive fork-safety measures. However, calling this +// function and then using BoringSSL across |fork| calls will leak secret keys. +// |fd| must be -1. // -// |fd| must be -1. We no longer support setting the file descriptor with this -// function. +// WARNING: This function affects BoringSSL for the entire address space. Thus +// this function should never be called by library code, only by code with +// global knowledge of the application's use of BoringSSL. // -// It has an unusual name because the buffer is unsafe across calls to |fork|. -// Hence, this function should never be called by libraries. +// Do not use this function unless a performance issue was measured with the +// default behavior. BoringSSL can efficiently detect forks on most platforms, +// in which case this function is a no-op and is unnecessary. In particular, +// Linux kernel versions 4.14 or later provide |MADV_WIPEONFORK|. Future +// versions of BoringSSL will remove this functionality when older kernels are +// sufficiently rare. +// +// This function has an unusual name because it historically controlled internal +// buffers, but no longer does. OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd); #endif diff --git a/include/openssl/stack.h b/include/openssl/stack.h index 7ff03fe48b..beb3c2dcce 100644 --- a/include/openssl/stack.h +++ b/include/openssl/stack.h @@ -416,6 +416,9 @@ BSSL_NAMESPACE_END * positive warning. */ \ OPENSSL_MSVC_PRAGMA(warning(push)) \ OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ + OPENSSL_CLANG_PRAGMA("clang diagnostic push") \ + OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wunknown-warning-option\"") \ + OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wcast-function-type-strict\"") \ \ DECLARE_STACK_OF(name) \ \ @@ -569,6 +572,7 @@ BSSL_NAMESPACE_END (OPENSSL_sk_free_func)free_func); \ } \ \ + OPENSSL_CLANG_PRAGMA("clang diagnostic pop") \ OPENSSL_MSVC_PRAGMA(warning(pop)) diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc index 992fb526b3..26819f165d 100644 --- a/ssl/dtls_record.cc +++ b/ssl/dtls_record.cc @@ -139,14 +139,14 @@ static uint64_t to_u64_be(const uint8_t in[8]) { // |bitmap| or is stale. Otherwise it returns zero. static bool dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, const uint8_t seq_num[8]) { - const unsigned kWindowSize = sizeof(bitmap->map) * 8; + const size_t kWindowSize = bitmap->map.size(); uint64_t seq_num_u = to_u64_be(seq_num); if (seq_num_u > bitmap->max_seq_num) { return false; } uint64_t idx = bitmap->max_seq_num - seq_num_u; - return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx)); + return idx >= kWindowSize || bitmap->map[idx]; } // dtls1_bitmap_record updates |bitmap| to record receipt of sequence number @@ -154,14 +154,14 @@ static bool dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, // this function on a stale sequence number. static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, const uint8_t seq_num[8]) { - const unsigned kWindowSize = sizeof(bitmap->map) * 8; + const size_t kWindowSize = bitmap->map.size(); uint64_t seq_num_u = to_u64_be(seq_num); // Shift the window if necessary. if (seq_num_u > bitmap->max_seq_num) { uint64_t shift = seq_num_u - bitmap->max_seq_num; if (shift >= kWindowSize) { - bitmap->map = 0; + bitmap->map.reset(); } else { bitmap->map <<= shift; } @@ -170,7 +170,7 @@ static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, uint64_t idx = bitmap->max_seq_num - seq_num_u; if (idx < kWindowSize) { - bitmap->map |= ((uint64_t)1) << idx; + bitmap->map[idx] = true; } } diff --git a/ssl/internal.h b/ssl/internal.h index 7e3b21fd57..717759a54c 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -147,6 +147,7 @@ #include #include +#include #include #include #include @@ -994,9 +995,9 @@ class SSLAEADContext { // DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect // replayed packets. It should be initialized by zeroing every field. struct DTLS1_BITMAP { - // map is a bit mask of the last 64 sequence numbers. Bit - // |1< map; // max_seq_num is the largest sequence number seen so far as a 64-bit // integer. uint64_t max_seq_num = 0; diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index c5705c5e37..16d1fda2ec 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -10004,7 +10004,7 @@ func addDTLSReplayTests() { config: Config{ Bugs: ProtocolBugs{ SequenceNumberMapping: func(in uint64) uint64 { - return in * 127 + return in * 1023 }, }, }, @@ -10019,11 +10019,15 @@ func addDTLSReplayTests() { config: Config{ Bugs: ProtocolBugs{ SequenceNumberMapping: func(in uint64) uint64 { - return in ^ 31 + // This mapping has numbers counting backwards in groups + // of 256, and then jumping forwards 511 numbers. + return in ^ 255 }, }, }, - messageCount: 200, + // This messageCount is large enough to make sure that the SequenceNumberMapping + // will reach the point where it jumps forwards after stepping backwards. + messageCount: 500, replayWrites: true, }) }