From 0a143f61dcc7fa25b2c44b285c3cf736f14a3abc Mon Sep 17 00:00:00 2001 From: Mike <45243121+tankf33der@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:46:17 +0200 Subject: [PATCH] crypto.cipher: fix xor_key_stream() for CTR mode, add test vector created with OpenSSL (#25866) --- vlib/crypto/cipher/ctr.v | 15 +++++++-------- vlib/crypto/cipher/ctr_test.v | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/vlib/crypto/cipher/ctr.v b/vlib/crypto/cipher/ctr.v index fa71eb6f5..52786f38b 100644 --- a/vlib/crypto/cipher/ctr.v +++ b/vlib/crypto/cipher/ctr.v @@ -66,18 +66,17 @@ pub fn (mut x Ctr) xor_key_stream(mut dst []u8, src []u8) { if x.out_used == x.out.len { x.b.encrypt(mut x.out, x.next) x.out_used = 0 + // increment counter + for i := x.next.len - 1; i >= 0; i-- { + x.next[i]++ + if x.next[i] != 0 { + break + } + } } n := xor_bytes(mut local_dst, local_src, x.out[x.out_used..]) - // increment counter - for i := x.next.len - 1; i >= 0; i-- { - x.next[i]++ - if x.next[i] != 0 { - break - } - } - local_dst = local_dst[n..] local_src = local_src[n..] x.out_used += n diff --git a/vlib/crypto/cipher/ctr_test.v b/vlib/crypto/cipher/ctr_test.v index b1327ba55..a1c22f1d3 100644 --- a/vlib/crypto/cipher/ctr_test.v +++ b/vlib/crypto/cipher/ctr_test.v @@ -1,3 +1,4 @@ +import crypto.aes import crypto.cipher import crypto.des @@ -16,3 +17,17 @@ fn test_ctr_stream_cipher() ! { cipher: c } } + +fn test_ctr_byte_by_byte() { + key := []u8{len: 16, init: index} + iv := []u8{len: 16, init: index} + txt := []u8{len: 32, init: index} + mut out := []u8{len: 32} + + mut ofb := cipher.new_ctr(aes.new_cipher(key), iv) + for i in 0 .. 32 { + ofb.xor_key_stream(mut out[i..i + 1], txt[i..i + 1]) + } + assert out == [u8(10), 149, 9, 182, 69, 107, 246, 66, 249, 202, 158, 83, 202, 94, 228, 85, + 18, 114, 254, 135, 114, 13, 100, 129, 130, 195, 231, 20, 87, 185, 17, 195] +} -- 2.39.5