1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 
7 /*
8  * Copyright (C) 1998 by the FundsXpress, INC.
9  *
10  * All rights reserved.
11  *
12  * Export of this software from the United States of America may require
13  * a specific license from the United States Government.  It is the
14  * responsibility of any person or organization contemplating export to
15  * obtain such a license before exporting.
16  *
17  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18  * distribute this software and its documentation for any purpose and
19  * without fee is hereby granted, provided that the above copyright
20  * notice appear in all copies and that both that copyright notice and
21  * this permission notice appear in supporting documentation, and that
22  * the name of FundsXpress. not be used in advertising or publicity pertaining
23  * to distribution of the software without specific, written prior
24  * permission.  FundsXpress makes no representations about the suitability of
25  * this software for any purpose.  It is provided "as is" without express
26  * or implied warranty.
27  *
28  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31  */
32 
33 #ifdef	_KERNEL
34 /* Solaris Kerberos:
35  * we don't provide these functions to the kernel
36  */
37 #define	krb5int_des_string_to_key	NULL
38 #define	krb5_dk_string_to_key	NULL
39 #define	krb5int_arcfour_string_to_key	NULL
40 #endif	/* _KERNEL */
41 
42 #include <k5-int.h>
43 #include <enc_provider.h>
44 #include <hash_provider.h>
45 #include <etypes.h>
46 #include <old.h>
47 #include <raw.h>
48 
49 #include <dk.h>
50 #include <arcfour.h>
51 
52 /* these will be linear searched.  if they ever get big, a binary
53    search or hash table would be better, which means these would need
54    to be sorted.  An array would be more efficient, but that assumes
55    that the keytypes are all near each other.  I'd rather not make
56    that assumption. */
57 
58 struct krb5_keytypes krb5_enctypes_list[] = {
59     { ENCTYPE_DES_CBC_CRC,
60       "des-cbc-crc", "DES cbc mode with CRC-32",
61       &krb5int_enc_des, &krb5int_hash_crc32,
62       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
63       CKSUMTYPE_RSA_MD5,
64 #ifndef _KERNEL
65       krb5int_des_string_to_key,
66 #else
67       SUN_CKM_DES_CBC,
68       NULL,
69       CRYPTO_MECH_INVALID,
70       CRYPTO_MECH_INVALID
71 #endif /* !_KERNEL */
72 },
73     { ENCTYPE_DES_CBC_MD5,
74       "des-cbc-md5", "DES cbc mode with RSA-MD5",
75       &krb5int_enc_des, &krb5int_hash_md5,
76       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
77       CKSUMTYPE_RSA_MD5,
78 #ifndef _KERNEL
79       krb5int_des_string_to_key,
80 #else
81       SUN_CKM_DES_CBC,
82       SUN_CKM_MD5,
83       CRYPTO_MECH_INVALID,
84       CRYPTO_MECH_INVALID
85 #endif /* !_KERNEL */
86 },
87     { ENCTYPE_DES_CBC_MD5,
88       "des", "DES cbc mode with RSA-MD5", /* alias */
89       &krb5int_enc_des, &krb5int_hash_md5,
90       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
91       CKSUMTYPE_RSA_MD5,
92 #ifndef _KERNEL
93       krb5int_des_string_to_key,
94 #else
95       SUN_CKM_DES_CBC,
96       SUN_CKM_MD5,
97       CRYPTO_MECH_INVALID,
98       CRYPTO_MECH_INVALID
99 #endif /* _KERNEL */
100  },
101     { ENCTYPE_DES_CBC_RAW,
102       "des-cbc-raw", "DES cbc mode raw",
103       &krb5int_enc_des, NULL,
104       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
105       0,
106 #ifndef _KERNEL
107       krb5int_des_string_to_key,
108 #else
109       SUN_CKM_DES_CBC,
110       NULL,
111       CRYPTO_MECH_INVALID,
112       CRYPTO_MECH_INVALID
113 #endif /* !_KERNEL */
114 },
115 
116     { ENCTYPE_DES3_CBC_RAW,
117       "des3-cbc-raw", "Triple DES cbc mode raw",
118       &krb5int_enc_des3, NULL,
119       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
120       0,
121 #ifndef _KERNEL
122       krb5int_dk_string_to_key,
123 #else
124       SUN_CKM_DES3_CBC,
125       NULL,
126       CRYPTO_MECH_INVALID,
127       CRYPTO_MECH_INVALID
128 #endif /* !_KERNEL */
129 },
130 
131     { ENCTYPE_DES3_CBC_SHA1,
132       "des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
133       &krb5int_enc_des3, &krb5int_hash_sha1,
134       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
135       CKSUMTYPE_HMAC_SHA1_DES3,
136 #ifndef _KERNEL
137       krb5int_dk_string_to_key,
138 #else
139       SUN_CKM_DES3_CBC,
140       SUN_CKM_SHA1_HMAC,
141       CRYPTO_MECH_INVALID,
142       CRYPTO_MECH_INVALID
143 #endif
144  },
145     { ENCTYPE_DES3_CBC_SHA1,	/* alias */
146       "des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
147       &krb5int_enc_des3, &krb5int_hash_sha1,
148       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
149       CKSUMTYPE_HMAC_SHA1_DES3,
150 #ifndef _KERNEL
151       krb5int_dk_string_to_key,
152 #else
153       SUN_CKM_DES3_CBC,
154       SUN_CKM_SHA1_HMAC,
155       CRYPTO_MECH_INVALID,
156       CRYPTO_MECH_INVALID
157 #endif /* !_KERNEL */
158 },
159     { ENCTYPE_DES3_CBC_SHA1,	/* alias */
160       "des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
161       &krb5int_enc_des3, &krb5int_hash_sha1,
162       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
163       CKSUMTYPE_HMAC_SHA1_DES3,
164 #ifndef _KERNEL
165       krb5int_dk_string_to_key,
166 #else
167       SUN_CKM_DES3_CBC,
168       SUN_CKM_SHA1_HMAC,
169       CRYPTO_MECH_INVALID,
170       CRYPTO_MECH_INVALID
171 #endif /* !_KERNEL */
172 },
173       /* The des3-cbc-hmac-sha1-kd is the official enctype associated with
174        * 3DES/SHA1 in draft-ietf-krb-wg-crypto-00.txt
175        */
176     { ENCTYPE_DES3_CBC_SHA1,	/* alias */
177       "des3-cbc-hmac-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
178       &krb5int_enc_des3, &krb5int_hash_sha1,
179       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
180       CKSUMTYPE_HMAC_SHA1_DES3,
181 #ifndef _KERNEL
182       krb5int_dk_string_to_key,
183 #else
184       SUN_CKM_DES3_CBC,
185       SUN_CKM_SHA1_HMAC,
186       CRYPTO_MECH_INVALID,
187       CRYPTO_MECH_INVALID
188 #endif /* !_KERNEL */
189 },
190 
191     { ENCTYPE_DES_HMAC_SHA1,
192       "des-hmac-sha1", "DES with HMAC/sha1",
193       &krb5int_enc_des, &krb5int_hash_sha1,
194       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
195       0,
196 #ifndef _KERNEL
197       krb5int_dk_string_to_key,
198 #else
199       SUN_CKM_DES_CBC,
200       SUN_CKM_SHA1_HMAC,
201       CRYPTO_MECH_INVALID,
202       CRYPTO_MECH_INVALID
203 #endif /* !_KERNEL */
204 },
205     { ENCTYPE_ARCFOUR_HMAC,
206       "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
207       &krb5int_hash_md5,
208 krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
209       krb5_arcfour_decrypt,
210 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
211 #ifndef _KERNEL
212 	krb5int_arcfour_string_to_key,
213 #else
214       SUN_CKM_RC4,
215       SUN_CKM_MD5_HMAC,
216       CRYPTO_MECH_INVALID,
217       CRYPTO_MECH_INVALID
218 #endif /* !_KERNEL */
219     },
220     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
221       "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
222       &krb5int_hash_md5,
223       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
224       krb5_arcfour_decrypt,
225 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
226 #ifndef _KERNEL
227 	krb5int_arcfour_string_to_key,
228 #else
229       SUN_CKM_RC4,
230       SUN_CKM_MD5_HMAC,
231       CRYPTO_MECH_INVALID,
232       CRYPTO_MECH_INVALID
233 #endif /* !_KERNEL */
234     },
235     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
236       "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
237       &krb5int_hash_md5,
238       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
239       krb5_arcfour_decrypt,
240 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
241 #ifndef _KERNEL
242 	krb5int_arcfour_string_to_key,
243 #else
244       SUN_CKM_RC4,
245       SUN_CKM_MD5_HMAC,
246       CRYPTO_MECH_INVALID,
247       CRYPTO_MECH_INVALID
248 #endif /* !_KERNEL */
249     },
250     { ENCTYPE_ARCFOUR_HMAC_EXP,
251 	"arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5",
252 	&krb5int_enc_arcfour,
253 	&krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
254 	krb5_arcfour_decrypt,
255 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
256 #ifndef _KERNEL
257 	krb5int_arcfour_string_to_key,
258 #else
259       SUN_CKM_RC4,
260       SUN_CKM_MD5_HMAC,
261       CRYPTO_MECH_INVALID,
262       CRYPTO_MECH_INVALID
263 #endif /* !_KERNEL */
264     },
265     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
266       "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
267       &krb5int_enc_arcfour,
268       &krb5int_hash_md5,
269       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
270       krb5_arcfour_decrypt,
271 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
272 #ifndef _KERNEL
273 	krb5int_arcfour_string_to_key,
274 #else
275       SUN_CKM_RC4,
276       SUN_CKM_MD5_HMAC,
277       CRYPTO_MECH_INVALID,
278       CRYPTO_MECH_INVALID
279 #endif /* !_KERNEL */
280     },
281     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
282       "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
283       &krb5int_enc_arcfour,
284       &krb5int_hash_md5,
285       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
286       krb5_arcfour_decrypt,
287 	CKSUMTYPE_HMAC_MD5_ARCFOUR,
288 #ifndef _KERNEL
289 	krb5int_arcfour_string_to_key,
290 #else
291       SUN_CKM_RC4,
292       SUN_CKM_MD5_HMAC,
293       CRYPTO_MECH_INVALID,
294       CRYPTO_MECH_INVALID
295 #endif /* !_KERNEL */
296     },
297 
298     /*
299      * Note, all AES enctypes must use SUN_CKM_AES_CBC.  See aes_provider.c for
300      * more info.
301      */
302     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
303       "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
304       &krb5int_enc_aes128, &krb5int_hash_sha1,
305       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
306       CKSUMTYPE_HMAC_SHA1_96_AES128,
307 #ifndef _KERNEL
308       krb5int_aes_string_to_key,
309 #else
310       SUN_CKM_AES_CBC,
311       SUN_CKM_SHA1_HMAC,
312       CRYPTO_MECH_INVALID,
313       CRYPTO_MECH_INVALID
314 #endif /* !_KERNEL */
315     },
316     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
317 	"aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
318 	&krb5int_enc_aes128, &krb5int_hash_sha1,
319 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
320 	CKSUMTYPE_HMAC_SHA1_96_AES128,
321 #ifndef _KERNEL
322 	krb5int_aes_string_to_key,
323 #else
324       SUN_CKM_AES_CBC,
325       SUN_CKM_SHA1_HMAC,
326       CRYPTO_MECH_INVALID,
327       CRYPTO_MECH_INVALID
328 #endif /* !_KERNEL */
329     },
330     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
331       "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
332       &krb5int_enc_aes256, &krb5int_hash_sha1,
333       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
334       CKSUMTYPE_HMAC_SHA1_96_AES256,
335 #ifndef _KERNEL
336       krb5int_aes_string_to_key,
337 #else
338       SUN_CKM_AES_CBC,
339       SUN_CKM_SHA1_HMAC,
340       CRYPTO_MECH_INVALID,
341       CRYPTO_MECH_INVALID
342 #endif /* !_KERNEL */
343     },
344     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
345 	"aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
346 	&krb5int_enc_aes256, &krb5int_hash_sha1,
347 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
348 	CKSUMTYPE_HMAC_SHA1_96_AES256,
349 #ifndef _KERNEL
350 	krb5int_aes_string_to_key,
351 #else
352       SUN_CKM_AES_CBC,
353       SUN_CKM_SHA1_HMAC,
354       CRYPTO_MECH_INVALID,
355       CRYPTO_MECH_INVALID
356 #endif /* !_KERNEL */
357     },
358 };
359 
360 const int krb5_enctypes_length =
361 sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes);
362 
363 #ifdef _KERNEL
364 
365 /*
366  * Routine to pre-fetch the mechanism types from KEF so
367  * we dont keep doing this step later.
368  */
369 void
setup_kef_keytypes()370 setup_kef_keytypes()
371 {
372 	int i;
373 	struct krb5_keytypes *kt;
374 
375 	for (i=0; i<krb5_enctypes_length; i++) {
376 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
377 		if (kt->kef_cipher_mt == CRYPTO_MECH_INVALID &&
378 		    kt->mt_e_name != NULL) {
379 			krb5_enctypes_list[i].kef_cipher_mt =
380 				crypto_mech2id(kt->mt_e_name);
381 		}
382 
383 		if (kt->kef_hash_mt == CRYPTO_MECH_INVALID &&
384 		    kt->mt_h_name != NULL) {
385 			krb5_enctypes_list[i].kef_hash_mt =
386 				crypto_mech2id(kt->mt_h_name);
387 		}
388 		KRB5_LOG1(KRB5_INFO, "setup_kef_keytypes(): %s ==> %ld",
389 			kt->mt_e_name,
390 			(ulong_t) krb5_enctypes_list[i].kef_cipher_mt);
391 	}
392 }
393 
394 /*ARGSUSED*/
395 crypto_mech_type_t
get_cipher_mech_type(krb5_context context,krb5_keyblock * key)396 get_cipher_mech_type(krb5_context context, krb5_keyblock *key)
397 {
398 	int i;
399 	struct krb5_keytypes *kt;
400 
401 	if (key == NULL)
402 		return (CRYPTO_MECH_INVALID);
403 
404 	for (i=0; i<krb5_enctypes_length; i++) {
405 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
406 		if (kt->etype == key->enctype) {
407 			KRB5_LOG1(KRB5_INFO, "get_cipher_mech_type() "
408 				"found %s %ld",
409 				kt->mt_e_name,
410 				(ulong_t) kt->kef_cipher_mt);
411 			return (kt->kef_cipher_mt);
412 		}
413 	}
414 	return (CRYPTO_MECH_INVALID);
415 }
416 
417 /*ARGSUSED*/
418 crypto_mech_type_t
get_hash_mech_type(krb5_context context,krb5_keyblock * key)419 get_hash_mech_type(krb5_context context, krb5_keyblock *key)
420 {
421 	int i;
422 	struct krb5_keytypes *kt;
423 
424 	if (key == NULL)
425 		return (CRYPTO_MECH_INVALID);
426 
427 	for (i=0; i<krb5_enctypes_length; i++) {
428 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
429 		if (kt->etype == key->enctype) {
430 			KRB5_LOG1(KRB5_INFO, "get_hash_mech_type() "
431 				"found %s %ld",
432 				kt->mt_h_name,
433 				(ulong_t) kt->kef_hash_mt);
434 			return (kt->kef_hash_mt);
435 		}
436 	}
437 	return (CRYPTO_MECH_INVALID);
438 }
439 
440 #endif /* _KERNEL */
441