2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <crypt.h>
2N/A#include <cryptoutil.h>
2N/A#include <pwd.h>
2N/A#include <pthread.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <strings.h>
2N/A#include <sys/types.h>
2N/A#include <sys/sysmacros.h>
2N/A#include <security/cryptoki.h>
2N/A#include "softGlobal.h"
2N/A#include "softCrypt.h"
2N/A#include "softSession.h"
2N/A#include "softObject.h"
2N/A#include "softKeys.h"
2N/A#include "softKeystore.h"
2N/A#include "softKeystoreUtil.h"
2N/A#include "softMAC.h"
2N/A#include "softOps.h"
2N/A
2N/A/*
2N/A * The token session is just a pseudo session (a place holder)
2N/A * to hold some information during encryption/decryption and
2N/A * sign/verify operations when writing/reading the keystore
2N/A * token object.
2N/A */
2N/Asoft_session_t token_session;
2N/A
2N/A/*
2N/A * soft_gen_hashed_pin()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * pPin: pointer to caller provided Pin
2N/A * result: output argument which contains the address of the
2N/A * pointer to the hashed pin
2N/A * salt: input argument (if non-NULL), or
2N/A * output argument (if NULL):
2N/A * address of pointer to the "salt" of the hashed pin
2N/A *
2N/A * Description:
2N/A *
2N/A * Generate a hashed pin using system provided crypt(3C) function.
2N/A *
2N/A * Returns:
2N/A *
2N/A * 0: no error
2N/A * -1: some error occurred while generating the hashed pin
2N/A *
2N/A */
2N/Aint
2N/Asoft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt)
2N/A{
2N/A
2N/A uid_t uid;
2N/A struct passwd pwd, *pw;
2N/A char pwdbuf[PWD_BUFFER_SIZE];
2N/A boolean_t new_salt = B_FALSE;
2N/A
2N/A /*
2N/A * We need to get the passwd entry of the application, which is required
2N/A * by the crypt_gensalt() below.
2N/A */
2N/A uid = geteuid();
2N/A if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
2N/A return (-1);
2N/A }
2N/A
2N/A if (*salt == NULL) {
2N/A new_salt = B_TRUE;
2N/A /*
2N/A * crypt_gensalt() will allocate memory to store the new salt.
2N/A * on return. Pass "$5" here to default to crypt_sha256 since
2N/A * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
2N/A * assume the system default is that strong.
2N/A */
2N/A if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
2N/A return (-1);
2N/A }
2N/A }
2N/A
2N/A if ((*result = crypt((char *)pPin, *salt)) == NULL) {
2N/A if (new_salt)
2N/A free(*salt);
2N/A return (-1);
2N/A }
2N/A
2N/A return (0);
2N/A}
2N/A
2N/A/*
2N/A * Authenticate user's PIN for C_Login.
2N/A */
2N/ACK_RV
2N/Asoft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
2N/A{
2N/A
2N/A char *user_cryptpin = NULL;
2N/A char *ks_cryptpin = NULL;
2N/A char *salt = NULL;
2N/A uchar_t *tmp_pin = NULL;
2N/A boolean_t pin_initialized = B_FALSE;
2N/A CK_RV rv = CKR_OK;
2N/A
2N/A /*
2N/A * Check to see if keystore is initialized.
2N/A */
2N/A rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
2N/A B_FALSE);
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A /*
2N/A * Authenticate user's PIN for C_Login.
2N/A */
2N/A if (pin_initialized) {
2N/A
2N/A if (soft_keystore_get_pin_salt(&salt) < 0) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A goto cleanup;
2N/A }
2N/A
2N/A /*
2N/A * Generate the hashed value based on the user's supplied pin.
2N/A */
2N/A tmp_pin = malloc(ulPinLen + 1);
2N/A if (tmp_pin == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A goto cleanup;
2N/A }
2N/A
2N/A (void) memcpy(tmp_pin, pPin, ulPinLen);
2N/A tmp_pin[ulPinLen] = '\0';
2N/A
2N/A if (soft_gen_hashed_pin(tmp_pin, &user_cryptpin, &salt) < 0) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A goto cleanup;
2N/A }
2N/A
2N/A /*
2N/A * Compare hash value of the user supplied PIN with
2N/A * hash value of the keystore PIN.
2N/A */
2N/A if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
2N/A rv = CKR_PIN_INCORRECT;
2N/A goto cleanup;
2N/A }
2N/A
2N/A /*
2N/A * Provide the user's PIN to low-level keystore so that
2N/A * it can use it to generate encryption key as needed for
2N/A * encryption/decryption of the private objects in
2N/A * keystore.
2N/A */
2N/A if (soft_keystore_authpin(tmp_pin) != 0) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A } else {
2N/A rv = CKR_OK;
2N/A }
2N/A goto cleanup;
2N/A } else {
2N/A /*
2N/A * The PIN is not initialized in the keystore
2N/A * We will let it pass the authentication anyway but set the
2N/A * "userpin_change_needed" flag so that the application
2N/A * will get CKR_PIN_EXPIRED by other C_functions such as
2N/A * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
2N/A */
2N/A soft_slot.userpin_change_needed = 1;
2N/A rv = CKR_OK;
2N/A }
2N/A
2N/Acleanup:
2N/A if (salt)
2N/A free(salt);
2N/A if (tmp_pin) {
2N/A /* Zero out our PIN memory copy. */
2N/A (void) memset(tmp_pin, 0, ulPinLen);
2N/A free(tmp_pin);
2N/A }
2N/A if (ks_cryptpin)
2N/A free(ks_cryptpin);
2N/A
2N/A return (rv);
2N/A}
2N/A
2N/A/*
2N/A * The second level C_SetPIN function.
2N/A */
2N/ACK_RV
2N/Asoft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
2N/A CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
2N/A{
2N/A
2N/A char *user_cryptpin = NULL;
2N/A char *ks_cryptpin = NULL;
2N/A char *salt = NULL;
2N/A boolean_t pin_initialized = B_FALSE;
2N/A uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
2N/A CK_RV rv = CKR_OK;
2N/A
2N/A /*
2N/A * Check to see if keystore is initialized.
2N/A */
2N/A rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
2N/A B_FALSE);
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A /*
2N/A * Authenticate user's PIN for C_SetPIN.
2N/A */
2N/A if (pin_initialized) {
2N/A /*
2N/A * Generate the hashed value based on the user supplied PIN.
2N/A */
2N/A if (soft_keystore_get_pin_salt(&salt) < 0) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A goto cleanup;
2N/A }
2N/A
2N/A tmp_old_pin = malloc(ulOldPinLen + 1);
2N/A if (tmp_old_pin == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A goto cleanup;
2N/A }
2N/A (void) memcpy(tmp_old_pin, pOldPin, ulOldPinLen);
2N/A tmp_old_pin[ulOldPinLen] = '\0';
2N/A
2N/A if (soft_gen_hashed_pin(tmp_old_pin, &user_cryptpin,
2N/A &salt) < 0) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A goto cleanup;
2N/A }
2N/A
2N/A /*
2N/A * Compare hashed value of the user supplied PIN with the
2N/A * hashed value of the keystore PIN.
2N/A */
2N/A if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
2N/A rv = CKR_PIN_INCORRECT;
2N/A goto cleanup;
2N/A }
2N/A } else {
2N/A /*
2N/A * This is the first time to setpin, the oldpin must be
2N/A * "changeme".
2N/A */
2N/A if (strncmp("changeme", (const char *)pOldPin,
2N/A ulOldPinLen) != 0) {
2N/A rv = CKR_PIN_INCORRECT;
2N/A goto cleanup;
2N/A }
2N/A }
2N/A
2N/A tmp_new_pin = malloc(ulNewPinLen + 1);
2N/A if (tmp_new_pin == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A goto cleanup;
2N/A }
2N/A (void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
2N/A tmp_new_pin[ulNewPinLen] = '\0';
2N/A
2N/A /*
2N/A * Set the new pin after the old pin is authenticated.
2N/A */
2N/A if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
2N/A rv = CKR_FUNCTION_FAILED;
2N/A goto cleanup;
2N/A } else {
2N/A (void) pthread_mutex_lock(&soft_giant_mutex);
2N/A soft_slot.userpin_change_needed = 0;
2N/A (void) pthread_mutex_unlock(&soft_giant_mutex);
2N/A rv = CKR_OK;
2N/A }
2N/A
2N/Acleanup:
2N/A if (salt)
2N/A free(salt);
2N/A if (ks_cryptpin)
2N/A free(ks_cryptpin);
2N/A if (tmp_old_pin)
2N/A free(tmp_old_pin);
2N/A if (tmp_new_pin)
2N/A free(tmp_new_pin);
2N/A
2N/A return (rv);
2N/A}
2N/A
2N/A/*
2N/A * soft_keystore_pack_obj()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * obj: pointer to the soft_object_t of the token object to
2N/A * be packed
2N/A * ks_buf: output argument which contains the address of the
2N/A * pointer to the buf of the packed token object
2N/A * soft_keystore_pack_obj() will allocate memory for the buf,
2N/A * it is caller's responsibility to free it.
2N/A * len: output argument which contains the address of the
2N/A * buffer length of the packed token object
2N/A *
2N/A * Description:
2N/A *
2N/A * Pack the in-core token object into the keystore format.
2N/A *
2N/A * Returns:
2N/A *
2N/A * CKR_OK: no error
2N/A * Other: some error occurred while packing the object
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_keystore_pack_obj(soft_object_t *obj, uchar_t **ks_buf, size_t *len)
2N/A{
2N/A ks_obj_hdr_t hdr;
2N/A ks_attr_hdr_t attr_hdr;
2N/A CK_ATTRIBUTE_INFO_PTR extra_attr;
2N/A int num_attrs = 0;
2N/A ulong_t len_attrs = 0;
2N/A size_t ks_len;
2N/A uchar_t *buf, *buf1;
2N/A CK_RV rv;
2N/A int i;
2N/A
2N/A (void) memset(&hdr, 0, sizeof (ks_obj_hdr_t));
2N/A
2N/A /*
2N/A * The first part of the packed format contains
2N/A * the ks_obj_hdr_t struct.
2N/A */
2N/A hdr.class = SWAP64((uint64_t)obj->class);
2N/A hdr.key_type = SWAP64((uint64_t)obj->key_type);
2N/A hdr.cert_type = SWAP64((uint64_t)obj->cert_type);
2N/A hdr.bool_attr_mask = SWAP64(obj->bool_attr_mask);
2N/A hdr.mechanism = SWAP64((uint64_t)obj->mechanism);
2N/A hdr.object_type = obj->object_type;
2N/A
2N/A /*
2N/A * The second part of the packed format contains
2N/A * the attributes from the extra attribute list.
2N/A */
2N/A extra_attr = obj->extra_attrlistp;
2N/A
2N/A while (extra_attr) {
2N/A num_attrs++;
2N/A len_attrs += ROUNDUP(extra_attr->attr.ulValueLen, 8);
2N/A extra_attr = extra_attr->next;
2N/A }
2N/A hdr.num_attrs = SWAP32(num_attrs);
2N/A ks_len = soft_pack_object_size(obj);
2N/A ks_len += sizeof (ks_obj_hdr_t) + len_attrs +
2N/A 2 * num_attrs * sizeof (uint64_t);
2N/A buf = calloc(1, ks_len);
2N/A if (buf == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A (void) memcpy(buf, &hdr, sizeof (ks_obj_hdr_t));
2N/A buf1 = buf + sizeof (ks_obj_hdr_t);
2N/A extra_attr = obj->extra_attrlistp;
2N/A for (i = 0; i < num_attrs; i++) {
2N/A attr_hdr.type = SWAP64((uint64_t)extra_attr->attr.type);
2N/A attr_hdr.ulValueLen =
2N/A SWAP64((uint64_t)extra_attr->attr.ulValueLen);
2N/A (void) memcpy(buf1, &attr_hdr, sizeof (ks_attr_hdr_t));
2N/A buf1 = buf1 + sizeof (ks_attr_hdr_t);
2N/A (void) memcpy(buf1, extra_attr->attr.pValue,
2N/A extra_attr->attr.ulValueLen);
2N/A buf1 = buf1 + ROUNDUP(extra_attr->attr.ulValueLen, 8);
2N/A extra_attr = extra_attr->next;
2N/A }
2N/A
2N/A /*
2N/A * The third part of the packed format contains
2N/A * the key itself.
2N/A */
2N/A rv = soft_pack_object(obj, buf1);
2N/A *len = ks_len;
2N/A *ks_buf = buf;
2N/A
2N/A return (rv);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * soft_keystore_unpack_obj()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * obj: pointer to the soft_object_t to store the unpacked
2N/A * token object
2N/A * ks_obj: input argument which contains the pointer to the
2N/A * ks_obj_t struct of packed token object to be unpacked
2N/A *
2N/A * Description:
2N/A *
2N/A * Unpack the token object in keystore format to in-core soft_object_t.
2N/A *
2N/A * Returns:
2N/A *
2N/A * CKR_OK: no error
2N/A * Other: some error occurred while unpacking the object
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_keystore_unpack_obj(soft_object_t *obj, ks_obj_t *ks_obj)
2N/A{
2N/A
2N/A CK_RV rv;
2N/A ks_obj_hdr_t *hdr;
2N/A ks_attr_hdr_t *attr_hdr;
2N/A CK_ATTRIBUTE template;
2N/A int i;
2N/A uchar_t *buf;
2N/A
2N/A /*
2N/A * Unpack the common area.
2N/A */
2N/A (void) strcpy((char *)obj->ks_handle.name,
2N/A (char *)ks_obj->ks_handle.name);
2N/A obj->ks_handle.public = ks_obj->ks_handle.public;
2N/A /* LINTED: pointer alignment */
2N/A hdr = (ks_obj_hdr_t *)ks_obj->buf;
2N/A obj->version = ks_obj->obj_version;
2N/A obj->class = (CK_OBJECT_CLASS)(SWAP64(hdr->class));
2N/A obj->key_type = (CK_KEY_TYPE)(SWAP64(hdr->key_type));
2N/A obj->cert_type = (CK_CERTIFICATE_TYPE)(SWAP64(hdr->cert_type));
2N/A obj->bool_attr_mask = SWAP64(hdr->bool_attr_mask);
2N/A obj->mechanism = (CK_MECHANISM_TYPE)(SWAP64(hdr->mechanism));
2N/A obj->object_type = hdr->object_type;
2N/A
2N/A /*
2N/A * Initialize other stuffs which were not from keystore.
2N/A */
2N/A (void) pthread_rwlock_init(&obj->object_rwlock, NULL);
2N/A (void) pthread_mutex_init(&obj->object_mutex, NULL);
2N/A obj->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
2N/A obj->session_handle = (CK_SESSION_HANDLE)NULL;
2N/A
2N/A buf = ks_obj->buf + sizeof (ks_obj_hdr_t);
2N/A
2N/A /*
2N/A * Unpack extra attribute list.
2N/A */
2N/A for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
2N/A /* LINTED: pointer alignment */
2N/A attr_hdr = (ks_attr_hdr_t *)buf;
2N/A (void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
2N/A template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
2N/A template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
2N/A buf = buf + sizeof (ks_attr_hdr_t);
2N/A /* Allocate storage for the value of the attribute. */
2N/A if (template.ulValueLen > 0) {
2N/A template.pValue = malloc(template.ulValueLen);
2N/A if (template.pValue == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A (void) memcpy(template.pValue, buf,
2N/A template.ulValueLen);
2N/A }
2N/A
2N/A rv = soft_add_extra_attr(&template, obj);
2N/A if (template.pValue) {
2N/A free(template.pValue);
2N/A }
2N/A
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A
2N/A buf = buf + ROUNDUP(template.ulValueLen, 8);
2N/A }
2N/A
2N/A /*
2N/A * Unpack the key itself.
2N/A */
2N/A rv = soft_unpack_object(obj, buf);
2N/A return (rv);
2N/A
2N/A}
2N/A
2N/A
2N/A/*
2N/A * soft_unpack_obj_attribute()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * buf: contains the packed data (attributes) from keystore
2N/A * key_dest: the key attribute will be unpacked and save in key_dest
2N/A * cert_dest: the certificate attribute will be unpacked an
2N/A * in cert_dest
2N/A * offset: length of the current attribute occupies.
2N/A * The caller should use this returned "offset" to
2N/A * advance the buffer pointer to next attribute.
2N/A * cert: TRUE for certificate (use cert_dest)
2N/A * FALSE for key (use key_dest)
2N/A *
2N/A * Description:
2N/A *
2N/A * Unpack the attribute from keystore format to the big integer format.
2N/A *
2N/A * Returns:
2N/A *
2N/A * CKR_OK: no error
2N/A * Other: some error occurred while unpacking the object attribute
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_unpack_obj_attribute(uchar_t *buf, biginteger_t *key_dest,
2N/A cert_attr_t **cert_dest, ulong_t *offset, boolean_t cert)
2N/A{
2N/A
2N/A CK_RV rv;
2N/A CK_ATTRIBUTE template;
2N/A
2N/A /* LINTED: pointer alignment */
2N/A template.ulValueLen = SWAP64(*(uint64_t *)buf);
2N/A buf = buf + sizeof (uint64_t);
2N/A template.pValue = malloc(template.ulValueLen);
2N/A if (template.pValue == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A (void) memcpy(template.pValue, buf, template.ulValueLen);
2N/A if (cert) {
2N/A rv = get_cert_attr_from_template(cert_dest, &template);
2N/A } else {
2N/A rv = get_bigint_attr_from_template(key_dest, &template);
2N/A }
2N/A
2N/A free(template.pValue);
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A
2N/A *offset = sizeof (uint64_t) + template.ulValueLen;
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Calculate the total buffer length required to store the
2N/A * object key (the third part) in a keystore format.
2N/A */
2N/Aulong_t
2N/Asoft_pack_object_size(soft_object_t *objp)
2N/A{
2N/A
2N/A CK_OBJECT_CLASS class = objp->class;
2N/A CK_KEY_TYPE keytype = objp->key_type;
2N/A CK_CERTIFICATE_TYPE certtype = objp->cert_type;
2N/A
2N/A switch (class) {
2N/A case CKO_PUBLIC_KEY:
2N/A switch (keytype) {
2N/A case CKK_RSA:
2N/A /*
2N/A * modulus_bits + modulus_len + modulus +
2N/A * pubexpo_len + pubexpo
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_RSA_MOD(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len, 8) +
2N/A 3 * sizeof (uint64_t));
2N/A
2N/A case CKK_DSA:
2N/A /*
2N/A * prime_len + prime + subprime_len + subprime +
2N/A * base_len + base + value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_VALUE(objp))->big_value_len, 8) +
2N/A 4 * sizeof (uint64_t));
2N/A case CKK_EC:
2N/A /*
2N/A * ec_point_len + ec_point
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_EC_POINT(objp))->big_value_len, 8) +
2N/A sizeof (uint64_t));
2N/A case CKK_DH:
2N/A /*
2N/A * prime_len + prime + base_len + base +
2N/A * value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH_VALUE(objp))->big_value_len, 8) +
2N/A 3 * sizeof (uint64_t));
2N/A
2N/A case CKK_X9_42_DH:
2N/A /*
2N/A * prime_len + prime + base_len + base +
2N/A * subprime_len + subprime + value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_VALUE(objp))->big_value_len, 8) +
2N/A 4 * sizeof (uint64_t));
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_PRIVATE_KEY:
2N/A switch (keytype) {
2N/A case CKK_RSA:
2N/A /*
2N/A * modulus_len + modulus + pubexpo_len + pubexpo +
2N/A * priexpo_len + priexpo + prime1_len + prime1 +
2N/A * prime2_len + prime2 + expo1_len + expo1 +
2N/A * expo2_len + expo2 + coef_len + coef
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_MOD(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_COEF(objp))->big_value_len, 8) +
2N/A 8 * sizeof (uint64_t));
2N/A
2N/A case CKK_DSA:
2N/A /*
2N/A * prime_len + prime + subprime_len + subprime +
2N/A * base_len + base + value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_VALUE(objp))->big_value_len, 8) +
2N/A 4 * sizeof (uint64_t));
2N/A
2N/A case CKK_DH:
2N/A /*
2N/A * value_bits + prime_len + prime + base_len + base +
2N/A * value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH_VALUE(objp))->big_value_len, 8) +
2N/A 4 * sizeof (uint64_t));
2N/A
2N/A case CKK_EC:
2N/A /*
2N/A * value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_EC_VALUE(objp))->big_value_len, 8) +
2N/A sizeof (uint64_t));
2N/A
2N/A case CKK_X9_42_DH:
2N/A /*
2N/A * prime_len + prime + base_len + base +
2N/A * subprime_len + subprime + value_len + value
2N/A */
2N/A return (ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_BASE(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8) +
2N/A ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_VALUE(objp))->big_value_len, 8) +
2N/A 4 * sizeof (uint64_t));
2N/A
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_SECRET_KEY:
2N/A /*
2N/A * value_len + value
2N/A */
2N/A return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
2N/A sizeof (uint64_t));
2N/A
2N/A case CKO_CERTIFICATE:
2N/A switch (certtype) {
2N/A case CKC_X_509:
2N/A /*
2N/A * subject_len + subject + value_len + value
2N/A */
2N/A return (ROUNDUP(((cert_attr_t *)
2N/A X509_CERT_SUBJECT(objp))->length, 8) +
2N/A ROUNDUP(((cert_attr_t *)
2N/A X509_CERT_VALUE(objp))->length, 8) +
2N/A 2 * sizeof (uint64_t));
2N/A
2N/A case CKC_X_509_ATTR_CERT:
2N/A /*
2N/A * owner_len + owner + value_len + value
2N/A */
2N/A return (ROUNDUP(((cert_attr_t *)
2N/A X509_ATTR_CERT_OWNER(objp))->length, 8) +
2N/A ROUNDUP(((cert_attr_t *)
2N/A X509_ATTR_CERT_VALUE(objp))->length, 8) +
2N/A 2 * sizeof (uint64_t));
2N/A }
2N/A return (0);
2N/A
2N/A case CKO_DOMAIN_PARAMETERS:
2N/A
2N/A return (0);
2N/A }
2N/A return (0);
2N/A}
2N/A
2N/A/*
2N/A * Pack the object key (the third part) from the soft_object_t
2N/A * into the keystore format.
2N/A */
2N/ACK_RV
2N/Asoft_pack_object(soft_object_t *objp, uchar_t *buf)
2N/A{
2N/A
2N/A CK_OBJECT_CLASS class = objp->class;
2N/A CK_KEY_TYPE keytype = objp->key_type;
2N/A CK_CERTIFICATE_TYPE certtype = objp->cert_type;
2N/A uint64_t tmp_val;
2N/A
2N/A switch (class) {
2N/A case CKO_PUBLIC_KEY:
2N/A switch (keytype) {
2N/A case CKK_RSA:
2N/A /* modulus_bits */
2N/A tmp_val = SWAP64((uint64_t)OBJ_PUB_RSA_MOD_BITS(objp));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A /* modulus_len + modulus */
2N/A tmp_val = SWAP64((uint64_t)(((biginteger_t *)
2N/A OBJ_PUB_RSA_MOD(objp))->big_value_len));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)(((biginteger_t *)
2N/A OBJ_PUB_RSA_MOD(objp))->big_value),
2N/A ((biginteger_t *)
2N/A OBJ_PUB_RSA_MOD(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_RSA_MOD(objp))->big_value_len, 8);
2N/A
2N/A /* pubexpo_len + pubexpo */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)(((biginteger_t *)
2N/A OBJ_PUB_RSA_PUBEXPO(objp))->big_value),
2N/A ((biginteger_t *)
2N/A OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
2N/A break;
2N/A
2N/A case CKK_DSA:
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DSA_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DSA_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DSA_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* subprime_len + subprime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DSA_SUBPRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DSA_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DSA_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DSA_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DSA_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DSA_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DSA_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DSA_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A case CKK_EC:
2N/A /* point_len + point */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_EC_POINT(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_EC_POINT(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_EC_POINT(objp))->big_value_len);
2N/A break;
2N/A
2N/A case CKK_DH:
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A
2N/A case CKK_X9_42_DH:
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH942_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH942_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH942_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH942_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH942_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH942_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* subprime_len + subprime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH942_SUBPRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PUB_DH942_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PUB_DH942_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PUB_DH942_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_PRIVATE_KEY:
2N/A switch (keytype) {
2N/A case CKK_RSA:
2N/A /* modulus_len + modulus */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_MOD(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_MOD(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_MOD(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_MOD(objp))->big_value_len, 8);
2N/A
2N/A /* pubexpo_len + pubexpo */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_PUBEXPO(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8);
2N/A
2N/A /* priexpo_len + priexpo */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIEXPO(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8);
2N/A
2N/A /* prime1_len + prime1 */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME1(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8);
2N/A
2N/A /* prime2_len + prime2 */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME2(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8);
2N/A
2N/A /* expo1_len + expo1 */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO1(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8);
2N/A
2N/A /* expo2_len + expo2 */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO2(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8);
2N/A
2N/A /* coef_len + coef */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_RSA_COEF(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_RSA_COEF(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_RSA_COEF(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_RSA_COEF(objp))->big_value_len, 8);
2N/A
2N/A break;
2N/A
2N/A case CKK_DSA:
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DSA_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DSA_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DSA_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* subprime_len + subprime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DSA_SUBPRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DSA_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DSA_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DSA_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DSA_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DSA_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DSA_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DSA_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A case CKK_EC:
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_EC_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_EC_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_EC_VALUE(objp))->big_value_len);
2N/A break;
2N/A
2N/A case CKK_DH:
2N/A /* value_bits */
2N/A tmp_val = SWAP64((uint64_t)OBJ_PRI_DH_VAL_BITS(objp));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A
2N/A case CKK_X9_42_DH:
2N/A /* prime_len + prime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH942_PRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH942_PRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH942_PRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8);
2N/A
2N/A /* base_len + base */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH942_BASE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH942_BASE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH942_BASE(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_BASE(objp))->big_value_len, 8);
2N/A
2N/A /* subprime_len + subprime */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH942_SUBPRIME(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
2N/A buf = buf + ROUNDUP(((biginteger_t *)
2N/A OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)((biginteger_t *)
2N/A OBJ_PRI_DH942_VALUE(objp))->big_value_len);
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((biginteger_t *)
2N/A OBJ_PRI_DH942_VALUE(objp))->big_value,
2N/A ((biginteger_t *)
2N/A OBJ_PRI_DH942_VALUE(objp))->big_value_len);
2N/A
2N/A break;
2N/A
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_SECRET_KEY:
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)OBJ_SEC_VALUE_LEN(objp));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A if (OBJ_SEC_VALUE_LEN(objp) > 0) {
2N/A (void) memcpy(buf, (char *)OBJ_SEC_VALUE(objp),
2N/A OBJ_SEC_VALUE_LEN(objp));
2N/A buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
2N/A }
2N/A
2N/A break;
2N/A
2N/A case CKO_CERTIFICATE:
2N/A
2N/A switch (certtype) {
2N/A case CKC_X_509:
2N/A /* subject_len + subject */
2N/A tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
2N/A X509_CERT_SUBJECT(objp))->length));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((cert_attr_t *)
2N/A X509_CERT_SUBJECT(objp))->value,
2N/A ((cert_attr_t *)
2N/A X509_CERT_SUBJECT(objp))->length);
2N/A buf = buf + ROUNDUP(((cert_attr_t *)
2N/A X509_CERT_SUBJECT(objp))->length, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
2N/A X509_CERT_VALUE(objp))->length));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((cert_attr_t *)
2N/A X509_CERT_VALUE(objp))->value,
2N/A ((cert_attr_t *)
2N/A X509_CERT_VALUE(objp))->length);
2N/A break;
2N/A
2N/A case CKC_X_509_ATTR_CERT:
2N/A /* owner_len + owner */
2N/A tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
2N/A X509_ATTR_CERT_OWNER(objp))->length));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((cert_attr_t *)
2N/A X509_ATTR_CERT_OWNER(objp))->value,
2N/A ((cert_attr_t *)
2N/A X509_ATTR_CERT_OWNER(objp))->length);
2N/A buf = buf + ROUNDUP(((cert_attr_t *)
2N/A X509_ATTR_CERT_OWNER(objp))->length, 8);
2N/A
2N/A /* value_len + value */
2N/A tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
2N/A X509_ATTR_CERT_VALUE(objp))->length));
2N/A (void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A (void) memcpy(buf, (char *)((cert_attr_t *)
2N/A X509_ATTR_CERT_VALUE(objp))->value,
2N/A ((cert_attr_t *)
2N/A X509_ATTR_CERT_VALUE(objp))->length);
2N/A break;
2N/A }
2N/A break;
2N/A
2N/A case CKO_DOMAIN_PARAMETERS:
2N/A
2N/A return (0);
2N/A }
2N/A return (CKR_OK);
2N/A}
2N/A
2N/A/*
2N/A * Unpack the object key in keystore format (the third part)
2N/A * into soft_object_t.
2N/A */
2N/ACK_RV
2N/Asoft_unpack_object(soft_object_t *objp, uchar_t *buf)
2N/A{
2N/A
2N/A public_key_obj_t *pbk = NULL;
2N/A private_key_obj_t *pvk = NULL;
2N/A secret_key_obj_t *sck;
2N/A certificate_obj_t *cert;
2N/A CK_OBJECT_CLASS class = objp->class;
2N/A CK_KEY_TYPE keytype = objp->key_type;
2N/A CK_CERTIFICATE_TYPE certtype = objp->cert_type;
2N/A
2N/A biginteger_t modulus;
2N/A biginteger_t pubexpo;
2N/A biginteger_t prime;
2N/A biginteger_t subprime;
2N/A biginteger_t base;
2N/A biginteger_t value;
2N/A
2N/A biginteger_t priexpo;
2N/A biginteger_t prime1;
2N/A biginteger_t prime2;
2N/A biginteger_t expo1;
2N/A biginteger_t expo2;
2N/A biginteger_t coef;
2N/A CK_RV rv = CKR_OK;
2N/A ulong_t offset = 0;
2N/A uint64_t tmp_val;
2N/A
2N/A /* prevent bigint_attr_cleanup from freeing invalid attr value */
2N/A (void) memset(&modulus, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&prime, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&subprime, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&base, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&value, 0x0, sizeof (biginteger_t));
2N/A
2N/A (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&prime1, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&prime2, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&expo1, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&expo2, 0x0, sizeof (biginteger_t));
2N/A (void) memset(&coef, 0x0, sizeof (biginteger_t));
2N/A
2N/A switch (class) {
2N/A
2N/A case CKO_PUBLIC_KEY:
2N/A /* Allocate storage for Public Key Object. */
2N/A pbk = calloc(1, sizeof (public_key_obj_t));
2N/A if (pbk == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A return (rv);
2N/A }
2N/A
2N/A objp->object_class_u.public_key = pbk;
2N/A
2N/A switch (keytype) {
2N/A case CKK_RSA: /* modulus_bits */
2N/A (void) memcpy(&tmp_val, buf, sizeof (uint64_t));
2N/A KEY_PUB_RSA_MOD_BITS(pbk) = (CK_ULONG)(SWAP64(tmp_val));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A /* modulus */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &modulus,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&modulus, KEY_PUB_RSA_MOD(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* pubexpo */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
2N/A
2N/A break;
2N/A
2N/A case CKK_DSA:
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* subprime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &subprime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
2N/A
2N/A break;
2N/A
2N/A case CKK_DH:
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
2N/A
2N/A break;
2N/A
2N/A case CKK_EC:
2N/A /* ec_point */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PUB_EC_POINT(pbk));
2N/A break;
2N/A
2N/A case CKK_X9_42_DH:
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* subprime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &subprime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&subprime,
2N/A KEY_PUB_DH942_SUBPRIME(pbk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pub_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PUB_DH942_VALUE(pbk));
2N/A
2N/A break;
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_PRIVATE_KEY:
2N/A /* Allocate storage for Private Key Object. */
2N/A pvk = calloc(1, sizeof (private_key_obj_t));
2N/A if (pvk == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A return (rv);
2N/A }
2N/A
2N/A objp->object_class_u.private_key = pvk;
2N/A
2N/A switch (keytype) {
2N/A case CKK_RSA:
2N/A /* modulus */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &modulus,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* pubexpo */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* priexpo */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &priexpo,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* prime1 */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime1,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* prime2 */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime2,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* expo1 */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &expo1,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* expo2 */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &expo2,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* coef */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &coef,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2N/A
2N/A break;
2N/A
2N/A case CKK_DSA:
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* subprime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &subprime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2N/A
2N/A break;
2N/A
2N/A case CKK_DH:
2N/A /* value_bits */
2N/A (void) memcpy(&tmp_val, buf, sizeof (uint64_t));
2N/A KEY_PRI_DH_VAL_BITS(pvk) = (CK_ULONG)(SWAP64(tmp_val));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2N/A
2N/A break;
2N/A
2N/A case CKK_EC:
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2N/A break;
2N/A
2N/A case CKK_X9_42_DH:
2N/A /* prime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &prime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* base */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &base,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* subprime */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &subprime,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&subprime, KEY_PRI_DH942_BASE(pvk));
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, &value,
2N/A NULL, &offset, B_FALSE)) != CKR_OK)
2N/A goto pri_cleanup;
2N/A
2N/A copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2N/A
2N/A break;
2N/A } /* keytype */
2N/A
2N/A break;
2N/A
2N/A case CKO_SECRET_KEY:
2N/A /* Allocate storage for Secret Key Object. */
2N/A sck = calloc(1, sizeof (secret_key_obj_t));
2N/A if (sck == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A objp->object_class_u.secret_key = sck;
2N/A
2N/A /* value */
2N/A (void) memcpy((void *)&tmp_val, buf, sizeof (uint64_t));
2N/A OBJ_SEC_VALUE_LEN(objp) = (CK_ULONG)(SWAP64(tmp_val));
2N/A buf = buf + sizeof (uint64_t);
2N/A
2N/A if (OBJ_SEC_VALUE_LEN(objp) > 0) {
2N/A OBJ_SEC_VALUE(objp) = malloc(OBJ_SEC_VALUE_LEN(objp));
2N/A if (OBJ_SEC_VALUE(objp) == NULL) {
2N/A free(sck);
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A (void) memcpy(OBJ_SEC_VALUE(objp), buf,
2N/A OBJ_SEC_VALUE_LEN(objp));
2N/A
2N/A buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
2N/A }
2N/A
2N/A return (rv);
2N/A
2N/A case CKO_CERTIFICATE:
2N/A /* Allocate storage for Certificate Object. */
2N/A cert = calloc(1, sizeof (certificate_obj_t));
2N/A if (cert == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A (void) memset((void *)cert, 0, sizeof (certificate_obj_t));
2N/A
2N/A cert->certificate_type = certtype;
2N/A objp->object_class_u.certificate = cert;
2N/A
2N/A switch (certtype) {
2N/A case CKC_X_509:
2N/A /* subject */
2N/A if ((rv = soft_unpack_obj_attribute(buf, NULL,
2N/A &cert->cert_type_u.x509.subject,
2N/A &offset, B_TRUE)) != CKR_OK) {
2N/A free(cert);
2N/A return (rv);
2N/A }
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, NULL,
2N/A &cert->cert_type_u.x509.value,
2N/A &offset, B_TRUE)) != CKR_OK) {
2N/A free(cert);
2N/A return (rv);
2N/A }
2N/A
2N/A break;
2N/A
2N/A case CKC_X_509_ATTR_CERT:
2N/A /* owner */
2N/A if ((rv = soft_unpack_obj_attribute(buf, NULL,
2N/A &cert->cert_type_u.x509_attr.owner,
2N/A &offset, B_TRUE)) != CKR_OK) {
2N/A free(cert);
2N/A return (rv);
2N/A }
2N/A
2N/A buf += ROUNDUP(offset, 8);
2N/A
2N/A /* value */
2N/A if ((rv = soft_unpack_obj_attribute(buf, NULL,
2N/A &cert->cert_type_u.x509_attr.value,
2N/A &offset, B_TRUE)) != CKR_OK) {
2N/A free(cert);
2N/A return (rv);
2N/A }
2N/A
2N/A break;
2N/A }
2N/A
2N/A return (rv);
2N/A
2N/A case CKO_DOMAIN_PARAMETERS:
2N/A
2N/A break;
2N/A }
2N/A
2N/Apub_cleanup:
2N/A /*
2N/A * cleanup the storage allocated to the local variables.
2N/A */
2N/A if (rv != CKR_OK)
2N/A free(pbk);
2N/A bigint_attr_cleanup(&modulus);
2N/A bigint_attr_cleanup(&pubexpo);
2N/A bigint_attr_cleanup(&prime);
2N/A bigint_attr_cleanup(&subprime);
2N/A bigint_attr_cleanup(&base);
2N/A bigint_attr_cleanup(&value);
2N/A return (rv);
2N/A
2N/Apri_cleanup:
2N/A /*
2N/A * cleanup the storage allocated to the local variables.
2N/A */
2N/A if (rv != CKR_OK)
2N/A free(pvk);
2N/A bigint_attr_cleanup(&modulus);
2N/A bigint_attr_cleanup(&priexpo);
2N/A bigint_attr_cleanup(&prime);
2N/A bigint_attr_cleanup(&subprime);
2N/A bigint_attr_cleanup(&base);
2N/A bigint_attr_cleanup(&value);
2N/A bigint_attr_cleanup(&pubexpo);
2N/A bigint_attr_cleanup(&prime1);
2N/A bigint_attr_cleanup(&prime2);
2N/A bigint_attr_cleanup(&expo1);
2N/A bigint_attr_cleanup(&expo2);
2N/A bigint_attr_cleanup(&coef);
2N/A return (rv);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Store the token object to a keystore file.
2N/A */
2N/ACK_RV
2N/Asoft_put_object_to_keystore(soft_object_t *objp)
2N/A{
2N/A
2N/A uchar_t *buf;
2N/A size_t len;
2N/A CK_RV rv;
2N/A
2N/A rv = soft_keystore_pack_obj(objp, &buf, &len);
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A (void) pthread_mutex_lock(&soft_slot.slot_mutex);
2N/A if (objp->object_type == TOKEN_PUBLIC) {
2N/A if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
2N/A B_FALSE, &objp->ks_handle)) == -1) {
2N/A (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
2N/A free(buf);
2N/A return (CKR_FUNCTION_FAILED);
2N/A }
2N/A } else {
2N/A if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
2N/A B_FALSE, &objp->ks_handle)) == -1) {
2N/A (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
2N/A free(buf);
2N/A return (CKR_FUNCTION_FAILED);
2N/A }
2N/A }
2N/A (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
2N/A free(buf);
2N/A return (CKR_OK);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * Modify the in-core token object and then write it to
2N/A * a keystore file.
2N/A */
2N/ACK_RV
2N/Asoft_modify_object_to_keystore(soft_object_t *objp)
2N/A{
2N/A
2N/A uchar_t *buf;
2N/A size_t len;
2N/A CK_RV rv;
2N/A
2N/A rv = soft_keystore_pack_obj(objp, &buf, &len);
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A /* B_TRUE: caller has held a writelock on the keystore */
2N/A if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
2N/A B_TRUE) < 0) {
2N/A return (CKR_FUNCTION_FAILED);
2N/A }
2N/A
2N/A free(buf);
2N/A return (CKR_OK);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * Read the token object from the keystore file.
2N/A */
2N/ACK_RV
2N/Asoft_get_token_objects_from_keystore(ks_search_type_t type)
2N/A{
2N/A CK_RV rv;
2N/A ks_obj_t *ks_obj = NULL, *ks_obj_next;
2N/A soft_object_t *new_objp = NULL;
2N/A
2N/A /* Load the token object from keystore based on the object type */
2N/A rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A
2N/A while (ks_obj) {
2N/A
2N/A new_objp = calloc(1, sizeof (soft_object_t));
2N/A if (new_objp == NULL) {
2N/A rv = CKR_HOST_MEMORY;
2N/A goto cleanup;
2N/A }
2N/A /* Convert the keystore format to memory format */
2N/A rv = soft_keystore_unpack_obj(new_objp, ks_obj);
2N/A if (rv != CKR_OK) {
2N/A if (new_objp->class == CKO_CERTIFICATE)
2N/A soft_cleanup_cert_object(new_objp);
2N/A else
2N/A soft_cleanup_object(new_objp);
2N/A goto cleanup;
2N/A }
2N/A
2N/A soft_add_token_object_to_slot(new_objp);
2N/A
2N/A /* Free the ks_obj list */
2N/A ks_obj_next = ks_obj->next;
2N/A if (ks_obj->buf)
2N/A free(ks_obj->buf);
2N/A free(ks_obj);
2N/A ks_obj = ks_obj_next;
2N/A }
2N/A
2N/A return (CKR_OK);
2N/A
2N/Acleanup:
2N/A while (ks_obj) {
2N/A ks_obj_next = ks_obj->next;
2N/A free(ks_obj->buf);
2N/A free(ks_obj);
2N/A ks_obj = ks_obj_next;
2N/A }
2N/A return (rv);
2N/A}
2N/A
2N/A/*
2N/A * soft_gen_crypt_key()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * pPIN: pointer to caller provided Pin
2N/A * key: output argument which contains the address of the
2N/A * pointer to encryption key in the soft_object_t.
2N/A * It is caller's responsibility to call soft_delete_object()
2N/A * if this key is no longer in use.
2N/A * saltdata: input argument (if non-NULL), or
2N/A * output argument (if NULL):
2N/A * address of pointer to the "salt" of the encryption key
2N/A *
2N/A * Description:
2N/A *
2N/A * Generate an encryption key of the input PIN.
2N/A *
2N/A * Returns:
2N/A *
2N/A * CKR_OK: no error
2N/A * Other: some error occurred while generating the encryption key
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
2N/A{
2N/A CK_OBJECT_CLASS class = CKO_SECRET_KEY;
2N/A CK_ATTRIBUTE tmpl[5];
2N/A int attrs = 0;
2N/A CK_RV rv;
2N/A CK_MECHANISM Mechanism;
2N/A CK_PKCS5_PBKD2_PARAMS params;
2N/A CK_BYTE salt[PBKD2_SALT_SIZE];
2N/A CK_ULONG keylen = AES_MIN_KEY_BYTES;
2N/A CK_KEY_TYPE keytype = CKK_AES;
2N/A static CK_BBOOL truevalue = TRUE;
2N/A soft_object_t *secret_key;
2N/A CK_OBJECT_HANDLE hKey;
2N/A CK_ULONG passwd_size;
2N/A
2N/A if (pPIN == NULL)
2N/A return (CKR_FUNCTION_FAILED);
2N/A
2N/A tmpl[attrs].type = CKA_CLASS;
2N/A tmpl[attrs].pValue = &class;
2N/A tmpl[attrs].ulValueLen = sizeof (class);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_KEY_TYPE;
2N/A tmpl[attrs].pValue = &keytype;
2N/A tmpl[attrs].ulValueLen = sizeof (keytype);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_ENCRYPT;
2N/A tmpl[attrs].pValue = &truevalue;
2N/A tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_DECRYPT;
2N/A tmpl[attrs].pValue = &truevalue;
2N/A tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_VALUE_LEN;
2N/A tmpl[attrs].pValue = &keylen;
2N/A tmpl[attrs].ulValueLen = sizeof (keylen);
2N/A attrs++;
2N/A
2N/A if (*saltdata == NULL) {
2N/A bzero(salt, sizeof (salt));
2N/A (void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
2N/A *saltdata = malloc(PBKD2_SALT_SIZE);
2N/A if (*saltdata == NULL)
2N/A return (CKR_HOST_MEMORY);
2N/A (void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
2N/A } else {
2N/A bzero(salt, sizeof (salt));
2N/A (void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
2N/A }
2N/A
2N/A Mechanism.mechanism = CKM_PKCS5_PBKD2;
2N/A Mechanism.pParameter = &params;
2N/A Mechanism.ulParameterLen = sizeof (params);
2N/A passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2N/A
2N/A params.saltSource = CKZ_SALT_SPECIFIED;
2N/A params.pSaltSourceData = (void *)salt;
2N/A params.ulSaltSourceDataLen = sizeof (salt);
2N/A params.iterations = PBKD2_ITERATIONS;
2N/A params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2N/A params.pPrfData = NULL;
2N/A params.ulPrfDataLen = 0;
2N/A params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2N/A params.ulPasswordLen = &passwd_size;
2N/A
2N/A rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2N/A CKO_SECRET_KEY, CKK_AES, 0, SOFT_GEN_KEY, B_TRUE);
2N/A
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A
2N/A /* Obtain the secret object pointer. */
2N/A secret_key = (soft_object_t *)hKey;
2N/A keylen = OBJ_SEC_VALUE_LEN(secret_key);
2N/A if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2N/A soft_delete_object(&token_session, secret_key,
2N/A B_FALSE, B_FALSE);
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2N/A secret_key);
2N/A
2N/A if (rv != CKR_OK)
2N/A soft_delete_object(&token_session, secret_key,
2N/A B_FALSE, B_FALSE);
2N/A else
2N/A *key = secret_key;
2N/A
2N/A return (rv);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * soft_gen_hmac_key()
2N/A *
2N/A * Arguments:
2N/A *
2N/A * pPIN: pointer to caller provided Pin
2N/A * key: output argument which contains the address of the
2N/A * pointer to hmac key in the soft_object_t.
2N/A * It is caller's responsibility to call soft_delete_object()
2N/A * if this key is no longer in use.
2N/A * saltdata: input argument (if non-NULL), or
2N/A * output argument (if NULL):
2N/A * address of pointer to the "salt" of the hmac key
2N/A *
2N/A * Description:
2N/A *
2N/A * Generate a hmac key of the input PIN.
2N/A *
2N/A * Returns:
2N/A *
2N/A * CKR_OK: no error
2N/A * Other: some error occurred while generating the hmac key
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
2N/A{
2N/A CK_OBJECT_CLASS class = CKO_SECRET_KEY;
2N/A CK_ATTRIBUTE tmpl[5];
2N/A int attrs = 0;
2N/A CK_RV rv;
2N/A CK_MECHANISM Mechanism;
2N/A CK_PKCS5_PBKD2_PARAMS params;
2N/A CK_BYTE salt[PBKD2_SALT_SIZE];
2N/A CK_ULONG keylen = 16;
2N/A CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
2N/A static CK_BBOOL truevalue = TRUE;
2N/A soft_object_t *secret_key;
2N/A CK_OBJECT_HANDLE hKey;
2N/A CK_ULONG passwd_size;
2N/A
2N/A if (pPIN == NULL)
2N/A return (CKR_FUNCTION_FAILED);
2N/A
2N/A tmpl[attrs].type = CKA_CLASS;
2N/A tmpl[attrs].pValue = &class;
2N/A tmpl[attrs].ulValueLen = sizeof (class);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_KEY_TYPE;
2N/A tmpl[attrs].pValue = &keytype;
2N/A tmpl[attrs].ulValueLen = sizeof (keytype);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_SIGN;
2N/A tmpl[attrs].pValue = &truevalue;
2N/A tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_VERIFY;
2N/A tmpl[attrs].pValue = &truevalue;
2N/A tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2N/A attrs++;
2N/A
2N/A tmpl[attrs].type = CKA_VALUE_LEN;
2N/A tmpl[attrs].pValue = &keylen;
2N/A tmpl[attrs].ulValueLen = sizeof (keylen);
2N/A attrs++;
2N/A
2N/A if (*saltdata == NULL) {
2N/A bzero(salt, sizeof (salt));
2N/A (void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
2N/A *saltdata = malloc(PBKD2_SALT_SIZE);
2N/A if (*saltdata == NULL)
2N/A return (CKR_HOST_MEMORY);
2N/A (void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
2N/A } else {
2N/A bzero(salt, sizeof (salt));
2N/A (void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
2N/A }
2N/A
2N/A Mechanism.mechanism = CKM_PKCS5_PBKD2;
2N/A Mechanism.pParameter = &params;
2N/A Mechanism.ulParameterLen = sizeof (params);
2N/A passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2N/A
2N/A params.saltSource = CKZ_SALT_SPECIFIED;
2N/A params.pSaltSourceData = (void *)salt;
2N/A params.ulSaltSourceDataLen = sizeof (salt);
2N/A params.iterations = PBKD2_ITERATIONS;
2N/A params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2N/A params.pPrfData = NULL;
2N/A params.ulPrfDataLen = 0;
2N/A params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2N/A params.ulPasswordLen = &passwd_size;
2N/A
2N/A rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2N/A CKO_SECRET_KEY, CKK_GENERIC_SECRET, 0, SOFT_GEN_KEY, B_TRUE);
2N/A
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A
2N/A /* Obtain the secret object pointer. */
2N/A secret_key = (soft_object_t *)hKey;
2N/A keylen = OBJ_SEC_VALUE_LEN(secret_key);
2N/A if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2N/A soft_delete_object(&token_session, secret_key,
2N/A B_FALSE, B_FALSE);
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2N/A secret_key);
2N/A
2N/A if (rv != CKR_OK)
2N/A soft_delete_object(&token_session, secret_key,
2N/A B_FALSE, B_FALSE);
2N/A else
2N/A *key = secret_key;
2N/A
2N/A return (rv);
2N/A
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/Asoft_init_token_session(void)
2N/A{
2N/A
2N/A
2N/A token_session.magic_marker = SOFTTOKEN_SESSION_MAGIC;
2N/A token_session.pApplication = NULL_PTR;
2N/A token_session.Notify = NULL;
2N/A token_session.flags = CKF_SERIAL_SESSION;
2N/A token_session.state = CKS_RO_PUBLIC_SESSION;
2N/A token_session.object_list = NULL;
2N/A token_session.ses_refcnt = 0;
2N/A token_session.ses_close_sync = 0;
2N/A token_session.next = NULL;
2N/A token_session.prev = NULL;
2N/A
2N/A /* Initialize the lock for the token session */
2N/A if (pthread_mutex_init(&token_session.session_mutex, NULL) != 0) {
2N/A return (CKR_CANT_LOCK);
2N/A }
2N/A
2N/A (void) pthread_cond_init(&token_session.ses_free_cond, NULL);
2N/A
2N/A return (CKR_OK);
2N/A
2N/A}
2N/A
2N/Avoid
2N/Asoft_destroy_token_session(void)
2N/A{
2N/A token_session.ses_refcnt = 0;
2N/A soft_delete_all_objects_in_session(&token_session, B_TRUE);
2N/A (void) pthread_cond_destroy(&token_session.ses_free_cond);
2N/A (void) pthread_mutex_destroy(&token_session.session_mutex);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * Encrypt/Decrypt the private token object when dealing with the keystore.
2N/A * This function only applies to the private token object.
2N/A */
2N/ACK_RV
2N/Asoft_keystore_crypt(soft_object_t *key_p, uchar_t *ivec, boolean_t encrypt,
2N/A CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2N/A{
2N/A CK_MECHANISM mech;
2N/A soft_aes_ctx_t *soft_aes_ctx;
2N/A CK_RV rv;
2N/A CK_ULONG tmplen, tmplen1;
2N/A
2N/A /*
2N/A * The caller will pass NULL for "out" (output buffer) to find out
2N/A * the output buffer size that it need to allocate for the encryption
2N/A * or decryption.
2N/A */
2N/A if (out == NULL) {
2N/A mech.mechanism = CKM_AES_CBC_PAD;
2N/A mech.pParameter = (void *)ivec;
2N/A mech.ulParameterLen = AES_BLOCK_LEN;
2N/A
2N/A rv = soft_aes_crypt_init_common(&token_session, &mech,
2N/A key_p, encrypt ? SOFT_ENCRYPT_OP : SOFT_DECRYPT_OP);
2N/A
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A
2N/A (void) pthread_mutex_lock(&token_session.session_mutex);
2N/A
2N/A if (encrypt)
2N/A soft_aes_ctx =
2N/A (soft_aes_ctx_t *)token_session.encrypt.context;
2N/A else
2N/A soft_aes_ctx =
2N/A (soft_aes_ctx_t *)token_session.decrypt.context;
2N/A
2N/A /* Copy Initialization Vector (IV) into the context. */
2N/A (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2N/A
2N/A /* Allocate a context for AES cipher-block chaining. */
2N/A soft_aes_ctx->mode_ctx = (void *)aes_cbc_ctx_init(
2N/A soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2N/A soft_aes_ctx->ivec);
2N/A
2N/A if (soft_aes_ctx->mode_ctx == NULL) {
2N/A bzero(soft_aes_ctx->key_sched,
2N/A soft_aes_ctx->keysched_len);
2N/A free(soft_aes_ctx->key_sched);
2N/A if (encrypt) {
2N/A free(token_session.encrypt.context);
2N/A token_session.encrypt.context = NULL;
2N/A } else {
2N/A free(token_session.encrypt.context);
2N/A token_session.encrypt.context = NULL;
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&token_session.
2N/A session_mutex);
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&token_session.session_mutex);
2N/A /*
2N/A * Since out == NULL, the soft_aes_xxcrypt_common() will
2N/A * simply return the output buffer length to the caller.
2N/A */
2N/A if (encrypt) {
2N/A rv = soft_aes_encrypt_common(&token_session, in,
2N/A in_len, out, out_len, B_FALSE);
2N/A } else {
2N/A rv = soft_aes_decrypt_common(&token_session, in,
2N/A in_len, out, out_len, B_FALSE);
2N/A }
2N/A
2N/A } else {
2N/A /*
2N/A * The caller has allocated the output buffer, so that we
2N/A * are doing the real encryption/decryption this time.
2N/A */
2N/A tmplen = *out_len;
2N/A if (encrypt) {
2N/A rv = soft_aes_encrypt_common(&token_session, in,
2N/A in_len, out, &tmplen, B_TRUE);
2N/A if (rv == CKR_OK) {
2N/A tmplen1 = *out_len - tmplen;
2N/A rv = soft_encrypt_final(&token_session,
2N/A out+tmplen, &tmplen1);
2N/A *out_len = tmplen + tmplen1;
2N/A }
2N/A } else {
2N/A rv = soft_aes_decrypt_common(&token_session, in,
2N/A in_len, out, &tmplen, B_TRUE);
2N/A if (rv == CKR_OK) {
2N/A tmplen1 = *out_len - tmplen;
2N/A rv = soft_decrypt_final(&token_session,
2N/A out+tmplen, &tmplen1);
2N/A *out_len = tmplen + tmplen1;
2N/A }
2N/A }
2N/A }
2N/A
2N/A return (rv);
2N/A
2N/A}
2N/A
2N/A/*
2N/A * Sign/Verify the private token object for checking its data integrity
2N/A * when dealing with the keystore.
2N/A * This function only applies to the private token object.
2N/A */
2N/ACK_RV
2N/Asoft_keystore_hmac(soft_object_t *key_p, boolean_t sign,
2N/A CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2N/A{
2N/A CK_MECHANISM mech;
2N/A CK_RV rv;
2N/A
2N/A mech.mechanism = CKM_MD5_HMAC;
2N/A mech.pParameter = NULL_PTR;
2N/A mech.ulParameterLen = 0;
2N/A
2N/A rv = soft_hmac_sign_verify_init_common(&token_session, &mech,
2N/A key_p, sign);
2N/A
2N/A if (rv != CKR_OK)
2N/A return (rv);
2N/A
2N/A if (sign) {
2N/A rv = soft_sign(&token_session, in, in_len, out, out_len);
2N/A } else {
2N/A rv = soft_verify(&token_session, in, in_len, out, *out_len);
2N/A }
2N/A
2N/A return (rv);
2N/A}