Add.
[shishi.git] / lib / crypto-rc4.c
blob5ecc711abfc81b2a14a4c515bec750cdeff7b8c2
1 /* crypto-rc4.c --- draft-brezak-win2k-krb-rc4-hmac-04 crypto functions.
2 * Copyright (C) 2003, 2004, 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"
25 /* Get prototypes. */
26 #include "crypto.h"
28 /* Get _shishi_escapeprint, etc. */
29 #include "utils.h"
31 static int
32 arcfour_keyusage (int keyusage)
34 /* From draft-brezak-win2k-krb-rc4-hmac-04.txt:
36 * 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with
37 * the client key (T=1)
38 * 2. AS-REP Ticket and TGS-REP Ticket (includes TGS session key
39 * or application session key), encrypted with the service key
40 * (T=2)
41 * 3. AS-REP encrypted part (includes TGS session key or
42 * application session key), encrypted with the client key (T=8)
43 * 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
44 * TGS session key (T=4)
45 * 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
46 * TGS authenticator subkey (T=5)
47 * 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
48 * with the TGS session key (T=6)
49 * 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
50 * TGS authenticator subkey), encrypted with the TGS session key
51 * (T=7)
52 * 8. TGS-REP encrypted part (includes application session key),
53 * encrypted with the TGS session key (T=8)
54 * 9. TGS-REP encrypted part (includes application session key),
55 * encrypted with the TGS authenticator subkey (T=8)
56 * 10. AP-REQ Authenticator cksum, keyed with the application
57 * session key (T=10)
58 * 11. AP-REQ Authenticator (includes application authenticator
59 * subkey), encrypted with the application session key (T=11)
60 * 12. AP-REP encrypted part (includes application session
61 * subkey), encrypted with the application session key (T=12)
62 * 13. KRB-PRIV encrypted part, encrypted with a key chosen by
63 * the application. Also for data encrypted with GSS Wrap (T=13)
64 * 14. KRB-CRED encrypted part, encrypted with a key chosen by
65 * the application (T=14)
66 * 15. KRB-SAFE cksum, keyed with a key chosen by the
67 * application. Also for data signed in GSS MIC (T=15)
70 if (keyusage == SHISHI_KEYUSAGE_ENCASREPPART)
71 return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
72 else if (keyusage == SHISHI_KEYUSAGE_ENCTGSREPPART_AUTHENTICATOR_KEY)
73 return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
75 /* Continued, this probably refer to the non-standard 3DES GSSAPI
76 * keyusages; RFC 1964 does not discuss key uses at all. When this
77 * comment was written, GSSLib did not support ARCFOUR though.
79 * Relative to RFC-1964 key uses:
81 * T = 0 in the generation of sequence number for the MIC token
82 * T = 0 in the generation of sequence number for the WRAP token
83 * T = 0 in the generation of encrypted data for the WRAPPED token
87 if (keyusage == SHISHI_KEYUSAGE_GSS_R1 ||
88 keyusage == SHISHI_KEYUSAGE_GSS_R2 ||
89 keyusage == SHISHI_KEYUSAGE_GSS_R3)
90 return 0;
92 return keyusage;
95 static int
96 arcfour_hmac_encrypt (Shishi * handle,
97 Shishi_key * key,
98 int keyusage,
99 const char *iv,
100 size_t ivlen,
101 char **ivout, size_t * ivoutlen,
102 const char *in, size_t inlen, char **out,
103 size_t * outlen)
105 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
106 int arcfourkeyusage = arcfour_keyusage (keyusage);
107 char L40[14] = "fortybits";
108 uint8_t T[4];
109 char *K1 = NULL;
110 char K2[16];
111 char *K3 = NULL;
112 char *pt = NULL;
113 size_t ptlen;
114 char *ct = NULL;
115 char *cksum = NULL;
116 int offset;
117 int err;
119 T[0] = arcfourkeyusage & 0xFF;
120 T[1] = (arcfourkeyusage >> 8) & 0xFF;
121 T[2] = (arcfourkeyusage >> 16) & 0xFF;
122 T[3] = (arcfourkeyusage >> 24) & 0xFF;
124 memcpy (L40 + 10, T, 4);
126 if (export)
127 offset = 0;
128 else
129 offset = 10;
131 if (VERBOSECRYPTONOISE (handle))
133 puts ("k1pt");
134 _shishi_hexprint (L40 + offset, 14 - offset);
137 err = shishi_hmac_md5 (handle,
138 shishi_key_value (key), shishi_key_length (key),
139 L40 + offset, 14 - offset, &K1);
140 if (err)
141 goto done;
143 if (VERBOSECRYPTONOISE (handle))
145 puts ("k1");
146 _shishi_hexprint (K1, 16);
149 memcpy (K2, K1, 16);
150 if (export)
151 memset (K1 + 7, 0xAB, 9);
153 if (VERBOSECRYPTONOISE (handle))
155 puts ("k1");
156 _shishi_hexprint (K1, 16);
157 puts ("k2");
158 _shishi_hexprint (K2, 16);
161 /* Note that in ENCRYPT of draft-brezak-win2k-krb-rc4-hmac-04.txt change:
163 * edata.Checksum = HMAC (K2, edata);
165 * into
167 * edata.Checksum = HMAC (K2, concat(edata.Confounder, edata.Data));
169 * otherwise it will not work. Compare DECRYPT where the later is
170 * taken from. Another interpretation would be to HMAC a zeroized
171 * checksum field, like certain other cipher suites do, but that
172 * does not interoperate.
176 ptlen = 8 + inlen;
177 pt = xmalloc (ptlen);
179 err = shishi_randomize (handle, 0, pt, 8);
180 if (err)
181 goto done;
182 memcpy (pt + 8, in, inlen);
184 if (VERBOSECRYPTONOISE (handle))
186 puts ("random");
187 _shishi_hexprint (pt, 8);
190 err = shishi_hmac_md5 (handle, K2, 16, pt, ptlen, &cksum);
191 if (err)
192 goto done;
194 if (VERBOSECRYPTONOISE (handle))
196 puts ("cksum");
197 _shishi_hexprint (cksum, 16);
200 err = shishi_hmac_md5 (handle, K1, 16, cksum, 16, &K3);
201 if (err)
202 goto done;
204 if (VERBOSECRYPTONOISE (handle))
206 puts ("k3");
207 _shishi_hexprint (K3, 16);
210 err = shishi_arcfour (handle, 0, K3, 16, iv, ivout, pt, ptlen, &ct);
211 if (err)
212 goto done;
214 if (VERBOSECRYPTONOISE (handle))
216 puts ("ct");
217 _shishi_hexprint (ct, ptlen);
220 *outlen = 16 + ptlen;
221 *out = xmalloc (*outlen);
222 memcpy (*out, cksum, 16);
223 memcpy (*out + 16, ct, ptlen);
225 if (ivoutlen)
226 /* size = sbox[256] + int8_t i + int8_t j */
227 *ivoutlen = 256 + 2 * 8;
229 err = SHISHI_OK;
231 done:
232 free (cksum);
233 free (K3);
234 free (pt);
235 free (ct);
236 free (K1);
237 return err;
240 static int
241 arcfour_hmac_decrypt (Shishi * handle,
242 Shishi_key * key,
243 int keyusage,
244 const char *iv,
245 size_t ivlen,
246 char **ivout, size_t * ivoutlen,
247 const char *in, size_t inlen, char **out,
248 size_t * outlen)
250 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
251 int arcfourkeyusage = arcfour_keyusage (keyusage);
252 char L40[14] = "fortybits";
253 uint8_t T[4];
254 char *K1 = NULL;
255 char K2[16];
256 char *K3 = NULL;
257 char *cksum = NULL;
258 char *pt = NULL;
259 int offset;
260 int err;
262 T[0] = arcfourkeyusage & 0xFF;
263 T[1] = (arcfourkeyusage >> 8) & 0xFF;
264 T[2] = (arcfourkeyusage >> 16) & 0xFF;
265 T[3] = (arcfourkeyusage >> 24) & 0xFF;
267 memcpy (L40 + 10, T, 4);
269 if (export)
270 offset = 0;
271 else
272 offset = 10;
274 if (VERBOSECRYPTONOISE (handle))
276 puts ("k1pt");
277 _shishi_hexprint (L40 + offset, 14 - offset);
280 err = shishi_hmac_md5 (handle,
281 shishi_key_value (key), shishi_key_length (key),
282 L40 + offset, 14 - offset, &K1);
283 if (err)
284 goto done;
286 if (VERBOSECRYPTONOISE (handle))
288 puts ("k1");
289 _shishi_hexprint (K1, 16);
292 memcpy (K2, K1, 16);
293 if (export)
294 memset (K1 + 7, 0xAB, 9);
296 if (VERBOSECRYPTONOISE (handle))
298 puts ("k1");
299 _shishi_hexprint (K1, 16);
300 puts ("k2");
301 _shishi_hexprint (K2, 16);
304 err = shishi_hmac_md5 (handle, K1, 16, in, 16, &K3);
305 if (err)
306 goto done;
308 if (VERBOSECRYPTONOISE (handle))
310 puts ("k3");
311 _shishi_hexprint (K3, 16);
314 err =
315 shishi_arcfour (handle, 1, K3, 16, iv, ivout, in + 16, inlen - 16, &pt);
316 if (err)
317 goto done;
319 if (VERBOSECRYPTONOISE (handle))
321 puts ("cksum pt");
322 _shishi_hexprint (pt, inlen - 16);
325 err = shishi_hmac_md5 (handle, K2, 16, pt, inlen - 16, &cksum);
326 if (err)
327 goto done;
329 if (VERBOSECRYPTONOISE (handle))
331 puts ("cksum");
332 _shishi_hexprint (cksum, 16);
333 puts ("cksumin");
334 _shishi_hexprint (in, 16);
337 if (memcmp (cksum, in, 16) != 0)
339 err = SHISHI_CRYPTO_ERROR;
340 goto done;
343 *outlen = inlen - 16 - 8;
344 *out = xmalloc (*outlen);
345 memcpy (*out, pt + 8, inlen - 16 - 8);
347 if (ivoutlen)
348 /* size = sbox[256] + int8_t i + int8_t j */
349 *ivoutlen = 256 + 2 * 8;
351 err = SHISHI_OK;
353 done:
354 free (cksum);
355 free (K3);
356 free (K1);
357 free (pt);
358 return err;
361 static int
362 arcfour_hmac_exp_encrypt (Shishi * handle,
363 Shishi_key * key,
364 int keyusage,
365 const char *iv,
366 size_t ivlen,
367 char **ivout, size_t * ivoutlen,
368 const char *in, size_t inlen,
369 char **out, size_t * outlen)
371 return arcfour_hmac_encrypt (handle, key, keyusage, iv, ivlen,
372 ivout, ivoutlen, in, inlen, out, outlen);
376 static int
377 arcfour_hmac_exp_decrypt (Shishi * handle,
378 Shishi_key * key,
379 int keyusage,
380 const char *iv,
381 size_t ivlen,
382 char **ivout, size_t * ivoutlen,
383 const char *in, size_t inlen,
384 char **out, size_t * outlen)
386 return arcfour_hmac_decrypt (handle, key, keyusage, iv, ivlen,
387 ivout, ivoutlen, in, inlen, out, outlen);
390 #define ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT "signaturekey"
392 static int
393 arcfour_hmac_md5_checksum (Shishi * handle,
394 Shishi_key * key,
395 int keyusage,
396 int cksumtype,
397 const char *in, size_t inlen,
398 char **out, size_t * outlen)
400 int arcfourkeyusage = arcfour_keyusage (keyusage);
401 char *Ksign = NULL;
402 char *pt = NULL;
403 size_t ptlen;
404 char *tmp = NULL;
405 char T[4];
406 int err;
408 T[0] = arcfourkeyusage & 0xFF;
409 T[1] = (arcfourkeyusage >> 8) & 0xFF;
410 T[2] = (arcfourkeyusage >> 16) & 0xFF;
411 T[3] = (arcfourkeyusage >> 24) & 0xFF;
413 err = shishi_hmac_md5 (handle,
414 shishi_key_value (key), shishi_key_length (key),
415 ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT,
416 strlen (ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT) + 1,
417 &Ksign);
418 if (err)
419 goto done;
421 if (VERBOSECRYPTONOISE (handle))
423 puts ("Ksign");
424 _shishi_hexprint (Ksign, 16);
427 ptlen = 4 + inlen;
428 pt = xmalloc (ptlen);
429 memcpy (pt, T, 4);
430 memcpy (pt + 4, in, inlen);
432 if (VERBOSECRYPTONOISE (handle))
434 puts ("pt");
435 _shishi_hexprint (pt, ptlen);
438 err = shishi_md5 (handle, pt, ptlen, &tmp);
439 if (err)
440 goto done;
442 if (VERBOSECRYPTONOISE (handle))
444 puts ("md");
445 _shishi_hexprint (tmp, 16);
448 *outlen = 16;
449 err = shishi_hmac_md5 (handle, Ksign, 16, tmp, 16, out);
450 if (err)
451 goto done;
453 if (VERBOSECRYPTONOISE (handle))
455 puts ("hmac");
456 _shishi_hexprint (*out, 16);
459 err = SHISHI_OK;
461 done:
462 free (Ksign);
463 free (pt);
464 free (tmp);
465 return err;
468 static int
469 arcfour_hmac_random_to_key (Shishi * handle,
470 const char *rnd, size_t rndlen,
471 Shishi_key * outkey)
473 if (rndlen != shishi_key_length (outkey))
475 shishi_error_printf (handle, "ARCFOUR random to key caller error");
476 return SHISHI_CRYPTO_ERROR;
479 shishi_key_value_set (outkey, rnd);
481 return SHISHI_OK;
484 static int
485 arcfour_hmac_string_to_key (Shishi * handle,
486 const char *string,
487 size_t stringlen,
488 const char *salt,
489 size_t saltlen,
490 const char *parameter, Shishi_key * outkey)
492 char *tmp, *md;
493 size_t tmplen, i;
494 int rc;
496 tmplen = 2 * stringlen;
497 tmp = xmalloc (tmplen);
499 for (i = 0; i < stringlen; i++)
501 tmp[2 * i] = string[i];
502 tmp[2 * i + 1] = '\x0';
505 rc = shishi_md4 (handle, tmp, tmplen, &md);
506 free (tmp);
507 if (rc != SHISHI_OK)
508 return rc;
510 shishi_key_value_set (outkey, md);
512 free (md);
514 return SHISHI_OK;
517 cipherinfo arcfour_hmac_info = {
518 SHISHI_ARCFOUR_HMAC,
519 "arcfour-hmac",
524 SHISHI_ARCFOUR_HMAC_MD5,
525 arcfour_hmac_random_to_key,
526 arcfour_hmac_string_to_key,
527 arcfour_hmac_encrypt,
528 arcfour_hmac_decrypt
531 cipherinfo arcfour_hmac_exp_info = {
532 SHISHI_ARCFOUR_HMAC_EXP,
533 "arcfour-hmac-exp",
538 SHISHI_ARCFOUR_HMAC_MD5,
539 arcfour_hmac_random_to_key,
540 arcfour_hmac_string_to_key,
541 arcfour_hmac_exp_encrypt,
542 arcfour_hmac_exp_decrypt
545 checksuminfo arcfour_hmac_md5_info = {
546 SHISHI_ARCFOUR_HMAC_MD5,
547 "arcfour-hmac-md5",
549 arcfour_hmac_md5_checksum