]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | /* | |
20 | * rijndaelApi.c - AES API layer | |
21 | * | |
22 | * Based on rijndael-api-ref.h v2.0 written by Paulo Barreto | |
23 | * and Vincent Rijmen | |
24 | */ | |
25 | #include <stdlib.h> | |
26 | #include <string.h> | |
27 | ||
28 | #include "rijndael-alg-ref.h" | |
29 | #include "rijndaelApi.h" | |
30 | ||
31 | #ifdef ALTIVEC_ENABLE | |
32 | /* this goes somewhere else and gets init'd by the plugin object.... */ | |
33 | /* as of 4/11/2001, the vectorized routines do NOT work */ | |
34 | int gHasAltivec = 0; | |
35 | #endif | |
36 | ||
37 | int doAES128 = 1; | |
38 | ||
39 | #define CBC_DEBUG 0 | |
40 | #if CBC_DEBUG | |
41 | static void dumpChainBuf(cipherInstance *cipher, char *op) | |
42 | { | |
43 | int t,j; | |
44 | int columns = cipher->blockLen / 32; | |
45 | ||
46 | printf("chainBuf %s: ", op); | |
47 | for (j = 0; j < columns; j++) { | |
48 | for(t = 0; t < 4; t++) { | |
49 | printf("%02x ", cipher->chainBlock[t][j]); | |
50 | } | |
51 | } | |
52 | printf("\n"); | |
53 | } | |
54 | #else | |
55 | #define dumpChainBuf(c, o) | |
56 | #endif | |
57 | ||
58 | int makeKey( | |
59 | keyInstance *key, | |
60 | int keyLen, // in BITS | |
61 | int blockLen, // in BITS | |
62 | word8 *keyMaterial, | |
63 | int enable128Opt) | |
64 | { | |
65 | unsigned keyBytes; | |
66 | unsigned i; | |
67 | ||
68 | if (key == NULL) { | |
69 | return BAD_KEY_INSTANCE; | |
70 | } | |
71 | if(keyMaterial == NULL) { | |
72 | return BAD_KEY_MAT; | |
73 | } | |
74 | if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { | |
75 | key->keyLen = keyLen; | |
76 | } else { | |
77 | return BAD_KEY_MAT; | |
78 | } | |
79 | key->blockLen = blockLen; | |
80 | key->columns = blockLen / 32; | |
81 | ||
82 | /* initialize key schedule */ | |
29654253 | 83 | #if !GLADMAN_AES_128_ENABLE |
bac41a7b A |
84 | if(enable128Opt && |
85 | (keyLen == MIN_AES_KEY_BITS) && | |
86 | (blockLen == MIN_AES_BLOCK_BITS)) { | |
87 | /* optimized, 128 bit key and block size */ | |
88 | word8 k[4][KC_128_OPT] __attribute__((aligned(4))); | |
89 | ||
90 | for(i = 0; i < (MIN_AES_KEY_BITS/8); i++) { | |
91 | /* speed this up */ | |
92 | k[i % 4][i / 4] = keyMaterial[i]; | |
93 | } | |
94 | rijndaelKeySched128 (k, key->keySched); | |
95 | memset(k, 0, 4 * KC_128_OPT); | |
96 | } | |
29654253 A |
97 | else |
98 | #endif /* !GLADMAN_AES_128_ENABLE */ | |
99 | { | |
100 | ||
bac41a7b A |
101 | /* general case */ |
102 | word8 k[4][MAXKC]; | |
103 | ||
104 | keyBytes = keyLen / 8; | |
105 | for(i = 0; i < keyBytes; i++) { | |
106 | k[i % 4][i / 4] = keyMaterial[i]; | |
107 | } | |
108 | rijndaelKeySched (k, key->keyLen, key->blockLen, key->keySched); | |
109 | memset(k, 0, 4 * MAXKC); | |
110 | } | |
111 | return TRUE; | |
112 | } | |
113 | ||
114 | /* | |
115 | * Simplified single-block encrypt/decrypt. | |
116 | */ | |
117 | #define AES_CONSISTENCY_CHECK 1 | |
118 | ||
119 | int rijndaelBlockEncrypt( | |
120 | keyInstance *key, | |
121 | word8 *input, | |
122 | word8 *outBuffer) | |
123 | { | |
df0e469f A |
124 | int t; |
125 | unsigned j; | |
bac41a7b A |
126 | word8 localBlock[4][MAXBC]; // working memory: encrypt/decrypt in place here |
127 | ||
128 | #if AES_CONSISTENCY_CHECK | |
129 | if (key == NULL || | |
130 | (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) || | |
131 | (key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) { | |
132 | return BAD_KEY_INSTANCE; | |
133 | } | |
134 | #endif /* AES_CONSISTENCY_CHECK */ | |
135 | ||
136 | #if defined(__ppc__) && defined(ALTIVEC_ENABLE) | |
137 | if(gHasAltivec && (key->blockLen == 128)) { | |
138 | vBlockEncrypt128(key, input, outBuffer); | |
139 | return 128; | |
140 | } | |
141 | #endif | |
142 | ||
143 | for (j = 0; j < key->columns; j++) { | |
144 | for(t = 0; t < 4; t++) | |
145 | /* parse input stream into rectangular array */ | |
146 | localBlock[t][j] = input[4*j+t]; | |
147 | } | |
148 | rijndaelEncrypt (localBlock, key->keyLen, key->blockLen, key->keySched); | |
149 | for (j = 0; j < key->columns; j++) { | |
150 | /* parse rectangular array into output ciphertext bytes */ | |
151 | for(t = 0; t < 4; t++) | |
152 | outBuffer[4*j+t] = (word8) localBlock[t][j]; | |
153 | } | |
154 | memset(localBlock, 0, 4 * MAXBC); | |
155 | return key->blockLen; | |
156 | } | |
157 | ||
158 | int rijndaelBlockDecrypt( | |
159 | keyInstance *key, | |
160 | word8 *input, | |
161 | word8 *outBuffer) | |
162 | { | |
df0e469f A |
163 | int t; |
164 | unsigned j; | |
bac41a7b A |
165 | word8 localBlock[4][MAXBC]; // working memory: encrypt/decrypt in place here |
166 | ||
167 | #if AES_CONSISTENCY_CHECK | |
168 | if (key == NULL || | |
169 | (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) || | |
170 | (key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) { | |
171 | return BAD_KEY_INSTANCE; | |
172 | } | |
173 | #endif /* AES_CONSISTENCY_CHECK */ | |
174 | ||
175 | #if defined(__ppc__) && defined(ALTIVEC_ENABLE) | |
176 | if(gHasAltivec && (cipher->blockLen == 128)) { | |
177 | vBlockDecrypt128(key, input, outBuffer); | |
178 | return 128; | |
179 | } | |
180 | #endif | |
181 | ||
182 | for (j = 0; j < key->columns; j++) { | |
183 | for(t = 0; t < 4; t++) | |
184 | /* parse input stream into rectangular array */ | |
185 | localBlock[t][j] = input[4*j+t]; | |
186 | } | |
187 | rijndaelDecrypt (localBlock, key->keyLen, key->blockLen, key->keySched); | |
188 | for (j = 0; j < key->columns; j++) { | |
189 | /* parse rectangular array into output ciphertext bytes */ | |
190 | for(t = 0; t < 4; t++) | |
191 | outBuffer[4*j+t] = (word8) localBlock[t][j]; | |
192 | } | |
193 | memset(localBlock, 0, 4 * MAXBC); | |
194 | return key->blockLen; | |
195 | } | |
196 | ||
29654253 | 197 | #if !GLADMAN_AES_128_ENABLE |
bac41a7b A |
198 | /* |
199 | * Optimized routines for 128 bit block and 128 bit key. | |
200 | */ | |
201 | int rijndaelBlockEncrypt128( | |
202 | keyInstance *key, | |
203 | word8 *input, | |
204 | word8 *outBuffer) | |
205 | { | |
206 | int j; | |
207 | word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4))); | |
208 | word8 *row0 = localBlock[0]; | |
209 | word8 *row1 = localBlock[1]; | |
210 | word8 *row2 = localBlock[2]; | |
211 | word8 *row3 = localBlock[3]; | |
212 | ||
213 | /* parse input stream into rectangular array */ | |
214 | for (j = 0; j < BC_128_OPT; j++) { | |
215 | *row0++ = *input++; | |
216 | *row1++ = *input++; | |
217 | *row2++ = *input++; | |
218 | *row3++ = *input++; | |
219 | } | |
220 | rijndaelEncrypt128 (localBlock, key->keySched); | |
221 | ||
222 | /* parse rectangular array into output ciphertext bytes */ | |
223 | row0 = localBlock[0]; | |
224 | row1 = localBlock[1]; | |
225 | row2 = localBlock[2]; | |
226 | row3 = localBlock[3]; | |
227 | ||
228 | for (j = 0; j < BC_128_OPT; j++) { | |
229 | *outBuffer++ = *row0++; | |
230 | *outBuffer++ = *row1++; | |
231 | *outBuffer++ = *row2++; | |
232 | *outBuffer++ = *row3++; | |
233 | } | |
234 | memset(localBlock, 0, 4*BC_128_OPT); | |
235 | return MIN_AES_BLOCK_BITS; | |
236 | } | |
237 | ||
238 | int rijndaelBlockDecrypt128( | |
239 | keyInstance *key, | |
240 | word8 *input, | |
241 | word8 *outBuffer) | |
242 | { | |
243 | int j; | |
244 | word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4))); | |
245 | word8 *row0 = localBlock[0]; | |
246 | word8 *row1 = localBlock[1]; | |
247 | word8 *row2 = localBlock[2]; | |
248 | word8 *row3 = localBlock[3]; | |
249 | ||
250 | /* parse input stream into rectangular array */ | |
251 | for (j = 0; j < BC_128_OPT; j++) { | |
252 | *row0++ = *input++; | |
253 | *row1++ = *input++; | |
254 | *row2++ = *input++; | |
255 | *row3++ = *input++; | |
256 | } | |
257 | ||
258 | rijndaelDecrypt128 (localBlock, key->keySched); | |
259 | ||
260 | /* parse rectangular array into output ciphertext bytes */ | |
261 | row0 = localBlock[0]; | |
262 | row1 = localBlock[1]; | |
263 | row2 = localBlock[2]; | |
264 | row3 = localBlock[3]; | |
265 | ||
266 | for (j = 0; j < BC_128_OPT; j++) { | |
267 | *outBuffer++ = *row0++; | |
268 | *outBuffer++ = *row1++; | |
269 | *outBuffer++ = *row2++; | |
270 | *outBuffer++ = *row3++; | |
271 | } | |
272 | memset(localBlock, 0, 4*BC_128_OPT); | |
273 | return MIN_AES_BLOCK_BITS; | |
274 | } | |
29654253 | 275 | #endif /* !GLADMAN_AES_128_ENABLE */ |
bac41a7b | 276 |