ARCFOUR additions (unfinished).
[shishi.git] / lib / crypto-rc4.c
blobf8fe378c3731aedfd612e0a75cabf868cfac78cd
1 /* crypto-rc4.c draft-brezak-win2k-krb-rc4-hmac-04 crypto functions
2 * Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 #include "crypto.h"
26 static int arcfour_keyusage (int keyusage)
29 * 1. AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with
30 * the client key (T=1)
31 * 2. AS-REP Ticket and TGS-REP Ticket (includes TGS session key
32 * or application session key), encrypted with the service key
33 * (T=2)
34 * 3. AS-REP encrypted part (includes TGS session key or
35 * application session key), encrypted with the client key (T=8)
36 * 4. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
37 * TGS session key (T=4)
38 * 5. TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the
39 * TGS authenticator subkey (T=5)
40 * 6. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
41 * with the TGS session key (T=6)
42 * 7. TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
43 * TGS authenticator subkey), encrypted with the TGS session key
44 * (T=7)
45 * 8. TGS-REP encrypted part (includes application session key),
46 * encrypted with the TGS session key (T=8)
47 * 9. TGS-REP encrypted part (includes application session key),
48 * encrypted with the TGS authenticator subkey (T=8)
49 * 10. AP-REQ Authenticator cksum, keyed with the application
50 * session key (T=10)
51 * 11. AP-REQ Authenticator (includes application authenticator
52 * subkey), encrypted with the application session key (T=11)
53 * 12. AP-REP encrypted part (includes application session
54 * subkey), encrypted with the application session key (T=12)
55 * 13. KRB-PRIV encrypted part, encrypted with a key chosen by
56 * the application. Also for data encrypted with GSS Wrap (T=13)
57 * 14. KRB-CRED encrypted part, encrypted with a key chosen by
58 * the application (T=14)
59 * 15. KRB-SAFE cksum, keyed with a key chosen by the
60 * application. Also for data signed in GSS MIC (T=15)
62 * Relative to RFC-1964 key uses:
64 * T = 0 in the generation of sequence number for the MIC token
65 * T = 0 in the generation of sequence number for the WRAP token
66 * T = 0 in the generation of encrypted data for the WRAPPED token
70 if (keyusage == 3)
71 return 8;
72 else if (keyusage == 9)
73 return 8;
75 return keyusage;
78 static int
79 arcfour_hmac_encrypt (Shishi * handle,
80 Shishi_key * key,
81 int keyusage,
82 const char *iv,
83 size_t ivlen,
84 char **ivout, size_t * ivoutlen,
85 const char *in, size_t inlen, char **out, size_t * outlen)
87 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
88 int arcfourkeyusage = arcfour_keyusage (keyusage);
89 char L40[14] = "fortybits";
90 uint8_t T[4];
91 char *K1 = NULL;
92 char K2[16];
93 char *K3 = NULL;
94 char *pt = NULL;
95 char *cksum = NULL;
96 int offset;
97 int err;
99 T[0] = arcfourkeyusage & 0xFF;
100 T[1] = (arcfourkeyusage >> 8) & 0xFF;
101 T[2] = (arcfourkeyusage >> 16) & 0xFF;
102 T[3] = (arcfourkeyusage >> 24) & 0xFF;
104 memcpy (L40 + 10, T, 4);
106 if (export)
107 offset = 10;
108 else
109 offset = 0;
111 err = shishi_hmac_md5 (handle,
112 shishi_key_value (key), shishi_key_length (key),
113 L40 + offset, 14 - offset, &K1);
114 if (err)
115 goto done;
117 memcpy (K2, K1, 16);
118 if (export)
119 memset (K1 + 7, 0xAB, 9);
121 pt = xmalloc (16 + 8 + inlen);
123 memset (pt, 0, 16);
124 err = shishi_randomize (handle, pt + 16, 8);
125 if (err)
126 goto done;
127 memcpy (pt + 16 + 8, in, inlen);
129 err = shishi_hmac_md5 (handle, K2, 16, pt, 16 + 8 + inlen, &cksum);
130 if (err)
131 goto done;
132 err = shishi_hmac_md5 (handle, K1, 16, cksum, 16, &K3);
133 if (err)
134 goto done;
136 *outlen = 8 + inlen;
137 err = shishi_arcfour (handle, 0, K3, 16, pt + 16, 8 + inlen, out);
138 if (err)
139 goto done;
141 memcpy (out, cksum, 16);
143 err = SHISHI_OK;
145 done:
146 free (cksum);
147 free (K3);
148 free (pt);
149 free (K1);
150 return err;
153 static int
154 arcfour_hmac_decrypt (Shishi * handle,
155 Shishi_key * key,
156 int keyusage,
157 const char *iv,
158 size_t ivlen,
159 char **ivout, size_t * ivoutlen,
160 const char *in, size_t inlen, char **out, size_t * outlen)
162 int export = shishi_key_type (key) == SHISHI_ARCFOUR_HMAC_EXP;
163 int arcfourkeyusage = arcfour_keyusage (keyusage);
164 char L40[14] = "fortybits";
165 uint8_t T[4];
166 char *K1 = NULL;
167 char K2[16];
168 char *K3 = NULL;
169 char *pt = NULL;
170 char *cksum = NULL;
171 int offset;
172 int err;
174 T[0] = arcfourkeyusage & 0xFF;
175 T[1] = (arcfourkeyusage >> 8) & 0xFF;
176 T[2] = (arcfourkeyusage >> 16) & 0xFF;
177 T[3] = (arcfourkeyusage >> 24) & 0xFF;
179 memcpy (L40 + 10, T, 4);
181 if (export)
182 offset = 10;
183 else
184 offset = 0;
186 err = shishi_hmac_md5 (handle,
187 shishi_key_value (key), shishi_key_length (key),
188 L40 + offset, 14 - offset, &K1);
189 if (err)
190 goto done;
192 memcpy (K2, K1, 16);
193 if (export)
194 memset (K1 + 7, 0xAB, 9);
196 pt = xmalloc (16 + 8 + inlen);
198 memset (pt, 0, 16);
199 err = shishi_randomize (handle, pt + 16, 8);
200 if (err)
201 goto done;
202 memcpy (pt + 16 + 8, in, inlen);
204 err = shishi_hmac_md5 (handle, K2, 16, pt, 16 + 8 + inlen, &cksum);
205 if (err)
206 goto done;
207 err = shishi_hmac_md5 (handle, K1, 16, cksum, 16, &K3);
208 if (err)
209 goto done;
211 *outlen = 8 + inlen;
212 err = shishi_arcfour (handle, 0, K3, 16, pt + 16, 8 + inlen, out);
213 if (err)
214 goto done;
216 err = SHISHI_OK;
218 done:
219 free (cksum);
220 free (K3);
221 free (pt);
222 free (K1);
223 return err;
226 static int
227 arcfour_hmac_exp_encrypt (Shishi * handle,
228 Shishi_key * key,
229 int keyusage,
230 const char *iv,
231 size_t ivlen,
232 char **ivout, size_t * ivoutlen,
233 const char *in, size_t inlen,
234 char **out, size_t * outlen)
236 return arcfour_hmac_encrypt (handle, key, keyusage, iv, ivlen,
237 ivout, ivoutlen, in, inlen, out, outlen);
241 static int
242 arcfour_hmac_exp_decrypt (Shishi * handle,
243 Shishi_key * key,
244 int keyusage,
245 const char *iv,
246 size_t ivlen,
247 char **ivout, size_t * ivoutlen,
248 const char *in, size_t inlen,
249 char **out, size_t * outlen)
251 return arcfour_hmac_decrypt (handle, key, keyusage, iv, ivlen,
252 ivout, ivoutlen, in, inlen, out, outlen);
255 #define ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT "signaturekey"
257 static int
258 arcfour_hmac_md5_checksum (Shishi * handle,
259 Shishi_key * key,
260 int keyusage,
261 int cksumtype,
262 const char *in, size_t inlen,
263 char **out, size_t * outlen)
265 int arcfourkeyusage = arcfour_keyusage (keyusage);
266 char *Ksign = NULL;
267 char *pt = NULL;
268 char T[4];
269 int err;
271 T[0] = arcfourkeyusage & 0xFF;
272 T[1] = (arcfourkeyusage >> 8) & 0xFF;
273 T[2] = (arcfourkeyusage >> 16) & 0xFF;
274 T[3] = (arcfourkeyusage >> 24) & 0xFF;
276 err = shishi_hmac_md5 (handle,
277 shishi_key_value (key), shishi_key_length (key),
278 ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT,
279 strlen (ARCFOUR_HMAC_CKSUM_KEY_DERIVE_CONSTANT) + 1,
280 &Ksign);
281 if (err)
282 goto done;
284 pt = xmalloc (4 + inlen);
285 memcpy (pt, T, 4);
286 memcpy (pt + 4, in, inlen);
288 *outlen = 16;
289 err = shishi_hmac_md5 (handle, Ksign, 16, in, inlen, out);
290 if (err)
291 goto done;
293 err = SHISHI_OK;
295 done:
296 free (Ksign);
297 free (pt);
298 return err;
301 static int
302 arcfour_hmac_random_to_key (Shishi * handle,
303 const char *random, size_t randomlen,
304 Shishi_key * outkey)
306 if (randomlen != shishi_key_length (outkey))
308 shishi_error_printf (handle, "ARCFOUR random to key caller error");
309 return SHISHI_CRYPTO_ERROR;
312 shishi_key_value_set (outkey, random);
314 return SHISHI_OK;
317 static int
318 arcfour_hmac_string_to_key (Shishi * handle,
319 const char *string,
320 size_t stringlen,
321 const char *salt,
322 size_t saltlen,
323 const char *parameter, Shishi_key * outkey)
325 char *tmp, *md;
326 size_t tmplen, i;
327 int rc;
329 tmplen = 2 * stringlen;
330 tmp = xmalloc (tmplen);
332 for (i = 0; i < stringlen; i++)
334 tmp[2 * i] = string[i];
335 tmp[2 * i + 1] = '\x0';
338 rc = shishi_md4 (handle, tmp, tmplen, &md);
339 free (tmp);
340 if (rc != SHISHI_OK)
341 return rc;
343 shishi_key_value_set (outkey, md);
345 return SHISHI_OK;
348 cipherinfo arcfour_hmac_info = {
349 SHISHI_ARCFOUR_HMAC,
350 "arcfour-hmac",
356 SHISHI_ARCFOUR_HMAC_MD5,
357 arcfour_hmac_random_to_key,
358 arcfour_hmac_string_to_key,
359 arcfour_hmac_encrypt,
360 arcfour_hmac_decrypt
363 cipherinfo arcfour_hmac_exp_info = {
364 SHISHI_ARCFOUR_HMAC_EXP,
365 "arcfour-hmac-exp",
371 SHISHI_ARCFOUR_HMAC_MD5,
372 arcfour_hmac_random_to_key,
373 arcfour_hmac_string_to_key,
374 arcfour_hmac_exp_encrypt,
375 arcfour_hmac_exp_decrypt
378 checksuminfo arcfour_hmac_md5_info = {
379 SHISHI_ARCFOUR_HMAC_MD5,
380 "arcfour-hmac-md5",
382 arcfour_hmac_md5_checksum