]>
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 | { | |
124 | int j, t; | |
125 | word8 localBlock[4][MAXBC]; // working memory: encrypt/decrypt in place here | |
126 | ||
127 | #if AES_CONSISTENCY_CHECK | |
128 | if (key == NULL || | |
129 | (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) || | |
130 | (key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) { | |
131 | return BAD_KEY_INSTANCE; | |
132 | } | |
133 | #endif /* AES_CONSISTENCY_CHECK */ | |
134 | ||
135 | #if defined(__ppc__) && defined(ALTIVEC_ENABLE) | |
136 | if(gHasAltivec && (key->blockLen == 128)) { | |
137 | vBlockEncrypt128(key, input, outBuffer); | |
138 | return 128; | |
139 | } | |
140 | #endif | |
141 | ||
142 | for (j = 0; j < key->columns; j++) { | |
143 | for(t = 0; t < 4; t++) | |
144 | /* parse input stream into rectangular array */ | |
145 | localBlock[t][j] = input[4*j+t]; | |
146 | } | |
147 | rijndaelEncrypt (localBlock, key->keyLen, key->blockLen, key->keySched); | |
148 | for (j = 0; j < key->columns; j++) { | |
149 | /* parse rectangular array into output ciphertext bytes */ | |
150 | for(t = 0; t < 4; t++) | |
151 | outBuffer[4*j+t] = (word8) localBlock[t][j]; | |
152 | } | |
153 | memset(localBlock, 0, 4 * MAXBC); | |
154 | return key->blockLen; | |
155 | } | |
156 | ||
157 | int rijndaelBlockDecrypt( | |
158 | keyInstance *key, | |
159 | word8 *input, | |
160 | word8 *outBuffer) | |
161 | { | |
162 | int j, t; | |
163 | word8 localBlock[4][MAXBC]; // working memory: encrypt/decrypt in place here | |
164 | ||
165 | #if AES_CONSISTENCY_CHECK | |
166 | if (key == NULL || | |
167 | (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256) || | |
168 | (key->blockLen != 128 && key->blockLen != 192 && key->blockLen != 256)) { | |
169 | return BAD_KEY_INSTANCE; | |
170 | } | |
171 | #endif /* AES_CONSISTENCY_CHECK */ | |
172 | ||
173 | #if defined(__ppc__) && defined(ALTIVEC_ENABLE) | |
174 | if(gHasAltivec && (cipher->blockLen == 128)) { | |
175 | vBlockDecrypt128(key, input, outBuffer); | |
176 | return 128; | |
177 | } | |
178 | #endif | |
179 | ||
180 | for (j = 0; j < key->columns; j++) { | |
181 | for(t = 0; t < 4; t++) | |
182 | /* parse input stream into rectangular array */ | |
183 | localBlock[t][j] = input[4*j+t]; | |
184 | } | |
185 | rijndaelDecrypt (localBlock, key->keyLen, key->blockLen, key->keySched); | |
186 | for (j = 0; j < key->columns; j++) { | |
187 | /* parse rectangular array into output ciphertext bytes */ | |
188 | for(t = 0; t < 4; t++) | |
189 | outBuffer[4*j+t] = (word8) localBlock[t][j]; | |
190 | } | |
191 | memset(localBlock, 0, 4 * MAXBC); | |
192 | return key->blockLen; | |
193 | } | |
194 | ||
29654253 | 195 | #if !GLADMAN_AES_128_ENABLE |
bac41a7b A |
196 | /* |
197 | * Optimized routines for 128 bit block and 128 bit key. | |
198 | */ | |
199 | int rijndaelBlockEncrypt128( | |
200 | keyInstance *key, | |
201 | word8 *input, | |
202 | word8 *outBuffer) | |
203 | { | |
204 | int j; | |
205 | word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4))); | |
206 | word8 *row0 = localBlock[0]; | |
207 | word8 *row1 = localBlock[1]; | |
208 | word8 *row2 = localBlock[2]; | |
209 | word8 *row3 = localBlock[3]; | |
210 | ||
211 | /* parse input stream into rectangular array */ | |
212 | for (j = 0; j < BC_128_OPT; j++) { | |
213 | *row0++ = *input++; | |
214 | *row1++ = *input++; | |
215 | *row2++ = *input++; | |
216 | *row3++ = *input++; | |
217 | } | |
218 | rijndaelEncrypt128 (localBlock, key->keySched); | |
219 | ||
220 | /* parse rectangular array into output ciphertext bytes */ | |
221 | row0 = localBlock[0]; | |
222 | row1 = localBlock[1]; | |
223 | row2 = localBlock[2]; | |
224 | row3 = localBlock[3]; | |
225 | ||
226 | for (j = 0; j < BC_128_OPT; j++) { | |
227 | *outBuffer++ = *row0++; | |
228 | *outBuffer++ = *row1++; | |
229 | *outBuffer++ = *row2++; | |
230 | *outBuffer++ = *row3++; | |
231 | } | |
232 | memset(localBlock, 0, 4*BC_128_OPT); | |
233 | return MIN_AES_BLOCK_BITS; | |
234 | } | |
235 | ||
236 | int rijndaelBlockDecrypt128( | |
237 | keyInstance *key, | |
238 | word8 *input, | |
239 | word8 *outBuffer) | |
240 | { | |
241 | int j; | |
242 | word8 localBlock[4][BC_128_OPT] __attribute__((aligned(4))); | |
243 | word8 *row0 = localBlock[0]; | |
244 | word8 *row1 = localBlock[1]; | |
245 | word8 *row2 = localBlock[2]; | |
246 | word8 *row3 = localBlock[3]; | |
247 | ||
248 | /* parse input stream into rectangular array */ | |
249 | for (j = 0; j < BC_128_OPT; j++) { | |
250 | *row0++ = *input++; | |
251 | *row1++ = *input++; | |
252 | *row2++ = *input++; | |
253 | *row3++ = *input++; | |
254 | } | |
255 | ||
256 | rijndaelDecrypt128 (localBlock, key->keySched); | |
257 | ||
258 | /* parse rectangular array into output ciphertext bytes */ | |
259 | row0 = localBlock[0]; | |
260 | row1 = localBlock[1]; | |
261 | row2 = localBlock[2]; | |
262 | row3 = localBlock[3]; | |
263 | ||
264 | for (j = 0; j < BC_128_OPT; j++) { | |
265 | *outBuffer++ = *row0++; | |
266 | *outBuffer++ = *row1++; | |
267 | *outBuffer++ = *row2++; | |
268 | *outBuffer++ = *row3++; | |
269 | } | |
270 | memset(localBlock, 0, 4*BC_128_OPT); | |
271 | return MIN_AES_BLOCK_BITS; | |
272 | } | |
29654253 | 273 | #endif /* !GLADMAN_AES_128_ENABLE */ |
bac41a7b | 274 |