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) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <sys/types.h>
2N/A#include <sys/errno.h>
2N/A#include <sys/fcntl.h>
2N/A#include <sys/time.h>
2N/A#include <sys/unistd.h>
2N/A#include <sys/kmem.h>
2N/A#include <sys/systm.h>
2N/A#include <sys/sysmacros.h>
2N/A#include <sys/sha1.h>
2N/A#define _SHA2_IMPL
2N/A#include <sys/sha2.h>
2N/A#include <sys/crypto/common.h>
2N/A#include <modes/modes.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <strings.h>
2N/A#include <stdio.h>
2N/A#include <security/cryptoki.h>
2N/A#include <cryptoutil.h>
2N/A#include "softCrypt.h"
2N/A#include "softGlobal.h"
2N/A#include "softRSA.h"
2N/A#include "softDSA.h"
2N/A#include "softOps.h"
2N/A#include "softMAC.h"
2N/A#include <fips/fips_post.h>
2N/A
2N/A#define MAX_ECKEY_LEN 72
2N/A
2N/A
2N/A/*
2N/A * FIPS 140-2 pairwise consistency check utilized to validate key pair.
2N/A *
2N/A * This function returns
2N/A * CKR_OK if pairwise consistency check passed
2N/A * CKR_GENERAL_ERROR if pairwise consistency check failed
2N/A * other error codes if pairwise consistency check could not be
2N/A * performed, for example, CKR_HOST_MEMORY.
2N/A *
2N/A * Key type Mechanism type
2N/A * --------------------------------
2N/A *
2N/A * For sign/verify: CKK_RSA => CKM_SHA1_RSA_PKCS
2N/A * CKK_DSA => CKM_DSA_SHA1
2N/A * CKK_EC => CKM_ECDSA_SHA1
2N/A * others => CKM_INVALID_MECHANISM
2N/A *
2N/A * None of these mechanisms has a parameter.
2N/A */
2N/ACK_RV
2N/Afips_pairwise_check(soft_session_t *session_p,
2N/A soft_object_t *publicKey, soft_object_t *privateKey,
2N/A CK_KEY_TYPE keyType)
2N/A{
2N/A
2N/A CK_MECHANISM mech = {0, NULL, 0};
2N/A uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
2N/A uint32_t modulus_len = sizeof (modulus);
2N/A boolean_t can_sign_verify = B_FALSE;
2N/A CK_RV rv;
2N/A
2N/A /* Variables used for Signature/Verification functions. */
2N/A /* always uses SHA-1 digest */
2N/A unsigned char *known_digest = (unsigned char *)"OpenSolarisCommunity";
2N/A unsigned char *signature;
2N/A CK_ULONG signature_length;
2N/A
2N/A if (keyType == CKK_RSA) {
2N/A /* Get modulus length of private key. */
2N/A rv = soft_get_private_value(privateKey, CKA_MODULUS,
2N/A modulus, &modulus_len);
2N/A if (rv != CKR_OK) {
2N/A return (CKR_DEVICE_ERROR);
2N/A }
2N/A }
2N/A
2N/A /*
2N/A * Pairwise Consistency Check of Sign/Verify
2N/A */
2N/A
2N/A /* Check to see if key object supports signature. */
2N/A can_sign_verify = (privateKey->bool_attr_mask & SIGN_BOOL_ON);
2N/A
2N/A if (can_sign_verify) {
2N/A /* Determine length of signature. */
2N/A switch (keyType) {
2N/A case CKK_RSA:
2N/A signature_length = modulus_len;
2N/A mech.mechanism = CKM_SHA1_RSA_PKCS;
2N/A break;
2N/A
2N/A case CKK_DSA:
2N/A signature_length = FIPS_DSA_SIGNATURE_LENGTH;
2N/A mech.mechanism = CKM_DSA_SHA1;
2N/A break;
2N/A
2N/A case CKK_EC:
2N/A signature_length = MAX_ECKEY_LEN * 2;
2N/A mech.mechanism = CKM_ECDSA_SHA1;
2N/A break;
2N/A
2N/A default:
2N/A return (CKR_DEVICE_ERROR);
2N/A }
2N/A
2N/A /* Allocate space for signature data. */
2N/A signature = (unsigned char *) calloc(1, signature_length);
2N/A if (signature == NULL) {
2N/A return (CKR_HOST_MEMORY);
2N/A }
2N/A
2N/A /* Sign the known hash using the private key. */
2N/A rv = soft_sign_init(session_p, &mech, privateKey);
2N/A if (rv != CKR_OK) {
2N/A free(signature);
2N/A return (rv);
2N/A }
2N/A
2N/A rv = soft_sign(session_p, known_digest, PAIRWISE_DIGEST_LENGTH,
2N/A signature, &signature_length);
2N/A if (rv != CKR_OK) {
2N/A free(signature);
2N/A return (rv);
2N/A }
2N/A
2N/A /* Verify the known hash using the public key. */
2N/A rv = soft_verify_init(session_p, &mech, publicKey);
2N/A if (rv != CKR_OK) {
2N/A free(signature);
2N/A return (rv);
2N/A }
2N/A
2N/A rv = soft_verify(session_p, known_digest,
2N/A PAIRWISE_DIGEST_LENGTH, signature,
2N/A signature_length);
2N/A
2N/A /* Free signature data. */
2N/A free(signature);
2N/A if ((rv == CKR_SIGNATURE_LEN_RANGE) ||
2N/A (rv == CKR_SIGNATURE_INVALID)) {
2N/A return (CKR_GENERAL_ERROR);
2N/A }
2N/A
2N/A if (rv != CKR_OK) {
2N/A return (rv);
2N/A }
2N/A }
2N/A
2N/A return (CKR_OK);
2N/A}