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
58struct 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,
208krb5_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
360const int krb5_enctypes_length =
361sizeof(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 */
369void
370setup_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*/
395crypto_mech_type_t
396get_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*/
418crypto_mech_type_t
419get_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