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