Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 321 lines (262 sloc) 7.69 kB
ca5f82c @mrash Removed legacy $Id$ tags from svn
authored
1 /*
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
2 *****************************************************************************
3 *
4 * File: cipher_funcs.c
5 *
6 * Author: Damien S. Stuart
7 *
8 * Purpose: Cipher functions used by fwknop
9 *
0f6ca00 Updated the GPL blurb at the top of the source files. Added some mis…
Damien Stuart authored
10 * Copyright 2009-2010 Damien Stuart (dstuart@dstuart.org)
11 *
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
12 * License (GNU Public License):
13 *
0f6ca00 Updated the GPL blurb at the top of the source files. Added some mis…
Damien Stuart authored
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
23 *
0f6ca00 Updated the GPL blurb at the top of the source files. Added some mis…
Damien Stuart authored
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 * USA
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
28 *
29 *****************************************************************************
30 */
31 #include <stdio.h>
32 #include <string.h>
4192eb8 Updates and revisions to accommodate a Windows build.
Damien Stuart authored
33
34 #ifdef WIN32
35 #include <sys/timeb.h>
36 #include <time.h>
37 #include <stdlib.h>
38 #else
39 #include <sys/time.h>
40 #endif
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
41
42 #include "cipher_funcs.h"
43 #include "digest.h"
44
4192eb8 Updates and revisions to accommodate a Windows build.
Damien Stuart authored
45 #ifndef WIN32
46 #ifndef RAND_FILE
47 #define RAND_FILE "/dev/urandom"
48 #endif
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
49 #endif
50
51 /* Get random data.
52 */
6388e8a @mrash added 'const' to function prototype vars where possible
authored
53 static void
54 get_random_data(unsigned char *data, const size_t len)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
55 {
6388e8a @mrash added 'const' to function prototype vars where possible
authored
56 uint32_t i;
4192eb8 Updates and revisions to accommodate a Windows build.
Damien Stuart authored
57 #ifdef WIN32
58 int rnum;
59 struct _timeb tb;
60
61 _ftime_s(&tb);
62
63 srand((uint32_t)(tb.time*1000)+tb.millitm);
64
65 for(i=0; i<len; i++)
66 {
67 rnum = rand();
68 *(data+i) = rnum % 0xff;
69 }
70 #else
71 FILE *rfd;
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
72 struct timeval tv;
1092e6e @mrash * Fixed a few minor warnings like the following:
authored
73 int do_time = 0;
74 size_t amt_read;
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
75
76 /* Attempt to read seed data from /dev/urandom. If that does not
77 * work, then fall back to a time-based method (less secure, but
78 * probably more portable).
79 */
80 if((rfd = fopen(RAND_FILE, "r")) == NULL)
81 {
1092e6e @mrash * Fixed a few minor warnings like the following:
authored
82 do_time = 1;
83 }
84 else
85 {
86 /* Read seed from /dev/urandom
87 */
88 amt_read = fread(data, len, 1, rfd);
89 fclose(rfd);
90
91 if (amt_read != 1)
92 do_time = 1;
93 }
94
95 if (do_time)
96 {
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
97 /* Seed based on time (current usecs).
98 */
99 gettimeofday(&tv, NULL);
100 srand(tv.tv_usec);
101
102 for(i=0; i<len; i++)
103 *(data+i) = rand() % 0xff;
104 }
1092e6e @mrash * Fixed a few minor warnings like the following:
authored
105
4192eb8 Updates and revisions to accommodate a Windows build.
Damien Stuart authored
106 #endif
107
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
108 }
109
e846cdd First cut at GPG encrytion support (decryption and doc update are pen…
Damien Stuart authored
110
111 /*** These are Rijndael-specific functions ***/
112
113 /* Rijndael function to generate initial salt and initialization vector
114 * (iv). This is is done to be compatible with the data produced via
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
115 * the Perl Crypt::CBC module's use of Rijndael.
116 */
6388e8a @mrash added 'const' to function prototype vars where possible
authored
117 static void
118 rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
119 {
a82c361 Another major re-write of the fwknop library.
Damien Stuart authored
120 char pw_buf[16];
121 unsigned char tmp_buf[64]; /* How big does this need to be? */
122 unsigned char kiv_buf[48]; /* Key and IV buffer */
123 unsigned char md5_buf[16]; /* Buffer for computed md5 hash */
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
124
e846cdd First cut at GPG encrytion support (decryption and doc update are pen…
Damien Stuart authored
125 size_t kiv_len = 0;
126 size_t plen = strlen(pass);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
127
8041bdf More updates to address compatibility issues with the perl version of…
Damien Stuart authored
128 /* First make pw 16 bytes (pad with "0" (ascii 0x30)) or truncate.
129 * Note: pw_buf was initialized with '0' chars (again, not the value
130 * 0, but the digit '0' character).
131 */
132 if(plen < 16)
133 {
134 memcpy(pw_buf, pass, plen);
135 memset(pw_buf+plen, '0', 16 - plen);
136 }
137 else
138 strncpy(pw_buf, pass, 16);
6388e8a @mrash added 'const' to function prototype vars where possible
authored
139
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
140 /* If we are decrypting, data will contain the salt. Otherwise,
141 * for encryption, we generate a random salt.
142 */
143 if(data != NULL)
144 {
145 /* Pull the salt from the data
146 */
147 memcpy(ctx->salt, (data+8), 8);
148 }
149 else
150 {
151 /* Generate a random 8-byte salt.
152 */
153 get_random_data(ctx->salt, 8);
154 }
155
156 /* Now generate the key and initialization vector.
8041bdf More updates to address compatibility issues with the perl version of…
Damien Stuart authored
157 * (again it is the perl Crypt::CBC way, with a touch of
158 * fwknop).
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
159 */
8041bdf More updates to address compatibility issues with the perl version of…
Damien Stuart authored
160 memcpy(tmp_buf+16, pw_buf, 16);
161 memcpy(tmp_buf+32, ctx->salt, 8);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
162
163 while(kiv_len < sizeof(kiv_buf))
164 {
165 if(kiv_len == 0)
8041bdf More updates to address compatibility issues with the perl version of…
Damien Stuart authored
166 md5(md5_buf, tmp_buf+16, 24);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
167 else
8041bdf More updates to address compatibility issues with the perl version of…
Damien Stuart authored
168 md5(md5_buf, tmp_buf, 40);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
169
170 memcpy(tmp_buf, md5_buf, 16);
171
172 memcpy(kiv_buf + kiv_len, md5_buf, 16);
173
174 kiv_len += 16;
175 }
176
177 memcpy(ctx->key, kiv_buf, 32);
178 memcpy(ctx->iv, kiv_buf+32, 16);
179 }
180
181 /* Initialization entry point.
182 */
6388e8a @mrash added 'const' to function prototype vars where possible
authored
183 static void
184 rijndael_init(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
185 {
186
187 /* Use ECB mode to be compatible with the Crypt::CBC perl module.
188 */
189 ctx->mode = MODE_ECB;
190
191 /* Generate the salt and initialization vector.
192 */
e846cdd First cut at GPG encrytion support (decryption and doc update are pen…
Damien Stuart authored
193 rij_salt_and_iv(ctx, pass, data);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
194
195 /* Intialize our rinjdael context.
196 */
197 rijndael_setup(ctx, 32, ctx->key);
198 }
199
200 /* Take a chunk of data, encrypt it in the same way the perl Crypt::CBC
201 * module would.
202 */
e846cdd First cut at GPG encrytion support (decryption and doc update are pen…
Damien Stuart authored
203 size_t
6388e8a @mrash added 'const' to function prototype vars where possible
authored
204 rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
205 {
206 RIJNDAEL_context ctx;
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
207 unsigned char plaintext[RIJNDAEL_BLOCKSIZE];
208 unsigned char mixtext[RIJNDAEL_BLOCKSIZE];
209 unsigned char ciphertext[RIJNDAEL_BLOCKSIZE];
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
210 int i, pad_val;
211
a82c361 Another major re-write of the fwknop library.
Damien Stuart authored
212 unsigned char *ondx = out;
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
213
214 rijndael_init(&ctx, pass, NULL);
215
216 /* Prepend the salt...
217 */
218 memcpy(ondx, "Salted__", 8);
219 ondx+=8;
220 memcpy(ondx, ctx.salt, 8);
221 ondx+=8;
222
223 /* Now iterate of the input data and encrypt in 16-byte chunks.
224 */
225 while(in_len)
226 {
227 for(i=0; i<sizeof(plaintext); i++)
228 {
229 if(in_len < 1)
230 break;
231
232 plaintext[i] = *in++;
233 in_len--;
234 }
235
236 pad_val = sizeof(plaintext) - i;
237
238 for(; i < sizeof(plaintext); i++)
239 plaintext[i] = pad_val;
240
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
241 for(i=0; i<RIJNDAEL_BLOCKSIZE; i++)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
242 mixtext[i] = plaintext[i] ^ ctx.iv[i];
243
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
244 block_encrypt(&ctx, mixtext, RIJNDAEL_BLOCKSIZE, ciphertext, ctx.iv);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
245
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
246 memcpy(ctx.iv, ciphertext, RIJNDAEL_BLOCKSIZE);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
247
248 for(i=0; i<sizeof(ciphertext); i++)
249 *ondx++ = ciphertext[i];
250 }
251
252 return(ondx - out);
253 }
254
255 /* Decrypt the given data.
256 */
e846cdd First cut at GPG encrytion support (decryption and doc update are pen…
Damien Stuart authored
257 size_t
6388e8a @mrash added 'const' to function prototype vars where possible
authored
258 rij_decrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
259 {
260 RIJNDAEL_context ctx;
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
261 unsigned char plaintext[RIJNDAEL_BLOCKSIZE];
262 unsigned char mixtext[RIJNDAEL_BLOCKSIZE];
263 unsigned char ciphertext[RIJNDAEL_BLOCKSIZE];
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
264 int i, pad_val, pad_err = 0;
a82c361 Another major re-write of the fwknop library.
Damien Stuart authored
265 unsigned char *pad_s;
266 unsigned char *ondx = out;
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
267
268 rijndael_init(&ctx, pass, in);
269
270 /* Remove the salt from the input.
271 */
272 in_len -= 16;
273 memmove(in, in+16, in_len);
274
275 while(in_len)
276 {
277 for(i=0; i<sizeof(ciphertext); i++)
278 {
279 if(in_len < 1)
280 break;
281
282 ciphertext[i] = *in++;
283 in_len--;
284 }
285
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
286 block_decrypt(&ctx, ciphertext, RIJNDAEL_BLOCKSIZE, mixtext, ctx.iv);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
287
288 for(i=0; i<sizeof(ciphertext); i++)
289 plaintext[i] = mixtext[i] ^ ctx.iv[i];
290
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
291 memcpy(ctx.iv, ciphertext, RIJNDAEL_BLOCKSIZE);
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
292
293 for(i=0; i<sizeof(plaintext); i++)
294 *ondx++ = plaintext[i];
295 }
296
297 /* Find and remove padding.
298 */
299 pad_val = *(ondx-1);
300
7e8e484 @mrash convert Rijndael blocksize values '16' to use RIJNDAEL_BLOCKSIZE macro
authored
301 if(pad_val >= 0 && pad_val <= RIJNDAEL_BLOCKSIZE)
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
302 {
303 pad_s = ondx - pad_val;
304
305 for(i=0; i < (ondx-pad_s); i++)
306 {
307 if(*(pad_s+i) != pad_val)
308 pad_err++;
309 }
6388e8a @mrash added 'const' to function prototype vars where possible
authored
310
1e7534d Added rijndael code, spa digest and message functions, and a shitload…
Damien Stuart authored
311 if(pad_err == 0)
312 ondx -= pad_val;
313 }
314
315 *ondx = '\0';
316
317 return(ondx - out);
318 }
319
320 /***EOF***/
Something went wrong with that request. Please try again.