summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/modes/cts128.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/modes/cts128.c226
1 files changed, 216 insertions, 10 deletions
diff --git a/src/lib/libcrypto/modes/cts128.c b/src/lib/libcrypto/modes/cts128.c
index e0430f9fdc..c0e1f3696c 100644
--- a/src/lib/libcrypto/modes/cts128.c
+++ b/src/lib/libcrypto/modes/cts128.c
@@ -5,7 +5,8 @@
5 * forms are granted according to the OpenSSL license. 5 * forms are granted according to the OpenSSL license.
6 */ 6 */
7 7
8#include "modes.h" 8#include <openssl/crypto.h>
9#include "modes_lcl.h"
9#include <string.h> 10#include <string.h>
10 11
11#ifndef MODES_DEBUG 12#ifndef MODES_DEBUG
@@ -23,8 +24,9 @@
23 * deviates from mentioned RFCs. Most notably it allows input to be 24 * deviates from mentioned RFCs. Most notably it allows input to be
24 * of block length and it doesn't flip the order of the last two 25 * of block length and it doesn't flip the order of the last two
25 * blocks. CTS is being discussed even in ECB context, but it's not 26 * blocks. CTS is being discussed even in ECB context, but it's not
26 * adopted for any known application. This implementation complies 27 * adopted for any known application. This implementation provides
27 * with mentioned RFCs and [as such] extends CBC mode. 28 * two interfaces: one compliant with above mentioned RFCs and one
29 * compliant with the NIST proposal, both extending CBC mode.
28 */ 30 */
29 31
30size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, 32size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
@@ -54,6 +56,34 @@ size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
54 return len+residue; 56 return len+residue;
55} 57}
56 58
59size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out,
60 size_t len, const void *key,
61 unsigned char ivec[16], block128_f block)
62{ size_t residue, n;
63
64 assert (in && out && key && ivec);
65
66 if (len < 16) return 0;
67
68 residue=len%16;
69
70 len -= residue;
71
72 CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
73
74 if (residue==0) 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
57size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, 87size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
58 size_t len, const void *key, 88 size_t len, const void *key,
59 unsigned char ivec[16], cbc128_f cbc) 89 unsigned char ivec[16], cbc128_f cbc)
@@ -90,6 +120,41 @@ size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
90 return len+residue; 120 return len+residue;
91} 121}
92 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{ size_t residue;
127 union { size_t align; unsigned char c[16]; } tmp;
128
129 assert (in && out && key && ivec);
130
131 if (len < 16) return 0;
132
133 residue=len%16;
134
135 len -= residue;
136
137 (*cbc)(in,out,len,key,ivec,1);
138
139 if (residue==0) return len;
140
141 in += len;
142 out += len;
143
144#if defined(CBC_HANDLES_TRUNCATED_IO)
145 (*cbc)(in,out-16+residue,residue,key,ivec,1);
146#else
147 {
148 size_t n;
149 for (n=0; n<16; n+=sizeof(size_t))
150 *(size_t *)(tmp.c+n) = 0;
151 memcpy(tmp.c,in,residue);
152 }
153 (*cbc)(tmp.c,out-16+residue,16,key,ivec,1);
154#endif
155 return len+residue;
156}
157
93size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out, 158size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
94 size_t len, const void *key, 159 size_t len, const void *key,
95 unsigned char ivec[16], block128_f block) 160 unsigned char ivec[16], block128_f block)
@@ -125,7 +190,51 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
125 for(residue+=16; n<residue; ++n) 190 for(residue+=16; n<residue; ++n)
126 out[n] = tmp.c[n] ^ in[n]; 191 out[n] = tmp.c[n] ^ in[n];
127 192
128 return len+residue-16; 193 return 16+len+residue;
194}
195
196size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out,
197 size_t len, const void *key,
198 unsigned char ivec[16], block128_f block)
199{ size_t residue, n;
200 union { size_t align; unsigned char c[32]; } tmp;
201
202 assert (in && out && key && ivec);
203
204 if (len<16) return 0;
205
206 residue=len%16;
207
208 if (residue==0) {
209 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
210 return len;
211 }
212
213 len -= 16+residue;
214
215 if (len) {
216 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
217 in += len;
218 out += len;
219 }
220
221 (*block)(in+residue,tmp.c+16,key);
222
223 for (n=0; n<16; n+=sizeof(size_t))
224 *(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
225 memcpy(tmp.c,in,residue);
226 (*block)(tmp.c,tmp.c,key);
227
228 for(n=0; n<16; ++n) {
229 unsigned char c = in[n];
230 out[n] = tmp.c[n] ^ ivec[n];
231 ivec[n] = in[n+residue];
232 tmp.c[n] = c;
233 }
234 for(residue+=16; n<residue; ++n)
235 out[n] = tmp.c[n] ^ tmp.c[n-16];
236
237 return 16+len+residue;
129} 238}
130 239
131size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, 240size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
@@ -160,7 +269,47 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
160 (*cbc)(tmp.c,tmp.c,32,key,ivec,0); 269 (*cbc)(tmp.c,tmp.c,32,key,ivec,0);
161 memcpy(out,tmp.c,16+residue); 270 memcpy(out,tmp.c,16+residue);
162#endif 271#endif
163 return len+residue; 272 return 16+len+residue;
273}
274
275size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
276 size_t len, const void *key,
277 unsigned char ivec[16], cbc128_f cbc)
278{ size_t residue, n;
279 union { size_t align; unsigned char c[32]; } tmp;
280
281 assert (in && out && key && ivec);
282
283 if (len<16) return 0;
284
285 residue=len%16;
286
287 if (residue==0) {
288 (*cbc)(in,out,len,key,ivec,0);
289 return len;
290 }
291
292 len -= 16+residue;
293
294 if (len) {
295 (*cbc)(in,out,len,key,ivec,0);
296 in += len;
297 out += len;
298 }
299
300 for (n=16; n<32; n+=sizeof(size_t))
301 *(size_t *)(tmp.c+n) = 0;
302 /* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
303 (*cbc)(in+residue,tmp.c,16,key,tmp.c+16,0);
304
305 memcpy(tmp.c,in,residue);
306#if defined(CBC_HANDLES_TRUNCATED_IO)
307 (*cbc)(tmp.c,out,16+residue,key,ivec,0);
308#else
309 (*cbc)(tmp.c,tmp.c,32,key,ivec,0);
310 memcpy(out,tmp.c,16+residue);
311#endif
312 return 16+len+residue;
164} 313}
165 314
166#if defined(SELFTEST) 315#if defined(SELFTEST)
@@ -200,9 +349,8 @@ static const unsigned char vector_64[64] =
200static AES_KEY encks, decks; 349static AES_KEY encks, decks;
201 350
202void test_vector(const unsigned char *vector,size_t len) 351void test_vector(const unsigned char *vector,size_t len)
203{ unsigned char cleartext[64]; 352{ unsigned char iv[sizeof(test_iv)];
204 unsigned char iv[sizeof(test_iv)]; 353 unsigned char cleartext[64],ciphertext[64];
205 unsigned char ciphertext[64];
206 size_t tail; 354 size_t tail;
207 355
208 printf("vector_%d\n",len); fflush(stdout); 356 printf("vector_%d\n",len); fflush(stdout);
@@ -243,7 +391,57 @@ void test_vector(const unsigned char *vector,size_t len)
243 fprintf(stderr,"iv_%d mismatch\n",len), exit(4); 391 fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
244} 392}
245 393
246main() 394void test_nistvector(const unsigned char *vector,size_t len)
395{ unsigned char iv[sizeof(test_iv)];
396 unsigned char cleartext[64],ciphertext[64],nistvector[64];
397 size_t tail;
398
399 printf("nistvector_%d\n",len); fflush(stdout);
400
401 if ((tail=len%16) == 0) tail = 16;
402
403 len -= 16 + tail;
404 memcpy(nistvector,vector,len);
405 /* flip two last blocks */
406 memcpy(nistvector+len,vector+len+16,tail);
407 memcpy(nistvector+len+tail,vector+len,16);
408 len += 16 + tail;
409 tail = 16;
410
411 /* test block-based encryption */
412 memcpy(iv,test_iv,sizeof(test_iv));
413 CRYPTO_nistcts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
414 if (memcmp(ciphertext,nistvector,len))
415 fprintf(stderr,"output_%d mismatch\n",len), exit(1);
416 if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
417 fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
418
419 /* test block-based decryption */
420 memcpy(iv,test_iv,sizeof(test_iv));
421 CRYPTO_nistcts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
422 if (memcmp(cleartext,test_input,len))
423 fprintf(stderr,"input_%d mismatch\n",len), exit(2);
424 if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
425 fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
426
427 /* test streamed encryption */
428 memcpy(iv,test_iv,sizeof(test_iv));
429 CRYPTO_nistcts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
430 if (memcmp(ciphertext,nistvector,len))
431 fprintf(stderr,"output_%d mismatch\n",len), exit(3);
432 if (memcmp(iv,nistvector+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_nistcts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
438 if (memcmp(cleartext,test_input,len))
439 fprintf(stderr,"input_%d mismatch\n",len), exit(4);
440 if (memcmp(iv,nistvector+len-tail,sizeof(iv)))
441 fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
442}
443
444int main()
247{ 445{
248 AES_set_encrypt_key(test_key,128,&encks); 446 AES_set_encrypt_key(test_key,128,&encks);
249 AES_set_decrypt_key(test_key,128,&decks); 447 AES_set_decrypt_key(test_key,128,&decks);
@@ -254,6 +452,14 @@ main()
254 test_vector(vector_47,sizeof(vector_47)); 452 test_vector(vector_47,sizeof(vector_47));
255 test_vector(vector_48,sizeof(vector_48)); 453 test_vector(vector_48,sizeof(vector_48));
256 test_vector(vector_64,sizeof(vector_64)); 454 test_vector(vector_64,sizeof(vector_64));
257 exit(0); 455
456 test_nistvector(vector_17,sizeof(vector_17));
457 test_nistvector(vector_31,sizeof(vector_31));
458 test_nistvector(vector_32,sizeof(vector_32));
459 test_nistvector(vector_47,sizeof(vector_47));
460 test_nistvector(vector_48,sizeof(vector_48));
461 test_nistvector(vector_64,sizeof(vector_64));
462
463 return 0;
258} 464}
259#endif 465#endif