1 /*************************************************************************\
2 *
3 * Package: TestU01
4 * File: ucrypto.c
5 * Environment: ANSI C
6 *
7 * Copyright (c) 2002 Pierre L'Ecuyer, DIRO, Université de Montréal.
8 * e-mail: lecuyer@iro.umontreal.ca
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted without a fee for private, research,
13 * academic, or other non-commercial purposes.
14 * Any use of this software in a commercial environment requires a
15 * written licence from the copyright owner.
16 *
17 * Any changes made to this package must be clearly identified as such.
18 *
19 * In scientific publications which used this software, a reference to it
20 * would be appreciated.
21 *
22 * Redistributions of source code must retain this copyright notice
23 * and the following disclaimer.
24 *
25 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
27 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28 *
29 \*************************************************************************/
30
31 #include "util.h"
32 #include "addstr.h"
33 #include "num.h"
34
35 #include "rijndael-alg-fst.h"
36 #include "tu01_sha1.h"
37 #include "ucrypto.h"
38 #include "unif01.h"
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <time.h>
43 #include <limits.h>
44
45 #define LEN 200 /* Max length of strings */
46 #define MAX_SIZE 64 /* number of ASCII char's in a key */
47
48
49
50 /*-------------------------------------------------------------------------*/
51
52 typedef struct
53 {
54 int Nr; /* Number of rounds */
55 int Nk; /* Number of columns (key length in words) */
56 int Nb; /* Number of bytes (block size in bytes) */
57 int r; /* Number of initial bytes dropped */
58 int s; /* Number of bytes kept */
59 } AES_param;
60
61 typedef struct
62 {
63 uint32_t *K; /* Key */
64 uint8_t *PT; /* Plain text */
65 uint8_t *CT; /* Cypher text */
66 int i; /* Byte number */
67 int Nk;
68 ucrypto_Mode mode;
69 } AES_state;
70
71
72 typedef struct
73 {
74 SHA1_CTX context;
75 int i; /* byte used for output */
76 int r; /* Number of initial bytes dropped */
77 int s; /* Number of bytes kept */
78 ucrypto_Mode mode;
79 unsigned char V[64];
80 unsigned char output[20];
81 } SHA1_state;
82
83
84
85 /*============================ functions ==================================*/
86
increment8(uint8_t A[],int n)87 static void increment8 (uint8_t A[], int n)
88 {
89 /* A is an array of n char's; it is viewed here as an 8n-bit integer.
90 This function increments the integer by 1 mod 2^(8n). */
91 int i;
92 for (i = n-1; i >= 0; --i) {
93 ++A[i];
94 #if CHAR_BIT > 8
95 A[i] &= 0xff;
96 #endif
97 if (A[i] > 0)
98 return;
99 }
100 }
101
102
103 /*-------------------------------------------------------------------------*/
104
increment32(uint32_t A[],int n)105 static void increment32 (uint32_t A[], int n)
106 {
107 /* A is an array of n unsigned int's; it is viewed here as an 32n-bit integer.
108 This function increments this integer by 1 mod 2^(32n). */
109 int i;
110 for (i = n-1; i >= 0; --i) {
111 ++A[i];
112 #if UINT_MAX > 4294967295U
113 A[i] &= 0xffffffffU;
114 #endif
115 if (A[i] > 0)
116 return;
117 }
118 }
119
120
121 /*-------------------------------------------------------------------------*/
122 #if 0
123
124 int main ()
125 {
126 #if 0
127 unsigned char A[] = { 25, 255, 254 };
128 unsigned char B[] = { 111, 124 };
129 #else
130 unsigned int A[] = { 25, 255, 0xfffffff9 };
131 #endif
132 int i, j;
133 for (j = 0; j < 10; ++j) {
134 increment32 (A, 3);
135 for (i = 0; i < 3; i++) {
136 printf (" %13u", (unsigned int) A[i]);
137 }
138 printf ("\n");
139 }
140 }
141 #endif
142
143
144 /*=========================================================================*/
145
AES_Bits(void * vpar,void * vsta)146 static unsigned long AES_Bits (void *vpar, void *vsta)
147 {
148 AES_param *param = vpar;
149 AES_state *state = vsta;
150 int k;
151 unsigned long Z = 0;
152
153 /* 4 bytes = one 32-bit random number */
154 for (k = 0; k < 4; ++k) {
155 if (state->i >= param->s) {
156 int j;
157 rijndaelEncrypt (state->K, param->Nr, state->PT, state->CT);
158
159 switch (state->mode) {
160 case ucrypto_OFB:
161 for (j = 0; j < 16; j++)
162 state->PT[j] = state->CT[j];
163 break;
164 case ucrypto_CTR:
165 increment8 (state->PT, 16); /* pt = pt + 1 mod 2^128 */
166 break;
167 case ucrypto_KTR:
168 increment32 (state->K, param->Nk); /* K = K + 1 mod 2^(32Nk) */
169 break;
170 default:
171 util_Error ("ucrypto_CreateAES: no such mode");
172 }
173 state->i = param->r;
174 }
175 Z <<= 8;
176 Z |= (unsigned long) state->CT[state->i++];
177 }
178
179 return Z;
180 }
181
182
183 /*-------------------------------------------------------------------------*/
184
AES_U01(void * vpar,void * vsta)185 static double AES_U01 (void *vpar, void *vsta)
186 {
187 return AES_Bits (vpar, vsta) * unif01_INV32;
188 }
189
190
191 /*-------------------------------------------------------------------------*/
192
WrAES(void * vsta)193 static void WrAES (void *vsta)
194 {
195 AES_state *state = vsta;
196 unsigned char A[32];
197 int i;
198 printf (" Char's are written as small decimal integers\n");
199
200 switch (state->mode) {
201 case ucrypto_OFB:
202 case ucrypto_CTR:
203 printf (" T = {\n ");
204 for (i = 0; i < 16; i++) {
205 printf (" %3d", (unsigned int) state->PT[i]);
206 if ((i + 1) % 8 == 0)
207 printf ("\n ");
208 }
209 break;
210
211 case ucrypto_KTR:
212 num_Uint2Uchar (A, state->K, state->Nk);
213 printf (" Key = {\n ");
214 for (i = 0; i < 4*state->Nk; i++) {
215 printf (" %3d", (unsigned int) A[i]);
216 if ((i + 1) % 8 == 0)
217 printf ("\n ");
218 }
219 break;
220
221 default:
222 util_Error ("ucrypto_CreateAES: no such mode");
223 }
224 printf ("}\n");
225 }
226
227
228 /*-------------------------------------------------------------------------*/
229
getStringMode(ucrypto_Mode mode,char * str)230 static void getStringMode (ucrypto_Mode mode, char *str)
231 /* Transforms the mode in a string */
232 {
233 switch (mode) {
234 case ucrypto_OFB:
235 strcpy (str, "OFB");
236 break;
237 case ucrypto_CTR:
238 strcpy (str, "CTR");
239 break;
240 case ucrypto_KTR:
241 strcpy (str, "KTR");
242 break;
243 default:
244 util_Error ("ucrypto_Mode: no such case");
245 }
246 }
247
248
249 /*-------------------------------------------------------------------------*/
250
ucrypto_CreateAES(unsigned char * Key,int KeyLen,unsigned char * Seed,ucrypto_Mode mode,int r,int s)251 unif01_Gen * ucrypto_CreateAES (unsigned char *Key, int KeyLen,
252 unsigned char *Seed, ucrypto_Mode mode, int r, int s)
253 {
254 unif01_Gen *gen;
255 AES_param *param;
256 AES_state *state;
257 size_t len1;
258 char name[LEN + 1] = {0};
259 char str[16] = {0};
260 int i;
261 unsigned int D[64];
262
263 util_Assert ((KeyLen == 128) || (KeyLen == 192) || (KeyLen == 256),
264 "ucrypto_CreateAES: klen must be in { 128, 192, 256 }");
265 util_Assert (r < 16, "ucrypto_CreateAES: r > 15");
266 util_Assert (0 < s, "ucrypto_CreateAES: s <= 0");
267 util_Assert (s <= 16, "ucrypto_CreateAES: s > 16");
268 util_Assert (r + s <= 16, "ucrypto_CreateAES: r + s > 16");
269 gen = util_Malloc (sizeof (unif01_Gen));
270 param = util_Malloc (sizeof (AES_param));
271 state = util_Malloc (sizeof (AES_state));
272
273 if (r < 0) r = 0;
274 switch (KeyLen) {
275 case 128:
276 param->Nb = 16;
277 param->Nk = 4;
278 param->Nr = 10;
279 break;
280 case 192:
281 param->Nb = 16;
282 param->Nk = 6;
283 param->Nr = 12;
284 break;
285 case 256:
286 param->Nb = 16;
287 param->Nk = 8;
288 param->Nr = 14;
289 break;
290 default:
291 util_Error ("ucrypto_CreateAES, klen: no such case");
292 }
293
294 strncpy (name, "ucrypto_CreateAES: mode = ", (size_t) LEN);
295 getStringMode (mode, str);
296 strncat (name, str, (size_t) LEN);
297 addstr_Int (name, ", r = ", r);
298 addstr_Int (name, ", s = ", s);
299 addstr_Long (name, ", klen = ", (long) KeyLen);
300 for (i = 0; i < KeyLen / 8; i++)
301 D[i] = Key[i];
302 addstr_ArrayUint (name, ", Key = ", KeyLen / 8, D);
303 for (i = 0; i < param->Nb; i++)
304 D[i] = Seed[i];
305 addstr_ArrayUint (name, ", Seed = ", param->Nb, D);
306 len1 = strlen (name);
307 gen->name = util_Calloc (len1 + 1, sizeof (char));
308 strncpy (gen->name, name, len1);
309
310 state->PT = util_Calloc ((size_t) param->Nb, sizeof (uint8_t));
311 state->CT = util_Calloc ((size_t) param->Nb, sizeof (uint8_t));
312 state->K = util_Calloc ((size_t) 4 * (param->Nr + 1), sizeof (uint32_t));
313 rijndaelKeySetupEnc (state->K, Key, KeyLen);
314
315 for (i = 0; i < param->Nb; i++)
316 state->PT[i] = Seed[i];
317 state->mode = mode;
318 param->r = r;
319 param->s = s + r;
320 state->i = 16;
321 state->Nk = param->Nk;
322 gen->param = param;
323 gen->state = state;
324 gen->GetBits = &AES_Bits;
325 gen->GetU01 = &AES_U01;
326 gen->Write = &WrAES;
327 return gen;
328 }
329
330
331 /*-------------------------------------------------------------------------*/
332
ucrypto_DeleteAES(unif01_Gen * gen)333 void ucrypto_DeleteAES (unif01_Gen * gen)
334 {
335 AES_param *param;
336 AES_state *state;
337
338 if (NULL == gen)
339 return;
340 param = gen->param;
341 state = gen->state;
342 util_Free (state->CT);
343 util_Free (state->PT);
344 util_Free (state->K);
345 gen->state = util_Free (gen->state);
346 gen->param = util_Free (gen->param);
347 gen->name = util_Free (gen->name);
348 util_Free (gen);
349 }
350
351
352 /*=========================================================================*/
353 #define SLEN 55
354
SHA1_Bits(void * junk,void * vsta)355 static unsigned long SHA1_Bits (void *junk, void *vsta)
356 {
357 SHA1_state *state = vsta;
358 int k;
359 unsigned long Z = 0;
360
361 /* 4 bytes = one 32-bit random number */
362 for (k = 0; k < 4; ++k) {
363 if (state->i >= state->s) {
364 switch (state->mode) {
365 case ucrypto_OFB:
366 SHA1Init (&state->context);
367 SHA1Update (&state->context, state->output, 20);
368 SHA1Final (state->output, &state->context);
369 break;
370 case ucrypto_CTR:
371 SHA1Init (&state->context);
372 SHA1Update (&state->context, state->V, SLEN);
373 SHA1Final (state->output, &state->context);
374 increment8 (state->V, SLEN); /* V = V + 1 mod 2^440 */
375 break;
376 default:
377 util_Error ("ucrypto_CreateSHA1: no such mode");
378 }
379
380 state->i = state->r;
381 }
382
383 Z <<= 8;
384 Z |= (unsigned long) state->output[state->i++];
385 }
386
387 return Z;
388 }
389
390 /*-------------------------------------------------------------------------*/
391
SHA1_U01(void * vpar,void * vsta)392 static double SHA1_U01 (void *vpar, void *vsta)
393 {
394 return SHA1_Bits (vpar, vsta) * unif01_INV32;
395 }
396
397 /*-------------------------------------------------------------------------*/
398
WrSHA1(void * vsta)399 static void WrSHA1 (void *vsta)
400 {
401 SHA1_state *state = vsta;
402 int i;
403 printf (" Char's are written as small decimal integers\n");
404 printf (" T = {\n ");
405
406 switch (state->mode) {
407 case ucrypto_OFB:
408 for (i = 0; i < 20; i++) {
409 printf (" %3d", (unsigned int) state->output[i]);
410 if ((i + 1) % 10 == 0)
411 printf ("\n ");
412 }
413 break;
414
415 case ucrypto_CTR:
416 for (i = 0; i < SLEN; i++) {
417 printf (" %3d", (unsigned int) state->V[i]);
418 if ((i + 1) % 10 == 0)
419 printf ("\n ");
420 }
421 break;
422
423 default:
424 util_Error ("ucrypto_SHA1: no such mode");
425 }
426 printf (" }\n");
427 }
428
429
430 /*-------------------------------------------------------------------------*/
431
ucrypto_CreateSHA1(unsigned char * Seed,int len,ucrypto_Mode mode,int r,int s)432 unif01_Gen * ucrypto_CreateSHA1 (unsigned char *Seed, int len, ucrypto_Mode mode,
433 int r, int s)
434 {
435 unif01_Gen *gen;
436 SHA1_state *state;
437 int i;
438 unsigned int D[SLEN];
439 size_t len1;
440 char name[LEN + 1] = {0};
441 char str[16] = {0};
442
443 util_Assert (4 == sizeof (uint32_t),
444 "ucrypto_CreateSHA1: uint32 must be exactly 32 bits wide");
445 util_Assert (r < 20, "ucrypto_CreateSHA1: r > 19");
446 util_Assert (0 < s, "ucrypto_CreateSHA1: s <= 0");
447 util_Assert (s <= 20, "ucrypto_CreateSHA1: s > 20");
448 util_Assert (r + s <= 20, "ucrypto_CreateSHA1: r + s > 20");
449 gen = util_Malloc (sizeof (unif01_Gen));
450 state = util_Malloc (sizeof (SHA1_state));
451 memset (state, 0, sizeof (SHA1_state));
452 if (r < 0) r = 0;
453
454 strncpy (name, "ucrypto_CreateSHA1: mode = ", (size_t) LEN);
455 getStringMode (mode, str);
456 strncat (name, str, (size_t) LEN);
457 addstr_Int (name, ", r = ", r);
458 addstr_Int (name, ", s = ", s);
459 addstr_Int (name, ", len = ", len);
460 if (len > SLEN) len = SLEN;
461 for (i = 0; i < len; i++)
462 D[i] = Seed[i];
463 addstr_ArrayUint (name, ", Seed = ", len, D);
464 len1 = strlen (name);
465 gen->name = util_Calloc (len1 + 1, sizeof (char));
466 strncpy (gen->name, name, len1);
467
468 switch (mode) {
469 case ucrypto_OFB:
470 SHA1Init (&state->context);
471 SHA1Update (&state->context, Seed, len);
472 SHA1Final (state->output, &state->context);
473 break;
474 case ucrypto_CTR:
475 for (i = 0; i < len; i++)
476 state->V[i] = Seed[i];
477 break;
478 default:
479 util_Error ("ucrypto_CreateSHA1: no such mode");
480 }
481
482 state->mode = mode;
483 state->r = r;
484 state->s = s + r;
485 state->i = 20;
486 gen->param = NULL;
487 gen->state = state;
488 gen->GetBits = &SHA1_Bits;
489 gen->GetU01 = &SHA1_U01;
490 gen->Write = &WrSHA1;
491 return gen;
492 }
493
494
495 /*-------------------------------------------------------------------------*/
496
ucrypto_DeleteSHA1(unif01_Gen * gen)497 void ucrypto_DeleteSHA1 (unif01_Gen * gen)
498 {
499 SHA1_state *state;
500
501 if (NULL == gen)
502 return;
503 state = gen->state;
504 SHA1Final (state->output, &state->context);
505 gen->state = util_Free (gen->state);
506 gen->name = util_Free (gen->name);
507 util_Free (gen);
508 }
509
510 #undef SLEN
511
512 /*=========================================================================*/
513 /* Generator ISAAC */
514
515 #include "ucryptoIS.c"
516