update master-with-bazel from master branch
This commit is contained in:
@@ -5637,6 +5637,14 @@ enum ssl_compliance_policy_t BORINGSSL_ENUM_INT {
|
||||
// implementation risks of using a more obscure primitive like P-384
|
||||
// dominate other considerations.
|
||||
ssl_compliance_policy_wpa3_192_202304,
|
||||
|
||||
// ssl_compliance_policy_cnsa_202407 confingures a TLS connection to use:
|
||||
// * For TLS 1.3, AES-256-GCM over AES-128-GCM over ChaCha20-Poly1305.
|
||||
//
|
||||
// I.e. it ensures that AES-GCM will be used whenever the client supports it.
|
||||
// The cipher suite configuration mini-language can be used to similarly
|
||||
// configure prior TLS versions if they are enabled.
|
||||
ssl_compliance_policy_cnsa_202407,
|
||||
};
|
||||
|
||||
// SSL_CTX_set_compliance_policy configures various aspects of |ctx| based on
|
||||
|
||||
+26
-13
@@ -244,23 +244,36 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out,
|
||||
// Add TLS 1.3 ciphers. Order ChaCha20-Poly1305 relative to AES-GCM based on
|
||||
// hardware support.
|
||||
if (hs->max_version >= TLS1_3_VERSION) {
|
||||
static const uint16_t kCiphersNoAESHardware[] = {
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
|
||||
TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
|
||||
TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff,
|
||||
};
|
||||
static const uint16_t kCiphersAESHardware[] = {
|
||||
TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
|
||||
TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
|
||||
};
|
||||
static const uint16_t kCiphersCNSA[] = {
|
||||
TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff,
|
||||
TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
|
||||
};
|
||||
|
||||
const bool has_aes_hw = ssl->config->aes_hw_override
|
||||
? ssl->config->aes_hw_override_value
|
||||
: EVP_has_aes_hardware();
|
||||
const bssl::Span<const uint16_t> ciphers =
|
||||
ssl->config->tls13_cipher_policy == ssl_compliance_policy_cnsa_202407
|
||||
? bssl::Span<const uint16_t>(kCiphersCNSA)
|
||||
: (has_aes_hw ? bssl::Span<const uint16_t>(kCiphersAESHardware)
|
||||
: bssl::Span<const uint16_t>(kCiphersNoAESHardware));
|
||||
|
||||
if ((!has_aes_hw && //
|
||||
!ssl_add_tls13_cipher(&child,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
|
||||
ssl->config->tls13_cipher_policy)) ||
|
||||
!ssl_add_tls13_cipher(&child, TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff,
|
||||
ssl->config->tls13_cipher_policy) ||
|
||||
!ssl_add_tls13_cipher(&child, TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff,
|
||||
ssl->config->tls13_cipher_policy) ||
|
||||
(has_aes_hw && //
|
||||
!ssl_add_tls13_cipher(&child,
|
||||
TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff,
|
||||
ssl->config->tls13_cipher_policy))) {
|
||||
return false;
|
||||
for (auto cipher : ciphers) {
|
||||
if (!ssl_add_tls13_cipher(&child, cipher,
|
||||
ssl->config->tls13_cipher_policy)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-16
@@ -659,36 +659,49 @@ void tls_next_message(SSL *ssl) {
|
||||
}
|
||||
}
|
||||
|
||||
// CipherScorer produces a "score" for each possible cipher suite offered by
|
||||
// the client.
|
||||
class CipherScorer {
|
||||
public:
|
||||
CipherScorer(bool has_aes_hw) : aes_is_fine_(has_aes_hw) {}
|
||||
using Score = int;
|
||||
static constexpr Score kMinScore = 0;
|
||||
|
||||
typedef std::tuple<bool, bool> Score;
|
||||
virtual Score Evaluate(const SSL_CIPHER *cipher) const = 0;
|
||||
};
|
||||
|
||||
// MinScore returns a |Score| that will compare less than the score of all
|
||||
// cipher suites.
|
||||
Score MinScore() const {
|
||||
return Score(false, false);
|
||||
}
|
||||
// AesHwCipherScorer scores cipher suites based on whether AES is supported in
|
||||
// hardware.
|
||||
class AesHwCipherScorer : public CipherScorer {
|
||||
public:
|
||||
explicit AesHwCipherScorer(bool has_aes_hw) : aes_is_fine_(has_aes_hw) {}
|
||||
|
||||
Score Evaluate(const SSL_CIPHER *a) const {
|
||||
return Score(
|
||||
Score Evaluate(const SSL_CIPHER *a) const override {
|
||||
return
|
||||
// Something is always preferable to nothing.
|
||||
true,
|
||||
1 +
|
||||
// Either AES is fine, or else ChaCha20 is preferred.
|
||||
aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305);
|
||||
((aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305) ? 1 : 0);
|
||||
}
|
||||
|
||||
private:
|
||||
const bool aes_is_fine_;
|
||||
};
|
||||
|
||||
// CNsaCipherScorer prefers AES-256-GCM over AES-128-GCM over anything else.
|
||||
class CNsaCipherScorer : public CipherScorer {
|
||||
Score Evaluate(const SSL_CIPHER *a) const override {
|
||||
if (a->id == TLS1_3_CK_AES_256_GCM_SHA384) {
|
||||
return 3;
|
||||
} else if (a->id == TLS1_3_CK_AES_128_GCM_SHA256) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id,
|
||||
enum ssl_compliance_policy_t policy) {
|
||||
switch (policy) {
|
||||
case ssl_compliance_policy_none:
|
||||
case ssl_compliance_policy_cnsa_202407:
|
||||
return true;
|
||||
|
||||
case ssl_compliance_policy_fips_202205:
|
||||
@@ -728,8 +741,12 @@ const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw,
|
||||
}
|
||||
|
||||
const SSL_CIPHER *best = nullptr;
|
||||
CipherScorer scorer(has_aes_hw);
|
||||
CipherScorer::Score best_score = scorer.MinScore();
|
||||
AesHwCipherScorer aes_hw_scorer(has_aes_hw);
|
||||
CNsaCipherScorer cnsa_scorer;
|
||||
CipherScorer *const scorer = (policy == ssl_compliance_policy_cnsa_202407)
|
||||
? static_cast<CipherScorer*>(&cnsa_scorer)
|
||||
: static_cast<CipherScorer*>(&aes_hw_scorer);
|
||||
CipherScorer::Score best_score = CipherScorer::kMinScore;
|
||||
|
||||
while (CBS_len(&cipher_suites) > 0) {
|
||||
uint16_t cipher_suite;
|
||||
@@ -750,7 +767,7 @@ const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw,
|
||||
continue;
|
||||
}
|
||||
|
||||
const CipherScorer::Score candidate_score = scorer.Evaluate(candidate);
|
||||
const CipherScorer::Score candidate_score = scorer->Evaluate(candidate);
|
||||
// |candidate_score| must be larger to displace the current choice. That way
|
||||
// the client's order controls between ciphers with an equal score.
|
||||
if (candidate_score > best_score) {
|
||||
|
||||
@@ -3403,6 +3403,21 @@ static int Configure(SSL *ssl) {
|
||||
|
||||
} // namespace wpa202304
|
||||
|
||||
namespace cnsa202407 {
|
||||
|
||||
static int Configure(SSL_CTX *ctx) {
|
||||
ctx->tls13_cipher_policy = ssl_compliance_policy_cnsa_202407;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Configure(SSL *ssl) {
|
||||
ssl->config->tls13_cipher_policy =
|
||||
ssl_compliance_policy_cnsa_202407;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int SSL_CTX_set_compliance_policy(SSL_CTX *ctx,
|
||||
enum ssl_compliance_policy_t policy) {
|
||||
switch (policy) {
|
||||
@@ -3410,6 +3425,8 @@ int SSL_CTX_set_compliance_policy(SSL_CTX *ctx,
|
||||
return fips202205::Configure(ctx);
|
||||
case ssl_compliance_policy_wpa3_192_202304:
|
||||
return wpa202304::Configure(ctx);
|
||||
case ssl_compliance_policy_cnsa_202407:
|
||||
return cnsa202407::Configure(ctx);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -3421,6 +3438,8 @@ int SSL_set_compliance_policy(SSL *ssl, enum ssl_compliance_policy_t policy) {
|
||||
return fips202205::Configure(ssl);
|
||||
case ssl_compliance_policy_wpa3_192_202304:
|
||||
return wpa202304::Configure(ssl);
|
||||
case ssl_compliance_policy_cnsa_202407:
|
||||
return cnsa202407::Configure(ssl);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19928,6 +19928,38 @@ func addCompliancePolicyTests() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AES-256-GCM is the most preferred.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
protocol: protocol,
|
||||
name: "Compliance-cnsa202407-" + protocol.String() + "-AES-256-preferred",
|
||||
config: Config{
|
||||
MinVersion: VersionTLS13,
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384},
|
||||
},
|
||||
flags: []string{
|
||||
"-cnsa-202407",
|
||||
},
|
||||
expectations: connectionExpectations{cipher: TLS_AES_256_GCM_SHA384},
|
||||
})
|
||||
|
||||
// AES-128-GCM is preferred over ChaCha20-Poly1305.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
protocol: protocol,
|
||||
name: "Compliance-cnsa202407-" + protocol.String() + "-AES-128-preferred",
|
||||
config: Config{
|
||||
MinVersion: VersionTLS13,
|
||||
MaxVersion: VersionTLS13,
|
||||
CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256},
|
||||
},
|
||||
flags: []string{
|
||||
"-cnsa-202407",
|
||||
},
|
||||
expectations: connectionExpectations{cipher: TLS_AES_128_GCM_SHA256},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -478,6 +478,7 @@ const Flag<TestConfig> *FindFlag(const char *name) {
|
||||
&TestConfig::early_write_after_message),
|
||||
BoolFlag("-fips-202205", &TestConfig::fips_202205),
|
||||
BoolFlag("-wpa-202304", &TestConfig::wpa_202304),
|
||||
BoolFlag("-cnsa-202407", &TestConfig::cnsa_202407),
|
||||
BoolFlag("-no-check-client-certificate-type",
|
||||
&TestConfig::no_check_client_certificate_type),
|
||||
BoolFlag("-no-check-ecdsa-curve", &TestConfig::no_check_ecdsa_curve),
|
||||
@@ -2096,7 +2097,9 @@ bssl::UniquePtr<SSL> TestConfig::NewSSL(
|
||||
if (enable_ech_grease) {
|
||||
SSL_set_enable_ech_grease(ssl.get(), 1);
|
||||
}
|
||||
if (static_cast<int>(fips_202205) + static_cast<int>(wpa_202304) > 1) {
|
||||
if (static_cast<int>(fips_202205) + static_cast<int>(wpa_202304) +
|
||||
static_cast<int>(cnsa_202407) >
|
||||
1) {
|
||||
fprintf(stderr, "Multiple policy options given\n");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2110,6 +2113,11 @@ bssl::UniquePtr<SSL> TestConfig::NewSSL(
|
||||
fprintf(stderr, "SSL_set_compliance_policy failed\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (cnsa_202407 && !SSL_set_compliance_policy(
|
||||
ssl.get(), ssl_compliance_policy_cnsa_202407)) {
|
||||
fprintf(stderr, "SSL_set_compliance_policy failed\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (!ech_config_list.empty() &&
|
||||
!SSL_set1_ech_config_list(
|
||||
ssl.get(), reinterpret_cast<const uint8_t *>(ech_config_list.data()),
|
||||
|
||||
@@ -214,6 +214,7 @@ struct TestConfig {
|
||||
int early_write_after_message = 0;
|
||||
bool fips_202205 = false;
|
||||
bool wpa_202304 = false;
|
||||
bool cnsa_202407 = false;
|
||||
bool no_check_client_certificate_type = false;
|
||||
bool no_check_ecdsa_curve = false;
|
||||
int expect_selected_credential = -1;
|
||||
|
||||
Reference in New Issue
Block a user