1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/errno.h> 28 #include <sys/fcntl.h> 29 #include <sys/time.h> 30 #include <sys/unistd.h> 31 #include <sys/kmem.h> 32 #include <sys/systm.h> 33 #include <sys/sysmacros.h> 34 #include <sys/sha1.h> 35 #define _SHA2_IMPL 36 #include <sys/sha2.h> 37 #include <sys/crypto/common.h> 38 #include <modes/modes.h> 39 #include <bignum.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <strings.h> 43 #include <stdio.h> 44 #include <security/cryptoki.h> 45 #include <cryptoutil.h> 46 #include "softCrypt.h" 47 #include "softGlobal.h" 48 #include "softRSA.h" 49 #include "softDSA.h" 50 #include "softRandom.h" 51 #include "softOps.h" 52 #include "softMAC.h" 53 #include <fips_post.h> 54 55 #define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ 56 #define MAX_ECKEY_LEN 72 57 58 59 /* 60 * FIPS 140-2 pairwise consistency check utilized to validate key pair. 61 * 62 * This function returns 63 * CKR_OK if pairwise consistency check passed 64 * CKR_GENERAL_ERROR if pairwise consistency check failed 65 * other error codes if paiswise consistency check could not be 66 * performed, for example, CKR_HOST_MEMORY. 67 * 68 * Key type Mechanism type 69 * -------------------------------- 70 * 71 * For sign/verify: CKK_RSA => CKM_SHA1_RSA_PKCS 72 * CKK_DSA => CKM_DSA_SHA1 73 * CKK_EC => CKM_ECDSA_SHA1 74 * others => CKM_INVALID_MECHANISM 75 * 76 * None of these mechanisms has a parameter. 77 */ 78 CK_RV 79 fips_pairwise_check(soft_session_t *session_p, 80 soft_object_t *publicKey, soft_object_t *privateKey, 81 CK_KEY_TYPE keyType) 82 { 83 84 CK_MECHANISM mech = {0, NULL, 0}; 85 uchar_t modulus[MAX_KEY_ATTR_BUFLEN]; 86 uint32_t modulus_len = sizeof (modulus); 87 boolean_t can_sign_verify = B_FALSE; 88 CK_RV rv; 89 90 /* Variables used for Signature/Verification functions. */ 91 /* always uses SHA-1 digest */ 92 unsigned char *known_digest = (unsigned char *)"OpenSolarisCommunity"; 93 unsigned char *signature; 94 CK_ULONG signature_length; 95 96 if (keyType == CKK_RSA) { 97 /* Get modulus length of private key. */ 98 rv = soft_get_private_value(privateKey, CKA_MODULUS, 99 modulus, &modulus_len); 100 if (rv != CKR_OK) { 101 return (CKR_DEVICE_ERROR); 102 } 103 } 104 105 /* 106 * Pairwise Consistency Check of Sign/Verify 107 */ 108 109 /* Check to see if key object supports signature. */ 110 can_sign_verify = (privateKey->bool_attr_mask & SIGN_BOOL_ON); 111 112 if (can_sign_verify) { 113 /* Determine length of signature. */ 114 switch (keyType) { 115 case CKK_RSA: 116 signature_length = modulus_len; 117 mech.mechanism = CKM_SHA1_RSA_PKCS; 118 break; 119 120 case CKK_DSA: 121 signature_length = FIPS_DSA_SIGNATURE_LENGTH; 122 mech.mechanism = CKM_DSA_SHA1; 123 break; 124 125 case CKK_EC: 126 signature_length = MAX_ECKEY_LEN * 2; 127 mech.mechanism = CKM_ECDSA_SHA1; 128 break; 129 130 default: 131 return (CKR_DEVICE_ERROR); 132 } 133 134 /* Allocate space for signature data. */ 135 signature = (unsigned char *) calloc(1, signature_length); 136 if (signature == NULL) { 137 return (CKR_HOST_MEMORY); 138 } 139 140 /* Sign the known hash using the private key. */ 141 rv = soft_sign_init(session_p, &mech, privateKey); 142 if (rv != CKR_OK) { 143 free(signature); 144 return (rv); 145 } 146 147 rv = soft_sign(session_p, known_digest, PAIRWISE_DIGEST_LENGTH, 148 signature, &signature_length); 149 if (rv != CKR_OK) { 150 free(signature); 151 return (rv); 152 } 153 154 /* Verify the known hash using the public key. */ 155 rv = soft_verify_init(session_p, &mech, publicKey); 156 if (rv != CKR_OK) { 157 free(signature); 158 return (rv); 159 } 160 161 rv = soft_verify(session_p, known_digest, 162 PAIRWISE_DIGEST_LENGTH, signature, 163 signature_length); 164 165 /* Free signature data. */ 166 free(signature); 167 if ((rv == CKR_SIGNATURE_LEN_RANGE) || 168 (rv == CKR_SIGNATURE_INVALID)) { 169 return (CKR_GENERAL_ERROR); 170 } 171 172 if (rv != CKR_OK) { 173 return (rv); 174 } 175 } 176 177 return (CKR_OK); 178 } 179