Add 3des-none.
[shishi.git] / lib / crypto.c
blobaabb4f0dd0577c6d0de585908b235ebd2fe5fe92
1 /* crypto.c crypto functions
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* XXX several functions with out/outlen writes longer than the outlen */
24 #include "internal.h"
25 #include <gcrypt.h>
27 static void
28 escapeprint (const char *str, int len)
30 int i;
32 printf ("\t ;; `");
33 for (i = 0; i < len; i++)
34 if ((str[i] >= 'A' && str[i] <= 'Z') ||
35 (str[i] >= 'a' && str[i] <= 'z') ||
36 (str[i] >= '0' && str[i] <= '9') || str[i] == '.')
37 printf ("%c", str[i] & 0xFF);
38 else
39 printf ("\\x%02x", str[i] & 0xFF);
40 printf ("' (length %d bytes)\n", len);
43 static void
44 hexprint (const char *str, int len)
46 int i;
48 printf ("\t ;; ");
49 for (i = 0; i < len; i++)
51 printf ("%02x ", str[i] & 0xFF);
52 if ((i + 1) % 8 == 0)
53 printf (" ");
54 if ((i + 1) % 16 == 0 && i + 1 < len)
55 printf ("\n\t ;; ");
59 static void
60 binprint (const char *str, int len)
62 int i;
64 printf ("\t ;; ");
65 for (i = 0; i < len; i++)
67 printf ("%d%d%d%d%d%d%d%d ",
68 str[i] & 0x80 ? 1 : 0,
69 str[i] & 0x40 ? 1 : 0,
70 str[i] & 0x20 ? 1 : 0,
71 str[i] & 0x10 ? 1 : 0,
72 str[i] & 0x08 ? 1 : 0,
73 str[i] & 0x04 ? 1 : 0,
74 str[i] & 0x02 ? 1 : 0, str[i] & 0x01 ? 1 : 0);
75 if ((i + 1) % 3 == 0)
76 printf (" ");
77 if ((i + 1) % 6 == 0 && i + 1 < len)
78 printf ("\n\t ;; ");
82 static void
83 bin7print (const char *str, int len)
85 int i;
87 printf ("\t ;; ");
88 for (i = 0; i < len; i++)
90 printf ("%d%d%d%d%d%d%d ",
91 str[i] & 0x40 ? 1 : 0,
92 str[i] & 0x20 ? 1 : 0,
93 str[i] & 0x10 ? 1 : 0,
94 str[i] & 0x08 ? 1 : 0,
95 str[i] & 0x04 ? 1 : 0,
96 str[i] & 0x02 ? 1 : 0, str[i] & 0x01 ? 1 : 0);
97 if ((i + 1) % 3 == 0)
98 printf (" ");
99 if ((i + 1) % 6 == 0 && i + 1 < len)
100 printf ("\n\t ;; ");
104 static int
105 gcd (int a, int b)
107 if (b == 0)
108 return a;
109 else
110 return gcd (b, a % b);
113 static int
114 lcm (int a, int b)
116 return a * b / gcd (a, b);
119 static int
120 rot13 (Shishi * handle, char *in, char *out, int len)
122 if (VERBOSECRYPTO (handle))
124 printf ("\t ;; rot 13 in:\n");
125 escapeprint (in, len);
126 hexprint (in, len);
127 puts ("");
128 binprint (in, len);
129 puts ("");
132 if (len == 1)
134 out[0] =
135 ((in[0] >> 5) & 0x01) |
136 ((in[0] >> 5) & 0x02) |
137 ((in[0] >> 5) & 0x04) |
138 ((in[0] << 3) & 0x08) |
139 ((in[0] << 3) & 0x10) |
140 ((in[0] << 3) & 0x20) | ((in[0] << 3) & 0x40) | ((in[0] << 3) & 0x80);
142 else if (len > 1)
144 char nexttolast, last;
145 int i;
147 nexttolast = in[len - 2];
148 last = in[len - 1];
150 for (i = len * 8 - 1; i >= 13; i--)
152 int pos = i / 8;
153 char mask = ~(1 << (7 - i % 8));
154 int pos2 = (i - 13) / 8;
155 char mask2 = (1 << (7 - (i - 13) % 8));
157 out[pos] = (out[pos] & mask) |
158 (((in[pos2] & mask2) ? 0xFF : 0x00) & ~mask);
160 out[0] = ((nexttolast & 0xFF) << 3) | ((last & 0xFF) >> 5);
161 out[1] = (in[1] & ~(0xFF & (0xFF << 3))) | (0xFF & (last << 3));
164 if (VERBOSECRYPTO (handle))
166 printf ("\t ;; rot13 out:\n");
167 escapeprint (out, len);
168 hexprint (out, len);
169 puts ("");
170 binprint (out, len);
171 puts ("");
174 return SHISHI_OK;
177 static int
178 ocadd (char *add1, char *add2, char *sum, int len)
180 int i;
181 int carry = 0;
183 for (i = len - 1; i >= 0; i--)
185 int tmpsum = (unsigned char) add1[i] + (unsigned char) add2[i];
187 sum[i] = (tmpsum + carry) & 0xFF;
188 if (tmpsum + carry > 0xFF)
189 carry = 1;
190 else
191 carry = 0;
193 if (carry)
195 int done = 0;
197 for (i = len - 1; i >= 0; i--)
198 if ((unsigned char) sum[i] != 0xFF)
200 sum[i]++;
201 done = 1;
202 break;
205 if (!done)
206 memset (sum, 0, len);
209 return SHISHI_OK;
212 static int
213 simplified_hmac (Shishi * handle,
214 Shishi_key * key,
215 const char *in,
216 size_t inlen, char *outhash, size_t outhashlen)
218 GCRY_MD_HD mdh;
219 int halg = GCRY_MD_SHA1;
220 size_t hlen = gcry_md_get_algo_dlen (halg);
221 unsigned char *hash;
222 int res;
224 mdh = gcry_md_open (halg, GCRY_MD_FLAG_HMAC);
225 if (mdh == NULL)
226 return SHISHI_GCRYPT_ERROR;
228 res = gcry_md_setkey (mdh, shishi_key_value (key), shishi_key_length (key));
229 if (res != GCRYERR_SUCCESS)
231 shishi_error_set (handle, gcry_strerror (res));
232 return SHISHI_GCRYPT_ERROR;
235 gcry_md_write (mdh, (const unsigned char *) in, inlen);
237 hash = gcry_md_read (mdh, halg);
238 if (hash == NULL)
239 return SHISHI_GCRYPT_ERROR;
241 memcpy (outhash, hash, outhashlen < hlen ? outhashlen : hlen);
243 gcry_md_close (mdh);
245 return SHISHI_OK;
248 static int
249 simplified_hmac_verify (Shishi * handle,
250 Shishi_key * key,
251 const char *in, size_t inlen,
252 const char *hmac, size_t hmaclen)
254 char hash[MAX_HASH_LEN];
255 int res;
257 res = simplified_hmac (handle, key, in, inlen, hash, hmaclen);
258 if (res != SHISHI_OK)
259 return res;
261 if (memcmp (hash, hmac, hmaclen) != 0)
263 if (VERBOSE (handle))
264 printf ("simplified hmac verify fail\n");
265 return SHISHI_CRYPTO_ERROR;
268 return SHISHI_OK;
271 typedef enum
273 SHISHI_DERIVEKEYMODE_CHECKSUM,
274 SHISHI_DERIVEKEYMODE_PRIVACY,
275 SHISHI_DERIVEKEYMODE_INTEGRITY
277 Shishi_derivekeymode;
279 static int
280 simplified_derivekey (Shishi * handle,
281 Shishi_key * key,
282 int keyusage,
283 int derivekeymode, Shishi_key * derivedkey)
285 char constant[5];
286 int res = SHISHI_OK;
288 if (VERBOSECRYPTO (handle))
290 printf ("simplified_derivekey\n");
291 printf ("\t ;; mode %d (%s)\n", derivekeymode,
292 derivekeymode == SHISHI_DERIVEKEYMODE_CHECKSUM ? "checksum" :
293 derivekeymode == SHISHI_DERIVEKEYMODE_INTEGRITY ? "integrity" :
294 derivekeymode == SHISHI_DERIVEKEYMODE_PRIVACY ? "privacy" :
295 "base-key");
296 hexprint (shishi_key_value (key), shishi_key_length (key));
297 puts ("");
300 shishi_key_type_set (derivedkey, shishi_key_type (key));
302 if (keyusage)
304 uint32_t tmp = htonl (keyusage);
305 memcpy (constant, &tmp, 4);
306 if (derivekeymode == SHISHI_DERIVEKEYMODE_CHECKSUM)
307 constant[4] = '\x99';
308 else if (derivekeymode == SHISHI_DERIVEKEYMODE_INTEGRITY)
309 constant[4] = '\x55';
310 else /* if (derivekeymode == SHISHI_DERIVEKEYMODE_PRIVACY) */
311 constant[4] = '\xAA';
313 res = shishi_dk (handle, key, constant, 5, derivedkey);
315 else
317 shishi_key_copy (derivedkey, key);
320 if (VERBOSECRYPTO (handle))
322 printf ("\t ;; simplified_derivekey out (%d):\n",
323 shishi_key_length (derivedkey));
324 hexprint (shishi_key_value (derivedkey),
325 shishi_key_length (derivedkey));
326 puts ("");
329 return res;
332 static int
333 simplified_dencrypt (Shishi * handle,
334 Shishi_key * key,
335 const char *iv, size_t ivlen,
336 const char *in, size_t inlen,
337 char *out, size_t * outlen,
338 int direction)
340 int res;
341 GCRY_CIPHER_HD ch;
342 int alg = 0;
343 int mode = GCRY_CIPHER_MODE_CBC;
344 int flags = 0;
346 switch (shishi_key_type (key))
348 case SHISHI_DES3_CBC_HMAC_SHA1_KD:
349 alg = GCRY_CIPHER_3DES;
350 break;
352 case SHISHI_DES_CBC_CRC:
353 case SHISHI_DES_CBC_MD4:
354 case SHISHI_DES_CBC_MD5:
355 alg = GCRY_CIPHER_DES;
356 break;
358 case SHISHI_AES128_CTS_HMAC_SHA1_96:
359 case SHISHI_AES256_CTS_HMAC_SHA1_96:
360 alg = GCRY_CIPHER_AES;
361 flags = GCRY_CIPHER_CBC_CTS;
362 break;
365 ch = gcry_cipher_open (alg, mode, flags);
366 if (ch == NULL)
367 return SHISHI_GCRYPT_ERROR;
369 res =
370 gcry_cipher_setkey (ch, shishi_key_value (key), shishi_key_length (key));
371 if (res == GCRYERR_SUCCESS)
372 res = gcry_cipher_setiv (ch, iv, ivlen);
374 if (res == GCRYERR_SUCCESS)
375 res = direction ?
376 gcry_cipher_decrypt (ch, (unsigned char *) out, *outlen,
377 (const unsigned char *) in, inlen) :
378 gcry_cipher_encrypt (ch, (unsigned char *) out, *outlen,
379 (const unsigned char *) in, inlen);
381 if (res != GCRYERR_SUCCESS)
383 puts (gcry_strerror (res));
384 shishi_error_set (handle, gcry_strerror (res));
385 return SHISHI_GCRYPT_ERROR;
388 *outlen = inlen;
390 gcry_cipher_close (ch);
392 return SHISHI_OK;
395 static int
396 simplified_encrypt (Shishi * handle,
397 Shishi_key * key,
398 int keyusage,
399 const char *iv, size_t ivlen,
400 const char *in, size_t inlen,
401 char *out, size_t * outlen)
403 int res;
404 int padzerolen = 0;
406 if ((shishi_key_type (key) == SHISHI_DES3_CBC_HMAC_SHA1_KD ||
407 shishi_key_type (key) == SHISHI_DES_CBC_CRC ||
408 shishi_key_type (key) == SHISHI_DES_CBC_MD4 ||
409 shishi_key_type (key) == SHISHI_DES_CBC_MD5) && (inlen % 8) != 0)
410 while (((inlen + padzerolen) % 8) != 0)
411 padzerolen++;
413 if (keyusage != 0)
415 char *buffer;
416 int buflen;
417 int blen = shishi_cipher_blocksize (shishi_key_type (key));
418 int halg = GCRY_MD_SHA1;
419 int hlen = gcry_md_get_algo_dlen (halg);
420 size_t len;
421 Shishi_key *derivedkey;
423 res = shishi_key_from_value (handle, shishi_key_type (key),
424 NULL, &derivedkey);
425 if (res != SHISHI_OK)
426 return res;
428 buflen = inlen + blen + padzerolen;
429 buffer = malloc (buflen);
430 if (!buffer)
431 return SHISHI_MALLOC_ERROR;
433 res = shishi_randomize (handle, buffer, blen);
434 if (res != SHISHI_OK)
435 return res;
437 memcpy (buffer + blen, in, inlen);
438 memset (buffer + blen + inlen, 0, padzerolen);
440 res = simplified_derivekey (handle, key, keyusage,
441 SHISHI_DERIVEKEYMODE_PRIVACY, derivedkey);
442 if (res != SHISHI_OK)
443 return res;
445 len = *outlen;
446 res = simplified_dencrypt (handle, derivedkey, iv, ivlen,
447 buffer, buflen, out, &len, 0);
448 if (res != SHISHI_OK)
449 return res;
451 res = simplified_derivekey (handle, key, keyusage,
452 SHISHI_DERIVEKEYMODE_INTEGRITY, derivedkey);
453 if (res != SHISHI_OK)
454 return res;
456 res = simplified_hmac (handle, derivedkey, buffer, buflen,
457 out + len, hlen);
458 if (res != SHISHI_OK)
459 return res;
461 shishi_key_done (&derivedkey);
463 *outlen = buflen + hlen;
465 else
467 res = simplified_dencrypt (handle, key, iv, ivlen,
468 in, inlen, out, outlen, 0);
471 return res;
474 static int
475 simplified_decrypt (Shishi * handle,
476 Shishi_key * key,
477 int keyusage,
478 const char *iv, size_t ivlen,
479 const char *in, size_t inlen,
480 char *out, size_t * outlen)
482 int res;
484 if (keyusage)
486 Shishi_key *derivedkey;
487 int blen = shishi_cipher_blocksize (shishi_key_type (key));
488 int halg = GCRY_MD_SHA1;
489 size_t hlen = gcry_md_get_algo_dlen (halg);
490 size_t len;
492 res = shishi_key_from_value (handle, shishi_key_type (key),
493 NULL, &derivedkey);
494 if (res != SHISHI_OK)
495 return res;
497 res = simplified_derivekey (handle, key, keyusage,
498 SHISHI_DERIVEKEYMODE_PRIVACY, derivedkey);
499 if (res != SHISHI_OK)
500 return res;
502 len = *outlen;
503 *outlen = 0;
504 res = simplified_dencrypt (handle, derivedkey, iv, ivlen,
505 in, inlen - hlen, out, &len, 1);
506 if (res != SHISHI_OK)
507 return res;
509 res = simplified_derivekey (handle, key, keyusage,
510 SHISHI_DERIVEKEYMODE_INTEGRITY, derivedkey);
511 if (res != SHISHI_OK)
512 return res;
514 res = simplified_hmac_verify (handle, derivedkey, out, len,
515 in + inlen - hlen, hlen);
517 if (res != SHISHI_OK)
518 return res;
520 shishi_key_done (&derivedkey);
522 memmove (out, out + blen, len - blen);
523 *outlen = len - blen;
525 else
527 res = simplified_dencrypt (handle, key, iv, ivlen,
528 in, inlen, out, outlen, 1);
531 return res;
534 static int
535 simplified_checksum (Shishi * handle,
536 Shishi_key * key,
537 int keyusage,
538 char *in, int inlen, char *out, int *outlen)
540 Shishi_key *derivedkey;
541 int halg = GCRY_MD_SHA1; /* XXX hide this in crypto-lowlevel.c */
542 int hlen = gcry_md_get_algo_dlen (halg);
543 int res;
545 res = shishi_key_from_value (handle, shishi_key_type (key),
546 NULL, &derivedkey);
547 if (res != SHISHI_OK)
548 return res;
550 res = simplified_derivekey (handle, key, keyusage,
551 SHISHI_DERIVEKEYMODE_CHECKSUM, derivedkey);
552 if (res != SHISHI_OK)
553 return res;
555 res = simplified_hmac (handle, derivedkey, in, inlen, out, hlen);
556 if (res != SHISHI_OK)
558 shishi_error_set (handle, "verify failed");
559 return res;
561 *outlen = hlen;
563 shishi_key_done (&derivedkey);
565 return SHISHI_OK;
568 typedef int (*Shishi_random_to_key_function) (Shishi * handle,
569 const char *random,
570 size_t randomlen,
571 Shishi_key * outkey);
573 typedef int (*Shishi_string_to_key_function) (Shishi * handle,
574 const char *password,
575 size_t passwordlen,
576 const char *salt,
577 size_t saltlen,
578 const char *parameter,
579 Shishi_key * outkey);
581 typedef int (*Shishi_encrypt_function) (Shishi * handle,
582 Shishi_key * key,
583 int keyusage,
584 const char *iv, size_t ivlen,
585 const char *in, size_t inlen,
586 char *out, size_t * outlen);
588 typedef int (*Shishi_decrypt_function) (Shishi * handle,
589 Shishi_key * key,
590 int keyusage,
591 const char *iv, size_t ivlen,
592 const char *in, size_t inlen,
593 char *out, size_t * outlen);
595 #include "crypto-null.c"
596 #include "crypto-des.c"
597 #include "crypto-3des.c"
598 #include "crypto-aes.c"
600 struct cipherinfo
602 int type;
603 char *name;
604 int blocksize;
605 int minpadsize;
606 int confoundersize;
607 int keylen;
608 int randomlen;
609 int defaultcksumtype;
610 Shishi_random_to_key_function random2key;
611 Shishi_string_to_key_function string2key;
612 Shishi_encrypt_function encrypt;
613 Shishi_decrypt_function decrypt;
615 typedef struct cipherinfo cipherinfo;
617 static cipherinfo null_info = {
619 "NULL",
625 SHISHI_RSA_MD5,
626 null_random_to_key,
627 null_string_to_key,
628 null_encrypt,
629 null_decrypt
632 static cipherinfo des_cbc_crc_info = {
634 "des-cbc-crc",
640 SHISHI_RSA_MD5_DES,
641 des_random_to_key,
642 des_string_to_key,
643 des_crc_encrypt,
644 des_crc_decrypt
647 static cipherinfo des_cbc_md4_info = {
649 "des-cbc-md4",
655 SHISHI_RSA_MD4_DES,
656 des_random_to_key,
657 des_string_to_key,
658 des_md4_encrypt,
659 des_md4_decrypt
662 static cipherinfo des_cbc_md5_info = {
664 "des-cbc-md5",
670 SHISHI_RSA_MD5_DES,
671 des_random_to_key,
672 des_string_to_key,
673 des_md5_encrypt,
674 des_md5_decrypt
677 static cipherinfo des3_cbc_sha1_kd_info = {
679 "des3-cbc-sha1-kd",
683 3 * 8,
684 3 * 8,
685 SHISHI_HMAC_SHA1_DES3_KD,
686 des3_random_to_key,
687 des3_string_to_key,
688 des3_encrypt,
689 des3_decrypt
692 static cipherinfo des3_cbc_none_info = {
693 -4097,
694 "des3-cbc-none",
698 3 * 8,
699 3 * 8,
700 SHISHI_HMAC_SHA1_DES3_KD,
701 des3_random_to_key,
702 des3_string_to_key,
703 des3none_encrypt,
704 des3none_decrypt
707 static cipherinfo aes128_cts_hmac_sha1_96_info = {
709 "aes128-cts-hmac-sha1-96",
713 128 / 8,
714 128 / 8,
715 SHISHI_HMAC_SHA1_96_AES128,
716 aes128_random_to_key,
717 aes128_string_to_key,
718 aes128_encrypt,
719 aes128_decrypt
722 static cipherinfo aes256_cts_hmac_sha1_96_info = {
724 "aes256-cts-hmac-sha1-96",
728 256 / 8,
729 256 / 8,
730 SHISHI_HMAC_SHA1_96_AES256,
731 aes256_random_to_key,
732 aes256_string_to_key,
733 aes256_encrypt,
734 aes256_decrypt
737 static cipherinfo *ciphers[] = {
738 &null_info,
739 &des_cbc_crc_info,
740 &des_cbc_md4_info,
741 &des_cbc_md5_info,
742 &des3_cbc_sha1_kd_info,
743 &des3_cbc_none_info,
744 &aes128_cts_hmac_sha1_96_info,
745 &aes256_cts_hmac_sha1_96_info
749 _shishi_cipher_init (void)
751 if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P) == 0)
753 if (gcry_check_version (GCRYPT_VERSION) == NULL)
754 return SHISHI_GCRYPT_ERROR;
755 if (gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0) != GCRYERR_SUCCESS)
756 return SHISHI_GCRYPT_ERROR;
757 if (gcry_control (GCRYCTL_INITIALIZATION_FINISHED,
758 NULL, 0) != GCRYERR_SUCCESS)
759 return SHISHI_GCRYPT_ERROR;
762 return SHISHI_OK;
766 * shishi_cipher_supported_p:
767 * @type: encryption type, see Shishi_etype.
769 * Return value: Return 0 iff cipher is unsupported.
772 shishi_cipher_supported_p (int type)
774 size_t i;
776 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
777 if (type == ciphers[i]->type)
778 return 1;
780 return 0;
784 * shishi_cipher_name:
785 * @type: encryption type, see Shishi_etype.
787 * Return value: Return name of encryption type,
788 * e.g. "des3-cbc-sha1-kd", as defined in the standards.
790 const char *
791 shishi_cipher_name (int type)
793 size_t i;
794 char *p;
796 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
798 if (type == ciphers[i]->type)
799 return ciphers[i]->name;
802 shishi_asprintf (&p, "unknown cipher %d", type);
803 return p;
807 * shishi_cipher_blocksize:
808 * @type: encryption type, see Shishi_etype.
810 * Return value: Return block size for encryption type, as defined in
811 * the standards.
814 shishi_cipher_blocksize (int type)
816 size_t i;
818 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
819 if (type == ciphers[i]->type)
820 return ciphers[i]->blocksize;
822 return -1;
826 * shishi_cipher_minpadsize:
827 * @type: encryption type, see Shishi_etype.
829 * Return value: Return the minimum pad size for encryption type, as
830 * defined in the standards.
833 shishi_cipher_minpadsize (int type)
835 size_t i;
837 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
838 if (type == ciphers[i]->type)
839 return ciphers[i]->minpadsize;
841 return -1;
845 * shishi_cipher_confoundersize:
846 * @type: encryption type, see Shishi_etype.
848 * Return value: Returns the size of the confounder (random data) for
849 * encryption type, as defined in the standards.
852 shishi_cipher_confoundersize (int type)
854 size_t i;
856 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
857 if (type == ciphers[i]->type)
858 return ciphers[i]->confoundersize;
860 return -1;
864 * shishi_cipher_keylen:
865 * @type: encryption type, see Shishi_etype.
867 * Return value: Return length of key used for the encryption type, as
868 * defined in the standards.
870 size_t
871 shishi_cipher_keylen (int type)
873 size_t i;
875 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
876 if (type == ciphers[i]->type)
877 return ciphers[i]->keylen;
879 return -1;
883 * shishi_cipher_randomlen:
884 * @type: encryption type, see Shishi_etype.
886 * Return value: Return length of random used for the encryption type,
887 * as defined in the standards.
889 size_t
890 shishi_cipher_randomlen (int type)
892 size_t i;
894 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
895 if (type == ciphers[i]->type)
896 return ciphers[i]->randomlen;
898 return -1;
902 * shishi_cipher_defaultcksumtype:
903 * @type: encryption type, see Shishi_etype.
905 * Return value: Return associated checksum mechanism for the
906 * encryption type, as defined in the standards.
909 shishi_cipher_defaultcksumtype (int type)
911 size_t i;
913 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
914 if (type == ciphers[i]->type)
915 return ciphers[i]->defaultcksumtype;
917 return -1;
921 * shishi_cipher_parse:
922 * @cipher: name of encryption type, e.g. "des3-cbc-sha1-kd".
924 * Return value: Return encryption type corresponding to a string.
927 shishi_cipher_parse (const char *cipher)
929 size_t i;
930 char *endptr;
932 i = strtol (cipher, &endptr, 0);
934 if (endptr != cipher)
935 return i;
937 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
938 if (strcasecmp (cipher, ciphers[i]->name) == 0)
939 return ciphers[i]->type;
941 return -1;
944 static Shishi_random_to_key_function
945 _shishi_cipher_random_to_key (int type)
947 size_t i;
949 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
950 if (type == ciphers[i]->type)
951 return ciphers[i]->random2key;
953 return NULL;
956 static Shishi_string_to_key_function
957 _shishi_cipher_string_to_key (int type)
959 size_t i;
961 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
962 if (type == ciphers[i]->type)
963 return ciphers[i]->string2key;
965 return NULL;
968 static Shishi_encrypt_function
969 _shishi_cipher_encrypt (int type)
971 size_t i;
973 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
974 if (type == ciphers[i]->type)
975 return ciphers[i]->encrypt;
977 return NULL;
980 static Shishi_decrypt_function
981 _shishi_cipher_decrypt (int type)
983 size_t i;
985 for (i = 0; i < sizeof (ciphers) / sizeof (ciphers[0]); i++)
986 if (type == ciphers[i]->type)
987 return ciphers[i]->decrypt;
989 return NULL;
993 * shishi_string_to_key:
994 * @handle: shishi handle as allocated by shishi_init().
995 * @keytype: cryptographic encryption type, see Shishi_etype.
996 * @password: input array with password.
997 * @passwordlen: length of input array with password.
998 * @salt: input array with salt.
999 * @saltlen: length of input array with salt.
1000 * @parameter: input array with opaque encryption type specific information.
1001 * @outkey: allocated key handle that will contain new key.
1003 * Derive key from a string (password) and salt (commonly
1004 * concatenation of realm and principal) for specified key type, and
1005 * set the type and value in the given key to the computed values.
1006 * The parameter value is specific for each keytype, and can be set if
1007 * the parameter information is not available.
1009 * Return value: Returns %SHISHI_OK iff successful.
1012 shishi_string_to_key (Shishi * handle,
1013 int keytype,
1014 const char *password,
1015 int passwordlen,
1016 const char *salt,
1017 int saltlen, const char *parameter, Shishi_key * outkey)
1019 Shishi_string_to_key_function string2key;
1020 int res;
1022 shishi_key_type_set (outkey, keytype);
1024 if (VERBOSECRYPTO (handle))
1026 printf ("string_to_key (%s, password, salt)\n",
1027 shishi_key_name (outkey));
1028 printf ("\t ;; password:\n");
1029 escapeprint (password, passwordlen);
1030 hexprint (password, passwordlen);
1031 puts ("");
1032 printf ("\t ;; salt:\n");
1033 escapeprint (salt, saltlen);
1034 hexprint (salt, saltlen);
1035 puts ("");
1038 string2key = _shishi_cipher_string_to_key (shishi_key_type (outkey));
1039 if (string2key == NULL)
1041 shishi_error_printf (handle, "Unsupported keytype %d",
1042 shishi_key_type (outkey));
1043 return !SHISHI_OK;
1046 res = (*string2key) (handle, password, passwordlen,
1047 salt, saltlen, parameter, outkey);
1049 if (VERBOSECRYPTO (handle))
1051 printf ("\t ;; string_to_key key:\n");
1052 hexprint (shishi_key_value (outkey), shishi_key_length (outkey));
1053 puts ("");
1054 binprint (shishi_key_value (outkey), shishi_key_length (outkey));
1055 puts ("");
1058 return res;
1062 * shishi_random_to_key:
1063 * @handle: shishi handle as allocated by shishi_init().
1064 * @keytype: cryptographic encryption type, see Shishi_etype.
1065 * @random: input array with random data.
1066 * @randomlen: length of input array with random data.
1067 * @outkey: allocated key handle that will contain new key.
1069 * Derive key from random data for specified key type, and set the
1070 * type and value in the given key to the computed values.
1072 * Return value: Returns %SHISHI_OK iff successful.
1075 shishi_random_to_key (Shishi * handle,
1076 int keytype,
1077 char *random, int randomlen, Shishi_key * outkey)
1079 Shishi_random_to_key_function random2key;
1080 int res;
1082 shishi_key_type_set (outkey, keytype);
1084 if (VERBOSECRYPTO (handle))
1086 printf ("random_to_key (%s, random)\n", shishi_key_name (outkey));
1087 printf ("\t ;; random:\n");
1088 hexprint (random, randomlen);
1089 puts ("");
1090 binprint (random, randomlen);
1091 puts ("");
1094 random2key = _shishi_cipher_random_to_key (keytype);
1095 if (random2key == NULL)
1097 shishi_error_printf (handle, "Unsupported random_to_key() ekeytype %d",
1098 keytype);
1099 return !SHISHI_OK;
1102 res = (*random2key) (handle, random, randomlen, outkey);
1104 if (VERBOSECRYPTO (handle))
1106 printf ("\t ;; random_to_key key:\n");
1107 hexprint (shishi_key_value (outkey), shishi_key_length (outkey));
1108 puts ("");
1109 binprint (shishi_key_value (outkey), shishi_key_length (outkey));
1110 puts ("");
1113 return res;
1117 * shishi_checksum:
1118 * @handle: shishi handle as allocated by shishi_init().
1119 * @key: key to encrypt with.
1120 * @keyusage: integer specifying what this key is encrypting.
1121 * @cksumtype: the checksum algorithm to use.
1122 * @in: input array with data to integrity protect.
1123 * @inlen: size of input array with data to integrity protect.
1124 * @out: output array with integrity protected data.
1125 * @outlen: on input, holds maximum size of output array, on output,
1126 * holds actual size of output array.
1128 * Integrity protect data using key, possibly altered by supplied key
1129 * usage. If key usage is 0, no key derivation is used.
1131 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1132 * used by the caller to allocate the proper buffer size.
1134 * Return value: Returns %SHISHI_OK iff successful.
1137 shishi_checksum (Shishi * handle,
1138 Shishi_key * key,
1139 int keyusage,
1140 int cksumtype, char *in, int inlen, char *out, int *outlen)
1142 int res;
1144 if (VERBOSECRYPTO (handle))
1146 printf ("checksum (%s, %d, in, out)\n",
1147 shishi_key_name (key), cksumtype);
1148 printf ("\t ;; key (%d):\n", shishi_key_length (key));
1149 hexprint (shishi_key_value (key), shishi_key_length (key));
1150 puts ("");
1151 printf ("\t ;; in:\n");
1152 escapeprint (in, inlen);
1153 hexprint (in, inlen);
1154 puts ("");
1157 if (cksumtype == 0)
1158 cksumtype = shishi_cipher_defaultcksumtype (shishi_key_type (key));
1160 /* XXX create a dispatcher instead of hardcoding this */
1162 switch (cksumtype)
1164 case SHISHI_RSA_MD4_DES:
1166 char buffer[BUFSIZ];
1167 int buflen;
1168 char *keyp;
1169 int i;
1171 buflen = sizeof (buffer);
1172 res = checksum_md4 (handle, buffer, &buflen, in, inlen);
1173 if (res != SHISHI_OK)
1175 shishi_error_set (handle, "checksum failed");
1176 return res;
1179 keyp = shishi_key_value (key);
1181 for (i = 0; i < 8; i++)
1182 keyp[i] ^= 0xF0;
1184 res = simplified_dencrypt (handle, key, NULL, 0, buffer, buflen,
1185 out, outlen, 0);
1187 for (i = 0; i < 8; i++)
1188 keyp[i] ^= 0xF0;
1190 if (res != SHISHI_OK)
1192 shishi_error_set (handle, "encrypt failed");
1193 return res;
1196 break;
1198 case SHISHI_RSA_MD5_DES:
1200 char buffer[BUFSIZ];
1201 int buflen;
1202 char *keyp;
1203 int i;
1205 buflen = sizeof (buffer);
1206 res = checksum_md5 (handle, buffer, &buflen, in, inlen);
1207 if (res != SHISHI_OK)
1209 shishi_error_set (handle, "checksum failed");
1210 return res;
1213 keyp = shishi_key_value (key);
1215 for (i = 0; i < 8; i++)
1216 keyp[i] ^= 0xF0;
1218 res = simplified_dencrypt (handle, key, NULL, 0, buffer, buflen,
1219 out, outlen, 0);
1221 for (i = 0; i < 8; i++)
1222 keyp[i] ^= 0xF0;
1224 if (res != SHISHI_OK)
1226 shishi_error_set (handle, "encrypt failed");
1227 return res;
1230 break;
1232 case SHISHI_HMAC_SHA1_DES3_KD:
1233 res =
1234 simplified_checksum (handle, key, keyusage, in, inlen, out, outlen);
1235 break;
1237 case SHISHI_HMAC_SHA1_96_AES128:
1238 res =
1239 simplified_checksum (handle, key, keyusage, in, inlen, out, outlen);
1240 *outlen = 96 / 8;
1241 break;
1243 case SHISHI_HMAC_SHA1_96_AES256:
1244 res =
1245 simplified_checksum (handle, key, keyusage, in, inlen, out, outlen);
1246 *outlen = 96 / 8;
1247 break;
1250 default:
1251 res = !SHISHI_OK;
1252 printf ("unimplemented checksum type!\n");
1253 break;
1256 if (VERBOSECRYPTO (handle))
1258 printf ("\t ;; checksum out:\n");
1259 escapeprint (out, *outlen);
1260 hexprint (out, *outlen);
1261 puts ("");
1264 return res;
1268 * shishi_encrypt_iv_etype:
1269 * @handle: shishi handle as allocated by shishi_init().
1270 * @key: key to encrypt with.
1271 * @keyusage: integer specifying what this key is encrypting.
1272 * @etype: integer specifying what decryption method to use.
1273 * @iv: input array with initialization vector.
1274 * @ivlen: size of input array with initialization vector.
1275 * @in: input array with data to encrypt.
1276 * @inlen: size of input array with data to encrypt.
1277 * @out: output array with encrypted data.
1278 * @outlen: on input, holds maximum size of output array, on output,
1279 * holds actual size of output array.
1281 * Encrypts data using key, possibly altered by supplied key usage.
1282 * If key usage is 0, no key derivation is used.
1284 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1285 * used by the caller to allocate the proper buffer size.
1287 * Return value: Returns %SHISHI_OK iff successful.
1290 shishi_encrypt_iv_etype (Shishi * handle,
1291 Shishi_key * key,
1292 int keyusage,
1293 int etype,
1294 char *iv, int ivlen,
1295 char *in, int inlen,
1296 char *out, int *outlen)
1298 Shishi_encrypt_function encrypt;
1299 int res;
1301 if (VERBOSECRYPTO (handle))
1303 printf ("encrypt (type=%s, usage=%d, key, in)\n",
1304 shishi_key_name (key), keyusage);
1305 printf ("\t ;; key (%d):\n", shishi_key_length (key));
1306 hexprint (shishi_key_value (key), shishi_key_length (key));
1307 puts ("");
1308 printf ("\t ;; in (%d):\n", inlen);
1309 escapeprint (in, inlen);
1310 hexprint (in, inlen);
1311 puts ("");
1314 encrypt = _shishi_cipher_encrypt (etype);
1315 if (encrypt == NULL)
1317 shishi_error_printf (handle, "Unsupported keytype %d",
1318 shishi_key_type (key));
1319 return !SHISHI_OK;
1322 res = (*encrypt) (handle, key, keyusage, iv, ivlen, in, inlen, out, outlen);
1324 if (VERBOSECRYPTO (handle))
1326 printf ("\t ;; encrypt out:\n");
1327 escapeprint (out, *outlen);
1328 hexprint (out, *outlen);
1329 puts ("");
1332 return res;
1336 * shishi_encrypt:
1337 * @handle: shishi handle as allocated by shishi_init().
1338 * @key: key to encrypt with.
1339 * @keyusage: integer specifying what this key is encrypting.
1340 * @in: input array with data to encrypt.
1341 * @inlen: size of input array with data to encrypt.
1342 * @out: output array with encrypted data.
1343 * @outlen: on input, holds maximum size of output array, on output,
1344 * holds actual size of output array.
1346 * Encrypts data using key, possibly altered by supplied key usage.
1347 * If key usage is 0, no key derivation is used.
1349 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1350 * used by the caller to allocate the proper buffer size.
1352 * Return value: Returns %SHISHI_OK iff successful.
1355 shishi_encrypt_iv (Shishi * handle,
1356 Shishi_key * key,
1357 int keyusage,
1358 char *iv, int ivlen,
1359 char *in, int inlen,
1360 char *out, int *outlen)
1362 return shishi_encrypt_iv_etype (handle, key, keyusage, shishi_key_type (key),
1363 NULL, 0, in, inlen, out, outlen);
1367 * shishi_encrypt:
1368 * @handle: shishi handle as allocated by shishi_init().
1369 * @key: key to encrypt with.
1370 * @keyusage: integer specifying what this key is encrypting.
1371 * @in: input array with data to encrypt.
1372 * @inlen: size of input array with data to encrypt.
1373 * @out: output array with encrypted data.
1374 * @outlen: on input, holds maximum size of output array, on output,
1375 * holds actual size of output array.
1377 * Encrypts data using key, possibly altered by supplied key usage.
1378 * If key usage is 0, no key derivation is used.
1380 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1381 * used by the caller to allocate the proper buffer size.
1383 * Return value: Returns %SHISHI_OK iff successful.
1386 shishi_encrypt (Shishi * handle,
1387 Shishi_key * key,
1388 int keyusage, char *in, int inlen, char *out, int *outlen)
1390 return shishi_encrypt_iv (handle, key, keyusage, NULL, 0,
1391 in, inlen, out, outlen);
1395 * shishi_decrypt_iv_etype:
1396 * @handle: shishi handle as allocated by shishi_init().
1397 * @key: key to decrypt with.
1398 * @keyusage: integer specifying what this key is decrypting.
1399 * @etype: integer specifying what decryption method to use.
1400 * @iv: input array with initialization vector.
1401 * @ivlen: size of input array with initialization vector.
1402 * @in: input array with data to decrypt.
1403 * @inlen: size of input array with data to decrypt.
1404 * @out: output array with decrypted data.
1405 * @outlen: on input, holds maximum size of output array, on output,
1406 * holds actual size of output array.
1408 * Decrypts data using key, possibly altered by supplied key usage.
1409 * If key usage is 0, no key derivation is used.
1411 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1412 * used by the caller to allocate the proper buffer size.
1414 * Return value: Returns %SHISHI_OK iff successful.
1417 shishi_decrypt_iv_etype (Shishi * handle,
1418 Shishi_key * key,
1419 int keyusage,
1420 int etype,
1421 char *iv, int ivlen,
1422 char *in, int inlen,
1423 char *out, int *outlen)
1425 Shishi_decrypt_function decrypt;
1426 int res;
1428 if (VERBOSECRYPTO (handle))
1430 printf ("decrypt (type=%s, usage=%d, key, in, out)\n",
1431 shishi_key_name (key), keyusage);
1432 printf ("\t ;; key (%d):\n", shishi_key_length (key));
1433 hexprint (shishi_key_value (key), shishi_key_length (key));
1434 puts ("");
1435 printf ("\t ;; in (%d):\n", inlen);
1436 escapeprint (in, inlen);
1437 hexprint (in, inlen);
1438 puts ("");
1441 decrypt = _shishi_cipher_decrypt (etype);
1442 if (decrypt == NULL)
1444 shishi_error_printf (handle, "Unsupported keytype %d",
1445 shishi_key_type (key));
1446 return !SHISHI_OK;
1449 res = (*decrypt) (handle, key, keyusage, iv, ivlen, in, inlen, out, outlen);
1451 if (VERBOSECRYPTO (handle))
1453 printf ("\t ;; decrypt out:\n");
1454 escapeprint (out, *outlen);
1455 hexprint (out, *outlen);
1456 puts ("");
1459 return res;
1463 * shishi_decrypt_iv:
1464 * @handle: shishi handle as allocated by shishi_init().
1465 * @key: key to decrypt with.
1466 * @keyusage: integer specifying what this key is decrypting.
1467 * @iv: input array with initialization vector.
1468 * @ivlen: size of input array with initialization vector.
1469 * @in: input array with data to decrypt.
1470 * @inlen: size of input array with data to decrypt.
1471 * @out: output array with decrypted data.
1472 * @outlen: on input, holds maximum size of output array, on output,
1473 * holds actual size of output array.
1475 * Decrypts data using key, possibly altered by supplied key usage.
1476 * If key usage is 0, no key derivation is used.
1478 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1479 * used by the caller to allocate the proper buffer size.
1481 * Return value: Returns %SHISHI_OK iff successful.
1484 shishi_decrypt_iv (Shishi * handle,
1485 Shishi_key * key,
1486 int keyusage,
1487 char *iv, int ivlen,
1488 char *in, int inlen,
1489 char *out, int *outlen)
1491 return shishi_decrypt_iv_etype (handle, key, keyusage,
1492 shishi_key_type (key),
1493 iv, ivlen,
1494 in, inlen,
1495 out, outlen);
1499 * shishi_decrypt:
1500 * @handle: shishi handle as allocated by shishi_init().
1501 * @key: key to decrypt with.
1502 * @keyusage: integer specifying what this key is decrypting.
1503 * @in: input array with data to decrypt.
1504 * @inlen: size of input array with data to decrypt.
1505 * @out: output array with decrypted data.
1506 * @outlen: on input, holds maximum size of output array, on output,
1507 * holds actual size of output array.
1509 * Decrypts data using key, possibly altered by supplied key usage.
1510 * If key usage is 0, no key derivation is used.
1512 * If OUT is NULL, this functions only set OUTLEN. This usage may be
1513 * used by the caller to allocate the proper buffer size.
1515 * Return value: Returns %SHISHI_OK iff successful.
1518 shishi_decrypt (Shishi * handle,
1519 Shishi_key * key,
1520 int keyusage, char *in, int inlen, char *out, int *outlen)
1522 return shishi_decrypt_iv (handle, key, keyusage, NULL, 0,
1523 in, inlen, out, outlen);
1527 * shishi_randomize:
1528 * @handle: shishi handle as allocated by shishi_init().
1529 * @data: output array to be filled with random data.
1530 * @datalen: size of output array.
1532 * Store cryptographically strong random data of given size in the
1533 * provided buffer.
1535 * Return value: Returns %SHISHI_OK iff successful.
1538 shishi_randomize (Shishi * handle, char *data, int datalen)
1540 char tmp[BUFSIZ];
1542 memcpy (data, tmp, datalen < BUFSIZ ? datalen : BUFSIZ);
1544 gcry_randomize (data, datalen, GCRY_STRONG_RANDOM);
1546 if (datalen > 0 &&
1547 memcmp (data, tmp, datalen < BUFSIZ ? datalen : BUFSIZ) == 0)
1549 shishi_error_set (handle, "No random data collected.");
1550 return SHISHI_GCRYPT_ERROR;
1553 return SHISHI_OK;
1557 * shishi_n_fold:
1558 * @handle: shishi handle as allocated by shishi_init().
1559 * @in: input array with data to decrypt.
1560 * @inlen: size of input array with data to decrypt ("M").
1561 * @out: output array with decrypted data.
1562 * @outlen: size of output array ("N").
1564 * Fold data into a fixed length output array, with the intent to give
1565 * each input bit approximately equal weight in determining the value
1566 * of each output bit.
1568 * The algorithm is from "A Better Key Schedule For DES-like Ciphers"
1569 * by Uri Blumenthal and Steven M. Bellovin,
1570 * <URL:http://www.research.att.com/~smb/papers/ides.pdf>, although
1571 * the sample vectors provided by the paper are incorrect.
1573 * Return value: Returns %SHISHI_OK iff successful.
1576 shishi_n_fold (Shishi * handle, char *in, int inlen, char *out, int outlen)
1578 int m = inlen;
1579 int n = outlen;
1580 char *buf = NULL;
1581 char *a = NULL;
1582 int lcmmn = 0;
1583 int i = 0;
1586 To n-fold a number X, replicate the input value to a length that is
1587 the least common multiple of n and the length of X. Before each
1588 repetition, the input is rotated to the right by 13 bit
1589 positions. The successive n-bit chunks are added together using
1590 1's-complement addition (that is, addition with end-around carry)
1591 to yield a n-bit result denoted <X>_n.
1594 a = (char *) malloc (m);
1595 if (a == NULL)
1596 return SHISHI_MALLOC_ERROR;
1597 memcpy (a, in, m);
1599 lcmmn = lcm (m, n);
1601 if (VERBOSECRYPTO (handle))
1603 printf ("%d-fold (string)\n", n * 8);
1604 printf ("\t ;; string length %d bytes %d bits\n", m, m * 8);
1605 escapeprint (a, m);
1606 hexprint (a, m);
1607 puts ("");
1608 printf ("\t ;; lcm(%d, %d) = lcm(%d, %d) = %d\n",
1609 8 * m, 8 * n, m, n, lcmmn);
1610 puts ("");
1613 buf = (char *) malloc (lcmmn);
1614 if (buf == NULL)
1615 return SHISHI_MALLOC_ERROR;
1617 /* Replicate the input th the LCMMN length */
1618 for (i = 0; i < (lcmmn / m); i++)
1620 if (VERBOSECRYPTO (handle))
1622 printf ("\t ;; %d-th replication\n", i + 1);
1623 printf ("string = rot13(string)\n");
1626 memcpy ((char *) &buf[i * m], a, m);
1627 rot13 (handle, a, a, m);
1629 if (VERBOSECRYPTO (handle))
1630 puts ("");
1633 memset (out, 0, n); /* just in case */
1635 if (VERBOSECRYPTO (handle))
1637 printf ("\t ;; replicated string (length %d):\n", lcmmn);
1638 hexprint (buf, lcmmn);
1639 puts ("");
1640 binprint (buf, lcmmn);
1641 puts ("");
1642 printf ("sum = 0\n");
1645 /* Now we view the buf as set of n-byte strings
1646 Add the n-byte long chunks together, using
1647 one's complement addition, storing the
1648 result in the output string. */
1650 for (i = 0; i < (lcmmn / n); i++)
1652 if (VERBOSECRYPTO (handle))
1654 printf ("\t ;; %d-th one's complement addition sum\n", i + 1);
1655 printf ("\t ;; sum:\n");
1656 hexprint (out, n);
1657 puts ("");
1658 binprint (out, n);
1659 puts ("");
1660 printf ("\t ;; A (offset %d):\n", i * n);
1661 hexprint (&buf[i * n], n);
1662 puts ("");
1663 binprint (&buf[i * n], n);
1664 puts ("");
1665 printf ("sum = ocadd(sum, A);\n");
1668 ocadd (out, (char *) &buf[i * n], out, n);
1670 if (VERBOSECRYPTO (handle))
1672 printf ("\t ;; sum:\n");
1673 hexprint (out, n);
1674 puts ("");
1675 binprint (out, n);
1676 puts ("");
1677 puts ("");
1681 if (VERBOSECRYPTO (handle))
1683 printf ("\t ;; nfold\n");
1684 hexprint (out, n);
1685 puts ("");
1686 binprint (out, n);
1687 puts ("");
1688 puts ("");
1691 free (buf);
1692 free (a);
1694 return SHISHI_OK;
1697 #define MAX_DR_CONSTANT 1024
1700 * shishi_dr:
1701 * @handle: shishi handle as allocated by shishi_init().
1702 * @etype: cryptographic encryption type, see Shishi_etype.
1703 * @key: input array with cryptographic key to use.
1704 * @keylen: size of input array with cryptographic key.
1705 * @constant: input array with the constant string.
1706 * @constantlen: size of input array with the constant string.
1707 * @derivedrandom: output array with derived random data.
1708 * @derivedrandomlen: size of output array with derived random data.
1710 * Derive "random" data from a key and a constant thusly:
1711 * DR(KEY, CONSTANT) = TRUNCATE(DERIVEDRANDOMLEN,
1712 * SHISHI_ENCRYPT(KEY, CONSTANT)).
1714 * Return value: Returns %SHISHI_OK iff successful.
1717 shishi_dr (Shishi * handle,
1718 Shishi_key * key,
1719 char *constant,
1720 int constantlen, char *derivedrandom, int derivedrandomlen)
1722 char cipher[MAX_DR_CONSTANT];
1723 char plaintext[MAX_DR_CONSTANT];
1724 char nfoldconstant[MAX_DR_CONSTANT];
1725 int blocksize = shishi_cipher_blocksize (shishi_key_type (key));
1726 int totlen, cipherlen;
1727 int res;
1729 if (VERBOSECRYPTO (handle))
1731 printf ("dr (%s, key, constant, %d)\n",
1732 shishi_cipher_name (shishi_key_type (key)), derivedrandomlen);
1733 printf ("\t ;; key (length %d):\n", shishi_key_type (key));
1734 hexprint (shishi_key_value (key), shishi_key_type (key));
1735 puts ("");
1736 binprint (shishi_key_value (key), shishi_key_type (key));
1737 puts ("");
1738 printf ("\t ;; constant %s':\n", constant);
1739 escapeprint (constant, constantlen);
1740 hexprint (constant, constantlen);
1741 puts ("");
1742 binprint (constant, constantlen);
1743 puts ("");
1744 puts ("");
1747 if (constantlen > MAX_DR_CONSTANT)
1748 return !SHISHI_OK;
1750 if (constantlen == blocksize)
1752 memcpy (nfoldconstant, constant, constantlen);
1754 else
1756 res = shishi_n_fold (handle, constant, constantlen, nfoldconstant,
1757 blocksize);
1758 if (res != SHISHI_OK)
1759 return res;
1762 if (VERBOSECRYPTO (handle))
1764 printf ("\t ;; possibly nfolded constant (length %d):\n", blocksize);
1765 escapeprint (nfoldconstant, blocksize);
1766 hexprint (nfoldconstant, blocksize);
1767 puts ("");
1768 binprint (nfoldconstant, blocksize);
1769 puts ("");
1772 memcpy (plaintext, nfoldconstant, blocksize);
1774 totlen = 0;
1777 cipherlen = sizeof (cipher);
1778 res = shishi_encrypt (handle, key, 0, plaintext, blocksize,
1779 cipher, &cipherlen);
1780 if (res != SHISHI_OK)
1781 return res;
1782 memcpy (derivedrandom + totlen, cipher, cipherlen);
1783 memcpy (plaintext, cipher, cipherlen);
1784 totlen += cipherlen;
1786 while (totlen < derivedrandomlen);
1788 if (VERBOSECRYPTO (handle))
1790 printf ("\t ;; derived random (length %d):\n", derivedrandomlen);
1791 hexprint (derivedrandom, derivedrandomlen);
1792 puts ("");
1793 binprint (derivedrandom, derivedrandomlen);
1794 puts ("");
1797 return SHISHI_OK;
1801 * shishi_dk:
1802 * @handle: shishi handle as allocated by shishi_init().
1803 * @etype: cryptographic encryption type, see Shishi_etype.
1804 * @key: input array with cryptographic key to use.
1805 * @keylen: size of input array with cryptographic key.
1806 * @constant: input array with the constant string.
1807 * @constantlen: size of input array with the constant string.
1808 * @derivedkey: output array with derived key.
1809 * @derivedkeylen: size of output array with derived key.
1811 * Derive a key from a key and a constant thusly:
1812 * DK(KEY, CONSTANT) = SHISHI_RANDOM-TO-KEY(SHISHI_DR(KEY, CONSTANT)).
1814 * Return value: Returns %SHISHI_OK iff successful.
1817 shishi_dk (Shishi * handle,
1818 Shishi_key * key,
1819 char *constant, int constantlen, Shishi_key * derivedkey)
1821 char random[MAX_RANDOM_LEN];
1822 int res;
1824 if (VERBOSECRYPTO (handle))
1826 printf ("dk (%s, key, constant)\n", shishi_key_name (key));
1827 printf ("\t ;; key (length %d):\n", shishi_key_length (key));
1828 hexprint (shishi_key_value (key), shishi_key_length (key));
1829 puts ("");
1830 binprint (shishi_key_value (key), shishi_key_length (key));
1831 puts ("");
1832 printf ("\t ;; constant:\n");
1833 escapeprint (constant, constantlen);
1834 hexprint (constant, constantlen);
1835 puts ("");
1836 binprint (constant, constantlen);
1837 puts ("");
1838 puts ("");
1841 shishi_key_type_set (derivedkey, shishi_key_type (key));
1843 res = shishi_dr (handle, key, constant, constantlen, random,
1844 shishi_key_length (derivedkey));
1845 if (res != SHISHI_OK)
1846 return res;
1848 res = shishi_random_to_key (handle, shishi_key_type (derivedkey),
1849 random, shishi_key_length (derivedkey),
1850 derivedkey);
1851 if (res != SHISHI_OK)
1852 return res;
1854 return SHISHI_OK;