]> git.saurik.com Git - apple/security.git/blame - AppleCSP/AES/rijndaelApi.c
Security-54.1.9.tar.gz
[apple/security.git] / AppleCSP / AES / rijndaelApi.c
CommitLineData
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 */
34int gHasAltivec = 0;
35#endif
36
37int doAES128 = 1;
38
39#define CBC_DEBUG 0
40#if CBC_DEBUG
41static 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
58int 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
119int 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
157int 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 */
199int 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
236int 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