2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <stdlib.h>
2N/A#include <strings.h>
2N/A#include <sys/types.h>
2N/A#include <security/cryptoki.h>
2N/A#include "softObject.h"
2N/A#include "softOps.h"
2N/A#include "softSession.h"
2N/A#include "softMAC.h"
2N/A#include "softRSA.h"
2N/A#include "softDSA.h"
2N/A#include "softEC.h"
2N/A#include "softCrypt.h"
2N/A
2N/A/*
2N/A * soft_sign_init()
2N/A *
2N/A * Arguments:
2N/A * session_p: pointer to soft_session_t struct
2N/A * pMechanism: pointer to CK_MECHANISM struct provided by application
2N/A * key_p: pointer to key soft_object_t struct
2N/A *
2N/A * Description:
2N/A * called by C_SignInit(). This function calls the corresponding
2N/A * sign init routine based on the mechanism.
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_sign_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
2N/A soft_object_t *key_p)
2N/A{
2N/A
2N/A switch (pMechanism->mechanism) {
2N/A
2N/A case CKM_SSL3_MD5_MAC:
2N/A case CKM_SSL3_SHA1_MAC:
2N/A case CKM_MD5_HMAC_GENERAL:
2N/A case CKM_MD5_HMAC:
2N/A case CKM_SHA_1_HMAC_GENERAL:
2N/A case CKM_SHA_1_HMAC:
2N/A case CKM_SHA224_HMAC_GENERAL:
2N/A case CKM_SHA224_HMAC:
2N/A case CKM_SHA256_HMAC_GENERAL:
2N/A case CKM_SHA256_HMAC:
2N/A case CKM_SHA384_HMAC_GENERAL:
2N/A case CKM_SHA384_HMAC:
2N/A case CKM_SHA512_HMAC_GENERAL:
2N/A case CKM_SHA512_HMAC:
2N/A
2N/A return (soft_hmac_sign_verify_init_common(session_p,
2N/A pMechanism, key_p, B_TRUE));
2N/A
2N/A case CKM_RSA_X_509:
2N/A case CKM_RSA_PKCS:
2N/A case CKM_MD5_RSA_PKCS:
2N/A case CKM_SHA1_RSA_PKCS:
2N/A case CKM_SHA224_RSA_PKCS:
2N/A case CKM_SHA256_RSA_PKCS:
2N/A case CKM_SHA384_RSA_PKCS:
2N/A case CKM_SHA512_RSA_PKCS:
2N/A
2N/A return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
2N/A key_p, B_TRUE));
2N/A
2N/A case CKM_DSA:
2N/A case CKM_DSA_SHA1:
2N/A
2N/A return (soft_dsa_sign_verify_init_common(session_p, pMechanism,
2N/A key_p, B_TRUE));
2N/A
2N/A case CKM_ECDSA:
2N/A case CKM_ECDSA_SHA1:
2N/A
2N/A return (soft_ecc_sign_verify_init_common(session_p, pMechanism,
2N/A key_p, B_TRUE));
2N/A
2N/A case CKM_DES_MAC_GENERAL:
2N/A case CKM_DES_MAC:
2N/A
2N/A return (soft_des_sign_verify_init_common(session_p, pMechanism,
2N/A key_p, B_TRUE));
2N/A
2N/A default:
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A
2N/A}
2N/A
2N/A
2N/A/*
2N/A * soft_sign()
2N/A *
2N/A * Arguments:
2N/A * session_p: pointer to soft_session_t struct
2N/A * pData: pointer to the input data to be signed
2N/A * ulDataLen: length of the input data
2N/A * pSignature: pointer to the signature after signing
2N/A * pulSignatureLen: pointer to the length of the signature
2N/A *
2N/A * Description:
2N/A * called by C_Sign(). This function calls the corresponding
2N/A * sign routine based on the mechanism.
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_sign(soft_session_t *session_p, CK_BYTE_PTR pData,
2N/A CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
2N/A CK_ULONG_PTR pulSignatureLen)
2N/A{
2N/A
2N/A CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism;
2N/A CK_RV rv = CKR_OK;
2N/A
2N/A switch (mechanism) {
2N/A
2N/A case CKM_SSL3_MD5_MAC:
2N/A case CKM_SSL3_SHA1_MAC:
2N/A case CKM_MD5_HMAC_GENERAL:
2N/A case CKM_MD5_HMAC:
2N/A case CKM_SHA_1_HMAC_GENERAL:
2N/A case CKM_SHA_1_HMAC:
2N/A case CKM_SHA224_HMAC_GENERAL:
2N/A case CKM_SHA224_HMAC:
2N/A case CKM_SHA256_HMAC_GENERAL:
2N/A case CKM_SHA256_HMAC:
2N/A case CKM_SHA384_HMAC_GENERAL:
2N/A case CKM_SHA384_HMAC:
2N/A case CKM_SHA512_HMAC_GENERAL:
2N/A case CKM_SHA512_HMAC:
2N/A {
2N/A CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */
2N/A
2N/A if (pSignature != NULL) {
2N/A /* Pass local buffer to avoid overflow. */
2N/A rv = soft_hmac_sign_verify_common(session_p, pData,
2N/A ulDataLen, hmac, pulSignatureLen, B_TRUE);
2N/A } else {
2N/A /* Pass original pSignature, let callee to handle it. */
2N/A rv = soft_hmac_sign_verify_common(session_p, pData,
2N/A ulDataLen, pSignature, pulSignatureLen, B_TRUE);
2N/A }
2N/A
2N/A if ((rv == CKR_OK) && (pSignature != NULL))
2N/A (void) memcpy(pSignature, hmac, *pulSignatureLen);
2N/A
2N/A return (rv);
2N/A }
2N/A case CKM_DES_MAC_GENERAL:
2N/A case CKM_DES_MAC:
2N/A {
2N/A CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
2N/A
2N/A if (pSignature != NULL) {
2N/A /* Pass local buffer to avoid overflow. */
2N/A rv = soft_des_sign_verify_common(session_p, pData,
2N/A ulDataLen, signature, pulSignatureLen, B_TRUE,
2N/A B_FALSE);
2N/A } else {
2N/A /* Pass NULL, let callee to handle it. */
2N/A rv = soft_des_sign_verify_common(session_p, pData,
2N/A ulDataLen, NULL, pulSignatureLen, B_TRUE, B_FALSE);
2N/A }
2N/A
2N/A if ((rv == CKR_OK) && (pSignature != NULL))
2N/A (void) memcpy(pSignature, signature, *pulSignatureLen);
2N/A
2N/A return (rv);
2N/A }
2N/A case CKM_RSA_X_509:
2N/A case CKM_RSA_PKCS:
2N/A
2N/A return (soft_rsa_sign_common(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen, mechanism));
2N/A
2N/A case CKM_MD5_RSA_PKCS:
2N/A case CKM_SHA1_RSA_PKCS:
2N/A case CKM_SHA224_RSA_PKCS:
2N/A case CKM_SHA256_RSA_PKCS:
2N/A case CKM_SHA384_RSA_PKCS:
2N/A case CKM_SHA512_RSA_PKCS:
2N/A
2N/A return (soft_rsa_digest_sign_common(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen, mechanism, B_FALSE));
2N/A
2N/A case CKM_DSA:
2N/A
2N/A return (soft_dsa_sign(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen));
2N/A
2N/A case CKM_DSA_SHA1:
2N/A
2N/A return (soft_dsa_digest_sign_common(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen, B_FALSE));
2N/A
2N/A case CKM_ECDSA:
2N/A
2N/A return (soft_ecc_sign(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen));
2N/A
2N/A case CKM_ECDSA_SHA1:
2N/A
2N/A return (soft_ecc_digest_sign_common(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen, B_FALSE));
2N/A
2N/A default:
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A}
2N/A
2N/A
2N/A/*
2N/A * soft_sign_update()
2N/A *
2N/A * Arguments:
2N/A * session_p: pointer to soft_session_t struct
2N/A * pPart: pointer to the input data to be signed
2N/A * ulPartLen: length of the input data
2N/A *
2N/A * Description:
2N/A * called by C_SignUpdate(). This function calls the corresponding
2N/A * sign update routine based on the mechanism.
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_sign_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
2N/A CK_ULONG ulPartLen)
2N/A{
2N/A CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism;
2N/A
2N/A switch (mechanism) {
2N/A
2N/A case CKM_SSL3_MD5_MAC:
2N/A case CKM_SSL3_SHA1_MAC:
2N/A case CKM_MD5_HMAC_GENERAL:
2N/A case CKM_MD5_HMAC:
2N/A case CKM_SHA_1_HMAC_GENERAL:
2N/A case CKM_SHA_1_HMAC:
2N/A case CKM_SHA224_HMAC_GENERAL:
2N/A case CKM_SHA224_HMAC:
2N/A case CKM_SHA256_HMAC_GENERAL:
2N/A case CKM_SHA256_HMAC:
2N/A case CKM_SHA384_HMAC_GENERAL:
2N/A case CKM_SHA384_HMAC:
2N/A case CKM_SHA512_HMAC_GENERAL:
2N/A case CKM_SHA512_HMAC:
2N/A
2N/A return (soft_hmac_sign_verify_update(session_p, pPart,
2N/A ulPartLen, B_TRUE));
2N/A
2N/A case CKM_DES_MAC_GENERAL:
2N/A case CKM_DES_MAC:
2N/A
2N/A return (soft_des_mac_sign_verify_update(session_p, pPart,
2N/A ulPartLen));
2N/A
2N/A case CKM_MD5_RSA_PKCS:
2N/A case CKM_SHA1_RSA_PKCS:
2N/A case CKM_SHA224_RSA_PKCS:
2N/A case CKM_SHA256_RSA_PKCS:
2N/A case CKM_SHA384_RSA_PKCS:
2N/A case CKM_SHA512_RSA_PKCS:
2N/A /*
2N/A * The MD5/SHA1 digest value is accumulated in the context
2N/A * of the multiple-part digesting operation. In the final
2N/A * operation, the digest is encoded and then perform RSA
2N/A * signing.
2N/A */
2N/A case CKM_DSA_SHA1:
2N/A case CKM_ECDSA_SHA1:
2N/A
2N/A return (soft_digest_update(session_p, pPart, ulPartLen));
2N/A
2N/A default:
2N/A /* PKCS11: The mechanism only supports single-part operation. */
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A}
2N/A
2N/A
2N/A/*
2N/A * soft_sign_final()
2N/A *
2N/A * Arguments:
2N/A * session_p: pointer to soft_session_t struct
2N/A * pSignature: pointer to the signature after signing
2N/A * pulSignatureLen: pointer to the length of the signature
2N/A *
2N/A * Description:
2N/A * called by C_SignFinal(). This function calls the corresponding
2N/A * sign final routine based on the mechanism.
2N/A *
2N/A */
2N/ACK_RV
2N/Asoft_sign_final(soft_session_t *session_p, CK_BYTE_PTR pSignature,
2N/A CK_ULONG_PTR pulSignatureLen)
2N/A{
2N/A
2N/A CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism;
2N/A CK_RV rv = CKR_OK;
2N/A
2N/A switch (mechanism) {
2N/A
2N/A case CKM_SSL3_MD5_MAC:
2N/A case CKM_SSL3_SHA1_MAC:
2N/A case CKM_MD5_HMAC_GENERAL:
2N/A case CKM_MD5_HMAC:
2N/A case CKM_SHA_1_HMAC_GENERAL:
2N/A case CKM_SHA_1_HMAC:
2N/A case CKM_SHA224_HMAC_GENERAL:
2N/A case CKM_SHA224_HMAC:
2N/A case CKM_SHA256_HMAC_GENERAL:
2N/A case CKM_SHA256_HMAC:
2N/A case CKM_SHA384_HMAC_GENERAL:
2N/A case CKM_SHA384_HMAC:
2N/A case CKM_SHA512_HMAC_GENERAL:
2N/A case CKM_SHA512_HMAC:
2N/A {
2N/A CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */
2N/A
2N/A if (pSignature != NULL) {
2N/A /* Pass local buffer to avoid overflow */
2N/A rv = soft_hmac_sign_verify_common(session_p, NULL,
2N/A 0, hmac, pulSignatureLen, B_TRUE);
2N/A } else {
2N/A /* Pass original pSignature, let callee to handle it. */
2N/A rv = soft_hmac_sign_verify_common(session_p, NULL,
2N/A 0, pSignature, pulSignatureLen, B_TRUE);
2N/A }
2N/A
2N/A if ((rv == CKR_OK) && (pSignature != NULL))
2N/A (void) memcpy(pSignature, hmac, *pulSignatureLen);
2N/A
2N/A return (rv);
2N/A }
2N/A case CKM_DES_MAC_GENERAL:
2N/A case CKM_DES_MAC:
2N/A {
2N/A CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
2N/A
2N/A if (pSignature != NULL) {
2N/A /* Pass local buffer to avoid overflow. */
2N/A rv = soft_des_sign_verify_common(session_p, NULL, 0,
2N/A signature, pulSignatureLen, B_TRUE, B_TRUE);
2N/A } else {
2N/A /* Pass NULL, let callee to handle it. */
2N/A rv = soft_des_sign_verify_common(session_p, NULL, 0,
2N/A NULL, pulSignatureLen, B_TRUE, B_TRUE);
2N/A }
2N/A
2N/A if ((rv == CKR_OK) && (pSignature != NULL))
2N/A (void) memcpy(pSignature, signature, *pulSignatureLen);
2N/A
2N/A return (rv);
2N/A }
2N/A case CKM_MD5_RSA_PKCS:
2N/A case CKM_SHA1_RSA_PKCS:
2N/A case CKM_SHA224_RSA_PKCS:
2N/A case CKM_SHA256_RSA_PKCS:
2N/A case CKM_SHA384_RSA_PKCS:
2N/A case CKM_SHA512_RSA_PKCS:
2N/A
2N/A return (soft_rsa_digest_sign_common(session_p, NULL, 0,
2N/A pSignature, pulSignatureLen, mechanism, B_TRUE));
2N/A
2N/A case CKM_DSA_SHA1:
2N/A
2N/A return (soft_dsa_digest_sign_common(session_p, NULL, 0,
2N/A pSignature, pulSignatureLen, B_TRUE));
2N/A
2N/A case CKM_ECDSA_SHA1:
2N/A
2N/A return (soft_ecc_digest_sign_common(session_p, NULL, 0,
2N/A pSignature, pulSignatureLen, B_TRUE));
2N/A
2N/A default:
2N/A /* PKCS11: The mechanism only supports single-part operation. */
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/Asoft_sign_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
2N/A soft_object_t *key_p)
2N/A{
2N/A
2N/A switch (pMechanism->mechanism) {
2N/A
2N/A case CKM_RSA_X_509:
2N/A case CKM_RSA_PKCS:
2N/A
2N/A return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
2N/A key_p, B_TRUE));
2N/A
2N/A default:
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A}
2N/A
2N/A
2N/ACK_RV
2N/Asoft_sign_recover(soft_session_t *session_p, CK_BYTE_PTR pData,
2N/A CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
2N/A CK_ULONG_PTR pulSignatureLen)
2N/A{
2N/A
2N/A CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism;
2N/A
2N/A switch (mechanism) {
2N/A
2N/A case CKM_RSA_X_509:
2N/A case CKM_RSA_PKCS:
2N/A
2N/A return (soft_rsa_sign_common(session_p, pData, ulDataLen,
2N/A pSignature, pulSignatureLen, mechanism));
2N/A
2N/A default:
2N/A return (CKR_MECHANISM_INVALID);
2N/A }
2N/A}
2N/A
2N/A/*
2N/A * This function frees the allocated active crypto context.
2N/A * It is only called by the first tier of sign/verify routines
2N/A * and the caller of this function may or may not hold the session mutex.
2N/A */
2N/Avoid
2N/Asoft_sign_verify_cleanup(soft_session_t *session_p, boolean_t sign,
2N/A boolean_t lock_held)
2N/A{
2N/A
2N/A crypto_active_op_t *active_op;
2N/A boolean_t lock_true = B_TRUE;
2N/A
2N/A if (!lock_held)
2N/A (void) pthread_mutex_lock(&session_p->session_mutex);
2N/A
2N/A active_op = (sign) ? &(session_p->sign) : &(session_p->verify);
2N/A
2N/A switch (active_op->mech.mechanism) {
2N/A
2N/A case CKM_MD5_RSA_PKCS:
2N/A case CKM_SHA1_RSA_PKCS:
2N/A case CKM_SHA224_RSA_PKCS:
2N/A case CKM_SHA256_RSA_PKCS:
2N/A case CKM_SHA384_RSA_PKCS:
2N/A case CKM_SHA512_RSA_PKCS:
2N/A if (session_p->digest.context != NULL) {
2N/A free(session_p->digest.context);
2N/A session_p->digest.context = NULL;
2N/A session_p->digest.flags = 0;
2N/A }
2N/A /* FALLTHRU */
2N/A
2N/A case CKM_RSA_PKCS:
2N/A case CKM_RSA_X_509:
2N/A {
2N/A soft_rsa_ctx_t *rsa_ctx =
2N/A (soft_rsa_ctx_t *)active_op->context;
2N/A
2N/A if (rsa_ctx != NULL && rsa_ctx->key != NULL) {
2N/A soft_cleanup_object(rsa_ctx->key);
2N/A free(rsa_ctx->key);
2N/A }
2N/A break;
2N/A
2N/A }
2N/A case CKM_DSA_SHA1:
2N/A if (session_p->digest.context != NULL) {
2N/A free(session_p->digest.context);
2N/A session_p->digest.context = NULL;
2N/A session_p->digest.flags = 0;
2N/A }
2N/A
2N/A /* FALLTHRU */
2N/A case CKM_DSA:
2N/A {
2N/A soft_dsa_ctx_t *dsa_ctx =
2N/A (soft_dsa_ctx_t *)active_op->context;
2N/A
2N/A if (dsa_ctx != NULL && dsa_ctx->key != NULL) {
2N/A soft_cleanup_object(dsa_ctx->key);
2N/A free(dsa_ctx->key);
2N/A }
2N/A break;
2N/A
2N/A }
2N/A case CKM_SSL3_MD5_MAC:
2N/A case CKM_SSL3_SHA1_MAC:
2N/A case CKM_MD5_HMAC_GENERAL:
2N/A case CKM_MD5_HMAC:
2N/A case CKM_SHA_1_HMAC_GENERAL:
2N/A case CKM_SHA_1_HMAC:
2N/A case CKM_SHA224_HMAC_GENERAL:
2N/A case CKM_SHA224_HMAC:
2N/A case CKM_SHA256_HMAC_GENERAL:
2N/A case CKM_SHA256_HMAC:
2N/A case CKM_SHA384_HMAC_GENERAL:
2N/A case CKM_SHA384_HMAC:
2N/A case CKM_SHA512_HMAC_GENERAL:
2N/A case CKM_SHA512_HMAC:
2N/A if (active_op->context != NULL)
2N/A bzero(active_op->context, sizeof (soft_hmac_ctx_t));
2N/A break;
2N/A case CKM_DES_MAC_GENERAL:
2N/A case CKM_DES_MAC:
2N/A if (session_p->encrypt.context != NULL) {
2N/A free(session_p->encrypt.context);
2N/A session_p->encrypt.context = NULL;
2N/A session_p->encrypt.flags = 0;
2N/A }
2N/A if (active_op->context != NULL)
2N/A bzero(active_op->context, sizeof (soft_des_ctx_t));
2N/A break;
2N/A
2N/A }
2N/A
2N/A if (active_op->context != NULL) {
2N/A free(active_op->context);
2N/A active_op->context = NULL;
2N/A }
2N/A
2N/A active_op->flags = 0;
2N/A
2N/A if (!lock_held)
2N/A SES_REFRELE(session_p, lock_true);
2N/A}