Branch data Line data Source code
1 : : /* crypto-rc4.c --- draft-brezak-win2k-krb-rc4-hmac-04 crypto functions.
2 : : * Copyright (C) 2003, 2004, 2006, 2007, 2008 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
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.
10 : : *
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.
15 : : *
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
20 : : *
21 : : */
22 : :
23 : : #include "internal.h"
24 : :
25 : : /* Get prototypes. */
26 : : #include "crypto.h"
27 : :
28 : : /* Get _shishi_escapeprint, etc. */
29 : : #include "utils.h"
30 : :
31 : : static int
32 : 288 : arcfour_keyusage (int keyusage)
33 : : {
34 : : /* From draft-brezak-win2k-krb-rc4-hmac-04.txt:
35 : : *
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)
68 : : */
69 : :
70 [ + - ]: 288 : if (keyusage == SHISHI_KEYUSAGE_ENCASREPPART)
71 : 288 : return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
72 [ # # ]: 0 : else if (keyusage == SHISHI_KEYUSAGE_ENCTGSREPPART_AUTHENTICATOR_KEY)
73 : 0 : return SHISHI_KEYUSAGE_ENCTGSREPPART_SESSION_KEY;
74 : :
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.
78 : : *
79 : : * Relative to RFC-1964 key uses:
80 : : *
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
84 : : *
85 : : */
86 : :
87 [ # # ][ # # ]: 0 : if (keyusage == SHISHI_KEYUSAGE_GSS_R1 ||
[ # # ]
88 : : keyusage == SHISHI_KEYUSAGE_GSS_R2 ||
89 : : keyusage == SHISHI_KEYUSAGE_GSS_R3)
90 : 0 : return 0;
91 : :
92 : 288 : return keyusage;
93 : : }
94 : :
95 : : static int
96 : 144 : 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)
104 : : {
105 : 144 : int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
106 : 144 : int arcfourkeyusage = arcfour_keyusage (keyusage);
107 : 144 : char L40[14] = "fortybits";
108 : : uint8_t T[4];
109 : 144 : char *K1 = NULL;
110 : : char K2[16];
111 : 144 : char *K3 = NULL;
112 : 144 : char *pt = NULL;
113 : : size_t ptlen;
114 : 144 : char *ct = NULL;
115 : 144 : char *cksum = NULL;
116 : : int offset;
117 : : int err;
118 : :
119 : 144 : T[0] = arcfourkeyusage & 0xFF;
120 : 144 : T[1] = (arcfourkeyusage >> 8) & 0xFF;
121 : 144 : T[2] = (arcfourkeyusage >> 16) & 0xFF;
122 : 144 : T[3] = (arcfourkeyusage >> 24) & 0xFF;
123 : :
124 : 144 : memcpy (L40 + 10, T, 4);
125 : :
126 [ + + ]: 144 : if (export)
127 : 72 : offset = 0;
128 : : else
129 : 72 : offset = 10;
130 : :
131 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
132 : : {
133 : 0 : puts ("k1pt");
134 : 0 : _shishi_hexprint (L40 + offset, 14 - offset);
135 : : }
136 : :
137 : 144 : err = shishi_hmac_md5 (handle,
138 : : shishi_key_value (key), shishi_key_length (key),
139 : 144 : L40 + offset, 14 - offset, &K1);
140 [ - + ]: 144 : if (err)
141 : 0 : goto done;
142 : :
143 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
144 : : {
145 : 0 : puts ("k1");
146 : 0 : _shishi_hexprint (K1, 16);
147 : : }
148 : :
149 : 144 : memcpy (K2, K1, 16);
150 [ + + ]: 144 : if (export)
151 : 72 : memset (K1 + 7, 0xAB, 9);
152 : :
153 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
154 : : {
155 : 0 : puts ("k1");
156 : 0 : _shishi_hexprint (K1, 16);
157 : 0 : puts ("k2");
158 : 0 : _shishi_hexprint (K2, 16);
159 : : }
160 : :
161 : : /* Note that in ENCRYPT of draft-brezak-win2k-krb-rc4-hmac-04.txt change:
162 : : *
163 : : * edata.Checksum = HMAC (K2, edata);
164 : : *
165 : : * into
166 : : *
167 : : * edata.Checksum = HMAC (K2, concat(edata.Confounder, edata.Data));
168 : : *
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.
173 : : *
174 : : */
175 : :
176 : 144 : ptlen = 8 + inlen;
177 : 144 : pt = xmalloc (ptlen);
178 : :
179 : 144 : err = shishi_randomize (handle, 0, pt, 8);
180 [ - + ]: 144 : if (err)
181 : 0 : goto done;
182 : 144 : memcpy (pt + 8, in, inlen);
183 : :
184 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
185 : : {
186 : 0 : puts ("random");
187 : 0 : _shishi_hexprint (pt, 8);
188 : : }
189 : :
190 : 144 : err = shishi_hmac_md5 (handle, K2, 16, pt, ptlen, &cksum);
191 [ - + ]: 144 : if (err)
192 : 0 : goto done;
193 : :
194 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
195 : : {
196 : 0 : puts ("cksum");
197 : 0 : _shishi_hexprint (cksum, 16);
198 : : }
199 : :
200 : 144 : err = shishi_hmac_md5 (handle, K1, 16, cksum, 16, &K3);
201 [ - + ]: 144 : if (err)
202 : 0 : goto done;
203 : :
204 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
205 : : {
206 : 0 : puts ("k3");
207 : 0 : _shishi_hexprint (K3, 16);
208 : : }
209 : :
210 : 144 : err = shishi_arcfour (handle, 0, K3, 16, iv, ivout, pt, ptlen, &ct);
211 [ - + ]: 144 : if (err)
212 : 0 : goto done;
213 : :
214 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
215 : : {
216 : 0 : puts ("ct");
217 : 0 : _shishi_hexprint (ct, ptlen);
218 : : }
219 : :
220 : 144 : *outlen = 16 + ptlen;
221 : 144 : *out = xmalloc (*outlen);
222 : 144 : memcpy (*out, cksum, 16);
223 : 144 : memcpy (*out + 16, ct, ptlen);
224 : :
225 [ + - ]: 144 : if (ivoutlen)
226 : : /* size = sbox[256] + int8_t i + int8_t j */
227 : 144 : *ivoutlen = 256 + 2 * 8;
228 : :
229 : 144 : err = SHISHI_OK;
230 : :
231 : : done:
232 : 144 : free (cksum);
233 : 144 : free (K3);
234 : 144 : free (pt);
235 : 144 : free (ct);
236 : 144 : free (K1);
237 : 144 : return err;
238 : : }
239 : :
240 : : static int
241 : 144 : 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)
249 : : {
250 : 144 : int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
251 : 144 : int arcfourkeyusage = arcfour_keyusage (keyusage);
252 : 144 : char L40[14] = "fortybits";
253 : : uint8_t T[4];
254 : 144 : char *K1 = NULL;
255 : : char K2[16];
256 : 144 : char *K3 = NULL;
257 : 144 : char *cksum = NULL;
258 : 144 : char *pt = NULL;
259 : : int offset;
260 : : int err;
261 : :
262 : 144 : T[0] = arcfourkeyusage & 0xFF;
263 : 144 : T[1] = (arcfourkeyusage >> 8) & 0xFF;
264 : 144 : T[2] = (arcfourkeyusage >> 16) & 0xFF;
265 : 144 : T[3] = (arcfourkeyusage >> 24) & 0xFF;
266 : :
267 : 144 : memcpy (L40 + 10, T, 4);
268 : :
269 [ + + ]: 144 : if (export)
270 : 72 : offset = 0;
271 : : else
272 : 72 : offset = 10;
273 : :
274 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
275 : : {
276 : 0 : puts ("k1pt");
277 : 0 : _shishi_hexprint (L40 + offset, 14 - offset);
278 : : }
279 : :
280 : 144 : err = shishi_hmac_md5 (handle,
281 : : shishi_key_value (key), shishi_key_length (key),
282 : 144 : L40 + offset, 14 - offset, &K1);
283 [ - + ]: 144 : if (err)
284 : 0 : goto done;
285 : :
286 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
287 : : {
288 : 0 : puts ("k1");
289 : 0 : _shishi_hexprint (K1, 16);
290 : : }
291 : :
292 : 144 : memcpy (K2, K1, 16);
293 [ + + ]: 144 : if (export)
294 : 72 : memset (K1 + 7, 0xAB, 9);
295 : :
296 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
297 : : {
298 : 0 : puts ("k1");
299 : 0 : _shishi_hexprint (K1, 16);
300 : 0 : puts ("k2");
301 : 0 : _shishi_hexprint (K2, 16);
302 : : }
303 : :
304 : 144 : err = shishi_hmac_md5 (handle, K1, 16, in, 16, &K3);
305 [ - + ]: 144 : if (err)
306 : 0 : goto done;
307 : :
308 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
309 : : {
310 : 0 : puts ("k3");
311 : 0 : _shishi_hexprint (K3, 16);
312 : : }
313 : :
314 : 144 : err =
315 : 144 : shishi_arcfour (handle, 1, K3, 16, iv, ivout, in + 16, inlen - 16, &pt);
316 [ - + ]: 144 : if (err)
317 : 0 : goto done;
318 : :
319 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
320 : : {
321 : 0 : puts ("cksum pt");
322 : 0 : _shishi_hexprint (pt, inlen - 16);
323 : : }
324 : :
325 : 144 : err = shishi_hmac_md5 (handle, K2, 16, pt, inlen - 16, &cksum);
326 [ - + ]: 144 : if (err)
327 : 0 : goto done;
328 : :
329 [ - + ]: 144 : if (VERBOSECRYPTONOISE (handle))
330 : : {
331 : 0 : puts ("cksum");
332 : 0 : _shishi_hexprint (cksum, 16);
333 : 0 : puts ("cksumin");
334 : 0 : _shishi_hexprint (in, 16);
335 : : }
336 : :
337 [ - + ]: 144 : if (memcmp (cksum, in, 16) != 0)
338 : : {
339 : 0 : err = SHISHI_CRYPTO_ERROR;
340 : 0 : goto done;
341 : : }
342 : :
343 : 144 : *outlen = inlen - 16 - 8;
344 : 144 : *out = xmalloc (*outlen);
345 : 144 : memcpy (*out, pt + 8, inlen - 16 - 8);
346 : :
347 [ + - ]: 144 : if (ivoutlen)
348 : : /* size = sbox[256] + int8_t i + int8_t j */
349 : 144 : *ivoutlen = 256 + 2 * 8;
350 : :
351 : 144 : err = SHISHI_OK;
352 : :
353 : : done:
354 : 144 : free (cksum);
355 : 144 : free (K3);
356 : 144 : free (K1);
357 : 144 : free (pt);
358 : 144 : return err;
359 : : }
360 : :
361 : : static int
362 : 72 : 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)
370 : : {
371 : 72 : return arcfour_hmac_encrypt (handle, key, keyusage, iv, ivlen,
372 : : ivout, ivoutlen, in, inlen, out, outlen);
373 : :
374 : : }
375 : :
376 : : static int
377 : 72 : 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)
385 : : {
386 : 72 : return arcfour_hmac_decrypt (handle, key, keyusage, iv, ivlen,
387 : : ivout, ivoutlen, in, inlen, out, outlen);
388 : : }
389 : :
390 : : #define ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT "signaturekey"
391 : :
392 : : static int
393 : 0 : 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)
399 : : {
400 : 0 : int arcfourkeyusage = arcfour_keyusage (keyusage);
401 : 0 : char *Ksign = NULL;
402 : 0 : char *pt = NULL;
403 : : size_t ptlen;
404 : 0 : char *tmp = NULL;
405 : : char T[4];
406 : : int err;
407 : :
408 : 0 : T[0] = arcfourkeyusage & 0xFF;
409 : 0 : T[1] = (arcfourkeyusage >> 8) & 0xFF;
410 : 0 : T[2] = (arcfourkeyusage >> 16) & 0xFF;
411 : 0 : T[3] = (arcfourkeyusage >> 24) & 0xFF;
412 : :
413 : 0 : 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 [ # # ]: 0 : if (err)
419 : 0 : goto done;
420 : :
421 [ # # ]: 0 : if (VERBOSECRYPTONOISE (handle))
422 : : {
423 : 0 : puts ("Ksign");
424 : 0 : _shishi_hexprint (Ksign, 16);
425 : : }
426 : :
427 : 0 : ptlen = 4 + inlen;
428 : 0 : pt = xmalloc (ptlen);
429 : 0 : memcpy (pt, T, 4);
430 : 0 : memcpy (pt + 4, in, inlen);
431 : :
432 [ # # ]: 0 : if (VERBOSECRYPTONOISE (handle))
433 : : {
434 : 0 : puts ("pt");
435 : 0 : _shishi_hexprint (pt, ptlen);
436 : : }
437 : :
438 : 0 : err = shishi_md5 (handle, pt, ptlen, &tmp);
439 [ # # ]: 0 : if (err)
440 : 0 : goto done;
441 : :
442 [ # # ]: 0 : if (VERBOSECRYPTONOISE (handle))
443 : : {
444 : 0 : puts ("md");
445 : 0 : _shishi_hexprint (tmp, 16);
446 : : }
447 : :
448 : 0 : *outlen = 16;
449 : 0 : err = shishi_hmac_md5 (handle, Ksign, 16, tmp, 16, out);
450 [ # # ]: 0 : if (err)
451 : 0 : goto done;
452 : :
453 [ # # ]: 0 : if (VERBOSECRYPTONOISE (handle))
454 : : {
455 : 0 : puts ("hmac");
456 : 0 : _shishi_hexprint (*out, 16);
457 : : }
458 : :
459 : 0 : err = SHISHI_OK;
460 : :
461 : : done:
462 : 0 : free (Ksign);
463 : 0 : free (pt);
464 : 0 : free (tmp);
465 : 0 : return err;
466 : : }
467 : :
468 : : static int
469 : 2 : arcfour_hmac_random_to_key (Shishi * handle,
470 : : const char *rnd, size_t rndlen,
471 : : Shishi_key * outkey)
472 : : {
473 [ - + ]: 2 : if (rndlen != shishi_key_length (outkey))
474 : : {
475 : 0 : shishi_error_printf (handle, "ARCFOUR random to key caller error");
476 : 0 : return SHISHI_CRYPTO_ERROR;
477 : : }
478 : :
479 : 2 : shishi_key_value_set (outkey, rnd);
480 : :
481 : 2 : return SHISHI_OK;
482 : : }
483 : :
484 : : static int
485 : 1 : 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)
491 : : {
492 : : char *tmp, *md;
493 : : size_t tmplen, i;
494 : : int rc;
495 : :
496 : 1 : tmplen = 2 * stringlen;
497 : 1 : tmp = xmalloc (tmplen);
498 : :
499 [ + + ]: 4 : for (i = 0; i < stringlen; i++)
500 : : {
501 : 3 : tmp[2 * i] = string[i];
502 : 3 : tmp[2 * i + 1] = '\x0';
503 : : }
504 : :
505 : 1 : rc = shishi_md4 (handle, tmp, tmplen, &md);
506 : 1 : free (tmp);
507 [ - + ]: 1 : if (rc != SHISHI_OK)
508 : 0 : return rc;
509 : :
510 : 1 : shishi_key_value_set (outkey, md);
511 : :
512 : 1 : free (md);
513 : :
514 : 1 : return SHISHI_OK;
515 : : }
516 : :
517 : : cipherinfo arcfour_hmac_info = {
518 : : SHISHI_ARCFOUR_HMAC,
519 : : "arcfour-hmac",
520 : : 1,
521 : : 16,
522 : : 16,
523 : : 16,
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
529 : : };
530 : :
531 : : cipherinfo arcfour_hmac_exp_info = {
532 : : SHISHI_ARCFOUR_HMAC_EXP,
533 : : "arcfour-hmac-exp",
534 : : 1,
535 : : 16,
536 : : 16,
537 : : 16,
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
543 : : };
544 : :
545 : : checksuminfo arcfour_hmac_md5_info = {
546 : : SHISHI_ARCFOUR_HMAC_MD5,
547 : : "arcfour-hmac-md5",
548 : : 16,
549 : : arcfour_hmac_md5_checksum,
550 : : NULL
551 : : };
|