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
30 _shishi_crypto_init (Shishi
* handle
)
35 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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
50 * Return value: Returns %SHISHI_OK iff successful.
53 shishi_randomize (Shishi
* handle
, int strong
, void *data
, size_t datalen
)
58 rc
= gc_random (data
, datalen
);
60 rc
= gc_pseudo_random (data
, datalen
);
63 return SHISHI_FILE_ERROR
;
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
82 * Return value: Returns SHISHI_OK iff successful.
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
);
90 (*out
)[0] = crc
& 0xFF;
91 (*out
)[1] = (crc
>> 8) & 0xFF;
92 (*out
)[2] = (crc
>> 16) & 0xFF;
93 (*out
)[3] = (crc
>> 24) & 0xFF;
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])
116 *out
= xmalloc (GC_MD4_DIGEST_SIZE
);
117 rc
= gc_md4 (in
, inlen
, *out
);
119 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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])
142 *out
= xmalloc (GC_MD5_DIGEST_SIZE
);
143 rc
= gc_md5 (in
, inlen
, *out
);
145 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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])
171 *outhash
= xmalloc (GC_MD5_DIGEST_SIZE
);
172 rc
= gc_hmac_md5 (key
, keylen
, in
, inlen
, *outhash
);
174 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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
,
201 *outhash
= xmalloc (GC_SHA1_DIGEST_SIZE
);
202 rc
= gc_hmac_sha1 (key
, keylen
, in
, inlen
, *outhash
);
204 return SHISHI_CRYPTO_INTERNAL_ERROR
;
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
,
227 const char *in
, size_t inlen
, char *out
[8])
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
));
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
));
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
));
270 gcry_cipher_close (ch
);
275 libgcrypt_dencrypt (Shishi
* handle
, int algo
, int flags
, int mode
,
277 const char *key
, size_t keylen
,
279 char **ivout
, const char *in
, size_t inlen
, char **out
)
281 size_t ivlen
= gcry_cipher_get_algo_blklen (algo
);
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
);
312 err
= gcry_cipher_decrypt (ch
, (unsigned char *) *out
, inlen
,
313 (const unsigned char *) in
, inlen
);
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
;
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. */
337 ivdiff
= ivlen
+ inlen
% ivlen
;
339 ivdiff
= ivlen
+ ivlen
;
342 ivpos
= inlen
- ivdiff
;
345 ivpos
= inlen
- ivlen
;
348 memcpy (*ivout
, in
+ ivpos
, inlen
>= ivlen
? ivlen
: inlen
);
350 memcpy (*ivout
, *out
+ ivpos
, inlen
>= ivlen
? ivlen
: inlen
);
353 gcry_cipher_close (ch
);
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
)
388 *out
= xmalloc (inlen
);
391 memcpy (&ctx
, iv
, sizeof (ctx
));
393 arcfour_setkey (&ctx
, key
, keylen
);
395 arcfour_stream (&ctx
, in
, *out
, inlen
);
399 *ivout
= xmalloc (sizeof (ctx
));
400 memcpy (*ivout
, &ctx
, sizeof (ctx
));
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
,
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
);
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
,
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
);
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
478 * Return value: Returns SHISHI_OK iff successful.
481 shishi_aes_cts (Shishi
* handle
, int decryptp
,
482 const char *key
, size_t keylen
,
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
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
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
)
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
;
534 return SHISHI_CRYPTO_INTERNAL_ERROR
;