diff options
author | John Sonnenschein <johns@joyent.com> | 2012-05-17 18:26:57 +0000 |
---|---|---|
committer | John Sonnenschein <johns@joyent.com> | 2012-05-17 18:26:57 +0000 |
commit | 04b244dd661c24b510ac22936decfc0972d202d3 (patch) | |
tree | 3ebfef98afc303fddf3415d6fba64e8682f495e8 /usr/src/lib/pkcs11 | |
parent | eac250589e41f1b705e1b7427b02b3379aac9f9e (diff) | |
parent | a69187741b83640a90dd8586195456dd50c016a8 (diff) | |
download | illumos-joyent-20120517.tar.gz |
Merge git.joyent.com:illumos-joyent20120517
Diffstat (limited to 'usr/src/lib/pkcs11')
32 files changed, 0 insertions, 9989 deletions
diff --git a/usr/src/lib/pkcs11/Makefile b/usr/src/lib/pkcs11/Makefile index 61351cd3c0..c552af6b57 100644 --- a/usr/src/lib/pkcs11/Makefile +++ b/usr/src/lib/pkcs11/Makefile @@ -36,7 +36,6 @@ SUBDIRS = \ libsoftcrypto \ libkcfd \ pkcs11_kernel \ - pkcs11_kms \ pkcs11_softtoken \ pkcs11_tpm diff --git a/usr/src/lib/pkcs11/pkcs11_kms/Makefile b/usr/src/lib/pkcs11/pkcs11_kms/Makefile deleted file mode 100644 index f82f4a6763..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# - -include $(SRC)/lib/Makefile.lib - -SUBDIRS = $(MACH) -$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET= all -check := TARGET= check -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install -lint := TARGET= lint - -.KEEP_STATE: - -all clean clobber install lint: $(SUBDIRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: diff --git a/usr/src/lib/pkcs11/pkcs11_kms/Makefile.com b/usr/src/lib/pkcs11/pkcs11_kms/Makefile.com deleted file mode 100644 index d9f7e19b22..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/Makefile.com +++ /dev/null @@ -1,99 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. -# - -LIBRARY= pkcs11_kms.a -VERS= .1 - -CORE_OBJECTS= \ - kmsAESCrypt.o \ - kmsAttributeUtil.o \ - kmsDecrypt.o \ - kmsDigest.o \ - kmsDualCrypt.o \ - kmsEncrypt.o \ - kmsGeneral.o \ - kmsKeys.o \ - kmsKeystoreUtil.o \ - kmsObject.o \ - kmsObjectUtil.o \ - kmsRand.o \ - kmsSession.o \ - kmsSessionUtil.o \ - kmsSign.o \ - kmsSlottable.o \ - kmsSlotToken.o \ - kmsVerify.o - -OBJECTS= $(CORE_OBJECTS) - -AESDIR= $(SRC)/common/crypto/aes -KMSAGENTDIR= $(SRC)/lib/libkmsagent/common - -include $(SRC)/lib/Makefile.lib - -# set signing mode -POST_PROCESS_SO += ; $(ELFSIGN_CRYPTO) - -SRCDIR= ../common -CORESRCS = $(CORE_OBJECTS:%.o=$(SRCDIR)/%.c) - -LIBS = $(DYNLIB) -LDLIBS += -lc -lcryptoutil -lsoftcrypto -lmd -lavl -lkmsagent - -CFLAGS += $(CCVERBOSE) - -CPPFLAGS += -DUSESOLARIS_AES -DKMSUSERPKCS12 - -ROOTLIBDIR= $(ROOT)/usr/lib/security -ROOTLIBDIR64= $(ROOT)/usr/lib/security/$(MACH64) - -lint \ -pics/kmsAESCrypt.o \ -pics/kmsEncrypt.o \ -pics/kmsDecrypt.o \ -pics/kmsSlotToken.o \ -pics/kmsKeystoreUtil.o \ -pics/kmsAttributeUtil.o := CPPFLAGS += -I$(AESDIR) -I$(SRC)/common/crypto - -CPPFLAGS += -I$(KMSAGENTDIR) - -.KEEP_STATE: - -all: $(LIBS) - -# -# -lkmsagent is not here because it is C++ and we don't lint C++ code. -# -LINTLDLIBS = -lc -lcryptoutil -lavl -lmd -lsoftcrypto - -LINTFLAGS64 += -errchk=longptr64 -errtags=yes - -lintcheck := SRCS = $(CORESRCS) -lintcheck := LDLIBS = -L$(ROOT)/lib -L$(ROOT)/usr/lib $(LINTLDLIBS) - -lintother: $$(OSRCS) - $(LINT.c) $(LINTCHECKFLAGS) $(OSRCS) $(LINTLDLIBS) - -lint: lintcheck - -include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/amd64/Makefile b/usr/src/lib/pkcs11/pkcs11_kms/amd64/Makefile deleted file mode 100644 index 99c7ac2351..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/amd64/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# - - -include ../Makefile.com -include ../../../Makefile.lib.64 - -LINTCHECKFLAGS += -erroff=E_INCONS_ARG_DECL2 \ - -erroff=E_INCONS_ARG_USED2 \ - -erroff=E_INCONS_VAL_TYPE_DECL2 \ - -erroff=E_INCONS_VAL_TYPE_USED2 \ - -erroff=E_FUNC_DECL_VAR_ARG2 - -install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAESCrypt.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAESCrypt.c deleted file mode 100644 index 0e384e0043..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAESCrypt.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <sys/types.h> -#include <security/cryptoki.h> -#include <aes_impl.h> - -#include "kmsSession.h" -#include "kmsObject.h" -#include "kmsCrypt.h" - -/* - * Add padding bytes with the value of length of padding. - */ -static void -kms_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len) -{ - - ulong_t i, pad_len; - CK_BYTE pad_value; - - pad_len = block_size - (data_len % block_size); - pad_value = (CK_BYTE)pad_len; - - for (i = 0; i < pad_len; i++) - buf[i] = pad_value; -} - -/* - * Remove padding bytes. - */ -static CK_RV -kms_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len, - CK_ULONG *pulDataLen, int block_size) -{ - - CK_BYTE pad_value; - ulong_t i; - - pad_value = pData[padded_len - 1]; - - - /* Make sure there is a valid padding value. */ - if ((pad_value == 0) || (pad_value > block_size)) - return (CKR_ENCRYPTED_DATA_INVALID); - - for (i = padded_len - pad_value; i < padded_len; i++) - if (pad_value != pData[i]) - return (CKR_ENCRYPTED_DATA_INVALID); - - *pulDataLen = padded_len - pad_value; - return (CKR_OK); -} - -/* - * Allocate context for the active encryption or decryption operation, and - * generate AES key schedule to speed up the operation. - */ -CK_RV -kms_aes_crypt_init_common(kms_session_t *session_p, - CK_MECHANISM_PTR pMechanism, kms_object_t *key_p, - boolean_t encrypt) -{ - size_t size; - kms_aes_ctx_t *kms_aes_ctx; - - kms_aes_ctx = calloc(1, sizeof (kms_aes_ctx_t)); - if (kms_aes_ctx == NULL) { - return (CKR_HOST_MEMORY); - } - - kms_aes_ctx->key_sched = aes_alloc_keysched(&size, 0); - - if (kms_aes_ctx->key_sched == NULL) { - free(kms_aes_ctx); - return (CKR_HOST_MEMORY); - } - - kms_aes_ctx->keysched_len = size; - - (void) pthread_mutex_lock(&session_p->session_mutex); - if (encrypt) { - /* Called by C_EncryptInit. */ - session_p->encrypt.context = kms_aes_ctx; - session_p->encrypt.mech.mechanism = pMechanism->mechanism; - } else { - /* Called by C_DecryptInit. */ - session_p->decrypt.context = kms_aes_ctx; - session_p->decrypt.mech.mechanism = pMechanism->mechanism; - } - (void) pthread_mutex_unlock(&session_p->session_mutex); - - /* - * If this is a non-sensitive key and it does NOT have - * a key schedule yet, then allocate one and expand it. - * Otherwise, if it's a non-sensitive key, and it DOES have - * a key schedule already attached to it, just copy the - * pre-expanded schedule to the context and avoid the - * extra key schedule expansion operation. - */ - if (!(key_p->bool_attr_mask & SENSITIVE_BOOL_ON)) { - if (OBJ_KEY_SCHED(key_p) == NULL) { - void *ks; - - (void) pthread_mutex_lock(&key_p->object_mutex); - if (OBJ_KEY_SCHED(key_p) == NULL) { - ks = aes_alloc_keysched(&size, 0); - if (ks == NULL) { - (void) pthread_mutex_unlock( - &key_p->object_mutex); - free(kms_aes_ctx); - return (CKR_HOST_MEMORY); - } -#ifdef __sparcv9 - /* LINTED */ - aes_init_keysched(OBJ_SEC_VALUE(key_p), (uint_t) - (OBJ_SEC_VALUE_LEN(key_p) * 8), ks); -#else /* !__sparcv9 */ - aes_init_keysched(OBJ_SEC_VALUE(key_p), - (OBJ_SEC_VALUE_LEN(key_p) * 8), ks); -#endif /* __sparcv9 */ - OBJ_KEY_SCHED_LEN(key_p) = size; - OBJ_KEY_SCHED(key_p) = ks; - } - (void) pthread_mutex_unlock(&key_p->object_mutex); - } - (void) memcpy(kms_aes_ctx->key_sched, OBJ_KEY_SCHED(key_p), - OBJ_KEY_SCHED_LEN(key_p)); - kms_aes_ctx->keysched_len = OBJ_KEY_SCHED_LEN(key_p); - } else { - /* - * Initialize key schedule for AES. aes_init_keysched() - * requires key length in bits. - */ -#ifdef __sparcv9 - /* LINTED */ - aes_init_keysched(OBJ_SEC_VALUE(key_p), (uint_t) - (OBJ_SEC_VALUE_LEN(key_p) * 8), kms_aes_ctx->key_sched); -#else /* !__sparcv9 */ - aes_init_keysched(OBJ_SEC_VALUE(key_p), - (OBJ_SEC_VALUE_LEN(key_p) * 8), kms_aes_ctx->key_sched); -#endif /* __sparcv9 */ - } - return (CKR_OK); -} - -/* - * kms_aes_encrypt_common() - * - * Arguments: - * session_p: pointer to kms_session_t struct - * pData: pointer to the input data to be encrypted - * ulDataLen: length of the input data - * pEncrypted: pointer to the output data after encryption - * pulEncryptedLen: pointer to the length of the output data - * update: boolean flag indicates caller is kms_encrypt - * or kms_encrypt_update - * - * Description: - * This function calls the corresponding encrypt routine based - * on the mechanism. - * - * Returns: - * CKR_OK: success - * CKR_BUFFER_TOO_SMALL: the output buffer provided by application - * is too small - * CKR_FUNCTION_FAILED: encrypt function failed - * CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize - */ -CK_RV -kms_aes_encrypt_common(kms_session_t *session_p, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted, - CK_ULONG_PTR pulEncryptedLen, boolean_t update) -{ - - int rc = 0; - CK_RV rv = CKR_OK; - kms_aes_ctx_t *kms_aes_ctx = - (kms_aes_ctx_t *)session_p->encrypt.context; - aes_ctx_t *aes_ctx; - CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; - CK_BYTE *in_buf = NULL; - CK_BYTE *out_buf = NULL; - CK_ULONG out_len; - CK_ULONG total_len; - CK_ULONG remain; - - if (mechanism == CKM_AES_CTR) - goto do_encryption; - - /* - * AES only takes input length that is a multiple of blocksize - * for C_Encrypt function with the mechanism CKM_AES_ECB or - * CKM_AES_CBC. - * - * AES allows any input length for C_Encrypt function with the - * mechanism CKM_AES_CBC_PAD and for C_EncryptUpdate function. - */ - if ((!update) && (mechanism != CKM_AES_CBC_PAD)) { - if ((ulDataLen % AES_BLOCK_LEN) != 0) { - rv = CKR_DATA_LEN_RANGE; - goto cleanup; - } - } - - if (!update) { - /* - * Called by C_Encrypt - */ - if (mechanism == CKM_AES_CBC_PAD) { - /* - * For CKM_AES_CBC_PAD, compute output length to - * count for the padding. If the length of input - * data is a multiple of blocksize, then make output - * length to be the sum of the input length and - * one blocksize. Otherwise, output length will - * be rounded up to the next multiple of blocksize. - */ - out_len = AES_BLOCK_LEN * - (ulDataLen / AES_BLOCK_LEN + 1); - } else { - /* - * For non-padding mode, the output length will - * be same as the input length. - */ - out_len = ulDataLen; - } - - /* - * If application asks for the length of the output buffer - * to hold the ciphertext? - */ - if (pEncrypted == NULL) { - *pulEncryptedLen = out_len; - return (CKR_OK); - } - - /* Is the application-supplied buffer large enough? */ - if (*pulEncryptedLen < out_len) { - *pulEncryptedLen = out_len; - return (CKR_BUFFER_TOO_SMALL); - } - - /* Encrypt pad bytes in a separate operation */ - if (mechanism == CKM_AES_CBC_PAD) { - out_len -= AES_BLOCK_LEN; - } - - in_buf = pData; - out_buf = pEncrypted; - } else { - /* - * Called by C_EncryptUpdate - * - * Add the lengths of last remaining data and current - * plaintext together to get the total input length. - */ - total_len = kms_aes_ctx->remain_len + ulDataLen; - - /* - * If the total input length is less than one blocksize, - * or if the total input length is just one blocksize and - * the mechanism is CKM_AES_CBC_PAD, we will need to delay - * encryption until when more data comes in next - * C_EncryptUpdate or when C_EncryptFinal is called. - */ - if ((total_len < AES_BLOCK_LEN) || - ((mechanism == CKM_AES_CBC_PAD) && - (total_len == AES_BLOCK_LEN))) { - if (pEncrypted != NULL) { - /* - * Save input data and its length in - * the remaining buffer of AES context. - */ - (void) memcpy(kms_aes_ctx->data + - kms_aes_ctx->remain_len, pData, ulDataLen); - kms_aes_ctx->remain_len += ulDataLen; - } - - /* Set encrypted data length to 0. */ - *pulEncryptedLen = 0; - return (CKR_OK); - } - - /* Compute the length of remaing data. */ - remain = total_len % AES_BLOCK_LEN; - - /* - * Make sure that the output length is a multiple of - * blocksize. - */ - out_len = total_len - remain; - - /* - * If application asks for the length of the output buffer - * to hold the ciphertext? - */ - if (pEncrypted == NULL) { - *pulEncryptedLen = out_len; - return (CKR_OK); - } - - /* Is the application-supplied buffer large enough? */ - if (*pulEncryptedLen < out_len) { - *pulEncryptedLen = out_len; - return (CKR_BUFFER_TOO_SMALL); - } - - if (kms_aes_ctx->remain_len != 0) { - /* - * Copy last remaining data and current input data - * to the output buffer. - */ - (void) memmove(pEncrypted + kms_aes_ctx->remain_len, - pData, out_len - kms_aes_ctx->remain_len); - (void) memcpy(pEncrypted, kms_aes_ctx->data, - kms_aes_ctx->remain_len); - bzero(kms_aes_ctx->data, kms_aes_ctx->remain_len); - - in_buf = pEncrypted; - } else { - in_buf = pData; - } - out_buf = pEncrypted; - } - -do_encryption: - /* - * Begin Encryption now. - */ - switch (mechanism) { - - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - { - crypto_data_t out; - - out.cd_format = CRYPTO_DATA_RAW; - out.cd_offset = 0; - out.cd_length = out_len; - out.cd_raw.iov_base = (char *)out_buf; - out.cd_raw.iov_len = out_len; - - /* Encrypt multiple blocks of data. */ - rc = aes_encrypt_contiguous_blocks( - (aes_ctx_t *)kms_aes_ctx->aes_cbc, - (char *)in_buf, out_len, &out); - - if (rc != 0) - goto encrypt_failed; - - if (update) { - /* - * For encrypt update, if there is remaining data, - * save it and its length in the context. - */ - if (remain != 0) - (void) memcpy(kms_aes_ctx->data, pData + - (ulDataLen - remain), remain); - kms_aes_ctx->remain_len = remain; - } else if (mechanism == CKM_AES_CBC_PAD) { - /* - * Save the remainder of the input - * block in a temporary block because - * we dont want to overrun the buffer - * by tacking on pad bytes. - */ - CK_BYTE tmpblock[AES_BLOCK_LEN]; - (void) memcpy(tmpblock, in_buf + out_len, - ulDataLen - out_len); - kms_add_pkcs7_padding(tmpblock + - (ulDataLen - out_len), - AES_BLOCK_LEN, ulDataLen - out_len); - - out.cd_offset = out_len; - out.cd_length = AES_BLOCK_LEN; - out.cd_raw.iov_base = (char *)out_buf; - out.cd_raw.iov_len = out_len + AES_BLOCK_LEN; - - /* Encrypt last block containing pad bytes. */ - rc = aes_encrypt_contiguous_blocks( - (aes_ctx_t *)kms_aes_ctx->aes_cbc, - (char *)tmpblock, AES_BLOCK_LEN, &out); - - out_len += AES_BLOCK_LEN; - } - - if (rc == 0) { - *pulEncryptedLen = out_len; - break; - } -encrypt_failed: - *pulEncryptedLen = 0; - rv = CKR_FUNCTION_FAILED; - goto cleanup; - } - default: - rv = CKR_MECHANISM_INVALID; - goto cleanup; - } /* end switch */ - - if (update) - return (CKR_OK); - - /* - * The following code will be executed if the caller is - * kms_encrypt() or an error occurred. The encryption - * operation will be terminated so we need to do some cleanup. - */ -cleanup: - (void) pthread_mutex_lock(&session_p->session_mutex); - aes_ctx = (aes_ctx_t *)kms_aes_ctx->aes_cbc; - if (aes_ctx != NULL) { - bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len); - free(kms_aes_ctx->aes_cbc); - } - - bzero(kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - free(session_p->encrypt.context); - session_p->encrypt.context = NULL; - (void) pthread_mutex_unlock(&session_p->session_mutex); - - return (rv); -} - - -/* - * kms_aes_decrypt_common() - * - * Arguments: - * session_p: pointer to kms_session_t struct - * pEncrypted: pointer to the input data to be decrypted - * ulEncryptedLen: length of the input data - * pData: pointer to the output data - * pulDataLen: pointer to the length of the output data - * Update: boolean flag indicates caller is kms_decrypt - * or kms_decrypt_update - * - * Description: - * This function calls the corresponding decrypt routine based - * on the mechanism. - * - * Returns: - * CKR_OK: success - * CKR_BUFFER_TOO_SMALL: the output buffer provided by application - * is too small - * CKR_ENCRYPTED_DATA_LEN_RANGE: the input data is not a multiple - * of blocksize - * CKR_FUNCTION_FAILED: decrypt function failed - */ -CK_RV -kms_aes_decrypt_common(kms_session_t *session_p, CK_BYTE_PTR pEncrypted, - CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, - CK_ULONG_PTR pulDataLen, boolean_t update) -{ - - int rc = 0; - CK_RV rv = CKR_OK; - kms_aes_ctx_t *kms_aes_ctx = - (kms_aes_ctx_t *)session_p->decrypt.context; - aes_ctx_t *aes_ctx; - CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; - CK_BYTE *in_buf = NULL; - CK_BYTE *out_buf = NULL; - CK_ULONG out_len; - CK_ULONG total_len; - CK_ULONG remain; - - if (mechanism == CKM_AES_CTR) - goto do_decryption; - - /* - * AES only takes input length that is a multiple of 16 bytes - * for C_Decrypt function with the mechanism CKM_AES_ECB, - * CKM_AES_CBC or CKM_AES_CBC_PAD. - * - * AES allows any input length for C_DecryptUpdate function. - */ - if (!update) { - /* - * Called by C_Decrypt - */ - if ((ulEncryptedLen % AES_BLOCK_LEN) != 0) { - rv = CKR_ENCRYPTED_DATA_LEN_RANGE; - goto cleanup; - } - - /* - * If application asks for the length of the output buffer - * to hold the plaintext? - */ - if (pData == NULL) { - *pulDataLen = ulEncryptedLen; - return (CKR_OK); - } - - /* Is the application-supplied buffer large enough? */ - if (mechanism != CKM_AES_CBC_PAD) { - if (*pulDataLen < ulEncryptedLen) { - *pulDataLen = ulEncryptedLen; - return (CKR_BUFFER_TOO_SMALL); - } - out_len = ulEncryptedLen; - } else { - /* - * For CKM_AES_CBC_PAD, we don't know how - * many bytes for padding at this time, so - * we'd assume one block was padded. - */ - if (*pulDataLen < (ulEncryptedLen - AES_BLOCK_LEN)) { - *pulDataLen = ulEncryptedLen - AES_BLOCK_LEN; - return (CKR_BUFFER_TOO_SMALL); - } - out_len = ulEncryptedLen - AES_BLOCK_LEN; - } - in_buf = pEncrypted; - out_buf = pData; - } else { - /* - * Called by C_DecryptUpdate - * - * Add the lengths of last remaining data and current - * input data together to get the total input length. - */ - total_len = kms_aes_ctx->remain_len + ulEncryptedLen; - - /* - * If the total input length is less than one blocksize, - * or if the total input length is just one blocksize and - * the mechanism is CKM_AES_CBC_PAD, we will need to delay - * decryption until when more data comes in next - * C_DecryptUpdate or when C_DecryptFinal is called. - */ - if ((total_len < AES_BLOCK_LEN) || - ((mechanism == CKM_AES_CBC_PAD) && - (total_len == AES_BLOCK_LEN))) { - if (pData != NULL) { - /* - * Save input data and its length in - * the remaining buffer of AES context. - */ - (void) memcpy(kms_aes_ctx->data + - kms_aes_ctx->remain_len, - pEncrypted, ulEncryptedLen); - kms_aes_ctx->remain_len += ulEncryptedLen; - } - - /* Set output data length to 0. */ - *pulDataLen = 0; - return (CKR_OK); - } - - /* Compute the length of remaing data. */ - remain = total_len % AES_BLOCK_LEN; - - /* - * Make sure that the output length is a multiple of - * blocksize. - */ - out_len = total_len - remain; - - if (mechanism == CKM_AES_CBC_PAD) { - /* - * If the input data length is a multiple of - * blocksize, then save the last block of input - * data in the remaining buffer. C_DecryptFinal - * will handle this last block of data. - */ - if (remain == 0) { - remain = AES_BLOCK_LEN; - out_len -= AES_BLOCK_LEN; - } - } - - /* - * If application asks for the length of the output buffer - * to hold the plaintext? - */ - if (pData == NULL) { - *pulDataLen = out_len; - return (CKR_OK); - } - - /* - * Is the application-supplied buffer large enough? - */ - if (*pulDataLen < out_len) { - *pulDataLen = out_len; - return (CKR_BUFFER_TOO_SMALL); - } - - if (kms_aes_ctx->remain_len != 0) { - /* - * Copy last remaining data and current input data - * to the output buffer. - */ - (void) memmove(pData + kms_aes_ctx->remain_len, - pEncrypted, out_len - kms_aes_ctx->remain_len); - (void) memcpy(pData, kms_aes_ctx->data, - kms_aes_ctx->remain_len); - bzero(kms_aes_ctx->data, kms_aes_ctx->remain_len); - - in_buf = pData; - } else { - in_buf = pEncrypted; - } - out_buf = pData; - } - -do_decryption: - /* - * Begin Decryption. - */ - switch (mechanism) { - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - { - crypto_data_t out; - CK_ULONG rem_len; - uint8_t last_block[AES_BLOCK_LEN]; - - out.cd_format = CRYPTO_DATA_RAW; - out.cd_offset = 0; - out.cd_length = out_len; - out.cd_raw.iov_base = (char *)out_buf; - out.cd_raw.iov_len = out_len; - - /* Decrypt multiple blocks of data. */ - rc = aes_decrypt_contiguous_blocks( - (aes_ctx_t *)kms_aes_ctx->aes_cbc, - (char *)in_buf, out_len, &out); - - if (rc != 0) - goto decrypt_failed; - - if ((mechanism == CKM_AES_CBC_PAD) && (!update)) { - /* Decrypt last block containing pad bytes. */ - out.cd_offset = 0; - out.cd_length = AES_BLOCK_LEN; - out.cd_raw.iov_base = (char *)last_block; - out.cd_raw.iov_len = AES_BLOCK_LEN; - - /* Decrypt last block containing pad bytes. */ - rc = aes_decrypt_contiguous_blocks( - (aes_ctx_t *)kms_aes_ctx->aes_cbc, - (char *)in_buf + out_len, AES_BLOCK_LEN, &out); - - if (rc != 0) - goto decrypt_failed; - - /* - * Remove padding bytes after decryption of - * ciphertext block to produce the original - * plaintext. - */ - rv = kms_remove_pkcs7_padding(last_block, - AES_BLOCK_LEN, &rem_len, AES_BLOCK_LEN); - if (rv == CKR_OK) { - if (rem_len != 0) - (void) memcpy(out_buf + out_len, - last_block, rem_len); - *pulDataLen = out_len + rem_len; - } else { - *pulDataLen = 0; - goto cleanup; - } - } else { - *pulDataLen = out_len; - } - - if (update) { - /* - * For decrypt update, if there is remaining data, - * save it and its length in the context. - */ - if (remain != 0) - (void) memcpy(kms_aes_ctx->data, pEncrypted + - (ulEncryptedLen - remain), remain); - kms_aes_ctx->remain_len = remain; - } - - if (rc == 0) - break; -decrypt_failed: - *pulDataLen = 0; - rv = CKR_FUNCTION_FAILED; - goto cleanup; - } - default: - rv = CKR_MECHANISM_INVALID; - goto cleanup; - } /* end switch */ - - if (update) - return (CKR_OK); - - /* - * The following code will be executed if the caller is - * kms_decrypt() or an error occurred. The decryption - * operation will be terminated so we need to do some cleanup. - */ -cleanup: - (void) pthread_mutex_lock(&session_p->session_mutex); - aes_ctx = (aes_ctx_t *)kms_aes_ctx->aes_cbc; - if (aes_ctx != NULL) { - bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len); - free(kms_aes_ctx->aes_cbc); - } - - bzero(kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - free(session_p->decrypt.context); - session_p->decrypt.context = NULL; - (void) pthread_mutex_unlock(&session_p->session_mutex); - - return (rv); -} - - -/* - * Allocate and initialize a context for AES CBC mode of operation. - */ -void * -aes_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec) -{ - aes_ctx_t *aes_ctx; - - if ((aes_ctx = calloc(1, sizeof (aes_ctx_t))) == NULL) - return (NULL); - - aes_ctx->ac_keysched = key_sched; - - (void) memcpy(&aes_ctx->ac_iv[0], ivec, AES_BLOCK_LEN); - - aes_ctx->ac_lastp = (uint8_t *)aes_ctx->ac_iv; - aes_ctx->ac_keysched_len = size; - aes_ctx->ac_flags |= CBC_MODE; - - return ((void *)aes_ctx); -} - -/* - * kms_encrypt_final() - * - * Arguments: - * session_p: pointer to kms_session_t struct - * pLastEncryptedPart: pointer to the last encrypted data part - * pulLastEncryptedPartLen: pointer to the length of the last - * encrypted data part - * - * Description: - * called by C_EncryptFinal(). - * - * Returns: - * CKR_OK: success - * CKR_FUNCTION_FAILED: encrypt final function failed - * CKR_DATA_LEN_RANGE: remaining buffer contains bad length - */ -CK_RV -kms_aes_encrypt_final(kms_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart, - CK_ULONG_PTR pulLastEncryptedPartLen) -{ - - CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; - CK_ULONG out_len; - CK_RV rv = CKR_OK; - int rc; - - (void) pthread_mutex_lock(&session_p->session_mutex); - - if (session_p->encrypt.context == NULL) { - rv = CKR_OPERATION_NOT_INITIALIZED; - *pulLastEncryptedPartLen = 0; - - } - if (mechanism == CKM_AES_CBC_PAD) { - kms_aes_ctx_t *aes_ctx; - - aes_ctx = (kms_aes_ctx_t *)session_p->encrypt.context; - /* - * For CKM_AES_CBC_PAD, compute output length with - * padding. If the remaining buffer has one block - * of data, then output length will be two blocksize of - * ciphertext. If the remaining buffer has less than - * one block of data, then output length will be - * one blocksize. - */ - if (aes_ctx->remain_len == AES_BLOCK_LEN) - out_len = 2 * AES_BLOCK_LEN; - else - out_len = AES_BLOCK_LEN; - - if (pLastEncryptedPart == NULL) { - /* - * Application asks for the length of the output - * buffer to hold the ciphertext. - */ - *pulLastEncryptedPartLen = out_len; - goto clean1; - } else { - crypto_data_t out; - - /* Copy remaining data to the output buffer. */ - (void) memcpy(pLastEncryptedPart, aes_ctx->data, - aes_ctx->remain_len); - - /* - * Add padding bytes prior to encrypt final. - */ - kms_add_pkcs7_padding(pLastEncryptedPart + - aes_ctx->remain_len, AES_BLOCK_LEN, - aes_ctx->remain_len); - - out.cd_format = CRYPTO_DATA_RAW; - out.cd_offset = 0; - out.cd_length = out_len; - out.cd_raw.iov_base = (char *)pLastEncryptedPart; - out.cd_raw.iov_len = out_len; - - /* Encrypt multiple blocks of data. */ - rc = aes_encrypt_contiguous_blocks( - (aes_ctx_t *)aes_ctx->aes_cbc, - (char *)pLastEncryptedPart, out_len, &out); - - if (rc == 0) { - *pulLastEncryptedPartLen = out_len; - } else { - *pulLastEncryptedPartLen = 0; - rv = CKR_FUNCTION_FAILED; - } - - /* Cleanup memory space. */ - free(aes_ctx->aes_cbc); - bzero(aes_ctx->key_sched, - aes_ctx->keysched_len); - free(aes_ctx->key_sched); - } - } else if (mechanism == CKM_AES_CBC) { - kms_aes_ctx_t *aes_ctx; - - aes_ctx = (kms_aes_ctx_t *)session_p->encrypt.context; - /* - * CKM_AES_CBC and CKM_AES_ECB does not do any padding, - * so when the final is called, the remaining buffer - * should not contain any more data. - */ - *pulLastEncryptedPartLen = 0; - if (aes_ctx->remain_len != 0) { - rv = CKR_DATA_LEN_RANGE; - } else { - if (pLastEncryptedPart == NULL) - goto clean1; - } - - /* Cleanup memory space. */ - free(aes_ctx->aes_cbc); - bzero(aes_ctx->key_sched, aes_ctx->keysched_len); - free(aes_ctx->key_sched); - } else { - rv = CKR_MECHANISM_INVALID; - } - - free(session_p->encrypt.context); - session_p->encrypt.context = NULL; -clean1: - (void) pthread_mutex_unlock(&session_p->session_mutex); - return (rv); -} - -/* - * kms_decrypt_final() - * - * Arguments: - * session_p: pointer to kms_session_t struct - * pLastPart: pointer to the last recovered data part - * pulLastPartLen: pointer to the length of the last recovered data part - * - * Description: - * called by C_DecryptFinal(). - * - * Returns: - * CKR_OK: success - * CKR_FUNCTION_FAILED: decrypt final function failed - * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length - */ -CK_RV -kms_aes_decrypt_final(kms_session_t *session_p, CK_BYTE_PTR pLastPart, - CK_ULONG_PTR pulLastPartLen) -{ - - CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; - CK_ULONG out_len; - CK_RV rv = CKR_OK; - int rc; - - (void) pthread_mutex_lock(&session_p->session_mutex); - - if (session_p->decrypt.context == NULL) { - rv = CKR_OPERATION_NOT_INITIALIZED; - *pulLastPartLen = 0; - goto clean2; - } - switch (mechanism) { - - case CKM_AES_CBC_PAD: - { - kms_aes_ctx_t *kms_aes_ctx; - kms_aes_ctx = (kms_aes_ctx_t *)session_p->decrypt.context; - - /* - * We should have only one block of data left in the - * remaining buffer. - */ - if (kms_aes_ctx->remain_len != AES_BLOCK_LEN) { - *pulLastPartLen = 0; - rv = CKR_ENCRYPTED_DATA_LEN_RANGE; - /* Cleanup memory space. */ - free(kms_aes_ctx->aes_cbc); - bzero(kms_aes_ctx->key_sched, - kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - - goto clean1; - } - - out_len = AES_BLOCK_LEN; - - /* - * If application asks for the length of the output buffer - * to hold the plaintext? - */ - if (pLastPart == NULL) { - *pulLastPartLen = out_len; - rv = CKR_OK; - goto clean2; - } else { - crypto_data_t out; - - /* Copy remaining data to the output buffer. */ - (void) memcpy(pLastPart, kms_aes_ctx->data, - AES_BLOCK_LEN); - - out.cd_format = CRYPTO_DATA_RAW; - out.cd_offset = 0; - out.cd_length = AES_BLOCK_LEN; - out.cd_raw.iov_base = (char *)pLastPart; - out.cd_raw.iov_len = AES_BLOCK_LEN; - - /* Decrypt final block of data. */ - rc = aes_decrypt_contiguous_blocks( - (aes_ctx_t *)kms_aes_ctx->aes_cbc, - (char *)pLastPart, AES_BLOCK_LEN, &out); - - if (rc == 0) { - /* - * Remove padding bytes after decryption of - * ciphertext block to produce the original - * plaintext. - */ - rv = kms_remove_pkcs7_padding(pLastPart, - AES_BLOCK_LEN, &out_len, AES_BLOCK_LEN); - if (rv != CKR_OK) - *pulLastPartLen = 0; - else - *pulLastPartLen = out_len; - } else { - *pulLastPartLen = 0; - rv = CKR_FUNCTION_FAILED; - } - - /* Cleanup memory space. */ - free(kms_aes_ctx->aes_cbc); - bzero(kms_aes_ctx->key_sched, - kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - - } - - break; - } - - case CKM_AES_CBC: - { - kms_aes_ctx_t *kms_aes_ctx; - - kms_aes_ctx = (kms_aes_ctx_t *)session_p->decrypt.context; - /* - * CKM_AES_CBC and CKM_AES_ECB does not do any padding, - * so when the final is called, the remaining buffer - * should not contain any more data. - */ - *pulLastPartLen = 0; - if (kms_aes_ctx->remain_len != 0) { - rv = CKR_ENCRYPTED_DATA_LEN_RANGE; - } else { - if (pLastPart == NULL) - goto clean2; - } - - /* Cleanup memory space. */ - free(kms_aes_ctx->aes_cbc); - bzero(kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - - break; - } - default: - /* PKCS11: The mechanism only supports single-part operation. */ - rv = CKR_MECHANISM_INVALID; - break; - } - -clean1: - free(session_p->decrypt.context); - session_p->decrypt.context = NULL; - -clean2: - (void) pthread_mutex_unlock(&session_p->session_mutex); - - return (rv); - -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAttributeUtil.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAttributeUtil.c deleted file mode 100644 index 9a50d5f084..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsAttributeUtil.c +++ /dev/null @@ -1,1726 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Milan Jurik. All rights reserved. - */ -#include <stdlib.h> -#include <string.h> -#include <security/cryptoki.h> -#include <sys/crypto/common.h> -#include <aes_impl.h> -#include "kmsGlobal.h" -#include "kmsObject.h" -#include "kmsSession.h" -#include "kmsSlot.h" - -/* - * This attribute table is used by the kms_lookup_attr() - * to validate the attributes. - */ -CK_ATTRIBUTE_TYPE attr_map[] = { - CKA_PRIVATE, - CKA_LABEL, - CKA_APPLICATION, - CKA_OBJECT_ID, - CKA_CERTIFICATE_TYPE, - CKA_ISSUER, - CKA_SERIAL_NUMBER, - CKA_AC_ISSUER, - CKA_OWNER, - CKA_ATTR_TYPES, - CKA_SUBJECT, - CKA_ID, - CKA_SENSITIVE, - CKA_START_DATE, - CKA_END_DATE, - CKA_MODULUS, - CKA_MODULUS_BITS, - CKA_PUBLIC_EXPONENT, - CKA_PRIVATE_EXPONENT, - CKA_PRIME_1, - CKA_PRIME_2, - CKA_EXPONENT_1, - CKA_EXPONENT_2, - CKA_COEFFICIENT, - CKA_PRIME, - CKA_SUBPRIME, - CKA_BASE, - CKA_EXTRACTABLE, - CKA_LOCAL, - CKA_NEVER_EXTRACTABLE, - CKA_ALWAYS_SENSITIVE, - CKA_MODIFIABLE, - CKA_ECDSA_PARAMS, - CKA_EC_POINT, - CKA_SECONDARY_AUTH, - CKA_AUTH_PIN_FLAGS, - CKA_HW_FEATURE_TYPE, - CKA_RESET_ON_INIT, - CKA_HAS_RESET -}; - -/* - * attributes that exists only in secret key objects - * Note: some attributes may also exist in one or two - * other object classes, but they are also listed - * because not all object have them. - */ -CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] = -{ - CKA_VALUE_LEN, - CKA_ENCRYPT, - CKA_DECRYPT, - CKA_WRAP, - CKA_UNWRAP, - CKA_SIGN, - CKA_VERIFY, - CKA_SENSITIVE, - CKA_EXTRACTABLE, - CKA_NEVER_EXTRACTABLE, - CKA_ALWAYS_SENSITIVE -}; - -/* - * Validate the attribute by using binary search algorithm. - */ -CK_RV -kms_lookup_attr(CK_ATTRIBUTE_TYPE type) -{ - size_t lower, middle, upper; - - lower = 0; - upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1; - - while (lower <= upper) { - /* Always starts from middle. */ - middle = (lower + upper) / 2; - - if (type > attr_map[middle]) { - /* Adjust the lower bound to upper half. */ - lower = middle + 1; - continue; - } - - if (type == attr_map[middle]) { - /* Found it. */ - return (CKR_OK); - } - - if (type < attr_map[middle]) { - /* Adjust the upper bound to lower half. */ - upper = middle - 1; - continue; - } - } - - /* Failed to find the matching attribute from the attribute table. */ - return (CKR_ATTRIBUTE_TYPE_INVALID); -} - - -/* - * Validate the attribute by using the following search algorithm: - * - * 1) Search for the most frequently used attributes first. - * 2) If not found, search for the usage-purpose attributes - these - * attributes have dense set of values, therefore compiler will - * optimize it with a branch table and branch to the appropriate - * case. - * 3) If still not found, use binary search for the rest of the - * attributes in the attr_map[] table. - */ -CK_RV -kms_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum, - CK_OBJECT_CLASS *class) -{ - - CK_ULONG i; - CK_RV rv = CKR_OK; - - for (i = 0; i < ulAttrNum; i++) { - /* First tier search */ - switch (template[i].type) { - case CKA_CLASS: - *class = *((CK_OBJECT_CLASS*)template[i].pValue); - break; - case CKA_TOKEN: - break; - case CKA_KEY_TYPE: - break; - case CKA_VALUE: - break; - case CKA_VALUE_LEN: - break; - case CKA_VALUE_BITS: - break; - default: - /* Second tier search */ - switch (template[i].type) { - case CKA_ENCRYPT: - break; - case CKA_DECRYPT: - break; - case CKA_WRAP: - break; - case CKA_UNWRAP: - break; - case CKA_SIGN: - break; - case CKA_SIGN_RECOVER: - break; - case CKA_VERIFY: - break; - case CKA_VERIFY_RECOVER: - break; - case CKA_DERIVE: - break; - default: - /* Third tier search */ - rv = kms_lookup_attr(template[i].type); - if (rv != CKR_OK) - return (rv); - break; - } - break; - } - } - return (rv); -} - - -/* - * Clean up and release all the storage in the extra attribute list - * of an object. - */ -void -kms_cleanup_extra_attr(kms_object_t *object_p) -{ - - CK_ATTRIBUTE_INFO_PTR extra_attr; - CK_ATTRIBUTE_INFO_PTR tmp; - - if (object_p == NULL) - return; - - extra_attr = object_p->extra_attrlistp; - while (extra_attr) { - tmp = extra_attr->next; - if (extra_attr->attr.pValue) - /* - * All extra attributes in the extra attribute - * list have pValue points to the value of the - * attribute (with simple byte array type). - * Free the storage for the value of the attribute. - */ - free(extra_attr->attr.pValue); - - /* Free the storage for the attribute_info struct. */ - free(extra_attr); - extra_attr = tmp; - } - - object_p->extra_attrlistp = NULL; -} - -/* - * Create the attribute_info struct to hold the object's attribute, - * and add it to the extra attribute list of an object. - */ -CK_RV -kms_add_extra_attr(CK_ATTRIBUTE_PTR template, kms_object_t *object_p) -{ - - CK_ATTRIBUTE_INFO_PTR attrp; - - /* Allocate the storage for the attribute_info struct. */ - attrp = calloc(1, sizeof (attribute_info_t)); - if (attrp == NULL) { - return (CKR_HOST_MEMORY); - } - - /* Set up attribute_info struct. */ - attrp->attr.type = template->type; - attrp->attr.ulValueLen = template->ulValueLen; - - if ((template->pValue != NULL) && - (template->ulValueLen > 0)) { - /* Allocate storage for the value of the attribute. */ - attrp->attr.pValue = malloc(template->ulValueLen); - if (attrp->attr.pValue == NULL) { - free(attrp); - return (CKR_HOST_MEMORY); - } - - (void) memcpy(attrp->attr.pValue, template->pValue, - template->ulValueLen); - } else { - attrp->attr.pValue = NULL; - } - - /* Insert the new attribute in front of extra attribute list. */ - if (object_p->extra_attrlistp == NULL) { - object_p->extra_attrlistp = attrp; - attrp->next = NULL; - } else { - attrp->next = object_p->extra_attrlistp; - object_p->extra_attrlistp = attrp; - } - - return (CKR_OK); -} - -/* - * Copy the attribute_info struct from the old object to a new attribute_info - * struct, and add that new struct to the extra attribute list of the new - * object. - */ -CK_RV -kms_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, - kms_object_t *object_p) -{ - CK_ATTRIBUTE_INFO_PTR attrp; - - /* Allocate attribute_info struct. */ - attrp = calloc(1, sizeof (attribute_info_t)); - if (attrp == NULL) { - return (CKR_HOST_MEMORY); - } - - attrp->attr.type = old_attrp->attr.type; - attrp->attr.ulValueLen = old_attrp->attr.ulValueLen; - - if ((old_attrp->attr.pValue != NULL) && - (old_attrp->attr.ulValueLen > 0)) { - attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen); - if (attrp->attr.pValue == NULL) { - free(attrp); - return (CKR_HOST_MEMORY); - } - - (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue, - old_attrp->attr.ulValueLen); - } else { - attrp->attr.pValue = NULL; - } - - /* Insert the new attribute in front of extra attribute list */ - if (object_p->extra_attrlistp == NULL) { - object_p->extra_attrlistp = attrp; - attrp->next = NULL; - } else { - attrp->next = object_p->extra_attrlistp; - object_p->extra_attrlistp = attrp; - } - - return (CKR_OK); -} - -/* - * Get the attribute triple from the extra attribute list in the object - * (if the specified attribute type is found), and copy it to a template. - * Note the type of the attribute to be copied is specified by the template, - * and the storage is pre-allocated for the atrribute value in the template - * for doing the copy. - */ -CK_RV -get_extra_attr_from_object(kms_object_t *object_p, CK_ATTRIBUTE_PTR template) -{ - CK_ATTRIBUTE_INFO_PTR extra_attr; - CK_ATTRIBUTE_TYPE type = template->type; - - extra_attr = object_p->extra_attrlistp; - - while (extra_attr) { - if (type == extra_attr->attr.type) { - /* Found it. */ - break; - } else { - /* Does not match, try next one. */ - extra_attr = extra_attr->next; - } - } - - if (extra_attr == NULL) { - /* A valid but un-initialized attribute. */ - template->ulValueLen = 0; - return (CKR_OK); - } - - /* - * We found the attribute in the extra attribute list. - */ - if (template->pValue == NULL) { - template->ulValueLen = extra_attr->attr.ulValueLen; - return (CKR_OK); - } - - if (template->ulValueLen >= extra_attr->attr.ulValueLen) { - /* - * The buffer provided by the application is large - * enough to hold the value of the attribute. - */ - (void) memcpy(template->pValue, extra_attr->attr.pValue, - extra_attr->attr.ulValueLen); - template->ulValueLen = extra_attr->attr.ulValueLen; - return (CKR_OK); - } else { - /* - * The buffer provided by the application does - * not have enough space to hold the value. - */ - template->ulValueLen = (CK_ULONG)-1; - return (CKR_BUFFER_TOO_SMALL); - } -} - -/* - * Modify the attribute triple in the extra attribute list of the object - * if the specified attribute type is found. Otherwise, just add it to - * list. - */ -CK_RV -set_extra_attr_to_object(kms_object_t *object_p, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE_PTR template) -{ - CK_ATTRIBUTE_INFO_PTR extra_attr; - - extra_attr = object_p->extra_attrlistp; - - while (extra_attr) { - if (type == extra_attr->attr.type) { - /* Found it. */ - break; - } else { - /* Does not match, try next one. */ - extra_attr = extra_attr->next; - } - } - - if (extra_attr == NULL) { - /* - * This attribute is a new one, go ahead adding it to - * the extra attribute list. - */ - return (kms_add_extra_attr(template, object_p)); - } - - /* We found the attribute in the extra attribute list. */ - if ((template->pValue != NULL) && - (template->ulValueLen > 0)) { - if (template->ulValueLen > extra_attr->attr.ulValueLen) { - /* The old buffer is too small to hold the new value. */ - if (extra_attr->attr.pValue != NULL) - /* Free storage for the old attribute value. */ - free(extra_attr->attr.pValue); - - /* Allocate storage for the new attribute value. */ - extra_attr->attr.pValue = malloc(template->ulValueLen); - if (extra_attr->attr.pValue == NULL) { - return (CKR_HOST_MEMORY); - } - } - - /* Replace the attribute with new value. */ - extra_attr->attr.ulValueLen = template->ulValueLen; - (void) memcpy(extra_attr->attr.pValue, template->pValue, - template->ulValueLen); - } else { - extra_attr->attr.pValue = NULL; - } - - return (CKR_OK); -} - -/* - * Copy the boolean data type attribute value from an object for the - * specified attribute to the template. - */ -CK_RV -get_bool_attr_from_object(kms_object_t *object_p, CK_ULONG bool_flag, - CK_ATTRIBUTE_PTR template) -{ - - if (template->pValue == NULL) { - template->ulValueLen = sizeof (CK_BBOOL); - return (CKR_OK); - } - - if (template->ulValueLen >= sizeof (CK_BBOOL)) { - /* - * The buffer provided by the application is large - * enough to hold the value of the attribute. - */ - if (object_p->bool_attr_mask & bool_flag) { - *((CK_BBOOL *)template->pValue) = B_TRUE; - } else { - *((CK_BBOOL *)template->pValue) = B_FALSE; - } - - template->ulValueLen = sizeof (CK_BBOOL); - return (CKR_OK); - } else { - /* - * The buffer provided by the application does - * not have enough space to hold the value. - */ - template->ulValueLen = (CK_ULONG)-1; - return (CKR_BUFFER_TOO_SMALL); - } -} - -/* - * Set the boolean data type attribute value in the object. - */ -CK_RV -set_bool_attr_to_object(kms_object_t *object_p, CK_ULONG bool_flag, - CK_ATTRIBUTE_PTR template) -{ - - if (*(CK_BBOOL *)template->pValue) - object_p->bool_attr_mask |= bool_flag; - else - object_p->bool_attr_mask &= ~bool_flag; - - return (CKR_OK); -} - - -/* - * Copy the CK_ULONG data type attribute value from an object to the - * template. - */ -CK_RV -get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template) -{ - - if (template->pValue == NULL) { - template->ulValueLen = sizeof (CK_ULONG); - return (CKR_OK); - } - - if (template->ulValueLen >= sizeof (CK_ULONG)) { - /* - * The buffer provided by the application is large - * enough to hold the value of the attribute. - */ - *(CK_ULONG_PTR)template->pValue = value; - template->ulValueLen = sizeof (CK_ULONG); - return (CKR_OK); - } else { - /* - * The buffer provided by the application does - * not have enough space to hold the value. - */ - template->ulValueLen = (CK_ULONG)-1; - return (CKR_BUFFER_TOO_SMALL); - } -} - -CK_RV -get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src) -{ - if ((src->pValue != NULL) && - (src->ulValueLen > 0)) { - /* Allocate storage for the value of the attribute. */ - dest->pValue = malloc(src->ulValueLen); - if (dest->pValue == NULL) { - return (CKR_HOST_MEMORY); - } - - (void) memcpy(dest->pValue, src->pValue, - src->ulValueLen); - dest->ulValueLen = src->ulValueLen; - dest->type = src->type; - } else { - dest->pValue = NULL; - dest->ulValueLen = 0; - dest->type = src->type; - } - - return (CKR_OK); - -} - -void -string_attr_cleanup(CK_ATTRIBUTE_PTR template) -{ - - if (template->pValue) { - free(template->pValue); - template->pValue = NULL; - template->ulValueLen = 0; - } -} - -/* - * Parse the common attributes. Return to caller with appropriate return - * value to indicate if the supplied template specifies a valid attribute - * with a valid value. - */ -static CK_RV -kms_parse_common_attrs(CK_ATTRIBUTE_PTR template, uint64_t *attr_mask_p) -{ - CK_RV rv = CKR_OK; - kms_slot_t *pslot = get_slotinfo(); - - switch (template->type) { - case CKA_CLASS: - break; - case CKA_TOKEN: - if ((*(CK_BBOOL *)template->pValue) == TRUE) - *attr_mask_p |= TOKEN_BOOL_ON; - break; - - case CKA_PRIVATE: - if ((*(CK_BBOOL *)template->pValue) == TRUE) { - /* - * Cannot create a private object if the token - * has a keystore and the user isn't logged in. - */ - if (pslot->sl_state != CKU_USER) { - rv = CKR_ATTRIBUTE_VALUE_INVALID; - } else { - *attr_mask_p |= PRIVATE_BOOL_ON; - } - } - break; - - case CKA_MODIFIABLE: - if ((*(CK_BBOOL *)template->pValue) == FALSE) { - *attr_mask_p &= ~MODIFIABLE_BOOL_ON; - } - break; - - case CKA_LABEL: - break; - - default: - rv = CKR_TEMPLATE_INCONSISTENT; - } - - return (rv); -} - -/* - * Build a Secret Key Object. - * - * - Parse the object's template, and when an error is detected such as - * invalid attribute type, invalid attribute value, etc., return - * with appropriate return value. - * - Set up attribute mask field in the object for the supplied common - * attributes that have boolean type. - * - Build the attribute_info struct to hold the value of each supplied - * attribute that has byte array type. Link attribute_info structs - * together to form the extra attribute list of the object. - * - Allocate storage for the Secret Key object. - * - Build the Secret Key object. Allocate storage to hold the big integer - * value for the attribute CKA_VALUE that is required for all the key - * types supported by secret key object. - * - */ -CK_RV -kms_build_secret_key_object(CK_ATTRIBUTE_PTR template, - CK_ULONG ulAttrNum, kms_object_t *new_object) -{ - int i; - CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL; - uint64_t attr_mask; - CK_RV rv = CKR_OK; - int isLabel = 0; - /* Must not set flags */ - int isValueLen = 0; - CK_ATTRIBUTE string_tmp; - secret_key_obj_t *sck; - - string_tmp.pValue = NULL; - - /* - * If the object was pulled from the KMS, the - * attributes are encoded in the object record - * before this function is called, we don't - * want to overwrite them unless the attribute - * template says differently. - */ - if (new_object->bool_attr_mask != 0) - attr_mask = new_object->bool_attr_mask; - else - attr_mask = SECRET_KEY_DEFAULT; - - /* Allocate storage for Secret Key Object. */ - sck = calloc(1, sizeof (secret_key_obj_t)); - if (sck == NULL) { - rv = CKR_HOST_MEMORY; - goto fail_cleanup; - } - - new_object->object_class_u.secret_key = sck; - new_object->class = CKO_SECRET_KEY; - - for (i = 0; i < ulAttrNum; i++) { - - /* Secret Key Object Attributes */ - switch (template[i].type) { - - /* common key attributes */ - case CKA_KEY_TYPE: - keytype = *((CK_KEY_TYPE*)template[i].pValue); - break; - - case CKA_ID: - case CKA_START_DATE: - case CKA_END_DATE: - /* - * Allocate storage to hold the attribute - * value with byte array type, and add it to - * the extra attribute list of the object. - */ - rv = kms_add_extra_attr(&template[i], - new_object); - if (rv != CKR_OK) { - goto fail_cleanup; - } - break; - - /* - * The following key related attribute types must - * not be specified by C_CreateObject. - */ - case CKA_LOCAL: - case CKA_KEY_GEN_MECHANISM: - case CKA_ALWAYS_SENSITIVE: - case CKA_NEVER_EXTRACTABLE: - rv = CKR_TEMPLATE_INCONSISTENT; - goto fail_cleanup; - - /* Key related boolean attributes */ - case CKA_DERIVE: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= DERIVE_BOOL_ON; - break; - - case CKA_SENSITIVE: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= SENSITIVE_BOOL_ON; - break; - - case CKA_ENCRYPT: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= ENCRYPT_BOOL_ON; - else - attr_mask &= ~ENCRYPT_BOOL_ON; - break; - - case CKA_DECRYPT: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= DECRYPT_BOOL_ON; - else - attr_mask &= ~DECRYPT_BOOL_ON; - break; - - case CKA_SIGN: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= SIGN_BOOL_ON; - else - attr_mask &= ~SIGN_BOOL_ON; - break; - - case CKA_VERIFY: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= VERIFY_BOOL_ON; - else - attr_mask &= ~VERIFY_BOOL_ON; - break; - - case CKA_WRAP: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= WRAP_BOOL_ON; - break; - - case CKA_UNWRAP: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= UNWRAP_BOOL_ON; - break; - - case CKA_EXTRACTABLE: - if (*(CK_BBOOL *)template[i].pValue) - attr_mask |= EXTRACTABLE_BOOL_ON; - else - attr_mask &= ~EXTRACTABLE_BOOL_ON; - break; - - case CKA_VALUE: - if ((template[i].ulValueLen == 0) || - (template[i].pValue == NULL)) { - rv = CKR_ATTRIBUTE_VALUE_INVALID; - goto fail_cleanup; - } - /* - * Copyin attribute from template - * to a local variable. - */ - sck->sk_value = malloc(template[i].ulValueLen); - if (sck->sk_value == NULL) { - rv = CKR_HOST_MEMORY; - goto fail_cleanup; - } - (void) memcpy(sck->sk_value, template[i].pValue, - template[i].ulValueLen); - sck->sk_value_len = template[i].ulValueLen; - break; - - case CKA_VALUE_LEN: - isValueLen = 1; - if (template[i].pValue != NULL) - sck->sk_value_len = - *(CK_ULONG_PTR)template[i].pValue; - else - sck->sk_value_len = 0; - break; - - case CKA_LABEL: - isLabel = 1; - rv = get_string_from_template(&string_tmp, - &template[i]); - if (rv != CKR_OK) - goto fail_cleanup; - break; - - default: - rv = kms_parse_common_attrs(&template[i], &attr_mask); - if (rv != CKR_OK) - goto fail_cleanup; - break; - - } - } /* For */ - - if (keytype == (CK_KEY_TYPE)~0UL) { - rv = CKR_TEMPLATE_INCOMPLETE; - goto fail_cleanup; - } - - new_object->key_type = keytype; - - /* Supported key types of the Secret Key Object */ - switch (keytype) { - - case CKK_AES: - if (!isValueLen) { - rv = CKR_TEMPLATE_INCOMPLETE; - goto fail_cleanup; - } - if (sck->sk_value_len != AES_MIN_KEY_BYTES && - sck->sk_value_len != AES_192_KEY_BYTES && - sck->sk_value_len != AES_MAX_KEY_BYTES) { - rv = CKR_ATTRIBUTE_VALUE_INVALID; - goto fail_cleanup; - } - break; - - case CKK_RC4: - case CKK_GENERIC_SECRET: - case CKK_BLOWFISH: - case CKK_DES: - case CKK_DES2: - case CKK_DES3: - default: - rv = CKR_TEMPLATE_INCONSISTENT; - goto fail_cleanup; - } - - /* Set up object. */ - new_object->bool_attr_mask = attr_mask; - if (isLabel) { - rv = kms_add_extra_attr(&string_tmp, new_object); - if (rv != CKR_OK) - goto fail_cleanup; - string_attr_cleanup(&string_tmp); - } - - return (rv); - -fail_cleanup: - /* - * cleanup the storage allocated to the local variables. - */ - string_attr_cleanup(&string_tmp); - - /* - * cleanup the storage allocated inside the object itself. - */ - kms_cleanup_object(new_object); - - return (rv); -} - -/* - * Validate the attribute types in the object's template. Then, - * call the appropriate build function according to the class of - * the object specified in the template. - * - * Note: The following classes of objects are supported: - * - CKO_SECRET_KEY - */ -CK_RV -kms_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum, - kms_object_t *new_object) -{ - CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL; - CK_RV rv = CKR_OK; - - if (template == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - /* Validate the attribute type in the template. */ - rv = kms_validate_attr(template, ulAttrNum, &class); - if (rv != CKR_OK) - return (rv); - - if (class == (CK_OBJECT_CLASS)~0UL) - return (CKR_TEMPLATE_INCOMPLETE); - - /* - * Call the appropriate function based on the supported class - * of the object. - */ - switch (class) { - - case CKO_SECRET_KEY: - rv = kms_build_secret_key_object(template, ulAttrNum, - new_object); - break; - - case CKO_DOMAIN_PARAMETERS: - case CKO_DATA: - case CKO_CERTIFICATE: - case CKO_HW_FEATURE: - case CKO_VENDOR_DEFINED: - case CKO_PUBLIC_KEY: - case CKO_PRIVATE_KEY: - default: - return (CKR_ATTRIBUTE_VALUE_INVALID); - } - - return (rv); -} - - -/* - * Get the value of a requested attribute that is common to all supported - * classes (i.e. public key, private key, secret key classes). - */ -CK_RV -kms_get_common_attrs(kms_object_t *object_p, CK_ATTRIBUTE_PTR template) -{ - - CK_RV rv = CKR_OK; - - switch (template->type) { - - case CKA_CLASS: - return (get_ulong_attr_from_object(object_p->class, - template)); - - /* default boolean attributes */ - case CKA_TOKEN: - template->ulValueLen = sizeof (CK_BBOOL); - if (template->pValue == NULL) { - return (CKR_OK); - } - - *((CK_BBOOL *)template->pValue) = B_FALSE; - break; - - case CKA_PRIVATE: - - template->ulValueLen = sizeof (CK_BBOOL); - if (template->pValue == NULL) { - return (CKR_OK); - } - if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) { - *((CK_BBOOL *)template->pValue) = B_TRUE; - } else { - *((CK_BBOOL *)template->pValue) = B_FALSE; - } - break; - - case CKA_MODIFIABLE: - template->ulValueLen = sizeof (CK_BBOOL); - if (template->pValue == NULL) { - return (CKR_OK); - } - if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON) - *((CK_BBOOL *)template->pValue) = B_TRUE; - else - *((CK_BBOOL *)template->pValue) = B_FALSE; - break; - - case CKA_LABEL: - return (get_extra_attr_from_object(object_p, - template)); - - default: - /* - * The specified attribute for the object is invalid. - * (the object does not possess such an attribute.) - */ - template->ulValueLen = (CK_ULONG)-1; - return (CKR_ATTRIBUTE_TYPE_INVALID); - } - - return (rv); -} - -/* - * Get the value of a requested attribute that is common to all key objects - * (i.e. public key, private key and secret key). - */ -CK_RV -kms_get_common_key_attrs(kms_object_t *object_p, - CK_ATTRIBUTE_PTR template) -{ - - switch (template->type) { - - case CKA_KEY_TYPE: - return (get_ulong_attr_from_object(object_p->key_type, - template)); - - case CKA_ID: - case CKA_START_DATE: - case CKA_END_DATE: - /* - * The above extra attributes have byte array type. - */ - return (get_extra_attr_from_object(object_p, - template)); - - /* Key related boolean attributes */ - case CKA_LOCAL: - return (get_bool_attr_from_object(object_p, - LOCAL_BOOL_ON, template)); - - case CKA_DERIVE: - return (get_bool_attr_from_object(object_p, - DERIVE_BOOL_ON, template)); - - case CKA_KEY_GEN_MECHANISM: - return (get_ulong_attr_from_object(object_p->mechanism, - template)); - - default: - return (CKR_ATTRIBUTE_TYPE_INVALID); - } -} - -/* - * Get the value of a requested attribute of a Secret Key Object. - * - * Rule: All the attributes in the secret key object can be revealed - * except those marked with footnote number "7" when the object - * has its CKA_SENSITIVE attribute set to TRUE or its - * CKA_EXTRACTABLE attribute set to FALSE. - */ -CK_RV -kms_get_secret_key_attribute(kms_object_t *object_p, - CK_ATTRIBUTE_PTR template) -{ - - CK_RV rv = CKR_OK; - CK_KEY_TYPE keytype = object_p->key_type; - - switch (template->type) { - - /* Key related boolean attributes */ - case CKA_SENSITIVE: - return (get_bool_attr_from_object(object_p, - SENSITIVE_BOOL_ON, template)); - - case CKA_ENCRYPT: - return (get_bool_attr_from_object(object_p, - ENCRYPT_BOOL_ON, template)); - - case CKA_DECRYPT: - return (get_bool_attr_from_object(object_p, - DECRYPT_BOOL_ON, template)); - - case CKA_SIGN: - return (get_bool_attr_from_object(object_p, - SIGN_BOOL_ON, template)); - - case CKA_VERIFY: - return (get_bool_attr_from_object(object_p, - VERIFY_BOOL_ON, template)); - - case CKA_WRAP: - return (get_bool_attr_from_object(object_p, - WRAP_BOOL_ON, template)); - - case CKA_UNWRAP: - return (get_bool_attr_from_object(object_p, - UNWRAP_BOOL_ON, template)); - - case CKA_EXTRACTABLE: - return (get_bool_attr_from_object(object_p, - EXTRACTABLE_BOOL_ON, template)); - - case CKA_ALWAYS_SENSITIVE: - return (get_bool_attr_from_object(object_p, - ALWAYS_SENSITIVE_BOOL_ON, template)); - - case CKA_NEVER_EXTRACTABLE: - return (get_bool_attr_from_object(object_p, - NEVER_EXTRACTABLE_BOOL_ON, template)); - - case CKA_VALUE: - /* - * If the specified attribute for the secret key object - * cannot be revealed because the object is sensitive - * or unextractable, then the ulValueLen is set to -1. - */ - if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) || - !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { - template->ulValueLen = (CK_ULONG)-1; - return (CKR_ATTRIBUTE_SENSITIVE); - } - - switch (keytype) { - case CKK_AES: - /* - * Copy secret key object attributes to template. - */ - if (template->pValue == NULL) { - template->ulValueLen = - OBJ_SEC_VALUE_LEN(object_p); - return (CKR_OK); - } - - if (OBJ_SEC_VALUE(object_p) == NULL) { - template->ulValueLen = 0; - return (CKR_OK); - } - - if (template->ulValueLen >= - OBJ_SEC_VALUE_LEN(object_p)) { - (void) memcpy(template->pValue, - OBJ_SEC_VALUE(object_p), - OBJ_SEC_VALUE_LEN(object_p)); - template->ulValueLen = - OBJ_SEC_VALUE_LEN(object_p); - return (CKR_OK); - } else { - template->ulValueLen = (CK_ULONG)-1; - return (CKR_BUFFER_TOO_SMALL); - } - - case CKK_RC4: - case CKK_GENERIC_SECRET: - case CKK_RC5: - case CKK_DES: - case CKK_DES2: - case CKK_DES3: - case CKK_CDMF: - case CKK_BLOWFISH: - default: - template->ulValueLen = (CK_ULONG)-1; - rv = CKR_ATTRIBUTE_TYPE_INVALID; - break; - } - break; - - case CKA_VALUE_LEN: - return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p), - template)); - - default: - /* - * First, get the value of the request attribute defined - * in the list of common key attributes. If the request - * attribute is not found in that list, then get the - * attribute from the list of common attributes. - */ - rv = kms_get_common_key_attrs(object_p, template); - if (rv == CKR_ATTRIBUTE_TYPE_INVALID) { - rv = kms_get_common_attrs(object_p, template); - } - break; - } - - return (rv); - -} - -/* - * Call the appropriate get attribute function according to the class - * of object. - * - * The caller of this function holds the lock on the object. - */ -CK_RV -kms_get_attribute(kms_object_t *object_p, CK_ATTRIBUTE_PTR template) -{ - - CK_RV rv = CKR_OK; - CK_OBJECT_CLASS class = object_p->class; - - switch (class) { - case CKO_SECRET_KEY: - rv = kms_get_secret_key_attribute(object_p, template); - break; - - case CKO_PRIVATE_KEY: - case CKO_PUBLIC_KEY: - default: - /* - * If the specified attribute for the object is invalid - * (the object does not possess such as attribute), then - * the ulValueLen is modified to hold the value -1. - */ - template->ulValueLen = (CK_ULONG)-1; - return (CKR_ATTRIBUTE_TYPE_INVALID); - } - - return (rv); - -} - -/* - * Set the value of an attribute that is common to all key objects - * (i.e. public key, private key and secret key). - */ -static CK_RV -kms_set_common_key_attribute(kms_object_t *object_p, - CK_ATTRIBUTE_PTR template, boolean_t copy) -{ - - kms_slot_t *pslot = get_slotinfo(); - CK_RV rv = CKR_OK; - - switch (template->type) { - - case CKA_LABEL: - /* - * Only the LABEL can be modified in the common storage - * object attributes after the object is created. - */ - return (set_extra_attr_to_object(object_p, - CKA_LABEL, template)); - - case CKA_ID: - return (set_extra_attr_to_object(object_p, - CKA_ID, template)); - - case CKA_START_DATE: - return (set_extra_attr_to_object(object_p, - CKA_START_DATE, template)); - - case CKA_END_DATE: - return (set_extra_attr_to_object(object_p, - CKA_END_DATE, template)); - - case CKA_DERIVE: - return (set_bool_attr_to_object(object_p, - DERIVE_BOOL_ON, template)); - - case CKA_CLASS: - case CKA_KEY_TYPE: - case CKA_LOCAL: - return (CKR_ATTRIBUTE_READ_ONLY); - - case CKA_PRIVATE: - if (!copy) { - /* called from C_SetAttributeValue() */ - return (CKR_ATTRIBUTE_READ_ONLY); - } - - /* called from C_CopyObject() */ - if ((*(CK_BBOOL *)template->pValue) != B_TRUE) { - return (CKR_OK); - } - - (void) pthread_mutex_lock(&pslot->sl_mutex); - /* - * Cannot create a private object if the token - * has a keystore and the user isn't logged in. - */ - if (pslot->sl_state != CKU_USER) { - rv = CKR_USER_NOT_LOGGED_IN; - } else { - rv = set_bool_attr_to_object(object_p, - PRIVATE_BOOL_ON, template); - } - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); - - case CKA_MODIFIABLE: - if (copy) { - rv = set_bool_attr_to_object(object_p, - MODIFIABLE_BOOL_ON, template); - } else { - rv = CKR_ATTRIBUTE_READ_ONLY; - } - return (rv); - - default: - return (CKR_TEMPLATE_INCONSISTENT); - } - -} - -/* - * Set the value of an attribute of a Secret Key Object. - * - * Rule: The attributes marked with footnote number "8" in the PKCS11 - * spec may be modified (p.88 in PKCS11 spec.). - */ -static CK_RV -kms_set_secret_key_attribute(kms_object_t *object_p, - CK_ATTRIBUTE_PTR template, boolean_t copy) -{ - CK_KEY_TYPE keytype = object_p->key_type; - - switch (template->type) { - - case CKA_SENSITIVE: - /* - * Cannot set SENSITIVE to FALSE if it is already ON. - */ - if (((*(CK_BBOOL *)template->pValue) == B_FALSE) && - (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) { - return (CKR_ATTRIBUTE_READ_ONLY); - } - - if (*(CK_BBOOL *)template->pValue) - object_p->bool_attr_mask |= SENSITIVE_BOOL_ON; - return (CKR_OK); - - case CKA_ENCRYPT: - return (set_bool_attr_to_object(object_p, - ENCRYPT_BOOL_ON, template)); - - case CKA_DECRYPT: - return (set_bool_attr_to_object(object_p, - DECRYPT_BOOL_ON, template)); - - case CKA_SIGN: - return (set_bool_attr_to_object(object_p, - SIGN_BOOL_ON, template)); - - case CKA_VERIFY: - return (set_bool_attr_to_object(object_p, - VERIFY_BOOL_ON, template)); - - case CKA_WRAP: - return (set_bool_attr_to_object(object_p, - WRAP_BOOL_ON, template)); - - case CKA_UNWRAP: - return (set_bool_attr_to_object(object_p, - UNWRAP_BOOL_ON, template)); - - case CKA_EXTRACTABLE: - /* - * Cannot set EXTRACTABLE to TRUE if it is already OFF. - */ - if ((*(CK_BBOOL *)template->pValue) && - !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { - return (CKR_ATTRIBUTE_READ_ONLY); - } - - if ((*(CK_BBOOL *)template->pValue) == B_FALSE) - object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON; - return (CKR_OK); - - case CKA_VALUE: - return (CKR_ATTRIBUTE_READ_ONLY); - - case CKA_VALUE_LEN: - if ((keytype == CKK_RC4) || - (keytype == CKK_GENERIC_SECRET) || - (keytype == CKK_AES) || - (keytype == CKK_BLOWFISH)) - return (CKR_ATTRIBUTE_READ_ONLY); - break; - - default: - /* - * Set the value of a common key attribute. - */ - return (kms_set_common_key_attribute(object_p, - template, copy)); - } - - /* - * If we got this far, then the combination of key type - * and requested attribute is invalid. - */ - return (CKR_ATTRIBUTE_TYPE_INVALID); -} - -/* - * Call the appropriate set attribute function according to the class - * of object. - * - * The caller of this function does not hold the lock on the original - * object, since this function is setting the attribute on the new object - * that is being modified. - * - */ -CK_RV -kms_set_attribute(kms_object_t *object_p, CK_ATTRIBUTE_PTR template, - boolean_t copy) -{ - - CK_RV rv = CKR_OK; - CK_OBJECT_CLASS class = object_p->class; - - switch (class) { - - case CKO_SECRET_KEY: - rv = kms_set_secret_key_attribute(object_p, template, - copy); - break; - - case CKO_PUBLIC_KEY: - case CKO_PRIVATE_KEY: - default: - /* - * If the template specifies a value of an attribute - * which is incompatible with other existing attributes - * of the object, then fails with return code - * CKR_TEMPLATE_INCONSISTENT. - */ - rv = CKR_TEMPLATE_INCONSISTENT; - break; - } - - return (rv); -} - -CK_RV -kms_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p, - secret_key_obj_t **new_secret_key_obj_p) -{ - secret_key_obj_t *sk; - - sk = malloc(sizeof (secret_key_obj_t)); - if (sk == NULL) { - return (CKR_HOST_MEMORY); - } - (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t)); - - /* copy the secret key value */ - sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len)); - if (sk->sk_value == NULL) { - free(sk); - return (CKR_HOST_MEMORY); - } - (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value, - (sizeof (CK_BYTE) * sk->sk_value_len)); - - *new_secret_key_obj_p = sk; - - return (CKR_OK); -} - - - -/* - * If CKA_CLASS not given, guess CKA_CLASS using - * attributes on template. - * - * Some attributes are specific to an object class. If one or more - * of these attributes are in the template, make a list of classes - * that can have these attributes. This would speed up the search later, - * because we can immediately skip an object if the class of that - * object can not possibly contain one of the attributes. - * - */ -void -kms_process_find_attr(CK_OBJECT_CLASS *pclasses, - CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount) -{ - ulong_t i; - int j; - boolean_t secret_found = B_FALSE; - int num_secret_key_attrs; - int num_pclasses = 0; - - for (i = 0; i < ulCount; i++) { - if (pTemplate[i].type == CKA_CLASS) { - /* - * don't need to guess the class, it is specified. - * Just record the class, and return. - */ - pclasses[0] = - (*((CK_OBJECT_CLASS *)pTemplate[i].pValue)); - *num_result_pclasses = 1; - return; - } - } - - num_secret_key_attrs = - sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE); - - /* - * Get the list of objects class that might contain - * some attributes. - */ - for (i = 0; i < ulCount; i++) { - if (!secret_found) { - for (j = 0; j < num_secret_key_attrs; j++) { - if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) { - secret_found = B_TRUE; - pclasses[num_pclasses++] = - CKO_SECRET_KEY; - break; - } - } - } - } - *num_result_pclasses = num_pclasses; -} - - -boolean_t -kms_find_match_attrs(kms_object_t *obj, CK_OBJECT_CLASS *pclasses, - CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr) -{ - ulong_t i; - CK_ATTRIBUTE *tmpl_attr, *obj_attr; - uint64_t attr_mask; - boolean_t compare_attr, compare_boolean; - - /* - * Check if the class of this object match with any - * of object classes that can possibly contain the - * requested attributes. - */ - if (num_pclasses > 0) { - for (i = 0; i < num_pclasses; i++) { - if (obj->class == pclasses[i]) { - break; - } - } - if (i == num_pclasses) { - /* - * this object can't possibly contain one or - * more attributes, don't need to check this object - */ - return (B_FALSE); - } - } - - /* need to examine everything */ - for (i = 0; i < num_attr; i++) { - tmpl_attr = &(template[i]); - compare_attr = B_FALSE; - compare_boolean = B_FALSE; - switch (tmpl_attr->type) { - /* First, check the most common attributes */ - case CKA_CLASS: - if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) != - obj->class) { - return (B_FALSE); - } - break; - case CKA_KEY_TYPE: - if (*((CK_KEY_TYPE *)tmpl_attr->pValue) != - obj->key_type) { - return (B_FALSE); - } - break; - case CKA_ENCRYPT: - attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_DECRYPT: - attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_WRAP: - attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_UNWRAP: - attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_SIGN: - attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_SIGN_RECOVER: - attr_mask = (obj->bool_attr_mask) & - SIGN_RECOVER_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_VERIFY: - attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_VERIFY_RECOVER: - attr_mask = (obj->bool_attr_mask) & - VERIFY_RECOVER_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_DERIVE: - attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_LOCAL: - attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_SENSITIVE: - attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_SECONDARY_AUTH: - attr_mask = (obj->bool_attr_mask) & - SECONDARY_AUTH_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_TRUSTED: - attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_EXTRACTABLE: - attr_mask = (obj->bool_attr_mask) & - EXTRACTABLE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_ALWAYS_SENSITIVE: - attr_mask = (obj->bool_attr_mask) & - ALWAYS_SENSITIVE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_NEVER_EXTRACTABLE: - attr_mask = (obj->bool_attr_mask) & - NEVER_EXTRACTABLE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_TOKEN: - attr_mask = (obj->bool_attr_mask) & TOKEN_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_PRIVATE: - attr_mask = (obj->bool_attr_mask) & PRIVATE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_MODIFIABLE: - attr_mask = (obj->bool_attr_mask) & MODIFIABLE_BOOL_ON; - compare_boolean = B_TRUE; - break; - case CKA_SUBJECT: - case CKA_ID: - case CKA_START_DATE: - case CKA_END_DATE: - case CKA_KEY_GEN_MECHANISM: - case CKA_LABEL: - /* find these attributes from extra_attrlistp */ - obj_attr = get_extra_attr(tmpl_attr->type, obj); - compare_attr = B_TRUE; - break; - case CKA_VALUE_LEN: - /* only secret key has this attribute */ - if (obj->class == CKO_SECRET_KEY) { - if (*((CK_ULONG *)tmpl_attr->pValue) != - OBJ_SEC_VALUE_LEN(obj)) { - return (B_FALSE); - } - } else { - return (B_FALSE); - } - break; - case CKA_VALUE: - switch (obj->class) { - case CKO_SECRET_KEY: - break; - default: - return (B_FALSE); - } - break; - case CKA_VALUE_BITS: - case CKA_PRIME_BITS: - case CKA_SUBPRIME_BITS: - default: - /* - * any other attributes are currently not supported. - * so, it's not possible for them to be in the - * object - */ - return (B_FALSE); - } - if (compare_boolean) { - CK_BBOOL bval; - - if (attr_mask) { - bval = TRUE; - } else { - bval = FALSE; - } - if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) { - return (B_FALSE); - } - } else if (compare_attr) { - if (obj_attr == NULL) { - /* - * The attribute type is valid, and its value - * has not been initialized in the object. In - * this case, it only matches the template's - * attribute if the template's value length - * is 0. - */ - if (tmpl_attr->ulValueLen != 0) - return (B_FALSE); - } else { - if (tmpl_attr->ulValueLen != - obj_attr->ulValueLen) { - return (B_FALSE); - } - if (memcmp(tmpl_attr->pValue, obj_attr->pValue, - tmpl_attr->ulValueLen) != 0) { - return (B_FALSE); - } - } - } - } - return (B_TRUE); -} - -CK_ATTRIBUTE_PTR -get_extra_attr(CK_ATTRIBUTE_TYPE type, kms_object_t *obj) -{ - CK_ATTRIBUTE_INFO_PTR tmp; - - tmp = obj->extra_attrlistp; - while (tmp != NULL) { - if (tmp->attr.type == type) { - return (&(tmp->attr)); - } - tmp = tmp->next; - } - /* if get there, the specified attribute is not found */ - return (NULL); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsCrypt.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsCrypt.h deleted file mode 100644 index ade758af93..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsCrypt.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KMSCRYPT_H -#define _KMSCRYPT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <security/pkcs11t.h> -#ifdef USESOLARIS_AES -#include <modes/modes.h> -#else -#include <aes_cbc_crypt.h> -#define CBC_MODE AES_CBC_MODE -#endif -#include <aes_impl.h> -#include "kmsObject.h" -#include "kmsSession.h" - -typedef struct kms_aes_ctx { - void *key_sched; /* pointer to key schedule */ - size_t keysched_len; /* Length of the key schedule */ - uint8_t ivec[AES_BLOCK_LEN]; /* initialization vector */ - uint8_t data[AES_BLOCK_LEN]; /* for use by update */ - size_t remain_len; /* for use by update */ - void *aes_cbc; /* to be used by CBC mode */ -} kms_aes_ctx_t; - -/* - * Function Prototypes. - */ -void *aes_cbc_ctx_init(void *, size_t, uint8_t *); - -CK_RV kms_aes_crypt_init_common(kms_session_t *, CK_MECHANISM_PTR, - kms_object_t *, boolean_t); - -CK_RV kms_aes_encrypt_common(kms_session_t *, CK_BYTE_PTR, CK_ULONG, - CK_BYTE_PTR, CK_ULONG_PTR, boolean_t); - -CK_RV kms_aes_decrypt_common(kms_session_t *, CK_BYTE_PTR, CK_ULONG, - CK_BYTE_PTR, CK_ULONG_PTR, boolean_t); - -CK_RV kms_aes_encrypt_final(kms_session_t *, CK_BYTE_PTR, CK_ULONG_PTR); -CK_RV kms_aes_decrypt_final(kms_session_t *, CK_BYTE_PTR, CK_ULONG_PTR); - -void kms_crypt_cleanup(kms_session_t *, boolean_t, boolean_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMSCRYPT_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDecrypt.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDecrypt.c deleted file mode 100644 index 96d4bdcb30..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDecrypt.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <string.h> -#include <strings.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsCrypt.h" - - -/* - * kms_decrypt_init() - * - * Arguments: - * session_p: pointer to kms_session_t struct - * pMechanism: pointer to CK_MECHANISM struct provided by application - * key_p: pointer to key kms_object_t struct - * - * Description: - * called by C_DecryptInit(). This function calls the corresponding - * decrypt init routine based on the mechanism. - * - * Returns: - * CKR_OK: success - * CKR_HOST_MEMORY: run out of system memory - * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism - * CKR_MECHANISM_INVALID: invalid mechanism type - * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use - * with the specified mechanism - */ -CK_RV -kms_decrypt_init(kms_session_t *session_p, CK_MECHANISM_PTR pMechanism, - kms_object_t *key_p) -{ - - CK_RV rv; - - switch (pMechanism->mechanism) { - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - { - kms_aes_ctx_t *kms_aes_ctx; - - if (key_p->key_type != CKK_AES) { - return (CKR_KEY_TYPE_INCONSISTENT); - } - - if ((pMechanism->pParameter == NULL) || - (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { - return (CKR_MECHANISM_PARAM_INVALID); - } - - rv = kms_aes_crypt_init_common(session_p, pMechanism, - key_p, B_FALSE); - - if (rv != CKR_OK) - return (rv); - - (void) pthread_mutex_lock(&session_p->session_mutex); - - kms_aes_ctx = (kms_aes_ctx_t *)session_p->decrypt.context; - - /* Save Initialization Vector (IV) in the context. */ - (void) memcpy(kms_aes_ctx->ivec, pMechanism->pParameter, - AES_BLOCK_LEN); - - /* Allocate a context for AES cipher-block chaining. */ - kms_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( - kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len, - kms_aes_ctx->ivec); - - if (kms_aes_ctx->aes_cbc == NULL) { - bzero(kms_aes_ctx->key_sched, - kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - free(session_p->decrypt.context); - session_p->decrypt.context = NULL; - (void) pthread_mutex_unlock(&session_p->session_mutex); - return (CKR_HOST_MEMORY); - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - - return (rv); - } - default: - return (CKR_MECHANISM_INVALID); - } -} - -CK_RV -C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - CK_RV rv; - kms_session_t *session_p; - kms_object_t *key_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - if (pMechanism == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hKey, key_p, rv); - if (rv != CKR_OK) - goto clean_exit; - - /* Check to see if key object allows for decryption. */ - if (!(key_p->bool_attr_mask & DECRYPT_BOOL_ON)) { - rv = CKR_KEY_FUNCTION_NOT_PERMITTED; - goto clean_exit1; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* Check to see if decrypt operation is already active. */ - if (session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE) { - /* free the memory to avoid memory leak */ - kms_crypt_cleanup(session_p, B_FALSE, lock_held); - } - - /* - * This active flag will remain ON until application calls either - * C_Decrypt or C_DecryptFinal to actually obtain the final piece - * of plaintext. - */ - session_p->decrypt.flags = CRYPTO_OPERATION_ACTIVE; - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_decrypt_init(session_p, pMechanism, key_p); - - if (rv != CKR_OK) { - (void) pthread_mutex_lock(&session_p->session_mutex); - session_p->decrypt.flags &= ~CRYPTO_OPERATION_ACTIVE; - lock_held = B_TRUE; - } - -clean_exit1: - OBJ_REFRELE(key_p); -clean_exit: - REFRELE(session_p, lock_held); - return (rv); -} - -CK_RV -C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, - CK_ULONG ulEncryptedData, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) -{ - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obatin the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* - * Only check if input buffer is null. How to handle zero input - * length depents on the mechanism in use. For secret key mechanisms, - * unpadded ones yield zero length output, but padded ones always - * result in smaller than original, possibly zero, length output. - */ - if (pEncryptedData == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - /* - * No need to check pData because application might - * just want to know the length of decrypted data. - */ - if (pulDataLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* Application must call C_DecryptInit before calling C_Decrypt. */ - if (!(session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - /* - * C_Decrypt must be called without intervening C_DecryptUpdate - * calls. - */ - if (session_p->decrypt.flags & CRYPTO_OPERATION_UPDATE) { - /* - * C_Decrypt can not be used to terminate a multi-part - * operation, so we'll leave the active decrypt operation - * flag on and let the application continue with the - * decrypt update operation. - */ - REFRELE(session_p, lock_held); - return (CKR_FUNCTION_FAILED); - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_decrypt_common(session_p, pEncryptedData, - ulEncryptedData, pData, pulDataLen, FALSE); - - if ((rv == CKR_BUFFER_TOO_SMALL) || - (pData == NULL && rv == CKR_OK)) { - /* - * We will not terminate the active decrypt operation flag, - * when the application-supplied buffer is too small, or - * the application asks for the length of buffer to hold - * the plaintext. - */ - REFRELE(session_p, lock_held); - return (rv); - } - -clean_exit: - /* Clear context, free key, and release session counter */ - kms_crypt_cleanup(session_p, B_FALSE, B_FALSE); - - return (rv); -} - -CK_RV -C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, - CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, - CK_ULONG_PTR pulPartLen) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* - * Only check if input buffer is null. How to handle zero input - * length depents on the mechanism in use. For secret key mechanisms, - * unpadded ones yeild zero length output, but padded ones always - * result in smaller than original, possibly zero, length output. - */ - if (pEncryptedPart == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - /* - * Only check if pulPartLen is NULL. - * No need to check if pPart is NULL because application - * might just ask for the length of buffer to hold the - * recovered data. - */ - if (pulPartLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* - * Application must call C_DecryptInit before calling - * C_DecryptUpdate. - */ - if (!(session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - session_p->decrypt.flags |= CRYPTO_OPERATION_UPDATE; - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_decrypt_common(session_p, pEncryptedPart, - ulEncryptedPartLen, pPart, pulPartLen, B_TRUE); - - /* - * If CKR_OK or CKR_BUFFER_TOO_SMALL, don't terminate the - * current decryption operation. - */ - if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) { - REFRELE(session_p, lock_held); - return (rv); - } - -clean_exit: - /* - * After an error occurred, terminate the current decrypt - * operation by resetting the active and update flags. - */ - kms_crypt_cleanup(session_p, B_FALSE, lock_held); - - return (rv); -} - -CK_RV -C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, - CK_ULONG_PTR pulLastPartLen) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - if (pulLastPartLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* - * Application must call C_DecryptInit before calling - * C_DecryptFinal. - */ - if (!(session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_decrypt_final(session_p, pLastPart, pulLastPartLen); - - if ((rv == CKR_BUFFER_TOO_SMALL) || - (pLastPart == NULL && rv == CKR_OK)) { - /* - * We will not terminate the active decrypt operation flag, - * when the application-supplied buffer is too small, or - * the application asks for the length of buffer to hold - * the plaintext. - */ - REFRELE(session_p, lock_held); - return (rv); - } - - /* Terminates the active encrypt operation. */ - (void) pthread_mutex_lock(&session_p->session_mutex); - session_p->decrypt.flags = 0; - lock_held = B_TRUE; - REFRELE(session_p, lock_held); - return (rv); - -clean_exit: - /* Terminates the active decrypt operation */ - kms_crypt_cleanup(session_p, B_FALSE, lock_held); - - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDigest.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDigest.c deleted file mode 100644 index 5472ccb15b..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDigest.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <security/cryptoki.h> -#include "kmsGlobal.h" - -/*ARGSUSED*/ -CK_RV -C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, - CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDualCrypt.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDualCrypt.c deleted file mode 100644 index 1bde2b0946..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsDualCrypt.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - - -#include <security/cryptoki.h> -#include "kmsGlobal.h" - -/*ARGSUSED*/ -CK_RV -C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, - CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, - CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsEncrypt.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsEncrypt.c deleted file mode 100644 index 38ef8add89..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsEncrypt.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <string.h> -#include <strings.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsCrypt.h" - -static CK_RV -kms_encrypt_init(kms_session_t *session_p, CK_MECHANISM_PTR pMechanism, - kms_object_t *key_p) -{ - CK_RV rv = CKR_OK; - kms_aes_ctx_t *kms_aes_ctx; - - if (pMechanism->mechanism != CKM_AES_CBC && - pMechanism->mechanism != CKM_AES_CBC_PAD) - return (CKR_MECHANISM_INVALID); - - if (key_p->key_type != CKK_AES) { - return (CKR_KEY_TYPE_INCONSISTENT); - } - - if ((pMechanism->pParameter == NULL) || - (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { - return (CKR_MECHANISM_PARAM_INVALID); - } - - rv = kms_aes_crypt_init_common(session_p, pMechanism, - key_p, B_TRUE); - - if (rv != CKR_OK) - return (rv); - - (void) pthread_mutex_lock(&session_p->session_mutex); - - kms_aes_ctx = (kms_aes_ctx_t *)session_p->encrypt.context; - /* Copy Initialization Vector (IV) into the context. */ - - (void) memcpy(kms_aes_ctx->ivec, pMechanism->pParameter, - AES_BLOCK_LEN); - - /* Allocate a context for AES cipher-block chaining. */ - kms_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( - kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len, - kms_aes_ctx->ivec); - - if (kms_aes_ctx->aes_cbc == NULL) { - bzero(kms_aes_ctx->key_sched, - kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - free(session_p->encrypt.context); - session_p->encrypt.context = NULL; - rv = CKR_HOST_MEMORY; - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - - return (rv); -} - -void -kms_crypt_cleanup(kms_session_t *session_p, boolean_t encrypt, - boolean_t lock_held) -{ - kms_active_op_t *active_op; - boolean_t lock_true = B_TRUE; - kms_aes_ctx_t *kms_aes_ctx; - aes_ctx_t *aes_ctx; - - if (!lock_held) - (void) pthread_mutex_lock(&session_p->session_mutex); - - active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt); - if (active_op->mech.mechanism != CKM_AES_CBC && - active_op->mech.mechanism != CKM_AES_CBC_PAD) - return; - - kms_aes_ctx = (kms_aes_ctx_t *)active_op->context; - - if (kms_aes_ctx != NULL) { - aes_ctx = (aes_ctx_t *)kms_aes_ctx->aes_cbc; - if (aes_ctx != NULL) { - bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len); - free(kms_aes_ctx->aes_cbc); - bzero(kms_aes_ctx->key_sched, - kms_aes_ctx->keysched_len); - free(kms_aes_ctx->key_sched); - } - } - if (active_op->context != NULL) { - free(active_op->context); - active_op->context = NULL; - } - active_op->flags = 0; - if (!lock_held) - REFRELE(session_p, lock_true); -} - -CK_RV -C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - CK_RV rv; - kms_session_t *session_p; - kms_object_t *key_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - if (pMechanism == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - if (pMechanism->mechanism != CKM_AES_CBC && - pMechanism->mechanism != CKM_AES_CBC_PAD) - return (CKR_MECHANISM_INVALID); - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hKey, key_p, rv); - if (rv != CKR_OK) - goto clean_exit; - - /* Check to see if key object allows for encryption. */ - if (!(key_p->bool_attr_mask & ENCRYPT_BOOL_ON)) { - rv = CKR_KEY_FUNCTION_NOT_PERMITTED; - goto clean_exit1; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* Check to see if encrypt operation is already active. */ - if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) { - /* free the memory to avoid memory leak */ - kms_crypt_cleanup(session_p, B_TRUE, lock_held); - } - - /* - * This active flag will remain ON until application calls either - * C_Encrypt or C_EncryptFinal to actually obtain the final piece - * of ciphertext. - */ - session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE; - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_encrypt_init(session_p, pMechanism, key_p); - - if (rv != CKR_OK) { - (void) pthread_mutex_lock(&session_p->session_mutex); - session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE; - lock_held = B_TRUE; - } - -clean_exit1: - OBJ_REFRELE(key_p); -clean_exit: - REFRELE(session_p, lock_held); - return (rv); -} - - -CK_RV -C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, - CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) -{ - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* - * Only check if input buffer is null. How to handle zero input - * length depends on the mechanism in use. For secret key mechanisms, - * unpadded ones yield zero length output, but padded ones always - * result in greater than zero length output. - */ - if (pData == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - /* - * Only check if pulEncryptedDataLen is NULL. - * No need to check if pEncryptedData is NULL because - * application might just ask for the length of buffer to hold - * the ciphertext. - */ - if (pulEncryptedDataLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* Application must call C_EncryptInit before calling C_Encrypt. */ - if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - /* - * C_Encrypt must be called without intervening C_EncryptUpdate - * calls. - */ - if (session_p->encrypt.flags & CRYPTO_OPERATION_UPDATE) { - /* - * C_Encrypt can not be used to terminate a multi-part - * operation, so we'll leave the active encrypt operation - * flag on and let the application continue with the - * encrypt update operation. - */ - REFRELE(session_p, lock_held); - return (CKR_FUNCTION_FAILED); - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_encrypt_common(session_p, pData, ulDataLen, pEncryptedData, - pulEncryptedDataLen, 0); - - if ((rv == CKR_BUFFER_TOO_SMALL) || - (pEncryptedData == NULL && rv == CKR_OK)) { - /* - * We will not terminate the active encrypt operation flag, - * when the application-supplied buffer is too small, or - * the application asks for the length of buffer to hold - * the ciphertext. - */ - REFRELE(session_p, lock_held); - return (rv); - } - -clean_exit: - /* Clear context, free key, and release session counter */ - kms_crypt_cleanup(session_p, B_TRUE, B_FALSE); - return (rv); -} - -CK_RV -C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* - * Only check if input buffer is null. How to handle zero input - * length depends on the mechanism in use. For secret key mechanisms, - * unpadded ones yeild zero length output, but padded ones always - * result in greater than zero length output. - */ - if (pPart == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - /* - * Only check if pulEncryptedPartLen is NULL. - * No need to check if pEncryptedPart is NULL because - * application might just ask for the length of buffer to hold - * the ciphertext. - */ - if (pulEncryptedPartLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* - * Application must call C_EncryptInit before calling - * C_EncryptUpdate. - */ - if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - session_p->encrypt.flags |= CRYPTO_OPERATION_UPDATE; - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_encrypt_common(session_p, pPart, ulPartLen, - pEncryptedPart, pulEncryptedPartLen, B_TRUE); - - /* - * If CKR_OK or CKR_BUFFER_TOO_SMALL, don't terminate the - * current encryption operation. - */ - if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) { - REFRELE(session_p, lock_held); - return (rv); - } - -clean_exit: - /* - * After an error occurred, terminate the current encrypt - * operation by resetting the active and update flags. - */ - kms_crypt_cleanup(session_p, B_TRUE, lock_held); - - return (rv); -} - - -CK_RV -C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, - CK_ULONG_PTR pulLastEncryptedPartLen) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer. */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - if (pulLastEncryptedPartLen == NULL) { - rv = CKR_ARGUMENTS_BAD; - goto clean_exit; - } - - (void) pthread_mutex_lock(&session_p->session_mutex); - lock_held = B_TRUE; - - /* - * Application must call C_EncryptInit before calling - * C_EncryptFinal. - */ - if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - (void) pthread_mutex_unlock(&session_p->session_mutex); - lock_held = B_FALSE; - - rv = kms_aes_encrypt_final(session_p, pLastEncryptedPart, - pulLastEncryptedPartLen); - - if ((rv == CKR_BUFFER_TOO_SMALL) || - (pLastEncryptedPart == NULL && rv == CKR_OK)) { - /* - * We will not terminate the active encrypt operation flag, - * when the application-supplied buffer is too small, or - * the application asks for the length of buffer to hold - * the ciphertext. - */ - REFRELE(session_p, lock_held); - return (rv); - } - - /* Terminates the active encrypt operation. */ - (void) pthread_mutex_lock(&session_p->session_mutex); - session_p->encrypt.flags = 0; - lock_held = B_TRUE; - REFRELE(session_p, lock_held); - - return (rv); - -clean_exit: - /* Terminates the active encrypt operation. */ - kms_crypt_cleanup(session_p, B_TRUE, lock_held); - - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGeneral.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGeneral.c deleted file mode 100644 index 192d53827f..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGeneral.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <fcntl.h> -#include <pthread.h> -#include <strings.h> -#include <unistd.h> /* for pid */ -#include <errno.h> -#include <security/cryptoki.h> - -#include "kmsKeystoreUtil.h" -#include "kmsGlobal.h" -#include "kmsSession.h" -#include "kmsSlot.h" - -/* - * PKCS#11 KMS Crypto provider module. - * - * This module provides access to a Key Management System (v 2.0) - * through the Solaris Cryptographic Framework interfaces (PKCS#11). - * - * PREREQUISITES - * ============= - * 1. You must have access to a KMS on the network and you must - * know the IP address and name of the "Agent" assigned to - * you and the passphrase needed to access the Agent information. - * - * 2. The token configuration must be completed prior - * to using this provider using the kmscfg(1m) utility. - * - * This provider provides support for 3 AES mechanisms: - * CKM_AES_KEY_GEN (for 256 bit keys only) - * CKM_AES_CBC (encrypt/decrypt) - * CKM_AES_CBC_PAD (encrypt/decrypt) - * - * DETAILS - * ======= - * Each user has their own local configuration for the KMS. - * The local configuration information is typically located - * in a private token directory - /var/tmp/kms/$USERNAME - * The location may be overridden using an environment variable - * $KMSTOKEN_DIR. The user's private token namespace is configured - * using kmscfg(1M) which establishes the directory and populates - * it with a simple configuration file that this module later uses - * to access the KMS. - * - * INITIALIZING - * ============ - * Once the token configuration is established, C_InitToken - * is used to initialize the first contact with the KMS. This - * will cause the provider to contact the KMS and download - * the profile configuration data, a server certificate, and a - * private entity key and certificate (in a PKCS#12 file). - * Once the above data is collected it is stored under $KMSTOKEN_DIR. - * The user may then proceed with normal PKCS#11 activity. - * - * LOGIN - * ===== - * The concept of a "Login" is established when the user provides - * a PIN that will successfully unwrap the private data in the - * PKCS#12 file downloaded earlier when C_InitToken was called. - * If the PKCS#12 file is successfully opened, then the user - * is considered "logged in" and may use the private key and - * certificate to initiate secure communications with the KMS. - * - * CHANGE PIN - * ========== - * The C_SetPIN interface may be used to change the passphrase - * on the PKCS#12 file and thus effectively change the passphrase - * for the token itself (even though the wrapped private key and - * certificate do not change). - * - * KEY STORAGE - * =========== - * Keys generated in the KMS are always kept securely in the KMS. - * The local token area contains only a list of CKA_LABEL values - * for all successfully created keys, no sensitive key data - * is stored on the client system. When a key is "destroyed", the - * local references to that key's label is removed and it is no - * longer visible to the token provider. - * - * NOTE: The KMS itself does not have an interface for destroying - * keys, it only allows for the keys to be disassociated from - * a particular "DataUnit". Key labels should not be re-used. - */ -#pragma init(kms_init) -#pragma fini(kms_fini) - -static struct CK_FUNCTION_LIST functionList = { - { 2, 20 }, /* version */ - C_Initialize, - C_Finalize, - C_GetInfo, - C_GetFunctionList, - C_GetSlotList, - C_GetSlotInfo, - C_GetTokenInfo, - C_GetMechanismList, - C_GetMechanismInfo, - C_InitToken, - C_InitPIN, - C_SetPIN, - C_OpenSession, - C_CloseSession, - C_CloseAllSessions, - C_GetSessionInfo, - C_GetOperationState, - C_SetOperationState, - C_Login, - C_Logout, - C_CreateObject, - C_CopyObject, - C_DestroyObject, - C_GetObjectSize, - C_GetAttributeValue, - C_SetAttributeValue, - C_FindObjectsInit, - C_FindObjects, - C_FindObjectsFinal, - C_EncryptInit, - C_Encrypt, - C_EncryptUpdate, - C_EncryptFinal, - C_DecryptInit, - C_Decrypt, - C_DecryptUpdate, - C_DecryptFinal, - C_DigestInit, - C_Digest, - C_DigestUpdate, - C_DigestKey, - C_DigestFinal, - C_SignInit, - C_Sign, - C_SignUpdate, - C_SignFinal, - C_SignRecoverInit, - C_SignRecover, - C_VerifyInit, - C_Verify, - C_VerifyUpdate, - C_VerifyFinal, - C_VerifyRecoverInit, - C_VerifyRecover, - C_DigestEncryptUpdate, - C_DecryptDigestUpdate, - C_SignEncryptUpdate, - C_DecryptVerifyUpdate, - C_GenerateKey, - C_GenerateKeyPair, - C_WrapKey, - C_UnwrapKey, - C_DeriveKey, - C_SeedRandom, - C_GenerateRandom, - C_GetFunctionStatus, - C_CancelFunction, - C_WaitForSlotEvent -}; - -boolean_t kms_initialized = B_FALSE; -static pid_t kms_pid = 0; - - -/* protects kms_initialized and entrance to C_Initialize/Finalize */ -static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER; - -ses_to_be_freed_list_t ses_delay_freed; -object_to_be_freed_list_t obj_delay_freed; -kms_elem_t **kms_mechhash; /* Hash table for kCF mech numbers */ - -static void kms_finalize_common(); -static void kms_cleanup_library(); -static void kms_init(); -static void kms_fini(); -static void kms_fork_prepare(); -static void kms_fork_after(); - -CK_RV -C_Initialize(CK_VOID_PTR pInitArgs) -{ - int initialize_pid; - boolean_t supplied_ok; - CK_RV rv = CKR_OK; - - /* - * Grab lock to insure that only one thread enters this - * function at a time. - */ - (void) pthread_mutex_lock(&globalmutex); - initialize_pid = getpid(); - - if (kms_initialized) { - if (initialize_pid == kms_pid) { - /* - * This process has called C_Initialize already - */ - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_CRYPTOKI_ALREADY_INITIALIZED); - } else { - /* - * A fork has happened and the child is - * reinitializing. Do a kms_cleanup_library to close - * out any state from the parent, and then - * continue on. - */ - kms_cleanup_library(); - } - } - - if (pInitArgs != NULL) { - CK_C_INITIALIZE_ARGS *initargs1 = - (CK_C_INITIALIZE_ARGS *) pInitArgs; - - /* pReserved must be NULL */ - if (initargs1->pReserved != NULL) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_ARGUMENTS_BAD); - } - - /* - * ALL supplied function pointers need to have the value - * either NULL or non-NULL. - */ - supplied_ok = (initargs1->CreateMutex == NULL && - initargs1->DestroyMutex == NULL && - initargs1->LockMutex == NULL && - initargs1->UnlockMutex == NULL) || - (initargs1->CreateMutex != NULL && - initargs1->DestroyMutex != NULL && - initargs1->LockMutex != NULL && - initargs1->UnlockMutex != NULL); - - if (!supplied_ok) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_ARGUMENTS_BAD); - } - - /* - * When the CKF_OS_LOCKING_OK flag isn't set and mutex - * function pointers are supplied by an application, - * return an error. We must be able to use our own locks. - */ - if (!(initargs1->flags & CKF_OS_LOCKING_OK) && - (initargs1->CreateMutex != NULL)) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_CANT_LOCK); - } - } - - /* Create the hash table */ - kms_mechhash = calloc(KMECH_HASHTABLE_SIZE, sizeof (void *)); - if (kms_mechhash == NULL) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_HOST_MEMORY); - } - - /* Initialize the slot table */ - rv = kms_slottable_init(); - if (rv != CKR_OK) { - free(kms_mechhash); - goto end; - } - - /* Initialize the object_to_be_freed list */ - (void) pthread_mutex_init(&obj_delay_freed.obj_to_be_free_mutex, NULL); - obj_delay_freed.count = 0; - obj_delay_freed.first = NULL; - obj_delay_freed.last = NULL; - - /* Initialize the session_to_be_freed list */ - (void) pthread_mutex_init(&ses_delay_freed.ses_to_be_free_mutex, NULL); - ses_delay_freed.count = 0; - ses_delay_freed.first = NULL; - ses_delay_freed.last = NULL; - - rv = KMS_Initialize(); - if (rv != CKR_OK) { - free(kms_mechhash); - goto end; - } - - kms_initialized = B_TRUE; - kms_pid = initialize_pid; - -end: - (void) pthread_mutex_unlock(&globalmutex); - - return (CKR_OK); -} - -/* - * C_Finalize is a wrapper around kms_finalize_common. The - * globalmutex should be locked by C_Finalize(). - */ -CK_RV -C_Finalize(CK_VOID_PTR pReserved) -{ - (void) pthread_mutex_lock(&globalmutex); - - if (!kms_initialized) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_CRYPTOKI_NOT_INITIALIZED); - } - - /* Check to see if pReseved is NULL */ - if (pReserved != NULL) { - (void) pthread_mutex_unlock(&globalmutex); - return (CKR_ARGUMENTS_BAD); - } - - /* - * Delete all the sessions for each slot and release the allocated - * resources - */ - kms_delete_all_sessions(B_FALSE); - - kms_finalize_common(); - - (void) pthread_mutex_unlock(&globalmutex); - - return (CKR_OK); -} - -/* - * kms_finalize_common() does the work for C_Finalize. globalmutex - * must be held before calling this function. - */ -static void -kms_finalize_common() { - - int i; - kms_elem_t *elem, *next; - kms_object_t *delay_free_obj, *tmpo; - kms_session_t *delay_free_ses, *tmps; - - cleanup_slottable(); - /* Walk the hash table and free all entries */ - for (i = 0; i < KMECH_HASHTABLE_SIZE; i++) { - elem = kms_mechhash[i]; - while (elem != NULL) { - next = elem->knext; - free(elem); - elem = next; - } - } - - free(kms_mechhash); - - kms_mechhash = NULL; - kms_initialized = B_FALSE; - kms_pid = 0; - - /* - * free all entries in the delay_freed list - */ - delay_free_obj = obj_delay_freed.first; - while (delay_free_obj != NULL) { - tmpo = delay_free_obj->next; - free(delay_free_obj); - delay_free_obj = tmpo; - } - obj_delay_freed.count = 0; - obj_delay_freed.first = NULL; - obj_delay_freed.last = NULL; - (void) pthread_mutex_destroy(&obj_delay_freed.obj_to_be_free_mutex); - - delay_free_ses = ses_delay_freed.first; - while (delay_free_ses != NULL) { - tmps = delay_free_ses->next; - free(delay_free_ses); - delay_free_ses = tmps; - } - ses_delay_freed.count = 0; - ses_delay_freed.first = NULL; - ses_delay_freed.last = NULL; - (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex); -} - -/* - * This function cleans up all the resources in the library (user space only) - */ -static void -kms_cleanup_library() -{ - kms_slot_t *pslot = get_slotinfo(); - - if (pslot) - kms_cleanup_pri_objects_in_slot(pslot, NULL); - - /* - * Delete all the sessions for each slot and release the allocated - * resources from the library. The boolean argument TRUE indicates - * that we only wants to clean up the resource in the library only. - * We don't want to clean up the corresponding kernel part of - * resources, because they are used by the parent process still. - */ - kms_delete_all_sessions(B_TRUE); - - kms_finalize_common(); -} - -static void -kms_init() -{ - (void) pthread_atfork(kms_fork_prepare, kms_fork_after, - kms_fork_after); -} - -/* - * kms_fini() function required to make sure complete cleanup - * is done if pkcs11_kms is ever unloaded without - * a C_Finalize() call. - */ -static void -kms_fini() -{ - (void) pthread_mutex_lock(&globalmutex); - - (void) KMS_Finalize(); - - /* if we're not initilized, do not attempt to finalize */ - if (!kms_initialized) { - (void) pthread_mutex_unlock(&globalmutex); - return; - } - - kms_cleanup_library(); - - (void) pthread_mutex_unlock(&globalmutex); -} - -CK_RV -C_GetInfo(CK_INFO_PTR pInfo) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (pInfo == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - /* Check if the cryptoki was initialized */ - pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; - pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; - (void) strncpy((char *)pInfo->manufacturerID, - MANUFACTURER_ID, 32); - pInfo->flags = 0; - (void) strncpy((char *)pInfo->libraryDescription, - LIBRARY_DESCRIPTION, 32); - pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR; - pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR; - - return (CKR_OK); -} - -CK_RV -C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) -{ - if (ppFunctionList == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - *ppFunctionList = &functionList; - - return (CKR_OK); -} - -/* - * PKCS#11 states that C_GetFunctionStatus should always return - * CKR_FUNCTION_NOT_PARALLEL - */ -/*ARGSUSED*/ -CK_RV -C_GetFunctionStatus(CK_SESSION_HANDLE hSession) -{ - return (CKR_FUNCTION_NOT_PARALLEL); -} - -/* - * Take out all mutexes before fork. - * Order: - * 1. globalmutex - * 2. all slots mutexes (and all their sessions) via - * kms_acquire_all_slots_mutexes() - * 3. obj_delay_freed.obj_to_be_free_mutex; - * 4. ses_delay_freed.ses_to_be_free_mutex - */ -void -kms_fork_prepare() -{ - (void) pthread_mutex_lock(&globalmutex); - if (kms_initialized) { - kms_acquire_all_slots_mutexes(); - (void) pthread_mutex_lock( - &obj_delay_freed.obj_to_be_free_mutex); - (void) pthread_mutex_lock( - &ses_delay_freed.ses_to_be_free_mutex); - } -} - -/* - * Release in opposite order to kms_fork_prepare(). - * Function is used for parent and child. - */ -void -kms_fork_after() -{ - if (kms_initialized) { - (void) pthread_mutex_unlock( - &ses_delay_freed.ses_to_be_free_mutex); - (void) pthread_mutex_unlock( - &obj_delay_freed.obj_to_be_free_mutex); - kms_release_all_slots_mutexes(); - } - (void) pthread_mutex_unlock(&globalmutex); -} - -/* - * PKCS#11 states that C_CancelFunction should always return - * CKR_FUNCTION_NOT_PARALLEL - */ -/*ARGSUSED*/ -CK_RV -C_CancelFunction(CK_SESSION_HANDLE hSession) -{ - return (CKR_FUNCTION_NOT_PARALLEL); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGlobal.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGlobal.h deleted file mode 100644 index 224fd357fc..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsGlobal.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KMSGLOBAL_H -#define _KMSGLOBAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/crypto/common.h> -#include <security/cryptoki.h> -#include <security/pkcs11t.h> -#include "kmsObject.h" - -typedef struct kms_elem { - CK_MECHANISM_TYPE type; - struct kms_elem *knext; /* Next in hash chain */ -} kms_elem_t; - -extern kms_elem_t **kms_mechhash; -extern boolean_t kms_initialized; - -#define KMECH_HASHTABLE_SIZE 67 - -/* CK_INFO: Information about cryptoki */ -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 20 -#define MANUFACTURER_ID "Oracle Corporation " -#define LIBRARY_DESCRIPTION "Oracle Key Management System " -#define LIBRARY_VERSION_MAJOR 1 -#define LIBRARY_VERSION_MINOR 0 - -/* CK_SLOT_INFO: Information about our slot */ -#define SLOT_DESCRIPTION "Oracle Key Management System " \ - " " -#define KMS_TOKEN_LABEL "KMS " -#define KMS_TOKEN_MODEL " " -#define KMS_TOKEN_SERIAL " " -#define KMS_TOKEN_FLAGS CKF_LOGIN_REQUIRED -#define MAX_PIN_LEN 256 -#define MIN_PIN_LEN 1 -#define HARDWARE_VERSION_MAJOR 0 -#define HARDWARE_VERSION_MINOR 0 -#define FIRMWARE_VERSION_MAJOR 0 -#define FIRMWARE_VERSION_MINOR 0 - -CK_RV crypto2pkcs11_error_number(uint_t); -CK_RV kms_mech(CK_MECHANISM_TYPE); -unsigned char *get_symmetric_key_value(kms_object_t *); -void free_key_attributes(); - -CK_RV process_object_attributes(CK_ATTRIBUTE_PTR, CK_ULONG, caddr_t *, - CK_BBOOL *); -CK_RV get_object_attributes(CK_ATTRIBUTE_PTR, CK_ULONG, caddr_t); -void free_object_attributes(caddr_t, CK_ULONG); -CK_RV process_found_objects(kms_session_t *, CK_OBJECT_HANDLE *, - CK_ULONG *); -CK_RV get_mechanism_info(kms_slot_t *, CK_MECHANISM_TYPE, - CK_MECHANISM_INFO_PTR, uint32_t *); -CK_RV kms_add_extra_attr(CK_ATTRIBUTE_PTR, kms_object_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMSGLOBAL_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeys.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeys.c deleted file mode 100644 index c0edc35898..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeys.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Milan Jurik. All rights reserved. - */ - -#include <strings.h> -#include <errno.h> -#include <security/cryptoki.h> -#include <cryptoutil.h> -#include "kmsGlobal.h" -#include "kmsSession.h" -#include "kmsObject.h" -#include "kmsKeystoreUtil.h" - -static CK_RV -kms_generate_softkey(kms_object_t *keyp) -{ - if ((OBJ_SEC_VALUE(keyp) = malloc(OBJ_SEC_VALUE_LEN(keyp))) == NULL) - return (CKR_HOST_MEMORY); - - if (pkcs11_get_urandom(OBJ_SEC_VALUE(keyp), - OBJ_SEC_VALUE_LEN(keyp)) < 0) - return (CKR_DEVICE_ERROR); - - return (CKR_OK); -} - -CK_RV -C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) -{ - CK_RV rv = CKR_OK; - kms_session_t *session_p; - kms_object_t *new_objp = NULL; - kms_slot_t *pslot; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Obtain the session pointer */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - if ((pMechanism == NULL) || (phKey == NULL)) { - rv = CKR_ARGUMENTS_BAD; - goto failed_exit; - } - - if ((pTemplate == NULL) && (ulCount != 0)) { - rv = CKR_ARGUMENTS_BAD; - goto failed_exit; - } - - switch (pMechanism->mechanism) { - case CKM_AES_KEY_GEN: - break; - default: - rv = CKR_MECHANISM_INVALID; - goto failed_exit; - } - - /* Create an object record */ - new_objp = kms_new_object(); - if (new_objp == NULL) - return (CKR_HOST_MEMORY); - - new_objp->mechanism = pMechanism->mechanism; - rv = kms_build_object(pTemplate, ulCount, new_objp); - if (rv != CKR_OK) - goto failed_exit; - - /* - * Generate the KMS key. - * - * This will put the AES key value from the KMS key into the - * key object record. - */ - if (new_objp->bool_attr_mask & TOKEN_BOOL_ON) - rv = KMS_GenerateKey(session_p, new_objp); - else - rv = kms_generate_softkey(new_objp); - - if (rv != CKR_OK) - goto failed_exit; - - if (new_objp->bool_attr_mask & TOKEN_BOOL_ON) { - pslot = get_slotinfo(); - if (pslot == NULL) { - rv = CKR_GENERAL_ERROR; - goto failed_exit; - } - kms_add_token_object_to_slot(new_objp, pslot); - } else { - kms_add_object_to_session(new_objp, session_p); - } - - *phKey = (CK_OBJECT_HANDLE)new_objp; - REFRELE(session_p, ses_lock_held); - return (rv); - -failed_exit: - if (new_objp != NULL) - (void) free(new_objp); - - REFRELE(session_p, ses_lock_held); - return (rv); -} - -/*ARGSUSED*/ -CK_RV -C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, - CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.c deleted file mode 100644 index 2176aed030..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.c +++ /dev/null @@ -1,1227 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <stdio.h> -#include <malloc.h> -#include <memory.h> -#include <strings.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <cryptoutil.h> -#include <unistd.h> -#include <utmpx.h> -#include <pthread.h> -#include <pwd.h> -#include <sha2.h> -#include <security/cryptoki.h> -#include <aes_impl.h> -#include <sys/avl.h> - -#include "kmsSession.h" -#include "kmsGlobal.h" -#include "kmsObject.h" - -static CK_RV -GetPKCS11StatusFromAgentStatus(KMS_AGENT_STATUS status); - -static char keystore_path[BUFSIZ]; -static boolean_t keystore_path_initialized = B_FALSE; -static time_t last_objlist_mtime = 0; -pthread_mutex_t objlist_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t flock_mutex = PTHREAD_MUTEX_INITIALIZER; - -static struct flock fl = { - 0, - 0, - 0, - 0, - 0, - 0, - {0, 0, 0, 0} -}; - -#define KEYSTORE_PATH "/var/kms" -#define ALTERNATE_KEYSTORE_PATH "KMSTOKEN_DIR" -#define KMS_PROFILE_FILENAME "profile.cfg" -#define KMS_DATAUNIT_DESCRIPTION "Oracle PKCS11/KMS" -#define KMS_ATTR_DESC_PFX "PKCS#11v2.20: " -#define KMSTOKEN_CONFIG_FILENAME "kmstoken.cfg" -#define KMSTOKEN_LABELLIST_FILENAME "objlabels.lst" - -static void -kms_hash_string(char *label, uchar_t *hash) -{ - SHA2_CTX ctx; - - SHA2Init(SHA256, &ctx); - SHA2Update(&ctx, label, strlen(label)); - SHA2Final(hash, &ctx); -} - -static char * -get_username(char *username, int len) -{ - struct passwd pwd, *user_info; - long buflen; - char *pwdbuf = NULL; - - bzero(username, len); - - buflen = sysconf(_SC_GETPW_R_SIZE_MAX); - if (buflen == -1) - return (username); /* should not happen */ - - pwdbuf = calloc(1, buflen); - if (pwdbuf == NULL) - return (username); /* zero-ed earlier */ - - user_info = getpwuid_r(getuid(), &pwd, pwdbuf, buflen); - - if (user_info != NULL) - (void) strlcpy(username, user_info->pw_name, len); - - free(pwdbuf); - return (username); -} - -static char * -kms_get_keystore_path() -{ - char *env_val; - char username[sizeof (((struct utmpx *)0)->ut_user)]; - - if (!keystore_path_initialized) { - env_val = getenv(ALTERNATE_KEYSTORE_PATH); - bzero(keystore_path, sizeof (keystore_path)); - /* - * If it isn't set or is set to the empty string use the - * default location. We need to check for the empty string - * because some users "unset" environment variables by giving - * them no value, this isn't the same thing as removing it - * from the environment. - */ - if ((env_val == NULL) || (strcmp(env_val, "") == 0)) { - /* alternate path not specified, use /var/kms/$USER */ - (void) snprintf(keystore_path, - sizeof (keystore_path), "%s/%s", - KEYSTORE_PATH, - get_username(username, sizeof (username))); - } else { - (void) strlcpy(keystore_path, env_val, - sizeof (keystore_path)); - } - keystore_path_initialized = B_TRUE; - } - return (keystore_path); -} - -static char * -get_non_comment_line(char *cfgbuf, size_t cfglen, char *buf, size_t buflen) -{ - char *s = cfgbuf; - char *end = cfgbuf + cfglen; - char *f; - - /* Skip over blank lines CR/LF */ - while (s < end && (*s == '#' || *s == '\n' || *s == '\r')) { - /* check for comment sign */ - if (*s == '#') { - /* skip the rest of the line */ - while ((*s != '\n' || *s == '\r') && s < end) - s++; - } - if ((s < end) && (*s == '\n' || *s == '\r')) - s++; - } - - if (s < end) { - char save, *e; - f = s; /* mark the beginning. */ - /* Find the end of the line and null terminate it. */ - while (*s != '\n' && *s != '\r' && *s != '#' && s < end) s++; - save = *s; - *s = 0x00; - (void) strncpy(buf, f, buflen); - *s = save; - - /* Strip trailing whitespace */ - f = buf; - e = f + strlen(buf) - 1; - while (e >= f && isspace(*e)) { - *e = 0x00; - e--; - } - - } else { - /* If we reached the end, return NULL */ - s = NULL; - } -done: - return (s); -} - -static int -flock_fd(int fd, int cmd, pthread_mutex_t *mutex) -{ - int ret = 0; - - (void) pthread_mutex_lock(mutex); - - fl.l_type = cmd; - - while ((ret = fcntl(fd, F_SETLKW, &fl)) == -1) { - if (errno != EINTR) - break; - } - (void) pthread_mutex_unlock(mutex); - return (ret); -} - -/* - * Open the keystore description file in the specified mode. - * If the keystore doesn't exist, the "do_create_keystore" - * argument determines if the keystore should be created - */ -static int -open_and_lock_file(char *filename, int cmd, mode_t mode, - pthread_mutex_t *mutex) -{ - int fd; - - fd = open_nointr(filename, mode|O_NONBLOCK); - if (fd < 0) - return (fd); - - if (flock_fd(fd, cmd, mutex)) { - if (fd > 0) - (void) close(fd); - return (-1); - } - - return (fd); -} - -static int -kms_slurp_file(char *file, char *buf, size_t buflen) -{ - int n, fd, total = 0; - - fd = open_and_lock_file(file, F_RDLCK, O_RDONLY, &flock_mutex); - if (fd == -1) - return (-1); - - do { - n = readn_nointr(fd, &buf[total], buflen - total); - if (n != (buflen - total)) - break; - else - total += n; - } while (total < buflen); - - if (flock_fd(fd, F_UNLCK, &flock_mutex)) - total = -1; - - (void) close(fd); - - return (total); -} - -/* - * The KMS token is considered "initialized" if the file with the token - * configuration information is present. - */ -CK_BBOOL -kms_is_initialized() -{ - CK_BBOOL rv; - char *ksdir; - char cfgfile_path[BUFSIZ]; - struct stat statp; - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (CKR_FUNCTION_FAILED); - - (void) snprintf(cfgfile_path, sizeof (cfgfile_path), - "%s/%s", ksdir, KMSTOKEN_CONFIG_FILENAME); - - if (stat(cfgfile_path, &statp)) - rv = FALSE; - else - rv = TRUE; - - return (rv); -} - -static CK_RV -kms_read_config_data(char *path, kms_cfg_info_t *cfginfo) -{ - CK_RV rv = CKR_OK; - char *cfgbuf = NULL; - char *ptr; - char buf[BUFSIZ]; - size_t buflen = 0, remain; - struct stat statp; - - if (path == NULL || cfginfo == NULL) - return (CKR_ARGUMENTS_BAD); - - if (stat(path, &statp) == -1) { - return (CKR_FUNCTION_FAILED); - } - - cfgbuf = calloc(1, statp.st_size); - if (cfgbuf == NULL) - return (CKR_HOST_MEMORY); - - buflen = kms_slurp_file(path, cfgbuf, statp.st_size); - if (buflen != statp.st_size) { - free(cfgbuf); - return (CKR_FUNCTION_FAILED); - } - - remain = buflen; - ptr = cfgbuf; - ptr = get_non_comment_line(ptr, remain, - cfginfo->name, sizeof (cfginfo->name)); - if (ptr == NULL) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, - cfginfo->agentId, sizeof (cfginfo->agentId)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, - cfginfo->agentAddr, sizeof (cfginfo->agentAddr)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, buf, sizeof (buf)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - cfginfo->transTimeout = atoi(buf); - - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, buf, sizeof (buf)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - cfginfo->failoverLimit = atoi(buf); - - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, buf, sizeof (buf)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - cfginfo->discoveryFreq = atoi(buf); - - remain = buflen - (ptr - cfgbuf); - ptr = get_non_comment_line(ptr, remain, buf, sizeof (buf)); - if (ptr == 0) { - rv = CKR_FUNCTION_FAILED; - goto done; - } - cfginfo->securityMode = atoi(buf); -done: - if (cfgbuf != NULL) - free(cfgbuf); - return (rv); -} - -CK_BBOOL -kms_is_pin_set() -{ - CK_BBOOL rv = TRUE; - kms_cfg_info_t kmscfg; - struct stat statp; - char *ksdir; - char filepath[BUFSIZ]; - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (FALSE); - - (void) snprintf(filepath, sizeof (filepath), - "%s/%s", ksdir, KMSTOKEN_CONFIG_FILENAME); - - if ((rv = kms_read_config_data(filepath, &kmscfg))) - return (FALSE); - - /* - * The PK12 file is only established once the user has enrolled - * and is thus considered having a PIN set. - */ - (void) snprintf(filepath, sizeof (filepath), - "%s/%s/%s", ksdir, kmscfg.agentId, CLIENT_PK12_FILE); - - if (stat(filepath, &statp)) - rv = FALSE; /* file doesn't exist. */ - else - rv = TRUE; /* File exists, PIN is set */ - - return (rv); -} - -void -kms_clear_label_list(avl_tree_t *tree) -{ - void *cookie = NULL; - objlabel_t *node; - - while ((node = avl_destroy_nodes(tree, &cookie)) != NULL) { - free(node->label); - free(node); - } -} - -static void -add_label_node(avl_tree_t *tree, char *label) -{ - avl_index_t where; - objlabel_t *node; - objlabel_t *newnode; - int i; - - if (tree == NULL || label == NULL) - return; - - /* Remove trailing CR */ - i = strlen(label) - 1; - while (i > 0 && label[i] == '\n') - label[i--] = 0x00; - - newnode = calloc(1, sizeof (objlabel_t)); - newnode->label = (char *)strdup(label); - if (newnode->label == NULL) { - free(newnode); - return; - } - /* see if this entry already exists */ - node = avl_find(tree, newnode, &where); - if (node == NULL) { - avl_insert(tree, newnode, where); - } else { - /* It's a dup, don't add it */ - free(newnode->label); - free(newnode); - } -} - -CK_RV -kms_reload_labels(kms_session_t *sp) -{ - CK_RV rv = CKR_OK; - char *cfgbuf = NULL, *ptr, buffer[BUFSIZ]; - size_t buflen, remain; - struct stat statp; - char *ksdir; - char labelfile[BUFSIZ]; - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (CKR_GENERAL_ERROR); - - (void) snprintf(labelfile, sizeof (labelfile), - "%s/%s", ksdir, KMSTOKEN_LABELLIST_FILENAME); - - bzero(&statp, sizeof (statp)); - if (stat(labelfile, &statp) == -1) { - if (errno == ENOENT) { - FILE *fp; - /* Create it */ - fp = fopen(labelfile, "w"); - if (fp == NULL) - return (CKR_GENERAL_ERROR); - (void) fclose(fp); - } - } - - if (statp.st_size == 0) { - return (CKR_OK); - } - - cfgbuf = calloc(1, statp.st_size); - if (cfgbuf == NULL) - return (CKR_HOST_MEMORY); - - buflen = kms_slurp_file(labelfile, cfgbuf, statp.st_size); - if (buflen != statp.st_size) { - free(cfgbuf); - return (CKR_FUNCTION_FAILED); - } - - if (statp.st_mtime == last_objlist_mtime) { - /* No change */ - goto end; - } - - /* If we got here, we need to refresh the entire list */ - kms_clear_label_list(&sp->objlabel_tree); - - /* - * Read each line and add it as a label node. - */ - remain = buflen; - ptr = cfgbuf; - while (remain > 0) { - ptr = get_non_comment_line(ptr, remain, - buffer, sizeof (buffer)); - if (ptr == NULL) { - goto end; - } - add_label_node(&sp->objlabel_tree, buffer); - remain = buflen - (ptr - cfgbuf); - } -end: - if (cfgbuf) - free(cfgbuf); - - return (rv); -} - -static CK_RV -kms_get_object_label(kms_object_t *obj, char *label, int len) -{ - CK_RV rv = CKR_OK; - CK_ATTRIBUTE stLabel; - - bzero(label, len); - - stLabel.type = CKA_LABEL; - stLabel.pValue = label; - stLabel.ulValueLen = len; - - /* - * The caller MUST provide a CKA_LABEL when deleting. - */ - rv = kms_get_attribute(obj, &stLabel); - - return (rv); -} - -/* - * Retrieve a data unit associated with the label. - */ -static CK_RV -kms_get_data_unit(kms_session_t *session, char *label, - KMSAgent_DataUnit *pDataUnit) -{ - KMS_AGENT_STATUS status; - const utf8cstr pDescription = KMS_DATAUNIT_DESCRIPTION; - uchar_t externalUniqueId[SHA256_DIGEST_LENGTH]; - - /* Find the data unit that holds the key */ - kms_hash_string(label, externalUniqueId); - - status = KMSAgent_RetrieveDataUnitByExternalUniqueID( - &session->kmsProfile, - (const unsigned char *)externalUniqueId, - sizeof (externalUniqueId), - label, - pDescription, - pDataUnit); - - if (status != KMS_AGENT_STATUS_OK) { - return (GetPKCS11StatusFromAgentStatus(status)); - } - - return (CKR_OK); -} - -static CK_RV -kms_decode_description(char *description, kms_object_t *pKey) -{ - CK_RV rv = CKR_OK; - char *ptr; - uint32_t keylen; - u_longlong_t boolattrs; - - /* If it doesn't start with the expected prefix, return */ - if (strncmp(description, KMS_ATTR_DESC_PFX, - strlen(KMS_ATTR_DESC_PFX))) - return (rv); - - ptr = description + strlen(KMS_ATTR_DESC_PFX); - - /* - * Decode as follows: - * CK_OBJECT_CLASS (2 bytes) - * CK_KEY_TYPE (2 bytes) - * CKA_VALUE_LEN (4 bytes) - * CK_CERTIFICATE_TYPE (2 bytes - not used) - * CK_MECHANISM_TYPE (4 bytes) - * boolean attributes (3 bytes) - * extra attributes (1 byte) - * non-boolean attributes - */ - if (sscanf(ptr, - "%02lx%02lx%02x00%04lx%06llx00", - &pKey->class, - &pKey->key_type, - &keylen, - &pKey->mechanism, - &boolattrs) != 5) - /* We didn't get the full set of attributes */ - rv = CKR_ATTRIBUTE_TYPE_INVALID; - pKey->bool_attr_mask = boolattrs; - - return (rv); -} - -/* - * Create a new PKCS#11 object record for the KMSAgent_Key. - */ -static CK_RV -kms_new_key_object( - char *label, - KMSAgent_DataUnit *dataUnit, - KMSAgent_Key *pKey, - kms_object_t **pObj) -{ - CK_RV rv = CKR_OK; - CK_BBOOL bTrue = B_TRUE; - CK_KEY_TYPE keytype = CKK_AES; - CK_OBJECT_CLASS class = CKO_SECRET_KEY; - CK_ULONG keylen; - kms_object_t *newObj; - - CK_ATTRIBUTE template[] = { - {CKA_TOKEN, NULL, sizeof (bTrue)}, - {CKA_LABEL, NULL, 0}, - {CKA_KEY_TYPE, NULL, sizeof (keytype)}, - {CKA_CLASS, NULL, sizeof (class)}, - {CKA_VALUE, NULL, NULL}, - {CKA_VALUE_LEN, NULL, NULL}, - {CKA_PRIVATE, NULL, sizeof (bTrue)}, - }; - - keylen = (CK_ULONG)pKey->m_iKeyLength; - - template[0].pValue = &bTrue; - template[1].pValue = label; - template[1].ulValueLen = strlen(label); - template[2].pValue = &keytype; - template[3].pValue = &class; - template[4].pValue = pKey->m_acKey; - template[4].ulValueLen = pKey->m_iKeyLength; - template[5].pValue = &keylen; - template[5].ulValueLen = sizeof (keylen); - template[6].pValue = &bTrue; - - newObj = kms_new_object(); - if (newObj == NULL) - return (CKR_HOST_MEMORY); - - /* - * Decode the DataUnit description field to find various - * object attributes. - */ - rv = kms_decode_description(dataUnit->m_acDescription, newObj); - if (rv) { - free(newObj); - return (rv); - } - /* - * Set the template keytype and class according to the - * data parsed from the description. - */ - if (newObj->key_type) - keytype = newObj->key_type; - if (newObj->class) - class = newObj->class; - - rv = kms_build_object(template, 7, newObj); - if (rv) { - free(newObj); - return (rv); - } - - newObj->bool_attr_mask |= TOKEN_BOOL_ON; - - *pObj = newObj; - return (rv); -} - -static CK_RV -kms_get_data_unit_keys(kms_session_t *sp, KMSAgent_DataUnit *dataUnit, - KMSAgent_ArrayOfKeys **keylist, int *numkeys) -{ - CK_RV rv = CKR_OK; - KMSAgent_ArrayOfKeys *kmskeys = NULL; - KMS_AGENT_STATUS status; - int keysLeft = 0; - - status = KMSAgent_RetrieveDataUnitKeys( - &sp->kmsProfile, dataUnit, - KMS_MAX_PAGE_SIZE, 0, - (int * const)&keysLeft, - NULL, /* KeyID */ - &kmskeys); - - if (status != KMS_AGENT_STATUS_OK) { - return (GetPKCS11StatusFromAgentStatus(status)); - } - - if (keylist != NULL && kmskeys != NULL) - *keylist = kmskeys; - - if (numkeys != NULL && kmskeys != NULL) - *numkeys = kmskeys->m_iSize; - - if (keylist == NULL && kmskeys != NULL) - KMSAgent_FreeArrayOfKeys(kmskeys); - - return (rv); -} - - -/* - * Retrieve a key from KMS. We can't use "RetrieveKey" because - * we don't know the key id. Instead get all keys associated - * with our data unit (there should be only 1. - */ -CK_RV -KMS_RetrieveKeyObj(kms_session_t *sp, char *label, kms_object_t **pobj) -{ - CK_RV rv = CKR_OK; - KMSAgent_DataUnit dataUnit; - KMSAgent_ArrayOfKeys *kmsKeys = NULL; - KMSAgent_Key *pKey; - - rv = kms_get_data_unit(sp, label, &dataUnit); - if (rv != CKR_OK) - return (rv); - - rv = kms_get_data_unit_keys(sp, &dataUnit, &kmsKeys, NULL); - - if (rv != CKR_OK || kmsKeys == NULL || kmsKeys->m_iSize == 0) - return (CKR_GENERAL_ERROR); - - pKey = &kmsKeys->m_pKeys[0]; - - rv = kms_new_key_object(label, &dataUnit, pKey, pobj); - - KMSAgent_FreeArrayOfKeys(kmsKeys); - return (rv); -} - -CK_RV -KMS_RefreshObjectList(kms_session_t *sp, kms_slot_t *pslot) -{ - kms_object_t *pObj; - char label[BUFSIZ]; - CK_RV rv; - objlabel_t *node; - - rv = kms_reload_labels(sp); - if (rv != CKR_OK) - return (rv); - - /* - * If an object is not in the list, reload it from KMS. - */ - node = avl_first(&sp->objlabel_tree); - while (node != NULL) { - boolean_t found = FALSE; - /* Search object list for matching object */ - pObj = pslot->sl_tobj_list; - while (pObj != NULL && !found) { - (void) pthread_mutex_lock(&pObj->object_mutex); - if ((rv = kms_get_object_label(pObj, label, - sizeof (label))) != CKR_OK) { - (void) pthread_mutex_unlock( - &pObj->object_mutex); - return (rv); - } - (void) pthread_mutex_unlock(&pObj->object_mutex); - found = (strcmp(label, node->label) == 0); - pObj = pObj->next; - } - if (!found) { - /* - * Fetch KMS key and prepend it to the - * token object list for the slot. - */ - rv = KMS_RetrieveKeyObj(sp, node->label, &pObj); - if (rv == CKR_OK) { - if (pslot->sl_tobj_list == NULL) { - pslot->sl_tobj_list = pObj; - pObj->prev = NULL; - pObj->next = NULL; - } else { - pObj->next = pslot->sl_tobj_list; - pObj->prev = NULL; - pslot->sl_tobj_list = pObj; - } - } - } - node = AVL_NEXT(&sp->objlabel_tree, node); - } - return (rv); -} - -CK_RV -KMS_Initialize(void) -{ - char *ksdir; - struct stat fn_stat; - KMS_AGENT_STATUS kmsrv; - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (CKR_GENERAL_ERROR); - - /* - * If the keystore directory doesn't exist, create it. - */ - if ((stat(ksdir, &fn_stat) != 0) && (errno == ENOENT)) { - if (mkdir(ksdir, S_IRUSR|S_IWUSR|S_IXUSR) < 0) { - if (errno != EEXIST) - return (CKR_GENERAL_ERROR); - } - } - - if ((kmsrv = KMSAgent_InitializeLibrary(ksdir, FALSE)) != - KMS_AGENT_STATUS_OK) { - return (GetPKCS11StatusFromAgentStatus(kmsrv)); - } - - return (CKR_OK); -} - -CK_RV -KMS_Finalize() -{ - last_objlist_mtime = 0; - - return (KMSAgent_FinalizeLibrary() == KMS_AGENT_STATUS_OK) ? - CKR_OK : CKR_FUNCTION_FAILED; -} - -CK_RV -KMS_ChangeLocalPWD(kms_session_t *session, - const char *pOldPassword, - const char *pNewPassword) -{ - KMS_AGENT_STATUS status; - - status = KMSAgent_ChangeLocalPWD( - &session->kmsProfile, - (char * const)pOldPassword, - (char * const)pNewPassword); - - return (GetPKCS11StatusFromAgentStatus(status)); -} - -CK_RV -KMS_GetConfigInfo(kms_cfg_info_t *cfginfo) -{ - CK_RV rv = CKR_OK; - char cfgfile_path[BUFSIZ]; - char *ksdir = kms_get_keystore_path(); - - if (ksdir == NULL) - return (CKR_GENERAL_ERROR); - - (void) snprintf(cfgfile_path, sizeof (cfgfile_path), - "%s/%s", ksdir, KMSTOKEN_CONFIG_FILENAME); - - rv = kms_read_config_data(cfgfile_path, cfginfo); - - return (rv); -} - -CK_RV -KMS_LoadProfile(KMSClientProfile *profile, - kms_cfg_info_t *kmscfg, - const char *pPassword, - size_t iPasswordLength) -{ - KMS_AGENT_STATUS status; - CK_RV rv; - char *sPassword; - char cfgfile_path[BUFSIZ]; - char *ksdir; - - sPassword = calloc(1, iPasswordLength + 1); - if (sPassword == NULL) - return (CKR_FUNCTION_FAILED); - - (void) memcpy(sPassword, pPassword, iPasswordLength); - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (CKR_GENERAL_ERROR); - - (void) snprintf(cfgfile_path, sizeof (cfgfile_path), - "%s/%s", ksdir, KMSTOKEN_CONFIG_FILENAME); - - if ((rv = kms_read_config_data(cfgfile_path, kmscfg))) { - free(sPassword); - return (rv); - } - - /* First, try to load existing profile */ - status = KMSAgent_LoadProfile( - profile, - kmscfg->name, - kmscfg->agentId, - sPassword, - kmscfg->agentAddr, - kmscfg->transTimeout, - kmscfg->failoverLimit, - kmscfg->discoveryFreq, - kmscfg->securityMode); - - free(sPassword); - return (GetPKCS11StatusFromAgentStatus(status)); -} - -static CK_RV -GetPKCS11StatusFromAgentStatus(KMS_AGENT_STATUS status) -{ - switch (status) { - case KMS_AGENT_STATUS_OK: - return (CKR_OK); - - case KMS_AGENT_STATUS_GENERIC_ERROR: - return (CKR_GENERAL_ERROR); - - case KMS_AGENT_STATUS_NO_MEMORY: - return (CKR_HOST_MEMORY); - - case KMS_AGENT_STATUS_INVALID_PARAMETER: - return (CKR_ARGUMENTS_BAD); - - case KMS_AGENT_STATUS_PROFILE_NOT_LOADED: - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - case KMS_AGENT_STATUS_KMS_UNAVAILABLE: - case KMS_AGENT_STATUS_KMS_NO_READY_KEYS: - return (CKR_DEVICE_MEMORY); - - case KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE: - return (CKR_GENERAL_ERROR); - - case KMS_AGENT_STATUS_PROFILE_ALREADY_LOADED: - return (CKR_USER_ANOTHER_ALREADY_LOGGED_IN); - - case KMS_AGENT_STATUS_FIPS_KAT_AES_KEYWRAP_ERROR: - case KMS_AGENT_STATUS_FIPS_KAT_AES_ECB_ERROR: - case KMS_AGENT_STATUS_FIPS_KAT_HMAC_SHA1_ERROR: - return (CKR_DEVICE_ERROR); - - case KMS_AGENT_STATUS_ACCESS_DENIED: - case KMS_AGENT_LOCAL_AUTH_FAILURE: - return (CKR_PIN_INCORRECT); - - case KMS_AGENT_STATUS_SERVER_BUSY: - case KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS: - case KMS_AGENT_STATUS_DATA_UNIT_ID_NOT_FOUND_EXTERNAL_ID_EXISTS: - case KMS_AGENT_STATUS_KEY_DOES_NOT_EXIST: - case KMS_AGENT_STATUS_KEY_DESTROYED: - case KMS_AGENT_AES_KEY_UNWRAP_ERROR: - case KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR: - case KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE: - default: - return (CKR_GENERAL_ERROR); - } -} - -void -KMS_UnloadProfile(KMSClientProfile *kmsProfile) -{ - (void) KMSAgent_UnloadProfile(kmsProfile); -} - -/* - * kms_update_label_file - * - * KMS doesn't provide an API to allow one to query for available - * data units (which map 1-1 to keys). To allow for PKCS11 to - * query for a list of available objects, we keep a local list - * and update it when an object is added or deleted. - */ -static CK_RV -kms_update_label_file(kms_session_t *sp) -{ - CK_RV rv = CKR_OK; - objlabel_t *node; - char *ksdir, *tmpfile, labelfile[BUFSIZ]; - FILE *fp; - int fd; - struct stat statp; - - ksdir = kms_get_keystore_path(); - if (ksdir == NULL) - return (CKR_GENERAL_ERROR); - - (void) snprintf(labelfile, sizeof (labelfile), - "%s/%s", ksdir, KMSTOKEN_LABELLIST_FILENAME); - - tmpfile = tempnam(ksdir, "kmspk11"); - if (tmpfile == NULL) - return (CKR_HOST_MEMORY); - - fp = fopen(tmpfile, "w"); - if (fp == NULL) { - free(tmpfile); - return (CKR_GENERAL_ERROR); - } - - /* Lock it even though its a temporary file */ - fd = fileno(fp); - if ((rv = flock_fd(fd, F_WRLCK, &objlist_mutex))) { - (void) fclose(fp); - free(tmpfile); - return (rv); - } - - node = avl_first(&sp->objlabel_tree); - while (node != NULL) { - if (node->label != NULL) - (void) fprintf(fp, "%s\n", node->label); - node = AVL_NEXT(&sp->objlabel_tree, node); - } - - /* Update the last mtime */ - if (fstat(fd, &statp) == 0) { - last_objlist_mtime = statp.st_mtime; - } - - (void) flock_fd(fd, F_UNLCK, &objlist_mutex); - (void) fclose(fp); - - (void) unlink(labelfile); - if (rename(tmpfile, labelfile)) - rv = CKR_GENERAL_ERROR; - - free(tmpfile); - return (rv); -} - -/* - * Destroy a key in the KMS by disassociating an entire data unit. - * The KMSAgent API does not have an interface for destroying an - * individual key. - */ -CK_RV -KMS_DestroyKey(kms_session_t *session, kms_object_t *i_oKey) -{ - CK_RV rv; - KMSAgent_DataUnit oDataUnit; - KMS_AGENT_STATUS status; - char label[BUFSIZ]; - objlabel_t labelnode, *tnode; - avl_index_t where = 0; - - /* - * The caller MUST provide a CKA_LABEL when deleting. - */ - (void) pthread_mutex_lock(&i_oKey->object_mutex); - if ((rv = kms_get_object_label(i_oKey, label, sizeof (label)))) { - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - return (rv); - } - - rv = kms_get_data_unit(session, label, &oDataUnit); - if (rv != CKR_OK) - return (rv); - - status = KMSAgent_DisassociateDataUnitKeys( - &session->kmsProfile, &oDataUnit); - - /* - * Remove the label from the label list and update - * the file that tracks active keys. - */ - bzero(&labelnode, sizeof (labelnode)); - labelnode.label = label; - - if ((tnode = avl_find(&session->objlabel_tree, - &labelnode, &where)) != NULL) - avl_remove(&session->objlabel_tree, tnode); - - /* rewrite the list of labels to disk */ - rv = kms_update_label_file(session); - if (rv) - /* Ignore error here */ - rv = CKR_OK; - - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - - return (GetPKCS11StatusFromAgentStatus(status)); -} - -void -kms_encode_attributes(kms_object_t *pKey, char *attrstr, int len) -{ - char *ptr; - - bzero(attrstr, len); - - (void) strlcpy(attrstr, KMS_ATTR_DESC_PFX, len); - ptr = attrstr + strlen(attrstr); - - /* - * Encode as follows: - * CK_OBJECT_CLASS (2 bytes) - * CK_KEY_TYPE (2 bytes) - * CKA_VALUE_LEN (4 bytes) - * CK_CERTIFICATE_TYPE (2 bytes - not used) - * CK_MECHANISM_TYPE (4 bytes) - * boolean attributes (3 bytes) - * extra attributes (1 byte) - * non-boolean attributes - */ - (void) snprintf(ptr, len - strlen(attrstr), - "%02x%02x%02x00%04x%06x00", - pKey->class, - pKey->key_type, - 32, - pKey->mechanism, - (pKey->bool_attr_mask & 0x00FFFFFF)); -} - -CK_RV -KMS_GenerateKey(kms_session_t *session, kms_object_t *i_oKey) -{ - CK_RV rv; - CK_ATTRIBUTE stLabel; - KMSAgent_DataUnit oDataUnit; - KMSAgent_Key oKey; - KMS_AGENT_STATUS status; - char label[128]; - uchar_t externalUniqueId[SHA256_DIGEST_LENGTH]; - char pDescription[KMS_MAX_DESCRIPTION + 1]; - - (void) pthread_mutex_lock(&i_oKey->object_mutex); - - stLabel.type = CKA_LABEL; - stLabel.pValue = label; - stLabel.ulValueLen = sizeof (label); - - /* - * The caller MUST provide a CKA_LABEL for storing in the KMS. - */ - if ((rv = kms_get_attribute(i_oKey, &stLabel)) != CKR_OK) { - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - return (rv); - } - - label[stLabel.ulValueLen] = '\0'; - - kms_hash_string(label, externalUniqueId); - - /* Encode attributes in Description */ - kms_encode_attributes(i_oKey, pDescription, - sizeof (pDescription)); - - status = KMSAgent_CreateDataUnit( - &session->kmsProfile, - (const unsigned char *)externalUniqueId, - sizeof (externalUniqueId), - label, /* externalTag */ - pDescription, - &oDataUnit); - - /* - * If the DataUnit exists, check to see if it has any keys. - * If it has no keys, then it is OK to continue. - */ - if (status == KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS) { - int numkeys = 0; - - rv = kms_get_data_unit(session, label, &oDataUnit); - if (rv != CKR_OK) - return (rv); - - rv = kms_get_data_unit_keys(session, - &oDataUnit, NULL, &numkeys); - - if (rv != CKR_OK || numkeys > 0) - /* - * This would be better if there were PKCS#11 - * error codes for duplicate objects or - * something like that. - */ - return (CKR_ARGUMENTS_BAD); - - /* If no keys associated with data unit, continue */ - status = KMS_AGENT_STATUS_OK; - } - - if (status != KMS_AGENT_STATUS_OK) { - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - return (GetPKCS11StatusFromAgentStatus(status)); - } - - status = KMSAgent_CreateKey(&session->kmsProfile, - &oDataUnit, "", &oKey); - - if (status != KMS_AGENT_STATUS_OK) { - /* - * Clean up the old data unit. - */ - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - return (GetPKCS11StatusFromAgentStatus(status)); - } - - /* - * KMS Agent only creates AES-256 keys, so ignore what the user - * requested at this point. - */ - OBJ_SEC_VALUE(i_oKey) = malloc(oKey.m_iKeyLength); - if (OBJ_SEC_VALUE(i_oKey) == NULL) { - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - return (CKR_HOST_MEMORY); - } - (void) memcpy(OBJ_SEC_VALUE(i_oKey), oKey.m_acKey, - oKey.m_iKeyLength); - OBJ_SEC_VALUE_LEN(i_oKey) = oKey.m_iKeyLength; - - /* - * Add the label to the local list of available objects - */ - add_label_node(&session->objlabel_tree, label); - - rv = kms_update_label_file(session); - - (void) pthread_mutex_unlock(&i_oKey->object_mutex); - - return (GetPKCS11StatusFromAgentStatus(status)); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.h deleted file mode 100644 index 02e627f9fa..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsKeystoreUtil.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KEYSTOREUTIL_H -#define _KEYSTOREUTIL_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "kmsSession.h" -#include "kmsObject.h" - -CK_RV KMS_Initialize(void); -CK_RV KMS_Finalize(); -CK_RV KMS_LoadProfile(KMSClientProfile *, kms_cfg_info_t *, - const char *, size_t); -CK_RV KMS_GenerateKey(kms_session_t *, kms_object_t *); -CK_RV KMS_DestroyKey(kms_session_t *, kms_object_t *); -void KMS_UnloadProfile(KMSClientProfile *); -CK_RV KMS_RefreshObjectList(kms_session_t *, kms_slot_t *); -CK_RV KMS_ChangeLocalPWD(kms_session_t *, const char *, const char *); -CK_RV KMS_GetConfigInfo(kms_cfg_info_t *); - -CK_BBOOL kms_is_initialized(); -CK_BBOOL kms_is_pin_set(); -CK_RV kms_reload_labels(kms_session_t *); -void kms_clear_label_list(avl_tree_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _KEYSTOREUTIL_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.c deleted file mode 100644 index 2ddd76fab9..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - - -#include <pthread.h> -#include <stdlib.h> -#include <errno.h> -#include <errno.h> -#include <string.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsObject.h" -#include "kmsSession.h" - -CK_RV -C_CreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if ((pTemplate == NULL) || (ulCount == 0) || - (phObject == NULL)) { - return (CKR_ARGUMENTS_BAD); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Create a new object. */ - rv = kms_add_object(pTemplate, ulCount, phObject, session_p); - - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - - return (rv); -} - -CK_RV -C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phNewObject) -{ - - CK_RV rv; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - kms_object_t *old_object; - kms_object_t *new_object = NULL; - int i; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Check arguments */ - if (((ulCount > 0) && (pTemplate == NULL)) || - (phNewObject == NULL)) { - return (CKR_ARGUMENTS_BAD); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hObject, old_object, rv); - if (rv != CKR_OK) { - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - return (rv); - } - - (void) pthread_mutex_lock(&old_object->object_mutex); - - if (old_object->is_lib_obj) { - /* - * Copy the old object to a new object. - * The 3rd argument with TRUE value indicates that - * everything in the object will be duplicated. - */ - rv = kms_copy_object(old_object, &new_object, B_TRUE, - session_p); - (void) pthread_mutex_unlock(&old_object->object_mutex); - if ((rv != CKR_OK) || (new_object == NULL)) { - /* - * Most likely we ran out of space. - * Decrement the session reference count. - * We do not hold the session lock. - */ - OBJ_REFRELE(old_object); - REFRELE(session_p, ses_lock_held); - return (rv); - } - - new_object->is_lib_obj = B_TRUE; - - /* Modify the object attribute if requested */ - for (i = 0; i < ulCount; i++) { - /* Set the requested attribute into the new object. */ - rv = kms_set_attribute(new_object, &pTemplate[i], - B_TRUE); - - if (rv != CKR_OK) { - kms_cleanup_object(new_object); - OBJ_REFRELE(old_object); - REFRELE(session_p, ses_lock_held); - return (rv); - } - } - - /* Insert the new object into this session's object list. */ - kms_add_object_to_session(new_object, session_p); - - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - OBJ_REFRELE(old_object); - REFRELE(session_p, ses_lock_held); - - /* set handle of the new object */ - *phNewObject = (CK_ULONG)new_object; - - } - - return (rv); - -failed_cleanup: - if (new_object != NULL) { - (void) kms_free_object(new_object); - } - - OBJ_REFRELE(old_object); - REFRELE(session_p, ses_lock_held); - return (rv); -} - -CK_RV -C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - CK_RV rv; - kms_object_t *object_p; - kms_session_t *session_p = (kms_session_t *)(hSession); - kms_slot_t *pslot; - boolean_t ses_lock_held = B_FALSE; - CK_SESSION_HANDLE creating_session; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * The reason that we don't call handle2session is because - * the argument hSession may not be the creating_session of - * the object to be destroyed, and we want to avoid the lock - * contention. The handle2session will be called later for - * the creating_session. - */ - if ((session_p == NULL) || - (session_p->magic_marker != KMSTOKEN_SESSION_MAGIC)) { - return (CKR_SESSION_HANDLE_INVALID); - } - /* Obtain the object pointer without incrementing reference count. */ - HANDLE2OBJECT_DESTROY(hObject, object_p, rv); - if (rv != CKR_OK) { - return (rv); - } - - /* Only session objects can be destroyed at a read-only session. */ - if ((session_p->ses_RO) && - (object_p->bool_attr_mask & TOKEN_BOOL_ON)) { - return (CKR_SESSION_READ_ONLY); - } - - - /* - * If the object is a session object, obtain the session handle - * which object belongs to. For a token object, we will use the - * session handle from the caller, because the session used to - * create the token object may no longer exist. - */ - if (!(object_p->bool_attr_mask & TOKEN_BOOL_ON)) - creating_session = object_p->session_handle; - else - creating_session = hSession; - - rv = handle2session(creating_session, &session_p); - if (rv != CKR_OK) { - return (rv); - } - - /* - * Set OBJECT_IS_DELETING flag so any access to this - * object will be rejected. - */ - (void) pthread_mutex_lock(&object_p->object_mutex); - if (object_p->obj_delete_sync & OBJECT_IS_DELETING) { - (void) pthread_mutex_unlock(&object_p->object_mutex); - REFRELE(session_p, ses_lock_held); - return (CKR_OBJECT_HANDLE_INVALID); - } - object_p->obj_delete_sync |= OBJECT_IS_DELETING; - (void) pthread_mutex_unlock(&object_p->object_mutex); - - if (object_p->bool_attr_mask & TOKEN_BOOL_ON) { - /* - * The first FALSE boolean argument indicates that the caller - * does not hold the slot lock. The second FALSE boolean - * argument indicates that the caller wants to clean up the - * object in the HW provider also. - */ - pslot = get_slotinfo(); - rv = kms_delete_token_object(pslot, session_p, object_p, - B_FALSE, B_FALSE); - } else { - /* - * The first FALSE boolean argument indicates that the caller - * does not hold the session lock. The second FALSE boolean - * argument indicates that the caller wants to clean the object - * in the HW provider also. - */ - rv = kms_delete_object(session_p, object_p, B_FALSE, - B_FALSE); - } - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - return (rv); -} - -CK_RV -C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) -{ - - CK_RV rv = CKR_OK, rv1 = CKR_OK; - kms_object_t *object_p; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - int i; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if ((pTemplate == NULL) || (ulCount == 0)) - return (CKR_ARGUMENTS_BAD); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hObject, object_p, rv); - if (rv != CKR_OK) { - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - return (rv); - } - - /* Acquire the lock on the object. */ - (void) pthread_mutex_lock(&object_p->object_mutex); - - /* - * The object was created in the library. The library - * contains the value information of each attribute. - */ - for (i = 0; i < ulCount; i++) { - /* - * Get the value of each attribute in the template. - * (We must process EVERY attribute in the template.) - */ - rv = kms_get_attribute(object_p, &pTemplate[i]); - if (rv != CKR_OK) - rv1 = rv; - } - (void) pthread_mutex_unlock(&object_p->object_mutex); - -clean_exit: - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - OBJ_REFRELE(object_p); - REFRELE(session_p, ses_lock_held); - rv = rv1; - return (rv); -} - -CK_RV -C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) -{ - CK_RV rv = CKR_OK; - kms_object_t *object_p; - kms_object_t *new_object = NULL; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - int i; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if ((pTemplate == NULL) || (ulCount == 0)) - return (CKR_ARGUMENTS_BAD); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hObject, object_p, rv); - if (rv != CKR_OK) { - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - return (rv); - } - - /* lock the object */ - (void) pthread_mutex_lock(&object_p->object_mutex); - - /* - * If the object was created in the HW provider, changing its - * attributes' values need to be done in the provider too. - */ - if (!object_p->is_lib_obj) { - - /* Cannot modify a token object with a READ-ONLY session */ - if (session_p->ses_RO && - (object_p->bool_attr_mask & TOKEN_BOOL_ON)) { - (void) pthread_mutex_unlock(&object_p->object_mutex); - rv = CKR_SESSION_READ_ONLY; - goto clean_exit; - } - } - - /* - * if we come here, the object must have been created in the - * library. The work will be done completely in the library. - * - * Copy the old object to a new object. We work on the copied - * version because in case of error we still keep the old one - * intact. - */ - rv = kms_copy_object(object_p, &new_object, B_FALSE, NULL); - (void) pthread_mutex_unlock(&object_p->object_mutex); - if ((rv != CKR_OK) || (new_object == NULL)) { - /* - * Most likely we ran out of space. - * Decrement the session reference count. - * We do not hold the session lock. - */ - goto clean_exit; - } - - for (i = 0; i < ulCount; i++) { - /* Set the requested attribute into the new object. */ - rv = kms_set_attribute(new_object, &pTemplate[i], B_FALSE); - - if (rv != CKR_OK) { - kms_cleanup_object(new_object); - goto clean_exit; - } - } - - /* - * We've successfully set all the requested attributes. - * Merge the new object with the old object, then destory - * the new one. The reason to do the merging is because we - * have to keep the original object handle (address of object). - */ - (void) pthread_mutex_lock(&object_p->object_mutex); - kms_merge_object(object_p, new_object); - (void) pthread_mutex_unlock(&object_p->object_mutex); - -clean_exit: - if (new_object != NULL) - (void) kms_free_object(new_object); - - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - OBJ_REFRELE(object_p); - REFRELE(session_p, ses_lock_held); - - return (rv); -} - -CK_RV -C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, - CK_ULONG_PTR pulSize) -{ - - CK_RV rv = CKR_OK; - kms_object_t *object_p; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Check if pulSize is valid */ - if (pulSize == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Obtain the object pointer. */ - HANDLE2OBJECT(hObject, object_p, rv); - if (rv != CKR_OK) { - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - REFRELE(session_p, ses_lock_held); - return (rv); - } - - /* Acquire the lock on the object. */ - (void) pthread_mutex_lock(&object_p->object_mutex); - - rv = kms_get_object_size(object_p, pulSize); - - (void) pthread_mutex_unlock(&object_p->object_mutex); - - /* - * Decrement the session reference count. - * We do not hold the session lock. - */ - OBJ_REFRELE(object_p); - REFRELE(session_p, ses_lock_held); - return (rv); -} - -CK_RV -C_FindObjectsInit(CK_SESSION_HANDLE sh, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount) -{ - CK_RV rv; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Check the arguments */ - if ((ulCount > 0) && (pTemplate == NULL)) { - return (CKR_ARGUMENTS_BAD); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(sh, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Acquire the session lock */ - (void) pthread_mutex_lock(&session_p->session_mutex); - ses_lock_held = B_TRUE; - - /* Check to see if find operation is already active */ - if (session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE) { - /* decrement the session count, and unlock the mutex */ - REFRELE(session_p, ses_lock_held); - return (CKR_OPERATION_ACTIVE); - } else { - /* - * This active flag will remain ON until application calls - * C_FindObjectsFinal. - */ - session_p->find_objects.flags = CRYPTO_OPERATION_ACTIVE; - } - (void) pthread_mutex_unlock(&session_p->session_mutex); - - /* - * If the KMS provider supports object creation, we call the - * CRYPTO_OBJECT_FIND_INIT to initialize object finding. - * Otherwise, all the objects are created in the library and we - * do the find objects solely in the library. - */ - rv = kms_find_objects_init(session_p, pTemplate, ulCount); - if (rv != CKR_OK) { - (void) pthread_mutex_lock(&session_p->session_mutex); - session_p->find_objects.flags = 0; - (void) pthread_mutex_unlock(&session_p->session_mutex); - } - /* decrement the session count, and unlock the mutex */ - REFRELE(session_p, ses_lock_held); - return (rv); -} - -CK_RV -C_FindObjects(CK_SESSION_HANDLE sh, CK_OBJECT_HANDLE_PTR phObject, - CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) -{ - CK_RV rv = CKR_OK; - kms_slot_t *pslot = NULL; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* check for invalid arguments */ - if (((phObject == NULL) && (ulMaxObjectCount != 0)) || - (pulObjectCount == NULL)) { - return (CKR_ARGUMENTS_BAD); - } - - if (ulMaxObjectCount == 0) { - /* don't need to do anything, just return */ - *pulObjectCount = 0; - return (CKR_OK); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(sh, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Acquire the slot lock */ - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* Acquire the session lock */ - (void) pthread_mutex_lock(&session_p->session_mutex); - ses_lock_held = B_TRUE; - - /* Check to see if find operation is active */ - if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) { - rv = CKR_OPERATION_NOT_INITIALIZED; - goto clean_exit; - } - - /* - * Similar to C_FindObjectInit(), if the KMS provider supports object - * creation, we need to find objects. - * Otherwise, all the objects are created in the library and we do - * the find objects solely in the library. - */ - - rv = kms_find_objects(session_p, phObject, - ulMaxObjectCount, pulObjectCount); - -clean_exit: - /* decrement the session count, and release the session lock */ - REFRELE(session_p, ses_lock_held); - - /* release the slot lock */ - if (pslot) - (void) pthread_mutex_unlock(&pslot->sl_mutex); - - return (rv); -} - -CK_RV -C_FindObjectsFinal(CK_SESSION_HANDLE sh) -{ - kms_session_t *session_p; - CK_RV rv; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(sh, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Acquire the session lock */ - (void) pthread_mutex_lock(&session_p->session_mutex); - ses_lock_held = B_TRUE; - - /* Check to see if find operation is active */ - if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) { - REFRELE(session_p, ses_lock_held); - return (CKR_OPERATION_NOT_INITIALIZED); - } - - /* - * Similar to C_FindObjectInit(), if the KMS provider supports object - * creation, we need to finalize the search on the KMS side. - */ - kms_find_objects_final(session_p); - - /* decrement the session count, and release the lock */ - REFRELE(session_p, ses_lock_held); - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.h deleted file mode 100644 index afd5803854..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KMSOBJECT_H -#define _KMSOBJECT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <security/pkcs11t.h> -#include "kmsSession.h" -#include "kmsSlot.h" - -#define KMSTOKEN_OBJECT_MAGIC 0xECF0B004 - -#define KMS_CREATE_OBJ 1 -#define KMS_GEN_KEY 2 - -/* - * Secret key Struct - */ -typedef struct secret_key_obj { - CK_BYTE *sk_value; - CK_ULONG sk_value_len; - void *key_sched; - size_t keysched_len; -} secret_key_obj_t; - -/* - * This structure is used to hold the attributes in the - * Extra Attribute List. - */ -typedef struct attribute_info { - CK_ATTRIBUTE attr; - struct attribute_info *next; -} attribute_info_t; - -typedef attribute_info_t *CK_ATTRIBUTE_INFO_PTR; - -/* - * This is the main structure of the Objects. - */ -typedef struct object { - boolean_t is_lib_obj; /* default is TRUE */ - - /* Generic common fields. Always present */ - CK_OBJECT_CLASS class; - CK_KEY_TYPE key_type; - CK_ULONG magic_marker; - uint64_t bool_attr_mask; - CK_MECHANISM_TYPE mechanism; - - /* Fields for access and arbitration */ - pthread_mutex_t object_mutex; - struct object *next; - struct object *prev; - - /* Extra non-boolean attribute list */ - CK_ATTRIBUTE_INFO_PTR extra_attrlistp; - CK_ULONG extra_attrcount; - - /* For each object, only one object class is presented */ - union { - secret_key_obj_t *secret_key; - } object_class_u; - - /* Session handle that the object belongs to */ - CK_SESSION_HANDLE session_handle; - uint32_t obj_refcnt; /* object reference count */ - pthread_cond_t obj_free_cond; /* cond variable for signal and wait */ - uint32_t obj_delete_sync; /* object delete sync flags */ -} kms_object_t; - -typedef struct find_context { - kms_object_t **objs_found; - CK_ULONG num_results; - CK_ULONG next_result_index; /* next result object to return */ -} find_context_t; - -/* - * The following structure is used to link the to-be-freed session - * objects into a linked list. The objects on this linked list have - * not yet been freed via free() after C_DestroyObject() call; instead - * they are added to this list. The actual free will take place when - * the number of objects queued reaches MAX_OBJ_TO_BE_FREED, at which - * time the first object in the list will be freed. - */ -#define MAX_OBJ_TO_BE_FREED 300 - -typedef struct obj_to_be_freed_list { - kms_object_t *first; /* points to first obj in the list */ - kms_object_t *last; /* points to last obj in the list */ - uint32_t count; /* current total objs in the list */ - pthread_mutex_t obj_to_be_free_mutex; -} object_to_be_freed_list_t; - -extern object_to_be_freed_list_t obj_delay_freed; - -/* - * The following definitions are the shortcuts - */ - -/* - * Secret Key Object Attributes - */ -#define OBJ_SEC(o) \ - ((o)->object_class_u.secret_key) -#define OBJ_SEC_VALUE(o) \ - ((o)->object_class_u.secret_key->sk_value) -#define OBJ_SEC_VALUE_LEN(o) \ - ((o)->object_class_u.secret_key->sk_value_len) -#define OBJ_KEY_SCHED(o) \ - ((o)->object_class_u.secret_key->key_sched) -#define OBJ_KEY_SCHED_LEN(o) \ - ((o)->object_class_u.secret_key->keysched_len) - -/* - * key related attributes with CK_BBOOL data type - */ -#define DERIVE_BOOL_ON 0x00000001 -#define LOCAL_BOOL_ON 0x00000002 -#define SENSITIVE_BOOL_ON 0x00000004 -#define SECONDARY_AUTH_BOOL_ON 0x00000008 -#define ENCRYPT_BOOL_ON 0x00000010 -#define DECRYPT_BOOL_ON 0x00000020 -#define SIGN_BOOL_ON 0x00000040 -#define SIGN_RECOVER_BOOL_ON 0x00000080 -#define VERIFY_BOOL_ON 0x00000100 -#define VERIFY_RECOVER_BOOL_ON 0x00000200 -#define WRAP_BOOL_ON 0x00000400 -#define UNWRAP_BOOL_ON 0x00000800 -#define TRUSTED_BOOL_ON 0x00001000 -#define EXTRACTABLE_BOOL_ON 0x00002000 -#define ALWAYS_SENSITIVE_BOOL_ON 0x00004000 -#define NEVER_EXTRACTABLE_BOOL_ON 0x00008000 -#define PRIVATE_BOOL_ON 0x00010000 -#define TOKEN_BOOL_ON 0x00020000 -#define MODIFIABLE_BOOL_ON 0x00040000 - -#define SECRET_KEY_DEFAULT (ENCRYPT_BOOL_ON|\ - DECRYPT_BOOL_ON|\ - SIGN_BOOL_ON|\ - VERIFY_BOOL_ON|\ - WRAP_BOOL_ON|\ - UNWRAP_BOOL_ON|\ - EXTRACTABLE_BOOL_ON|\ - MODIFIABLE_BOOL_ON) - -/* - * Flag definitions for obj_delete_sync - */ -#define OBJECT_IS_DELETING 1 /* Object is in a deleting state */ -#define OBJECT_REFCNT_WAITING 2 /* Waiting for object reference */ - /* count to become zero */ - -/* - * This macro is used to type cast an object handle to a pointer to - * the object struct. Also, it checks to see if the object struct - * is tagged with an object magic number. This is to detect when an - * application passes a bogus object pointer. - * Also, it checks to see if the object is in the deleting state that - * another thread is performing. If not, increment the object reference - * count by one. This is to prevent this object from being deleted by - * other thread. - */ -#define HANDLE2OBJECT_COMMON(hObject, object_p, rv, REFCNT_CODE) { \ - object_p = (kms_object_t *)(hObject); \ - if ((object_p == NULL) || \ - (object_p->magic_marker != KMSTOKEN_OBJECT_MAGIC)) {\ - rv = CKR_OBJECT_HANDLE_INVALID; \ - } else { \ - (void) pthread_mutex_lock(&object_p->object_mutex); \ - if (!(object_p->obj_delete_sync & OBJECT_IS_DELETING)) { \ - REFCNT_CODE; \ - rv = CKR_OK; \ - } else { \ - rv = CKR_OBJECT_HANDLE_INVALID; \ - } \ - (void) pthread_mutex_unlock(&object_p->object_mutex); \ - } \ -} - -#define HANDLE2OBJECT(hObject, object_p, rv) \ - HANDLE2OBJECT_COMMON(hObject, object_p, rv, object_p->obj_refcnt++) - -#define HANDLE2OBJECT_DESTROY(hObject, object_p, rv) \ - HANDLE2OBJECT_COMMON(hObject, object_p, rv, /* no refcnt increment */) - - -#define OBJ_REFRELE(object_p) { \ - (void) pthread_mutex_lock(&object_p->object_mutex); \ - if ((--object_p->obj_refcnt) == 0 && \ - (object_p->obj_delete_sync & OBJECT_REFCNT_WAITING)) { \ - (void) pthread_cond_signal(&object_p->obj_free_cond); \ - } \ - (void) pthread_mutex_unlock(&object_p->object_mutex); \ -} - - -/* - * Function Prototypes. - */ -void kms_cleanup_object(kms_object_t *objp); - -CK_RV kms_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_ULONG *objecthandle_p, kms_session_t *sp); - -CK_RV kms_delete_object(kms_session_t *, kms_object_t *, - boolean_t, boolean_t); - -void kms_cleanup_extra_attr(kms_object_t *object_p); - -CK_RV kms_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, - kms_object_t *object_p); - -void kms_cleanup_object_bigint_attrs(kms_object_t *object_p); - -CK_RV kms_build_object(CK_ATTRIBUTE_PTR, CK_ULONG, kms_object_t *); - -CK_RV kms_copy_object(kms_object_t *old_object, - kms_object_t **new_object, boolean_t copy_everything, - kms_session_t *sp); - -void kms_merge_object(kms_object_t *old_object, - kms_object_t *new_object); - -CK_RV kms_get_attribute(kms_object_t *object_p, - CK_ATTRIBUTE_PTR template); - -CK_RV kms_set_attribute(kms_object_t *, CK_ATTRIBUTE_PTR, boolean_t); - -void kms_add_object_to_session(kms_object_t *objp, kms_session_t *sp); - -CK_RV kms_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p, - secret_key_obj_t **new_secret_key_obj_p); - -CK_RV kms_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum, - CK_OBJECT_CLASS *class); - -CK_RV kms_find_objects_init(kms_session_t *sp, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); - -void kms_find_objects_final(kms_session_t *sp); - -CK_RV kms_find_objects(kms_session_t *sp, - CK_OBJECT_HANDLE *obj_found, CK_ULONG max_obj_requested, - CK_ULONG *found_obj_count); - -void kms_process_find_attr(CK_OBJECT_CLASS *pclasses, - CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount); - -boolean_t kms_find_match_attrs(kms_object_t *obj, - CK_OBJECT_CLASS *pclasses, CK_ULONG num_pclasses, - CK_ATTRIBUTE *tmpl_attr, CK_ULONG num_attr); - -CK_ATTRIBUTE_PTR get_extra_attr(CK_ATTRIBUTE_TYPE type, kms_object_t *obj); - -CK_RV get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src); - -void string_attr_cleanup(CK_ATTRIBUTE_PTR template); - -void kms_add_token_object_to_slot(kms_object_t *objp, - kms_slot_t *pslot); - -void kms_remove_token_object_from_slot(kms_slot_t *pslot, - kms_object_t *objp); - -CK_RV kms_delete_token_object(kms_slot_t *pslot, kms_session_t *sp, - kms_object_t *obj, boolean_t lock_held, boolean_t wrapper_only); - -void kms_cleanup_pri_objects_in_slot(kms_slot_t *pslot, - kms_session_t *sp); - -CK_RV kms_get_object_size(kms_object_t *objp, CK_ULONG_PTR pulSize); - -void kms_object_delay_free(kms_object_t *); - -kms_object_t *kms_new_object(); -void kms_free_object(kms_object_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMSOBJECT_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObjectUtil.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObjectUtil.c deleted file mode 100644 index 64ddc11060..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObjectUtil.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <strings.h> -#include <errno.h> -#include <security/cryptoki.h> -#include <cryptoutil.h> - -#include "kmsGlobal.h" -#include "kmsObject.h" -#include "kmsSession.h" -#include "kmsSlot.h" -#include "kmsKeystoreUtil.h" - -kms_object_t * -kms_new_object() -{ - kms_object_t *obj; - - obj = calloc(1, sizeof (kms_object_t)); - if (obj == NULL) - return (NULL); - - (void) pthread_cond_init(&obj->obj_free_cond, NULL); - (void) pthread_mutex_init(&obj->object_mutex, NULL); - obj->magic_marker = KMSTOKEN_OBJECT_MAGIC; - - return (obj); -} - -/* - * Add an object to the session's object list. - * - * This function will acquire the lock on the session, and release - * that lock after adding the object to the session's object list. - */ -void -kms_add_object_to_session(kms_object_t *objp, kms_session_t *sp) -{ - /* Acquire the session lock. */ - (void) pthread_mutex_lock(&sp->session_mutex); - - /* Insert the new object in front of session's object list. */ - if (sp->object_list == NULL) { - sp->object_list = objp; - objp->next = NULL; - objp->prev = NULL; - } else { - sp->object_list->prev = objp; - objp->next = sp->object_list; - objp->prev = NULL; - sp->object_list = objp; - } - - /* Release the session lock. */ - (void) pthread_mutex_unlock(&sp->session_mutex); -} - -/* - * Clean up and release the storage allocated to the object. - * - * The function is called either with the object lock being held - * (by caller kms_delete_object()), or there is no object lock - * yet (by kms_build_XXX_object() during creating an object). - */ -void -kms_cleanup_object(kms_object_t *objp) -{ - /* - * Free the storage allocated to a secret key object. - */ - if (objp->class == CKO_SECRET_KEY) { - if (OBJ_SEC(objp) != NULL && OBJ_SEC_VALUE(objp) != NULL) { - bzero(OBJ_SEC_VALUE(objp), OBJ_SEC_VALUE_LEN(objp)); - free(OBJ_SEC_VALUE(objp)); - OBJ_SEC_VALUE(objp) = NULL; - OBJ_SEC_VALUE_LEN(objp) = 0; - } - if (OBJ_SEC(objp) != NULL) - free(OBJ_SEC(objp)); - - OBJ_SEC(objp) = NULL; - } - - /* - * Free the storage allocated to the extra attribute list. - */ - kms_cleanup_extra_attr(objp); -} - -void -kms_free_object(kms_object_t *obj) -{ - (void) pthread_cond_destroy(&obj->obj_free_cond); - (void) pthread_mutex_destroy(&obj->object_mutex); - - kms_cleanup_object(obj); - - free(obj); -} - -/* - * Create a new object. Copy the attributes that can be modified - * (in the boolean attribute mask field and extra attribute list) - * from the old object to the new object. - * - * The caller of this function holds the lock on the old object. - */ -CK_RV -kms_copy_object(kms_object_t *old_object, kms_object_t **new_object, - boolean_t copy_everything, kms_session_t *sp) -{ - CK_RV rv = CKR_OK; - kms_object_t *new_objp = NULL; - CK_ATTRIBUTE_INFO_PTR attrp; - - /* Allocate new object. */ - new_objp = kms_new_object(); - if (new_objp == NULL) - return (CKR_HOST_MEMORY); - - new_objp->class = old_object->class; - new_objp->bool_attr_mask = old_object->bool_attr_mask; - - attrp = old_object->extra_attrlistp; - while (attrp) { - /* - * Copy the attribute_info struct from the old - * object to a new attribute_info struct, and add - * that new struct to the extra attribute list - * of the new object. - */ - rv = kms_copy_extra_attr(attrp, new_objp); - if (rv != CKR_OK) { - kms_free_object(new_objp); - return (rv); - } - attrp = attrp->next; - } - - *new_object = new_objp; - - if (!copy_everything) { - /* done with copying all information that can be modified */ - return (CKR_OK); - } - - /* - * Copy the rest of the object. - * Certain fields that are not appropriate for coping will be - * initialized. - */ - new_objp->key_type = old_object->key_type; - new_objp->magic_marker = old_object->magic_marker; - new_objp->mechanism = old_object->mechanism; - new_objp->session_handle = (CK_SESSION_HANDLE)sp; - - /* copy key related information */ - switch (new_objp->class) { - case CKO_SECRET_KEY: - rv = kms_copy_secret_key_attr(OBJ_SEC(old_object), - &(OBJ_SEC(new_objp))); - break; - default: - /* should never be this case */ - break; - } - if (rv != CKR_OK) { - kms_free_object(new_objp); - *new_object = NULL; - } - return (rv); -} - -/* - * Copy the attributes (in the boolean attribute mask field and - * extra attribute list) from the new object back to the original - * object. Also, clean up and release all the storage in the extra - * attribute list of the original object. - * - * The caller of this function holds the lock on the old object. - */ -void -kms_merge_object(kms_object_t *old_object, kms_object_t *new_object) -{ - old_object->bool_attr_mask = new_object->bool_attr_mask; - kms_cleanup_extra_attr(old_object); - old_object->extra_attrlistp = new_object->extra_attrlistp; -} - -/* - * Create a new object struct. If it is a session object, add the object to - * the session's object list. If it is a token object, add it to the slot's - * token object list. The caller does not hold the slot lock. - */ -CK_RV -kms_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_ULONG *objecthandle_p, kms_session_t *sp) -{ - CK_RV rv = CKR_OK; - kms_object_t *new_objp = NULL; - kms_slot_t *pslot; - CK_ATTRIBUTE pritmpl; - CK_BBOOL is_pri_obj, is_token_obj; - - new_objp = kms_new_object(); - if (new_objp == NULL) - return (CKR_HOST_MEMORY); - - rv = kms_build_object(pTemplate, ulCount, new_objp); - if (rv != CKR_OK) - goto fail_cleanup; - - /* Cannot create a token object with a READ-ONLY session */ - pritmpl.type = CKA_TOKEN; - pritmpl.pValue = &is_token_obj; - pritmpl.ulValueLen = sizeof (is_token_obj); - rv = kms_get_attribute(new_objp, &pritmpl); - if (rv != CKR_OK) - goto fail_cleanup; - - if (is_token_obj && sp->ses_RO) { - rv = CKR_SESSION_READ_ONLY; - goto fail_cleanup; - } - - /* - * If the KMS supports object creation, create the object - * in the KMS. Otherwise, create the object in the library. - */ - - /* Get the CKA_PRIVATE value of this object. */ - pritmpl.type = CKA_PRIVATE; - pritmpl.pValue = &is_pri_obj; - pritmpl.ulValueLen = sizeof (is_pri_obj); - - rv = kms_get_attribute(new_objp, &pritmpl); - if (rv != CKR_OK) { - goto fail_cleanup; - } - - /* Set the PRIVATE_BOOL_ON and TOKEN_BOOL_ON attributes */ - if (is_pri_obj) - new_objp->bool_attr_mask |= PRIVATE_BOOL_ON; - else - new_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON; - - if (is_token_obj) - new_objp->bool_attr_mask |= TOKEN_BOOL_ON; - else - new_objp->bool_attr_mask &= ~TOKEN_BOOL_ON; - - new_objp->session_handle = (CK_SESSION_HANDLE)sp; - - if (is_token_obj) { - /* Add the new object to the slot's token object list. */ - pslot = get_slotinfo(); - kms_add_token_object_to_slot(new_objp, pslot); - } else { - /* Add the new object to the session's object list. */ - kms_add_object_to_session(new_objp, sp); - } - - /* Type casting the address of an object struct to an object handle. */ - if (rv == CKR_OK) - *objecthandle_p = (CK_ULONG)new_objp; - -fail_cleanup: - if (rv != CKR_OK) { - kms_free_object(new_objp); - } - return (rv); -} - -/* - * Remove an object from the session's object list. - * - * The caller of this function holds the session lock. - */ -CK_RV -kms_remove_object_from_session(kms_object_t *objp, kms_session_t *sp) -{ - kms_object_t *tmp_objp; - boolean_t found = B_FALSE; - - /* - * Remove the object from the session's object list. - */ - if ((sp == NULL) || - (sp->magic_marker != KMSTOKEN_SESSION_MAGIC)) { - return (CKR_SESSION_HANDLE_INVALID); - } - - if ((sp->object_list == NULL) || (objp == NULL) || - (objp->magic_marker != KMSTOKEN_OBJECT_MAGIC)) { - return (CKR_OBJECT_HANDLE_INVALID); - } - - tmp_objp = sp->object_list; - while (tmp_objp) { - if (tmp_objp == objp) { - found = B_TRUE; - break; - } - tmp_objp = tmp_objp->next; - } - if (!found) - return (CKR_OBJECT_HANDLE_INVALID); - - if (sp->object_list == objp) { - /* Object is the first one in the list. */ - if (objp->next) { - sp->object_list = objp->next; - objp->next->prev = NULL; - } else { - /* Object is the only one in the list. */ - sp->object_list = NULL; - } - } else { - /* Object is not the first one in the list. */ - if (objp->next) { - /* Object is in the middle of the list. */ - objp->prev->next = objp->next; - objp->next->prev = objp->prev; - } else { - /* Object is the last one in the list. */ - objp->prev->next = NULL; - } - } - return (CKR_OK); -} - -/* - * This function adds the to-be-freed session object to a linked list. - * When the number of objects queued in the linked list reaches the - * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first - * object (FIFO) in the list. - */ -void -kms_object_delay_free(kms_object_t *objp) -{ - kms_object_t *tmp; - - (void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex); - - /* Add the newly deleted object at the end of the list */ - objp->next = NULL; - if (obj_delay_freed.first == NULL) { - obj_delay_freed.last = objp; - obj_delay_freed.first = objp; - } else { - obj_delay_freed.last->next = objp; - obj_delay_freed.last = objp; - } - - if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) { - /* - * Free the first object in the list only if - * the total count reaches maximum threshold. - */ - obj_delay_freed.count--; - tmp = obj_delay_freed.first->next; - kms_free_object(obj_delay_freed.first); - obj_delay_freed.first = tmp; - } - (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex); -} - -static void -kms_delete_object_cleanup(kms_object_t *objp, boolean_t force) -{ - /* Acquire the lock on the object. */ - (void) pthread_mutex_lock(&objp->object_mutex); - - /* - * Make sure another thread hasn't freed the object. - */ - if (objp->magic_marker != KMSTOKEN_OBJECT_MAGIC) { - (void) pthread_mutex_unlock(&objp->object_mutex); - return; - } - - /* - * The deletion of an object must be blocked when the object - * reference count is not zero. This means if any object related - * operation starts prior to the delete object operation gets in, - * the object deleting thread must wait for the non-deleting - * operation to be completed before it can proceed the delete - * operation. - * - * Unless we are being forced to shut everything down, this only - * happens if the library's _fini() is running not if someone - * explicitly called C_Finalize(). - */ - if (force) { - objp->obj_refcnt = 0; - } - - while (objp->obj_refcnt != 0) { - /* - * We set the OBJECT_REFCNT_WAITING flag before we put - * this deleting thread in a wait state, so other non-deleting - * operation thread will signal to wake it up only when - * the object reference count becomes zero and this flag - * is set. - */ - objp->obj_delete_sync |= OBJECT_REFCNT_WAITING; - (void) pthread_cond_wait(&objp->obj_free_cond, - &objp->object_mutex); - } - - objp->obj_delete_sync &= ~OBJECT_REFCNT_WAITING; - - /* Mark object as no longer valid. */ - objp->magic_marker = 0; - kms_cleanup_object(objp); - - objp->obj_delete_sync &= ~OBJECT_IS_DELETING; - (void) pthread_mutex_unlock(&objp->object_mutex); - - if (objp->bool_attr_mask & TOKEN_BOOL_ON) - free(objp); - else - kms_object_delay_free(objp); -} - -/* - * Delete a session object: - * - Remove the object from the session's object list. - * - Release the storage allocated to the object. - * - * The boolean argument ses_lock_held is used to indicate that whether - * the caller holds the session lock or not. - * - When called by kms_delete_all_objects_in_session() or - * kms_delete_pri_objects_in_slot() -- ses_lock_held = TRUE. - * - * The boolean argument wrapper_only is used to indicate that whether - * the caller only wants to clean up the object wrapper from the library and - * needs not to make an call to KMS. - * - This argument only applies to the object created in the provider level. - * - When called by kms_cleanup_pri_objects_in_slot(), wrapper_only is TRUE. - * - When called by C_DestroyObject(), wrapper_only is FALSE. - * - When called by kms_delete_all_objects_in_session(), the value of - * wrapper_only depends on its caller. - */ -CK_RV -kms_delete_object(kms_session_t *sp, kms_object_t *objp, - boolean_t ses_lock_held, boolean_t wrapper_only) -{ - CK_RV rv = CKR_OK; - - /* - * Check to see if the caller holds the lock on the session. - * If not, we need to acquire that lock in order to proceed. - */ - if (!ses_lock_held) { - /* Acquire the session lock. */ - (void) pthread_mutex_lock(&sp->session_mutex); - } - - /* Remove the object from the session's object list first. */ - if ((rv = kms_remove_object_from_session(objp, sp))) { - if (!ses_lock_held) - (void) pthread_mutex_unlock(&sp->session_mutex); - return (rv); - } - - if (!wrapper_only) - (void) pthread_mutex_unlock(&sp->session_mutex); - - kms_delete_object_cleanup(objp, wrapper_only); - - return (rv); -} - -/* - * Delete all the objects in a session. The caller holds the lock - * on the session. If the wrapper_only argument is TRUE, the caller only - * want to clean up object wrappers in the library. - */ -void -kms_delete_all_objects_in_session(kms_session_t *sp, - boolean_t wrapper_only) -{ - kms_object_t *objp = sp->object_list; - kms_object_t *objp1; - - /* Delete all the objects in the session. */ - while (objp) { - objp1 = objp->next; - (void) kms_delete_object(sp, objp, B_TRUE, - wrapper_only); - - objp = objp1; - } -} - -static CK_RV -add_to_search_result(kms_object_t *obj, find_context_t *fcontext, - CK_ULONG *num_result_alloc) -{ - /* - * allocate space for storing results if the currently - * allocated space is not enough - */ - if (*num_result_alloc <= fcontext->num_results) { - fcontext->objs_found = realloc(fcontext->objs_found, - sizeof (kms_object_t *) * (*num_result_alloc + BUFSIZ)); - if (fcontext->objs_found == NULL) { - return (CKR_HOST_MEMORY); - } - *num_result_alloc += BUFSIZ; - } - - (fcontext->objs_found)[(fcontext->num_results)++] = obj; - return (CKR_OK); -} - -static CK_RV -search_for_objects(kms_session_t *sp, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, find_context_t *fcontext) -{ - kms_session_t *session_p; - kms_object_t *obj; - CK_OBJECT_CLASS pclasses[6]; /* classes attrs possibly exist */ - CK_ULONG num_pclasses; /* number of possible classes */ - CK_ULONG num_result_alloc = 0; /* spaces allocated for results */ - CK_RV rv = CKR_OK; - kms_slot_t *pslot = NULL; - boolean_t token_specified = B_FALSE; - boolean_t token_flag_val = B_FALSE; - int i; - - if (ulCount > 0) { - /* there are some search requirement */ - kms_process_find_attr(pclasses, &num_pclasses, - pTemplate, ulCount); - } - - /* - * look through template and see if it explicitly specifies - * whether we need to look for token objects or not - */ - for (i = 0; i < ulCount; i++) { - if (pTemplate[i].type == CKA_TOKEN) { - token_specified = B_TRUE; - token_flag_val = *((CK_BBOOL *)pTemplate[i].pValue); - break; - } - } - - pslot = get_slotinfo(); - - /* Acquire the slot lock */ - if (token_flag_val || !token_specified) { - (void) pthread_mutex_lock(&pslot->sl_mutex); - /* - * Make sure the object list is current. - */ - rv = KMS_RefreshObjectList(sp, pslot); - if (rv != CKR_OK) { - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); - } - - obj = pslot->sl_tobj_list; - while (obj) { - (void) pthread_mutex_lock(&obj->object_mutex); - if (((token_specified) && (ulCount > 1)) || - ((!token_specified) && (ulCount > 0))) { - if (kms_find_match_attrs(obj, pclasses, - num_pclasses, pTemplate, ulCount)) { - rv = add_to_search_result( - obj, fcontext, &num_result_alloc); - } - } else { - /* no search criteria, just record the object */ - rv = add_to_search_result(obj, fcontext, - &num_result_alloc); - } - (void) pthread_mutex_unlock(&obj->object_mutex); - if (rv != CKR_OK) { - goto cleanup; - } - obj = obj->next; - } - (void) pthread_mutex_unlock(&pslot->sl_mutex); - } - - if (token_flag_val) { - return (rv); - } - - /* - * Go through all objects in each session. - * Acquire individual session lock for the session - * we are searching. - */ - session_p = pslot->sl_sess_list; - while (session_p) { - (void) pthread_mutex_lock(&session_p->session_mutex); - obj = session_p->object_list; - while (obj) { - (void) pthread_mutex_lock(&obj->object_mutex); - if (ulCount > 0) { - if (kms_find_match_attrs(obj, pclasses, - num_pclasses, pTemplate, ulCount)) { - rv = add_to_search_result( - obj, fcontext, &num_result_alloc); - } - } else { - /* no search criteria, just record the object */ - rv = add_to_search_result(obj, fcontext, - &num_result_alloc); - } - (void) pthread_mutex_unlock(&obj->object_mutex); - if (rv != CKR_OK) { - (void) pthread_mutex_unlock( - &session_p->session_mutex); - goto cleanup; - } - obj = obj->next; - } - (void) pthread_mutex_unlock(&session_p->session_mutex); - session_p = session_p->next; - } - -cleanup: - /* Release the slot lock */ - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); -} - -/* - * Initialize the context for C_FindObjects() calls - */ -CK_RV -kms_find_objects_init(kms_session_t *sp, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount) -{ - CK_RV rv = CKR_OK; - CK_OBJECT_CLASS class; /* for kms_validate_attr(). Value unused */ - find_context_t *fcontext; - - if (ulCount) { - rv = kms_validate_attr(pTemplate, ulCount, &class); - /* Make sure all attributes in template are valid */ - if (rv != CKR_OK) { - return (rv); - } - } - - /* prepare the find context */ - fcontext = calloc(1, sizeof (find_context_t)); - if (fcontext == NULL) { - return (CKR_HOST_MEMORY); - } - - rv = search_for_objects(sp, pTemplate, ulCount, fcontext); - if (rv != CKR_OK) { - free(fcontext); - return (rv); - } - - /* store the find_context in the session */ - sp->find_objects.context = (CK_VOID_PTR)fcontext; - - return (rv); -} - -void -kms_find_objects_final(kms_session_t *sp) -{ - find_context_t *fcontext; - - fcontext = sp->find_objects.context; - sp->find_objects.context = NULL; - sp->find_objects.flags = 0; - if (fcontext->objs_found != NULL) { - free(fcontext->objs_found); - } - - free(fcontext); -} - -CK_RV -kms_find_objects(kms_session_t *sp, CK_OBJECT_HANDLE *obj_found, - CK_ULONG max_obj_requested, CK_ULONG *found_obj_count) -{ - find_context_t *fcontext; - CK_ULONG num_obj_found = 0; - CK_ULONG i; - kms_object_t *obj; - - fcontext = sp->find_objects.context; - - for (i = fcontext->next_result_index; - ((num_obj_found < max_obj_requested) && - (i < fcontext->num_results)); - i++) { - obj = fcontext->objs_found[i]; - if (obj != NULL) { - (void) pthread_mutex_lock(&obj->object_mutex); - /* a sanity check to make sure the obj is still valid */ - if (obj->magic_marker == KMSTOKEN_OBJECT_MAGIC) { - obj_found[num_obj_found] = - (CK_OBJECT_HANDLE)obj; - num_obj_found++; - } - (void) pthread_mutex_unlock(&obj->object_mutex); - } - } - fcontext->next_result_index = i; - *found_obj_count = num_obj_found; - return (CKR_OK); -} - -/* - * Add an token object to the token object list in slot. - * - * This function will acquire the lock on the slot, and release - * that lock after adding the object to the slot's token object list. - */ -void -kms_add_token_object_to_slot(kms_object_t *objp, kms_slot_t *pslot) -{ - /* Acquire the slot lock. */ - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* Insert the new object in front of slot's token object list. */ - if (pslot->sl_tobj_list == NULL) { - pslot->sl_tobj_list = objp; - objp->next = NULL; - objp->prev = NULL; - } else { - pslot->sl_tobj_list->prev = objp; - objp->next = pslot->sl_tobj_list; - objp->prev = NULL; - pslot->sl_tobj_list = objp; - } - - /* Release the slot lock. */ - (void) pthread_mutex_unlock(&pslot->sl_mutex); -} - -/* - * Remove an token object from the slot's token object list. - * This routine is called by kms_delete_token_object(). - * The caller of this function hold the slot lock. - */ -void -kms_remove_token_object_from_slot(kms_slot_t *pslot, - kms_object_t *objp) -{ - - if (pslot->sl_tobj_list == objp) { - /* Object is the first one in the list */ - if (objp->next) { - pslot->sl_tobj_list = objp->next; - objp->next->prev = NULL; - } else { - /* Object is the only one in the list. */ - pslot->sl_tobj_list = NULL; - } - } else { - /* Object is not the first one in the list. */ - if (objp->next) { - /* Object is in the middle of the list. */ - if (objp->prev) - objp->prev->next = objp->next; - objp->next->prev = objp->prev; - } else if (objp->prev) { - /* Object is the last one in the list. */ - objp->prev->next = NULL; - } - } -} - -/* - * Delete a token object: - * - Remove the object from the slot's token object list. - * - Release the storage allocated to the object. - * - * The boolean argument slot_lock_held is used to indicate that whether - * the caller holds the slot lock or not. When the caller does not hold - * the slot lock, this function will acquire that lock in order to proceed, - * and also release that lock before returning to caller. - * - * The boolean argument wrapper_only is used to indicate that whether - * the caller only wants to the object wrapper from library. - */ -CK_RV -kms_delete_token_object(kms_slot_t *pslot, kms_session_t *sp, - kms_object_t *objp, boolean_t slot_lock_held, boolean_t wrapper_only) -{ - CK_RV rv = CKR_OK; - - if (!slot_lock_held) { - (void) pthread_mutex_lock(&pslot->sl_mutex); - } - if (!wrapper_only && objp->class == CKO_SECRET_KEY) { - /* Delete from KMS */ - rv = KMS_DestroyKey(sp, objp); - } - - /* Remove the object from the slot's token object list first. */ - kms_remove_token_object_from_slot(pslot, objp); - - /* Release the slot lock if the call doesn't hold the lock. */ - if (!slot_lock_held) { - (void) pthread_mutex_unlock(&pslot->sl_mutex); - } - - kms_delete_object_cleanup(objp, wrapper_only); - - return (rv); -} - -/* - * Clean up private object wrappers in this slot. The caller holds the slot - * lock. - */ -void -kms_cleanup_pri_objects_in_slot(kms_slot_t *pslot, - kms_session_t *cur_sp) -{ - kms_session_t *session_p; - kms_object_t *objp; - kms_object_t *objp1; - - /* - * Delete every private token object from - * the slot token object list. - */ - (void) pthread_mutex_lock(&pslot->sl_mutex); - objp = pslot->sl_tobj_list; - while (objp) { - objp1 = objp->next; - /* - * The first TRUE boolean argument indicates that the caller - * hold the slot lock. The second TRUE boolean argument - * indicates that the caller just wants to clean up the object - * wrapper from the library only. - */ - if (objp->bool_attr_mask & PRIVATE_BOOL_ON) { - (void) kms_delete_token_object(pslot, cur_sp, objp, - B_TRUE, B_TRUE); - } - objp = objp1; - } - - (void) pthread_mutex_unlock(&pslot->sl_mutex); - /* - * Walk through all the sessions in this slot and delete every - * private object. - */ - session_p = pslot->sl_sess_list; - while (session_p) { - - /* Delete all the objects in the session. */ - objp = session_p->object_list; - while (objp) { - objp1 = objp->next; - /* - * The FALSE boolean argument indicates that the - * caller does not hold the session lock. The TRUE - * boolean argument indicates that the caller just - * want to clean upt the object wrapper from the - * library only. - */ - if (objp->bool_attr_mask & PRIVATE_BOOL_ON) { - (void) kms_delete_object(session_p, - objp, B_FALSE, B_TRUE); - } - objp = objp1; - } - - session_p = session_p->next; - } -} - -/* - * Get the object size in bytes for the objects created in the library. - */ -CK_RV -kms_get_object_size(kms_object_t *obj, CK_ULONG_PTR pulSize) -{ - CK_RV rv = CKR_OK; - CK_ULONG obj_size; - - obj_size = sizeof (kms_object_t); - - switch (obj->class) { - case CKO_SECRET_KEY: - obj_size += OBJ_SEC_VALUE_LEN(obj); - break; - - default: - rv = CKR_OBJECT_HANDLE_INVALID; - } - - if (rv == CKR_OK) { - *pulSize = obj_size; - } - - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsRand.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsRand.c deleted file mode 100644 index 088c09c204..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsRand.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <security/cryptoki.h> -#include "kmsGlobal.h" - -/*ARGSUSED*/ -CK_RV -C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, - CK_ULONG ulRandomLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.c deleted file mode 100644 index bdde865b56..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <pthread.h> -#include <errno.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsSession.h" -#include "kmsSlot.h" -#include "kmsKeystoreUtil.h" - -CK_RV -C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, - CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) -{ - CK_RV rv = CKR_OK; - kms_slot_t *pslot; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (!(flags & CKF_SERIAL_SESSION)) - return (CKR_SESSION_PARALLEL_NOT_SUPPORTED); - - if (phSession == NULL) - return (CKR_ARGUMENTS_BAD); - - if (slotID != KMS_TOKEN_SLOTID) { - return (CKR_SLOT_ID_INVALID); - } - - /* - * Acquire the slot lock to protect sl_state and sl_sess_list. - * These two fields need to be protected atomically, even though - * "sl_sess_list" is updated in kms_add_session(). - */ - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* If SO is logged in the slot, only the RW session is allowed. */ - if ((pslot->sl_state == CKU_SO) && !(flags & CKF_RW_SESSION)) { - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (CKR_SESSION_READ_WRITE_SO_EXISTS); - } - - /* Create a new session */ - rv = kms_add_session(slotID, flags, pApplication, Notify, - phSession); - - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); -} - -CK_RV -C_CloseSession(CK_SESSION_HANDLE hSession) -{ - CK_RV rv; - - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - (void) pthread_mutex_lock(&session_p->session_mutex); - ses_lock_held = B_TRUE; - - /* - * Set SESSION_IS_CLOSING flag so any access to this - * session will be rejected. - */ - if (session_p->ses_close_sync & SESSION_IS_CLOSING) { - REFRELE(session_p, ses_lock_held); - return (CKR_SESSION_CLOSED); - } - session_p->ses_close_sync |= SESSION_IS_CLOSING; - - /* - * Decrement the session reference count. - * We hold the session lock, and REFRELE() - * will release the session lock for us. - */ - REFRELE(session_p, ses_lock_held); - - /* - * Delete a session by calling kms_delete_session() with - * a session pointer and two boolean arguments. The 3rd argument - * boolean value FALSE indicates that the caller does not - * hold the slot lock. The 4th argument boolean value B_FALSE - * indicates that we want to delete all the objects completely. - * - * kms_delete_session() will reset SESSION_IS_CLOSING - * flag after it is done. - */ - kms_delete_session(session_p, B_FALSE, B_FALSE); - return (rv); -} - -/*ARGSUSED*/ -CK_RV -C_CloseAllSessions(CK_SLOT_ID slotID) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* Delete all the sessions and release the allocated resources */ - kms_delete_all_sessions(B_FALSE); - - return (CKR_OK); -} - -/* - * Utility routine to get CK_STATE value for a session. - * The caller should not be holding the session lock. - */ -static CK_STATE -get_ses_state(kms_session_t *session_p) -{ - CK_STATE state; - kms_slot_t *pslot; - - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - if (pslot->sl_state == CKU_PUBLIC) { - state = (session_p->ses_RO) ? - CKS_RO_PUBLIC_SESSION : CKS_RW_PUBLIC_SESSION; - } else if (pslot->sl_state == CKU_USER) { - state = (session_p->ses_RO) ? - CKS_RO_USER_FUNCTIONS : CKS_RW_USER_FUNCTIONS; - } else if (pslot->sl_state == CKU_SO) { - state = CKS_RW_SO_FUNCTIONS; - } - - (void) pthread_mutex_unlock(&pslot->sl_mutex); - - return (state); -} - -CK_RV -C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) -{ - kms_session_t *session_p; - CK_RV rv; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (pInfo == NULL) - return (CKR_ARGUMENTS_BAD); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Provide information for the specified session */ - pInfo->slotID = session_p->ses_slotid; - pInfo->flags = session_p->flags; - pInfo->ulDeviceError = 0; - pInfo->state = get_ses_state(session_p); - - /* - * Decrement the session reference count. - */ - REFRELE(session_p, ses_lock_held); - - return (rv); -} - -/*ARGSUSED*/ -CK_RV -C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, - CK_ULONG_PTR pulOperationStateLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, - CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, - CK_OBJECT_HANDLE hAuthenticationKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -CK_RV -C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, - CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) -{ - CK_RV rv = CKR_OK; - kms_session_t *session_p; - kms_slot_t *pslot; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if ((userType != CKU_SO) && (userType != CKU_USER)) { - return (CKR_USER_TYPE_INVALID); - } - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Acquire the slot lock */ - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* Check if the slot is logged in already */ - if ((pslot->sl_state == CKU_USER) || (pslot->sl_state == CKU_SO)) { - rv = CKR_USER_ALREADY_LOGGED_IN; - goto clean_exit; - } - - /* To login as SO, every session in this slot needs to be R/W */ - if (userType == CKU_SO) { - kms_session_t *sp; - boolean_t found; - - found = B_FALSE; - sp = pslot->sl_sess_list; - while (sp) { - /* - * Need not to lock individual sessions before - * accessing their "ses_RO" and "next" fields, - * because they are always accessed under the - * slot's mutex protection. - */ - if (sp->ses_RO) { - found = B_TRUE; - break; - } - sp = sp->next; - } - - if (found) { - rv = CKR_SESSION_READ_ONLY_EXISTS; - goto clean_exit; - } - } - - /* - * Login to KMS by attempting to load the profile using - * the given password. - */ - rv = KMS_LoadProfile( - &session_p->kmsProfile, - &session_p->configInfo, - (const char *)pPin, - (size_t)ulPinLen); - - if (rv == CKR_OK) { - /* Set the slot's session state. */ - pslot->sl_state = userType; - } - -clean_exit: - - REFRELE(session_p, ses_lock_held); - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); -} - -CK_RV -C_Logout(CK_SESSION_HANDLE hSession) -{ - CK_RV rv = CKR_OK; - kms_session_t *session_p; - kms_slot_t *pslot; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Acquire the slot lock. */ - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* Check if the user or SO was logged in */ - if (pslot->sl_state == CKU_PUBLIC) { - rv = CKR_USER_NOT_LOGGED_IN; - goto clean_exit; - } - - KMS_UnloadProfile(&session_p->kmsProfile); - - /* - * If this slot was logged in as USER previously, we need to clean up - * all private object wrappers in library for this slot. - */ - kms_cleanup_pri_objects_in_slot(pslot, session_p); - - if (rv == CKR_OK) { - /* Reset the slot's session state. */ - pslot->sl_state = CKU_PUBLIC; - } - -clean_exit: - REFRELE(session_p, ses_lock_held); - (void) pthread_mutex_unlock(&pslot->sl_mutex); - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.h deleted file mode 100644 index 3f8db9d250..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSession.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KMSSESSION_H -#define _KMSSESSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdio.h> -#include <pthread.h> -#include <sys/avl.h> -#include <security/pkcs11t.h> - -#define K_SOLARIS_PLATFORM -#include "KMSAgent.h" - -#define KMSTOKEN_SESSION_MAGIC 0xECF00004 - -#define CRYPTO_OPERATION_ACTIVE 0x01 -#define CRYPTO_OPERATION_UPDATE 0x02 - -typedef struct { - CK_MECHANISM mech; - void *context; - uint32_t flags; -} kms_active_op_t; - -typedef struct { - char *label; - avl_node_t nodep; -} objlabel_t; - -#define KMSOFFSETOF(s, m) ((size_t)(&(((s *)0)->m))) - -/* - * Data stored in the KMS profile config file. - */ -typedef struct { - char name[BUFSIZ]; - char agentId[BUFSIZ]; - char agentAddr[BUFSIZ]; - int transTimeout; - int failoverLimit; - int discoveryFreq; - int securityMode; -} kms_cfg_info_t; - -typedef struct session { - CK_ULONG magic_marker; /* magic # be validated for integrity */ - pthread_mutex_t session_mutex; /* session's mutex lock */ - pthread_mutex_t ses_free_mutex; /* mutex used during closing session */ - pthread_cond_t ses_free_cond; /* cond variable for signal and wait */ - uint32_t ses_refcnt; /* session reference count */ - uint32_t ses_close_sync; /* session closing flags */ - boolean_t ses_RO; /* RO or RW session flag */ - CK_SLOT_ID ses_slotid; /* slotID saved from C_OpenSession() */ - - /* Place holder for parameters passed in the C_OpenSession */ - CK_FLAGS flags; - CK_NOTIFY Notify; - CK_VOID_PTR pApplication; - - /* Pointers to form the global session list */ - struct session *next; /* points to next session on the list */ - struct session *prev; /* points to prev session on the list */ - - struct object *object_list; /* points to list of objects */ - - kms_active_op_t find_objects; - kms_active_op_t encrypt; - kms_active_op_t decrypt; - - kms_cfg_info_t configInfo; - - avl_tree_t objlabel_tree; - KMSClientProfile kmsProfile; -} kms_session_t; - -/* - * The following structure is used to link the to-be-freed sessions - * into a linked list. The sessions on this linked list have - * not yet been freed via free() after C_CloseSession() call; instead - * they are added to this list. The actual free will take place when - * the number of sessions queued reaches MAX_SES_TO_BE_FREED, at which - * time the first session in the list will be freed. - */ -#define MAX_SES_TO_BE_FREED 300 - -typedef struct ses_to_be_freed_list { - kms_session_t *first; /* points to the first session in the list */ - kms_session_t *last; /* points to the last session in the list */ - uint32_t count; /* current total sessions in the list */ - pthread_mutex_t ses_to_be_free_mutex; -} ses_to_be_freed_list_t; - -extern ses_to_be_freed_list_t ses_delay_freed; -extern CK_ULONG kms_session_cnt; -extern CK_ULONG kms_session_rw_cnt; - -/* - * Flag definitions for ses_close_sync - */ -#define SESSION_IS_CLOSING 1 /* Session is in a closing state */ -#define SESSION_REFCNT_WAITING 2 /* Waiting for session reference */ - /* count to become zero */ -/* - * This macro is used to decrement the session reference count by one. - * - * The caller of this macro uses the argument lock_held to indicate that - * whether the caller holds the lock on the session or not. - * - * REFRELE macro does the following: - * 1) Get the session lock if the caller does not hold it. - * 2) Decrement the session reference count by one. - * 3) If the session reference count becomes zero after being decremented, - * and there is a closing session thread in the wait state, then - * call pthread_cond_signal() to wake up that thread who is blocked - * in the session deletion routine due to non-zero reference ount. - * 4) Always release the session lock. - */ -#define REFRELE(s, ses_lock_held) { \ - if (!ses_lock_held) \ - (void) pthread_mutex_lock(&s->session_mutex); \ - if ((--((s)->ses_refcnt) == 0) && \ - (s->ses_close_sync & SESSION_REFCNT_WAITING)) { \ - (void) pthread_mutex_unlock(&s->session_mutex); \ - (void) pthread_cond_signal(&s->ses_free_cond); \ - } else { \ - (void) pthread_mutex_unlock(&s->session_mutex); \ - } \ -} - - -/* - * Function Prototypes. - */ -CK_RV -handle2session(CK_SESSION_HANDLE hSession, kms_session_t **session_p); - -void -kms_delete_all_sessions(boolean_t wrapper_only); - -void -kms_delete_all_objects_in_session(kms_session_t *sp, - boolean_t wrapper_only); - -CK_RV -kms_add_session(CK_SLOT_ID slotID, CK_FLAGS flags, - CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_ULONG *phSession); - -void -kms_delete_session(kms_session_t *sp, - boolean_t lock_held, boolean_t wrapper_only); - -void -kms_session_delay_free(kms_session_t *sp); - -void kms_acquire_all_slots_mutexes(); -void kms_release_all_slots_mutexes(); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMSSESSION_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSessionUtil.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSessionUtil.c deleted file mode 100644 index f46cda9b7c..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSessionUtil.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <pthread.h> -#include <syslog.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsSession.h" -#include "kmsSlot.h" -#include "kmsKeystoreUtil.h" - -static pthread_mutex_t delete_sessions_mutex = PTHREAD_MUTEX_INITIALIZER; -CK_ULONG kms_session_cnt = 0; -CK_ULONG kms_session_rw_cnt = 0; - -/* - * Delete all the sessions. First, obtain the slot lock. - * Then start to delete one session at a time. The boolean wrapper_only - * argument indicates that whether the caller only wants to clean up the - * session wrappers and the object wrappers in the library. - * - When this function is called by C_CloseAllSessions or indirectly by - * C_Finalize, wrapper_only is FALSE. - * - When this function is called by cleanup_child, wrapper_only is TRUE. - */ -void -kms_delete_all_sessions(boolean_t wrapper_only) -{ - kms_session_t *session_p; - kms_slot_t *pslot; - - (void) pthread_mutex_lock(&delete_sessions_mutex); - - pslot = get_slotinfo(); - - /* - * Delete all the sessions in the slot's session list. - * The routine kms_delete_session() updates the linked list. - * So, we do not need to maintain the list here. - */ - for (;;) { - (void) pthread_mutex_lock(&pslot->sl_mutex); - if (pslot->sl_sess_list == NULL) - break; - - session_p = pslot->sl_sess_list; - /* - * Set SESSION_IS_CLOSING flag so any access to this - * session will be rejected. - */ - (void) pthread_mutex_lock(&session_p->session_mutex); - if (session_p->ses_close_sync & SESSION_IS_CLOSING) { - (void) pthread_mutex_unlock(&session_p->session_mutex); - continue; - } - session_p->ses_close_sync |= SESSION_IS_CLOSING; - (void) pthread_mutex_unlock(&session_p->session_mutex); - - (void) pthread_mutex_unlock(&pslot->sl_mutex); - kms_delete_session(session_p, B_FALSE, wrapper_only); - } - (void) pthread_mutex_unlock(&pslot->sl_mutex); - (void) pthread_mutex_unlock(&delete_sessions_mutex); -} - -static int -labelcmp(const void *a, const void *b) -{ - objlabel_t *obja = (objlabel_t *)a; - objlabel_t *objb = (objlabel_t *)b; - int n; - - if (obja == NULL || obja->label == NULL) - return (-1); - if (objb == NULL || objb->label == NULL) - return (1); - - n = strcmp((char *)obja->label, (char *)objb->label); - if (n == 0) - return (0); - else if (n < 0) - return (-1); - return (1); -} - -/* - * Create a new session struct, and add it to the slot's session list. - * - * This function is called by C_OpenSession(), which hold the slot lock. - */ -CK_RV -kms_add_session(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, - CK_NOTIFY notify, CK_ULONG *sessionhandle_p) -{ - kms_session_t *new_sp = NULL; - kms_slot_t *pslot; - CK_RV rv; - - /* Allocate a new session struct */ - new_sp = calloc(1, sizeof (kms_session_t)); - if (new_sp == NULL) { - return (CKR_HOST_MEMORY); - } - - new_sp->magic_marker = KMSTOKEN_SESSION_MAGIC; - new_sp->pApplication = pApplication; - new_sp->Notify = notify; - new_sp->flags = flags; - new_sp->ses_RO = (flags & CKF_RW_SESSION) ? B_FALSE : B_TRUE; - new_sp->ses_slotid = slotID; - new_sp->object_list = NULL; - new_sp->ses_refcnt = 0; - new_sp->ses_close_sync = 0; - - avl_create(&new_sp->objlabel_tree, labelcmp, sizeof (objlabel_t), - KMSOFFSETOF(objlabel_t, nodep)); - - rv = kms_reload_labels(new_sp); - if (rv != CKR_OK) { - free(new_sp); - return (rv); - } - - /* Initialize the lock for the newly created session */ - if (pthread_mutex_init(&new_sp->session_mutex, NULL) != 0) { - free(new_sp); - return (CKR_CANT_LOCK); - } - - pslot = get_slotinfo(); - - (void) pthread_mutex_init(&new_sp->ses_free_mutex, NULL); - (void) pthread_cond_init(&new_sp->ses_free_cond, NULL); - - /* Insert the new session in front of the slot's session list */ - if (pslot->sl_sess_list == NULL) { - pslot->sl_sess_list = new_sp; - new_sp->prev = NULL; - new_sp->next = NULL; - } else { - pslot->sl_sess_list->prev = new_sp; - new_sp->next = pslot->sl_sess_list; - new_sp->prev = NULL; - pslot->sl_sess_list = new_sp; - } - - /* Type casting the address of a session struct to a session handle */ - *sessionhandle_p = (CK_ULONG)new_sp; - return (CKR_OK); -} - -/* - * Delete a session: - * - Remove the session from the slot's session list. - * - Release all the objects created by the session. - * - * The boolean argument slot_lock_held is used to indicate that whether - * the caller of this function holds the slot lock or not. - * - When called by kms_delete_all_sessions(), which is called by - * C_Finalize() or C_CloseAllSessions() -- slot_lock_held = TRUE. - * - When called by C_CloseSession() -- slot_lock_held = FALSE. - */ -void -kms_delete_session(kms_session_t *session_p, - boolean_t slot_lock_held, boolean_t wrapper_only) -{ - kms_slot_t *pslot; - kms_object_t *objp; - kms_object_t *objp1; - - /* - * Check to see if the caller holds the lock on the global - * session list. If not, we need to acquire that lock in - * order to proceed. - */ - pslot = get_slotinfo(); - if (!slot_lock_held) { - /* Acquire the slot lock */ - (void) pthread_mutex_lock(&pslot->sl_mutex); - } - - /* - * Remove the session from the slot's session list first. - */ - if (pslot->sl_sess_list == session_p) { - /* Session is the first one in the list */ - if (session_p->next) { - pslot->sl_sess_list = session_p->next; - session_p->next->prev = NULL; - } else { - /* Session is the only one in the list */ - pslot->sl_sess_list = NULL; - } - } else { - /* Session is not the first one in the list */ - if (session_p->next) { - /* Session is in the middle of the list */ - session_p->prev->next = session_p->next; - session_p->next->prev = session_p->prev; - } else { - /* Session is the last one in the list */ - session_p->prev->next = NULL; - } - } - - if (!slot_lock_held) { - /* - * If the slot lock is obtained by - * this function, then release that lock after - * removing the session from session linked list. - * We want the releasing of the objects of the - * session, and freeing of the session itself to - * be done without holding the slot's session list - * lock. - */ - (void) pthread_mutex_unlock(&pslot->sl_mutex); - } - - /* Acquire the individual session lock */ - (void) pthread_mutex_lock(&session_p->session_mutex); - - /* - * Make sure another thread hasn't freed the session. - */ - if (session_p->magic_marker != KMSTOKEN_SESSION_MAGIC) { - (void) pthread_mutex_unlock(&session_p->session_mutex); - return; - } - - /* - * The deletion of a session must be blocked when the session reference - * count is not zero. This means that if the thread that is attempting - * to close the session must wait until the prior operations on this - * session are finished. - * - * Unless we are being forced to shut everything down, this only - * happens if the library's _fini() is running not if someone - * explicitly called C_Finalize(). - */ - (void) pthread_mutex_lock(&session_p->ses_free_mutex); - - if (wrapper_only) { - session_p->ses_refcnt = 0; - } - - while (session_p->ses_refcnt != 0) { - /* - * We set the SESSION_REFCNT_WAITING flag before we put - * this closing thread in a wait state, so other non-closing - * operation thread will wake it up only when - * the session reference count becomes zero and this flag - * is set. - */ - session_p->ses_close_sync |= SESSION_REFCNT_WAITING; - (void) pthread_mutex_unlock(&session_p->session_mutex); - (void) pthread_cond_wait(&session_p->ses_free_cond, - &session_p->ses_free_mutex); - (void) pthread_mutex_lock(&session_p->session_mutex); - } - - session_p->ses_close_sync &= ~SESSION_REFCNT_WAITING; - - /* Mark session as no longer valid. */ - session_p->magic_marker = 0; - - (void) pthread_mutex_unlock(&session_p->ses_free_mutex); - (void) pthread_mutex_destroy(&session_p->ses_free_mutex); - (void) pthread_cond_destroy(&session_p->ses_free_cond); - - /* - * Remove all the objects created in this session, waiting - * until each object's refcnt is 0. - */ - kms_delete_all_objects_in_session(session_p, wrapper_only); - - /* Close the KMS agent profile. */ - KMS_UnloadProfile(&session_p->kmsProfile); - - /* Reset SESSION_IS_CLOSING flag. */ - session_p->ses_close_sync &= ~SESSION_IS_CLOSING; - - kms_clear_label_list(&session_p->objlabel_tree); - avl_destroy(&session_p->objlabel_tree); - - (void) pthread_mutex_unlock(&session_p->session_mutex); - /* Destroy the individual session lock */ - (void) pthread_mutex_destroy(&session_p->session_mutex); - - kms_session_delay_free(session_p); - - /* - * If there is no more session remained in this slot, reset the slot's - * session state to CKU_PUBLIC. Also, clean up all the token object - * wrappers in the library for this slot. - */ - /* Acquire the slot lock if lock is not held */ - if (!slot_lock_held) { - (void) pthread_mutex_lock(&pslot->sl_mutex); - } - - if (pslot->sl_sess_list == NULL) { - /* Reset the session auth state. */ - pslot->sl_state = CKU_PUBLIC; - - /* Clean up token object wrappers. */ - objp = pslot->sl_tobj_list; - while (objp) { - objp1 = objp->next; - (void) pthread_mutex_destroy(&objp->object_mutex); - (void) kms_cleanup_object(objp); - free(objp); - objp = objp1; - } - pslot->sl_tobj_list = NULL; - } - - /* Release the slot lock if lock is not held */ - if (!slot_lock_held) { - (void) pthread_mutex_unlock(&pslot->sl_mutex); - } -} - -/* - * This function is used to type cast a session handle to a pointer to - * the session struct. Also, it does the following things: - * 1) Check to see if the session struct is tagged with a session - * magic number. This is to detect when an application passes - * a bogus session pointer. - * 2) Acquire the locks on the designated session. - * 3) Check to see if the session is in the closing state that another - * thread is performing. - * 4) Increment the session reference count by one. This is to prevent - * this session from being closed by other thread. - * 5) Release the locks on the designated session. - */ -CK_RV -handle2session(CK_SESSION_HANDLE hSession, kms_session_t **session_p) -{ - kms_session_t *sp = (kms_session_t *)(hSession); - CK_RV rv; - - if ((sp == NULL) || - (sp->magic_marker != KMSTOKEN_SESSION_MAGIC)) { - return (CKR_SESSION_HANDLE_INVALID); - } else { - (void) pthread_mutex_lock(&sp->session_mutex); - if (sp->ses_close_sync & SESSION_IS_CLOSING) { - rv = CKR_SESSION_CLOSED; - } else { - /* Increment session ref count. */ - sp->ses_refcnt++; - rv = CKR_OK; - } - (void) pthread_mutex_unlock(&sp->session_mutex); - } - - if (rv == CKR_OK) - *session_p = sp; - - return (rv); -} - -/* - * This function adds the to-be-freed session to a linked list. - * When the number of sessions queued in the linked list reaches the - * maximum threshold MAX_SES_TO_BE_FREED, it will free the first - * session (FIFO) in the list. - */ -void -kms_session_delay_free(kms_session_t *sp) -{ - kms_session_t *tmp; - - (void) pthread_mutex_lock(&ses_delay_freed.ses_to_be_free_mutex); - - /* Add the newly deleted session at the end of the list */ - sp->next = NULL; - if (ses_delay_freed.first == NULL) { - ses_delay_freed.last = sp; - ses_delay_freed.first = sp; - } else { - ses_delay_freed.last->next = sp; - ses_delay_freed.last = sp; - } - - if (++ses_delay_freed.count >= MAX_SES_TO_BE_FREED) { - /* - * Free the first session in the list only if - * the total count reaches maximum threshold. - */ - ses_delay_freed.count--; - tmp = ses_delay_freed.first->next; - free(ses_delay_freed.first); - ses_delay_freed.first = tmp; - } - (void) pthread_mutex_unlock(&ses_delay_freed.ses_to_be_free_mutex); -} - -/* - * Acquire all slots' mutexes and all their sessions' mutexes. - * Order: - * 1. delete_sessions_mutex - * for each slot: - * 2. pslot->sl_mutex - * for each session: - * 3. session_p->session_mutex - * 4. session_p->ses_free_mutex - */ -void -kms_acquire_all_slots_mutexes() -{ - kms_slot_t *pslot; - kms_session_t *session_p; - - (void) pthread_mutex_lock(&delete_sessions_mutex); - - pslot = get_slotinfo(); - (void) pthread_mutex_lock(&pslot->sl_mutex); - - /* Iterate through sessions acquiring all mutexes */ - session_p = pslot->sl_sess_list; - while (session_p) { - struct object *objp; - - (void) pthread_mutex_lock(&session_p->session_mutex); - (void) pthread_mutex_lock(&session_p->ses_free_mutex); - - objp = session_p->object_list; - while (objp) { - (void) pthread_mutex_lock(&objp->object_mutex); - objp = objp->next; - } - - session_p = session_p->next; - } -} - -/* Release in opposite order to kms_acquire_all_slots_mutexes(). */ -void -kms_release_all_slots_mutexes() -{ - kms_slot_t *pslot; - kms_session_t *session_p; - - pslot = get_slotinfo(); - - /* Iterate through sessions releasing all mutexes */ - session_p = pslot->sl_sess_list; - while (session_p) { - struct object *objp; - - objp = session_p->object_list; - while (objp) { - (void) pthread_mutex_unlock(&objp->object_mutex); - objp = objp->next; - } - - (void) pthread_mutex_unlock(&session_p->ses_free_mutex); - (void) pthread_mutex_unlock(&session_p->session_mutex); - session_p = session_p->next; - } - - /* - * acquired in "acquire_all_slots_mutexes" which only - * happens just prior to a fork. - */ - (void) pthread_mutex_unlock(&pslot->sl_mutex); - (void) pthread_mutex_unlock(&delete_sessions_mutex); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSign.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSign.c deleted file mode 100644 index 9e2fe28784..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSign.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <security/cryptoki.h> -#include "kmsGlobal.h" - -/*ARGSUSED*/ -CK_RV -C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - - -/*ARGSUSED*/ -CK_RV -C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); - -} - -/*ARGSUSED*/ -CK_RV -C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlot.h b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlot.h deleted file mode 100644 index f1bb38f3d1..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlot.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef _KMS_SLOT_H -#define _KMS_SLOT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "kmsSession.h" - -#define CKU_PUBLIC 2 /* default session auth. state */ - -typedef struct kms_slot { - CK_SLOT_ID sl_provider_id; /* kernel provider ID */ - kms_session_t *sl_sess_list; /* all open sessions */ - CK_USER_TYPE sl_state; /* session's auth. state */ - struct object *sl_tobj_list; /* token object list */ - pthread_mutex_t sl_mutex; - - /* - * The valid values are defined above. - */ - uint32_t sl_flags; - int total_threshold_count; -} kms_slot_t; - -#define KMS_TOKEN_SLOTID 1 -#define KMS_SLOTS 1 - -/* - * Function Prototypes. - */ -CK_RV kms_slottable_init(); -void cleanup_slottable(); -kms_slot_t *get_slotinfo(); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMS_SLOT_H */ diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlotToken.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlotToken.c deleted file mode 100644 index 0ee47521f0..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlotToken.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - */ - - -#include <stdlib.h> -#include <strings.h> -#include <security/cryptoki.h> -#include <cryptoutil.h> -#include <errno.h> -#include <aes_impl.h> - -#include "kmsGlobal.h" -#include "kmsSlot.h" -#include "kmsKeystoreUtil.h" - -/* - * Just basic AES mechanisms (for now...) - */ -static CK_MECHANISM_TYPE kms_mechanisms[] = { - CKM_AES_KEY_GEN, - CKM_AES_CBC, - CKM_AES_CBC_PAD -}; - -/* - * KMS only supports 256 bit keys, so the range below is MAX-MAX - * instead of MIN-MAX. - */ -static CK_MECHANISM_INFO kms_mechanism_info[] = { - {AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_GENERATE}, - {AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_ENCRYPT|CKF_DECRYPT| - CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC */ - {AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_ENCRYPT|CKF_DECRYPT| - CKF_WRAP|CKF_UNWRAP} /* CKM_AES_CBC_PAD */ -}; - -/* ARGSUSED */ -CK_RV -C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, - CK_ULONG_PTR pulCount) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (pulCount == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - /* - * If KMS is not available or initialized, return 0 slots - * but CKR_OK status. - */ - if (!kms_is_initialized()) { - *pulCount = 0; - return (CKR_OK); - } - - if (pSlotList == NULL) { - *pulCount = KMS_SLOTS; - return (CKR_OK); - } - - if (*pulCount < KMS_SLOTS) { - *pulCount = KMS_SLOTS; - return (CKR_BUFFER_TOO_SMALL); - } - - *pulCount = 1; - pSlotList[0] = KMS_TOKEN_SLOTID; - - return (CKR_OK); -} - -CK_RV -C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (slotID != KMS_TOKEN_SLOTID || - !kms_is_initialized()) { - return (CKR_SLOT_ID_INVALID); - } - - if (pInfo == NULL) - return (CKR_ARGUMENTS_BAD); - - /* Provide information about the slot in the provided buffer */ - (void) strncpy((char *)pInfo->slotDescription, SLOT_DESCRIPTION, - 64); - (void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID, 32); - pInfo->flags = CKF_TOKEN_PRESENT; - pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR; - pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR; - pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR; - pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR; - - return (CKR_OK); -} - -CK_RV -C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) -{ - kms_cfg_info_t kmscfg; - KMSAGENT_PROFILE_FLAGS kmsflags = 0; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (slotID != KMS_TOKEN_SLOTID || - !kms_is_initialized()) - return (CKR_SLOT_ID_INVALID); - - if (pInfo == NULL) - return (CKR_ARGUMENTS_BAD); - - /* Provide information about a token in the provided buffer */ - (void) strncpy((char *)pInfo->label, KMS_TOKEN_LABEL, 32); - (void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID, 32); - (void) strncpy((char *)pInfo->model, KMS_TOKEN_MODEL, 16); - (void) strncpy((char *)pInfo->serialNumber, KMS_TOKEN_SERIAL, 16); - - pInfo->flags = KMS_TOKEN_FLAGS; - pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; - pInfo->ulSessionCount = kms_session_cnt; - pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE; - pInfo->ulRwSessionCount = kms_session_rw_cnt; - pInfo->ulMaxPinLen = MAX_PIN_LEN; - pInfo->ulMinPinLen = MIN_PIN_LEN; - pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR; - pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR; - pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR; - pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR; - (void) memset(pInfo->utcTime, ' ', 16); - - if (KMS_GetConfigInfo(&kmscfg) == CKR_OK && - KMSAgent_GetProfileStatus(kmscfg.name, &kmsflags) == - KMS_AGENT_STATUS_OK) { - - if ((kmsflags & KMSAGENT_PROFILE_EXISTS_FLAG) && - (kmsflags & KMSAGENT_CLIENTKEY_EXISTS_FLAG)) - pInfo->flags |= CKF_TOKEN_INITIALIZED; - else - pInfo->flags &= ~CKF_TOKEN_INITIALIZED; - } - return (CKR_OK); -} - -/*ARGSUSED*/ -CK_RV -C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - - -CK_RV -C_GetMechanismList(CK_SLOT_ID slotID, - CK_MECHANISM_TYPE_PTR pMechanismList, - CK_ULONG_PTR pulCount) -{ - int i; - ulong_t mechnum; - - /* - * Just check to see if the library has been - * properly initialized. - */ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * This is different from above check, this verifies that - * the KMS token is actually configured. - */ - if (slotID != KMS_TOKEN_SLOTID || - !kms_is_initialized()) - return (CKR_SLOT_ID_INVALID); - - mechnum = sizeof (kms_mechanisms) / sizeof (CK_MECHANISM_TYPE); - if (pMechanismList == NULL) { - *pulCount = mechnum; - return (CKR_OK); - } - if (*pulCount < mechnum) { - *pulCount = mechnum; - return (CKR_BUFFER_TOO_SMALL); - } - for (i = 0; i < mechnum; i++) - pMechanismList[i] = kms_mechanisms[i]; - - *pulCount = mechnum; - - return (CKR_OK); -} - -CK_RV -C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) -{ - CK_ULONG mechnum, i; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (slotID != KMS_TOKEN_SLOTID || - !kms_is_initialized()) - return (CKR_SLOT_ID_INVALID); - - if (pInfo == NULL) { - return (CKR_ARGUMENTS_BAD); - } - - mechnum = sizeof (kms_mechanisms) / sizeof (CK_MECHANISM_TYPE); - for (i = 0; i < mechnum; i++) { - if (kms_mechanisms[i] == type) - break; - } - - if (i == mechnum) - /* unsupported mechanism */ - return (CKR_MECHANISM_INVALID); - - pInfo->ulMinKeySize = kms_mechanism_info[i].ulMinKeySize; - pInfo->ulMaxKeySize = kms_mechanism_info[i].ulMaxKeySize; - pInfo->flags = kms_mechanism_info[i].flags; - - return (CKR_OK); -} - -/*ARGSUSED*/ -CK_RV -C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, - CK_UTF8CHAR_PTR pLabel) -{ - CK_RV rv = CKR_FUNCTION_FAILED; - kms_cfg_info_t kmscfg; - KMSAGENT_PROFILE_FLAGS kmsflags; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - if (slotID != KMS_TOKEN_SLOTID || - !kms_is_initialized()) - return (CKR_SLOT_ID_INVALID); - - if (KMS_GetConfigInfo(&kmscfg) != CKR_OK || - KMSAgent_GetProfileStatus(kmscfg.name, &kmsflags) != - KMS_AGENT_STATUS_OK) - return (CKR_FUNCTION_FAILED); - - if (!(kmsflags & KMSAGENT_PROFILE_EXISTS_FLAG) || - !(kmsflags & KMSAGENT_CLIENTKEY_EXISTS_FLAG)) { - KMSClientProfile kmsProfile; - /* - * Attempt to enroll and load a KMS profile. - * This will force the KMSAgent library to fetch - * the profile, the CA certificate, and the - * client private key and store them locally so that - * the KMS agent API can be used later. - */ - rv = KMS_LoadProfile( - &kmsProfile, - &kmscfg, - (const char *)pPin, - (size_t)ulPinLen); - - if (rv == CKR_OK) - KMS_UnloadProfile(&kmsProfile); - } - return (rv); -} - -/*ARGSUSED*/ -CK_RV -C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * Could be supported once the agent library supports - * storing the client certificate in a PKCS#12 file. - */ - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -CK_RV -C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, - CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen) -{ - CK_RV rv = CKR_OK; - kms_session_t *session_p; - boolean_t ses_lock_held = B_FALSE; - - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - /* - * Obtain the session pointer. Also, increment the session - * reference count. - */ - rv = handle2session(hSession, &session_p); - if (rv != CKR_OK) - return (rv); - - /* Make sure it is a RW session. */ - if (session_p->ses_RO) { - rv = CKR_SESSION_READ_ONLY; - REFRELE(session_p, ses_lock_held); - return (rv); - } - - /* - * If the token is not yet initialized, we cannot set the pin. - */ - if (!kms_is_initialized()) { - REFRELE(session_p, ses_lock_held); - return (CKR_FUNCTION_FAILED); - } - - if (pOldPin == NULL || ulOldLen == 0 || - pNewPin == NULL || ulNewLen == 0) { - REFRELE(session_p, ses_lock_held); - return (CKR_ARGUMENTS_BAD); - } - - if (!kms_is_pin_set()) { - /* - * We don't yet support this mode since - * the KMS private key file will automatically - * be generated using the KMS Agent passphrase - * which is initialized out-of-band. - */ - rv = CKR_FUNCTION_NOT_SUPPORTED; - - } else { - /* - * Login to KMS by attempting to load the profile using - * the given password. - */ - rv = KMS_LoadProfile(&session_p->kmsProfile, - &session_p->configInfo, - (const char *)pOldPin, - (size_t)ulOldLen); - if (rv == CKR_USER_ANOTHER_ALREADY_LOGGED_IN) - rv = CKR_OK; - - if (rv == CKR_OK) - rv = KMS_ChangeLocalPWD(session_p, - (const char *)pOldPin, - (const char *)pNewPin); - } - - REFRELE(session_p, ses_lock_held); - return (rv); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlottable.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlottable.c deleted file mode 100644 index c34954dc51..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlottable.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <errno.h> -#include <security/cryptoki.h> -#include "kmsGlobal.h" -#include "kmsSlot.h" - -static kms_slot_t *slotinfo = NULL; - -/* - * Initialize the slotinfo record. - * - * This function is called from C_Initialize() only. Since C_Initialize() - * holds the global mutex lock, there is no need to acquire another lock - * in this routine to protect the slot table. - */ -CK_RV -kms_slottable_init() -{ - CK_RV rv = CKR_OK; - - /* Allocate space for the slot table */ - slotinfo = calloc(KMS_SLOTS, sizeof (kms_slot_t)); - if (slotinfo == NULL) - return (CKR_HOST_MEMORY); - - slotinfo->sl_sess_list = NULL; - slotinfo->sl_tobj_list = NULL; - slotinfo->sl_state = CKU_PUBLIC; - - /* Initialize this slot's mutex */ - if (pthread_mutex_init(&slotinfo->sl_mutex, NULL) != 0) { - (void) free(slotinfo); - slotinfo = NULL; - return (CKR_FUNCTION_FAILED); - } - - return (rv); -} - -void -cleanup_slottable() -{ - if (slotinfo != NULL) { - (void) pthread_mutex_destroy(&slotinfo->sl_mutex); - (void) free(slotinfo); - slotinfo = NULL; - } -} - -kms_slot_t * -get_slotinfo() -{ - return (slotinfo); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsVerify.c b/usr/src/lib/pkcs11/pkcs11_kms/common/kmsVerify.c deleted file mode 100644 index 64db49c9a3..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/kmsVerify.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#include <security/cryptoki.h> -#include "kmsGlobal.h" - -/*ARGSUSED*/ -CK_RV -C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, - CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} - -/*ARGSUSED*/ -CK_RV -C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, - CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) -{ - if (!kms_initialized) - return (CKR_CRYPTOKI_NOT_INITIALIZED); - - return (CKR_FUNCTION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/pkcs11/pkcs11_kms/common/mapfile-vers b/usr/src/lib/pkcs11/pkcs11_kms/common/mapfile-vers deleted file mode 100644 index a66e3742f7..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/common/mapfile-vers +++ /dev/null @@ -1,98 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# - -$mapfile_version 2 - -SYMBOL_VERSION SUNW_1.1 { - global: - C_CancelFunction; - C_CloseAllSessions; - C_CloseSession; - C_CopyObject; - C_CreateObject; - C_Decrypt; - C_DecryptDigestUpdate; - C_DecryptFinal; - C_DecryptInit; - C_DecryptUpdate; - C_DecryptVerifyUpdate; - C_DeriveKey; - C_DestroyObject; - C_Digest; - C_DigestEncryptUpdate; - C_DigestFinal; - C_DigestInit; - C_DigestKey; - C_DigestUpdate; - C_Encrypt; - C_EncryptFinal; - C_EncryptInit; - C_EncryptUpdate; - C_Finalize; - C_FindObjects; - C_FindObjectsFinal; - C_FindObjectsInit; - C_GenerateKey; - C_GenerateKeyPair; - C_GenerateRandom; - C_GetAttributeValue; - C_GetFunctionList; - C_GetFunctionStatus; - C_GetInfo; - C_GetMechanismInfo; - C_GetMechanismList; - C_GetObjectSize; - C_GetOperationState; - C_GetSessionInfo; - C_GetSlotInfo; - C_GetSlotList; - C_GetTokenInfo; - C_Initialize; - C_InitPIN; - C_InitToken; - C_Login; - C_Logout; - C_OpenSession; - C_SeedRandom; - C_SetAttributeValue; - C_SetOperationState; - C_SetPIN; - C_Sign; - C_SignEncryptUpdate; - C_SignFinal; - C_SignInit; - C_SignRecover; - C_SignRecoverInit; - C_SignUpdate; - C_UnwrapKey; - C_Verify; - C_VerifyFinal; - C_VerifyInit; - C_VerifyRecover; - C_VerifyRecoverInit; - C_VerifyUpdate; - C_WaitForSlotEvent; - C_WrapKey; - local: - *; -}; diff --git a/usr/src/lib/pkcs11/pkcs11_kms/i386/Makefile b/usr/src/lib/pkcs11/pkcs11_kms/i386/Makefile deleted file mode 100644 index 5b0478c540..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/i386/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# - - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/pkcs11/pkcs11_kms/sparc/Makefile b/usr/src/lib/pkcs11/pkcs11_kms/sparc/Makefile deleted file mode 100644 index f51825ef6c..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/sparc/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/pkcs11/pkcs11_kms/sparcv9/Makefile b/usr/src/lib/pkcs11/pkcs11_kms/sparcv9/Makefile deleted file mode 100644 index 99c7ac2351..0000000000 --- a/usr/src/lib/pkcs11/pkcs11_kms/sparcv9/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# - - -include ../Makefile.com -include ../../../Makefile.lib.64 - -LINTCHECKFLAGS += -erroff=E_INCONS_ARG_DECL2 \ - -erroff=E_INCONS_ARG_USED2 \ - -erroff=E_INCONS_VAL_TYPE_DECL2 \ - -erroff=E_INCONS_VAL_TYPE_USED2 \ - -erroff=E_FUNC_DECL_VAR_ARG2 - -install: all $(ROOTLIBS64) $(ROOTLINKS64) |