authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-11-06 00:14:27-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-11-07 20:25:26-05:00
log75adba7cb9501f33453275c187bcd7f4b11eaa9d
treed895e1c2b7e79a6390dca57407922280b062b699
parenta4e88abf042f89cf98ff0b54dfe82eb3ad6eaa0b

std.crypto.tls: add support for secp384r1 key share


1 files changed, 23 insertions(+), 8 deletions(-)

lib/std/crypto/tls/Client.zig+23-8
...@@ -191,14 +191,14 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -191,14 +191,14 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
191 };191 };
192 const host_len: u16 = @intCast(host.len);192 const host_len: u16 = @intCast(host.len);
193193
194 var random_buffer: [128]u8 = undefined;194 var random_buffer: [176]u8 = undefined;
195 crypto.random.bytes(&random_buffer);195 crypto.random.bytes(&random_buffer);
196 const client_hello_rand = random_buffer[0..32].*;196 const client_hello_rand = random_buffer[0..32].*;
197 var key_seq: u64 = 0;197 var key_seq: u64 = 0;
198 var server_hello_rand: [32]u8 = undefined;198 var server_hello_rand: [32]u8 = undefined;
199 const legacy_session_id = random_buffer[32..64].*;199 const legacy_session_id = random_buffer[32..64].*;
200200
201 var key_share = KeyShare.init(random_buffer[64..128].*) catch |err| switch (err) {201 var key_share = KeyShare.init(random_buffer[64..176].*) catch |err| switch (err) {
202 // Only possible to happen if the seed is all zeroes.202 // Only possible to happen if the seed is all zeroes.
203 error.IdentityElement => return error.InsufficientEntropy,203 error.IdentityElement => return error.InsufficientEntropy,
204 };204 };
...@@ -223,6 +223,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -223,6 +223,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
223 })) ++ tls.extension(.supported_groups, array(u16, tls.NamedGroup, .{223 })) ++ tls.extension(.supported_groups, array(u16, tls.NamedGroup, .{
224 .x25519_ml_kem768,224 .x25519_ml_kem768,
225 .secp256r1,225 .secp256r1,
226 .secp384r1,
226 .x25519,227 .x25519,
227 })) ++ tls.extension(.psk_key_exchange_modes, array(u8, tls.PskKeyExchangeMode, .{228 })) ++ tls.extension(.psk_key_exchange_modes, array(u8, tls.PskKeyExchangeMode, .{
228 .psk_dhe_ke,229 .psk_dhe_ke,
...@@ -233,6 +234,8 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -233,6 +234,8 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
233 array(u16, u8, key_share.ml_kem768_kp.public_key.toBytes() ++ key_share.x25519_kp.public_key) ++234 array(u16, u8, key_share.ml_kem768_kp.public_key.toBytes() ++ key_share.x25519_kp.public_key) ++
234 int(u16, @intFromEnum(tls.NamedGroup.secp256r1)) ++235 int(u16, @intFromEnum(tls.NamedGroup.secp256r1)) ++
235 array(u16, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1()) ++236 array(u16, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1()) ++
237 int(u16, @intFromEnum(tls.NamedGroup.secp384r1)) ++
238 array(u16, u8, key_share.secp384r1_kp.public_key.toUncompressedSec1()) ++
236 int(u16, @intFromEnum(tls.NamedGroup.x25519)) ++239 int(u16, @intFromEnum(tls.NamedGroup.x25519)) ++
237 array(u16, u8, key_share.x25519_kp.public_key),240 array(u16, u8, key_share.x25519_kp.public_key),
238 ));241 ));
...@@ -1630,23 +1633,26 @@ inline fn big(x: anytype) @TypeOf(x) {...@@ -1630,23 +1633,26 @@ inline fn big(x: anytype) @TypeOf(x) {
1630}1633}
16311634
1632const KeyShare = struct {1635const KeyShare = struct {
1633 x25519_kp: crypto.dh.X25519.KeyPair,
1634 secp256r1_kp: crypto.sign.ecdsa.EcdsaP256Sha256.KeyPair,
1635 ml_kem768_kp: crypto.kem.ml_kem.MLKem768.KeyPair,1636 ml_kem768_kp: crypto.kem.ml_kem.MLKem768.KeyPair,
1637 secp256r1_kp: crypto.sign.ecdsa.EcdsaP256Sha256.KeyPair,
1638 secp384r1_kp: crypto.sign.ecdsa.EcdsaP384Sha384.KeyPair,
1639 x25519_kp: crypto.dh.X25519.KeyPair,
1636 sk_buf: [sk_max_len]u8,1640 sk_buf: [sk_max_len]u8,
1637 sk_len: std.math.IntFittingRange(0, sk_max_len),1641 sk_len: std.math.IntFittingRange(0, sk_max_len),
16381642
1639 const sk_max_len = @max(1643 const sk_max_len = @max(
1640 crypto.dh.X25519.shared_length + crypto.kem.ml_kem.MLKem768.shared_length,1644 crypto.dh.X25519.shared_length + crypto.kem.ml_kem.MLKem768.shared_length,
1641 crypto.dh.X25519.shared_length,
1642 crypto.ecc.P256.scalar.encoded_length,1645 crypto.ecc.P256.scalar.encoded_length,
1646 crypto.ecc.P384.scalar.encoded_length,
1647 crypto.dh.X25519.shared_length,
1643 );1648 );
16441649
1645 fn init(seed: [64]u8) error{IdentityElement}!KeyShare {1650 fn init(seed: [112]u8) error{IdentityElement}!KeyShare {
1646 return .{1651 return .{
1647 .x25519_kp = try .create(seed[0..32].*),
1648 .secp256r1_kp = try .create(seed[32..64].*),
1649 .ml_kem768_kp = try .create(null),1652 .ml_kem768_kp = try .create(null),
1653 .secp256r1_kp = try .create(seed[0..32].*),
1654 .secp384r1_kp = try .create(seed[32..80].*),
1655 .x25519_kp = try .create(seed[80..112].*),
1650 .sk_buf = undefined,1656 .sk_buf = undefined,
1651 .sk_len = 0,1657 .sk_len = 0,
1652 };1658 };
...@@ -1680,6 +1686,15 @@ const KeyShare = struct {...@@ -1680,6 +1686,15 @@ const KeyShare = struct {
1680 @memcpy(ks.sk_buf[0..sk.len], &sk);1686 @memcpy(ks.sk_buf[0..sk.len], &sk);
1681 ks.sk_len = sk.len;1687 ks.sk_len = sk.len;
1682 },1688 },
1689 .secp384r1 => {
1690 const PublicKey = crypto.sign.ecdsa.EcdsaP384Sha384.PublicKey;
1691 const pk = PublicKey.fromSec1(server_pub_key) catch return error.TlsDecryptFailure;
1692 const mul = pk.p.mulPublic(ks.secp384r1_kp.secret_key.bytes, .big) catch
1693 return error.TlsDecryptFailure;
1694 const sk = mul.affineCoordinates().x.toBytes(.big);
1695 @memcpy(ks.sk_buf[0..sk.len], &sk);
1696 ks.sk_len = sk.len;
1697 },
1683 .x25519 => {1698 .x25519 => {
1684 const ksl = crypto.dh.X25519.public_length;1699 const ksl = crypto.dh.X25519.public_length;
1685 if (server_pub_key.len != ksl) return error.TlsIllegalParameter;1700 if (server_pub_key.len != ksl) return error.TlsIllegalParameter;