@@ -182,6 +182,12 @@ pub const Cipher = union(CipherSuite) {
182182 };
183183 }
184184
185+ pub fn recordLen (c : * Cipher , cleartext_len : usize ) usize {
186+ return switch (c .* ) {
187+ inline else = > | * f | f .recordLen (cleartext_len ),
188+ };
189+ }
190+
185191 pub fn encryptSeq (c : Cipher ) u64 {
186192 return switch (c ) {
187193 inline else = > | f | f .encrypt_seq ,
@@ -276,6 +282,10 @@ fn Aead12Type(comptime AeadType: type) type {
276282 return buf [0.. record_len ];
277283 }
278284
285+ pub fn recordLen (_ : Self , cleartext_len : usize ) usize {
286+ return record .header_len + explicit_iv_len + cleartext_len + auth_tag_len ;
287+ }
288+
279289 /// Decrypts payload into cleartext. Returns tls record content type and
280290 /// cleartext.
281291 /// Accepts tls record header and payload:
@@ -362,6 +372,10 @@ fn Aead12ChaChaType(comptime AeadType: type) type {
362372 return buf [0.. record_len ];
363373 }
364374
375+ pub fn recordLen (_ : Self , cleartext_len : usize ) usize {
376+ return record .header_len + cleartext_len + auth_tag_len ;
377+ }
378+
365379 /// Decrypts payload into cleartext. Returns tls record content type and
366380 /// cleartext.
367381 /// Accepts tls record header and payload:
@@ -478,6 +492,11 @@ fn Aead13Type(comptime AeadType: type, comptime Hash: type) type {
478492 return buf [0.. record_len ];
479493 }
480494
495+ pub fn recordLen (_ : Self , cleartext_len : usize ) usize {
496+ const payload_len = cleartext_len + 1 + auth_tag_len ;
497+ return record .header_len + payload_len ;
498+ }
499+
481500 /// Decrypts payload into cleartext. Returns tls record content type and
482501 /// cleartext.
483502 /// Accepts tls record header and payload:
@@ -569,8 +588,7 @@ fn CbcType(comptime BlockCipher: type, comptime HashType: type) type {
569588 content_type : proto.ContentType ,
570589 cleartext : []const u8 ,
571590 ) ! []const u8 {
572- const max_record_len = record .header_len + iv_len + cleartext .len + mac_len + max_padding ;
573- if (buf .len < max_record_len ) return error .BufferOverflow ;
591+ if (buf .len < self .recordLen (cleartext .len )) return error .BufferOverflow ;
574592 const cleartext_idx = record .header_len + iv_len ; // position of cleartext in buf
575593 @memcpy (buf [cleartext_idx .. ][0.. cleartext .len ], cleartext );
576594
@@ -607,6 +625,12 @@ fn CbcType(comptime BlockCipher: type, comptime HashType: type) type {
607625 return buf [0 .. record .header_len + iv_len + ciphertext .len ];
608626 }
609627
628+ pub fn recordLen (_ : Self , cleartext_len : usize ) usize {
629+ const unpadded_len = cleartext_len + mac_len ;
630+ const padded_len = paddedLength (unpadded_len );
631+ return record .header_len + iv_len + padded_len ;
632+ }
633+
610634 /// Decrypts payload into cleartext. Returns tls record content type and
611635 /// cleartext.
612636 pub fn decrypt (
@@ -678,7 +702,7 @@ fn additionalData(seq: u64, content_type: proto.ContentType, payload_len: usize)
678702// https://ciphersuite.info/page/faq/
679703// https://github.com/golang/go/blob/73186ba00251b3ed8baaab36e4f5278c7681155b/src/crypto/tls/cipher_suites.go#L226
680704pub const cipher_suites = struct {
681- const tls12_secure = if (crypto .core .aes .has_hardware_support ) [_ ]CipherSuite {
705+ pub const tls12_secure = if (crypto .core .aes .has_hardware_support ) [_ ]CipherSuite {
682706 // recommended
683707 .ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ,
684708 .ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ,
@@ -698,7 +722,7 @@ pub const cipher_suites = struct {
698722 .ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
699723 .ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
700724 };
701- const tls12_week = [_ ]CipherSuite {
725+ pub const tls12_week = [_ ]CipherSuite {
702726 // week
703727 .ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,
704728 .ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ,
@@ -988,6 +1012,7 @@ fn encryptDecrypt(client_cipher: *Cipher, server_cipher: *Cipher) !void {
9881012 };
9891013 },
9901014 };
1015+ try testing .expectEqual (client_cipher .recordLen (cleartext .len ), encrypted .len );
9911016 try testing .expectEqual (expected_encrypted_len , encrypted .len );
9921017 // decrypt
9931018 const content_type , const decrypted = try server_cipher .decrypt (& buf , Record .init (encrypted ));
0 commit comments