]>
Commit | Line | Data |
---|---|---|
fe150ac2 AP |
1 | /* ==================================================================== |
2 | * Copyright (c) 2008 The OpenSSL Project. All rights reserved. | |
3 | * | |
4 | * Rights for redistribution and usage in source and binary | |
5 | * forms are granted according to the OpenSSL license. | |
6 | */ | |
7 | ||
a3654f05 | 8 | #include <openssl/crypto.h> |
f472ec8c | 9 | #include "modes_lcl.h" |
fe150ac2 AP |
10 | #include <string.h> |
11 | ||
fe150ac2 AP |
12 | /* |
13 | * Trouble with Ciphertext Stealing, CTS, mode is that there is no | |
14 | * common official specification, but couple of cipher/application | |
15 | * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to | |
16 | * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which | |
17 | * deviates from mentioned RFCs. Most notably it allows input to be | |
18 | * of block length and it doesn't flip the order of the last two | |
19 | * blocks. CTS is being discussed even in ECB context, but it's not | |
67a315b6 AP |
20 | * adopted for any known application. This implementation provides |
21 | * two interfaces: one compliant with above mentioned RFCs and one | |
22 | * compliant with the NIST proposal, both extending CBC mode. | |
fe150ac2 AP |
23 | */ |
24 | ||
0f113f3e MC |
25 | size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, |
26 | unsigned char *out, size_t len, | |
27 | const void *key, unsigned char ivec[16], | |
28 | block128_f block) | |
29 | { | |
30 | size_t residue, n; | |
fe150ac2 | 31 | |
0f113f3e MC |
32 | if (len <= 16) |
33 | return 0; | |
fe150ac2 | 34 | |
0f113f3e MC |
35 | if ((residue = len % 16) == 0) |
36 | residue = 16; | |
fe150ac2 | 37 | |
0f113f3e | 38 | len -= residue; |
fe150ac2 | 39 | |
0f113f3e | 40 | CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block); |
fe150ac2 | 41 | |
0f113f3e MC |
42 | in += len; |
43 | out += len; | |
fe150ac2 | 44 | |
0f113f3e MC |
45 | for (n = 0; n < residue; ++n) |
46 | ivec[n] ^= in[n]; | |
47 | (*block) (ivec, ivec, key); | |
48 | memcpy(out, out - 16, residue); | |
49 | memcpy(out - 16, ivec, 16); | |
fe150ac2 | 50 | |
0f113f3e | 51 | return len + residue; |
fe150ac2 AP |
52 | } |
53 | ||
0f113f3e MC |
54 | size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, |
55 | unsigned char *out, size_t len, | |
56 | const void *key, | |
57 | unsigned char ivec[16], | |
58 | block128_f block) | |
59 | { | |
60 | size_t residue, n; | |
67a315b6 | 61 | |
0f113f3e MC |
62 | if (len < 16) |
63 | return 0; | |
67a315b6 | 64 | |
0f113f3e | 65 | residue = len % 16; |
67a315b6 | 66 | |
0f113f3e | 67 | len -= residue; |
67a315b6 | 68 | |
0f113f3e | 69 | CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block); |
67a315b6 | 70 | |
0f113f3e MC |
71 | if (residue == 0) |
72 | return len; | |
67a315b6 | 73 | |
0f113f3e MC |
74 | in += len; |
75 | out += len; | |
67a315b6 | 76 | |
0f113f3e MC |
77 | for (n = 0; n < residue; ++n) |
78 | ivec[n] ^= in[n]; | |
79 | (*block) (ivec, ivec, key); | |
80 | memcpy(out - 16 + residue, ivec, 16); | |
67a315b6 | 81 | |
0f113f3e | 82 | return len + residue; |
67a315b6 AP |
83 | } |
84 | ||
fe150ac2 | 85 | size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, |
0f113f3e MC |
86 | size_t len, const void *key, |
87 | unsigned char ivec[16], cbc128_f cbc) | |
88 | { | |
89 | size_t residue; | |
90 | union { | |
91 | size_t align; | |
92 | unsigned char c[16]; | |
93 | } tmp; | |
fe150ac2 | 94 | |
0f113f3e MC |
95 | if (len <= 16) |
96 | return 0; | |
fe150ac2 | 97 | |
0f113f3e MC |
98 | if ((residue = len % 16) == 0) |
99 | residue = 16; | |
fe150ac2 | 100 | |
0f113f3e | 101 | len -= residue; |
fe150ac2 | 102 | |
0f113f3e | 103 | (*cbc) (in, out, len, key, ivec, 1); |
fe150ac2 | 104 | |
0f113f3e MC |
105 | in += len; |
106 | out += len; | |
fe150ac2 AP |
107 | |
108 | #if defined(CBC_HANDLES_TRUNCATED_IO) | |
0f113f3e MC |
109 | memcpy(tmp.c, out - 16, 16); |
110 | (*cbc) (in, out - 16, residue, key, ivec, 1); | |
111 | memcpy(out, tmp.c, residue); | |
fe150ac2 | 112 | #else |
0f113f3e MC |
113 | memset(tmp.c, 0, sizeof(tmp)); |
114 | memcpy(tmp.c, in, residue); | |
115 | memcpy(out, out - 16, residue); | |
116 | (*cbc) (tmp.c, out - 16, 16, key, ivec, 1); | |
fe150ac2 | 117 | #endif |
0f113f3e | 118 | return len + residue; |
fe150ac2 AP |
119 | } |
120 | ||
67a315b6 | 121 | size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, |
0f113f3e MC |
122 | size_t len, const void *key, |
123 | unsigned char ivec[16], cbc128_f cbc) | |
124 | { | |
125 | size_t residue; | |
126 | union { | |
127 | size_t align; | |
128 | unsigned char c[16]; | |
129 | } tmp; | |
67a315b6 | 130 | |
0f113f3e MC |
131 | if (len < 16) |
132 | return 0; | |
67a315b6 | 133 | |
0f113f3e | 134 | residue = len % 16; |
67a315b6 | 135 | |
0f113f3e | 136 | len -= residue; |
67a315b6 | 137 | |
0f113f3e | 138 | (*cbc) (in, out, len, key, ivec, 1); |
67a315b6 | 139 | |
0f113f3e MC |
140 | if (residue == 0) |
141 | return len; | |
67a315b6 | 142 | |
0f113f3e MC |
143 | in += len; |
144 | out += len; | |
67a315b6 AP |
145 | |
146 | #if defined(CBC_HANDLES_TRUNCATED_IO) | |
0f113f3e | 147 | (*cbc) (in, out - 16 + residue, residue, key, ivec, 1); |
67a315b6 | 148 | #else |
0f113f3e MC |
149 | memset(tmp.c, 0, sizeof(tmp)); |
150 | memcpy(tmp.c, in, residue); | |
151 | (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1); | |
67a315b6 | 152 | #endif |
0f113f3e | 153 | return len + residue; |
67a315b6 AP |
154 | } |
155 | ||
0f113f3e MC |
156 | size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, |
157 | unsigned char *out, size_t len, | |
158 | const void *key, unsigned char ivec[16], | |
159 | block128_f block) | |
160 | { | |
161 | size_t residue, n; | |
162 | union { | |
163 | size_t align; | |
164 | unsigned char c[32]; | |
165 | } tmp; | |
fe150ac2 | 166 | |
0f113f3e MC |
167 | if (len <= 16) |
168 | return 0; | |
fe150ac2 | 169 | |
0f113f3e MC |
170 | if ((residue = len % 16) == 0) |
171 | residue = 16; | |
fe150ac2 | 172 | |
0f113f3e | 173 | len -= 16 + residue; |
fe150ac2 | 174 | |
0f113f3e MC |
175 | if (len) { |
176 | CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); | |
177 | in += len; | |
178 | out += len; | |
179 | } | |
fe150ac2 | 180 | |
0f113f3e | 181 | (*block) (in, tmp.c + 16, key); |
fe150ac2 | 182 | |
0f113f3e MC |
183 | memcpy(tmp.c, tmp.c + 16, 16); |
184 | memcpy(tmp.c, in + 16, residue); | |
185 | (*block) (tmp.c, tmp.c, key); | |
fe150ac2 | 186 | |
0f113f3e MC |
187 | for (n = 0; n < 16; ++n) { |
188 | unsigned char c = in[n]; | |
189 | out[n] = tmp.c[n] ^ ivec[n]; | |
190 | ivec[n] = c; | |
191 | } | |
192 | for (residue += 16; n < residue; ++n) | |
193 | out[n] = tmp.c[n] ^ in[n]; | |
fe150ac2 | 194 | |
0f113f3e | 195 | return 16 + len + residue; |
67a315b6 AP |
196 | } |
197 | ||
0f113f3e MC |
198 | size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, |
199 | unsigned char *out, size_t len, | |
200 | const void *key, | |
201 | unsigned char ivec[16], | |
202 | block128_f block) | |
203 | { | |
204 | size_t residue, n; | |
205 | union { | |
206 | size_t align; | |
207 | unsigned char c[32]; | |
208 | } tmp; | |
67a315b6 | 209 | |
0f113f3e MC |
210 | if (len < 16) |
211 | return 0; | |
67a315b6 | 212 | |
0f113f3e | 213 | residue = len % 16; |
67a315b6 | 214 | |
0f113f3e MC |
215 | if (residue == 0) { |
216 | CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); | |
217 | return len; | |
218 | } | |
67a315b6 | 219 | |
0f113f3e | 220 | len -= 16 + residue; |
67a315b6 | 221 | |
0f113f3e MC |
222 | if (len) { |
223 | CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); | |
224 | in += len; | |
225 | out += len; | |
226 | } | |
67a315b6 | 227 | |
0f113f3e | 228 | (*block) (in + residue, tmp.c + 16, key); |
67a315b6 | 229 | |
0f113f3e MC |
230 | memcpy(tmp.c, tmp.c + 16, 16); |
231 | memcpy(tmp.c, in, residue); | |
232 | (*block) (tmp.c, tmp.c, key); | |
67a315b6 | 233 | |
0f113f3e MC |
234 | for (n = 0; n < 16; ++n) { |
235 | unsigned char c = in[n]; | |
236 | out[n] = tmp.c[n] ^ ivec[n]; | |
237 | ivec[n] = in[n + residue]; | |
238 | tmp.c[n] = c; | |
239 | } | |
240 | for (residue += 16; n < residue; ++n) | |
241 | out[n] = tmp.c[n] ^ tmp.c[n - 16]; | |
67a315b6 | 242 | |
0f113f3e | 243 | return 16 + len + residue; |
fe150ac2 AP |
244 | } |
245 | ||
246 | size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, | |
0f113f3e MC |
247 | size_t len, const void *key, |
248 | unsigned char ivec[16], cbc128_f cbc) | |
249 | { | |
250 | size_t residue; | |
251 | union { | |
252 | size_t align; | |
253 | unsigned char c[32]; | |
254 | } tmp; | |
fe150ac2 | 255 | |
0f113f3e MC |
256 | if (len <= 16) |
257 | return 0; | |
fe150ac2 | 258 | |
0f113f3e MC |
259 | if ((residue = len % 16) == 0) |
260 | residue = 16; | |
fe150ac2 | 261 | |
0f113f3e | 262 | len -= 16 + residue; |
fe150ac2 | 263 | |
0f113f3e MC |
264 | if (len) { |
265 | (*cbc) (in, out, len, key, ivec, 0); | |
266 | in += len; | |
267 | out += len; | |
268 | } | |
fe150ac2 | 269 | |
0f113f3e MC |
270 | memset(tmp.c, 0, sizeof(tmp)); |
271 | /* | |
272 | * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] | |
273 | */ | |
274 | (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0); | |
fe150ac2 | 275 | |
0f113f3e | 276 | memcpy(tmp.c, in + 16, residue); |
fe150ac2 | 277 | #if defined(CBC_HANDLES_TRUNCATED_IO) |
0f113f3e | 278 | (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0); |
fe150ac2 | 279 | #else |
0f113f3e MC |
280 | (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0); |
281 | memcpy(out, tmp.c, 16 + residue); | |
fe150ac2 | 282 | #endif |
0f113f3e | 283 | return 16 + len + residue; |
67a315b6 AP |
284 | } |
285 | ||
286 | size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, | |
0f113f3e MC |
287 | size_t len, const void *key, |
288 | unsigned char ivec[16], cbc128_f cbc) | |
289 | { | |
290 | size_t residue; | |
291 | union { | |
292 | size_t align; | |
293 | unsigned char c[32]; | |
294 | } tmp; | |
67a315b6 | 295 | |
0f113f3e MC |
296 | if (len < 16) |
297 | return 0; | |
67a315b6 | 298 | |
0f113f3e | 299 | residue = len % 16; |
67a315b6 | 300 | |
0f113f3e MC |
301 | if (residue == 0) { |
302 | (*cbc) (in, out, len, key, ivec, 0); | |
303 | return len; | |
304 | } | |
67a315b6 | 305 | |
0f113f3e | 306 | len -= 16 + residue; |
67a315b6 | 307 | |
0f113f3e MC |
308 | if (len) { |
309 | (*cbc) (in, out, len, key, ivec, 0); | |
310 | in += len; | |
311 | out += len; | |
312 | } | |
67a315b6 | 313 | |
0f113f3e MC |
314 | memset(tmp.c, 0, sizeof(tmp)); |
315 | /* | |
316 | * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] | |
317 | */ | |
318 | (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0); | |
67a315b6 | 319 | |
0f113f3e | 320 | memcpy(tmp.c, in, residue); |
67a315b6 | 321 | #if defined(CBC_HANDLES_TRUNCATED_IO) |
0f113f3e | 322 | (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0); |
67a315b6 | 323 | #else |
0f113f3e MC |
324 | (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0); |
325 | memcpy(out, tmp.c, 16 + residue); | |
67a315b6 | 326 | #endif |
0f113f3e | 327 | return 16 + len + residue; |
fe150ac2 AP |
328 | } |
329 | ||
330 | #if defined(SELFTEST) | |
0f113f3e MC |
331 | # include <stdio.h> |
332 | # include <openssl/aes.h> | |
fe150ac2 AP |
333 | |
334 | /* test vectors from RFC 3962 */ | |
335 | static const unsigned char test_key[16] = "chicken teriyaki"; | |
336 | static const unsigned char test_input[64] = | |
0f113f3e MC |
337 | "I would like the" " General Gau's C" |
338 | "hicken, please, " "and wonton soup."; | |
339 | static const unsigned char test_iv[16] = | |
340 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |
fe150ac2 | 341 | |
6ea3d183 | 342 | static const unsigned char vector_17[17] = { |
0f113f3e MC |
343 | 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, |
344 | 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, | |
345 | 0x97 | |
346 | }; | |
347 | ||
6ea3d183 | 348 | static const unsigned char vector_31[31] = { |
0f113f3e MC |
349 | 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, |
350 | 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22, | |
351 | 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, | |
352 | 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5 | |
353 | }; | |
354 | ||
6ea3d183 | 355 | static const unsigned char vector_32[32] = { |
0f113f3e MC |
356 | 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, |
357 | 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, | |
358 | 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, | |
359 | 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84 | |
360 | }; | |
361 | ||
6ea3d183 | 362 | static const unsigned char vector_47[47] = { |
0f113f3e MC |
363 | 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, |
364 | 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, | |
365 | 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, | |
366 | 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, | |
367 | 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, | |
368 | 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5 | |
369 | }; | |
370 | ||
6ea3d183 | 371 | static const unsigned char vector_48[48] = { |
0f113f3e MC |
372 | 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, |
373 | 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, | |
374 | 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, | |
375 | 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, | |
376 | 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, | |
377 | 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 | |
378 | }; | |
379 | ||
6ea3d183 | 380 | static const unsigned char vector_64[64] = { |
0f113f3e MC |
381 | 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, |
382 | 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, | |
383 | 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, | |
384 | 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, | |
385 | 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, | |
386 | 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40, | |
387 | 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, | |
388 | 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 | |
389 | }; | |
fe150ac2 AP |
390 | |
391 | static AES_KEY encks, decks; | |
392 | ||
0f113f3e MC |
393 | void test_vector(const unsigned char *vector, size_t len) |
394 | { | |
395 | unsigned char iv[sizeof(test_iv)]; | |
396 | unsigned char cleartext[64], ciphertext[64]; | |
397 | size_t tail; | |
398 | ||
399 | printf("vector_%d\n", len); | |
400 | fflush(stdout); | |
401 | ||
402 | if ((tail = len % 16) == 0) | |
403 | tail = 16; | |
404 | tail += 16; | |
405 | ||
406 | /* test block-based encryption */ | |
407 | memcpy(iv, test_iv, sizeof(test_iv)); | |
408 | CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv, | |
409 | (block128_f) AES_encrypt); | |
410 | if (memcmp(ciphertext, vector, len)) | |
411 | fprintf(stderr, "output_%d mismatch\n", len), exit(1); | |
412 | if (memcmp(iv, vector + len - tail, sizeof(iv))) | |
413 | fprintf(stderr, "iv_%d mismatch\n", len), exit(1); | |
414 | ||
415 | /* test block-based decryption */ | |
416 | memcpy(iv, test_iv, sizeof(test_iv)); | |
417 | CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv, | |
418 | (block128_f) AES_decrypt); | |
419 | if (memcmp(cleartext, test_input, len)) | |
420 | fprintf(stderr, "input_%d mismatch\n", len), exit(2); | |
421 | if (memcmp(iv, vector + len - tail, sizeof(iv))) | |
422 | fprintf(stderr, "iv_%d mismatch\n", len), exit(2); | |
423 | ||
424 | /* test streamed encryption */ | |
425 | memcpy(iv, test_iv, sizeof(test_iv)); | |
426 | CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv, | |
427 | (cbc128_f) AES_cbc_encrypt); | |
428 | if (memcmp(ciphertext, vector, len)) | |
429 | fprintf(stderr, "output_%d mismatch\n", len), exit(3); | |
430 | if (memcmp(iv, vector + len - tail, sizeof(iv))) | |
431 | fprintf(stderr, "iv_%d mismatch\n", len), exit(3); | |
432 | ||
433 | /* test streamed decryption */ | |
434 | memcpy(iv, test_iv, sizeof(test_iv)); | |
435 | CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv, | |
436 | (cbc128_f) AES_cbc_encrypt); | |
437 | if (memcmp(cleartext, test_input, len)) | |
438 | fprintf(stderr, "input_%d mismatch\n", len), exit(4); | |
439 | if (memcmp(iv, vector + len - tail, sizeof(iv))) | |
440 | fprintf(stderr, "iv_%d mismatch\n", len), exit(4); | |
fe150ac2 AP |
441 | } |
442 | ||
0f113f3e MC |
443 | void test_nistvector(const unsigned char *vector, size_t len) |
444 | { | |
445 | unsigned char iv[sizeof(test_iv)]; | |
446 | unsigned char cleartext[64], ciphertext[64], nistvector[64]; | |
447 | size_t tail; | |
448 | ||
449 | printf("nistvector_%d\n", len); | |
450 | fflush(stdout); | |
451 | ||
452 | if ((tail = len % 16) == 0) | |
453 | tail = 16; | |
454 | ||
455 | len -= 16 + tail; | |
456 | memcpy(nistvector, vector, len); | |
457 | /* flip two last blocks */ | |
458 | memcpy(nistvector + len, vector + len + 16, tail); | |
459 | memcpy(nistvector + len + tail, vector + len, 16); | |
460 | len += 16 + tail; | |
461 | tail = 16; | |
462 | ||
463 | /* test block-based encryption */ | |
464 | memcpy(iv, test_iv, sizeof(test_iv)); | |
465 | CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv, | |
466 | (block128_f) AES_encrypt); | |
467 | if (memcmp(ciphertext, nistvector, len)) | |
468 | fprintf(stderr, "output_%d mismatch\n", len), exit(1); | |
469 | if (memcmp(iv, nistvector + len - tail, sizeof(iv))) | |
470 | fprintf(stderr, "iv_%d mismatch\n", len), exit(1); | |
471 | ||
472 | /* test block-based decryption */ | |
473 | memcpy(iv, test_iv, sizeof(test_iv)); | |
474 | CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv, | |
475 | (block128_f) AES_decrypt); | |
476 | if (memcmp(cleartext, test_input, len)) | |
477 | fprintf(stderr, "input_%d mismatch\n", len), exit(2); | |
478 | if (memcmp(iv, nistvector + len - tail, sizeof(iv))) | |
479 | fprintf(stderr, "iv_%d mismatch\n", len), exit(2); | |
480 | ||
481 | /* test streamed encryption */ | |
482 | memcpy(iv, test_iv, sizeof(test_iv)); | |
483 | CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv, | |
484 | (cbc128_f) AES_cbc_encrypt); | |
485 | if (memcmp(ciphertext, nistvector, len)) | |
486 | fprintf(stderr, "output_%d mismatch\n", len), exit(3); | |
487 | if (memcmp(iv, nistvector + len - tail, sizeof(iv))) | |
488 | fprintf(stderr, "iv_%d mismatch\n", len), exit(3); | |
489 | ||
490 | /* test streamed decryption */ | |
491 | memcpy(iv, test_iv, sizeof(test_iv)); | |
492 | CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv, | |
493 | (cbc128_f) AES_cbc_encrypt); | |
494 | if (memcmp(cleartext, test_input, len)) | |
495 | fprintf(stderr, "input_%d mismatch\n", len), exit(4); | |
496 | if (memcmp(iv, nistvector + len - tail, sizeof(iv))) | |
497 | fprintf(stderr, "iv_%d mismatch\n", len), exit(4); | |
67a315b6 AP |
498 | } |
499 | ||
500 | int main() | |
fe150ac2 | 501 | { |
0f113f3e MC |
502 | AES_set_encrypt_key(test_key, 128, &encks); |
503 | AES_set_decrypt_key(test_key, 128, &decks); | |
504 | ||
505 | test_vector(vector_17, sizeof(vector_17)); | |
506 | test_vector(vector_31, sizeof(vector_31)); | |
507 | test_vector(vector_32, sizeof(vector_32)); | |
508 | test_vector(vector_47, sizeof(vector_47)); | |
509 | test_vector(vector_48, sizeof(vector_48)); | |
510 | test_vector(vector_64, sizeof(vector_64)); | |
511 | ||
512 | test_nistvector(vector_17, sizeof(vector_17)); | |
513 | test_nistvector(vector_31, sizeof(vector_31)); | |
514 | test_nistvector(vector_32, sizeof(vector_32)); | |
515 | test_nistvector(vector_47, sizeof(vector_47)); | |
516 | test_nistvector(vector_48, sizeof(vector_48)); | |
517 | test_nistvector(vector_64, sizeof(vector_64)); | |
518 | ||
519 | return 0; | |
fe150ac2 AP |
520 | } |
521 | #endif |