Wrongly removed in fe73b84879a560d69affca88ce21e61108e7c38d, it's required for calls with a payload smaller than a full block. Fixes issue #20474.
Unified · Split
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | typedef struct AVAESCTR { |
| 35 | 35 | DECLARE_ALIGNED(8, uint8_t, counter)[AES_BLOCK_SIZE]; |
| 36 | 36 | DECLARE_ALIGNED(8, uint8_t, encrypted_counter)[AES_BLOCK_SIZE]; |
| 37 | + int block_offset; | |
| 37 | 38 | AVAES aes; |
| 38 | 39 | } AVAESCTR; |
| 39 | 40 | |
| @@ -46,11 +47,13 @@ void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv) · 6 unmodified lines | ||
| 46 | 47 | { |
| 47 | 48 | memcpy(a->counter, iv, AES_CTR_IV_SIZE); |
| 48 | 49 | memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); |
| 50 | + a->block_offset = 0; | |
| 49 | 51 | } |
| 50 | 52 | |
| 51 | 53 | void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv) |
| 52 | 54 | { |
| 53 | 55 | memcpy(a->counter, iv, sizeof(a->counter)); |
| 56 | + a->block_offset = 0; | |
| 54 | 57 | } |
| 55 | 58 | |
| 56 | 59 | 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) · 16 unmodified lines | ||
| 73 | 76 | av_aes_init(&a->aes, key, 128, 0); |
| 74 | 77 | |
| 75 | 78 | memset(a->counter, 0, sizeof(a->counter)); |
| 79 | + a->block_offset = 0; | |
| 76 | 80 | |
| 77 | 81 | return 0; |
| 78 | 82 | } |
| @@ -92,10 +96,21 @@ void av_aes_ctr_increment_iv(struct AVAESCTR *a) · 13 unmodified lines | ||
| 92 | 96 | { |
| 93 | 97 | av_aes_ctr_increment_be64(a->counter); |
| 94 | 98 | memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); |
| 99 | + a->block_offset = 0; | |
| 95 | 100 | } |
| 96 | 101 | |
| 97 | 102 | void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count) |
| 98 | 103 | { |
| 104 | + if (a->block_offset && count > 0) { | |
| 105 | + int left = FFMIN(count, AES_BLOCK_SIZE - a->block_offset); | |
| 106 | + for (int len = 0; len < left; len++) | |
| 107 | + dst[len] = src[len] ^ a->encrypted_counter[a->block_offset++]; | |
| 108 | + a->block_offset &= AES_BLOCK_SIZE - 1; | |
| 109 | + dst += left; | |
| 110 | + src += left; | |
| 111 | + count -= left; | |
| 112 | + } | |
| 113 | + | |
| 99 | 114 | while (count >= AES_BLOCK_SIZE) { |
| 100 | 115 | av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); |
| 101 | 116 | av_aes_ctr_increment_be64(a->counter + 8); |
| @@ -115,6 +130,6 @@ void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int · 13 unmodified lines | ||
| 115 | 130 | av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); |
| 116 | 131 | av_aes_ctr_increment_be64(a->counter + 8); |
| 117 | 132 | for (int len = 0; len < count; len++) |
| 118 | − dst[len] = src[len] ^ a->encrypted_counter[len]; | |
| 133 | + dst[len] = src[len] ^ a->encrypted_counter[a->block_offset++]; | |
| 119 | 134 | } |
| 120 | 135 | } |