Mercurial > libavutil.hg
comparison aes.c @ 164:f45907fe2530 libavutil
aes support (unfinished)
author | michael |
---|---|
date | Sun, 14 Jan 2007 09:06:13 +0000 |
parents | |
children | d64f200afe17 |
comparison
equal
deleted
inserted
replaced
163:dfd02ce85c5d | 164:f45907fe2530 |
---|---|
1 /* | |
2 * copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at> | |
3 * | |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 #include "common.h" | |
22 #include "log.h" | |
23 #include "aes.h" | |
24 | |
25 typedef struct AVAES{ | |
26 uint8_t state[4][4]; | |
27 uint8_t round_key[15][4][4]; | |
28 int rounds; | |
29 }AVAES; | |
30 | |
31 static const uint8_t rcon[30] = { | |
32 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, | |
33 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, | |
34 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, | |
35 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 | |
36 }; | |
37 | |
38 static uint8_t log8[256]; | |
39 static uint8_t alog8[512]; | |
40 static uint8_t sbox[256]; | |
41 static uint8_t inv_sbox[256]; | |
42 | |
43 static inline void addkey(uint32_t state[4], uint32_t round_key[4]){ | |
44 int i; | |
45 for(i=0; i<4; i++) | |
46 state[i] ^= round_key[i]; //partial memory stall? FIXME benchmark | |
47 } | |
48 | |
49 #define SUBSHIFT0(s, box) s[0]=box[s[ 0]]; s[ 4]=box[s[ 4]]; s[ 8]=box[s[ 8]]; s[12]=box[s[12]]; | |
50 #define SUBSHIFT1(s, box) t=s[0]; s[0]=box[s[ 4]]; s[ 4]=box[s[ 8]]; s[ 8]=box[s[12]]; s[12]=box[t]; | |
51 #define SUBSHIFT2(s, box) t=s[0]; s[0]=box[s[ 8]]; s[ 8]=box[ t]; t=s[ 4]; s[ 4]=box[s[12]]; s[12]=box[t]; | |
52 #define SUBSHIFT3(s, box) t=s[0]; s[0]=box[s[12]]; s[12]=box[s[ 8]]; s[ 8]=box[s[ 4]]; s[ 4]=box[t]; | |
53 | |
54 static inline int mul(int a, int b){ | |
55 if(a==255) return 0; | |
56 else return alog8[a+b]; | |
57 } | |
58 | |
59 static inline void mix(uint8_t state[4][4], int c0, int c1, int c2, int c3){ | |
60 uint8_t tmp[4][4]; | |
61 int i, j; | |
62 | |
63 for(i=0; i<16; i++) | |
64 tmp[0][i]= log8[ state[0][i] ]; | |
65 for(j=0; j<4; j++) | |
66 for(i=0; i<4; i++) | |
67 state[j][i]= mul( tmp[j][ i ], c0 ) | |
68 ^mul( tmp[j][(i+ 1)&3], c1 ) | |
69 ^mul( tmp[j][(i+ 2)&3], c2 ) | |
70 ^mul( tmp[j][(i+ 3)&3], c3 ); | |
71 } | |
72 | |
73 | |
74 void av_aes_decrypt(AVAES *a){ | |
75 int t, r; | |
76 | |
77 for(r=a->rounds-1; r>=0; r--){ | |
78 if(r==a->rounds-1) | |
79 addkey(a->state, a->round_key[r+1]); | |
80 else | |
81 mix(a->state, log8[0xe], log8[0xb], log8[0xd], log8[9]); //FIXME replace log8 by const | |
82 SUBSHIFT0((a->state[0]+0), inv_sbox) | |
83 SUBSHIFT3((a->state[0]+1), inv_sbox) | |
84 SUBSHIFT2((a->state[0]+2), inv_sbox) | |
85 SUBSHIFT1((a->state[0]+3), inv_sbox) | |
86 addkey(a->state, a->round_key[r]); | |
87 } | |
88 } | |
89 | |
90 void av_aes_encrypt(AVAES *a){ | |
91 int r, t; | |
92 | |
93 for(r=0; r<a->rounds; r++){ | |
94 addkey(a->state, a->round_key[r]); | |
95 SUBSHIFT0((a->state[0]+0), sbox) | |
96 SUBSHIFT1((a->state[0]+1), sbox) | |
97 SUBSHIFT2((a->state[0]+2), sbox) | |
98 SUBSHIFT3((a->state[0]+3), sbox) | |
99 if(r==a->rounds-1) | |
100 addkey(a->state, a->round_key[r+1]); | |
101 else | |
102 mix(a->state, log8[2], log8[3], 0, 0); //FIXME replace log8 by const / optimze mix as this can be simplified alot | |
103 } | |
104 } | |
105 | |
106 // this is based on the reference AES code by Paulo Barreto and Vincent Rijmen | |
107 AVAES *av_aes_init(uint8_t *key, int keyBits) { | |
108 AVAES *a= av_malloc(sizeof(AVAES)); | |
109 int i, j, t, rconpointer = 0; | |
110 uint8_t tk[8][4]; | |
111 int KC= keyBits/32; | |
112 int ROUNDS= KC + 6; | |
113 | |
114 if(!sbox[255]){ | |
115 j=1; | |
116 for(i=0; i<255; i++){ | |
117 alog8[i]= | |
118 alog8[i+255]= j; | |
119 log8[j]= i; | |
120 j^= j+j; | |
121 if(j>255) j^= 0x11B; | |
122 } | |
123 log8[0]= 255; | |
124 for(i=0; i<256; i++){ | |
125 j= i ? alog8[255-log8[i]] : 0; | |
126 j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4) | |
127 ^(j>>7) ^ (j>>6) ^ (j>>5) ^ (j>>4) ^ 99; | |
128 j&=255; | |
129 inv_sbox[j]= i; | |
130 sbox [i]= j; | |
131 // av_log(NULL, AV_LOG_ERROR, "%d, ", log8[i]); | |
132 } | |
133 } | |
134 | |
135 a->rounds= ROUNDS; | |
136 | |
137 if(keyBits!=128 && keyBits!=192 && keyBits!=256) | |
138 return NULL; | |
139 | |
140 memcpy(tk, key, KC*4); | |
141 | |
142 for(t= 0; t < (ROUNDS+1)*4; ) { | |
143 for(j = 0; (j < KC) && (t < (ROUNDS+1)*4); j++, t++) | |
144 for(i = 0; i < 4; i++) | |
145 a->round_key[0][t][i] = tk[j][i]; | |
146 | |
147 for(i = 0; i < 4; i++) | |
148 tk[0][i] ^= sbox[tk[KC-1][(i+1)&3]]; | |
149 tk[0][0] ^= rcon[rconpointer++]; | |
150 | |
151 for(j = 1; j < KC; j++){ | |
152 if(KC != 8 || j != KC/2) | |
153 for(i = 0; i < 4; i++) tk[j][i] ^= tk[j-1][i]; | |
154 else | |
155 for(i = 0; i < 4; i++) | |
156 tk[KC/2][i] ^= sbox[tk[KC/2 - 1][i]]; | |
157 } | |
158 } | |
159 return a; | |
160 } | |
161 | |
162 #ifdef TEST | |
163 | |
164 int main(){ | |
165 int i,j,k; | |
166 AVAES *a= av_aes_init("PI=3.141592654..", 128); | |
167 | |
168 for(i=0; i<10000; i++){ | |
169 } | |
170 return 0; | |
171 } | |
172 #endif |