Add.
[shishi.git] / lib / crypto-rc4.c
blob5aae2ca56b6bec17c62bc12d38957ece872ccf4e
1 /* crypto-rc4.c --- draft-brezak-win2k-krb-rc4-hmac-04 crypto functions.
2 * Copyright (C) 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "internal.h"
24 /* Get prototypes. */
25 #include "crypto.h"
27 /* Get _shishi_escapeprint, etc. */
28 #include "utils.h"
30 static int
31 arcfour_keyusage (int keyusage)
33 /* From draft-brezak-win2k-krb-rc4-hmac-04.txt:
35 * 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with
36 * the client key (T=1)
37 * 2. AS-REP Ticket and TGS-REP Ticket (includes TGS session key
38 * or application session key), encrypted with the service key
39 * (T=2)
40 * 3. AS-REP encrypted part (includes TGS session key or
41 * application session key), encrypted with the client key (T=8)
42 * 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
43 * TGS session key (T=4)
44 * 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
45 * TGS authenticator subkey (T=5)
46 * 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
47 * with the TGS session key (T=6)
48 * 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
49 * TGS authenticator subkey), encrypted with the TGS session key
50 * (T=7)
51 * 8. TGS-REP encrypted part (includes application session key),
52 * encrypted with the TGS session key (T=8)
53 * 9. TGS-REP encrypted part (includes application session key),
54 * encrypted with the TGS authenticator subkey (T=8)
55 * 10. AP-REQ Authenticator cksum, keyed with the application
56 * session key (T=10)
57 * 11. AP-REQ Authenticator (includes application authenticator
58 * subkey), encrypted with the application session key (T=11)
59 * 12. AP-REP encrypted part (includes application session
60 * subkey), encrypted with the application session key (T=12)
61 * 13. KRB-PRIV encrypted part, encrypted with a key chosen by
62 * the application. Also for data encrypted with GSS Wrap (T=13)
63 * 14. KRB-CRED encrypted part, encrypted with a key chosen by
64 * the application (T=14)
65 * 15. KRB-SAFE cksum, keyed with a key chosen by the
66 * application. Also for data signed in GSS MIC (T=15)
69 if (keyusage == SHISHI_KEYUSAGE_ENCASREPPART)
70 return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
71 else if (keyusage == SHISHI_KEYUSAGE_ENCTGSREPPART_AUTHENTICATOR_KEY)
72 return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
74 /* Continued, this probably refer to the non-standard 3DES GSSAPI
75 * keyusages; RFC 1964 does not discuss key uses at all. When this
76 * comment was written, GSSLib did not support ARCFOUR though.
78 * Relative to RFC-1964 key uses:
80 * T = 0 in the generation of sequence number for the MIC token
81 * T = 0 in the generation of sequence number for the WRAP token
82 * T = 0 in the generation of encrypted data for the WRAPPED token
86 if (keyusage == SHISHI_KEYUSAGE_GSS_R1 ||
87 keyusage == SHISHI_KEYUSAGE_GSS_R2 ||
88 keyusage == SHISHI_KEYUSAGE_GSS_R3)
89 return 0;
91 return keyusage;
94 static int
95 arcfour_hmac_encrypt (Shishi * handle,
96 Shishi_key * key,
97 int keyusage,
98 const char *iv,
99 size_t ivlen,
100 char **ivout, size_t * ivoutlen,
101 const char *in, size_t inlen, char **out,
102 size_t * outlen)
104 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
105 int arcfourkeyusage = arcfour_keyusage (keyusage);
106 char L40[14] = "fortybits";
107 uint8_t T[4];
108 char *K1 = NULL;
109 char K2[16];
110 char *K3 = NULL;
111 char *pt = NULL;
112 size_t ptlen;
113 char *ct = NULL;
114 char *cksum = NULL;
115 int offset;
116 int err;
118 T[0] = arcfourkeyusage & 0xFF;
119 T[1] = (arcfourkeyusage >> 8) & 0xFF;
120 T[2] = (arcfourkeyusage >> 16) & 0xFF;
121 T[3] = (arcfourkeyusage >> 24) & 0xFF;
123 memcpy (L40 + 10, T, 4);
125 if (export)
126 offset = 0;
127 else
128 offset = 10;
130 if (VERBOSECRYPTONOISE (handle))
132 puts ("k1pt");
133 _shishi_hexprint (L40 + offset, 14 - offset);
136 err = shishi_hmac_md5 (handle,
137 shishi_key_value (key), shishi_key_length (key),
138 L40 + offset, 14 - offset, &K1);
139 if (err)
140 goto done;
142 if (VERBOSECRYPTONOISE (handle))
144 puts ("k1");
145 _shishi_hexprint (K1, 16);
148 memcpy (K2, K1, 16);
149 if (export)
150 memset (K1 + 7, 0xAB, 9);
152 if (VERBOSECRYPTONOISE (handle))
154 puts ("k1");
155 _shishi_hexprint (K1, 16);
156 puts ("k2");
157 _shishi_hexprint (K2, 16);
160 /* Note that in ENCRYPT of draft-brezak-win2k-krb-rc4-hmac-04.txt change:
162 * edata.Checksum = HMAC (K2, edata);
164 * into
166 * edata.Checksum = HMAC (K2, concat(edata.Confounder, edata.Data));
168 * otherwise it will not work. Compare DECRYPT where the later is
169 * taken from. Another interpretation would be to HMAC a zeroized
170 * checksum field, like certain other cipher suites do, but that
171 * does not interoperate.
175 ptlen = 8 + inlen;
176 pt = xmalloc (ptlen);
178 err = shishi_randomize (handle, 0, pt, 8);
179 if (err)
180 goto done;
181 memcpy (pt + 8, in, inlen);
183 if (VERBOSECRYPTONOISE (handle))
185 puts ("random");
186 _shishi_hexprint (pt, 8);
189 err = shishi_hmac_md5 (handle, K2, 16, pt, ptlen, &cksum);
190 if (err)
191 goto done;
193 if (VERBOSECRYPTONOISE (handle))
195 puts ("cksum");
196 _shishi_hexprint (cksum, 16);
199 err = shishi_hmac_md5 (handle, K1, 16, cksum, 16, &K3);
200 if (err)
201 goto done;
203 if (VERBOSECRYPTONOISE (handle))
205 puts ("k3");
206 _shishi_hexprint (K3, 16);
209 err = shishi_arcfour (handle, 0, K3, 16, iv, ivout, pt, ptlen, &ct);
210 if (err)
211 goto done;
213 if (VERBOSECRYPTONOISE (handle))
215 puts ("ct");
216 _shishi_hexprint (ct, ptlen);
219 *outlen = 16 + ptlen;
220 *out = xmalloc (*outlen);
221 memcpy (*out, cksum, 16);
222 memcpy (*out + 16, ct, ptlen);
224 if (ivoutlen)
225 /* size = sbox[256] + int8_t i + int8_t j */
226 *ivoutlen = 256 + 2 * 8;
228 err = SHISHI_OK;
230 done:
231 free (cksum);
232 free (K3);
233 free (pt);
234 free (ct);
235 free (K1);
236 return err;
239 static int
240 arcfour_hmac_decrypt (Shishi * handle,
241 Shishi_key * key,
242 int keyusage,
243 const char *iv,
244 size_t ivlen,
245 char **ivout, size_t * ivoutlen,
246 const char *in, size_t inlen, char **out,
247 size_t * outlen)
249 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
250 int arcfourkeyusage = arcfour_keyusage (keyusage);
251 char L40[14] = "fortybits";
252 uint8_t T[4];
253 char *K1 = NULL;
254 char K2[16];
255 char *K3 = NULL;
256 char *cksum = NULL;
257 char *pt = NULL;
258 int offset;
259 int err;
261 T[0] = arcfourkeyusage & 0xFF;
262 T[1] = (arcfourkeyusage >> 8) & 0xFF;
263 T[2] = (arcfourkeyusage >> 16) & 0xFF;
264 T[3] = (arcfourkeyusage >> 24) & 0xFF;
266 memcpy (L40 + 10, T, 4);
268 if (export)
269 offset = 0;
270 else
271 offset = 10;
273 if (VERBOSECRYPTONOISE (handle))
275 puts ("k1pt");
276 _shishi_hexprint (L40 + offset, 14 - offset);
279 err = shishi_hmac_md5 (handle,
280 shishi_key_value (key), shishi_key_length (key),
281 L40 + offset, 14 - offset, &K1);
282 if (err)
283 goto done;
285 if (VERBOSECRYPTONOISE (handle))
287 puts ("k1");
288 _shishi_hexprint (K1, 16);
291 memcpy (K2, K1, 16);
292 if (export)
293 memset (K1 + 7, 0xAB, 9);
295 if (VERBOSECRYPTONOISE (handle))
297 puts ("k1");
298 _shishi_hexprint (K1, 16);
299 puts ("k2");
300 _shishi_hexprint (K2, 16);
303 err = shishi_hmac_md5 (handle, K1, 16, in, 16, &K3);
304 if (err)
305 goto done;
307 if (VERBOSECRYPTONOISE (handle))
309 puts ("k3");
310 _shishi_hexprint (K3, 16);
313 err =
314 shishi_arcfour (handle, 1, K3, 16, iv, ivout, in + 16, inlen - 16, &pt);
315 if (err)
316 goto done;
318 if (VERBOSECRYPTONOISE (handle))
320 puts ("cksum pt");
321 _shishi_hexprint (pt, inlen - 16);
324 err = shishi_hmac_md5 (handle, K2, 16, pt, inlen - 16, &cksum);
325 if (err)
326 goto done;
328 if (VERBOSECRYPTONOISE (handle))
330 puts ("cksum");
331 _shishi_hexprint (cksum, 16);
332 puts ("cksumin");
333 _shishi_hexprint (in, 16);
336 if (memcmp (cksum, in, 16) != 0)
338 err = SHISHI_CRYPTO_ERROR;
339 goto done;
342 *outlen = inlen - 16 - 8;
343 *out = xmalloc (*outlen);
344 memcpy (*out, pt + 8, inlen - 16 - 8);
346 if (ivoutlen)
347 /* size = sbox[256] + int8_t i + int8_t j */
348 *ivoutlen = 256 + 2 * 8;
350 err = SHISHI_OK;
352 done:
353 free (cksum);
354 free (K3);
355 free (K1);
356 free (pt);
357 return err;
360 static int
361 arcfour_hmac_exp_encrypt (Shishi * handle,
362 Shishi_key * key,
363 int keyusage,
364 const char *iv,
365 size_t ivlen,
366 char **ivout, size_t * ivoutlen,
367 const char *in, size_t inlen,
368 char **out, size_t * outlen)
370 return arcfour_hmac_encrypt (handle, key, keyusage, iv, ivlen,
371 ivout, ivoutlen, in, inlen, out, outlen);
375 static int
376 arcfour_hmac_exp_decrypt (Shishi * handle,
377 Shishi_key * key,
378 int keyusage,
379 const char *iv,
380 size_t ivlen,
381 char **ivout, size_t * ivoutlen,
382 const char *in, size_t inlen,
383 char **out, size_t * outlen)
385 return arcfour_hmac_decrypt (handle, key, keyusage, iv, ivlen,
386 ivout, ivoutlen, in, inlen, out, outlen);
389 #define ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT "signaturekey"
391 static int
392 arcfour_hmac_md5_checksum (Shishi * handle,
393 Shishi_key * key,
394 int keyusage,
395 int cksumtype,
396 const char *in, size_t inlen,
397 char **out, size_t * outlen)
399 int arcfourkeyusage = arcfour_keyusage (keyusage);
400 char *Ksign = NULL;
401 char *pt = NULL;
402 size_t ptlen;
403 char *tmp = NULL;
404 char T[4];
405 int err;
407 T[0] = arcfourkeyusage & 0xFF;
408 T[1] = (arcfourkeyusage >> 8) & 0xFF;
409 T[2] = (arcfourkeyusage >> 16) & 0xFF;
410 T[3] = (arcfourkeyusage >> 24) & 0xFF;
412 err = shishi_hmac_md5 (handle,
413 shishi_key_value (key), shishi_key_length (key),
414 ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT,
415 strlen (ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT) + 1,
416 &Ksign);
417 if (err)
418 goto done;
420 if (VERBOSECRYPTONOISE (handle))
422 puts ("Ksign");
423 _shishi_hexprint (Ksign, 16);
426 ptlen = 4 + inlen;
427 pt = xmalloc (ptlen);
428 memcpy (pt, T, 4);
429 memcpy (pt + 4, in, inlen);
431 if (VERBOSECRYPTONOISE (handle))
433 puts ("pt");
434 _shishi_hexprint (pt, ptlen);
437 err = shishi_md5 (handle, pt, ptlen, &tmp);
438 if (err)
439 goto done;
441 if (VERBOSECRYPTONOISE (handle))
443 puts ("md");
444 _shishi_hexprint (tmp, 16);
447 *outlen = 16;
448 err = shishi_hmac_md5 (handle, Ksign, 16, tmp, 16, out);
449 if (err)
450 goto done;
452 if (VERBOSECRYPTONOISE (handle))
454 puts ("hmac");
455 _shishi_hexprint (*out, 16);
458 err = SHISHI_OK;
460 done:
461 free (Ksign);
462 free (pt);
463 free (tmp);
464 return err;
467 static int
468 arcfour_hmac_random_to_key (Shishi * handle,
469 const char *rnd, size_t rndlen,
470 Shishi_key * outkey)
472 if (rndlen != shishi_key_length (outkey))
474 shishi_error_printf (handle, "ARCFOUR random to key caller error");
475 return SHISHI_CRYPTO_ERROR;
478 shishi_key_value_set (outkey, rnd);
480 return SHISHI_OK;
483 static int
484 arcfour_hmac_string_to_key (Shishi * handle,
485 const char *string,
486 size_t stringlen,
487 const char *salt,
488 size_t saltlen,
489 const char *parameter, Shishi_key * outkey)
491 char *tmp, *md;
492 size_t tmplen, i;
493 int rc;
495 tmplen = 2 * stringlen;
496 tmp = xmalloc (tmplen);
498 for (i = 0; i < stringlen; i++)
500 tmp[2 * i] = string[i];
501 tmp[2 * i + 1] = '\x0';
504 rc = shishi_md4 (handle, tmp, tmplen, &md);
505 free (tmp);
506 if (rc != SHISHI_OK)
507 return rc;
509 shishi_key_value_set (outkey, md);
511 free (md);
513 return SHISHI_OK;
516 cipherinfo arcfour_hmac_info = {
517 SHISHI_ARCFOUR_HMAC,
518 "arcfour-hmac",
523 SHISHI_ARCFOUR_HMAC_MD5,
524 arcfour_hmac_random_to_key,
525 arcfour_hmac_string_to_key,
526 arcfour_hmac_encrypt,
527 arcfour_hmac_decrypt
530 cipherinfo arcfour_hmac_exp_info = {
531 SHISHI_ARCFOUR_HMAC_EXP,
532 "arcfour-hmac-exp",
537 SHISHI_ARCFOUR_HMAC_MD5,
538 arcfour_hmac_random_to_key,
539 arcfour_hmac_string_to_key,
540 arcfour_hmac_exp_encrypt,
541 arcfour_hmac_exp_decrypt
544 checksuminfo arcfour_hmac_md5_info = {
545 SHISHI_ARCFOUR_HMAC_MD5,
546 "arcfour-hmac-md5",
548 arcfour_hmac_md5_checksum