| ... | ... | @@ -10,10 +10,8 @@ const Certificate = std.crypto.Certificate; |
| 10 | 10 | const max_ciphertext_len = tls.max_ciphertext_len; |
| 11 | 11 | const hmacExpandLabel = tls.hmacExpandLabel; |
| 12 | 12 | const hkdfExpandLabel = tls.hkdfExpandLabel; |
| 13 | | const int2 = tls.int2; |
| 14 | | const int3 = tls.int3; |
| 13 | const int = tls.int; |
| 15 | 14 | const array = tls.array; |
| 16 | | const enum_array = tls.enum_array; |
| 17 | 15 | |
| 18 | 16 | tls_version: tls.ProtocolVersion, |
| 19 | 17 | read_seq: u64, |
| ... | ... | @@ -156,70 +154,62 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 156 | 154 | error.IdentityElement => return error.InsufficientEntropy, |
| 157 | 155 | }; |
| 158 | 156 | |
| 159 | | const extensions_payload = |
| 160 | | tls.extension(.supported_versions, [_]u8{2 + 2} ++ // byte length of supported versions |
| 161 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_3)) ++ |
| 162 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2))) ++ |
| 163 | | tls.extension(.signature_algorithms, enum_array(tls.SignatureScheme, &.{ |
| 157 | const extensions_payload = tls.extension(.supported_versions, array(u8, tls.ProtocolVersion, .{ |
| 158 | .tls_1_3, |
| 159 | .tls_1_2, |
| 160 | })) ++ tls.extension(.signature_algorithms, array(u16, tls.SignatureScheme, .{ |
| 164 | 161 | .ecdsa_secp256r1_sha256, |
| 165 | 162 | .ecdsa_secp384r1_sha384, |
| 166 | 163 | .rsa_pss_rsae_sha256, |
| 167 | 164 | .rsa_pss_rsae_sha384, |
| 168 | 165 | .rsa_pss_rsae_sha512, |
| 169 | 166 | .ed25519, |
| 170 | | })) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{ |
| 167 | })) ++ tls.extension(.supported_groups, array(u16, tls.NamedGroup, .{ |
| 171 | 168 | .x25519_ml_kem768, |
| 172 | 169 | .secp256r1, |
| 173 | 170 | .x25519, |
| 174 | | })) ++ tls.extension( |
| 175 | | .key_share, |
| 176 | | array(1, int2(@intFromEnum(tls.NamedGroup.x25519)) ++ |
| 177 | | array(1, key_share.x25519_kp.public_key) ++ |
| 178 | | int2(@intFromEnum(tls.NamedGroup.secp256r1)) ++ |
| 179 | | array(1, key_share.secp256r1_kp.public_key.toUncompressedSec1()) ++ |
| 180 | | int2(@intFromEnum(tls.NamedGroup.x25519_ml_kem768)) ++ |
| 181 | | array(1, key_share.x25519_kp.public_key ++ key_share.ml_kem768_kp.public_key.toBytes())), |
| 182 | | ) ++ |
| 183 | | int2(@intFromEnum(tls.ExtensionType.server_name)) ++ |
| 184 | | int2(host_len + 5) ++ // byte length of this extension payload |
| 185 | | int2(host_len + 3) ++ // server_name_list byte count |
| 186 | | [1]u8{0x00} ++ // name_type |
| 187 | | int2(host_len); |
| 171 | })) ++ tls.extension(.psk_key_exchange_modes, array(u8, tls.PskKeyExchangeMode, .{ |
| 172 | .psk_dhe_ke, |
| 173 | })) ++ tls.extension(.key_share, array( |
| 174 | u16, |
| 175 | u8, |
| 176 | int(u16, @intFromEnum(tls.NamedGroup.x25519_ml_kem768)) ++ |
| 177 | array(u16, u8, key_share.ml_kem768_kp.public_key.toBytes() ++ key_share.x25519_kp.public_key) ++ |
| 178 | int(u16, @intFromEnum(tls.NamedGroup.secp256r1)) ++ |
| 179 | array(u16, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1()) ++ |
| 180 | int(u16, @intFromEnum(tls.NamedGroup.x25519)) ++ |
| 181 | array(u16, u8, key_share.x25519_kp.public_key), |
| 182 | )) ++ int(u16, @intFromEnum(tls.ExtensionType.server_name)) ++ |
| 183 | int(u16, 2 + 1 + 2 + host_len) ++ // byte length of this extension payload |
| 184 | int(u16, 1 + 2 + host_len) ++ // server_name_list byte count |
| 185 | .{0x00} ++ // name_type |
| 186 | int(u16, host_len); |
| 188 | 187 | |
| 189 | 188 | const extensions_header = |
| 190 | | int2(@intCast(extensions_payload.len + host_len)) ++ |
| 189 | int(u16, @intCast(extensions_payload.len + host_len)) ++ |
| 191 | 190 | extensions_payload; |
| 192 | 191 | |
| 193 | | const legacy_compression_methods = 0x0100; |
| 194 | | |
| 195 | 192 | const client_hello = |
| 196 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 193 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 197 | 194 | client_hello_rand ++ |
| 198 | 195 | [1]u8{32} ++ legacy_session_id ++ |
| 199 | 196 | cipher_suites ++ |
| 200 | | int2(legacy_compression_methods) ++ |
| 197 | array(u8, tls.CompressionMethod, .{.null}) ++ |
| 201 | 198 | extensions_header; |
| 202 | 199 | |
| 203 | | const out_handshake = |
| 204 | | [_]u8{@intFromEnum(tls.HandshakeType.client_hello)} ++ |
| 205 | | int3(@intCast(client_hello.len + host_len)) ++ |
| 200 | const out_handshake = .{@intFromEnum(tls.HandshakeType.client_hello)} ++ |
| 201 | int(u24, @intCast(client_hello.len + host_len)) ++ |
| 206 | 202 | client_hello; |
| 207 | 203 | |
| 208 | | const cleartext_header = [_]u8{@intFromEnum(tls.ContentType.handshake)} ++ |
| 209 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_0)) ++ // legacy_record_version |
| 210 | | int2(@intCast(out_handshake.len + host_len)) ++ |
| 204 | const cleartext_header = .{@intFromEnum(tls.ContentType.handshake)} ++ |
| 205 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_0)) ++ |
| 206 | int(u16, @intCast(out_handshake.len + host_len)) ++ |
| 211 | 207 | out_handshake; |
| 212 | 208 | |
| 213 | 209 | { |
| 214 | 210 | var iovecs = [_]std.posix.iovec_const{ |
| 215 | | .{ |
| 216 | | .base = &cleartext_header, |
| 217 | | .len = cleartext_header.len, |
| 218 | | }, |
| 219 | | .{ |
| 220 | | .base = host.ptr, |
| 221 | | .len = host.len, |
| 222 | | }, |
| 211 | .{ .base = &cleartext_header, .len = cleartext_header.len }, |
| 212 | .{ .base = host.ptr, .len = host.len }, |
| 223 | 213 | }; |
| 224 | 214 | try stream.writevAll(&iovecs); |
| 225 | 215 | } |
| ... | ... | @@ -526,7 +516,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 526 | 516 | }, |
| 527 | 517 | .change_cipher_spec => { |
| 528 | 518 | try ctd.ensure(1); |
| 529 | | if (ctd.decode(u8) != 0x01) return error.TlsIllegalParameter; |
| 519 | if (ctd.decode(tls.ChangeCipherSpecType) != .change_cipher_spec) return error.TlsIllegalParameter; |
| 530 | 520 | cipher_state = pending_cipher_state; |
| 531 | 521 | }, |
| 532 | 522 | .handshake => while (true) { |
| ... | ... | @@ -648,20 +638,13 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 648 | 638 | if (handshake_state != .server_hello_done) return error.TlsUnexpectedMessage; |
| 649 | 639 | handshake_state = .finished; |
| 650 | 640 | |
| 651 | | const client_key_exchange_msg = |
| 652 | | [_]u8{@intFromEnum(tls.ContentType.handshake)} ++ // record content type |
| 653 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ // legacy protocol version |
| 654 | | int2(0x46) ++ // record length |
| 655 | | .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++ // handshake type |
| 656 | | int3(0x42) ++ // params length |
| 657 | | .{0x41} ++ // pubkey length |
| 658 | | key_share.secp256r1_kp.public_key.toUncompressedSec1(); |
| 659 | | // This message is to trick buggy proxies into behaving correctly. |
| 660 | | const client_change_cipher_spec_msg = |
| 661 | | [_]u8{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ // record content type |
| 662 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ // legacy protocol version |
| 663 | | int2(1) ++ // record length |
| 664 | | .{0x01}; |
| 641 | const client_key_exchange_msg = .{@intFromEnum(tls.ContentType.handshake)} ++ |
| 642 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 643 | array(u16, u8, .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++ |
| 644 | array(u24, u8, array(u8, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1()))); |
| 645 | const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ |
| 646 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 647 | array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec}); |
| 665 | 648 | const pre_master_secret = key_share.getSharedSecret().?; |
| 666 | 649 | switch (handshake_cipher) { |
| 667 | 650 | inline else => |*p| { |
| ... | ... | @@ -680,10 +663,13 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 680 | 663 | @sizeOf(P.Tls_1_2), |
| 681 | 664 | ); |
| 682 | 665 | const verify_data_len = 12; |
| 683 | | const client_verify_cleartext = |
| 684 | | [_]u8{@intFromEnum(tls.HandshakeType.finished)} ++ // handshake type |
| 685 | | int3(verify_data_len) ++ // verify data length |
| 686 | | hmacExpandLabel(P.Hmac, &master_secret, &.{ "client finished", &p.transcript_hash.peek() }, verify_data_len); |
| 666 | const client_verify_cleartext = .{@intFromEnum(tls.HandshakeType.finished)} ++ |
| 667 | array(u24, u8, hmacExpandLabel( |
| 668 | P.Hmac, |
| 669 | &master_secret, |
| 670 | &.{ "client finished", &p.transcript_hash.peek() }, |
| 671 | verify_data_len, |
| 672 | )); |
| 687 | 673 | p.transcript_hash.update(&client_verify_cleartext); |
| 688 | 674 | p.version = .{ .tls_1_2 = .{ |
| 689 | 675 | .server_verify_data = hmacExpandLabel( |
| ... | ... | @@ -709,25 +695,23 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 709 | 695 | const operand: V = pad ++ @as([8]u8, @bitCast(big(write_seq))); |
| 710 | 696 | break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand; |
| 711 | 697 | }; |
| 712 | | var client_verify_msg = [_]u8{@intFromEnum(tls.ContentType.handshake)} ++ // record content type |
| 713 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ // legacy protocol version |
| 714 | | int2(P.record_iv_length + client_verify_cleartext.len + P.mac_length) ++ // record length |
| 715 | | nonce[P.fixed_iv_length..].* ++ |
| 716 | | @as([client_verify_cleartext.len + P.mac_length]u8, undefined); |
| 698 | var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++ |
| 699 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 700 | array(u16, u8, nonce[P.fixed_iv_length..].* ++ |
| 701 | @as([client_verify_cleartext.len + P.mac_length]u8, undefined)); |
| 717 | 702 | P.AEAD.encrypt( |
| 718 | 703 | client_verify_msg[client_verify_msg.len - P.mac_length - |
| 719 | 704 | client_verify_cleartext.len ..][0..client_verify_cleartext.len], |
| 720 | 705 | client_verify_msg[client_verify_msg.len - P.mac_length ..][0..P.mac_length], |
| 721 | 706 | &client_verify_cleartext, |
| 722 | | std.mem.toBytes(big(write_seq)) ++ client_verify_msg[0 .. 1 + 2] ++ int2(client_verify_cleartext.len), |
| 707 | std.mem.toBytes(big(write_seq)) ++ client_verify_msg[0 .. 1 + 2] ++ int(u16, client_verify_cleartext.len), |
| 723 | 708 | nonce, |
| 724 | 709 | pv.app_cipher.client_write_key, |
| 725 | 710 | ); |
| 726 | 711 | const all_msgs = client_key_exchange_msg ++ client_change_cipher_spec_msg ++ client_verify_msg; |
| 727 | | var all_msgs_vec = [_]std.posix.iovec_const{.{ |
| 728 | | .base = &all_msgs, |
| 729 | | .len = all_msgs.len, |
| 730 | | }}; |
| 712 | var all_msgs_vec = [_]std.posix.iovec_const{ |
| 713 | .{ .base = &all_msgs, .len = all_msgs.len }, |
| 714 | }; |
| 731 | 715 | try stream.writevAll(&all_msgs_vec); |
| 732 | 716 | }, |
| 733 | 717 | } |
| ... | ... | @@ -755,11 +739,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 755 | 739 | if (cipher_state == .cleartext) return error.TlsUnexpectedMessage; |
| 756 | 740 | if (handshake_state != .finished) return error.TlsUnexpectedMessage; |
| 757 | 741 | // This message is to trick buggy proxies into behaving correctly. |
| 758 | | const client_change_cipher_spec_msg = |
| 759 | | [_]u8{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ |
| 760 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ // legacy protocol version |
| 761 | | int2(1) ++ // length |
| 762 | | .{0x01}; |
| 742 | const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ |
| 743 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 744 | array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec}); |
| 763 | 745 | const app_cipher = app_cipher: switch (handshake_cipher) { |
| 764 | 746 | inline else => |*p, tag| switch (tls_version) { |
| 765 | 747 | .tls_1_3 => { |
| ... | ... | @@ -771,17 +753,15 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 771 | 753 | if (!mem.eql(u8, &expected_server_verify_data, hsd.buf)) return error.TlsDecryptError; |
| 772 | 754 | const handshake_hash = p.transcript_hash.finalResult(); |
| 773 | 755 | const verify_data = tls.hmac(P.Hmac, &handshake_hash, pv.client_finished_key); |
| 774 | | const out_cleartext = [_]u8{ |
| 775 | | @intFromEnum(tls.HandshakeType.finished), |
| 776 | | 0, 0, verify_data.len, // length |
| 777 | | } ++ verify_data ++ [1]u8{@intFromEnum(tls.ContentType.handshake)}; |
| 756 | const out_cleartext = .{@intFromEnum(tls.HandshakeType.finished)} ++ |
| 757 | array(u24, u8, verify_data) ++ |
| 758 | .{@intFromEnum(tls.ContentType.handshake)}; |
| 778 | 759 | |
| 779 | 760 | const wrapped_len = out_cleartext.len + P.AEAD.tag_length; |
| 780 | 761 | |
| 781 | | var finished_msg = [_]u8{@intFromEnum(tls.ContentType.application_data)} ++ |
| 782 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ // legacy protocol version |
| 783 | | int2(wrapped_len) ++ // byte length of encrypted record |
| 784 | | @as([wrapped_len]u8, undefined); |
| 762 | var finished_msg = .{@intFromEnum(tls.ContentType.application_data)} ++ |
| 763 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 764 | array(u16, u8, @as([wrapped_len]u8, undefined)); |
| 785 | 765 | |
| 786 | 766 | const ad = finished_msg[0..tls.record_header_len]; |
| 787 | 767 | const ciphertext = finished_msg[tls.record_header_len..][0..out_cleartext.len]; |
| ... | ... | @@ -790,10 +770,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 790 | 770 | P.AEAD.encrypt(ciphertext, auth_tag, &out_cleartext, ad, nonce, pv.client_handshake_key); |
| 791 | 771 | |
| 792 | 772 | const all_msgs = client_change_cipher_spec_msg ++ finished_msg; |
| 793 | | var all_msgs_vec = [_]std.posix.iovec_const{.{ |
| 794 | | .base = &all_msgs, |
| 795 | | .len = all_msgs.len, |
| 796 | | }}; |
| 773 | var all_msgs_vec = [_]std.posix.iovec_const{ |
| 774 | .{ .base = &all_msgs, .len = all_msgs.len }, |
| 775 | }; |
| 797 | 776 | try stream.writevAll(&all_msgs_vec); |
| 798 | 777 | |
| 799 | 778 | const client_secret = hkdfExpandLabel(P.Hkdf, pv.master_secret, "c ap traffic", &handshake_hash, P.Hash.digest_length); |
| ... | ... | @@ -965,10 +944,9 @@ fn prepareCiphertextRecord( |
| 965 | 944 | |
| 966 | 945 | const record_start = ciphertext_end; |
| 967 | 946 | const ad = ciphertext_buf[ciphertext_end..][0..tls.record_header_len]; |
| 968 | | ad.* = |
| 969 | | [_]u8{@intFromEnum(tls.ContentType.application_data)} ++ |
| 970 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 971 | | int2(ciphertext_len + P.AEAD.tag_length); |
| 947 | ad.* = .{@intFromEnum(tls.ContentType.application_data)} ++ |
| 948 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 949 | int(u16, ciphertext_len + P.AEAD.tag_length); |
| 972 | 950 | ciphertext_end += ad.len; |
| 973 | 951 | const ciphertext = ciphertext_buf[ciphertext_end..][0..ciphertext_len]; |
| 974 | 952 | ciphertext_end += ciphertext_len; |
| ... | ... | @@ -1023,10 +1001,10 @@ fn prepareCiphertextRecord( |
| 1023 | 1001 | const record_start = ciphertext_end; |
| 1024 | 1002 | const record_header = ciphertext_buf[ciphertext_end..][0..tls.record_header_len]; |
| 1025 | 1003 | ciphertext_end += tls.record_header_len; |
| 1026 | | record_header.* = [_]u8{@intFromEnum(inner_content_type)} ++ |
| 1027 | | int2(@intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 1028 | | int2(P.record_iv_length + message_len + P.mac_length); |
| 1029 | | const ad = std.mem.toBytes(big(c.write_seq)) ++ record_header[0 .. 1 + 2] ++ int2(message_len); |
| 1004 | record_header.* = .{@intFromEnum(inner_content_type)} ++ |
| 1005 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 1006 | int(u16, P.record_iv_length + message_len + P.mac_length); |
| 1007 | const ad = std.mem.toBytes(big(c.write_seq)) ++ record_header[0 .. 1 + 2] ++ int(u16, message_len); |
| 1030 | 1008 | const record_iv = ciphertext_buf[ciphertext_end..][0..P.record_iv_length]; |
| 1031 | 1009 | ciphertext_end += P.record_iv_length; |
| 1032 | 1010 | const nonce: [P.AEAD.nonce_length]u8 = if (builtin.zig_backend == .stage2_x86_64 and |
| ... | ... | @@ -1569,25 +1547,17 @@ const KeyShare = struct { |
| 1569 | 1547 | ) error{ TlsIllegalParameter, TlsDecryptFailure }!void { |
| 1570 | 1548 | switch (named_group) { |
| 1571 | 1549 | .x25519_ml_kem768 => { |
| 1572 | | const xksl = crypto.dh.X25519.public_length; |
| 1573 | | const hksl = xksl + crypto.kem.ml_kem.MLKem768.ciphertext_length; |
| 1574 | | if (server_pub_key.len != hksl) return error.TlsIllegalParameter; |
| 1550 | const hksl = crypto.kem.ml_kem.MLKem768.ciphertext_length; |
| 1551 | const xksl = hksl + crypto.dh.X25519.public_length; |
| 1552 | if (server_pub_key.len != xksl) return error.TlsIllegalParameter; |
| 1575 | 1553 | |
| 1576 | | const xsk = crypto.dh.X25519.scalarmult(ks.x25519_kp.secret_key, server_pub_key[0..xksl].*) catch |
| 1554 | const hsk = ks.ml_kem768_kp.secret_key.decaps(server_pub_key[0..hksl]) catch |
| 1577 | 1555 | return error.TlsDecryptFailure; |
| 1578 | | const hsk = ks.ml_kem768_kp.secret_key.decaps(server_pub_key[xksl..hksl]) catch |
| 1556 | const xsk = crypto.dh.X25519.scalarmult(ks.x25519_kp.secret_key, server_pub_key[hksl..xksl].*) catch |
| 1579 | 1557 | return error.TlsDecryptFailure; |
| 1580 | | @memcpy(ks.sk_buf[0..xsk.len], &xsk); |
| 1581 | | @memcpy(ks.sk_buf[xsk.len..][0..hsk.len], &hsk); |
| 1582 | | ks.sk_len = xsk.len + hsk.len; |
| 1583 | | }, |
| 1584 | | .x25519 => { |
| 1585 | | const ksl = crypto.dh.X25519.public_length; |
| 1586 | | if (server_pub_key.len != ksl) return error.TlsIllegalParameter; |
| 1587 | | const sk = crypto.dh.X25519.scalarmult(ks.x25519_kp.secret_key, server_pub_key[0..ksl].*) catch |
| 1588 | | return error.TlsDecryptFailure; |
| 1589 | | @memcpy(ks.sk_buf[0..sk.len], &sk); |
| 1590 | | ks.sk_len = sk.len; |
| 1558 | @memcpy(ks.sk_buf[0..hsk.len], &hsk); |
| 1559 | @memcpy(ks.sk_buf[hsk.len..][0..xsk.len], &xsk); |
| 1560 | ks.sk_len = hsk.len + xsk.len; |
| 1591 | 1561 | }, |
| 1592 | 1562 | .secp256r1 => { |
| 1593 | 1563 | const PublicKey = crypto.sign.ecdsa.EcdsaP256Sha256.PublicKey; |
| ... | ... | @@ -1598,6 +1568,14 @@ const KeyShare = struct { |
| 1598 | 1568 | @memcpy(ks.sk_buf[0..sk.len], &sk); |
| 1599 | 1569 | ks.sk_len = sk.len; |
| 1600 | 1570 | }, |
| 1571 | .x25519 => { |
| 1572 | const ksl = crypto.dh.X25519.public_length; |
| 1573 | if (server_pub_key.len != ksl) return error.TlsIllegalParameter; |
| 1574 | const sk = crypto.dh.X25519.scalarmult(ks.x25519_kp.secret_key, server_pub_key[0..ksl].*) catch |
| 1575 | return error.TlsDecryptFailure; |
| 1576 | @memcpy(ks.sk_buf[0..sk.len], &sk); |
| 1577 | ks.sk_len = sk.len; |
| 1578 | }, |
| 1601 | 1579 | else => return error.TlsIllegalParameter, |
| 1602 | 1580 | } |
| 1603 | 1581 | } |
| ... | ... | @@ -1877,7 +1855,7 @@ fn limitVecs(iovecs: []std.posix.iovec, len: usize) []std.posix.iovec { |
| 1877 | 1855 | /// aes128-gcm: 138 MiB/s |
| 1878 | 1856 | /// aes256-gcm: 120 MiB/s |
| 1879 | 1857 | const cipher_suites = if (crypto.core.aes.has_hardware_support) |
| 1880 | | enum_array(tls.CipherSuite, &.{ |
| 1858 | array(u16, tls.CipherSuite, .{ |
| 1881 | 1859 | .AEGIS_128L_SHA256, |
| 1882 | 1860 | .AEGIS_256_SHA512, |
| 1883 | 1861 | .AES_128_GCM_SHA256, |
| ... | ... | @@ -1888,7 +1866,7 @@ const cipher_suites = if (crypto.core.aes.has_hardware_support) |
| 1888 | 1866 | .ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 1889 | 1867 | }) |
| 1890 | 1868 | else |
| 1891 | | enum_array(tls.CipherSuite, &.{ |
| 1869 | array(u16, tls.CipherSuite, .{ |
| 1892 | 1870 | .CHACHA20_POLY1305_SHA256, |
| 1893 | 1871 | .ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
| 1894 | 1872 | .AEGIS_128L_SHA256, |