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