No need for getline.h.
[shishi.git] / lib / low-crypto.c
blob724c779b6ae442f7b52392f3de7aaec17fb3b7eb
1 /* low-crypto.c --- Shishi crypto wrappers around generic crypto.
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
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.
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.
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
23 #include "internal.h"
24 #include "gc.h"
25 #include "arcfour.h"
26 #include <gcrypt.h>
27 #include "crc.h"
29 int
30 _shishi_crypto_init (Shishi * handle)
32 int rc = gc_init ();
34 if (rc != GC_OK)
35 return SHISHI_CRYPTO_INTERNAL_ERROR;
37 return SHISHI_OK;
40 /**
41 * shishi_randomize:
42 * @handle: shishi handle as allocated by shishi_init().
43 * @strong: 0 iff operation should not block, non-0 for very strong randomness.
44 * @data: output array to be filled with random data.
45 * @datalen: size of output array.
47 * Store cryptographically random data of given size in the provided
48 * buffer.
50 * Return value: Returns %SHISHI_OK iff successful.
51 **/
52 int
53 shishi_randomize (Shishi * handle, int strong, void *data, size_t datalen)
55 Gc_rc rc;
57 if (strong)
58 rc = gc_random (data, datalen);
59 else
60 rc = gc_pseudo_random (data, datalen);
62 if (rc != GC_OK)
63 return SHISHI_FILE_ERROR;
65 return SHISHI_OK;
68 /**
69 * shishi_crc:
70 * @handle: shishi handle as allocated by shishi_init().
71 * @in: input character array of data to checksum.
72 * @inlen: length of input character array of data to checksum.
73 * @out: newly allocated character array with checksum of data.
75 * Compute checksum of data using CRC32 modified according to RFC
76 * 1510. The @out buffer must be deallocated by the caller.
78 * The modifications compared to standard CRC32 is that no initial and
79 * final XOR is performed, and that the output is returned in
80 * LSB-first order.
82 * Return value: Returns SHISHI_OK iff successful.
83 **/
84 int
85 shishi_crc (Shishi * handle, const char *in, size_t inlen, char *out[4])
87 uint32_t crc = crc32_update_no_xor (0, in, inlen);
89 *out = xmalloc (4);
90 (*out)[0] = crc & 0xFF;
91 (*out)[1] = (crc >> 8) & 0xFF;
92 (*out)[2] = (crc >> 16) & 0xFF;
93 (*out)[3] = (crc >> 24) & 0xFF;
95 return SHISHI_OK;
98 /**
99 * shishi_md4:
100 * @handle: shishi handle as allocated by shishi_init().
101 * @in: input character array of data to hash.
102 * @inlen: length of input character array of data to hash.
103 * @out: newly allocated character array with hash of data.
105 * Compute hash of data using MD4. The @out buffer must be
106 * deallocated by the caller.
108 * Return value: Returns SHISHI_OK iff successful.
111 shishi_md4 (Shishi * handle,
112 const char *in, size_t inlen, char *out[16])
114 Gc_rc rc;
116 *out = xmalloc (GC_MD4_DIGEST_SIZE);
117 rc = gc_md4 (in, inlen, *out);
118 if (rc != GC_OK)
119 return SHISHI_CRYPTO_INTERNAL_ERROR;
121 return SHISHI_OK;
125 * shishi_md5:
126 * @handle: shishi handle as allocated by shishi_init().
127 * @in: input character array of data to hash.
128 * @inlen: length of input character array of data to hash.
129 * @out: newly allocated character array with hash of data.
131 * Compute hash of data using MD5. The @out buffer must be
132 * deallocated by the caller.
134 * Return value: Returns SHISHI_OK iff successful.
137 shishi_md5 (Shishi * handle,
138 const char *in, size_t inlen, char *out[16])
140 Gc_rc rc;
142 *out = xmalloc (GC_MD5_DIGEST_SIZE);
143 rc = gc_md5 (in, inlen, *out);
144 if (rc != GC_OK)
145 return SHISHI_CRYPTO_INTERNAL_ERROR;
147 return SHISHI_OK;
151 * shishi_hmac_md5:
152 * @handle: shishi handle as allocated by shishi_init().
153 * @key: input character array with key to use.
154 * @keylen: length of input character array with key to use.
155 * @in: input character array of data to hash.
156 * @inlen: length of input character array of data to hash.
157 * @outhash: newly allocated character array with keyed hash of data.
159 * Compute keyed checksum of data using HMAC-MD5. The @outhash buffer
160 * must be deallocated by the caller.
162 * Return value: Returns SHISHI_OK iff successful.
165 shishi_hmac_md5 (Shishi * handle,
166 const char *key, size_t keylen,
167 const char *in, size_t inlen, char *outhash[16])
169 Gc_rc rc;
171 *outhash = xmalloc (GC_MD5_DIGEST_SIZE);
172 rc = gc_hmac_md5 (key, keylen, in, inlen, *outhash);
173 if (rc != GC_OK)
174 return SHISHI_CRYPTO_INTERNAL_ERROR;
176 return SHISHI_OK;
180 * shishi_hmac_sha1:
181 * @handle: shishi handle as allocated by shishi_init().
182 * @key: input character array with key to use.
183 * @keylen: length of input character array with key to use.
184 * @in: input character array of data to hash.
185 * @inlen: length of input character array of data to hash.
186 * @outhash: newly allocated character array with keyed hash of data.
188 * Compute keyed checksum of data using HMAC-SHA1. The @outhash
189 * buffer must be deallocated by the caller.
191 * Return value: Returns SHISHI_OK iff successful.
194 shishi_hmac_sha1 (Shishi * handle,
195 const char *key, size_t keylen,
196 const char *in, size_t inlen,
197 char *outhash[20])
199 Gc_rc rc;
201 *outhash = xmalloc (GC_SHA1_DIGEST_SIZE);
202 rc = gc_hmac_sha1 (key, keylen, in, inlen, *outhash);
203 if (rc != GC_OK)
204 return SHISHI_CRYPTO_INTERNAL_ERROR;
206 return SHISHI_OK;
210 * shishi_des_cbc_mac:
211 * @handle: shishi handle as allocated by shishi_init().
212 * @key: input character array with key to use.
213 * @iv: input character array with initialization vector to use, can be NULL.
214 * @in: input character array of data to hash.
215 * @inlen: length of input character array of data to hash.
216 * @out: newly allocated character array with keyed hash of data.
218 * Computed keyed checksum of data using DES-CBC-MAC. The @out buffer
219 * must be deallocated by the caller.
221 * Return value: Returns SHISHI_OK iff successful.
224 shishi_des_cbc_mac (Shishi * handle,
225 const char key[8],
226 const char iv[8],
227 const char *in, size_t inlen, char *out[8])
229 gcry_cipher_hd_t ch;
230 gpg_error_t err;
231 int res = SHISHI_CRYPTO_INTERNAL_ERROR;
233 err = gcry_cipher_open (&ch, GCRY_CIPHER_DES,
234 GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
235 if (err != GPG_ERR_NO_ERROR)
237 shishi_error_printf (handle, "DES-CBC-MAC not available in libgcrypt");
238 return SHISHI_CRYPTO_INTERNAL_ERROR;
241 err = gcry_cipher_setkey (ch, key, 8);
242 if (err != GPG_ERR_NO_ERROR)
244 shishi_error_printf (handle, "DES setkey failed");
245 shishi_error_set (handle, gpg_strerror (err));
246 goto done;
249 err = gcry_cipher_setiv (ch, iv, 8);
250 if (err != GPG_ERR_NO_ERROR)
252 shishi_error_printf (handle, "DES setiv failed");
253 shishi_error_set (handle, gpg_strerror (err));
254 goto done;
257 *out = xmalloc (8);
259 err = gcry_cipher_encrypt (ch, *out, 8, in, inlen);
260 if (err != GPG_ERR_NO_ERROR)
262 shishi_error_printf (handle, "DES encrypt failed");
263 shishi_error_set (handle, gpg_strerror (err));
264 goto done;
267 res = SHISHI_OK;
269 done:
270 gcry_cipher_close (ch);
271 return res;
274 static int
275 libgcrypt_dencrypt (Shishi * handle, int algo, int flags, int mode,
276 int decryptp,
277 const char *key, size_t keylen,
278 const char *iv,
279 char **ivout, const char *in, size_t inlen, char **out)
281 size_t ivlen = gcry_cipher_get_algo_blklen (algo);
282 gcry_cipher_hd_t ch;
283 gpg_error_t err;
285 err = gcry_cipher_open (&ch, algo, mode, flags);
286 if (err != GPG_ERR_NO_ERROR)
288 shishi_error_printf (handle, "Libgcrypt cipher open failed");
289 shishi_error_set (handle, gpg_strerror (err));
290 return SHISHI_CRYPTO_INTERNAL_ERROR;
293 err = gcry_cipher_setkey (ch, key, keylen);
294 if (err != GPG_ERR_NO_ERROR)
296 shishi_error_printf (handle, "Libgcrypt setkey failed");
297 shishi_error_set (handle, gpg_strerror (err));
298 return SHISHI_CRYPTO_INTERNAL_ERROR;
301 err = gcry_cipher_setiv (ch, iv, ivlen);
302 if (err != GPG_ERR_NO_ERROR)
304 shishi_error_printf (handle, "Libgcrypt setiv failed");
305 shishi_error_set (handle, gpg_strerror (err));
306 return SHISHI_CRYPTO_INTERNAL_ERROR;
309 *out = xmalloc (inlen);
311 if (decryptp)
312 err = gcry_cipher_decrypt (ch, (unsigned char *) *out, inlen,
313 (const unsigned char *) in, inlen);
314 else
315 err = gcry_cipher_encrypt (ch, (unsigned char *) *out, inlen,
316 (const unsigned char *) in, inlen);
317 if (err != GPG_ERR_NO_ERROR)
319 shishi_error_printf (handle, "Libgcrypt ciphering failed");
320 shishi_error_set (handle, gpg_strerror (err));
321 return SHISHI_CRYPTO_INTERNAL_ERROR;
324 if (ivout)
326 size_t ivdiff, ivpos = 0;
328 *ivout = xmalloc (ivlen);
330 if (flags & GCRY_CIPHER_CBC_CTS)
332 /* XXX what is the output iv for CBC-CTS mode?
333 but is this value useful at all for that mode anyway?
334 Mostly it is DES apps that want the updated iv, so this is ok. */
336 if (inlen % ivlen)
337 ivdiff = ivlen + inlen % ivlen;
338 else
339 ivdiff = ivlen + ivlen;
341 if (inlen >= ivdiff)
342 ivpos = inlen - ivdiff;
344 else
345 ivpos = inlen - ivlen;
347 if (decryptp)
348 memcpy (*ivout, in + ivpos, inlen >= ivlen ? ivlen : inlen);
349 else
350 memcpy (*ivout, *out + ivpos, inlen >= ivlen ? ivlen : inlen);
353 gcry_cipher_close (ch);
355 return SHISHI_OK;
359 * shishi_arcfour:
360 * @handle: shishi handle as allocated by shishi_init().
361 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
362 * @key: input character array with key to use.
363 * @keylen: length of input key array.
364 * @iv: input character array with initialization vector to use, or NULL.
365 * @ivout: output character array with updated initialization vector, or NULL.
366 * @in: input character array of data to encrypt/decrypt.
367 * @inlen: length of input character array of data to encrypt/decrypt.
368 * @out: newly allocated character array with encrypted/decrypted data.
370 * Encrypt or decrypt data (depending on @decryptp) using ARCFOUR.
371 * The @out buffer must be deallocated by the caller.
373 * The "initialization vector" used here is the concatenation of the
374 * sbox and i and j, and is thus always of size 256 + 1 + 1. This is
375 * a slight abuse of terminology, and assumes you know what you are
376 * doing. Don't use it if you can avoid to.
378 * Return value: Returns SHISHI_OK iff successful.
381 shishi_arcfour (Shishi * handle, int decryptp,
382 const char *key, size_t keylen,
383 const char iv[258], char *ivout[258],
384 const char *in, size_t inlen, char **out)
386 arcfour_context ctx;
388 *out = xmalloc (inlen);
390 if (iv)
391 memcpy (&ctx, iv, sizeof (ctx));
392 else
393 arcfour_setkey (&ctx, key, keylen);
395 arcfour_stream (&ctx, in, *out, inlen);
397 if (ivout)
399 *ivout = xmalloc (sizeof (ctx));
400 memcpy (*ivout, &ctx, sizeof (ctx));
403 return SHISHI_OK;
407 * shishi_des:
408 * @handle: shishi handle as allocated by shishi_init().
409 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
410 * @key: input character array with key to use.
411 * @iv: input character array with initialization vector to use, or NULL.
412 * @ivout: output character array with updated initialization vector, or NULL.
413 * @in: input character array of data to encrypt/decrypt.
414 * @inlen: length of input character array of data to encrypt/decrypt.
415 * @out: newly allocated character array with encrypted/decrypted data.
417 * Encrypt or decrypt data (depending on @decryptp) using DES in CBC
418 * mode. The @out buffer must be deallocated by the caller.
420 * Return value: Returns SHISHI_OK iff successful.
423 shishi_des (Shishi * handle, int decryptp,
424 const char key[8],
425 const char iv[8],
426 char *ivout[8],
427 const char *in, size_t inlen, char **out)
429 return libgcrypt_dencrypt (handle, GCRY_CIPHER_DES, 0, GCRY_CIPHER_MODE_CBC,
430 decryptp, key, 8, iv, ivout, in, inlen, out);
434 * shishi_3des:
435 * @handle: shishi handle as allocated by shishi_init().
436 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
437 * @key: input character array with key to use.
438 * @iv: input character array with initialization vector to use, or NULL.
439 * @ivout: output character array with updated initialization vector, or NULL.
440 * @in: input character array of data to encrypt/decrypt.
441 * @inlen: length of input character array of data to encrypt/decrypt.
442 * @out: newly allocated character array with encrypted/decrypted data.
444 * Encrypt or decrypt data (depending on @decryptp) using 3DES in CBC
445 * mode. The @out buffer must be deallocated by the caller.
447 * Return value: Returns SHISHI_OK iff successful.
450 shishi_3des (Shishi * handle, int decryptp,
451 const char key[8],
452 const char iv[8],
453 char *ivout[8],
454 const char *in, size_t inlen, char **out)
456 return libgcrypt_dencrypt (handle, GCRY_CIPHER_3DES, 0,
457 GCRY_CIPHER_MODE_CBC, decryptp, key, 24, iv,
458 ivout, in, inlen, out);
462 * shishi_aes_cts:
463 * @handle: shishi handle as allocated by shishi_init().
464 * @decryptp: 0 to indicate encryption, non-0 to indicate decryption.
465 * @key: input character array with key to use.
466 * @keylen: length of input character array with key to use.
467 * @iv: input character array with initialization vector to use, or NULL.
468 * @ivout: output character array with updated initialization vector, or NULL.
469 * @in: input character array of data to encrypt/decrypt.
470 * @inlen: length of input character array of data to encrypt/decrypt.
471 * @out: newly allocated character array with encrypted/decrypted data.
473 * Encrypt or decrypt data (depending on @decryptp) using AES in
474 * CBC-CTS mode. The length of the key, @keylen, decide if AES 128 or
475 * AES 256 should be used. The @out buffer must be deallocated by the
476 * caller.
478 * Return value: Returns SHISHI_OK iff successful.
481 shishi_aes_cts (Shishi * handle, int decryptp,
482 const char *key, size_t keylen,
483 const char iv[16],
484 char *ivout[16],
485 const char *in, size_t inlen, char **out)
487 return libgcrypt_dencrypt (handle, GCRY_CIPHER_AES, GCRY_CIPHER_CBC_CTS,
488 GCRY_CIPHER_MODE_CBC, decryptp,
489 key, keylen, iv, ivout, in, inlen, out);
493 * shishi_pbkdf2_sha1:
494 * @handle: shishi handle as allocated by shishi_init().
495 * @P: input password, an octet string
496 * @Plen: length of password, an octet string
497 * @S: input salt, an octet string
498 * @Slen: length of salt, an octet string
499 * @c: iteration count, a positive integer
500 * @dkLen: intended length in octets of the derived key, a positive integer,
501 * at most (2^32 - 1) * hLen. The DK array must have room for this many
502 * characters.
503 * @DK: output derived key, a dkLen-octet string
505 * Derive key using the PBKDF2 defined in PKCS5. PBKDF2 applies a
506 * pseudorandom function to derive keys. The length of the derived key
507 * is essentially unbounded. (However, the maximum effective search
508 * space for the derived key may be limited by the structure of the
509 * underlying pseudorandom function, which is this function is always
510 * SHA1.)
512 * Return value: Returns SHISHI_OK iff successful.
515 shishi_pbkdf2_sha1 (Shishi * handle,
516 const char *P, size_t Plen,
517 const char *S, size_t Slen,
518 unsigned int c, unsigned int dkLen, char *DK)
520 Gc_rc rc;
522 rc = gc_pbkdf2_sha1 (P, Plen, S, Slen, c, DK, dkLen);
524 if (rc == GC_PKCS5_INVALID_ITERATION_COUNT)
525 return SHISHI_PKCS5_INVALID_ITERATION_COUNT;
527 if (rc == GC_PKCS5_INVALID_DERIVED_KEY_LENGTH)
528 return SHISHI_PKCS5_INVALID_DERIVED_KEY_LENGTH;
530 if (rc == GC_PKCS5_DERIVED_KEY_TOO_LONG)
531 return SHISHI_PKCS5_DERIVED_KEY_TOO_LONG;
533 if (rc != GC_OK)
534 return SHISHI_CRYPTO_INTERNAL_ERROR;
536 return SHISHI_OK;