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
28 /* Get _shishi_escapeprint, etc. */
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
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
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
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
)
96 arcfour_hmac_encrypt (Shishi
* handle
,
101 char **ivout
, size_t * ivoutlen
,
102 const char *in
, size_t inlen
, char **out
,
105 int export
= shishi_key_type (key
) == SHISHI_ARCFOUR_HMAC_EXP
;
106 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
107 char L40
[14] = "fortybits";
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);
131 if (VERBOSECRYPTONOISE (handle
))
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
);
143 if (VERBOSECRYPTONOISE (handle
))
146 _shishi_hexprint (K1
, 16);
151 memset (K1
+ 7, 0xAB, 9);
153 if (VERBOSECRYPTONOISE (handle
))
156 _shishi_hexprint (K1
, 16);
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);
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.
177 pt
= xmalloc (ptlen
);
179 err
= shishi_randomize (handle
, 0, pt
, 8);
182 memcpy (pt
+ 8, in
, inlen
);
184 if (VERBOSECRYPTONOISE (handle
))
187 _shishi_hexprint (pt
, 8);
190 err
= shishi_hmac_md5 (handle
, K2
, 16, pt
, ptlen
, &cksum
);
194 if (VERBOSECRYPTONOISE (handle
))
197 _shishi_hexprint (cksum
, 16);
200 err
= shishi_hmac_md5 (handle
, K1
, 16, cksum
, 16, &K3
);
204 if (VERBOSECRYPTONOISE (handle
))
207 _shishi_hexprint (K3
, 16);
210 err
= shishi_arcfour (handle
, 0, K3
, 16, iv
, ivout
, pt
, ptlen
, &ct
);
214 if (VERBOSECRYPTONOISE (handle
))
217 _shishi_hexprint (ct
, ptlen
);
220 *outlen
= 16 + ptlen
;
221 *out
= xmalloc (*outlen
);
222 memcpy (*out
, cksum
, 16);
223 memcpy (*out
+ 16, ct
, ptlen
);
226 /* size = sbox[256] + int8_t i + int8_t j */
227 *ivoutlen
= 256 + 2 * 8;
241 arcfour_hmac_decrypt (Shishi
* handle
,
246 char **ivout
, size_t * ivoutlen
,
247 const char *in
, size_t inlen
, char **out
,
250 int export
= shishi_key_type (key
) == SHISHI_ARCFOUR_HMAC_EXP
;
251 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
252 char L40
[14] = "fortybits";
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);
274 if (VERBOSECRYPTONOISE (handle
))
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
);
286 if (VERBOSECRYPTONOISE (handle
))
289 _shishi_hexprint (K1
, 16);
294 memset (K1
+ 7, 0xAB, 9);
296 if (VERBOSECRYPTONOISE (handle
))
299 _shishi_hexprint (K1
, 16);
301 _shishi_hexprint (K2
, 16);
304 err
= shishi_hmac_md5 (handle
, K1
, 16, in
, 16, &K3
);
308 if (VERBOSECRYPTONOISE (handle
))
311 _shishi_hexprint (K3
, 16);
315 shishi_arcfour (handle
, 1, K3
, 16, iv
, ivout
, in
+ 16, inlen
- 16, &pt
);
319 if (VERBOSECRYPTONOISE (handle
))
322 _shishi_hexprint (pt
, inlen
- 16);
325 err
= shishi_hmac_md5 (handle
, K2
, 16, pt
, inlen
- 16, &cksum
);
329 if (VERBOSECRYPTONOISE (handle
))
332 _shishi_hexprint (cksum
, 16);
334 _shishi_hexprint (in
, 16);
337 if (memcmp (cksum
, in
, 16) != 0)
339 err
= SHISHI_CRYPTO_ERROR
;
343 *outlen
= inlen
- 16 - 8;
344 *out
= xmalloc (*outlen
);
345 memcpy (*out
, pt
+ 8, inlen
- 16 - 8);
348 /* size = sbox[256] + int8_t i + int8_t j */
349 *ivoutlen
= 256 + 2 * 8;
362 arcfour_hmac_exp_encrypt (Shishi
* handle
,
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
);
377 arcfour_hmac_exp_decrypt (Shishi
* handle
,
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"
393 arcfour_hmac_md5_checksum (Shishi
* handle
,
397 const char *in
, size_t inlen
,
398 char **out
, size_t * outlen
)
400 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
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,
421 if (VERBOSECRYPTONOISE (handle
))
424 _shishi_hexprint (Ksign
, 16);
428 pt
= xmalloc (ptlen
);
430 memcpy (pt
+ 4, in
, inlen
);
432 if (VERBOSECRYPTONOISE (handle
))
435 _shishi_hexprint (pt
, ptlen
);
438 err
= shishi_md5 (handle
, pt
, ptlen
, &tmp
);
442 if (VERBOSECRYPTONOISE (handle
))
445 _shishi_hexprint (tmp
, 16);
449 err
= shishi_hmac_md5 (handle
, Ksign
, 16, tmp
, 16, out
);
453 if (VERBOSECRYPTONOISE (handle
))
456 _shishi_hexprint (*out
, 16);
469 arcfour_hmac_random_to_key (Shishi
* handle
,
470 const char *rnd
, size_t rndlen
,
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
);
485 arcfour_hmac_string_to_key (Shishi
* handle
,
490 const char *parameter
, Shishi_key
* outkey
)
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
);
510 shishi_key_value_set (outkey
, md
);
517 cipherinfo arcfour_hmac_info
= {
524 SHISHI_ARCFOUR_HMAC_MD5
,
525 arcfour_hmac_random_to_key
,
526 arcfour_hmac_string_to_key
,
527 arcfour_hmac_encrypt
,
531 cipherinfo arcfour_hmac_exp_info
= {
532 SHISHI_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
,
549 arcfour_hmac_md5_checksum