source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cts128.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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