xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright 2004 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     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
295 	"aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
296 	&krb5int_enc_aes128, &krb5_hash_sha1,
297 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
298 	CKSUMTYPE_HMAC_SHA1_96_AES128,
299 #ifndef _KERNEL
300 	krb5int_aes_string_to_key,
301 #else
302       SUN_CKM_AES_ECB,
303       SUN_CKM_SHA1_HMAC,
304       CRYPTO_MECH_INVALID,
305       CRYPTO_MECH_INVALID
306 #endif /* !_KERNEL */
307     },
308     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
309 	"aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
310 	&krb5int_enc_aes128, &krb5_hash_sha1,
311 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
312 	CKSUMTYPE_HMAC_SHA1_96_AES128,
313 #ifndef _KERNEL
314 	krb5int_aes_string_to_key,
315 #else
316       SUN_CKM_AES_ECB,
317       SUN_CKM_SHA1_HMAC,
318       CRYPTO_MECH_INVALID,
319       CRYPTO_MECH_INVALID
320 #endif /* !_KERNEL */
321     },
322     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
323 	"aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
324 	&krb5int_enc_aes256, &krb5_hash_sha1,
325 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
326 	CKSUMTYPE_HMAC_SHA1_96_AES256,
327 #ifndef _KERNEL
328 	krb5int_aes_string_to_key,
329 #else
330       SUN_CKM_AES_ECB,
331       SUN_CKM_SHA1_HMAC,
332       CRYPTO_MECH_INVALID,
333       CRYPTO_MECH_INVALID
334 #endif /* !_KERNEL */
335     },
336     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
337 	"aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
338 	&krb5int_enc_aes256, &krb5_hash_sha1,
339 	krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
340 	CKSUMTYPE_HMAC_SHA1_96_AES256,
341 #ifndef _KERNEL
342 	krb5int_aes_string_to_key,
343 #else
344       SUN_CKM_AES_ECB,
345       SUN_CKM_SHA1_HMAC,
346       CRYPTO_MECH_INVALID,
347       CRYPTO_MECH_INVALID
348 #endif /* !_KERNEL */
349     },
350 };
351 
352 const int krb5_enctypes_length =
353 sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes);
354 
355 #ifdef _KERNEL
356 
357 /*
358  * Routine to pre-fetch the mechanism types from KEF so
359  * we dont keep doing this step later.
360  */
361 void
362 setup_kef_keytypes()
363 {
364 	int i;
365 	struct krb5_keytypes *kt;
366 
367 	for (i=0; i<krb5_enctypes_length; i++) {
368 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
369 		if (kt->kef_cipher_mt == CRYPTO_MECH_INVALID &&
370 		    kt->mt_e_name != NULL) {
371 			krb5_enctypes_list[i].kef_cipher_mt =
372 				crypto_mech2id(kt->mt_e_name);
373 		}
374 
375 		if (kt->kef_hash_mt == CRYPTO_MECH_INVALID &&
376 		    kt->mt_h_name != NULL) {
377 			krb5_enctypes_list[i].kef_hash_mt =
378 				crypto_mech2id(kt->mt_h_name);
379 		}
380 		KRB5_LOG1(KRB5_INFO, "setup_kef_keytypes(): %s ==> %ld",
381 			kt->mt_e_name,
382 			(ulong_t) krb5_enctypes_list[i].kef_cipher_mt);
383 	}
384 }
385 
386 /*ARGSUSED*/
387 crypto_mech_type_t
388 get_cipher_mech_type(krb5_context context, krb5_keyblock *key)
389 {
390 	int i;
391 	struct krb5_keytypes *kt;
392 
393 	if (key == NULL)
394 		return (CRYPTO_MECH_INVALID);
395 
396 	for (i=0; i<krb5_enctypes_length; i++) {
397 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
398 		if (kt->etype == key->enctype) {
399 			KRB5_LOG1(KRB5_INFO, "get_cipher_mech_type() "
400 				"found %s %ld",
401 				kt->mt_e_name,
402 				(ulong_t) kt->kef_cipher_mt);
403 			return (kt->kef_cipher_mt);
404 		}
405 	}
406 	return (CRYPTO_MECH_INVALID);
407 }
408 
409 /*ARGSUSED*/
410 crypto_mech_type_t
411 get_hash_mech_type(krb5_context context, krb5_keyblock *key)
412 {
413 	int i;
414 	struct krb5_keytypes *kt;
415 
416 	if (key == NULL)
417 		return (CRYPTO_MECH_INVALID);
418 
419 	for (i=0; i<krb5_enctypes_length; i++) {
420 		kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
421 		if (kt->etype == key->enctype) {
422 			KRB5_LOG1(KRB5_INFO, "get_hash_mech_type() "
423 				"found %s %ld",
424 				kt->mt_h_name,
425 				(ulong_t) kt->kef_hash_mt);
426 			return (kt->kef_hash_mt);
427 		}
428 	}
429 	return (CRYPTO_MECH_INVALID);
430 }
431 
432 #endif /* _KERNEL */
433