]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/rijndaelApi.c
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / rijndaelApi.c
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple 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 */
83 #if !GLADMAN_AES_128_ENABLE
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 }
97 else
98 #endif /* !GLADMAN_AES_128_ENABLE */
99 {
100
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 t;
125 unsigned j;
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 {
163 int t;
164 unsigned j;
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
197 #if !GLADMAN_AES_128_ENABLE
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 }
275 #endif /* !GLADMAN_AES_128_ENABLE */
276