1*12573SDina.Nimeh@Sun.COM /* 2*12573SDina.Nimeh@Sun.COM * CDDL HEADER START 3*12573SDina.Nimeh@Sun.COM * 4*12573SDina.Nimeh@Sun.COM * The contents of this file are subject to the terms of the 5*12573SDina.Nimeh@Sun.COM * Common Development and Distribution License (the "License"). 6*12573SDina.Nimeh@Sun.COM * You may not use this file except in compliance with the License. 7*12573SDina.Nimeh@Sun.COM * 8*12573SDina.Nimeh@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*12573SDina.Nimeh@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*12573SDina.Nimeh@Sun.COM * See the License for the specific language governing permissions 11*12573SDina.Nimeh@Sun.COM * and limitations under the License. 12*12573SDina.Nimeh@Sun.COM * 13*12573SDina.Nimeh@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*12573SDina.Nimeh@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*12573SDina.Nimeh@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*12573SDina.Nimeh@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*12573SDina.Nimeh@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*12573SDina.Nimeh@Sun.COM * 19*12573SDina.Nimeh@Sun.COM * CDDL HEADER END 20*12573SDina.Nimeh@Sun.COM */ 21*12573SDina.Nimeh@Sun.COM 22*12573SDina.Nimeh@Sun.COM /* 23*12573SDina.Nimeh@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24*12573SDina.Nimeh@Sun.COM */ 25*12573SDina.Nimeh@Sun.COM 26*12573SDina.Nimeh@Sun.COM #include <sys/types.h> 27*12573SDina.Nimeh@Sun.COM #include <sys/sha1.h> 28*12573SDina.Nimeh@Sun.COM #define _SHA2_IMPL 29*12573SDina.Nimeh@Sun.COM #include <sys/sha2.h> 30*12573SDina.Nimeh@Sun.COM 31*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL 32*12573SDina.Nimeh@Sun.COM #include <sys/param.h> 33*12573SDina.Nimeh@Sun.COM #include <sys/kmem.h> 34*12573SDina.Nimeh@Sun.COM #else 35*12573SDina.Nimeh@Sun.COM #include <strings.h> 36*12573SDina.Nimeh@Sun.COM #include <cryptoutil.h> 37*12573SDina.Nimeh@Sun.COM #include "softMAC.h" 38*12573SDina.Nimeh@Sun.COM #endif 39*12573SDina.Nimeh@Sun.COM 40*12573SDina.Nimeh@Sun.COM #include <security/cryptoki.h> 41*12573SDina.Nimeh@Sun.COM #include <sys/crypto/common.h> 42*12573SDina.Nimeh@Sun.COM 43*12573SDina.Nimeh@Sun.COM #include <sha1/sha1_impl.h> 44*12573SDina.Nimeh@Sun.COM #define _DSA_FIPS_POST 45*12573SDina.Nimeh@Sun.COM #include <dsa/dsa_impl.h> 46*12573SDina.Nimeh@Sun.COM 47*12573SDina.Nimeh@Sun.COM 48*12573SDina.Nimeh@Sun.COM /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ 49*12573SDina.Nimeh@Sun.COM static uint8_t dsa_P[] = { 50*12573SDina.Nimeh@Sun.COM 0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28, 51*12573SDina.Nimeh@Sun.COM 0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63, 52*12573SDina.Nimeh@Sun.COM 0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0, 53*12573SDina.Nimeh@Sun.COM 0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c, 54*12573SDina.Nimeh@Sun.COM 0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91, 55*12573SDina.Nimeh@Sun.COM 0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0, 56*12573SDina.Nimeh@Sun.COM 0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7, 57*12573SDina.Nimeh@Sun.COM 0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63, 58*12573SDina.Nimeh@Sun.COM 0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7, 59*12573SDina.Nimeh@Sun.COM 0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56, 60*12573SDina.Nimeh@Sun.COM 0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b, 61*12573SDina.Nimeh@Sun.COM 0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4, 62*12573SDina.Nimeh@Sun.COM 0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6, 63*12573SDina.Nimeh@Sun.COM 0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64, 64*12573SDina.Nimeh@Sun.COM 0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a, 65*12573SDina.Nimeh@Sun.COM 0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15 66*12573SDina.Nimeh@Sun.COM }; 67*12573SDina.Nimeh@Sun.COM 68*12573SDina.Nimeh@Sun.COM static uint8_t dsa_Q[] = { 69*12573SDina.Nimeh@Sun.COM 0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e, 70*12573SDina.Nimeh@Sun.COM 0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6, 71*12573SDina.Nimeh@Sun.COM 0x91, 0x99, 0x8b, 0xcf 72*12573SDina.Nimeh@Sun.COM }; 73*12573SDina.Nimeh@Sun.COM 74*12573SDina.Nimeh@Sun.COM static uint8_t dsa_G[] = { 75*12573SDina.Nimeh@Sun.COM 0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4, 76*12573SDina.Nimeh@Sun.COM 0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6, 77*12573SDina.Nimeh@Sun.COM 0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3, 78*12573SDina.Nimeh@Sun.COM 0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17, 79*12573SDina.Nimeh@Sun.COM 0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d, 80*12573SDina.Nimeh@Sun.COM 0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a, 81*12573SDina.Nimeh@Sun.COM 0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24, 82*12573SDina.Nimeh@Sun.COM 0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25, 83*12573SDina.Nimeh@Sun.COM 0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb, 84*12573SDina.Nimeh@Sun.COM 0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79, 85*12573SDina.Nimeh@Sun.COM 0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac, 86*12573SDina.Nimeh@Sun.COM 0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25, 87*12573SDina.Nimeh@Sun.COM 0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27, 88*12573SDina.Nimeh@Sun.COM 0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed, 89*12573SDina.Nimeh@Sun.COM 0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f, 90*12573SDina.Nimeh@Sun.COM 0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38 91*12573SDina.Nimeh@Sun.COM }; 92*12573SDina.Nimeh@Sun.COM 93*12573SDina.Nimeh@Sun.COM /* 94*12573SDina.Nimeh@Sun.COM * DSA Known Random Values (known random key block is 160-bits) 95*12573SDina.Nimeh@Sun.COM * and (known random signature block is 160-bits). 96*12573SDina.Nimeh@Sun.COM */ 97*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_key_block[] = { 98*12573SDina.Nimeh@Sun.COM "This is DSA RNG key!" 99*12573SDina.Nimeh@Sun.COM }; 100*12573SDina.Nimeh@Sun.COM 101*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_signature_block[] = { 102*12573SDina.Nimeh@Sun.COM "Random DSA Signature" 103*12573SDina.Nimeh@Sun.COM }; 104*12573SDina.Nimeh@Sun.COM 105*12573SDina.Nimeh@Sun.COM /* DSA Known Digest (160-bits) */ 106*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_digest[] = { 107*12573SDina.Nimeh@Sun.COM "DSA Signature Digest" 108*12573SDina.Nimeh@Sun.COM }; 109*12573SDina.Nimeh@Sun.COM 110*12573SDina.Nimeh@Sun.COM /* DSA Known Signature (320-bits). */ 111*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_signature[] = { 112*12573SDina.Nimeh@Sun.COM 0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32, 113*12573SDina.Nimeh@Sun.COM 0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c, 114*12573SDina.Nimeh@Sun.COM 0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a, 115*12573SDina.Nimeh@Sun.COM 0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc, 116*12573SDina.Nimeh@Sun.COM 0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75 117*12573SDina.Nimeh@Sun.COM 118*12573SDina.Nimeh@Sun.COM }; 119*12573SDina.Nimeh@Sun.COM 120*12573SDina.Nimeh@Sun.COM 121*12573SDina.Nimeh@Sun.COM static int 122*12573SDina.Nimeh@Sun.COM fips_dsa_random_func(void *buf, size_t buflen) 123*12573SDina.Nimeh@Sun.COM { 124*12573SDina.Nimeh@Sun.COM /* should not happen */ 125*12573SDina.Nimeh@Sun.COM if (buflen != FIPS_DSA_SEED_LENGTH) 126*12573SDina.Nimeh@Sun.COM return (-1); 127*12573SDina.Nimeh@Sun.COM 128*12573SDina.Nimeh@Sun.COM (void) memcpy(buf, dsa_known_random_key_block, 129*12573SDina.Nimeh@Sun.COM FIPS_DSA_SEED_LENGTH); 130*12573SDina.Nimeh@Sun.COM return (0); 131*12573SDina.Nimeh@Sun.COM } 132*12573SDina.Nimeh@Sun.COM 133*12573SDina.Nimeh@Sun.COM static int 134*12573SDina.Nimeh@Sun.COM fips_dsa_signature_func(void *buf, size_t buflen) 135*12573SDina.Nimeh@Sun.COM { 136*12573SDina.Nimeh@Sun.COM /* should not happen */ 137*12573SDina.Nimeh@Sun.COM if (buflen != FIPS_DSA_SEED_LENGTH) 138*12573SDina.Nimeh@Sun.COM return (-1); 139*12573SDina.Nimeh@Sun.COM 140*12573SDina.Nimeh@Sun.COM (void) memcpy(buf, dsa_known_random_signature_block, 141*12573SDina.Nimeh@Sun.COM FIPS_DSA_SEED_LENGTH); 142*12573SDina.Nimeh@Sun.COM return (0); 143*12573SDina.Nimeh@Sun.COM } 144*12573SDina.Nimeh@Sun.COM 145*12573SDina.Nimeh@Sun.COM int 146*12573SDina.Nimeh@Sun.COM fips_dsa_genkey_pair(DSAbytekey *bkey) 147*12573SDina.Nimeh@Sun.COM { 148*12573SDina.Nimeh@Sun.COM return (dsa_genkey_pair(bkey)); 149*12573SDina.Nimeh@Sun.COM } 150*12573SDina.Nimeh@Sun.COM 151*12573SDina.Nimeh@Sun.COM int 152*12573SDina.Nimeh@Sun.COM fips_dsa_digest_sign(DSAbytekey *bkey, 153*12573SDina.Nimeh@Sun.COM uint8_t *in, uint32_t inlen, uint8_t *out) 154*12573SDina.Nimeh@Sun.COM { 155*12573SDina.Nimeh@Sun.COM CK_RV rv; 156*12573SDina.Nimeh@Sun.COM SHA1_CTX *sha1_context; 157*12573SDina.Nimeh@Sun.COM uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH]; 158*12573SDina.Nimeh@Sun.COM 159*12573SDina.Nimeh@Sun.COM sha1_context = fips_sha1_build_context(); 160*12573SDina.Nimeh@Sun.COM if (sha1_context == NULL) 161*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY); 162*12573SDina.Nimeh@Sun.COM 163*12573SDina.Nimeh@Sun.COM rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest); 164*12573SDina.Nimeh@Sun.COM if (rv != CKR_OK) 165*12573SDina.Nimeh@Sun.COM goto clean1; 166*12573SDina.Nimeh@Sun.COM 167*12573SDina.Nimeh@Sun.COM rv = dsa_sign(bkey, sha1_computed_digest, FIPS_DSA_DIGEST_LENGTH, out); 168*12573SDina.Nimeh@Sun.COM 169*12573SDina.Nimeh@Sun.COM clean1: 170*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL 171*12573SDina.Nimeh@Sun.COM kmem_free(sha1_context, sizeof (SHA1_CTX)); 172*12573SDina.Nimeh@Sun.COM #else 173*12573SDina.Nimeh@Sun.COM free(sha1_context); 174*12573SDina.Nimeh@Sun.COM #endif 175*12573SDina.Nimeh@Sun.COM return (rv); 176*12573SDina.Nimeh@Sun.COM } 177*12573SDina.Nimeh@Sun.COM 178*12573SDina.Nimeh@Sun.COM int 179*12573SDina.Nimeh@Sun.COM fips_dsa_verify(DSAbytekey *bkey, uint8_t *data, uint8_t *sig) 180*12573SDina.Nimeh@Sun.COM { 181*12573SDina.Nimeh@Sun.COM CK_RV rv; 182*12573SDina.Nimeh@Sun.COM SHA1_CTX *sha1_context; 183*12573SDina.Nimeh@Sun.COM uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH]; 184*12573SDina.Nimeh@Sun.COM 185*12573SDina.Nimeh@Sun.COM sha1_context = fips_sha1_build_context(); 186*12573SDina.Nimeh@Sun.COM if (sha1_context == NULL) 187*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY); 188*12573SDina.Nimeh@Sun.COM 189*12573SDina.Nimeh@Sun.COM rv = fips_sha1_hash(sha1_context, data, FIPS_DSA_DIGEST_LENGTH, 190*12573SDina.Nimeh@Sun.COM sha1_computed_digest); 191*12573SDina.Nimeh@Sun.COM if (rv != CKR_OK) 192*12573SDina.Nimeh@Sun.COM goto clean1; 193*12573SDina.Nimeh@Sun.COM 194*12573SDina.Nimeh@Sun.COM rv = dsa_verify(bkey, sha1_computed_digest, sig); 195*12573SDina.Nimeh@Sun.COM 196*12573SDina.Nimeh@Sun.COM clean1: 197*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL 198*12573SDina.Nimeh@Sun.COM kmem_free(sha1_context, sizeof (SHA1_CTX)); 199*12573SDina.Nimeh@Sun.COM #else 200*12573SDina.Nimeh@Sun.COM free(sha1_context); 201*12573SDina.Nimeh@Sun.COM #endif 202*12573SDina.Nimeh@Sun.COM return (rv); 203*12573SDina.Nimeh@Sun.COM } 204*12573SDina.Nimeh@Sun.COM 205*12573SDina.Nimeh@Sun.COM /* 206*12573SDina.Nimeh@Sun.COM * DSA Power-On SelfTest(s). 207*12573SDina.Nimeh@Sun.COM */ 208*12573SDina.Nimeh@Sun.COM int 209*12573SDina.Nimeh@Sun.COM fips_dsa_post(void) 210*12573SDina.Nimeh@Sun.COM { 211*12573SDina.Nimeh@Sun.COM DSAbytekey dsa_params; 212*12573SDina.Nimeh@Sun.COM CK_RV rv; 213*12573SDina.Nimeh@Sun.COM uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH]; 214*12573SDina.Nimeh@Sun.COM 215*12573SDina.Nimeh@Sun.COM /* 216*12573SDina.Nimeh@Sun.COM * Generate a DSA public/private key pair. 217*12573SDina.Nimeh@Sun.COM */ 218*12573SDina.Nimeh@Sun.COM dsa_params.prime = dsa_P; 219*12573SDina.Nimeh@Sun.COM dsa_params.prime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_PRIME_LENGTH); 220*12573SDina.Nimeh@Sun.COM dsa_params.subprime = dsa_Q; 221*12573SDina.Nimeh@Sun.COM dsa_params.subprime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_SUBPRIME_LENGTH); 222*12573SDina.Nimeh@Sun.COM dsa_params.base = dsa_G; 223*12573SDina.Nimeh@Sun.COM dsa_params.base_bytes = FIPS_DSA_BASE_LENGTH; 224*12573SDina.Nimeh@Sun.COM 225*12573SDina.Nimeh@Sun.COM dsa_params.rfunc = fips_dsa_random_func; 226*12573SDina.Nimeh@Sun.COM 227*12573SDina.Nimeh@Sun.COM rv = fips_dsa_genkey_pair(&dsa_params); 228*12573SDina.Nimeh@Sun.COM if (rv != CKR_OK) 229*12573SDina.Nimeh@Sun.COM return (CKR_DEVICE_ERROR); 230*12573SDina.Nimeh@Sun.COM 231*12573SDina.Nimeh@Sun.COM /* 232*12573SDina.Nimeh@Sun.COM * DSA Known Answer Signature Test 233*12573SDina.Nimeh@Sun.COM */ 234*12573SDina.Nimeh@Sun.COM 235*12573SDina.Nimeh@Sun.COM dsa_params.rfunc = fips_dsa_signature_func; 236*12573SDina.Nimeh@Sun.COM 237*12573SDina.Nimeh@Sun.COM /* Perform DSA signature process. */ 238*12573SDina.Nimeh@Sun.COM rv = fips_dsa_digest_sign(&dsa_params, 239*12573SDina.Nimeh@Sun.COM dsa_known_digest, FIPS_DSA_DIGEST_LENGTH, dsa_computed_signature); 240*12573SDina.Nimeh@Sun.COM 241*12573SDina.Nimeh@Sun.COM if ((rv != CKR_OK) || 242*12573SDina.Nimeh@Sun.COM (memcmp(dsa_computed_signature, dsa_known_signature, 243*12573SDina.Nimeh@Sun.COM FIPS_DSA_SIGNATURE_LENGTH) != 0)) { 244*12573SDina.Nimeh@Sun.COM goto clean; 245*12573SDina.Nimeh@Sun.COM } 246*12573SDina.Nimeh@Sun.COM 247*12573SDina.Nimeh@Sun.COM /* 248*12573SDina.Nimeh@Sun.COM * DSA Known Answer Verification Test 249*12573SDina.Nimeh@Sun.COM */ 250*12573SDina.Nimeh@Sun.COM 251*12573SDina.Nimeh@Sun.COM /* Perform DSA verification process. */ 252*12573SDina.Nimeh@Sun.COM rv = fips_dsa_verify(&dsa_params, 253*12573SDina.Nimeh@Sun.COM dsa_known_digest, dsa_computed_signature); 254*12573SDina.Nimeh@Sun.COM 255*12573SDina.Nimeh@Sun.COM clean: 256*12573SDina.Nimeh@Sun.COM if (rv != CKR_OK) 257*12573SDina.Nimeh@Sun.COM return (CKR_DEVICE_ERROR); 258*12573SDina.Nimeh@Sun.COM else 259*12573SDina.Nimeh@Sun.COM return (CKR_OK); 260*12573SDina.Nimeh@Sun.COM } 261