Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavutil/aes.c
Line
Count
Source
1
/*
2
 * copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
3
 *
4
 * some optimization ideas from aes128.c by Reimar Doeffinger
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#include <string.h>
24
25
#include "config.h"
26
#include "aes.h"
27
#include "aes_internal.h"
28
#include "attributes.h"
29
#include "error.h"
30
#include "intreadwrite.h"
31
#include "macros.h"
32
#include "mem.h"
33
#include "thread.h"
34
35
const int av_aes_size= sizeof(AVAES);
36
37
struct AVAES *av_aes_alloc(void)
38
290
{
39
290
    return av_mallocz(sizeof(struct AVAES));
40
290
}
41
42
static const uint8_t rcon[10] = {
43
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
44
};
45
46
static uint8_t     sbox[256];
47
static uint8_t inv_sbox[256];
48
#if CONFIG_SMALL
49
static uint32_t enc_multbl[1][256];
50
static uint32_t dec_multbl[1][256];
51
#else
52
static uint32_t enc_multbl[4][256];
53
static uint32_t dec_multbl[4][256];
54
#endif
55
56
#if HAVE_BIGENDIAN
57
#   define ROT(x, s) (((x) >> (s)) | ((x) << (32-(s))))
58
#else
59
3.06k
#   define ROT(x, s) (((x) << (s)) | ((x) >> (32-(s))))
60
#endif
61
62
static inline void addkey(av_aes_block *dst, const av_aes_block *src,
63
                          const av_aes_block *round_key)
64
33.4k
{
65
33.4k
    dst->u64[0] = src->u64[0] ^ round_key->u64[0];
66
33.4k
    dst->u64[1] = src->u64[1] ^ round_key->u64[1];
67
33.4k
}
68
69
static inline void addkey_s(av_aes_block *dst, const uint8_t *src,
70
                            const av_aes_block *round_key)
71
7.43k
{
72
7.43k
    dst->u64[0] = AV_RN64(src)     ^ round_key->u64[0];
73
7.43k
    dst->u64[1] = AV_RN64(src + 8) ^ round_key->u64[1];
74
7.43k
}
75
76
static inline void addkey_d(uint8_t *dst, const av_aes_block *src,
77
                            const av_aes_block *round_key)
78
3.71k
{
79
3.71k
    AV_WN64(dst,     src->u64[0] ^ round_key->u64[0]);
80
3.71k
    AV_WN64(dst + 8, src->u64[1] ^ round_key->u64[1]);
81
3.71k
}
82
83
static void subshift(av_aes_block s0[2], int s, const uint8_t *box)
84
571k
{
85
571k
    unsigned char *s1_dst = (unsigned char*)s0[0].u8 + 3 - s;
86
571k
    const unsigned char *s1_src = s1_dst + sizeof(*s0);
87
571k
    unsigned char *s3_dst = (unsigned char*)s0[0].u8 + s + 1;
88
571k
    const unsigned char *s3_src = s3_dst + sizeof(*s0);
89
90
571k
    s0[0].u8[ 0] = box[s0[1].u8[ 0]];
91
571k
    s0[0].u8[ 4] = box[s0[1].u8[ 4]];
92
571k
    s0[0].u8[ 8] = box[s0[1].u8[ 8]];
93
571k
    s0[0].u8[12] = box[s0[1].u8[12]];
94
571k
    s1_dst[ 0] = box[s1_src[ 4]];
95
571k
    s1_dst[ 4] = box[s1_src[ 8]];
96
571k
    s1_dst[ 8] = box[s1_src[12]];
97
571k
    s1_dst[12] = box[s1_src[ 0]];
98
571k
    s0[0].u8[ 2] = box[s0[1].u8[10]];
99
571k
    s0[0].u8[10] = box[s0[1].u8[ 2]];
100
571k
    s0[0].u8[ 6] = box[s0[1].u8[14]];
101
571k
    s0[0].u8[14] = box[s0[1].u8[ 6]];
102
571k
    s3_dst[ 0] = box[s3_src[12]];
103
571k
    s3_dst[12] = box[s3_src[ 8]];
104
571k
    s3_dst[ 8] = box[s3_src[ 4]];
105
571k
    s3_dst[ 4] = box[s3_src[ 0]];
106
571k
}
107
108
static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d)
109
2.40M
{
110
#if CONFIG_SMALL
111
    return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24);
112
#else
113
2.40M
    return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d];
114
2.40M
#endif
115
2.40M
}
116
117
static inline void mix(av_aes_block state[2], uint32_t multbl[][256], int s1, int s3)
118
600k
{
119
600k
    uint8_t (*src)[4] = state[1].u8x4;
120
600k
    state[0].u32[0] = mix_core(multbl, src[0][0], src[s1    ][1], src[2][2], src[s3    ][3]);
121
600k
    state[0].u32[1] = mix_core(multbl, src[1][0], src[s3 - 1][1], src[3][2], src[s1 - 1][3]);
122
600k
    state[0].u32[2] = mix_core(multbl, src[2][0], src[s3    ][1], src[0][2], src[s1    ][3]);
123
600k
    state[0].u32[3] = mix_core(multbl, src[3][0], src[s1 - 1][1], src[1][2], src[s3 - 1][3]);
124
600k
}
125
126
static inline void aes_crypt(AVAES *a, int s, const uint8_t *sbox_arg,
127
                         uint32_t multbl[][256])
128
3.71k
{
129
3.71k
    int r;
130
131
37.1k
    for (r = a->rounds - 1; r > 0; r--) {
132
33.4k
        mix(a->state, multbl, 3 - s, 1 + s);
133
33.4k
        addkey(&a->state[1], &a->state[0], &a->round_key[r]);
134
33.4k
    }
135
136
3.71k
    subshift(&a->state[0], s, sbox_arg);
137
3.71k
}
138
139
static void aes_encrypt(AVAES *a, uint8_t *dst, const uint8_t *src,
140
                        int count, uint8_t *iv, int rounds)
141
0
{
142
0
    while (count--) {
143
0
        addkey_s(&a->state[1], src, &a->round_key[rounds]);
144
0
        if (iv)
145
0
            addkey_s(&a->state[1], iv, &a->state[1]);
146
0
        aes_crypt(a, 2, sbox, enc_multbl);
147
0
        addkey_d(dst, &a->state[0], &a->round_key[0]);
148
0
        if (iv)
149
0
            memcpy(iv, dst, 16);
150
0
        src += 16;
151
0
        dst += 16;
152
0
    }
153
0
}
154
155
static void aes_decrypt(AVAES *a, uint8_t *dst, const uint8_t *src,
156
                        int count, uint8_t *iv, int rounds)
157
63.0k
{
158
66.7k
    while (count--) {
159
3.71k
        addkey_s(&a->state[1], src, &a->round_key[rounds]);
160
3.71k
        aes_crypt(a, 0, inv_sbox, dec_multbl);
161
3.71k
        if (iv) {
162
3.71k
            addkey_s(&a->state[0], iv, &a->state[0]);
163
3.71k
            memcpy(iv, src, 16);
164
3.71k
        }
165
3.71k
        addkey_d(dst, &a->state[0], &a->round_key[0]);
166
3.71k
        src += 16;
167
3.71k
        dst += 16;
168
3.71k
    }
169
63.0k
}
170
171
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src,
172
                  int count, uint8_t *iv, int decrypt)
173
63.0k
{
174
63.0k
    a->crypt(a, dst, src, count, iv, a->rounds);
175
63.0k
}
176
177
static void init_multbl2(uint32_t tbl[][256], const int c[4],
178
                         const uint8_t *log8, const uint8_t *alog8,
179
                         const uint8_t *sbox_arg)
180
4
{
181
4
    int i;
182
183
1.02k
    for (i = 0; i < 256; i++) {
184
1.02k
        int x = sbox_arg[i];
185
1.02k
        if (x) {
186
1.02k
            int k, l, m, n;
187
1.02k
            x = log8[x];
188
1.02k
            k = alog8[x + log8[c[0]]];
189
1.02k
            l = alog8[x + log8[c[1]]];
190
1.02k
            m = alog8[x + log8[c[2]]];
191
1.02k
            n = alog8[x + log8[c[3]]];
192
1.02k
            tbl[0][i] = AV_NE(MKBETAG(k, l, m, n), MKTAG(k, l, m, n));
193
1.02k
#if !CONFIG_SMALL
194
1.02k
            tbl[1][i] = ROT(tbl[0][i], 8);
195
1.02k
            tbl[2][i] = ROT(tbl[0][i], 16);
196
1.02k
            tbl[3][i] = ROT(tbl[0][i], 24);
197
1.02k
#endif
198
1.02k
        }
199
1.02k
    }
200
4
}
201
202
static AVOnce aes_static_init = AV_ONCE_INIT;
203
204
static av_cold void aes_init_static(void)
205
2
{
206
2
    uint8_t log8[256];
207
2
    uint8_t alog8[512];
208
2
    int i, j = 1;
209
210
512
    for (i = 0; i < 255; i++) {
211
510
        alog8[i] = alog8[i + 255] = j;
212
510
        log8[j] = i;
213
510
        j ^= j + j;
214
510
        if (j > 255)
215
256
            j ^= 0x11B;
216
510
    }
217
514
    for (i = 0; i < 256; i++) {
218
512
        j = i ? alog8[255 - log8[i]] : 0;
219
512
        j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4);
220
512
        j = (j ^ (j >> 8) ^ 99) & 255;
221
512
        inv_sbox[j] = i;
222
512
        sbox[i]     = j;
223
512
    }
224
2
    init_multbl2(dec_multbl, (const int[4]) { 0xe, 0x9, 0xd, 0xb },
225
2
                 log8, alog8, inv_sbox);
226
2
    init_multbl2(enc_multbl, (const int[4]) { 0x2, 0x1, 0x1, 0x3 },
227
2
                 log8, alog8, sbox);
228
2
}
229
230
// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen
231
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
232
63.0k
{
233
63.0k
    int i, j, t, rconpointer = 0;
234
63.0k
    uint8_t tk[8][4];
235
63.0k
    int KC = key_bits >> 5;
236
63.0k
    int rounds = KC + 6;
237
238
63.0k
    a->rounds = rounds;
239
63.0k
    a->crypt = decrypt ? aes_decrypt : aes_encrypt;
240
#if ARCH_X86 && HAVE_X86ASM && HAVE_AESNI_EXTERNAL
241
    ff_init_aes_x86(a, decrypt);
242
#elif ARCH_AARCH64 && HAVE_ARM_AES
243
    ff_init_aes_aarch64(a, decrypt);
244
#endif
245
246
63.0k
    ff_thread_once(&aes_static_init, aes_init_static);
247
248
63.0k
    if (key_bits != 128 && key_bits != 192 && key_bits != 256)
249
0
        return AVERROR(EINVAL);
250
251
63.0k
    memcpy(tk, key, KC * 4);
252
63.0k
    memcpy(a->round_key[0].u8, key, KC * 4);
253
254
693k
    for (t = KC * 4; t < (rounds + 1) * 16; t += KC * 4) {
255
3.15M
        for (i = 0; i < 4; i++)
256
2.52M
            tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]];
257
630k
        tk[0][0] ^= rcon[rconpointer++];
258
259
2.52M
        for (j = 1; j < KC; j++) {
260
1.89M
            if (KC != 8 || j != KC >> 1)
261
9.45M
                for (i = 0; i < 4; i++)
262
7.56M
                    tk[j][i] ^= tk[j - 1][i];
263
0
            else
264
0
                for (i = 0; i < 4; i++)
265
0
                    tk[j][i] ^= sbox[tk[j - 1][i]];
266
1.89M
        }
267
268
630k
        memcpy((unsigned char*)a->round_key + t, tk, KC * 4);
269
630k
    }
270
271
63.0k
    if (decrypt) {
272
630k
        for (i = 1; i < rounds; i++) {
273
567k
            av_aes_block tmp[3];
274
567k
            tmp[2] = a->round_key[i];
275
567k
            subshift(&tmp[1], 0, sbox);
276
567k
            mix(tmp, dec_multbl, 1, 3);
277
567k
            a->round_key[i] = tmp[0];
278
567k
        }
279
63.0k
    } else {
280
0
        for (i = 0; i < (rounds + 1) >> 1; i++)
281
0
            FFSWAP(av_aes_block, a->round_key[i], a->round_key[rounds - i]);
282
0
    }
283
284
63.0k
    return 0;
285
63.0k
}