| ... | ... | @@ -158,6 +158,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 158 | 158 | // Only possible to happen if the private key is all zeroes. |
| 159 | 159 | error.IdentityElement => return error.InsufficientEntropy, |
| 160 | 160 | }; |
| 161 | const kyber768_kp = crypto.kem.kyber_d00.Kyber768.KeyPair.create(null) catch {}; |
| 161 | 162 | |
| 162 | 163 | const extensions_payload = |
| 163 | 164 | tls.extension(.supported_versions, [_]u8{ |
| ... | ... | @@ -175,6 +176,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 175 | 176 | .rsa_pkcs1_sha512, |
| 176 | 177 | .ed25519, |
| 177 | 178 | })) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{ |
| 179 | .x25519_kyber768d00, |
| 178 | 180 | .secp256r1, |
| 179 | 181 | .x25519, |
| 180 | 182 | })) ++ tls.extension( |
| ... | ... | @@ -182,7 +184,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 182 | 184 | array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++ |
| 183 | 185 | array(1, x25519_kp.public_key) ++ |
| 184 | 186 | int2(@enumToInt(tls.NamedGroup.secp256r1)) ++ |
| 185 | | array(1, secp256r1_kp.public_key.toUncompressedSec1())), |
| 187 | array(1, secp256r1_kp.public_key.toUncompressedSec1()) ++ |
| 188 | int2(@enumToInt(tls.NamedGroup.x25519_kyber768d00)) ++ |
| 189 | array(1, x25519_kp.public_key ++ kyber768_kp.public_key.toBytes())), |
| 186 | 190 | ) ++ |
| 187 | 191 | int2(@enumToInt(tls.ExtensionType.server_name)) ++ |
| 188 | 192 | int2(host_len + 5) ++ // byte length of this extension payload |
| ... | ... | @@ -274,7 +278,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 274 | 278 | const extensions_size = hsd.decode(u16); |
| 275 | 279 | var all_extd = try hsd.sub(extensions_size); |
| 276 | 280 | var supported_version: u16 = 0; |
| 277 | | var shared_key: [32]u8 = undefined; |
| 281 | var shared_key: []const u8 = undefined; |
| 278 | 282 | var have_shared_key = false; |
| 279 | 283 | while (!all_extd.eof()) { |
| 280 | 284 | try all_extd.ensure(2 + 2); |
| ... | ... | @@ -295,14 +299,29 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 295 | 299 | const key_size = extd.decode(u16); |
| 296 | 300 | try extd.ensure(key_size); |
| 297 | 301 | switch (named_group) { |
| 302 | .x25519_kyber768d00 => { |
| 303 | const xksl = crypto.dh.X25519.public_length; |
| 304 | const hksl = xksl + crypto.kem.kyber_d00.Kyber768.ciphertext_length; |
| 305 | if (key_size != hksl) |
| 306 | return error.TlsIllegalParameter; |
| 307 | const server_ks = extd.array(hksl); |
| 308 | |
| 309 | shared_key = &((crypto.dh.X25519.scalarmult( |
| 310 | x25519_kp.secret_key, |
| 311 | server_ks[0..xksl].*, |
| 312 | ) catch return error.TlsDecryptFailure) ++ (kyber768_kp.secret_key.decaps( |
| 313 | server_ks[xksl..hksl], |
| 314 | ) catch return error.TlsDecryptFailure)); |
| 315 | }, |
| 298 | 316 | .x25519 => { |
| 299 | | if (key_size != 32) return error.TlsIllegalParameter; |
| 300 | | const server_pub_key = extd.array(32); |
| 317 | const ksl = crypto.dh.X25519.public_length; |
| 318 | if (key_size != ksl) return error.TlsIllegalParameter; |
| 319 | const server_pub_key = extd.array(ksl); |
| 301 | 320 | |
| 302 | | shared_key = crypto.dh.X25519.scalarmult( |
| 321 | shared_key = &(crypto.dh.X25519.scalarmult( |
| 303 | 322 | x25519_kp.secret_key, |
| 304 | 323 | server_pub_key.*, |
| 305 | | ) catch return error.TlsDecryptFailure; |
| 324 | ) catch return error.TlsDecryptFailure); |
| 306 | 325 | }, |
| 307 | 326 | .secp256r1 => { |
| 308 | 327 | const server_pub_key = extd.slice(key_size); |
| ... | ... | @@ -314,7 +333,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 314 | 333 | const mul = pk.p.mulPublic(secp256r1_kp.secret_key.bytes, .Big) catch { |
| 315 | 334 | return error.TlsDecryptFailure; |
| 316 | 335 | }; |
| 317 | | shared_key = mul.affineCoordinates().x.toBytes(.Big); |
| 336 | shared_key = &mul.affineCoordinates().x.toBytes(.Big); |
| 318 | 337 | }, |
| 319 | 338 | else => { |
| 320 | 339 | return error.TlsIllegalParameter; |
| ... | ... | @@ -358,7 +377,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 358 | 377 | const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes); |
| 359 | 378 | const empty_hash = tls.emptyHash(P.Hash); |
| 360 | 379 | const hs_derived_secret = hkdfExpandLabel(P.Hkdf, early_secret, "derived", &empty_hash, P.Hash.digest_length); |
| 361 | | p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, &shared_key); |
| 380 | p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, shared_key); |
| 362 | 381 | const ap_derived_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "derived", &empty_hash, P.Hash.digest_length); |
| 363 | 382 | p.master_secret = P.Hkdf.extract(&ap_derived_secret, &zeroes); |
| 364 | 383 | const client_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "c hs traffic", &hello_hash, P.Hash.digest_length); |