8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_krb5 / crypto / pkcs11slot.c
blob419298b237a821583a00a0c0c49fdda233fdd57b
1 /*
2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 #pragma ident "%Z%%M% %I% %E% SMI"
8 #include <etypes.h>
9 #include <security/cryptoki.h>
10 #include <security/pkcs11.h>
13 * get_algo
15 * This routine provides a mapping from Kerberos encryption
16 * and hash types to PKCS#11 encryption and hash types.
18 CK_RV
19 get_algo(krb5_enctype etype, KRB5_MECH_TO_PKCS *algos)
21 switch (etype) {
22 case ENCTYPE_DES_CBC_CRC:
23 algos->enc_algo = CKM_DES_CBC;
24 algos->hash_algo = 0;
25 algos->str2key_algo = 0;
26 algos->flags = USE_ENCR;
27 return (CKR_OK);
28 case ENCTYPE_DES_CBC_MD5:
29 algos->enc_algo = CKM_DES_CBC;
30 algos->hash_algo = CKM_MD5;
31 algos->str2key_algo = 0;
32 algos->flags = USE_ENCR | USE_HASH;
33 return (CKR_OK);
34 case ENCTYPE_DES_CBC_RAW:
35 algos->enc_algo = CKM_DES_CBC;
36 algos->hash_algo = 0;
37 algos->str2key_algo = 0;
38 algos->flags = USE_ENCR;
39 return (CKR_OK);
40 case ENCTYPE_DES_HMAC_SHA1:
41 algos->enc_algo = CKM_DES_CBC;
42 algos->hash_algo = CKM_SHA_1_HMAC;
43 algos->str2key_algo = 0;
44 algos->flags = USE_ENCR | USE_HASH;
45 return (CKR_OK);
46 case ENCTYPE_DES3_CBC_SHA1:
47 algos->enc_algo = CKM_DES3_CBC;
48 algos->hash_algo = CKM_SHA_1_HMAC;
49 algos->str2key_algo = 0;
50 algos->flags = USE_ENCR | USE_HASH;
51 return (CKR_OK);
52 case ENCTYPE_DES3_CBC_RAW:
53 algos->enc_algo = CKM_DES3_CBC;
54 algos->hash_algo = 0;
55 algos->str2key_algo = 0;
56 algos->flags = USE_ENCR;
57 return (CKR_OK);
58 case ENCTYPE_ARCFOUR_HMAC:
59 case ENCTYPE_ARCFOUR_HMAC_EXP:
60 algos->enc_algo = CKM_RC4;
61 algos->hash_algo = CKM_MD5_HMAC;
62 algos->str2key_algo = 0;
63 algos->flags = USE_ENCR;
64 return (CKR_OK);
65 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
66 case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
67 algos->enc_algo = CKM_AES_CBC;
68 algos->hash_algo = CKM_SHA_1_HMAC;
69 algos->str2key_algo = CKM_PKCS5_PBKD2;
70 algos->flags = USE_ENCR;
71 return (CKR_OK);
73 return (CKR_MECHANISM_INVALID);
77 * get_key_type
79 * map Kerberos key types to PKCS#11 key type values.
81 CK_RV
82 get_key_type(krb5_enctype etype, CK_KEY_TYPE *keyType)
84 switch (etype) {
85 case ENCTYPE_DES_CBC_CRC:
86 case ENCTYPE_DES_CBC_MD5:
87 case ENCTYPE_DES_CBC_RAW:
88 case ENCTYPE_DES_HMAC_SHA1:
89 *keyType = CKK_DES;
90 return (CKR_OK);
91 case ENCTYPE_DES3_CBC_SHA1:
92 case ENCTYPE_DES3_CBC_RAW:
93 *keyType = CKK_DES3;
94 return (CKR_OK);
95 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
96 case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
97 *keyType = CKK_AES;
98 return (CKR_OK);
99 case ENCTYPE_ARCFOUR_HMAC:
100 case ENCTYPE_ARCFOUR_HMAC_EXP:
101 *keyType = CKK_RC4;
102 return (CKR_OK);
105 /* There's no appropriate error. Just return the general one */
106 return (CKR_GENERAL_ERROR);
110 * slot_supports_krb5
112 * Determine whether the PKCS#11 "slot" supports the necessary
113 * crypto needed for Kerberos functionality.
115 * Return values:
116 * TRUE = The given slot is OK for Kerberos
117 * FALSE = Not ok, try something else.
119 krb5_error_code
120 slot_supports_krb5(CK_SLOT_ID_PTR slotid)
122 int i;
123 CK_MECHANISM_INFO info;
124 CK_RV rv;
125 int enctypes_found = 0;
126 KRB5_MECH_TO_PKCS algos;
127 krb5_enctype tempenctype;
129 for (i = 0; i < krb5_enctypes_length; i++) {
130 tempenctype = krb5_enctypes_list[i].etype;
131 if ((rv = get_algo(tempenctype, &algos)) != CKR_OK) {
132 KRB5_LOG0(KRB5_ERR, "Failed to get algorithm.");
134 * If the algorithm is not available, disable
135 * this enctype so kerberos doesn't try to use it
136 * again.
138 krb5_enctypes_list[i].etype = -1;
139 krb5_enctypes_list[i].in_string = "<unsupported>";
140 krb5_enctypes_list[i].out_string = "<unsupported>";
141 continue;
143 if (ENC_DEFINED(algos)) {
144 size_t keysize, keylength;
145 rv = C_GetMechanismInfo(*slotid, algos.enc_algo, &info);
146 if (rv != CKR_OK) {
147 KRB5_LOG1(KRB5_ERR, "C_GetMechanismInfo failed "
148 "for encr algorith %s: 0x%x\n",
149 krb5_enctypes_list[i].in_string,
150 rv);
151 return (FALSE);
154 * If the encryption algorithm is supported,
155 * make sure it supports the correct key sizes.
156 * If not, disable this enctype and continue.
158 keysize = krb5_enctypes_list[i].enc->keybytes;
159 keylength = krb5_enctypes_list[i].enc->keylength;
161 if (keylength > info.ulMaxKeySize) {
162 krb5_enctypes_list[i].etype = -1;
163 krb5_enctypes_list[i].in_string =
164 "<unsupported>";
165 krb5_enctypes_list[i].out_string =
166 "<unsupported>";
167 continue;
169 if (!(info.flags & (CKF_ENCRYPT|CKF_RNG)))
170 return (FALSE);
172 if (HASH_DEFINED(algos)) {
173 rv = C_GetMechanismInfo(*slotid, algos.hash_algo,
174 &info);
175 if (rv != CKR_OK) {
176 KRB5_LOG1(KRB5_ERR, "C_GetMechanismInfo failed "
177 "for hash algorithm %s: 0x%x\n",
178 krb5_enctypes_list[i].in_string,
179 rv);
180 return (FALSE);
182 if (!(info.flags & (CKF_DIGEST|CKF_SIGN|CKF_RNG)))
183 return (FALSE);
185 if (algos.str2key_algo != 0) {
186 rv = C_GetMechanismInfo(*slotid, algos.str2key_algo,
187 &info);
188 if (rv != CKR_OK) {
189 KRB5_LOG(KRB5_ERR, "C_GetMechanismInfo failed "
190 "for str2key algorithm: 0x%x\n", rv);
191 return (FALSE);
194 enctypes_found++;
197 * If NO enctypes were found to be supported, return FALSE.
199 if (!enctypes_found) {
200 KRB5_LOG0(KRB5_ERR,
201 "No crypto support available from PKCS#11.");
202 return (FALSE);
204 return (TRUE);