]>
git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/utilLib/rijndaelApi.c
2 * rijndaelApi.c - AES API layer
4 * Based on rijndael-api-ref.h v2.0 written by Paulo Barreto
10 #include "rijndael-alg-ref.h"
11 #include "rijndaelApi.h"
15 static void dumpChainBuf(cipherInstance
*cipher
, char *op
)
18 int columns
= cipher
->blockLen
/ 32;
20 printf("chainBuf %s: ", op
);
21 for (j
= 0; j
< columns
; j
++) {
22 for(t
= 0; t
< 4; t
++) {
23 printf("%02x ", cipher
->chainBlock
[t
][j
]);
29 #define dumpChainBuf(c, o)
32 int _makeKey( keyInstance
*key
,
34 int keyLen
, // in BITS
35 int blockLen
, // in BITS
43 return BAD_KEY_INSTANCE
;
45 if(keyMaterial
== NULL
) {
48 if ((direction
== DIR_ENCRYPT
) || (direction
== DIR_DECRYPT
)) {
49 key
->direction
= direction
;
54 if ((keyLen
== 128) || (keyLen
== 192) || (keyLen
== 256)) {
59 key
->blockLen
= blockLen
;
61 /* initialize key schedule: */
62 keyBytes
= keyLen
/ 8;
63 for(i
= 0; i
< keyBytes
; i
++) {
64 k
[i
% 4][i
/ 4] = keyMaterial
[i
];
66 _rijndaelKeySched (k
, key
->keyLen
, key
->blockLen
, key
->keySched
);
67 memset(k
, 0, 4 * MAXKC
);
71 int _cipherInit( cipherInstance
*cipher
,
73 int blockLen
, // in BITS
77 int columns
= blockLen
/ 32;
79 /* MODE_CFB1 not supported */
80 if ((mode
== MODE_ECB
) || (mode
== MODE_CBC
)) {
83 return BAD_CIPHER_MODE
;
85 cipher
->blockLen
= blockLen
;
88 /* Save IV in rectangular block format */
89 for (j
= 0; j
< columns
; j
++) {
90 for(t
= 0; t
< 4; t
++) {
91 /* parse initial value into rectangular array */
92 cipher
->chainBlock
[t
][j
] = IV
[t
+4*j
];
96 dumpChainBuf(cipher
, "init ");
101 int _blockEncrypt(cipherInstance
*cipher
,
102 keyInstance
*key
, BYTE
*input
, int inputLen
, BYTE
*outBuffer
)
104 int i
, j
, t
, numBlocks
;
105 unsigned blockSizeBytes
;
108 /* check parameter consistency: */
110 key
->direction
!= DIR_ENCRYPT
||
111 (key
->keyLen
!= 128 && key
->keyLen
!= 192 && key
->keyLen
!= 256)) {
114 if (cipher
== NULL
||
115 (cipher
->mode
!= MODE_ECB
&& cipher
->mode
!= MODE_CBC
) ||
116 (cipher
->blockLen
!= 128 && cipher
->blockLen
!= 192 && cipher
->blockLen
!= 256)) {
117 return BAD_CIPHER_STATE
;
120 numBlocks
= inputLen
/cipher
->blockLen
;
121 blockSizeBytes
= cipher
->blockLen
/ 8;
122 columns
= cipher
->blockLen
/ 32;
124 switch (cipher
->mode
) {
126 for (i
= 0; i
< numBlocks
; i
++) {
127 for (j
= 0; j
< columns
; j
++) {
128 for(t
= 0; t
< 4; t
++)
129 /* parse input stream into rectangular array */
130 cipher
->chainBlock
[t
][j
] = input
[4*j
+t
];
132 _rijndaelEncrypt (cipher
->chainBlock
, key
->keyLen
, cipher
->blockLen
, key
->keySched
);
133 for (j
= 0; j
< columns
; j
++) {
134 /* parse rectangular array into output ciphertext bytes */
135 for(t
= 0; t
< 4; t
++)
136 outBuffer
[4*j
+t
] = (BYTE
) cipher
->chainBlock
[t
][j
];
138 input
+= blockSizeBytes
;
139 outBuffer
+= blockSizeBytes
;
140 dumpChainBuf(cipher
, "encr ECB");
145 for (i
= 0; i
< numBlocks
; i
++) {
146 for (j
= 0; j
< columns
; j
++) {
147 for(t
= 0; t
< 4; t
++)
148 /* parse input stream into rectangular array and exor with
149 IV or the previous ciphertext */
150 cipher
->chainBlock
[t
][j
] ^= input
[4*j
+t
];
152 _rijndaelEncrypt (cipher
->chainBlock
, key
->keyLen
, cipher
->blockLen
, key
->keySched
);
153 for (j
= 0; j
< columns
; j
++) {
154 /* parse rectangular array into output ciphertext bytes */
155 for(t
= 0; t
< 4; t
++)
156 outBuffer
[4*j
+t
] = (BYTE
) cipher
->chainBlock
[t
][j
];
158 /* Hey! This code was broken for multi-block ops! */
159 input
+= blockSizeBytes
;
160 outBuffer
+= blockSizeBytes
;
161 dumpChainBuf(cipher
, "encr CBC");
165 default: return BAD_CIPHER_STATE
;
168 return numBlocks
*cipher
->blockLen
;
171 int _blockDecrypt(cipherInstance
*cipher
,
172 keyInstance
*key
, BYTE
*input
, int inputLen
, BYTE
*outBuffer
)
174 int i
, j
, t
, numBlocks
;
175 word8 block
[4][MAXBC
]; // working memory: encrypt/decrypt in place here
176 unsigned blockSizeBytes
;
177 word8 cblock
[4][MAXBC
]; // saved ciphertext
180 if (cipher
== NULL
||
182 key
->direction
== DIR_ENCRYPT
||
183 cipher
->blockLen
!= key
->blockLen
) {
184 return BAD_CIPHER_STATE
;
187 /* check parameter consistency: */
189 key
->direction
!= DIR_DECRYPT
||
190 (key
->keyLen
!= 128 && key
->keyLen
!= 192 && key
->keyLen
!= 256)) {
193 if (cipher
== NULL
||
194 (cipher
->mode
!= MODE_ECB
&& cipher
->mode
!= MODE_CBC
) ||
195 (cipher
->blockLen
!= 128 && cipher
->blockLen
!= 192 && cipher
->blockLen
!= 256)) {
196 return BAD_CIPHER_STATE
;
199 numBlocks
= inputLen
/cipher
->blockLen
;
200 blockSizeBytes
= cipher
->blockLen
/ 8;
201 columns
= cipher
->blockLen
/ 32;
203 switch (cipher
->mode
) {
205 for (i
= 0; i
< numBlocks
; i
++) {
206 for (j
= 0; j
< columns
; j
++) {
207 for(t
= 0; t
< 4; t
++)
208 /* parse input stream into rectangular array */
209 block
[t
][j
] = input
[4*j
+t
];
211 _rijndaelDecrypt (block
, key
->keyLen
, cipher
->blockLen
, key
->keySched
);
212 for (j
= 0; j
< columns
; j
++) {
213 /* parse rectangular array into output ciphertext bytes */
214 for(t
= 0; t
< 4; t
++)
215 outBuffer
[4*j
+t
] = (BYTE
) block
[t
][j
];
217 input
+= blockSizeBytes
;
218 outBuffer
+= blockSizeBytes
;
219 dumpChainBuf(cipher
, "decr ECB");
224 for (i
= 0; i
< numBlocks
; i
++) {
225 for (j
= 0; j
< columns
; j
++) {
226 for(t
= 0; t
< 4; t
++)
227 /* parse input stream into rectangular array */
228 block
[t
][j
] = input
[4*j
+t
];
231 /* save a copoy of incoming ciphertext for later chain; decrypt */
232 memmove(cblock
, block
, 4*MAXBC
);
233 _rijndaelDecrypt (block
, key
->keyLen
, cipher
->blockLen
, key
->keySched
);
236 * exor with last ciphertext --> plaintext out
237 * save this ciphertext in lastBlock
238 * FIXME - we can optimize this by avoiding the copy into
239 * lastBlock on all but last time thru...
241 for (j
= 0; j
< columns
; j
++) {
242 for(t
= 0; t
< 4; t
++) {
243 outBuffer
[4*j
+t
] = (block
[t
][j
] ^ cipher
->chainBlock
[t
][j
]);
246 memmove(cipher
->chainBlock
, cblock
, 4 * MAXBC
);
247 input
+= blockSizeBytes
;
248 outBuffer
+= blockSizeBytes
;
249 dumpChainBuf(cipher
, "decr CBC");
253 default: return BAD_CIPHER_STATE
;
255 memset(block
, 0, 4 * MAXBC
);
256 memset(cblock
, 0, 4 * MAXBC
);
257 return numBlocks
*cipher
->blockLen
;
261 * Apple addenda 3/28/2001: simplified single-block encrypt/decrypt.
262 * Used when chaining and padding is done in elsewhere.
264 #define AES_CONSISTENCY_CHECK 1
266 int _rijndaelBlockEncrypt(
267 cipherInstance
*cipher
,
273 unsigned blockSizeBytes
;
276 #if AES_CONSISTENCY_CHECK
277 /* check parameter consistency: */
279 key
->direction
!= DIR_ENCRYPT
||
280 (key
->keyLen
!= 128 && key
->keyLen
!= 192 && key
->keyLen
!= 256)) {
283 if (cipher
== NULL
||
284 (cipher
->mode
!= MODE_ECB
&& cipher
->mode
!= MODE_CBC
) ||
285 (cipher
->blockLen
!= 128 && cipher
->blockLen
!= 192 && cipher
->blockLen
!= 256)) {
286 return BAD_CIPHER_STATE
;
288 #endif /* AES_CONSISTENCY_CHECK */
290 blockSizeBytes
= cipher
->blockLen
>> 3; /* was / 8; should just save in cipher */
291 columns
= cipher
->blockLen
>> 5; /* was / 32; ditto */
293 for (j
= 0; j
< columns
; j
++) {
294 for(t
= 0; t
< 4; t
++)
295 /* parse input stream into rectangular array */
296 cipher
->chainBlock
[t
][j
] = input
[4*j
+t
];
298 _rijndaelEncrypt (cipher
->chainBlock
, key
->keyLen
, cipher
->blockLen
,
300 for (j
= 0; j
< columns
; j
++) {
301 /* parse rectangular array into output ciphertext bytes */
302 for(t
= 0; t
< 4; t
++)
303 outBuffer
[4*j
+t
] = (BYTE
) cipher
->chainBlock
[t
][j
];
305 return cipher
->blockLen
;
308 int _rijndaelBlockDecrypt(
309 cipherInstance
*cipher
,
315 word8 block
[4][MAXBC
]; // working memory: encrypt/decrypt in place here
316 unsigned blockSizeBytes
;
319 #if AES_CONSISTENCY_CHECK
320 if (cipher
== NULL
||
322 key
->direction
== DIR_ENCRYPT
||
323 cipher
->blockLen
!= key
->blockLen
) {
324 return BAD_CIPHER_STATE
;
327 /* check parameter consistency: */
329 key
->direction
!= DIR_DECRYPT
||
330 (key
->keyLen
!= 128 && key
->keyLen
!= 192 && key
->keyLen
!= 256)) {
333 if (cipher
== NULL
||
334 (cipher
->mode
!= MODE_ECB
&& cipher
->mode
!= MODE_CBC
) ||
335 (cipher
->blockLen
!= 128 && cipher
->blockLen
!= 192 && cipher
->blockLen
!= 256)) {
336 return BAD_CIPHER_STATE
;
338 #endif /* AES_CONSISTENCY_CHECK */
340 blockSizeBytes
= cipher
->blockLen
>> 3; /* was / 8; should just save in cipher */
341 columns
= cipher
->blockLen
>> 5; /* was / 32; ditto */
343 for (j
= 0; j
< columns
; j
++) {
344 for(t
= 0; t
< 4; t
++)
345 /* parse input stream into rectangular array */
346 block
[t
][j
] = input
[4*j
+t
];
348 _rijndaelDecrypt (block
, key
->keyLen
, cipher
->blockLen
, key
->keySched
);
349 for (j
= 0; j
< columns
; j
++) {
350 /* parse rectangular array into output ciphertext bytes */
351 for(t
= 0; t
< 4; t
++)
352 outBuffer
[4*j
+t
] = (BYTE
) block
[t
][j
];
355 return cipher
->blockLen
;