tls_mlkem_unittest.cc (19997B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ssl.h" 8 #include "sslerr.h" 9 #include "sslproto.h" 10 11 extern "C" { 12 // This is not something that should make you happy. 13 #include "libssl_internals.h" 14 } 15 16 #include "gtest_utils.h" 17 #include "nss_scoped_ptrs.h" 18 #include "tls_connect.h" 19 #include "tls_filter.h" 20 #include "tls_parser.h" 21 22 namespace nss_test { 23 24 TEST_P(TlsKeyExchangeTest13, Mlkem768x25519Supported) { 25 EnsureKeyShareSetup(); 26 ConfigNamedGroups({ssl_grp_kem_mlkem768x25519}); 27 28 Connect(); 29 CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_rsa_sign, 30 ssl_sig_rsa_pss_rsae_sha256); 31 } 32 33 TEST_P(TlsKeyExchangeTest13, Secp256r1Mlkem768Supported) { 34 EnsureKeyShareSetup(); 35 ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768}); 36 37 Connect(); 38 CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_secp256r1mlkem768, 39 ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); 40 } 41 42 TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024Supported) { 43 EnsureKeyShareSetup(); 44 ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024}); 45 46 Connect(); 47 CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_secp384r1mlkem1024, 48 ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); 49 } 50 51 TEST_P(TlsKeyExchangeTest, Tls12ClientMlkem768x25519NotSupported) { 52 EnsureKeyShareSetup(); 53 client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 54 SSL_LIBRARY_VERSION_TLS_1_2); 55 server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 56 SSL_LIBRARY_VERSION_TLS_1_3); 57 client_->DisableAllCiphers(); 58 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh); 59 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid); 60 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares( 61 client_->ssl_fd(), 62 kECDHEGroups.size() + kEcdhHybridGroups.size())); 63 64 Connect(); 65 std::vector<SSLNamedGroup> groups = GetGroupDetails(groups_capture_); 66 for (auto group : groups) { 67 EXPECT_NE(group, ssl_grp_kem_mlkem768x25519); 68 EXPECT_NE(group, ssl_grp_kem_secp256r1mlkem768); 69 EXPECT_NE(group, ssl_grp_kem_secp384r1mlkem1024); 70 } 71 } 72 73 TEST_P(TlsKeyExchangeTest13, Tls12ServerMlkem768x25519NotSupported) { 74 EnsureKeyShareSetup(); 75 76 client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 77 SSL_LIBRARY_VERSION_TLS_1_3); 78 server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 79 SSL_LIBRARY_VERSION_TLS_1_2); 80 81 client_->DisableAllCiphers(); 82 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh); 83 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid); 84 client_->ConfigNamedGroups( 85 {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}); 86 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 87 88 server_->EnableCiphersByKeyExchange(ssl_kea_ecdh); 89 server_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid); 90 server_->ConfigNamedGroups( 91 {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}); 92 93 Connect(); 94 CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign, 95 ssl_sig_rsa_pss_rsae_sha256); 96 } 97 98 TEST_P(TlsKeyExchangeTest13, Tls12ServerSecp256r1Mlkem768NotSupported) { 99 EnsureKeyShareSetup(); 100 101 client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 102 SSL_LIBRARY_VERSION_TLS_1_3); 103 server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, 104 SSL_LIBRARY_VERSION_TLS_1_2); 105 106 client_->DisableAllCiphers(); 107 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh); 108 client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid); 109 client_->ConfigNamedGroups( 110 {ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 111 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 112 113 server_->EnableCiphersByKeyExchange(ssl_kea_ecdh); 114 server_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid); 115 server_->ConfigNamedGroups( 116 {ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 117 118 Connect(); 119 CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign, 120 ssl_sig_rsa_pss_rsae_sha256); 121 } 122 123 TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ClientDisabledByPolicy) { 124 EnsureKeyShareSetup(); 125 client_->SetPolicy(SEC_OID_MLKEM768X25519, 0, NSS_USE_ALG_IN_SSL_KX); 126 ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1}); 127 128 Connect(); 129 CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1}); 130 } 131 132 TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ServerDisabledByPolicy) { 133 EnsureKeyShareSetup(); 134 server_->SetPolicy(SEC_OID_MLKEM768X25519, 0, NSS_USE_ALG_IN_SSL_KX); 135 ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1}); 136 137 Connect(); 138 CheckKEXDetails({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1}, 139 {ssl_grp_kem_mlkem768x25519}, ssl_grp_ec_secp256r1); 140 } 141 142 TEST_P(TlsKeyExchangeTest13, Secp256r1Mlkem768ClientDisabledByPolicy) { 143 EnsureKeyShareSetup(); 144 client_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX); 145 ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 146 147 Connect(); 148 CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1}); 149 } 150 151 TEST_P(TlsKeyExchangeTest13, Secp256r1Mlkem768ServerDisabledByPolicy) { 152 EnsureKeyShareSetup(); 153 server_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX); 154 ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 155 156 Connect(); 157 CheckKEXDetails({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}, 158 {ssl_grp_kem_secp256r1mlkem768}, ssl_grp_ec_secp256r1); 159 } 160 161 TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ClientDisabledByPolicy) { 162 EnsureKeyShareSetup(); 163 client_->SetPolicy(SEC_OID_SECP384R1MLKEM1024, 0, NSS_USE_ALG_IN_SSL_KX); 164 ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1}); 165 166 Connect(); 167 CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1}); 168 } 169 170 TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ServerDisabledByPolicy) { 171 EnsureKeyShareSetup(); 172 server_->SetPolicy(SEC_OID_SECP384R1MLKEM1024, 0, NSS_USE_ALG_IN_SSL_KX); 173 ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1}); 174 175 Connect(); 176 CheckKEXDetails({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1}, 177 {ssl_grp_kem_secp384r1mlkem1024}, ssl_grp_ec_secp256r1); 178 } 179 180 static void CheckECDHShareReuse( 181 const std::shared_ptr<TlsExtensionCapture>& capture) { 182 EXPECT_TRUE(capture->captured()); 183 const DataBuffer& ext = capture->extension(); 184 const int max_count = 4; 185 DataBuffer hybrid_share[max_count]; 186 DataBuffer ecdh_share[max_count]; 187 int hybrid_offset[max_count]; 188 SSLNamedGroup hybrid_ec_type[max_count]; 189 SSLNamedGroup ec_type[max_count]; 190 int ecdh_index[max_count]; 191 int nextHybrid = 0; 192 int nextECDH = 0; 193 194 size_t offset = 0; 195 uint32_t ext_len; 196 ext.Read(0, 2, &ext_len); 197 EXPECT_EQ(ext.len() - 2, ext_len); 198 offset += 2; 199 200 uint32_t named_group; 201 uint32_t named_group_len; 202 ext.Read(offset, 2, &named_group); 203 ext.Read(offset + 2, 2, &named_group_len); 204 while (offset < ext.len()) { 205 switch (named_group) { 206 case ssl_grp_kem_mlkem768x25519: 207 hybrid_share[nextHybrid] = 208 DataBuffer(ext.data() + offset + 2 + 2, named_group_len); 209 hybrid_offset[nextHybrid] = KYBER768_PUBLIC_KEY_BYTES; 210 hybrid_ec_type[nextHybrid] = ssl_grp_ec_curve25519; 211 nextHybrid++; 212 break; 213 case ssl_grp_kem_secp256r1mlkem768: 214 hybrid_share[nextHybrid] = 215 DataBuffer(ext.data() + offset + 2 + 2, named_group_len); 216 hybrid_offset[nextHybrid] = 0; 217 hybrid_ec_type[nextHybrid] = ssl_grp_ec_secp256r1; 218 nextHybrid++; 219 case ssl_grp_ec_curve25519: 220 case ssl_grp_ec_secp256r1: 221 ecdh_share[nextECDH] = 222 DataBuffer(ext.data() + offset + 2 + 2, named_group_len); 223 ec_type[nextECDH] = (SSLNamedGroup)named_group; 224 nextECDH++; 225 } 226 offset += 2 + 2 + named_group_len; 227 ext.Read(offset, 2, &named_group); 228 ext.Read(offset + 2, 2, &named_group_len); 229 } 230 EXPECT_EQ(offset, ext.len()); 231 232 ASSERT_TRUE(nextECDH <= max_count); 233 ASSERT_TRUE(nextHybrid <= max_count); 234 /* setup the hybrid ecdh indeces */ 235 for (int i = 0; i < nextHybrid; i++) { 236 ecdh_index[i] = -1; 237 for (int j = 0; j < nextECDH; j++) { 238 if (hybrid_ec_type[i] == ec_type[j]) { 239 ecdh_index[i] = j; 240 break; 241 } 242 } 243 ASSERT_TRUE(ecdh_index[i] != -1); 244 } 245 for (int i = 0; i < nextECDH; i++) { 246 ASSERT_TRUE(ecdh_share[i].data()); 247 } 248 for (int i = 0; i < nextHybrid; i++) { 249 int j = ecdh_index[i]; 250 ASSERT_TRUE(hybrid_share[i].data()); 251 ASSERT_GT(hybrid_share[i].len(), ecdh_share[j].len()); 252 EXPECT_EQ(0, memcmp(hybrid_share[i].data() + hybrid_offset[i], 253 ecdh_share[j].data(), ecdh_share[j].len())); 254 } 255 } 256 257 TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ShareReuseFirst) { 258 EnsureKeyShareSetup(); 259 ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}); 260 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 261 262 Connect(); 263 264 CheckKEXDetails({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}, 265 {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}); 266 CheckECDHShareReuse(shares_capture_); 267 } 268 269 TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ShareReuseSecond) { 270 EnsureKeyShareSetup(); 271 ConfigNamedGroups({ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519}); 272 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 273 274 Connect(); 275 276 CheckKEXDetails({ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519}, 277 {ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519}); 278 CheckECDHShareReuse(shares_capture_); 279 } 280 281 TEST_P(TlsKeyExchangeTest13, Secp256r1Mlkem768ShareReuseFirst) { 282 EnsureKeyShareSetup(); 283 ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 284 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 285 286 Connect(); 287 288 CheckKEXDetails({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}, 289 {ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1}); 290 CheckECDHShareReuse(shares_capture_); 291 } 292 293 TEST_P(TlsKeyExchangeTest13, Secp256r1Mlkem768ShareReuseSecond) { 294 EnsureKeyShareSetup(); 295 ConfigNamedGroups({ssl_grp_ec_secp256r1, ssl_grp_kem_secp256r1mlkem768}); 296 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 297 298 Connect(); 299 300 CheckKEXDetails({ssl_grp_ec_secp256r1, ssl_grp_kem_secp256r1mlkem768}, 301 {ssl_grp_ec_secp256r1, ssl_grp_kem_secp256r1mlkem768}); 302 CheckECDHShareReuse(shares_capture_); 303 } 304 305 TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ShareReuseFirst) { 306 EnsureKeyShareSetup(); 307 ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1}); 308 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 309 310 Connect(); 311 312 CheckKEXDetails({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1}, 313 {ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1}); 314 CheckECDHShareReuse(shares_capture_); 315 } 316 317 TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ShareReuseSecond) { 318 EnsureKeyShareSetup(); 319 ConfigNamedGroups({ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024}); 320 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 321 322 Connect(); 323 324 CheckKEXDetails({ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024}, 325 {ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024}); 326 CheckECDHShareReuse(shares_capture_); 327 } 328 329 class Mlkem768x25519ShareDamager : public TlsExtensionFilter { 330 public: 331 typedef enum { 332 downgrade, 333 extend, 334 truncate, 335 zero_ecdh, 336 modify_ecdh, 337 modify_mlkem, 338 modify_mlkem_pubkey_mod_q, 339 } damage_type; 340 341 Mlkem768x25519ShareDamager(const std::shared_ptr<TlsAgent>& a, 342 damage_type damage) 343 : TlsExtensionFilter(a), damage_(damage) {} 344 345 virtual PacketFilter::Action FilterExtension(uint16_t extension_type, 346 const DataBuffer& input, 347 DataBuffer* output) { 348 if (extension_type != ssl_tls13_key_share_xtn) { 349 return KEEP; 350 } 351 352 // Find the Mlkem768x25519 share 353 size_t offset = 0; 354 if (agent()->role() == TlsAgent::CLIENT) { 355 offset += 2; // skip KeyShareClientHello length 356 } 357 358 uint32_t named_group; 359 uint32_t named_group_len; 360 input.Read(offset, 2, &named_group); 361 input.Read(offset + 2, 2, &named_group_len); 362 while (named_group != ssl_grp_kem_mlkem768x25519) { 363 offset += 2 + 2 + named_group_len; 364 input.Read(offset, 2, &named_group); 365 input.Read(offset + 2, 2, &named_group_len); 366 } 367 EXPECT_EQ(named_group, ssl_grp_kem_mlkem768x25519); 368 369 DataBuffer hybrid_key_share(input.data() + offset, 2 + 2 + named_group_len); 370 371 // Damage the Mlkem768x25519 share 372 uint32_t mlkem_component_len = 373 hybrid_key_share.len() - 2 - 2 - X25519_PUBLIC_KEY_BYTES; 374 unsigned char* ecdh_component = 375 hybrid_key_share.data() + 2 + 2 + mlkem_component_len; 376 unsigned char* mlkem_component = hybrid_key_share.data() + 2 + 2; 377 switch (damage_) { 378 case Mlkem768x25519ShareDamager::downgrade: 379 // Downgrade a Mlkem768x25519 share to X25519 380 memcpy(mlkem_component, ecdh_component, X25519_PUBLIC_KEY_BYTES); 381 hybrid_key_share.Truncate(2 + 2 + X25519_PUBLIC_KEY_BYTES); 382 hybrid_key_share.Write(0, ssl_grp_ec_curve25519, 2); 383 hybrid_key_share.Write(2, X25519_PUBLIC_KEY_BYTES, 2); 384 break; 385 case Mlkem768x25519ShareDamager::truncate: 386 // Truncate a Mlkem768x25519 share before the X25519 component 387 hybrid_key_share.Truncate(2 + 2 + mlkem_component_len); 388 hybrid_key_share.Write(2, mlkem_component_len, 2); 389 break; 390 case Mlkem768x25519ShareDamager::extend: 391 // Append 4 bytes to a Mlkem768x25519 share 392 uint32_t current_len; 393 hybrid_key_share.Read(2, 2, ¤t_len); 394 hybrid_key_share.Write(hybrid_key_share.len(), current_len, 4); 395 hybrid_key_share.Write(2, current_len + 4, 2); 396 break; 397 case Mlkem768x25519ShareDamager::zero_ecdh: 398 // Replace an X25519 component with 0s 399 memset(ecdh_component, 0, X25519_PUBLIC_KEY_BYTES); 400 break; 401 case Mlkem768x25519ShareDamager::modify_ecdh: 402 // Flip a bit in the X25519 component 403 ecdh_component[0] ^= 0x01; 404 break; 405 case Mlkem768x25519ShareDamager::modify_mlkem: 406 // Flip a bit in the mlkem component 407 mlkem_component[0] ^= 0x01; 408 break; 409 case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q: 410 if (agent()->role() == TlsAgent::CLIENT) { 411 // Replace the client's public key with an sequence of 12-bit values 412 // in the same equivalence class mod 3329. The FIPS-203 input 413 // validation check should fail. 414 for (size_t i = 0; i < mlkem_component_len - 32; i += 3) { 415 // Pairs of 12-bit coefficients are packed into 3 bytes. 416 // Unpack them, change equivalence class if possible, and repack. 417 uint16_t coeff0 = 418 mlkem_component[i] | ((mlkem_component[i + 1] & 0x0f) << 8); 419 uint16_t coeff1 = (mlkem_component[i + 1] & 0xf0 >> 4) | 420 ((mlkem_component[i + 2]) << 4); 421 if (coeff0 < 4096 - 3329) { 422 coeff0 += 3329; 423 } 424 if (coeff1 < 4096 - 3329) { 425 coeff1 += 3329; 426 } 427 mlkem_component[i] = coeff0; 428 mlkem_component[i + 1] = (coeff0 >> 8) + ((coeff1 & 0x0f) << 4); 429 mlkem_component[i + 2] = coeff1 >> 4; 430 } 431 } 432 break; 433 } 434 435 *output = input; 436 output->Splice(hybrid_key_share, offset, 2 + 2 + named_group_len); 437 438 // Fix the KeyShareClientHello length if necessary 439 if (agent()->role() == TlsAgent::CLIENT && 440 hybrid_key_share.len() != 2 + 2 + named_group_len) { 441 output->Write(0, output->len() - 2, 2); 442 } 443 444 return CHANGE; 445 } 446 447 private: 448 damage_type damage_; 449 }; 450 451 class TlsMlkem768x25519DamageTest 452 : public TlsConnectTestBase, 453 public ::testing::WithParamInterface< 454 Mlkem768x25519ShareDamager::damage_type> { 455 public: 456 TlsMlkem768x25519DamageTest() 457 : TlsConnectTestBase(ssl_variant_stream, SSL_LIBRARY_VERSION_TLS_1_3) {} 458 459 protected: 460 void Damage(const std::shared_ptr<TlsAgent>& agent) { 461 EnsureTlsSetup(); 462 client_->ConfigNamedGroups( 463 {ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519}); 464 server_->ConfigNamedGroups( 465 {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519}); 466 EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1)); 467 MakeTlsFilter<Mlkem768x25519ShareDamager>(agent, GetParam()); 468 } 469 }; 470 471 TEST_P(TlsMlkem768x25519DamageTest, DamageClientShare) { 472 Damage(client_); 473 474 switch (GetParam()) { 475 case Mlkem768x25519ShareDamager::extend: 476 case Mlkem768x25519ShareDamager::truncate: 477 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 478 server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE); 479 break; 480 case Mlkem768x25519ShareDamager::zero_ecdh: 481 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 482 server_->CheckErrorCode(SEC_ERROR_INVALID_KEY); 483 break; 484 case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q: 485 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 486 server_->CheckErrorCode(SEC_ERROR_INVALID_ARGS); 487 break; 488 case Mlkem768x25519ShareDamager::downgrade: 489 case Mlkem768x25519ShareDamager::modify_ecdh: 490 case Mlkem768x25519ShareDamager::modify_mlkem: 491 client_->ExpectSendAlert(kTlsAlertBadRecordMac); 492 server_->ExpectSendAlert(kTlsAlertBadRecordMac); 493 ConnectExpectFail(); 494 client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); 495 server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); 496 break; 497 } 498 } 499 500 TEST_P(TlsMlkem768x25519DamageTest, DamageServerShare) { 501 Damage(server_); 502 503 switch (GetParam()) { 504 case Mlkem768x25519ShareDamager::extend: 505 case Mlkem768x25519ShareDamager::truncate: 506 client_->ExpectSendAlert(kTlsAlertIllegalParameter); 507 server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); 508 ConnectExpectFail(); 509 client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE); 510 break; 511 case Mlkem768x25519ShareDamager::zero_ecdh: 512 client_->ExpectSendAlert(kTlsAlertIllegalParameter); 513 server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); 514 ConnectExpectFail(); 515 client_->CheckErrorCode(SEC_ERROR_INVALID_KEY); 516 break; 517 case Mlkem768x25519ShareDamager::downgrade: 518 case Mlkem768x25519ShareDamager::modify_ecdh: 519 case Mlkem768x25519ShareDamager::modify_mlkem: 520 client_->ExpectSendAlert(kTlsAlertBadRecordMac); 521 server_->ExpectSendAlert(kTlsAlertBadRecordMac); 522 ConnectExpectFail(); 523 client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); 524 server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); 525 break; 526 case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q: 527 // The server doesn't send a public key, so nothing is changed. 528 break; 529 } 530 } 531 532 INSTANTIATE_TEST_SUITE_P( 533 TlsMlkem768x25519DamageTest, TlsMlkem768x25519DamageTest, 534 ::testing::Values(Mlkem768x25519ShareDamager::downgrade, 535 Mlkem768x25519ShareDamager::extend, 536 Mlkem768x25519ShareDamager::truncate, 537 Mlkem768x25519ShareDamager::zero_ecdh, 538 Mlkem768x25519ShareDamager::modify_ecdh, 539 Mlkem768x25519ShareDamager::modify_mlkem, 540 Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q)); 541 542 } // namespace nss_test