17c478bd9Sstevel@tonic-gate /*
2*c54c769dSwillf * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate #include <etypes.h>
77c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
87c478bd9Sstevel@tonic-gate #include <security/pkcs11.h>
97c478bd9Sstevel@tonic-gate
107c478bd9Sstevel@tonic-gate /*
117c478bd9Sstevel@tonic-gate * get_algo
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * This routine provides a mapping from Kerberos encryption
147c478bd9Sstevel@tonic-gate * and hash types to PKCS#11 encryption and hash types.
157c478bd9Sstevel@tonic-gate */
167c478bd9Sstevel@tonic-gate CK_RV
get_algo(krb5_enctype etype,KRB5_MECH_TO_PKCS * algos)177c478bd9Sstevel@tonic-gate get_algo(krb5_enctype etype, KRB5_MECH_TO_PKCS *algos)
187c478bd9Sstevel@tonic-gate {
197c478bd9Sstevel@tonic-gate switch (etype) {
207c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_CRC:
217c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES_CBC;
227c478bd9Sstevel@tonic-gate algos->hash_algo = 0;
237c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
247c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR;
257c478bd9Sstevel@tonic-gate return (CKR_OK);
267c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_MD5:
277c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES_CBC;
287c478bd9Sstevel@tonic-gate algos->hash_algo = CKM_MD5;
297c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
307c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR | USE_HASH;
317c478bd9Sstevel@tonic-gate return (CKR_OK);
327c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_RAW:
337c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES_CBC;
347c478bd9Sstevel@tonic-gate algos->hash_algo = 0;
357c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
367c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR;
377c478bd9Sstevel@tonic-gate return (CKR_OK);
387c478bd9Sstevel@tonic-gate case ENCTYPE_DES_HMAC_SHA1:
397c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES_CBC;
407c478bd9Sstevel@tonic-gate algos->hash_algo = CKM_SHA_1_HMAC;
417c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
427c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR | USE_HASH;
437c478bd9Sstevel@tonic-gate return (CKR_OK);
447c478bd9Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA1:
457c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES3_CBC;
467c478bd9Sstevel@tonic-gate algos->hash_algo = CKM_SHA_1_HMAC;
477c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
487c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR | USE_HASH;
497c478bd9Sstevel@tonic-gate return (CKR_OK);
507c478bd9Sstevel@tonic-gate case ENCTYPE_DES3_CBC_RAW:
517c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_DES3_CBC;
527c478bd9Sstevel@tonic-gate algos->hash_algo = 0;
537c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
547c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR;
557c478bd9Sstevel@tonic-gate return (CKR_OK);
567c478bd9Sstevel@tonic-gate case ENCTYPE_ARCFOUR_HMAC:
577c478bd9Sstevel@tonic-gate case ENCTYPE_ARCFOUR_HMAC_EXP:
587c478bd9Sstevel@tonic-gate algos->enc_algo = CKM_RC4;
597c478bd9Sstevel@tonic-gate algos->hash_algo = CKM_MD5_HMAC;
607c478bd9Sstevel@tonic-gate algos->str2key_algo = 0;
617c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR;
627c478bd9Sstevel@tonic-gate return (CKR_OK);
637c478bd9Sstevel@tonic-gate case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
647c478bd9Sstevel@tonic-gate case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
65*c54c769dSwillf algos->enc_algo = CKM_AES_CBC;
667c478bd9Sstevel@tonic-gate algos->hash_algo = CKM_SHA_1_HMAC;
677c478bd9Sstevel@tonic-gate algos->str2key_algo = CKM_PKCS5_PBKD2;
687c478bd9Sstevel@tonic-gate algos->flags = USE_ENCR;
697c478bd9Sstevel@tonic-gate return (CKR_OK);
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate * get_key_type
767c478bd9Sstevel@tonic-gate *
777c478bd9Sstevel@tonic-gate * map Kerberos key types to PKCS#11 key type values.
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate CK_RV
get_key_type(krb5_enctype etype,CK_KEY_TYPE * keyType)807c478bd9Sstevel@tonic-gate get_key_type(krb5_enctype etype, CK_KEY_TYPE *keyType)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate switch (etype) {
837c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_CRC:
847c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_MD5:
857c478bd9Sstevel@tonic-gate case ENCTYPE_DES_CBC_RAW:
867c478bd9Sstevel@tonic-gate case ENCTYPE_DES_HMAC_SHA1:
877c478bd9Sstevel@tonic-gate *keyType = CKK_DES;
887c478bd9Sstevel@tonic-gate return (CKR_OK);
897c478bd9Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA1:
907c478bd9Sstevel@tonic-gate case ENCTYPE_DES3_CBC_RAW:
917c478bd9Sstevel@tonic-gate *keyType = CKK_DES3;
927c478bd9Sstevel@tonic-gate return (CKR_OK);
937c478bd9Sstevel@tonic-gate case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
947c478bd9Sstevel@tonic-gate case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
957c478bd9Sstevel@tonic-gate *keyType = CKK_AES;
967c478bd9Sstevel@tonic-gate return (CKR_OK);
977c478bd9Sstevel@tonic-gate case ENCTYPE_ARCFOUR_HMAC:
987c478bd9Sstevel@tonic-gate case ENCTYPE_ARCFOUR_HMAC_EXP:
997c478bd9Sstevel@tonic-gate *keyType = CKK_RC4;
1007c478bd9Sstevel@tonic-gate return (CKR_OK);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate /* There's no appropriate error. Just return the general one */
1047c478bd9Sstevel@tonic-gate return (CKR_GENERAL_ERROR);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate * slot_supports_krb5
1097c478bd9Sstevel@tonic-gate *
1107c478bd9Sstevel@tonic-gate * Determine whether the PKCS#11 "slot" supports the necessary
1117c478bd9Sstevel@tonic-gate * crypto needed for Kerberos functionality.
1127c478bd9Sstevel@tonic-gate *
1137c478bd9Sstevel@tonic-gate * Return values:
1147c478bd9Sstevel@tonic-gate * TRUE = The given slot is OK for Kerberos
1157c478bd9Sstevel@tonic-gate * FALSE = Not ok, try something else.
1167c478bd9Sstevel@tonic-gate */
1177c478bd9Sstevel@tonic-gate krb5_error_code
slot_supports_krb5(CK_SLOT_ID_PTR slotid)1187c478bd9Sstevel@tonic-gate slot_supports_krb5(CK_SLOT_ID_PTR slotid)
1197c478bd9Sstevel@tonic-gate {
1207c478bd9Sstevel@tonic-gate int i;
1217c478bd9Sstevel@tonic-gate CK_MECHANISM_INFO info;
1227c478bd9Sstevel@tonic-gate CK_RV rv;
1237c478bd9Sstevel@tonic-gate int enctypes_found = 0;
1247c478bd9Sstevel@tonic-gate KRB5_MECH_TO_PKCS algos;
1257c478bd9Sstevel@tonic-gate krb5_enctype tempenctype;
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate for (i = 0; i < krb5_enctypes_length; i++) {
1287c478bd9Sstevel@tonic-gate tempenctype = krb5_enctypes_list[i].etype;
1297c478bd9Sstevel@tonic-gate if ((rv = get_algo(tempenctype, &algos)) != CKR_OK) {
1307c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "Failed to get algorithm.");
1317c478bd9Sstevel@tonic-gate /*
1327c478bd9Sstevel@tonic-gate * If the algorithm is not available, disable
1337c478bd9Sstevel@tonic-gate * this enctype so kerberos doesn't try to use it
1347c478bd9Sstevel@tonic-gate * again.
1357c478bd9Sstevel@tonic-gate */
1367c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].etype = -1;
1377c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].in_string = "<unsupported>";
1387c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].out_string = "<unsupported>";
1397c478bd9Sstevel@tonic-gate continue;
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate if (ENC_DEFINED(algos)) {
1427c478bd9Sstevel@tonic-gate size_t keysize, keylength;
1437c478bd9Sstevel@tonic-gate rv = C_GetMechanismInfo(*slotid, algos.enc_algo, &info);
1447c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1457c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_ERR, "C_GetMechanismInfo failed "
1467c478bd9Sstevel@tonic-gate "for encr algorith %s: 0x%x\n",
1477c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].in_string,
1487c478bd9Sstevel@tonic-gate rv);
1497c478bd9Sstevel@tonic-gate return (FALSE);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate /*
1527c478bd9Sstevel@tonic-gate * If the encryption algorithm is supported,
1537c478bd9Sstevel@tonic-gate * make sure it supports the correct key sizes.
1547c478bd9Sstevel@tonic-gate * If not, disable this enctype and continue.
1557c478bd9Sstevel@tonic-gate */
156505d05c7Sgtb keysize = krb5_enctypes_list[i].enc->keybytes;
157505d05c7Sgtb keylength = krb5_enctypes_list[i].enc->keylength;
158505d05c7Sgtb
1597c478bd9Sstevel@tonic-gate if (keylength > info.ulMaxKeySize) {
1607c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].etype = -1;
1617c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].in_string =
1627c478bd9Sstevel@tonic-gate "<unsupported>";
1637c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].out_string =
1647c478bd9Sstevel@tonic-gate "<unsupported>";
1657c478bd9Sstevel@tonic-gate continue;
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate if (!(info.flags & (CKF_ENCRYPT|CKF_RNG)))
1687c478bd9Sstevel@tonic-gate return (FALSE);
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate if (HASH_DEFINED(algos)) {
1717c478bd9Sstevel@tonic-gate rv = C_GetMechanismInfo(*slotid, algos.hash_algo,
1727c478bd9Sstevel@tonic-gate &info);
1737c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1747c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_ERR, "C_GetMechanismInfo failed "
1757c478bd9Sstevel@tonic-gate "for hash algorithm %s: 0x%x\n",
1767c478bd9Sstevel@tonic-gate krb5_enctypes_list[i].in_string,
1777c478bd9Sstevel@tonic-gate rv);
1787c478bd9Sstevel@tonic-gate return (FALSE);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate if (!(info.flags & (CKF_DIGEST|CKF_SIGN|CKF_RNG)))
1817c478bd9Sstevel@tonic-gate return (FALSE);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate if (algos.str2key_algo != 0) {
1847c478bd9Sstevel@tonic-gate rv = C_GetMechanismInfo(*slotid, algos.str2key_algo,
1857c478bd9Sstevel@tonic-gate &info);
1867c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1877c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "C_GetMechanismInfo failed "
1887c478bd9Sstevel@tonic-gate "for str2key algorithm: 0x%x\n", rv);
1897c478bd9Sstevel@tonic-gate return (FALSE);
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate enctypes_found++;
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate /*
1957c478bd9Sstevel@tonic-gate * If NO enctypes were found to be supported, return FALSE.
1967c478bd9Sstevel@tonic-gate */
1977c478bd9Sstevel@tonic-gate if (!enctypes_found) {
1987c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR,
1997c478bd9Sstevel@tonic-gate "No crypto support available from PKCS#11.");
2007c478bd9Sstevel@tonic-gate return (FALSE);
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate return (TRUE);
2037c478bd9Sstevel@tonic-gate }
204