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
27 /* Get _shishi_escapeprint, etc. */
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
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
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
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
)
95 arcfour_hmac_encrypt (Shishi
* handle
,
100 char **ivout
, size_t * ivoutlen
,
101 const char *in
, size_t inlen
, char **out
,
104 int export
= shishi_key_type (key
) == SHISHI_ARCFOUR_HMAC_EXP
;
105 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
106 char L40
[14] = "fortybits";
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);
130 if (VERBOSECRYPTONOISE (handle
))
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
);
142 if (VERBOSECRYPTONOISE (handle
))
145 _shishi_hexprint (K1
, 16);
150 memset (K1
+ 7, 0xAB, 9);
152 if (VERBOSECRYPTONOISE (handle
))
155 _shishi_hexprint (K1
, 16);
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);
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.
176 pt
= xmalloc (ptlen
);
178 err
= shishi_randomize (handle
, 0, pt
, 8);
181 memcpy (pt
+ 8, in
, inlen
);
183 if (VERBOSECRYPTONOISE (handle
))
186 _shishi_hexprint (pt
, 8);
189 err
= shishi_hmac_md5 (handle
, K2
, 16, pt
, ptlen
, &cksum
);
193 if (VERBOSECRYPTONOISE (handle
))
196 _shishi_hexprint (cksum
, 16);
199 err
= shishi_hmac_md5 (handle
, K1
, 16, cksum
, 16, &K3
);
203 if (VERBOSECRYPTONOISE (handle
))
206 _shishi_hexprint (K3
, 16);
209 err
= shishi_arcfour (handle
, 0, K3
, 16, iv
, ivout
, pt
, ptlen
, &ct
);
213 if (VERBOSECRYPTONOISE (handle
))
216 _shishi_hexprint (ct
, ptlen
);
219 *outlen
= 16 + ptlen
;
220 *out
= xmalloc (*outlen
);
221 memcpy (*out
, cksum
, 16);
222 memcpy (*out
+ 16, ct
, ptlen
);
225 /* size = sbox[256] + int8_t i + int8_t j */
226 *ivoutlen
= 256 + 2 * 8;
240 arcfour_hmac_decrypt (Shishi
* handle
,
245 char **ivout
, size_t * ivoutlen
,
246 const char *in
, size_t inlen
, char **out
,
249 int export
= shishi_key_type (key
) == SHISHI_ARCFOUR_HMAC_EXP
;
250 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
251 char L40
[14] = "fortybits";
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);
273 if (VERBOSECRYPTONOISE (handle
))
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
);
285 if (VERBOSECRYPTONOISE (handle
))
288 _shishi_hexprint (K1
, 16);
293 memset (K1
+ 7, 0xAB, 9);
295 if (VERBOSECRYPTONOISE (handle
))
298 _shishi_hexprint (K1
, 16);
300 _shishi_hexprint (K2
, 16);
303 err
= shishi_hmac_md5 (handle
, K1
, 16, in
, 16, &K3
);
307 if (VERBOSECRYPTONOISE (handle
))
310 _shishi_hexprint (K3
, 16);
314 shishi_arcfour (handle
, 1, K3
, 16, iv
, ivout
, in
+ 16, inlen
- 16, &pt
);
318 if (VERBOSECRYPTONOISE (handle
))
321 _shishi_hexprint (pt
, inlen
- 16);
324 err
= shishi_hmac_md5 (handle
, K2
, 16, pt
, inlen
- 16, &cksum
);
328 if (VERBOSECRYPTONOISE (handle
))
331 _shishi_hexprint (cksum
, 16);
333 _shishi_hexprint (in
, 16);
336 if (memcmp (cksum
, in
, 16) != 0)
338 err
= SHISHI_CRYPTO_ERROR
;
342 *outlen
= inlen
- 16 - 8;
343 *out
= xmalloc (*outlen
);
344 memcpy (*out
, pt
+ 8, inlen
- 16 - 8);
347 /* size = sbox[256] + int8_t i + int8_t j */
348 *ivoutlen
= 256 + 2 * 8;
361 arcfour_hmac_exp_encrypt (Shishi
* handle
,
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
);
376 arcfour_hmac_exp_decrypt (Shishi
* handle
,
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"
392 arcfour_hmac_md5_checksum (Shishi
* handle
,
396 const char *in
, size_t inlen
,
397 char **out
, size_t * outlen
)
399 int arcfourkeyusage
= arcfour_keyusage (keyusage
);
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,
420 if (VERBOSECRYPTONOISE (handle
))
423 _shishi_hexprint (Ksign
, 16);
427 pt
= xmalloc (ptlen
);
429 memcpy (pt
+ 4, in
, inlen
);
431 if (VERBOSECRYPTONOISE (handle
))
434 _shishi_hexprint (pt
, ptlen
);
437 err
= shishi_md5 (handle
, pt
, ptlen
, &tmp
);
441 if (VERBOSECRYPTONOISE (handle
))
444 _shishi_hexprint (tmp
, 16);
448 err
= shishi_hmac_md5 (handle
, Ksign
, 16, tmp
, 16, out
);
452 if (VERBOSECRYPTONOISE (handle
))
455 _shishi_hexprint (*out
, 16);
468 arcfour_hmac_random_to_key (Shishi
* handle
,
469 const char *rnd
, size_t rndlen
,
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
);
484 arcfour_hmac_string_to_key (Shishi
* handle
,
489 const char *parameter
, Shishi_key
* outkey
)
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
);
509 shishi_key_value_set (outkey
, md
);
516 cipherinfo arcfour_hmac_info
= {
523 SHISHI_ARCFOUR_HMAC_MD5
,
524 arcfour_hmac_random_to_key
,
525 arcfour_hmac_string_to_key
,
526 arcfour_hmac_encrypt
,
530 cipherinfo arcfour_hmac_exp_info
= {
531 SHISHI_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
,
548 arcfour_hmac_md5_checksum