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