2 * copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
4 * some optimization ideas from aes128.c by Reimar Doeffinger
6 * This file is part of FFmpeg.
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.
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.
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
27 // Note: round_key[16] is accessed in the init code, but this only
28 // overwrites state, which does not matter (see also r7471).
29 uint8_t round_key
[15][4][4];
30 uint8_t state
[2][4][4];
34 const int av_aes_size
= sizeof(AVAES
);
36 static const uint8_t rcon
[10] = {
37 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
40 static uint8_t sbox
[256];
41 static uint8_t inv_sbox
[256];
43 static uint32_t enc_multbl
[1][256];
44 static uint32_t dec_multbl
[1][256];
46 static uint32_t enc_multbl
[4][256];
47 static uint32_t dec_multbl
[4][256];
50 static inline void addkey(uint64_t dst
[2], const uint64_t src
[2], const uint64_t round_key
[2]){
51 dst
[0] = src
[0] ^ round_key
[0];
52 dst
[1] = src
[1] ^ round_key
[1];
55 static void subshift(uint8_t s0
[2][16], int s
, const uint8_t *box
){
56 uint8_t (*s1
)[16]= s0
[0] - s
;
57 uint8_t (*s3
)[16]= s0
[0] + s
;
58 s0
[0][0]=box
[s0
[1][ 0]]; s0
[0][ 4]=box
[s0
[1][ 4]]; s0
[0][ 8]=box
[s0
[1][ 8]]; s0
[0][12]=box
[s0
[1][12]];
59 s1
[0][3]=box
[s1
[1][ 7]]; s1
[0][ 7]=box
[s1
[1][11]]; s1
[0][11]=box
[s1
[1][15]]; s1
[0][15]=box
[s1
[1][ 3]];
60 s0
[0][2]=box
[s0
[1][10]]; s0
[0][10]=box
[s0
[1][ 2]]; s0
[0][ 6]=box
[s0
[1][14]]; s0
[0][14]=box
[s0
[1][ 6]];
61 s3
[0][1]=box
[s3
[1][13]]; s3
[0][13]=box
[s3
[1][ 9]]; s3
[0][ 9]=box
[s3
[1][ 5]]; s3
[0][ 5]=box
[s3
[1][ 1]];
64 static inline int mix_core(uint32_t multbl
[4][256], int a
, int b
, int c
, int d
){
66 #define ROT(x,s) ((x<<s)|(x>>(32-s)))
67 return multbl
[0][a
] ^ ROT(multbl
[0][b
], 8) ^ ROT(multbl
[0][c
], 16) ^ ROT(multbl
[0][d
], 24);
69 return multbl
[0][a
] ^ multbl
[1][b
] ^ multbl
[2][c
] ^ multbl
[3][d
];
73 static inline void mix(uint8_t state
[2][4][4], uint32_t multbl
[4][256], int s1
, int s3
){
74 ((uint32_t *)(state
))[0] = mix_core(multbl
, state
[1][0][0], state
[1][s1
][1], state
[1][2][2], state
[1][s3
][3]);
75 ((uint32_t *)(state
))[1] = mix_core(multbl
, state
[1][1][0], state
[1][s3
-1][1], state
[1][3][2], state
[1][s1
-1][3]);
76 ((uint32_t *)(state
))[2] = mix_core(multbl
, state
[1][2][0], state
[1][s3
][1], state
[1][0][2], state
[1][s1
][3]);
77 ((uint32_t *)(state
))[3] = mix_core(multbl
, state
[1][3][0], state
[1][s1
-1][1], state
[1][1][2], state
[1][s3
-1][3]);
80 static inline void crypt(AVAES
*a
, int s
, const uint8_t *sbox
, const uint32_t *multbl
){
83 for(r
=a
->rounds
-1; r
>0; r
--){
84 mix(a
->state
, multbl
, 3-s
, 1+s
);
85 addkey(a
->state
[1], a
->state
[0], a
->round_key
[r
]);
87 subshift(a
->state
[0][0], s
, sbox
);
90 void av_aes_crypt(AVAES
*a
, uint8_t *dst
, const uint8_t *src
, int count
, uint8_t *iv
, int decrypt
){
92 addkey(a
->state
[1], src
, a
->round_key
[a
->rounds
]);
94 crypt(a
, 0, inv_sbox
, dec_multbl
);
96 addkey(a
->state
[0], a
->state
[0], iv
);
99 addkey(dst
, a
->state
[0], a
->round_key
[0]);
101 if(iv
) addkey(a
->state
[1], a
->state
[1], iv
);
102 crypt(a
, 2, sbox
, enc_multbl
);
103 addkey(dst
, a
->state
[0], a
->round_key
[0]);
104 if(iv
) memcpy(iv
, dst
, 16);
111 static void init_multbl2(uint8_t tbl
[1024], const int c
[4], const uint8_t *log8
, const uint8_t *alog8
, const uint8_t *sbox
){
113 for(i
=0; i
<1024; i
++){
115 if(x
) tbl
[i
]= alog8
[ log8
[x
] + log8
[c
[i
&3]] ];
118 for(j
=256; j
<1024; j
++)
120 tbl
[4*j
+i
]= tbl
[4*j
+ ((i
-1)&3) - 1024];
124 // this is based on the reference AES code by Paulo Barreto and Vincent Rijmen
125 int av_aes_init(AVAES
*a
, const uint8_t *key
, int key_bits
, int decrypt
) {
126 int i
, j
, t
, rconpointer
= 0;
133 if(!enc_multbl
[0][sizeof(enc_multbl
)/sizeof(enc_multbl
[0][0])-1]){
135 for(i
=0; i
<255; i
++){
142 for(i
=0; i
<256; i
++){
143 j
= i
? alog8
[255-log8
[i
]] : 0;
144 j
^= (j
<<1) ^ (j
<<2) ^ (j
<<3) ^ (j
<<4);
145 j
= (j
^ (j
>>8) ^ 99) & 255;
149 init_multbl2(dec_multbl
[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8
, alog8
, inv_sbox
);
150 init_multbl2(enc_multbl
[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8
, alog8
, sbox
);
153 if(key_bits
!=128 && key_bits
!=192 && key_bits
!=256)
158 memcpy(tk
, key
, KC
*4);
160 for(t
= 0; t
< (rounds
+1)*16;) {
161 memcpy(a
->round_key
[0][0]+t
, tk
, KC
*4);
164 for(i
= 0; i
< 4; i
++)
165 tk
[0][i
] ^= sbox
[tk
[KC
-1][(i
+1)&3]];
166 tk
[0][0] ^= rcon
[rconpointer
++];
168 for(j
= 1; j
< KC
; j
++){
169 if(KC
!= 8 || j
!= KC
>>1)
170 for(i
= 0; i
< 4; i
++) tk
[j
][i
] ^= tk
[j
-1][i
];
172 for(i
= 0; i
< 4; i
++) tk
[j
][i
] ^= sbox
[tk
[j
-1][i
]];
177 for(i
=1; i
<rounds
; i
++){
179 memcpy(tmp
[2], a
->round_key
[i
][0], 16);
180 subshift(tmp
[1], 0, sbox
);
181 mix(tmp
, dec_multbl
, 1, 3);
182 memcpy(a
->round_key
[i
][0], tmp
[0], 16);
185 for(i
=0; i
<(rounds
+1)>>1; i
++){
187 FFSWAP(int, a
->round_key
[i
][0][j
], a
->round_key
[rounds
-i
][0][j
]);
201 uint8_t rkey
[2][16]= {
203 {0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59}};
204 uint8_t pt
[16], rpt
[2][16]= {
205 {0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad, 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3},
207 uint8_t rct
[2][16]= {
208 {0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7, 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf},
209 {0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65}};
213 av_aes_init(&ae
, "PI=3.141592654..", 128, 0);
214 av_aes_init(&ad
, "PI=3.141592654..", 128, 1);
215 av_log_set_level(AV_LOG_DEBUG
);
216 av_lfg_init(&prng
, 1);
219 av_aes_init(&b
, rkey
[i
], 128, 1);
220 av_aes_crypt(&b
, temp
, rct
[i
], 1, NULL
, 1);
222 if(rpt
[i
][j
] != temp
[j
])
223 av_log(NULL
, AV_LOG_ERROR
, "%d %02X %02X\n", j
, rpt
[i
][j
], temp
[j
]);
226 for(i
=0; i
<10000; i
++){
228 pt
[j
] = av_lfg_get(&prng
);
231 av_aes_crypt(&ae
, temp
, pt
, 1, NULL
, 0);
233 av_log(NULL
, AV_LOG_ERROR
, "%02X %02X %02X %02X\n", temp
[0], temp
[5], temp
[10], temp
[15]);
234 av_aes_crypt(&ad
, temp
, temp
, 1, NULL
, 1);
237 if(pt
[j
] != temp
[j
]){
238 av_log(NULL
, AV_LOG_ERROR
, "%d %d %02X %02X\n", i
,j
, pt
[j
], temp
[j
]);