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