1 /* low-crypto.c --- Shishi crypto wrappers around generic crypto.
2 * Copyright (C) 2002-2013 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23 #include "internal.h"
24 #include "gc.h"
25 #include "arcfour.h"
26 #include <gcrypt.h>
27 #include "crc.h"
28 #include "low-crypto.h"
29
30 int
_shishi_crypto_init(Shishi * handle)31 _shishi_crypto_init (Shishi * handle)
32 {
33 int rc = gc_init ();
34
35 if (rc != GC_OK)
36 return SHISHI_CRYPTO_INTERNAL_ERROR;
37
38 return SHISHI_OK;
39 }
40
41 void
_shishi_quick_random(void)42 _shishi_quick_random (void)
43 {
44 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
45 }
46
47 /**
48 * shishi_randomize:
49 * @handle: shishi handle as allocated by shishi_init().
50 * @strong: 0 iff operation should not block, non-0 for very strong randomness.
51 * @data: output array to be filled with random data.
52 * @datalen: size of output array.
53 *
54 * Store cryptographically random data of given size in the provided
55 * buffer.
56 *
57 * Return value: Returns %SHISHI_OK iff successful.
58 **/
59 int
shishi_randomize(Shishi * handle,int strong,void * data,size_t datalen)60 shishi_randomize (Shishi * handle, int strong, void *data, size_t datalen)
61 {
62 Gc_rc rc;
63
64 if (strong)
65 rc = gc_random (data, datalen);
66 else
67 rc = gc_pseudo_random (data, datalen);
68
69 if (rc != GC_OK)
70 return SHISHI_FILE_ERROR;
71
72 return SHISHI_OK;
73 }
74
75 /**
76 * shishi_crc:
77 * @handle: shishi handle as allocated by shishi_init().
78 * @in: input character array of data to checksum.
79 * @inlen: length of input character array of data to checksum.
80 * @out: newly allocated character array with checksum of data.
81 *
82 * Compute checksum of data using CRC32 modified according to RFC
83 * 1510. The @out buffer must be deallocated by the caller.
84 *
85 * The modifications compared to standard CRC32 is that no initial and
86 * final XOR is performed, and that the output is returned in
87 * LSB-first order.
88 *
89 * Return value: Returns SHISHI_OK iff successful.
90 **/
91 int
shishi_crc(Shishi * handle,const char * in,size_t inlen,char * out[4])92 shishi_crc (Shishi * handle, const char *in, size_t inlen, char *out[4])
93 {
94 uint32_t crc = crc32_update_no_xor (0, in, inlen);
95
96 *out = xmalloc (4);
97 (*out)[0] = crc & 0xFF;
98 (*out)[1] = (crc >> 8) & 0xFF;
99 (*out)[2] = (crc >> 16) & 0xFF;
100 (*out)[3] = (crc >> 24) & 0xFF;
101
102 return SHISHI_OK;
103 }
104
105 /**
106 * shishi_md4:
107 * @handle: shishi handle as allocated by shishi_init().
108 * @in: input character array of data to hash.
109 * @inlen: length of input character array of data to hash.
110 * @out: newly allocated character array with hash of data.
111 *
112 * Compute hash of data using MD4. The @out buffer must be
113 * deallocated by the caller.
114 *
115 * Return value: Returns SHISHI_OK iff successful.
116 **/
117 int
shishi_md4(Shishi * handle,const char * in,size_t inlen,char * out[16])118 shishi_md4 (Shishi * handle, const char *in, size_t inlen, char *out[16])
119 {
120 Gc_rc rc;
121
122 *out = xmalloc (GC_MD4_DIGEST_SIZE);
123 rc = gc_md4 (in, inlen, *out);
124 if (rc != GC_OK)
125 return SHISHI_CRYPTO_INTERNAL_ERROR;
126
127 return SHISHI_OK;
128 }
129
130 /**
131 * shishi_md5:
132 * @handle: shishi handle as allocated by shishi_init().
133 * @in: input character array of data to hash.
134 * @inlen: length of input character array of data to hash.
135 * @out: newly allocated character array with hash of data.
136 *
137 * Compute hash of data using MD5. The @out buffer must be
138 * deallocated by the caller.
139 *
140 * Return value: Returns SHISHI_OK iff successful.
141 **/
142 int
shishi_md5(Shishi * handle,const char * in,size_t inlen,char * out[16])143 shishi_md5 (Shishi * handle, const char *in, size_t inlen, char *out[16])
144 {
145 Gc_rc rc;
146
147 *out = xmalloc (GC_MD5_DIGEST_SIZE);
148 rc = gc_md5 (in, inlen, *out);
149 if (rc != GC_OK)
150 return SHISHI_CRYPTO_INTERNAL_ERROR;
151
152 return SHISHI_OK;
153 }
154
155 /**
156 * shishi_hmac_md5:
157 * @handle: shishi handle as allocated by shishi_init().
158 * @key: input character array with key to use.
159 * @keylen: length of input character array with key to use.
160 * @in: input character array of data to hash.
161 * @inlen: length of input character array of data to hash.
162 * @outhash: newly allocated character array with keyed hash of data.
163 *
164 * Compute keyed checksum of data using HMAC-MD5. The @outhash buffer
165 * must be deallocated by the caller.
166 *
167 * Return value: Returns SHISHI_OK iff successful.
168 **/
169 int
shishi_hmac_md5(Shishi * handle,const char * key,size_t keylen,const char * in,size_t inlen,char * outhash[16])170 shishi_hmac_md5 (Shishi * handle,
171 const char *key, size_t keylen,
172 const char *in, size_t inlen, char *outhash[16])
173 {
174 Gc_rc rc;
175
176 *outhash = xmalloc (GC_MD5_DIGEST_SIZE);
177 rc = gc_hmac_md5 (key, keylen, in, inlen, *outhash);
178 if (rc != GC_OK)
179 return SHISHI_CRYPTO_INTERNAL_ERROR;
180
181 return SHISHI_OK;
182 }
183
184 /**
185 * shishi_hmac_sha1:
186 * @handle: shishi handle as allocated by shishi_init().
187 * @key: input character array with key to use.
188 * @keylen: length of input character array with key to use.
189 * @in: input character array of data to hash.
190 * @inlen: length of input character array of data to hash.
191 * @outhash: newly allocated character array with keyed hash of data.
192 *
193 * Compute keyed checksum of data using HMAC-SHA1. The @outhash
194 * buffer must be deallocated by the caller.
195 *
196 * Return value: Returns SHISHI_OK iff successful.
197 **/
198 int
shishi_hmac_sha1(Shishi * handle,const char * key,size_t keylen,const char * in,size_t inlen,char * outhash[20])199 shishi_hmac_sha1 (Shishi * handle,
200 const char *key, size_t keylen,
201 const char *in, size_t inlen, char *outhash[20])
202 {
203 Gc_rc rc;
204
205 *outhash = xmalloc (GC_SHA1_DIGEST_SIZE);
206 rc = gc_hmac_sha1 (key, keylen, in, inlen, *outhash);
207 if (rc != GC_OK)
208 return SHISHI_CRYPTO_INTERNAL_ERROR;
209
210 return SHISHI_OK;
211 }
212
213 /**
214 * shishi_des_cbc_mac:
215 * @handle: shishi handle as allocated by shishi_init().
216 * @key: input character array with key to use.
217 * @iv: input character array with initialization vector to use, can be NULL.
218 * @in: input character array of data to hash.
219 * @inlen: length of input character array of data to hash.
220 * @out: newly allocated character array with keyed hash of data.
221 *
222 * Computed keyed checksum of data using DES-CBC-MAC. The @out buffer
223 * must be deallocated by the caller.
224 *
225 * Return value: Returns SHISHI_OK iff successful.
226 **/
227 int
shishi_des_cbc_mac(Shishi * handle,const char key[8],const char iv[8],const char * in,size_t inlen,char * out[8])228 shishi_des_cbc_mac (Shishi * handle,
229 const char key[8],
230 const char iv[8],
231 const char *in, size_t inlen, char *out[8])
232 {
233 gcry_cipher_hd_t ch;
234 gpg_error_t err;
235 int res = SHISHI_CRYPTO_INTERNAL_ERROR;
236
237 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES,
238 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
239 if (err != GPG_ERR_NO_ERROR)
240 {
241 shishi_error_printf (handle, "DES-CBC-MAC not available in libgcrypt");
242 return SHISHI_CRYPTO_INTERNAL_ERROR;
243 }
244
245 err = gcry_cipher_setkey (ch, key, 8);
246 if (err != GPG_ERR_NO_ERROR)
247 {
248 shishi_error_printf (handle, "DES setkey failed");
249 shishi_error_set (handle, gpg_strerror (err));
250 goto done;
251 }
252
253 err = gcry_cipher_setiv (ch, iv, 8);
254 if (err != GPG_ERR_NO_ERROR)
255 {
256 shishi_error_printf (handle, "DES setiv failed");
257 shishi_error_set (handle, gpg_strerror (err));
258 goto done;
259 }
260
261 *out = xmalloc (8);
262
263 err = gcry_cipher_encrypt (ch, *out, 8, in, inlen);
264 if (err != GPG_ERR_NO_ERROR)
265 {
266 shishi_error_printf (handle, "DES encrypt failed");
267 shishi_error_set (handle, gpg_strerror (err));
268 goto done;
269 }
270
271 res = SHISHI_OK;
272
273 done:
274 gcry_cipher_close (ch);
275 return res;
276 }
277
278 static int
libgcrypt_dencrypt(Shishi * handle,int algo,int flags,int mode,int decryptp,const char * key,size_t keylen,const char * iv,char ** ivout,const char * in,size_t inlen,char ** out)279 libgcrypt_dencrypt (Shishi * handle, int algo, int flags, int mode,
280 int decryptp,
281 const char *key, size_t keylen,
282 const char *iv,
283 char **ivout, const char *in, size_t inlen, char **out)
284 {
285 size_t ivlen = gcry_cipher_get_algo_blklen (algo);
286 gcry_cipher_hd_t ch;
287 gpg_error_t err;
288
289 err = gcry_cipher_open (&ch, algo, mode, flags);
290 if (err != GPG_ERR_NO_ERROR)
291 {
292 shishi_error_printf (handle, "Libgcrypt cipher open failed");
293 shishi_error_set (handle, gpg_strerror (err));
294 return SHISHI_CRYPTO_INTERNAL_ERROR;
295 }
296
297 err = gcry_cipher_setkey (ch, key, keylen);
298 if (err != GPG_ERR_NO_ERROR)
299 {
300 shishi_error_printf (handle, "Libgcrypt setkey failed");
301 shishi_error_set (handle, gpg_strerror (err));
302 return SHISHI_CRYPTO_INTERNAL_ERROR;
303 }
304
305 err = gcry_cipher_setiv (ch, iv, ivlen);
306 if (err != GPG_ERR_NO_ERROR)
307 {
308 shishi_error_printf (handle, "Libgcrypt setiv failed");
309 shishi_error_set (handle, gpg_strerror (err));
310 return SHISHI_CRYPTO_INTERNAL_ERROR;
311 }
312
313 *out = xmalloc (inlen);
314
315 if (decryptp)
316 err = gcry_cipher_decrypt (ch, (unsigned char *) *out, inlen,
317 (const unsigned char *) in, inlen);
318 else
319 err = gcry_cipher_encrypt (ch, (unsigned char *) *out, inlen,
320 (const unsigned char *) in, inlen);
321 if (err != GPG_ERR_NO_ERROR)
322 {
323 shishi_error_printf (handle, "Libgcrypt ciphering failed");
324 shishi_error_set (handle, gpg_strerror (err));
325 return SHISHI_CRYPTO_INTERNAL_ERROR;
326 }
327
328 if (ivout)
329 {
330 size_t ivdiff, ivpos = 0;
331
332 *ivout = xmalloc (ivlen);
333
334 if (flags & GCRY_CIPHER_CBC_CTS)
335 {
336 /* XXX what is the output iv for CBC-CTS mode?
337 but is this value useful at all for that mode anyway?
338 Mostly it is DES apps that want the updated iv, so this is ok. */
339
340 if (inlen % ivlen)
341 ivdiff = ivlen + inlen % ivlen;
342 else
343 ivdiff = ivlen + ivlen;
344
345 if (inlen >= ivdiff)
346 ivpos = inlen - ivdiff;
347 }
348 else
349 ivpos = inlen - ivlen;
350
351 if (decryptp)
352 memcpy (*ivout, in + ivpos, inlen >= ivlen ? ivlen : inlen);
353 else
354 memcpy (*ivout, *out + ivpos, inlen >= ivlen ? ivlen : inlen);
355 }
356
357 gcry_cipher_close (ch);
358
359 return SHISHI_OK;
360 }
361
362 /**
363 * shishi_arcfour:
364 * @handle: shishi handle as allocated by shishi_init().
365 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
366 * @key: input character array with key to use.
367 * @keylen: length of input key array.
368 * @iv: input character array with initialization vector to use, or NULL.
369 * @ivout: output character array with updated initialization vector, or NULL.
370 * @in: input character array of data to encrypt/decrypt.
371 * @inlen: length of input character array of data to encrypt/decrypt.
372 * @out: newly allocated character array with encrypted/decrypted data.
373 *
374 * Encrypt or decrypt data (depending on @decryptp) using ARCFOUR.
375 * The @out buffer must be deallocated by the caller.
376 *
377 * The "initialization vector" used here is the concatenation of the
378 * sbox and i and j, and is thus always of size 256 + 1 + 1. This is
379 * a slight abuse of terminology, and assumes you know what you are
380 * doing. Don't use it if you can avoid to.
381 *
382 * Return value: Returns SHISHI_OK iff successful.
383 **/
384 int
shishi_arcfour(Shishi * handle,int decryptp,const char * key,size_t keylen,const char iv[258],char * ivout[258],const char * in,size_t inlen,char ** out)385 shishi_arcfour (Shishi * handle, int decryptp,
386 const char *key, size_t keylen,
387 const char iv[258], char *ivout[258],
388 const char *in, size_t inlen, char **out)
389 {
390 arcfour_context ctx;
391
392 *out = xmalloc (inlen);
393
394 if (iv)
395 memcpy (&ctx, iv, sizeof (ctx));
396 else
397 arcfour_setkey (&ctx, key, keylen);
398
399 arcfour_stream (&ctx, in, *out, inlen);
400
401 if (ivout)
402 {
403 *ivout = xmalloc (sizeof (ctx));
404 memcpy (*ivout, &ctx, sizeof (ctx));
405 }
406
407 return SHISHI_OK;
408 }
409
410 /**
411 * shishi_des:
412 * @handle: shishi handle as allocated by shishi_init().
413 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
414 * @key: input character array with key to use.
415 * @iv: input character array with initialization vector to use, or NULL.
416 * @ivout: output character array with updated initialization vector, or NULL.
417 * @in: input character array of data to encrypt/decrypt.
418 * @inlen: length of input character array of data to encrypt/decrypt.
419 * @out: newly allocated character array with encrypted/decrypted data.
420 *
421 * Encrypt or decrypt data (depending on @decryptp) using DES in CBC
422 * mode. The @out buffer must be deallocated by the caller.
423 *
424 * Return value: Returns SHISHI_OK iff successful.
425 **/
426 int
shishi_des(Shishi * handle,int decryptp,const char key[8],const char iv[8],char * ivout[8],const char * in,size_t inlen,char ** out)427 shishi_des (Shishi * handle, int decryptp,
428 const char key[8],
429 const char iv[8],
430 char *ivout[8], const char *in, size_t inlen, char **out)
431 {
432 return libgcrypt_dencrypt (handle, GCRY_CIPHER_DES, 0, GCRY_CIPHER_MODE_CBC,
433 decryptp, key, 8, iv, ivout, in, inlen, out);
434 }
435
436 /**
437 * shishi_3des:
438 * @handle: shishi handle as allocated by shishi_init().
439 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
440 * @key: input character array with key to use.
441 * @iv: input character array with initialization vector to use, or NULL.
442 * @ivout: output character array with updated initialization vector, or NULL.
443 * @in: input character array of data to encrypt/decrypt.
444 * @inlen: length of input character array of data to encrypt/decrypt.
445 * @out: newly allocated character array with encrypted/decrypted data.
446 *
447 * Encrypt or decrypt data (depending on @decryptp) using 3DES in CBC
448 * mode. The @out buffer must be deallocated by the caller.
449 *
450 * Return value: Returns SHISHI_OK iff successful.
451 **/
452 int
shishi_3des(Shishi * handle,int decryptp,const char key[8],const char iv[8],char * ivout[8],const char * in,size_t inlen,char ** out)453 shishi_3des (Shishi * handle, int decryptp,
454 const char key[8],
455 const char iv[8],
456 char *ivout[8], const char *in, size_t inlen, char **out)
457 {
458 return libgcrypt_dencrypt (handle, GCRY_CIPHER_3DES, 0,
459 GCRY_CIPHER_MODE_CBC, decryptp, key, 24, iv,
460 ivout, in, inlen, out);
461 }
462
463 /**
464 * shishi_aes_cts:
465 * @handle: shishi handle as allocated by shishi_init().
466 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
467 * @key: input character array with key to use.
468 * @keylen: length of input character array with key to use.
469 * @iv: input character array with initialization vector to use, or NULL.
470 * @ivout: output character array with updated initialization vector, or NULL.
471 * @in: input character array of data to encrypt/decrypt.
472 * @inlen: length of input character array of data to encrypt/decrypt.
473 * @out: newly allocated character array with encrypted/decrypted data.
474 *
475 * Encrypt or decrypt data (depending on @decryptp) using AES in
476 * CBC-CTS mode. The length of the key, @keylen, decide if AES 128 or
477 * AES 256 should be used. The @out buffer must be deallocated by the
478 * caller.
479 *
480 * Return value: Returns SHISHI_OK iff successful.
481 **/
482 int
shishi_aes_cts(Shishi * handle,int decryptp,const char * key,size_t keylen,const char iv[16],char * ivout[16],const char * in,size_t inlen,char ** out)483 shishi_aes_cts (Shishi * handle, int decryptp,
484 const char *key, size_t keylen,
485 const char iv[16],
486 char *ivout[16], const char *in, size_t inlen, char **out)
487 {
488 return libgcrypt_dencrypt (handle, GCRY_CIPHER_AES, GCRY_CIPHER_CBC_CTS,
489 GCRY_CIPHER_MODE_CBC, decryptp,
490 key, keylen, iv, ivout, in, inlen, out);
491 }
492
493 /**
494 * shishi_pbkdf2_sha1:
495 * @handle: shishi handle as allocated by shishi_init().
496 * @P: input password, an octet string
497 * @Plen: length of password, an octet string
498 * @S: input salt, an octet string
499 * @Slen: length of salt, an octet string
500 * @c: iteration count, a positive integer
501 * @dkLen: intended length in octets of the derived key, a positive integer,
502 * at most (2^32 - 1) * hLen. The DK array must have room for this many
503 * characters.
504 * @DK: output derived key, a dkLen-octet string
505 *
506 * Derive key using the PBKDF2 defined in PKCS5. PBKDF2 applies a
507 * pseudorandom function to derive keys. The length of the derived key
508 * is essentially unbounded. (However, the maximum effective search
509 * space for the derived key may be limited by the structure of the
510 * underlying pseudorandom function, which is this function is always
511 * SHA1.)
512 *
513 * Return value: Returns SHISHI_OK iff successful.
514 **/
515 int
shishi_pbkdf2_sha1(Shishi * handle,const char * P,size_t Plen,const char * S,size_t Slen,unsigned int c,unsigned int dkLen,char * DK)516 shishi_pbkdf2_sha1 (Shishi * handle,
517 const char *P, size_t Plen,
518 const char *S, size_t Slen,
519 unsigned int c, unsigned int dkLen, char *DK)
520 {
521 Gc_rc rc;
522
523 rc = gc_pbkdf2_sha1 (P, Plen, S, Slen, c, DK, dkLen);
524
525 if (rc == GC_PKCS5_INVALID_ITERATION_COUNT)
526 return SHISHI_PKCS5_INVALID_ITERATION_COUNT;
527
528 if (rc == GC_PKCS5_INVALID_DERIVED_KEY_LENGTH)
529 return SHISHI_PKCS5_INVALID_DERIVED_KEY_LENGTH;
530
531 if (rc == GC_PKCS5_DERIVED_KEY_TOO_LONG)
532 return SHISHI_PKCS5_DERIVED_KEY_TOO_LONG;
533
534 if (rc != GC_OK)
535 return SHISHI_CRYPTO_INTERNAL_ERROR;
536
537 return SHISHI_OK;
538 }
539