f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * CDDL HEADER START
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers *
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * The contents of this file are subject to the terms of the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Common Development and Distribution License (the "License").
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * You may not use this file except in compliance with the License.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers *
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * or http://www.opensolaris.org/os/licensing.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * See the License for the specific language governing permissions
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * and limitations under the License.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers *
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * When distributing Covered Code, include this CDDL HEADER in each
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * If applicable, add the following below this CDDL HEADER, with the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * fields enclosed by brackets "[]" replaced with your own identifying
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * information: Portions Copyright [yyyy] [name of copyright owner]
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers *
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * CDDL HEADER END
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*
7b79d84636ec82b45f00c982cf6810db81852d17Dina K Nimeh * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Use is subject to license terms.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <stdlib.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <string.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <strings.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <sys/types.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <sys/crypto/common.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <security/cryptoki.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <bignum.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include <des_impl.h>
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softGlobal.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softSession.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softObject.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softEC.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softCrypt.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softOps.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#include "softMAC.h"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersvoid
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_free_ecparams(ECParams *params, boolean_t freeit)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->fieldID.u.prime, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->curve.a, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->curve.b, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->curve.seed, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->base, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->order, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->DEREncoding, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&params->curveOID, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (freeit)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(params);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersstatic void
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_free_ecc_context(soft_ecc_ctx_t *ecc_ctx)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ecc_ctx != NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ecc_ctx->key != NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_cleanup_object(ecc_ctx->key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(ecc_ctx->key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(&ecc_ctx->ecparams, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(ecc_ctx);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersvoid
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_free_ecprivkey(ECPrivateKey *key)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(&key->ecParams, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Don't free publicValue or privateValue
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * as these values are copied into objects.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&key->version, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Called from init routines to do basic sanity checks. Init routines,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * e.g. sign_init should fail rather than subsequent operations.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersstatic int
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerscheck_key(soft_object_t *key_p, boolean_t sign)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers biginteger_t *p;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ulong_t len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (sign) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((key_p->class != CKO_PRIVATE_KEY) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (key_p->key_type != CKK_EC))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_TYPE_INCONSISTENT);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers p = OBJ_PRI_EC_VALUE(key_p);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len = p->big_value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (p->big_value == NULL)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_SIZE_RANGE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((key_p->class != CKO_PUBLIC_KEY) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (key_p->key_type != CKK_EC))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_TYPE_INCONSISTENT);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers p = OBJ_PUB_EC_POINT(key_p);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len = p->big_value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (p->big_value == NULL)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) * 2 + 1 ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN) * 2 + 1)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_SIZE_RANGE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_OK);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * This function places the octet string of the specified attribute
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * into the corresponding key object.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersstatic void
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_genECkey_set_attribute(soft_object_t *key, biginteger_t *bi,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ATTRIBUTE_TYPE type)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers biginteger_t *dst;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers switch (type) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKA_VALUE:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers dst = OBJ_PRI_EC_VALUE(key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKA_EC_POINT:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers dst = OBJ_PUB_EC_POINT(key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers copy_bigint_attr(bi, dst);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ec_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ATTRIBUTE template;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECPrivateKey *privKey; /* contains both public and private values */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECParams *ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECKEYECParams params_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers biginteger_t bi;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t param_buffer[EC_MAX_OID_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint_t paramlen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((pubkey->class != CKO_PUBLIC_KEY) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (pubkey->key_type != CKK_EC))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_TYPE_INCONSISTENT);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((prikey->class != CKO_PRIVATE_KEY) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (prikey->key_type != CKK_EC))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_KEY_TYPE_INCONSISTENT);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.type = CKA_EC_PARAMS;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.pValue = param_buffer;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.ulValueLen = sizeof (param_buffer);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_get_public_key_attribute(pubkey, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers paramlen = template.ulValueLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* private key also has CKA_EC_PARAMS attribute */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = set_extra_attr_to_object(prikey, CKA_EC_PARAMS, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* ASN1 check */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (param_buffer[0] != 0x06 ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers param_buffer[1] != paramlen - 2) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_ATTRIBUTE_VALUE_INVALID);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.len = paramlen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.data = param_buffer;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* bad curve OID */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_ARGUMENTS_BAD);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (EC_NewKey(ecparams, &privKey, 0) != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(ecparams, B_TRUE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_FUNCTION_FAILED);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers bi.big_value = privKey->privateValue.data;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers bi.big_value_len = privKey->privateValue.len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_genECkey_set_attribute(prikey, &bi, CKA_VALUE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers bi.big_value = privKey->publicValue.data;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers bi.big_value_len = privKey->publicValue.len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_genECkey_set_attribute(pubkey, &bi, CKA_EC_POINT);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecprivkey(privKey);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(ecparams, B_TRUE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_OK);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ec_key_derive(soft_object_t *basekey, soft_object_t *secretkey,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers void *mech_params, size_t mech_params_len)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ATTRIBUTE template;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ECDH1_DERIVE_PARAMS *ecdh1_derive_params = mech_params;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t value[EC_MAX_VALUE_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint32_t value_len = sizeof (value);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t params[EC_MAX_OID_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint32_t params_len = sizeof (params);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint32_t keylen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECParams *ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECKEYECParams params_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECItem public_value_item, private_value_item, secret_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t *buf;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (mech_params_len != sizeof (CK_ECDH1_DERIVE_PARAMS) ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ecdh1_derive_params->kdf != CKD_NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_MECHANISM_PARAM_INVALID);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.type = CKA_VALUE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.pValue = value;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.ulValueLen = value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_get_private_key_attribute(basekey, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers value_len = template.ulValueLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers private_value_item.data = value;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers private_value_item.len = value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.type = CKA_EC_PARAMS;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.pValue = params;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.ulValueLen = params_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_get_private_key_attribute(basekey, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_len = template.ulValueLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers switch (secretkey->key_type) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_DES:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = DES_KEYSIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_DES2:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = DES2_KEYSIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_DES3:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = DES3_KEYSIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_RC4:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_AES:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case CKK_GENERIC_SECRET:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#ifdef __sparcv9
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* LINTED */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = (uint32_t)OBJ_SEC_VALUE_LEN(secretkey);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#else /* !__sparcv9 */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = OBJ_SEC_VALUE_LEN(secretkey);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#endif /* __sparcv9 */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers break;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* ASN1 check */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (params[0] != 0x06 ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params[1] != params_len - 2) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_ATTRIBUTE_VALUE_INVALID);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.data = params;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.len = params_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* bad curve OID */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_ARGUMENTS_BAD);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers public_value_item.data = ecdh1_derive_params->pPublicData;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers public_value_item.len = ecdh1_derive_params->ulPublicDataLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers secret_item.data = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers secret_item.len = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ECDH_Derive(&public_value_item, ecparams, &private_value_item,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers B_FALSE, &secret_item, 0) != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(ecparams, B_TRUE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_FUNCTION_FAILED);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_OK;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (keylen == 0)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers keylen = secret_item.len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (keylen > secret_item.len) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_ATTRIBUTE_VALUE_INVALID;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto out;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers buf = malloc(keylen);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (buf == NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_HOST_MEMORY;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto out;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers bcopy(secret_item.data + secret_item.len - keylen, buf, keylen);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers OBJ_SEC_VALUE_LEN(secretkey) = keylen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers OBJ_SEC_VALUE(secretkey) = buf;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersout:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecparams(ecparams, B_TRUE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECITEM_FreeItem(&secret_item, B_FALSE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Allocate a ECC context for the active sign or verify operation.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * This function is called without the session lock held.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ecc_sign_verify_init_common(soft_session_t *session_p,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers boolean_t sign)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ATTRIBUTE template;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_MECHANISM digest_mech;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_ecc_ctx_t *ecc_ctx;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_object_t *tmp_key = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t params[EC_MAX_OID_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECParams *ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECKEYECParams params_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((rv = check_key(key_p, sign)) != CKR_OK)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (pMechanism->mechanism == CKM_ECDSA_SHA1) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers digest_mech.mechanism = CKM_SHA_1;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_digest_init_internal(session_p, &digest_mech);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ecc_ctx = malloc(sizeof (soft_ecc_ctx_t));
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ecc_ctx == NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_HOST_MEMORY);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Make a copy of the signature or verification key, and save it
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * in the ECC crypto context since it will be used later for
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * signing/verification. We don't want to hold any object reference
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * on this original key while doing signing/verification.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&key_p->object_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH, NULL);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((rv != CKR_OK) || (tmp_key == NULL)) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* Most likely we ran out of space. */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&key_p->object_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(ecc_ctx);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.type = CKA_EC_PARAMS;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.pValue = params;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.ulValueLen = sizeof (params);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_get_private_key_attribute(key_p, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&key_p->object_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto out;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* ASN1 check */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (params[0] != 0x06 ||
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params[1] != template.ulValueLen - 2) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_ATTRIBUTE_VALUE_INVALID;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto out;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.data = params;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers params_item.len = template.ulValueLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ecc_ctx->key = tmp_key;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* bad curve OID */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_ARGUMENTS_BAD;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto out;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ecc_ctx->ecparams = *ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(ecparams);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (sign) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->sign.context = ecc_ctx;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->sign.mech.mechanism = pMechanism->mechanism;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->verify.context = ecc_ctx;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->verify.mech.mechanism = pMechanism->mechanism;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_OK);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersout:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_cleanup_object(tmp_key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(tmp_key);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers free(ecc_ctx);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ecc_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG_PTR pulSignedLen, boolean_t Final)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv = CKR_OK;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_BYTE hash[SHA1_HASH_SIZE];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG hash_len = SHA1_HASH_SIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (pSigned != NULL) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (Final) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_digest_final(session_p, hash, &hash_len);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_digest(session_p, pData, ulDataLen, hash,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers &hash_len);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecc_context(session_p->sign.context);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->sign.context = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->digest.flags = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_ecc_sign(session_p, hash, hash_len, pSigned, pulSignedLen);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersclean_exit:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* soft_digest_common() has freed the digest context */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->digest.flags = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersclean1:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ecc_sign(soft_session_t *session_p, CK_BYTE_PTR pData,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG_PTR pulSignedLen)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv = CKR_OK;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECStatus ss;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_ecc_ctx_t *ecc_ctx = session_p->sign.context;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_object_t *key = ecc_ctx->key;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t value[EC_MAX_VALUE_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECPrivateKey ECkey;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECItem signature_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECItem digest_item;
c64d15a587b6038b85a928885fc997da7315fbfemcpowers uint_t value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((key->class != CKO_PRIVATE_KEY) || (key->key_type != CKK_EC)) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_KEY_TYPE_INCONSISTENT;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ulDataLen > EC_MAX_DIGEST_LEN) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_DATA_LEN_RANGE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* structure assignment */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECkey.ecParams = ecc_ctx->ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
c64d15a587b6038b85a928885fc997da7315fbfemcpowers value_len = EC_MAX_VALUE_LEN;
c64d15a587b6038b85a928885fc997da7315fbfemcpowers rv = soft_get_private_value(key, CKA_VALUE, value, &value_len);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECkey.privateValue.data = value;
c64d15a587b6038b85a928885fc997da7315fbfemcpowers ECkey.privateValue.len = value_len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers signature_item.data = pSigned;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers signature_item.len = *pulSignedLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers digest_item.data = pData;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers digest_item.len = ulDataLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((ss = ECDSA_SignDigest(&ECkey, &signature_item, &digest_item, 0))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ss == SECBufferTooSmall)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (CKR_BUFFER_TOO_SMALL);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_FUNCTION_FAILED;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv == CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers *pulSignedLen = signature_item.len;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (pSigned == NULL)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersclean_exit:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecc_context(session_p->sign.context);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->sign.context = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ecc_verify(soft_session_t *session_p, CK_BYTE_PTR pData,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulSignatureLen)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv = CKR_OK;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_ecc_ctx_t *ecc_ctx = session_p->verify.context;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_object_t *key = ecc_ctx->key;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uchar_t point[EC_MAX_POINT_LEN];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ATTRIBUTE template;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECPublicKey ECkey;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECItem signature_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers SECItem digest_item;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if ((key->class != CKO_PUBLIC_KEY) ||(key->key_type != CKK_EC)) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_KEY_TYPE_INCONSISTENT;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ulSignatureLen > EC_MAX_SIG_LEN) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_SIGNATURE_LEN_RANGE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ulDataLen > EC_MAX_DIGEST_LEN) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_DATA_LEN_RANGE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* structure assignment */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECkey.ecParams = ecc_ctx->ecparams;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.type = CKA_EC_POINT;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.pValue = point;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers template.ulValueLen = sizeof (point);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_get_public_key_attribute(key, &template);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers goto clean_exit;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECkey.publicValue.data = point;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ECkey.publicValue.len = template.ulValueLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers signature_item.data = pSignature;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers signature_item.len = ulSignatureLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers digest_item.data = pData;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers digest_item.len = ulDataLen;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (ECDSA_VerifyDigest(&ECkey, &signature_item, &digest_item, 0)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers != SECSuccess) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_SIGNATURE_INVALID;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = CKR_OK;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersclean_exit:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecc_context(session_p->verify.context);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->verify.context = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersCK_RV
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowerssoft_ecc_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG ulSignedLen, boolean_t Final)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers{
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_RV rv;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_BYTE hash[SHA1_HASH_SIZE];
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CK_ULONG hash_len = SHA1_HASH_SIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (Final) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_digest_final(session_p, hash, &hash_len);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers } else {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (rv != CKR_OK) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers soft_free_ecc_context(session_p->verify.context);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->verify.context = NULL;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->digest.flags = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers }
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /*
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Now, we are ready to verify the data using signature.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * soft_ecc_verify() will free the verification key.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers rv = soft_ecc_verify(session_p, hash, hash_len,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers pSigned, ulSignedLen);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersclean_exit:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* soft_digest_common() has freed the digest context */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers session_p->digest.flags = 0;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (rv);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers}