1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "ossl-config.h" 25 26#include <stdio.h> 27#include <stdlib.h> 28#include <assert.h> 29 30#include "krb5-types.h" 31#include "rfc2459_asn1.h" 32 33#include "ossl-dsa.h" 34#include "ossl-common.h" 35 36/* #include "rk-roken.h" */ 37 38#ifdef HAVE_CDSA 39 40/* 41 * 42 */ 43 44#if 0 45 46static int 47load_key(CSSM_CSP_HANDLE cspHandle, DSA *dsa, int use_public, CSSM_KEY_PTR key, size_t *keysize) 48{ 49 CSSM_KEY_SIZE keySize; 50 CSSM_RETURN ret; 51 size_t size; 52 53 memset(key, 0, sizeof(*key)); 54 55 if (use_public) { 56 DSAPublicKey k; 57 58 memset(&k, 0, sizeof(k)); 59 60 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 61 if (ret == 0) { 62 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 63 } 64 if (ret) { 65 free_RSAPublicKey(&k); 66 return (0); 67 } 68 69 ASN1_MALLOC_ENCODE(RSAPublicKey, key->KeyData.Data, key->KeyData.Length, 70 &k, &size, ret); 71 free_RSAPublicKey(&k); 72 if (ret) { 73 return (1); 74 } 75 if (size != key->KeyData.Length) { 76 abort(); 77 } 78 } else { 79 RSAPrivateKey k; 80 81 memset(&k, 0, sizeof(k)); 82 83 k.version = 1; 84 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 85 if (ret == 0) { 86 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 87 } 88 if (ret == 0) { 89 ret = _cs_BN_to_integer(rsa->d, &k.privateExponent); 90 } 91 if (ret == 0) { 92 ret = _cs_BN_to_integer(rsa->p, &k.prime1); 93 } 94 if (ret == 0) { 95 ret = _cs_BN_to_integer(rsa->q, &k.prime2); 96 } 97 if (ret == 0) { 98 ret = _cs_BN_to_integer(rsa->dmp1, &k.exponent1); 99 } 100 if (ret == 0) { 101 ret = _cs_BN_to_integer(rsa->dmq1, &k.exponent2); 102 } 103 if (ret == 0) { 104 ret = _cs_BN_to_integer(rsa->iqmp, &k.coefficient); 105 } 106 if (ret) { 107 free_RSAPrivateKey(&k); 108 return (1); 109 } 110 111 ASN1_MALLOC_ENCODE(RSAPrivateKey, key->KeyData.Data, key->KeyData.Length, 112 &k, &size, ret); 113 free_RSAPrivateKey(&k); 114 if (ret) { 115 return (1); 116 } 117 if (size != key->KeyData.Length) { 118 abort(); 119 } 120 } 121 122 key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; 123 key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW; 124 key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; 125 key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA; 126 key->KeyHeader.KeyClass = use_public ? 127 CSSM_KEYCLASS_PUBLIC_KEY : 128 CSSM_KEYCLASS_PRIVATE_KEY; 129 key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; 130 key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; 131 132 ret = CSSM_QueryKeySizeInBits(cspHandle, 0, key, &keySize); 133 if (ret) { 134 return (1); 135 } 136 137 key->KeyHeader.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits; 138 139 *keysize = (keySize.LogicalKeySizeInBits + 7) / 8; 140 141 return (0); 142} 143 144 145static void 146unload_key(CSSM_KEY_PTR key) 147{ 148 free(key->KeyData.Data); 149 memset(key, 0, sizeof(*key)); 150} 151 152 153typedef CSSM_RETURN (*op)(CSSM_CC_HANDLE, const CSSM_DATA *, 154 uint32, CSSM_DATA_PTR, uint32, 155 CSSM_SIZE *, CSSM_DATA_PTR); 156 157 158static int 159perform_rsa_op(int flen, const unsigned char *from, 160 unsigned char *to, RSA *rsa, int padding, 161 CSSM_ENCRYPT_MODE algMode, op func) 162{ 163 CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle(); 164 CSSM_RETURN cret; 165 CSSM_ACCESS_CREDENTIALS creds; 166 CSSM_KEY cssmKey; 167 CSSM_CC_HANDLE handle = 0; 168 CSSM_DATA out, in, rem; 169 int fret = 0; 170 CSSM_SIZE outlen = 0; 171 char remdata[1024]; 172 size_t keysize; 173 174 if (padding != RSA_PKCS1_PADDING) { 175 return (-1); 176 } 177 178 memset(&creds, 0, sizeof(creds)); 179 180 fret = load_key(cspHandle, rsa, (algMode == CSSM_ALGMODE_PUBLIC_KEY), 181 &cssmKey, &keysize); 182 if (fret) { 183 return (-2); 184 } 185 186 fret = CSSM_CSP_CreateAsymmetricContext(cspHandle, 187 CSSM_ALGID_RSA, 188 &creds, 189 &cssmKey, 190 CSSM_PADDING_PKCS1, 191 &handle); 192 if (fret) { 193 abort(); 194 } 195 196 { 197 CSSM_CONTEXT_ATTRIBUTE attr; 198 199 attr.AttributeType = CSSM_ATTRIBUTE_MODE; 200 attr.AttributeLength = sizeof(attr.Attribute.Uint32); 201 attr.Attribute.Uint32 = algMode; 202 203 fret = CSSM_UpdateContextAttributes(handle, 1, &attr); 204 if (fret) { 205 abort(); 206 } 207 } 208 209 in.Data = (uint8 *)from; 210 in.Length = flen; 211 212 out.Data = (uint8 *)to; 213 out.Length = keysize; 214 215 rem.Data = (uint8 *)remdata; 216 rem.Length = sizeof(remdata); 217 218 cret = func(handle, &in, 1, &out, 1, &outlen, &rem); 219 if (cret) { 220 /* cssmErrorString(cret); */ 221 fret = -1; 222 } else{ 223 fret = outlen; 224 } 225 226 if (handle) { 227 CSSM_DeleteContext(handle); 228 } 229 unload_key(&cssmKey); 230 231 return (fret); 232} 233 234 235/* 236 * 237 */ 238static int 239cdsa_rsa_public_encrypt(int flen, const unsigned char *from, 240 unsigned char *to, RSA *rsa, int padding) 241{ 242 return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_EncryptData)); 243} 244 245 246static int 247cdsa_rsa_public_decrypt(int flen, const unsigned char *from, 248 unsigned char *to, RSA *rsa, int padding) 249{ 250 return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_DecryptData)); 251} 252 253 254static int 255cdsa_rsa_private_encrypt(int flen, const unsigned char *from, 256 unsigned char *to, RSA *rsa, int padding) 257{ 258 return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_EncryptData)); 259} 260 261 262static int 263cdsa_rsa_private_decrypt(int flen, const unsigned char *from, 264 unsigned char *to, RSA *rsa, int padding) 265{ 266 return (perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_DecryptData)); 267} 268 269 270static int 271cdsa_dsa_generate_key(DSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) 272{ 273 CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle(); 274 uint32_t pubAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA; 275 uint32_t privAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA; 276 CSSM_CC_HANDLE handle = 0; 277 CSSM_RETURN ret; 278 size_t len; 279 const unsigned char *p; 280 CSSM_KEY priv_key, pub_key; 281 AlgorithmIdentifier ai; 282 283 memset(&priv_key, 0, sizeof(priv_key)); 284 memset(&pub_key, 0, sizeof(pub_key)); 285 memset(&ai, 0, sizeof(ai)); 286 287 ret = CSSM_CSP_CreateKeyGenContext(cspHandle, 288 CSSM_ALGID_DSA, 289 bits, 290 NULL, /* Seed */ 291 NULL, /* Salt */ 292 NULL, /* StartDate */ 293 NULL, /* EndDate */ 294 NULL, /* Params */ 295 &handle); 296 if (ret) { 297 return (0); 298 } 299 300 { 301 CSSM_CONTEXT_ATTRIBUTE attr; 302 303 /* optional format specifiers */ 304 attr.AttributeType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT; 305 attr.AttributeLength = sizeof(attr.Attribute.Uint32); 306 attr.Attribute.Uint32 = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; 307 308 ret = CSSM_UpdateContextAttributes(handle, 1, &attr); 309 if (ret) { 310 abort(); 311 } 312 313 attr.AttributeType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT; 314 ret = CSSM_UpdateContextAttributes(handle, 1, &attr); 315 if (ret) { 316 abort(); 317 } 318 } 319 320 ret = CSSM_GenerateKeyPair(handle, 321 /* pubkey */ 322 CSSM_KEYUSE_DERIVE, 323 pubAttr, 324 &_cs_labelData, 325 &pub_key, 326 327 /* private key */ 328 CSSM_KEYUSE_DERIVE, 329 privAttr, 330 &_cs_labelData, 331 NULL, /* CredAndAclEntry */ 332 &priv_key); 333 334 CSSM_DeleteContext(handle); 335 if (ret) { 336 return (0); 337 } 338 339 ret = decode_AlgorithmIdentifier(priv_key.KeyData.Data, 340 priv_key.KeyData.Length, &ai, NULL); 341 if (ret || (ai.parameters == NULL)) { 342 p = priv_key.KeyData.Data; 343 len = priv_key.KeyData.Length; 344 } else { 345 p = ai.parameters->data; 346 len = ai.parameters->length; 347 } 348 349 ret = (d2i_DSAPrivateKey(dsa, &p, len) == NULL) ? 0 : 1; 350 free_AlgorithmIdentifier(&ai); 351 352 CSSM_FreeKey(cspHandle, NULL, &pub_key, CSSM_FALSE); 353 CSSM_FreeKey(cspHandle, NULL, &priv_key, CSSM_FALSE); 354 355 return (ret); 356} 357 358 359#endif /* #if 0 */ 360 361static DSA_SIG * 362cdsa_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 363{ 364 return (NULL); 365} 366 367 368static int 369cdsa_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) 370{ 371 return (1); 372} 373 374 375static int 376cdsa_dsa_do_verify(const unsigned char *dgst, int dgst_len, 377 DSA_SIG *sig, DSA *dsa) 378{ 379 return (1); 380} 381 382 383static int 384cdsa_dsa_init(DSA *dsa) 385{ 386 return (1); 387} 388 389 390static int 391cdsa_dsa_finish(DSA *dsa) 392{ 393 return (1); 394} 395 396 397static int 398cdsa_dsa_paramgen(DSA *dsa, int bits, unsigned char *seed, int seed_len, 399 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 400{ 401 return (1); 402} 403 404 405static int 406cdsa_dsa_keygen(DSA *dsa) 407{ 408 return (1); 409} 410 411 412const DSA_METHOD _ossl_dsa_cdsa_method = 413{ 414 .name = "cryptoshim cdsa DSA", 415 .dsa_do_sign = cdsa_dsa_do_sign, 416 .dsa_sign_setup = cdsa_dsa_sign_setup, 417 .dsa_do_verify = cdsa_dsa_do_verify, 418 .init = cdsa_dsa_init, 419 .finish = cdsa_dsa_finish, 420 0, 421 NULL, 422 .dsa_paramgen = cdsa_dsa_paramgen, 423 .dsa_keygen = cdsa_dsa_keygen 424}; 425#endif /* HAVE_CDSA */ 426 427const DSA_METHOD * 428DSA_cdsa_method(void) 429{ 430#ifdef HAVE_CDSA 431 return (&_ossl_dsa_cdsa_method); 432 433#else 434 return (NULL); 435#endif 436} 437