Fix standalone libtasn1.
[shishi.git] / lib / crypto-rc4.c
blob7be66faf3034a2436db678063226374b4bf989b9
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
27 rc4_hmac_encrypt (Shishi * handle,
28 Shishi_key * key,
29 int keyusage,
30 const char *iv,
31 size_t ivlen,
32 char **ivout, size_t * ivoutlen,
33 const char *in, size_t inlen, char **out, size_t * outlen)
35 #if 0
36 char L40[14] = "fortybits";
37 char SK = "signaturekey";
38 char T[4];
40 T[0] = keyusage & 0xFF;
41 T[1] = (keyusage >> 8) & 0xFF;
42 T[2] = (keyusage >> 16) & 0xFF;
43 T[3] = (keyusage >> 24) & 0xFF;
45 if (shishi_key_type (key) == SHISHI_RC4_HMAC_EXP)
47 memcpy (L40 + 10, T, 4);
48 HMAC (K, L40, 10 + 4, K1);
50 else
52 HMAC (K, &T, 4, K1);
54 memcpy (K2, K1, 16);
55 if (export)
56 memset (K1 + 7, 0xAB, 9);
58 nonce (edata.Confounder, 8);
59 memcpy (edata.Data, data);
61 edata.Checksum = HMAC (K2, edata);
62 K3 = HMAC (K1, edata.Checksum);
64 RC4 (K3, edata.Confounder);
65 RC4 (K3, data.Data);
66 #endif
68 return SHISHI_OK;
71 static int
72 rc4_hmac_decrypt (Shishi * handle,
73 Shishi_key * key,
74 int keyusage,
75 const char *iv,
76 size_t ivlen,
77 char **ivout, size_t * ivoutlen,
78 const char *in, size_t inlen, char **out, size_t * outlen)
80 return SHISHI_OK;
83 static int
84 rc4_hmac_exp_encrypt (Shishi * handle,
85 Shishi_key * key,
86 int keyusage,
87 const char *iv,
88 size_t ivlen,
89 char **ivout, size_t * ivoutlen,
90 const char *in, size_t inlen,
91 char **out, size_t * outlen)
95 static int
96 rc4_hmac_exp_decrypt (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,
103 char **out, size_t * outlen)
107 #define RC4_HMAC_CKSUM_KEY_DERIVE_CONSTANT "signaturekey"
109 static int
110 rc4_hmac_md5_checksum (Shishi * handle,
111 Shishi_key * key,
112 int keyusage,
113 int cksumtype,
114 const char *in, size_t inlen,
115 char **out, size_t * outlen)
117 #if 0
118 #if USE_GCRYPT
119 gcry_md_hd_t mdh, mdh2;
120 int halg = GCRY_MD_MD5;
121 size_t hlen = gcry_md_get_algo_dlen (halg);
122 unsigned char *hash;
123 gpg_error_t err;
124 char T[4];
126 T[0] = keyusage & 0xFF;
127 T[1] = (keyusage >> 8) & 0xFF;
128 T[2] = (keyusage >> 16) & 0xFF;
129 T[3] = (keyusage >> 24) & 0xFF;
131 err = gcry_md_open (&mdh, halg, GCRY_MD_FLAG_HMAC);
132 if (err != GPG_ERR_NO_ERROR)
134 shishi_error_printf (handle, "Libgcrypt md open failed");
135 shishi_error_set (handle, gpg_strerror (err));
136 return SHISHI_CRYPTO_INTERNAL_ERROR;
139 err = gcry_md_setkey (mdh, shishi_key_value (key), shishi_key_length (key));
140 if (err != GPG_ERR_NO_ERROR)
142 shishi_error_printf (handle, "Libgcrypt md setkey failed");
143 shishi_error_set (handle, gpg_strerror (err));
144 return SHISHI_CRYPTO_INTERNAL_ERROR;
147 gcry_md_write (mdh, RC4_HMAC_CKSUM_KEY_DERIVE_CONSTANT,
148 strlen (RC4_HMAC_CKSUM_KEY_DERIVE_CONSTANT) + 1);
150 err = gcry_md_open (&mdh2, halg, GCRY_MD_FLAG_HMAC);
151 if (err != GPG_ERR_NO_ERROR)
153 shishi_error_printf (handle, "Libgcrypt md open failed");
154 shishi_error_set (handle, gpg_strerror (err));
155 return SHISHI_CRYPTO_INTERNAL_ERROR;
158 err = gcry_md_setkey (mdh2, gcry_md_read (mdh, halg), hlen);
159 if (err != GPG_ERR_NO_ERROR)
161 shishi_error_printf (handle, "Libgcrypt md setkey failed");
162 shishi_error_set (handle, gpg_strerror (err));
163 return SHISHI_CRYPTO_INTERNAL_ERROR;
166 gcry_md_close (mdh);
168 gcry_md_write (mdh2, T, 4);
169 gcry_md_write (mdh2, in, inlen);
171 hash = gcry_md_read (mdh2, halg);
172 if (hash == NULL)
174 shishi_error_printf (handle, "Libgcrypt failed to compute hash");
175 return SHISHI_CRYPTO_INTERNAL_ERROR;
178 *outlen = hlen;
179 *out = xmemdup (hash, *outlen);
181 gcry_md_close (mdh2);
182 #else
183 struct hmac_md5_ctx ctx;
184 char Ksign[MD5_DIGEST_SIZE];
185 char T[4];
187 T[0] = keyusage & 0xFF;
188 T[1] = (keyusage >> 8) & 0xFF;
189 T[2] = (keyusage >> 16) & 0xFF;
190 T[3] = (keyusage >> 24) & 0xFF;
192 hmac_md5_set_key (&ctx, shishi_key_length (key), shishi_key_value (key));
193 hmac_md5_update (&ctx, strlen (RC4_HMAC_CKSUM_KEY_DERIVE_CONSTANT) + 1,
194 RC4_HMAC_CKSUM_KEY_DERIVE_CONSTANT);
195 hmac_md5_digest (&ctx, MD5_DIGEST_SIZE, Ksign);
197 hmac_md5_set_key (&ctx, MD5_DIGEST_SIZE, Ksign);
199 hmac_md5_update (&ctx, 4, T);
200 hmac_md5_update (&ctx, inlen, in);
202 *outlen = MD5_DIGEST_SIZE;
203 *out = xmalloc (*outlen);
205 hmac_md5_digest (&ctx, *outlen, *out);
206 #endif
207 #endif
208 return SHISHI_OK;
211 static int
212 rc4_hmac_random_to_key (Shishi * handle,
213 const char *random, size_t randomlen,
214 Shishi_key * outkey)
216 if (randomlen != shishi_key_length (outkey))
218 shishi_error_printf (handle, "RC4 random to key caller error");
219 return SHISHI_CRYPTO_ERROR;
222 shishi_key_value_set (outkey, random);
224 return SHISHI_OK;
227 static int
228 rc4_hmac_string_to_key (Shishi * handle,
229 const char *string,
230 size_t stringlen,
231 const char *salt,
232 size_t saltlen,
233 const char *parameter, Shishi_key * outkey)
235 char *tmp, *md;
236 size_t tmplen, i;
237 int rc;
239 tmplen = 2 * stringlen;
240 tmp = xmalloc (tmplen);
242 for (i = 0; i < stringlen; i++)
244 tmp[2 * i] = string[i];
245 tmp[2 * i + 1] = '\x0';
248 rc = shishi_md4 (handle, tmp, tmplen, &md);
249 free (tmp);
250 if (rc != SHISHI_OK)
251 return rc;
253 shishi_key_value_set (outkey, md);
255 return SHISHI_OK;
258 cipherinfo rc4_hmac_info = {
259 SHISHI_RC4_HMAC,
260 "rc4-hmac",
266 SHISHI_RC4_HMAC_MD5,
267 rc4_hmac_random_to_key,
268 rc4_hmac_string_to_key,
269 rc4_hmac_encrypt,
270 rc4_hmac_decrypt
273 cipherinfo rc4_hmac_exp_info = {
274 SHISHI_RC4_HMAC_EXP,
275 "rc4-hmac-exp",
281 SHISHI_RC4_HMAC_MD5,
282 rc4_hmac_random_to_key,
283 rc4_hmac_string_to_key,
284 rc4_hmac_exp_encrypt,
285 rc4_hmac_exp_decrypt
288 checksuminfo rc4_hmac_md5_info = {
289 SHISHI_RC4_HMAC_MD5,
290 "rc4-hmac-md5",
292 rc4_hmac_md5_checksum