2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <strings.h>
2N/A#include <cryptoutil.h>
2N/A#include <security/cryptoki.h>
2N/A#include <sys/crypto/common.h>
2N/A#include <arcfour/arcfour.h>
2N/A#include "softGlobal.h"
2N/A#include "softSession.h"
2N/A#include <aes/aes_impl.h>
2N/A#include <blowfish/blowfish_impl.h>
2N/A#include <des/des_impl.h>
2N/A#include <dsa/dsa_impl.h>
2N/A#include <ecc/ecc_impl.h>
2N/A#include <rsa/rsa_impl.h>
2N/A#include <sys/md5.h>
2N/A#include <sys/sha1.h>
2N/A#include <sys/sha2.h>
2N/A#include "softDH.h"
2N/A#include "softObject.h"
2N/A#include "softKeystore.h"
2N/A#include "softKeystoreUtil.h"
2N/A#include <sys/auxv.h>
2N/A#include <sys/auxv_SPARC.h>
2N/A#include <sys/auxv_386.h>
2N/A
2N/A
2N/A/*
2N/A * NOTE: If the order of this table is changed or if mechs are inserted
2N/A * or removed the _FIRST_MECH _LAST_MECH defines need to be updated.
2N/A * Care should also be take to group all mechs for a given algorithm together.
2N/A */
2N/Astatic CK_MECHANISM_TYPE soft_mechanisms[] = {
2N/A#define DES_FIRST_MECH 0
2N/A CKM_DES_CBC,
2N/A CKM_DES_CBC_PAD,
2N/A CKM_DES_ECB,
2N/A CKM_DES_KEY_GEN,
2N/A CKM_DES_MAC_GENERAL,
2N/A CKM_DES_MAC,
2N/A CKM_DES3_CBC,
2N/A CKM_DES3_CBC_PAD,
2N/A CKM_DES3_ECB,
2N/A CKM_DES2_KEY_GEN,
2N/A CKM_DES3_KEY_GEN,
2N/A#define DES_LAST_MECH 10
2N/A#define AES_FIRST_MECH 11
2N/A CKM_AES_CBC,
2N/A CKM_AES_CBC_PAD,
2N/A CKM_AES_CTR,
2N/A CKM_AES_ECB,
2N/A CKM_AES_KEY_GEN,
2N/A#define AES_LAST_MECH 15
2N/A CKM_BLOWFISH_CBC,
2N/A CKM_BLOWFISH_KEY_GEN,
2N/A#define SHA1_FIRST_MECH 18
2N/A CKM_SHA_1,
2N/A CKM_SHA_1_HMAC,
2N/A CKM_SHA_1_HMAC_GENERAL,
2N/A#define SHA1_LAST_MECH 20
2N/A#define SHA224_FIRST_MECH 21
2N/A CKM_SHA224,
2N/A CKM_SHA224_HMAC,
2N/A CKM_SHA224_HMAC_GENERAL,
2N/A CKM_SHA256,
2N/A CKM_SHA256_HMAC,
2N/A CKM_SHA256_HMAC_GENERAL,
2N/A#define SHA256_LAST_MECH 26
2N/A#define SHA384_FIRST_MECH 27
2N/A CKM_SHA384,
2N/A CKM_SHA384_HMAC,
2N/A CKM_SHA384_HMAC_GENERAL,
2N/A CKM_SHA512,
2N/A CKM_SHA512_HMAC,
2N/A CKM_SHA512_HMAC_GENERAL,
2N/A#define SHA512_LAST_MECH 32
2N/A CKM_SSL3_SHA1_MAC,
2N/A#define MD5_FIRST_MECH 34
2N/A CKM_MD5,
2N/A CKM_MD5_HMAC,
2N/A CKM_MD5_HMAC_GENERAL,
2N/A#define MD5_LAST_MECH 36
2N/A CKM_SSL3_MD5_MAC,
2N/A CKM_RC4,
2N/A CKM_RC4_KEY_GEN,
2N/A#define DSA_FIRST_MECH 40
2N/A CKM_DSA,
2N/A CKM_DSA_SHA1,
2N/A CKM_DSA_KEY_PAIR_GEN,
2N/A#define DSA_LAST_MECH 42
2N/A#define RSA_FIRST_MECH 43
2N/A CKM_RSA_PKCS,
2N/A CKM_RSA_PKCS_KEY_PAIR_GEN,
2N/A CKM_RSA_X_509,
2N/A CKM_MD5_RSA_PKCS,
2N/A CKM_SHA1_RSA_PKCS,
2N/A CKM_SHA224_RSA_PKCS,
2N/A CKM_SHA256_RSA_PKCS,
2N/A CKM_SHA384_RSA_PKCS,
2N/A CKM_SHA512_RSA_PKCS,
2N/A#define RSA_LAST_MECH 51
2N/A#define DH_FIRST_MECH 52
2N/A CKM_DH_PKCS_KEY_PAIR_GEN,
2N/A CKM_DH_PKCS_DERIVE,
2N/A#define DH_LAST_MECH 54
2N/A CKM_MD5_KEY_DERIVATION,
2N/A CKM_SHA1_KEY_DERIVATION,
2N/A CKM_SHA224_KEY_DERIVATION,
2N/A CKM_SHA256_KEY_DERIVATION,
2N/A CKM_SHA384_KEY_DERIVATION,
2N/A CKM_SHA512_KEY_DERIVATION,
2N/A CKM_PBE_SHA1_RC4_128,
2N/A CKM_PKCS5_PBKD2,
2N/A CKM_SSL3_PRE_MASTER_KEY_GEN,
2N/A CKM_TLS_PRE_MASTER_KEY_GEN,
2N/A CKM_SSL3_MASTER_KEY_DERIVE,
2N/A CKM_TLS_MASTER_KEY_DERIVE,
2N/A CKM_SSL3_MASTER_KEY_DERIVE_DH,
2N/A CKM_TLS_MASTER_KEY_DERIVE_DH,
2N/A CKM_SSL3_KEY_AND_MAC_DERIVE,
2N/A CKM_TLS_KEY_AND_MAC_DERIVE,
2N/A CKM_TLS_PRF,
2N/A#define EC_FIRST_MECH 71
2N/A CKM_EC_KEY_PAIR_GEN,
2N/A CKM_ECDSA,
2N/A CKM_ECDSA_SHA1,
2N/A CKM_ECDH1_DERIVE
2N/A#define EC_LAST_MECH 74
2N/A};
2N/A
2N/A/*
2N/A * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms.
2N/A * The index for this table is the same as the one above for the same
2N/A * mechanism.
2N/A * The minimum and maximum sizes of the key for the mechanism can be measured
2N/A * in bits or in bytes (i.e. mechanism-dependent). This table specifies the
2N/A * supported range of key sizes in bytes; unless noted as in bits.
2N/A */
2N/Astatic CK_MECHANISM_INFO soft_mechanism_info[] = {
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC */
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC_PAD */
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_ECB */
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_GENERATE}, /* CKM_DES_KEY_GEN */
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC_GENERAL */
2N/A {DES_MINBYTES, DES_MAXBYTES,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC */
2N/A {DES3_MINBYTES, DES3_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC */
2N/A {DES3_MINBYTES, DES3_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC_PAD */
2N/A {DES3_MINBYTES, DES3_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_ECB */
2N/A {DES2_MAXBYTES, DES2_MAXBYTES,
2N/A CKF_GENERATE}, /* CKM_DES2_KEY_GEN */
2N/A {DES3_MAXBYTES, DES3_MAXBYTES, /* CKK_DES3 only */
2N/A CKF_GENERATE}, /* CKM_DES3_KEY_GEN */
2N/A {AES_MINBYTES, AES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC */
2N/A {AES_MINBYTES, AES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC_PAD */
2N/A {AES_MINBYTES, AES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CTR */
2N/A {AES_MINBYTES, AES_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_ECB */
2N/A {AES_MINBYTES, AES_MAXBYTES,
2N/A CKF_GENERATE}, /* CKM_AES_KEY_GEN */
2N/A {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_WRAP|CKF_UNWRAP}, /* CKM_BLOWFISH_ECB */
2N/A {BLOWFISH_MINBYTES, BLOWFISH_MAXBYTES,
2N/A CKF_GENERATE}, /* CKM_BLOWFISH_KEY_GEN */
2N/A {0, 0, CKF_DIGEST}, /* CKM_SHA_1 */
2N/A {1, SHA1_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC */
2N/A {1, SHA1_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC_GENERAL */
2N/A {0, 0, CKF_DIGEST}, /* CKM_SHA224 */
2N/A {1, SHA256_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA224_HMAC */
2N/A {1, SHA256_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA224_HMAC_GENERAL */
2N/A {0, 0, CKF_DIGEST}, /* CKM_SHA256 */
2N/A {1, SHA256_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_HMAC */
2N/A {1, SHA256_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_HMAC_GENERAL */
2N/A {0, 0, CKF_DIGEST}, /* CKM_SHA384 */
2N/A {1, SHA512_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_HMAC */
2N/A {1, SHA512_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_HMAC_GENERAL */
2N/A {0, 0, CKF_DIGEST}, /* CKM_SHA512 */
2N/A {1, SHA512_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_HMAC */
2N/A {1, SHA512_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_HMAC_GENERAL */
2N/A {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_SHA1_MAC */
2N/A {0, 0, CKF_DIGEST}, /* CKM_MD5 */
2N/A {1, MD5_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC */
2N/A {1, MD5_HMAC_BLOCK_SIZE,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC_GENERAL */
2N/A {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_MD5_MAC */
2N/A {ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
2N/A CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */
2N/A {ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
2N/A CKF_GENERATE }, /* CKM_RC4_KEY_GEN */
2N/A {MIN_DSA_KEY_LEN_BITS, MAX_DSA_KEY_LEN_BITS,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_DSA */
2N/A {MIN_DSA_KEY_LEN_BITS, MAX_DSA_SHA1_KEY_LEN_BITS,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_DSA_SHA1 */
2N/A {MIN_DSA_KEY_LEN_BITS, MAX_DSA_KEY_LEN_BITS,
2N/A CKF_GENERATE_KEY_PAIR}, /* CKM_DSA_KEY_PAIR_GEN */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_SIGN|CKF_SIGN_RECOVER|
2N/A CKF_WRAP|CKF_UNWRAP|
2N/A CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_GENERATE_KEY_PAIR}, /* CKM_RSA_PKCS_KEY_PAIR_GEN; */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_ENCRYPT|CKF_DECRYPT|
2N/A CKF_SIGN|CKF_SIGN_RECOVER|
2N/A CKF_WRAP|CKF_UNWRAP|
2N/A CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_X_509 */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA1_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA224_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_RSA_PKCS */
2N/A {RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
2N/A CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_RSA_PKCS */
2N/A {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
2N/A CKF_GENERATE_KEY_PAIR}, /* CKM_DH_PKCS_KEY_PAIR_GEN */
2N/A {DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
2N/A CKF_DERIVE}, /* CKM_DH_PKCS_DERIVE; */
2N/A {1, MD5_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_MD5_KEY_DERIVATION */
2N/A {1, SHA1_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_SHA1_KEY_DERIVATION */
2N/A {1, SHA224_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_SHA224_KEY_DERIVATION */
2N/A {1, SHA256_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_SHA256_KEY_DERIVATION */
2N/A {1, SHA384_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_SHA384_KEY_DERIVATION */
2N/A {1, SHA512_DIGEST_LENGTH, CKF_DERIVE}, /* CKM_SHA512_KEY_DERIVATION */
2N/A {0, 0, CKF_GENERATE}, /* CKM_PBE_SHA1_RC4_128 */
2N/A {0, 0, CKF_GENERATE}, /* CKM_PKCS5_PBKD2 */
2N/A {48, 48, CKF_GENERATE}, /* CKM_SSL3_PRE_MASTER_KEY_GEN */
2N/A {48, 48, CKF_GENERATE}, /* CKM_TLS_PRE_MASTER_KEY_GEN */
2N/A {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE */
2N/A {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE */
2N/A {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE_DH */
2N/A {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE_DH */
2N/A {0, 0, CKF_DERIVE}, /* CKM_SSL3_KEY_AND_MAC_DERIVE */
2N/A {0, 0, CKF_DERIVE}, /* CKM_TLS_KEY_AND_MAC_DERIVE */
2N/A {0, 0, CKF_DERIVE}, /* CKM_TLS_PRF */
2N/A {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
2N/A {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
2N/A {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_SIGN|CKF_VERIFY},
2N/A {EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CKF_DERIVE}
2N/A};
2N/A
2N/A/*
2N/A * For those mechanisms that we have ISA hardware instructions for
2N/A * set the CKF_HW flag.
2N/A */
2N/Avoid
2N/Aupdate_mech_hw_flags(void)
2N/A{
2N/A uint_t ui = 0;
2N/A int m;
2N/A
2N/A (void) getisax(&ui, 1);
2N/A /* SPARC or Intel AES */
2N/A#ifdef __sparc
2N/A if (ui & (AV_SPARC_AES|AV_SPARC_FJAES)) {
2N/A#elif defined(__i386) || defined(__amd64)
2N/A if (ui & AV_386_AES) {
2N/A#endif
2N/A for (m = AES_FIRST_MECH; m <= AES_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A
2N/A#ifdef __sparc
2N/A if (ui & (AV_SPARC_DES|AV_SPARC_FJDES)) {
2N/A for (m = DES_FIRST_MECH; m <= DES_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A if (ui & AV_SPARC_MD5) {
2N/A for (m = MD5_FIRST_MECH; m <= MD5_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A if (ui & AV_SPARC_SHA1) {
2N/A for (m = SHA1_FIRST_MECH; m <= SHA1_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A if (ui & AV_SPARC_SHA256) {
2N/A for (m = SHA224_FIRST_MECH; m <= SHA256_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A if (ui & AV_SPARC_SHA512) {
2N/A for (m = SHA384_FIRST_MECH; m <= SHA512_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A
2N/A if ((ui & AV_SPARC_MONT) && (ui & AV_SPARC_MPMUL)) {
2N/A for (m = RSA_FIRST_MECH; m <= RSA_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A for (m = DSA_FIRST_MECH; m <= DSA_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A for (m = DH_FIRST_MECH; m <= DH_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A for (m = EC_FIRST_MECH; m <= EC_LAST_MECH; m++) {
2N/A soft_mechanism_info[m].flags |= CKF_HW;
2N/A }
2N/A }
2N/A#endif /* __sparc */
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Slot ID for softtoken is always 1. tokenPresent is ignored.
2N/A * Also, only one slot is used.
2N/A */
2N/A/*ARGSUSED*/
2N/ACK_RV
2N/AC_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
2N/A CK_ULONG_PTR pulCount)
2N/A{
2N/A
2N/A CK_RV rv;
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A if (pulCount == NULL) {
2N/A return (CKR_ARGUMENTS_BAD);
2N/A }
2N/A
2N/A if (pSlotList == NULL) {
2N/A /*
2N/A * Application only wants to know the number of slots.
2N/A */
2N/A *pulCount = 1;
2N/A return (CKR_OK);
2N/A }
2N/A
2N/A if ((*pulCount < 1) && (pSlotList != NULL)) {
2N/A rv = CKR_BUFFER_TOO_SMALL;
2N/A } else {
2N/A pSlotList[0] = SOFTTOKEN_SLOTID;
2N/A rv = CKR_OK;
2N/A }
2N/A
2N/A *pulCount = 1;
2N/A return (rv);
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/AC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
2N/A{
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A if (pInfo == NULL)
2N/A return (CKR_ARGUMENTS_BAD);
2N/A
2N/A /* Make sure the slot ID is valid */
2N/A if (slotID != SOFTTOKEN_SLOTID)
2N/A return (CKR_SLOT_ID_INVALID);
2N/A
2N/A /* Provide information about the slot in the provided buffer */
2N/A (void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION,
2N/A 64);
2N/A (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
2N/A pInfo->flags = CKF_TOKEN_PRESENT;
2N/A pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
2N/A pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
2N/A pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
2N/A pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
2N/A
2N/A return (CKR_OK);
2N/A}
2N/A
2N/ACK_RV
2N/AC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
2N/A{
2N/A boolean_t pin_initialized = B_FALSE;
2N/A char *ks_cryptpin = NULL;
2N/A CK_RV rv;
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A /* Make sure the slot ID is valid */
2N/A if (slotID != SOFTTOKEN_SLOTID)
2N/A return (CKR_SLOT_ID_INVALID);
2N/A
2N/A if (pInfo == NULL)
2N/A return (CKR_ARGUMENTS_BAD);
2N/A
2N/A /*
2N/A * It is intentional that we don't forward the error code
2N/A * returned from soft_keystore_pin_initialized() to the caller
2N/A */
2N/A pInfo->flags = SOFT_TOKEN_FLAGS;
2N/A rv = soft_keystore_pin_initialized(&pin_initialized,
2N/A &ks_cryptpin, B_FALSE);
2N/A if (ks_cryptpin)
2N/A free(ks_cryptpin);
2N/A
2N/A if (rv == CKR_OK) {
2N/A pInfo->flags |= CKF_TOKEN_INITIALIZED;
2N/A pInfo->flags |= CKF_LOGIN_REQUIRED;
2N/A if (pin_initialized) {
2N/A pInfo->flags |= CKF_USER_PIN_INITIALIZED;
2N/A } else {
2N/A pInfo->flags |= CKF_USER_PIN_TO_BE_CHANGED;
2N/A }
2N/A }
2N/A
2N/A
2N/A /* Provide information about a token in the provided buffer */
2N/A (void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32);
2N/A (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32);
2N/A (void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16);
2N/A (void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16);
2N/A
2N/A pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
2N/A pInfo->ulSessionCount = soft_session_cnt;
2N/A pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
2N/A pInfo->ulRwSessionCount = soft_session_rw_cnt;
2N/A pInfo->ulMaxPinLen = MAX_PIN_LEN;
2N/A pInfo->ulMinPinLen = MIN_PIN_LEN;
2N/A pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
2N/A pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
2N/A pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
2N/A pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
2N/A pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
2N/A pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
2N/A pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
2N/A pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
2N/A (void) memset(pInfo->utcTime, ' ', 16);
2N/A
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A/*ARGSUSED*/
2N/ACK_RV
2N/AC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
2N/A{
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A /*
2N/A * This is currently not implemented, however we could cause this
2N/A * to wait for the token files to appear if soft_token_present is
2N/A * false.
2N/A * However there is currently no polite and portable way to do that
2N/A * because we might not even be able to get to an fd to the
2N/A * parent directory, so instead we don't support any slot events.
2N/A */
2N/A return (CKR_FUNCTION_NOT_SUPPORTED);
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/AC_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
2N/A CK_ULONG_PTR pulCount)
2N/A{
2N/A
2N/A ulong_t i;
2N/A ulong_t mechnum;
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A if (slotID != SOFTTOKEN_SLOTID)
2N/A return (CKR_SLOT_ID_INVALID);
2N/A
2N/A mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
2N/A
2N/A if (pMechanismList == NULL) {
2N/A /*
2N/A * Application only wants to know the number of
2N/A * supported mechanism types.
2N/A */
2N/A *pulCount = mechnum;
2N/A return (CKR_OK);
2N/A }
2N/A
2N/A if (*pulCount < mechnum) {
2N/A *pulCount = mechnum;
2N/A return (CKR_BUFFER_TOO_SMALL);
2N/A }
2N/A
2N/A for (i = 0; i < mechnum; i++) {
2N/A pMechanismList[i] = soft_mechanisms[i];
2N/A }
2N/A
2N/A *pulCount = mechnum;
2N/A
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/AC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
2N/A CK_MECHANISM_INFO_PTR pInfo)
2N/A{
2N/A
2N/A ulong_t i;
2N/A ulong_t mechnum;
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A if (slotID != SOFTTOKEN_SLOTID)
2N/A return (CKR_SLOT_ID_INVALID);
2N/A
2N/A if (pInfo == NULL) {
2N/A return (CKR_ARGUMENTS_BAD);
2N/A }
2N/A
2N/A mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE);
2N/A for (i = 0; i < mechnum; i++) {
2N/A if (soft_mechanisms[i] == type)
2N/A break;
2N/A }
2N/A
2N/A if (i == mechnum)
2N/A /* unsupported mechanism */
2N/A return (CKR_MECHANISM_INVALID);
2N/A
2N/A update_mech_hw_flags();
2N/A pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize;
2N/A pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize;
2N/A pInfo->flags = soft_mechanism_info[i].flags;
2N/A
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A
2N/A/*ARGSUSED*/
2N/ACK_RV
2N/AC_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
2N/A CK_UTF8CHAR_PTR pLabel)
2N/A{
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A /*
2N/A * pPin and pLabel are not used as softtoken
2N/A * doesn't have the concept of an SO user. We don't
2N/A * reject any values (if set), as generic applications
2N/A * (like KMF) may set these for other tokens and
2N/A * if we error out with something like CKR_ARGUMENTS_BAD
2N/A * the application likely won't know how to recover.
2N/A */
2N/A
2N/A if (slotID != SOFTTOKEN_SLOTID)
2N/A return (CKR_SLOT_ID_INVALID);
2N/A
2N/A if (create_keystore() != 0)
2N/A return (CKR_FUNCTION_FAILED);
2N/A
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A/*ARGSUSED*/
2N/ACK_RV
2N/AC_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
2N/A{
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A return (CKR_FUNCTION_NOT_SUPPORTED);
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/AC_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
2N/A CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
2N/A{
2N/A
2N/A soft_session_t *session_p;
2N/A CK_RV rv;
2N/A boolean_t lock_held = B_FALSE;
2N/A
2N/A if (!softtoken_initialized)
2N/A return (CKR_CRYPTOKI_NOT_INITIALIZED);
2N/A
2N/A /*
2N/A * Obtain the session pointer. Also, increment the session
2N/A * reference count.
2N/A */
2N/A rv = handle2session(hSession, &session_p);
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A if (!soft_keystore_status(KEYSTORE_LOAD)) {
2N/A SES_REFRELE(session_p, lock_held);
2N/A return (CKR_DEVICE_REMOVED);
2N/A }
2N/A
2N/A if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) ||
2N/A (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) {
2N/A SES_REFRELE(session_p, lock_held);
2N/A return (CKR_PIN_LEN_RANGE);
2N/A }
2N/A
2N/A if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) {
2N/A /*
2N/A * We don't support CKF_PROTECTED_AUTHENTICATION_PATH
2N/A */
2N/A SES_REFRELE(session_p, lock_held);
2N/A return (CKR_ARGUMENTS_BAD);
2N/A }
2N/A
2N/A /* check the state of the session */
2N/A if ((session_p->state != CKS_RW_PUBLIC_SESSION) &&
2N/A (session_p->state != CKS_RW_USER_FUNCTIONS)) {
2N/A SES_REFRELE(session_p, lock_held);
2N/A return (CKR_SESSION_READ_ONLY);
2N/A }
2N/A
2N/A rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
2N/A
2N/A SES_REFRELE(session_p, lock_held);
2N/A return (rv);
2N/A}