if_iwm - Recognize IWM_FW_PAGING_BLOCK_CMD wide cmd response correctly.
[dragonfly.git] / crypto / openssl / crypto / modes / cts128.c
blob137be595a1055b4c4447c73e373dedfe36e43e84
1 /* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
4 * Rights for redistribution and usage in source and binary
5 * forms are granted according to the OpenSSL license.
6 */
8 #include <openssl/crypto.h>
9 #include "modes_lcl.h"
10 #include <string.h>
12 #ifndef MODES_DEBUG
13 # ifndef NDEBUG
14 # define NDEBUG
15 # endif
16 #endif
17 #include <assert.h>
20 * Trouble with Ciphertext Stealing, CTS, mode is that there is no
21 * common official specification, but couple of cipher/application
22 * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
23 * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
24 * deviates from mentioned RFCs. Most notably it allows input to be
25 * of block length and it doesn't flip the order of the last two
26 * blocks. CTS is being discussed even in ECB context, but it's not
27 * adopted for any known application. This implementation provides
28 * two interfaces: one compliant with above mentioned RFCs and one
29 * compliant with the NIST proposal, both extending CBC mode.
32 size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
33 unsigned char *out, size_t len,
34 const void *key, unsigned char ivec[16],
35 block128_f block)
37 size_t residue, n;
39 assert(in && out && key && ivec);
41 if (len <= 16)
42 return 0;
44 if ((residue = len % 16) == 0)
45 residue = 16;
47 len -= residue;
49 CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
51 in += len;
52 out += len;
54 for (n = 0; n < residue; ++n)
55 ivec[n] ^= in[n];
56 (*block) (ivec, ivec, key);
57 memcpy(out, out - 16, residue);
58 memcpy(out - 16, ivec, 16);
60 return len + residue;
63 size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
64 unsigned char *out, size_t len,
65 const void *key,
66 unsigned char ivec[16],
67 block128_f block)
69 size_t residue, n;
71 assert(in && out && key && ivec);
73 if (len < 16)
74 return 0;
76 residue = len % 16;
78 len -= residue;
80 CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
82 if (residue == 0)
83 return len;
85 in += len;
86 out += len;
88 for (n = 0; n < residue; ++n)
89 ivec[n] ^= in[n];
90 (*block) (ivec, ivec, key);
91 memcpy(out - 16 + residue, ivec, 16);
93 return len + residue;
96 size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
97 size_t len, const void *key,
98 unsigned char ivec[16], cbc128_f cbc)
100 size_t residue;
101 union {
102 size_t align;
103 unsigned char c[16];
104 } tmp;
106 assert(in && out && key && ivec);
108 if (len <= 16)
109 return 0;
111 if ((residue = len % 16) == 0)
112 residue = 16;
114 len -= residue;
116 (*cbc) (in, out, len, key, ivec, 1);
118 in += len;
119 out += len;
121 #if defined(CBC_HANDLES_TRUNCATED_IO)
122 memcpy(tmp.c, out - 16, 16);
123 (*cbc) (in, out - 16, residue, key, ivec, 1);
124 memcpy(out, tmp.c, residue);
125 #else
126 memset(tmp.c, 0, sizeof(tmp));
127 memcpy(tmp.c, in, residue);
128 memcpy(out, out - 16, residue);
129 (*cbc) (tmp.c, out - 16, 16, key, ivec, 1);
130 #endif
131 return len + residue;
134 size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
135 size_t len, const void *key,
136 unsigned char ivec[16], cbc128_f cbc)
138 size_t residue;
139 union {
140 size_t align;
141 unsigned char c[16];
142 } tmp;
144 assert(in && out && key && ivec);
146 if (len < 16)
147 return 0;
149 residue = len % 16;
151 len -= residue;
153 (*cbc) (in, out, len, key, ivec, 1);
155 if (residue == 0)
156 return len;
158 in += len;
159 out += len;
161 #if defined(CBC_HANDLES_TRUNCATED_IO)
162 (*cbc) (in, out - 16 + residue, residue, key, ivec, 1);
163 #else
164 memset(tmp.c, 0, sizeof(tmp));
165 memcpy(tmp.c, in, residue);
166 (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1);
167 #endif
168 return len + residue;
171 size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
172 unsigned char *out, size_t len,
173 const void *key, unsigned char ivec[16],
174 block128_f block)
176 size_t residue, n;
177 union {
178 size_t align;
179 unsigned char c[32];
180 } tmp;
182 assert(in && out && key && ivec);
184 if (len <= 16)
185 return 0;
187 if ((residue = len % 16) == 0)
188 residue = 16;
190 len -= 16 + residue;
192 if (len) {
193 CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
194 in += len;
195 out += len;
198 (*block) (in, tmp.c + 16, key);
200 memcpy(tmp.c, tmp.c + 16, 16);
201 memcpy(tmp.c, in + 16, residue);
202 (*block) (tmp.c, tmp.c, key);
204 for (n = 0; n < 16; ++n) {
205 unsigned char c = in[n];
206 out[n] = tmp.c[n] ^ ivec[n];
207 ivec[n] = c;
209 for (residue += 16; n < residue; ++n)
210 out[n] = tmp.c[n] ^ in[n];
212 return 16 + len + residue;
215 size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
216 unsigned char *out, size_t len,
217 const void *key,
218 unsigned char ivec[16],
219 block128_f block)
221 size_t residue, n;
222 union {
223 size_t align;
224 unsigned char c[32];
225 } tmp;
227 assert(in && out && key && ivec);
229 if (len < 16)
230 return 0;
232 residue = len % 16;
234 if (residue == 0) {
235 CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
236 return len;
239 len -= 16 + residue;
241 if (len) {
242 CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
243 in += len;
244 out += len;
247 (*block) (in + residue, tmp.c + 16, key);
249 memcpy(tmp.c, tmp.c + 16, 16);
250 memcpy(tmp.c, in, residue);
251 (*block) (tmp.c, tmp.c, key);
253 for (n = 0; n < 16; ++n) {
254 unsigned char c = in[n];
255 out[n] = tmp.c[n] ^ ivec[n];
256 ivec[n] = in[n + residue];
257 tmp.c[n] = c;
259 for (residue += 16; n < residue; ++n)
260 out[n] = tmp.c[n] ^ tmp.c[n - 16];
262 return 16 + len + residue;
265 size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
266 size_t len, const void *key,
267 unsigned char ivec[16], cbc128_f cbc)
269 size_t residue;
270 union {
271 size_t align;
272 unsigned char c[32];
273 } tmp;
275 assert(in && out && key && ivec);
277 if (len <= 16)
278 return 0;
280 if ((residue = len % 16) == 0)
281 residue = 16;
283 len -= 16 + residue;
285 if (len) {
286 (*cbc) (in, out, len, key, ivec, 0);
287 in += len;
288 out += len;
291 memset(tmp.c, 0, sizeof(tmp));
293 * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
295 (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0);
297 memcpy(tmp.c, in + 16, residue);
298 #if defined(CBC_HANDLES_TRUNCATED_IO)
299 (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
300 #else
301 (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
302 memcpy(out, tmp.c, 16 + residue);
303 #endif
304 return 16 + len + residue;
307 size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
308 size_t len, const void *key,
309 unsigned char ivec[16], cbc128_f cbc)
311 size_t residue;
312 union {
313 size_t align;
314 unsigned char c[32];
315 } tmp;
317 assert(in && out && key && ivec);
319 if (len < 16)
320 return 0;
322 residue = len % 16;
324 if (residue == 0) {
325 (*cbc) (in, out, len, key, ivec, 0);
326 return len;
329 len -= 16 + residue;
331 if (len) {
332 (*cbc) (in, out, len, key, ivec, 0);
333 in += len;
334 out += len;
337 memset(tmp.c, 0, sizeof(tmp));
339 * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
341 (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0);
343 memcpy(tmp.c, in, residue);
344 #if defined(CBC_HANDLES_TRUNCATED_IO)
345 (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
346 #else
347 (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
348 memcpy(out, tmp.c, 16 + residue);
349 #endif
350 return 16 + len + residue;
353 #if defined(SELFTEST)
354 # include <stdio.h>
355 # include <openssl/aes.h>
357 /* test vectors from RFC 3962 */
358 static const unsigned char test_key[16] = "chicken teriyaki";
359 static const unsigned char test_input[64] =
360 "I would like the" " General Gau's C"
361 "hicken, please, " "and wonton soup.";
362 static const unsigned char test_iv[16] =
363 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
365 static const unsigned char vector_17[17] = {
366 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
367 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f,
368 0x97
371 static const unsigned char vector_31[31] = {
372 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
373 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22,
374 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
375 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5
378 static const unsigned char vector_32[32] = {
379 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
380 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
381 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
382 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84
385 static const unsigned char vector_47[47] = {
386 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
387 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
388 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
389 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e,
390 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
391 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
394 static const unsigned char vector_48[48] = {
395 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
396 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
397 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
398 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8,
399 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
400 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
403 static const unsigned char vector_64[64] = {
404 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
405 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
406 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
407 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
408 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
409 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40,
410 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
411 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
414 static AES_KEY encks, decks;
416 void test_vector(const unsigned char *vector, size_t len)
418 unsigned char iv[sizeof(test_iv)];
419 unsigned char cleartext[64], ciphertext[64];
420 size_t tail;
422 printf("vector_%d\n", len);
423 fflush(stdout);
425 if ((tail = len % 16) == 0)
426 tail = 16;
427 tail += 16;
429 /* test block-based encryption */
430 memcpy(iv, test_iv, sizeof(test_iv));
431 CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
432 (block128_f) AES_encrypt);
433 if (memcmp(ciphertext, vector, len))
434 fprintf(stderr, "output_%d mismatch\n", len), exit(1);
435 if (memcmp(iv, vector + len - tail, sizeof(iv)))
436 fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
438 /* test block-based decryption */
439 memcpy(iv, test_iv, sizeof(test_iv));
440 CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
441 (block128_f) AES_decrypt);
442 if (memcmp(cleartext, test_input, len))
443 fprintf(stderr, "input_%d mismatch\n", len), exit(2);
444 if (memcmp(iv, vector + len - tail, sizeof(iv)))
445 fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
447 /* test streamed encryption */
448 memcpy(iv, test_iv, sizeof(test_iv));
449 CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv,
450 (cbc128_f) AES_cbc_encrypt);
451 if (memcmp(ciphertext, vector, len))
452 fprintf(stderr, "output_%d mismatch\n", len), exit(3);
453 if (memcmp(iv, vector + len - tail, sizeof(iv)))
454 fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
456 /* test streamed decryption */
457 memcpy(iv, test_iv, sizeof(test_iv));
458 CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv,
459 (cbc128_f) AES_cbc_encrypt);
460 if (memcmp(cleartext, test_input, len))
461 fprintf(stderr, "input_%d mismatch\n", len), exit(4);
462 if (memcmp(iv, vector + len - tail, sizeof(iv)))
463 fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
466 void test_nistvector(const unsigned char *vector, size_t len)
468 unsigned char iv[sizeof(test_iv)];
469 unsigned char cleartext[64], ciphertext[64], nistvector[64];
470 size_t tail;
472 printf("nistvector_%d\n", len);
473 fflush(stdout);
475 if ((tail = len % 16) == 0)
476 tail = 16;
478 len -= 16 + tail;
479 memcpy(nistvector, vector, len);
480 /* flip two last blocks */
481 memcpy(nistvector + len, vector + len + 16, tail);
482 memcpy(nistvector + len + tail, vector + len, 16);
483 len += 16 + tail;
484 tail = 16;
486 /* test block-based encryption */
487 memcpy(iv, test_iv, sizeof(test_iv));
488 CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
489 (block128_f) AES_encrypt);
490 if (memcmp(ciphertext, nistvector, len))
491 fprintf(stderr, "output_%d mismatch\n", len), exit(1);
492 if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
493 fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
495 /* test block-based decryption */
496 memcpy(iv, test_iv, sizeof(test_iv));
497 CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
498 (block128_f) AES_decrypt);
499 if (memcmp(cleartext, test_input, len))
500 fprintf(stderr, "input_%d mismatch\n", len), exit(2);
501 if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
502 fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
504 /* test streamed encryption */
505 memcpy(iv, test_iv, sizeof(test_iv));
506 CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv,
507 (cbc128_f) AES_cbc_encrypt);
508 if (memcmp(ciphertext, nistvector, len))
509 fprintf(stderr, "output_%d mismatch\n", len), exit(3);
510 if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
511 fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
513 /* test streamed decryption */
514 memcpy(iv, test_iv, sizeof(test_iv));
515 CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv,
516 (cbc128_f) AES_cbc_encrypt);
517 if (memcmp(cleartext, test_input, len))
518 fprintf(stderr, "input_%d mismatch\n", len), exit(4);
519 if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
520 fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
523 int main()
525 AES_set_encrypt_key(test_key, 128, &encks);
526 AES_set_decrypt_key(test_key, 128, &decks);
528 test_vector(vector_17, sizeof(vector_17));
529 test_vector(vector_31, sizeof(vector_31));
530 test_vector(vector_32, sizeof(vector_32));
531 test_vector(vector_47, sizeof(vector_47));
532 test_vector(vector_48, sizeof(vector_48));
533 test_vector(vector_64, sizeof(vector_64));
535 test_nistvector(vector_17, sizeof(vector_17));
536 test_nistvector(vector_31, sizeof(vector_31));
537 test_nistvector(vector_32, sizeof(vector_32));
538 test_nistvector(vector_47, sizeof(vector_47));
539 test_nistvector(vector_48, sizeof(vector_48));
540 test_nistvector(vector_64, sizeof(vector_64));
542 return 0;
544 #endif