diff options
Diffstat (limited to 'all_pairs/source/rijndael_enc/rijndael_enc.c')
-rw-r--r-- | all_pairs/source/rijndael_enc/rijndael_enc.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/all_pairs/source/rijndael_enc/rijndael_enc.c b/all_pairs/source/rijndael_enc/rijndael_enc.c new file mode 100644 index 0000000..f74d595 --- /dev/null +++ b/all_pairs/source/rijndael_enc/rijndael_enc.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | |||
3 | This program is part of the TACLeBench benchmark suite. | ||
4 | Version V 2.0 | ||
5 | |||
6 | Name: rijndael_enc | ||
7 | |||
8 | Author: Dr Brian Gladman | ||
9 | |||
10 | Function: rijndael_enc is an implementation of the AES encryption | ||
11 | algorithm (Rijndael). | ||
12 | |||
13 | Source: security section of MiBench | ||
14 | |||
15 | Changes: Add computation of a checksum, refactoring | ||
16 | |||
17 | License: see below | ||
18 | |||
19 | */ | ||
20 | |||
21 | /* | ||
22 | ----------------------------------------------------------------------- | ||
23 | Copyright (c) 2001 Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK | ||
24 | |||
25 | TERMS | ||
26 | |||
27 | Redistribution and use in source and binary forms, with or without | ||
28 | modification, are permitted provided that the following conditions | ||
29 | are met: | ||
30 | 1. Redistributions of source code must retain the above copyright | ||
31 | notice, this list of conditions and the following disclaimer. | ||
32 | 2. Redistributions in binary form must reproduce the above copyright | ||
33 | notice, this list of conditions and the following disclaimer in the | ||
34 | documentation and/or other materials provided with the distribution. | ||
35 | |||
36 | This software is provided 'as is' with no guarantees of correctness or | ||
37 | fitness for purpose. | ||
38 | ----------------------------------------------------------------------- | ||
39 | */ | ||
40 | |||
41 | #include "../extra.h" | ||
42 | #include "aes.h" | ||
43 | #include "rijndael_enc_libc.h" | ||
44 | |||
45 | /* | ||
46 | Global variable definitions | ||
47 | */ | ||
48 | unsigned char rijndael_enc_key[32]; | ||
49 | int rijndael_enc_key_len; | ||
50 | |||
51 | extern unsigned char rijndael_enc_data[]; | ||
52 | struct rijndael_enc_FILE rijndael_enc_fin; | ||
53 | |||
54 | int rijndael_enc_checksum = 0; | ||
55 | |||
56 | /* | ||
57 | Forward declaration of functions | ||
58 | */ | ||
59 | void rijndael_enc_init( void ); | ||
60 | int rijndael_enc_return( void ); | ||
61 | void rijndael_enc_fillrand( unsigned char *buf, int len ); | ||
62 | void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ); | ||
63 | void rijndael_enc_main( void ); | ||
64 | |||
65 | void rijndael_enc_init( void ) | ||
66 | { | ||
67 | /* create a pseudo-file for the input*/ | ||
68 | rijndael_enc_fin.data = rijndael_enc_data; | ||
69 | rijndael_enc_fin.size = 31369; | ||
70 | rijndael_enc_fin.cur_pos = 0; | ||
71 | |||
72 | unsigned i; | ||
73 | volatile int x = 0; | ||
74 | rijndael_enc_fin.size ^= x; | ||
75 | _Pragma( "loopbound min 31369 max 31369" ) | ||
76 | for ( i = 0; i < rijndael_enc_fin.size; i++ ) | ||
77 | rijndael_enc_fin.data[i] ^= x; | ||
78 | |||
79 | /* this is a pointer to the hexadecimal key digits */ | ||
80 | const volatile char *cp = | ||
81 | "1234567890abcdeffedcba09876543211234567890abcdeffedcba0987654321"; | ||
82 | char ch; | ||
83 | int by = 0; | ||
84 | |||
85 | i = 0; /* this is a count for the input digits processed */ | ||
86 | _Pragma( "loopbound min 64 max 64" ) | ||
87 | while ( i < 64 && *cp ) { /* the maximum key length is 32 bytes and */ | ||
88 | /* hence at most 64 hexadecimal digits */ | ||
89 | ch = rijndael_enc_toupper( *cp++ ); /* process a hexadecimal digit */ | ||
90 | if ( ch >= '0' && ch <= '9' ) | ||
91 | by = ( by << 4 ) + ch - '0'; | ||
92 | else | ||
93 | if ( ch >= 'A' && ch <= 'F' ) | ||
94 | by = ( by << 4 ) + ch - 'A' + 10; | ||
95 | else { /* error if not hexadecimal */ | ||
96 | rijndael_enc_checksum = -2; | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | /* store a key byte for each pair of hexadecimal digits */ | ||
101 | if ( i++ & 1 ) | ||
102 | rijndael_enc_key[i / 2 - 1] = by & 0xff; | ||
103 | } | ||
104 | |||
105 | if ( *cp ) { | ||
106 | rijndael_enc_checksum = -3; | ||
107 | return; | ||
108 | } else | ||
109 | if ( i < 32 || ( i & 15 ) ) { | ||
110 | rijndael_enc_checksum = -4; | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | rijndael_enc_key_len = i / 2; | ||
115 | } | ||
116 | |||
117 | int rijndael_enc_return( void ) | ||
118 | { | ||
119 | return ( ( rijndael_enc_checksum == ( int )249509 ) ? 0 : -1 ); | ||
120 | } | ||
121 | |||
122 | /* A Pseudo Random Number Generator (PRNG) used for the */ | ||
123 | /* Initialisation Vector. The PRNG is George Marsaglia's */ | ||
124 | /* Multiply-With-Carry (MWC) PRNG that concatenates two */ | ||
125 | /* 16-bit MWC generators: */ | ||
126 | /* x(n)=36969 * x(n-1) + carry mod 2^16 */ | ||
127 | /* y(n)=18000 * y(n-1) + carry mod 2^16 */ | ||
128 | /* to produce a combined PRNG with a period of about 2^60. */ | ||
129 | |||
130 | #define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + (b = 18000 * (b & 65535) + (b >> 16)) ) | ||
131 | |||
132 | void rijndael_enc_fillrand( unsigned char *buf, int len ) | ||
133 | { | ||
134 | static unsigned long a[2], mt = 1, count = 4; | ||
135 | static char r[4]; | ||
136 | int i; | ||
137 | |||
138 | if ( mt ) { | ||
139 | mt = 0; | ||
140 | a[0] = 0xeaf3; | ||
141 | a[1] = 0x35fe; | ||
142 | } | ||
143 | |||
144 | _Pragma( "loopbound min 1 max 16" ) | ||
145 | for ( i = 0; i < len; ++i ) { | ||
146 | if ( count == 4 ) { | ||
147 | *( unsigned long * )r = RAND( a[0], a[1] ); | ||
148 | count = 0; | ||
149 | } | ||
150 | |||
151 | buf[i] = r[count++]; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ) | ||
156 | { | ||
157 | unsigned char inbuf[16], outbuf[16]; | ||
158 | long int flen; | ||
159 | unsigned long i = 0, l = 0; | ||
160 | |||
161 | rijndael_enc_fillrand( outbuf, | ||
162 | 16 ); /* set an IV for CBC mode */ | ||
163 | flen = fin->size; | ||
164 | |||
165 | rijndael_enc_fillrand( inbuf, | ||
166 | 1 ); /* make top 4 bits of a byte random */ | ||
167 | l = 15; /* and store the length of the last */ | ||
168 | /* block in the lower 4 bits */ | ||
169 | inbuf[0] = ( ( char )flen & 15 ) | ( inbuf[0] & ~15 ); | ||
170 | |||
171 | /* TODO: this is necessarily an input-dependent loop bound */ | ||
172 | _Pragma( "loopbound min 1961 max 1961" ) | ||
173 | while ( !rijndael_enc_feof( | ||
174 | fin ) ) { /* loop to encrypt the input file */ | ||
175 | /* input 1st 16 bytes to buf[1..16] */ | ||
176 | i = rijndael_enc_fread( inbuf + 16 - l, 1, l, fin ); /* on 1st round byte[0] */ | ||
177 | /* is the length code */ | ||
178 | if ( i < l ) break; /* if end of the input file reached */ | ||
179 | |||
180 | _Pragma( "loopbound min 16 max 16" ) | ||
181 | for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ | ||
182 | inbuf[i] ^= outbuf[i]; | ||
183 | |||
184 | rijndael_enc_encrypt( inbuf, outbuf, | ||
185 | ctx ); /* and do the encryption */ | ||
186 | |||
187 | rijndael_enc_checksum += outbuf[15]; | ||
188 | |||
189 | /* in all but first round read 16 */ | ||
190 | l = 16; /* bytes into the buffer */ | ||
191 | } | ||
192 | |||
193 | /* except for files of length less than two blocks we now have one */ | ||
194 | /* byte from the previous block and 'i' bytes from the current one */ | ||
195 | /* to encrypt and 15 - i empty buffer positions. For files of less */ | ||
196 | /* than two blocks (0 or 1) we have i + 1 bytes and 14 - i empty */ | ||
197 | /* buffer position to set to zero since the 'count' byte is extra */ | ||
198 | |||
199 | if ( l == 15 ) /* adjust for extra byte in the */ | ||
200 | ++i; /* in the first block */ | ||
201 | |||
202 | if ( i ) { /* if bytes remain to be output */ | ||
203 | _Pragma( "loopbound min 6 max 6" ) | ||
204 | while ( i < 16 ) /* clear empty buffer positions */ | ||
205 | inbuf[i++] = 0; | ||
206 | |||
207 | _Pragma( "loopbound min 16 max 16" ) | ||
208 | for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ | ||
209 | inbuf[i] ^= outbuf[i]; | ||
210 | |||
211 | rijndael_enc_encrypt( inbuf, outbuf, ctx ); /* encrypt and output it */ | ||
212 | |||
213 | rijndael_enc_checksum += outbuf[15]; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | void _Pragma( "entrypoint" ) rijndael_enc_main( void ) | ||
218 | { | ||
219 | struct aes ctx[1]; | ||
220 | |||
221 | /* encryption in Cipher Block Chaining mode */ | ||
222 | rijndael_enc_set_key( rijndael_enc_key, rijndael_enc_key_len, enc, ctx ); | ||
223 | rijndael_enc_encfile( &rijndael_enc_fin, ctx ); | ||
224 | } | ||
225 | |||
226 | int main( int argc, char** argv ) | ||
227 | { | ||
228 | SET_UP | ||
229 | for (jobsComplete=-1; jobsComplete<maxJobs; jobsComplete++){ | ||
230 | START_LOOP | ||
231 | rijndael_enc_init(); | ||
232 | rijndael_enc_main(); | ||
233 | STOP_LOOP | ||
234 | } | ||
235 | WRITE_TO_FILE | ||
236 | return ( rijndael_enc_return() ); | ||
237 | } | ||
238 | |||