Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] avutil/aes_ctr: reintroduce the block offset state (PR #20479)
@ 2025-09-09 14:36 James Almer via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: James Almer via ffmpeg-devel @ 2025-09-09 14:36 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: James Almer

PR #20479 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20479
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20479.patch

Wrongly removed in fe73b84879a560d69affca88ce21e61108e7c38d, it's required for calls with a payload smaller than a full block.

Fixes issue #20474.


>From a143034f66fa607e59580983ffc672ccafbcec51 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Tue, 9 Sep 2025 11:31:45 -0300
Subject: [PATCH 1/2] avutil/aes_ctr: reintroduce the block offset state

Wrongly removed in fe73b84879a560d69affca88ce21e61108e7c38d, it's required for calls with
a payload smaller than a full block.

Fixes issue #20474.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavutil/aes_ctr.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/libavutil/aes_ctr.c b/libavutil/aes_ctr.c
index 63dcb20d3a..23c06ddacb 100644
--- a/libavutil/aes_ctr.c
+++ b/libavutil/aes_ctr.c
@@ -34,6 +34,7 @@
 typedef struct AVAESCTR {
     DECLARE_ALIGNED(8, uint8_t, counter)[AES_BLOCK_SIZE];
     DECLARE_ALIGNED(8, uint8_t, encrypted_counter)[AES_BLOCK_SIZE];
+    int block_offset;
     AVAES aes;
 } AVAESCTR;
 
@@ -46,11 +47,13 @@ void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv)
 {
     memcpy(a->counter, iv, AES_CTR_IV_SIZE);
     memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE);
+    a->block_offset = 0;
 }
 
 void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv)
 {
     memcpy(a->counter, iv, sizeof(a->counter));
+    a->block_offset = 0;
 }
 
 const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a)
@@ -73,6 +76,7 @@ int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
     av_aes_init(&a->aes, key, 128, 0);
 
     memset(a->counter, 0, sizeof(a->counter));
+    a->block_offset = 0;
 
     return 0;
 }
@@ -92,10 +96,20 @@ void av_aes_ctr_increment_iv(struct AVAESCTR *a)
 {
     av_aes_ctr_increment_be64(a->counter);
     memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE);
+    a->block_offset = 0;
 }
 
 void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
 {
+    if (a->block_offset) {
+        int left = FFMIN(count, AES_BLOCK_SIZE - a->block_offset);
+        for (int len = 0; len < left; len++)
+            dst[len] = src[len] ^ a->encrypted_counter[a->block_offset++];
+        dst += left;
+        src += left;
+        count -= left;
+        a->block_offset = 0;
+    }
     while (count >= AES_BLOCK_SIZE) {
         av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0);
         av_aes_ctr_increment_be64(a->counter + 8);
@@ -112,9 +126,11 @@ void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int
     }
 
     if (count > 0) {
+        int len;
         av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0);
         av_aes_ctr_increment_be64(a->counter + 8);
-        for (int len = 0; len < count; len++)
+        for (len = 0; len < count; len++)
             dst[len] = src[len] ^ a->encrypted_counter[len];
+        a->block_offset = len;
     }
 }
-- 
2.49.1


>From 535cae3b40683f7ef6fcb9da1eb77aa5ce28b5fa Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Tue, 9 Sep 2025 11:32:17 -0300
Subject: [PATCH 2/2] avutil/tests/aes_ctr: extend the test to cover payloads
 smaller than a block

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavutil/tests/aes_ctr.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/libavutil/tests/aes_ctr.c b/libavutil/tests/aes_ctr.c
index 5af48428aa..765c049f93 100644
--- a/libavutil/tests/aes_ctr.c
+++ b/libavutil/tests/aes_ctr.c
@@ -46,6 +46,8 @@ static DECLARE_ALIGNED(8, uint32_t, key)[4];
 
 static DECLARE_ALIGNED(8, uint8_t, tmp)[20];
 
+#define SIZE 12
+
 int main (void)
 {
     int ret = 1;
@@ -85,14 +87,28 @@ int main (void)
         iv =   av_aes_ctr_get_iv(ae);
         av_aes_ctr_set_full_iv(ad, iv);
 
-        av_aes_ctr_crypt(ae, tmp, plain, sizeof(tmp));
-        if (i && memcmp(tmp, encrypted, sizeof(tmp)) != 0) {
+        // encrypt less than a full block in the first call to test the state
+        // preserving code of aes-ctr.
+        av_aes_ctr_crypt(ae, tmp, plain, SIZE);
+        if (i && memcmp(tmp, encrypted, SIZE) != 0) {
+            av_log(NULL, AV_LOG_ERROR, "test failed\n");
+            goto ERROR;
+        }
+        // encrypt the rest
+        av_aes_ctr_crypt(ae, tmp + SIZE, plain + SIZE, sizeof(tmp) - SIZE);
+        if (i && memcmp(tmp + SIZE, encrypted + SIZE, sizeof(tmp) - SIZE) != 0) {
             av_log(NULL, AV_LOG_ERROR, "test failed\n");
             goto ERROR;
         }
 
-        av_aes_ctr_crypt(ad, tmp, tmp,   sizeof(tmp));
-        if (memcmp(tmp, plain, sizeof(tmp)) != 0){
+        // same as with encryption, test the state preserving code of aes-ctr.
+        av_aes_ctr_crypt(ad, tmp, tmp, SIZE);
+        if (memcmp(tmp, plain, SIZE) != 0) {
+            av_log(NULL, AV_LOG_ERROR, "test failed\n");
+            goto ERROR;
+        }
+        av_aes_ctr_crypt(ad, tmp + SIZE, tmp + SIZE, sizeof(tmp) - SIZE);
+        if (memcmp(tmp + SIZE, plain + SIZE, sizeof(tmp) - SIZE) != 0) {
             av_log(NULL, AV_LOG_ERROR, "test failed\n");
             goto ERROR;
         }
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-09-09 14:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-09 14:36 [FFmpeg-devel] [PATCH] avutil/aes_ctr: reintroduce the block offset state (PR #20479) James Almer via ffmpeg-devel

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git