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/* 25 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan 26 * (Royal Institute of Technology, Stockholm, Sweden). 27 * All rights reserved. 28 * 29 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 42 * 3. Neither the name of the Institute nor the names of its contributors 43 * may be used to endorse or promote products derived from this software 44 * without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 */ 58 59#include "ossl-config.h" 60 61 62#include <stdio.h> 63#include <stdlib.h> 64#include <assert.h> 65 66#include "krb5-types.h" 67#include "ossl-rsa.h" 68#include "rfc2459_asn1.h" 69#include "ossl-common.h" 70 71#ifdef HAVE_CDSA 72 73static int 74load_key(CSSM_CSP_HANDLE cspHandle, RSA *rsa, int use_public, CSSM_KEY_PTR key, size_t *keysize) 75{ 76 CSSM_KEY_SIZE keySize; 77 CSSM_RETURN ret; 78 size_t size; 79 80 memset(key, 0, sizeof(*key)); 81 82 if (use_public) { 83 RSAPublicKey k; 84 85 memset(&k, 0, sizeof(k)); 86 87 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 88 if (ret == 0) { 89 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 90 } 91 if (ret) { 92 free_RSAPublicKey(&k); 93 return (0); 94 } 95 96 ASN1_MALLOC_ENCODE(RSAPublicKey, key->KeyData.Data, key->KeyData.Length, 97 &k, &size, ret); 98 free_RSAPublicKey(&k); 99 if (ret) { 100 return (1); 101 } 102 if (size != key->KeyData.Length) { 103 abort(); 104 } 105 } else { 106 RSAPrivateKey k; 107 108 memset(&k, 0, sizeof(k)); 109 110 k.version = 1; 111 ret = _cs_BN_to_integer(rsa->n, &k.modulus); 112 if (ret == 0) { 113 ret = _cs_BN_to_integer(rsa->e, &k.publicExponent); 114 } 115 if (ret == 0) { 116 ret = _cs_BN_to_integer(rsa->d, &k.privateExponent); 117 } 118 if (ret == 0) { 119 ret = _cs_BN_to_integer(rsa->p, &k.prime1); 120 } 121 if (ret == 0) { 122 ret = _cs_BN_to_integer(rsa->q, &k.prime2); 123 } 124 if (ret == 0) { 125 ret = _cs_BN_to_integer(rsa->dmp1, &k.exponent1); 126 } 127 if (ret == 0) { 128 ret = _cs_BN_to_integer(rsa->dmq1, &k.exponent2); 129 } 130 if (ret == 0) { 131 ret = _cs_BN_to_integer(rsa->iqmp, &k.coefficient); 132 } 133 if (ret) { 134 free_RSAPrivateKey(&k); 135 return (1); 136 } 137 138 ASN1_MALLOC_ENCODE(RSAPrivateKey, key->KeyData.Data, key->KeyData.Length, 139 &k, &size, ret); 140 free_RSAPrivateKey(&k); 141 if (ret) { 142 return (1); 143 } 144 if (size != key->KeyData.Length) { 145 abort(); 146 } 147 } 148 149 key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; 150 key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW; 151 key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; 152 key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA; 153 key->KeyHeader.KeyClass = use_public ? 154 CSSM_KEYCLASS_PUBLIC_KEY : 155 CSSM_KEYCLASS_PRIVATE_KEY; 156 key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; 157 key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; 158 159 ret = CSSM_QueryKeySizeInBits(cspHandle, 0, key, &keySize); 160 if (ret) { 161 return (1); 162 } 163 164 key->KeyHeader.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits; 165 166 *keysize = (keySize.LogicalKeySizeInBits + 7) / 8; 167 168 return (0); 169} 170 171 172static void 173unload_key(CSSM_KEY_PTR key) 174{ 175 free(key->KeyData.Data); 176 memset(key, 0, sizeof(*key)); 177} 178 179 180typedef CSSM_RETURN (*op)(CSSM_CC_HANDLE, const CSSM_DATA *, 181 uint32, CSSM_DATA_PTR, uint32, 182 CSSM_SIZE *, CSSM_DATA_PTR); 183 184 185static int 186perform_rsa_op(int flen, const unsigned char *from, 187 unsigned char *to, RSA *rsa, int padding, 188 CSSM_ENCRYPT_MODE algMode, op func) 189{ 190 CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle(); 191 CSSM_RETURN cret; 192 CSSM_ACCESS_CREDENTIALS creds; 193 CSSM_KEY cssmKey; 194 CSSM_CC_HANDLE handle = 0; 195 CSSM_DATA out, in, rem; 196 int fret = 0; 197 CSSM_SIZE outlen = 0; 198 char remdata[1024]; 199 size_t keysize; 200 201 if (padding != RSA_PKCS1_PADDING) { 202 return (-1); 203 } 204 205 memset(&creds, 0, sizeof(creds)); 206 207 fret = load_key(cspHandle, rsa, (algMode == CSSM_ALGMODE_PUBLIC_KEY), 208 &cssmKey, &keysize); 209 if (fret) { 210 return (-2); 211 } 212 213 fret = CSSM_CSP_CreateAsymmetricContext(cspHandle, 214 CSSM_ALGID_RSA, 215 &creds, 216 &cssmKey, 217 CSSM_PADDING_PKCS1, 218 &handle); 219 if (fret) { 220 abort(); 221 } 222 223 { 224 CSSM_CONTEXT_ATTRIBUTE attr; 225 226 attr.AttributeType = CSSM_ATTRIBUTE_MODE; 227 attr.AttributeLength = sizeof(attr.Attribute.Uint32); 228 attr.Attribute.Uint32 = algMode; 229 230 fret = CSSM_UpdateContextAttributes(handle, 1, &attr); 231 if (fret) { 232 abort(); 233 } 234 } 235 236 in.Data = (uint8 *)from; 237 in.Length = flen; 238 239 out.Data = (uint8 *)to; 240 out.Length = keysize; 241 242 rem.Data = (uint8 *)remdata; 243 rem.Length = sizeof(remdata); 244 245 cret = func(handle, &in, 1, &out, 1, &outlen, &rem); 246 if (cret) { 247 /* cssmErrorString(cret); */ 248 fret = -1; 249 } else{ 250 fret = outlen; 251 } 252 253 if (handle) { 254 CSSM_DeleteContext(handle); 255 } 256 unload_key(&cssmKey); 257 258 return (fret); 259} 260 261 262/* 263 * 264 */ 265static int 266cdsa_rsa_public_encrypt(int flen, const unsigned char *from, 267 unsigned char *to, RSA *rsa, int padding) 268{ 269 int rc = perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_EncryptData); 270 271 return (rc); 272} 273 274 275static int 276cdsa_rsa_public_decrypt(int flen, const unsigned char *from, 277 unsigned char *to, RSA *rsa, int padding) 278{ 279 char *str = NULL; 280 int rc = perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PUBLIC_KEY, CSSM_DecryptData); 281 282 return (rc); 283} 284 285 286static int 287cdsa_rsa_private_encrypt(int flen, const unsigned char *from, 288 unsigned char *to, RSA *rsa, int padding) 289{ 290 int rc = perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_EncryptData); 291 292 return (rc); 293} 294 295 296static int 297cdsa_rsa_private_decrypt(int flen, const unsigned char *from, 298 unsigned char *to, RSA *rsa, int padding) 299{ 300 int rc = perform_rsa_op(flen, from, to, rsa, padding, CSSM_ALGMODE_PRIVATE_KEY, CSSM_DecryptData); 301 302 return (rc); 303} 304 305 306static int 307cdsa_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) 308{ 309 CSSM_CSP_HANDLE cspHandle = _cs_get_cdsa_csphandle(); 310 uint32_t pubAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA; 311 uint32_t privAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA; 312 CSSM_CC_HANDLE handle; 313 CSSM_RETURN ret; 314 size_t len; 315 const unsigned char *p; 316 CSSM_KEY priv_key, pub_key; 317 AlgorithmIdentifier ai; 318 319 memset(&priv_key, 0, sizeof(priv_key)); 320 memset(&pub_key, 0, sizeof(pub_key)); 321 memset(&ai, 0, sizeof(ai)); 322 323 ret = CSSM_CSP_CreateKeyGenContext(cspHandle, 324 CSSM_ALGID_RSA, 325 bits, 326 NULL, 327 NULL, 328 NULL, 329 NULL, 330 NULL, 331 &handle); 332 if (ret) { 333 return (0); 334 } 335 336 { 337 CSSM_CONTEXT_ATTRIBUTE attr; 338 339 attr.AttributeType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT; 340 attr.AttributeLength = sizeof(attr.Attribute.Uint32); 341 attr.Attribute.Uint32 = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; 342 343 ret = CSSM_UpdateContextAttributes(handle, 1, &attr); 344 if (ret) { 345 abort(); 346 } 347 348 attr.AttributeType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT; 349 ret = CSSM_UpdateContextAttributes(handle, 1, &attr); 350 if (ret) { 351 abort(); 352 } 353 } 354 355 ret = CSSM_GenerateKeyPair(handle, 356 /* pubkey */ 357 CSSM_KEYUSE_DERIVE, 358 pubAttr, 359 &_cs_labelData, 360 &pub_key, 361 /* private key */ 362 CSSM_KEYUSE_DERIVE, 363 privAttr, 364 &_cs_labelData, 365 NULL, 366 &priv_key); 367 368 CSSM_DeleteContext(handle); 369 if (ret) { 370 return (0); 371 } 372 373 ret = decode_AlgorithmIdentifier(priv_key.KeyData.Data, 374 priv_key.KeyData.Length, &ai, NULL); 375 if (ret || (ai.parameters == NULL)) { 376 p = priv_key.KeyData.Data; 377 len = priv_key.KeyData.Length; 378 } else { 379 p = ai.parameters->data; 380 len = ai.parameters->length; 381 } 382 383 ret = (d2i_RSAPrivateKey(rsa, &p, len) == NULL) ? 0 : 1; 384 free_AlgorithmIdentifier(&ai); 385 386 CSSM_FreeKey(cspHandle, NULL, &pub_key, CSSM_FALSE); 387 CSSM_FreeKey(cspHandle, NULL, &priv_key, CSSM_FALSE); 388 389 return (ret); 390} 391 392 393static int 394cdsa_rsa_init(RSA *rsa) 395{ 396 return (1); 397} 398 399 400static int 401cdsa_rsa_finish(RSA *rsa) 402{ 403 return (1); 404} 405 406 407const RSA_METHOD _ossl_rsa_cdsa_method = 408{ 409 .name = "cryptoshim cdsa RSA", 410 .rsa_pub_enc = cdsa_rsa_public_encrypt, 411 .rsa_pub_dec = cdsa_rsa_public_decrypt, 412 .rsa_priv_enc = cdsa_rsa_private_encrypt, 413 .rsa_priv_dec = cdsa_rsa_private_decrypt, 414 .rsa_mod_exp = NULL, 415 .bn_mod_exp = NULL, 416 .init = cdsa_rsa_init, 417 .finish = cdsa_rsa_finish, 418 .flags = 0, 419 .app_data = NULL, 420 .rsa_sign = NULL, 421 .rsa_verity = NULL, 422 .rsa_keygen = cdsa_rsa_generate_key 423}; 424#endif /* HAVE_CDSA */ 425 426const RSA_METHOD * 427RSA_cdsa_method(void) 428{ 429#ifdef HAVE_CDSA 430 return (&_ossl_rsa_cdsa_method); 431 432#else 433 return (NULL); 434#endif 435} 436