authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-05-29 12:12:26+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-07-05 12:26:21+02:00
log0e4371b5ec9ce9ad86438ae65d949f5ff4b6e472
tree142d5e4fcb94f3a0474cba7a128f516e18ab7e92
parent05d745ea634b085380b94e47f006c1a80555aec2

crypto.aes_ccm: immediately reject large messages on decryption

AES-CCM has pretty low limits. With a 13 byte nonce, we only have 2 bytes left to encode the message length, so it can't encrypt messages larger than 65535 bytes. In the encryption function we immediately rejected messages that would be too large. But not in the decryption function. So, do it as well in the decryption function. Message larger than the encodable length will never be valid ciphertexts.

1 files changed, 11 insertions(+), 0 deletions(-)

lib/std/crypto/aes_ccm.zig+11
...@@ -122,6 +122,9 @@ fn AesCcm(comptime BlockCipher: type, comptime tag_len: usize, comptime nonce_le...@@ -122,6 +122,9 @@ fn AesCcm(comptime BlockCipher: type, comptime tag_len: usize, comptime nonce_le
122 ) AuthenticationError!void {122 ) AuthenticationError!void {
123 assert(m.len == c.len);123 assert(m.len == c.len);
124124
125 const max_msg_len: u64 = if (L >= 8) std.math.maxInt(u64) else (@as(u64, 1) << @as(u6, @intCast(L * 8))) - 1;
126 if (c.len > max_msg_len) return error.AuthenticationFailed;
127
125 const cipher_ctx = BlockCipher.initEnc(key);128 const cipher_ctx = BlockCipher.initEnc(key);
126129
127 // Decrypt the ciphertext using CTR mode (starting from counter = 1)130 // Decrypt the ciphertext using CTR mode (starting from counter = 1)
...@@ -874,3 +877,11 @@ test "Aes256Ccm0 - Basic encryption-only round-trip" {...@@ -874,3 +877,11 @@ test "Aes256Ccm0 - Basic encryption-only round-trip" {
874877
875 try testing.expectEqualSlices(u8, m[0..], m2[0..]);878 try testing.expectEqualSlices(u8, m[0..], m2[0..]);
876}879}
880
881test "Aes256Ccm decryption of oversized ciphertext" {
882 const key: [32]u8 = @splat(0);
883 const nonce: [13]u8 = @splat(0);
884 const tag: [Aes256Ccm16.tag_length]u8 = @splat(0);
885 var buf: [65536]u8 = @splat(0);
886 try testing.expectError(error.AuthenticationFailed, Aes256Ccm16.decrypt(&buf, &buf, tag, "", nonce, key));
887}