1 /* $NetBSD: crypto-arcfour.c,v 1.1.1.2 2014/04/24 12:45:49 pettai Exp $ */
4 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include "krb5_locl.h"
42 static struct _krb5_key_type keytype_arcfour
= {
43 ENCTYPE_ARCFOUR_HMAC_MD5
,
47 sizeof(struct _krb5_evp_schedule
),
57 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
61 _krb5_HMAC_MD5_checksum(krb5_context context
,
62 struct _krb5_key_data
*key
,
69 struct _krb5_checksum_type
*c
= _krb5_find_checksum (CKSUMTYPE_RSA_MD5
);
70 const char signature
[] = "signaturekey";
72 struct _krb5_key_data ksign
;
75 unsigned char tmp
[16];
76 unsigned char ksign_c_data
[16];
79 m
= EVP_MD_CTX_create();
81 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
84 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
85 ksign_c
.checksum
.data
= ksign_c_data
;
86 ret
= _krb5_internal_hmac(context
, c
, signature
, sizeof(signature
),
89 EVP_MD_CTX_destroy(m
);
93 kb
.keyvalue
= ksign_c
.checksum
;
94 EVP_DigestInit_ex(m
, EVP_md5(), NULL
);
95 t
[0] = (usage
>> 0) & 0xFF;
96 t
[1] = (usage
>> 8) & 0xFF;
97 t
[2] = (usage
>> 16) & 0xFF;
98 t
[3] = (usage
>> 24) & 0xFF;
99 EVP_DigestUpdate(m
, t
, 4);
100 EVP_DigestUpdate(m
, data
, len
);
101 EVP_DigestFinal_ex (m
, tmp
, NULL
);
102 EVP_MD_CTX_destroy(m
);
104 ret
= _krb5_internal_hmac(context
, c
, tmp
, sizeof(tmp
), 0, &ksign
, result
);
110 struct _krb5_checksum_type _krb5_checksum_hmac_md5
= {
116 _krb5_HMAC_MD5_checksum
,
121 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
123 * warning: not for small children
126 static krb5_error_code
127 ARCFOUR_subencrypt(krb5_context context
,
128 struct _krb5_key_data
*key
,
135 struct _krb5_checksum_type
*c
= _krb5_find_checksum (CKSUMTYPE_RSA_MD5
);
136 Checksum k1_c
, k2_c
, k3_c
, cksum
;
137 struct _krb5_key_data ke
;
140 unsigned char *cdata
= data
;
141 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
144 t
[0] = (usage
>> 0) & 0xFF;
145 t
[1] = (usage
>> 8) & 0xFF;
146 t
[2] = (usage
>> 16) & 0xFF;
147 t
[3] = (usage
>> 24) & 0xFF;
149 k1_c
.checksum
.length
= sizeof(k1_c_data
);
150 k1_c
.checksum
.data
= k1_c_data
;
152 ret
= _krb5_internal_hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
154 krb5_abortx(context
, "hmac failed");
156 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
158 k2_c
.checksum
.length
= sizeof(k2_c_data
);
159 k2_c
.checksum
.data
= k2_c_data
;
162 kb
.keyvalue
= k2_c
.checksum
;
164 cksum
.checksum
.length
= 16;
165 cksum
.checksum
.data
= data
;
167 ret
= _krb5_internal_hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
169 krb5_abortx(context
, "hmac failed");
172 kb
.keyvalue
= k1_c
.checksum
;
174 k3_c
.checksum
.length
= sizeof(k3_c_data
);
175 k3_c
.checksum
.data
= k3_c_data
;
177 ret
= _krb5_internal_hmac(NULL
, c
, data
, 16, 0, &ke
, &k3_c
);
179 krb5_abortx(context
, "hmac failed");
181 EVP_CIPHER_CTX_init(&ctx
);
183 EVP_CipherInit_ex(&ctx
, EVP_rc4(), NULL
, k3_c
.checksum
.data
, NULL
, 1);
184 EVP_Cipher(&ctx
, cdata
+ 16, cdata
+ 16, len
- 16);
185 EVP_CIPHER_CTX_cleanup(&ctx
);
187 memset (k1_c_data
, 0, sizeof(k1_c_data
));
188 memset (k2_c_data
, 0, sizeof(k2_c_data
));
189 memset (k3_c_data
, 0, sizeof(k3_c_data
));
193 static krb5_error_code
194 ARCFOUR_subdecrypt(krb5_context context
,
195 struct _krb5_key_data
*key
,
202 struct _krb5_checksum_type
*c
= _krb5_find_checksum (CKSUMTYPE_RSA_MD5
);
203 Checksum k1_c
, k2_c
, k3_c
, cksum
;
204 struct _krb5_key_data ke
;
207 unsigned char *cdata
= data
;
208 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
209 unsigned char cksum_data
[16];
212 t
[0] = (usage
>> 0) & 0xFF;
213 t
[1] = (usage
>> 8) & 0xFF;
214 t
[2] = (usage
>> 16) & 0xFF;
215 t
[3] = (usage
>> 24) & 0xFF;
217 k1_c
.checksum
.length
= sizeof(k1_c_data
);
218 k1_c
.checksum
.data
= k1_c_data
;
220 ret
= _krb5_internal_hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
222 krb5_abortx(context
, "hmac failed");
224 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
226 k2_c
.checksum
.length
= sizeof(k2_c_data
);
227 k2_c
.checksum
.data
= k2_c_data
;
230 kb
.keyvalue
= k1_c
.checksum
;
232 k3_c
.checksum
.length
= sizeof(k3_c_data
);
233 k3_c
.checksum
.data
= k3_c_data
;
235 ret
= _krb5_internal_hmac(NULL
, c
, cdata
, 16, 0, &ke
, &k3_c
);
237 krb5_abortx(context
, "hmac failed");
239 EVP_CIPHER_CTX_init(&ctx
);
240 EVP_CipherInit_ex(&ctx
, EVP_rc4(), NULL
, k3_c
.checksum
.data
, NULL
, 0);
241 EVP_Cipher(&ctx
, cdata
+ 16, cdata
+ 16, len
- 16);
242 EVP_CIPHER_CTX_cleanup(&ctx
);
245 kb
.keyvalue
= k2_c
.checksum
;
247 cksum
.checksum
.length
= 16;
248 cksum
.checksum
.data
= cksum_data
;
250 ret
= _krb5_internal_hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
252 krb5_abortx(context
, "hmac failed");
254 memset (k1_c_data
, 0, sizeof(k1_c_data
));
255 memset (k2_c_data
, 0, sizeof(k2_c_data
));
256 memset (k3_c_data
, 0, sizeof(k3_c_data
));
258 if (ct_memcmp (cksum
.checksum
.data
, data
, 16) != 0) {
259 krb5_clear_error_message (context
);
260 return KRB5KRB_AP_ERR_BAD_INTEGRITY
;
267 * convert the usage numbers used in
268 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
269 * draft-brezak-win2k-krb-rc4-hmac-04.txt
273 _krb5_usage2arcfour(krb5_context context
, unsigned *usage
)
276 case KRB5_KU_AS_REP_ENC_PART
: /* 3 */
279 case KRB5_KU_USAGE_SEAL
: /* 22 */
282 case KRB5_KU_USAGE_SIGN
: /* 23 */
285 case KRB5_KU_USAGE_SEQ
: /* 24 */
293 static krb5_error_code
294 ARCFOUR_encrypt(krb5_context context
,
295 struct _krb5_key_data
*key
,
298 krb5_boolean encryptp
,
303 unsigned keyusage
= usage
;
305 if((ret
= _krb5_usage2arcfour (context
, &keyusage
)) != 0)
309 return ARCFOUR_subencrypt (context
, key
, data
, len
, keyusage
, ivec
);
311 return ARCFOUR_subdecrypt (context
, key
, data
, len
, keyusage
, ivec
);
314 struct _krb5_encryption_type _krb5_enctype_arcfour_hmac_md5
= {
315 ETYPE_ARCFOUR_HMAC_MD5
,
321 &_krb5_checksum_hmac_md5
,
322 &_krb5_checksum_hmac_md5
,