/ OSX / libsecurity_transform / lib / CEncryptDecrypt.c
CEncryptDecrypt.c
 1  /*
 2   * Copyright (c) 2012 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  #include <CoreFoundation/CoreFoundation.h>
26  #include "corecrypto/ccsha1.h"
27  #include "corecrypto/ccrsa_priv.h"
28  #include "corecrypto/ccrng_system.h"
29  #include "corecrypto/ccn.h"
30  #include "stdio.h"
31  #include "misc.h"
32  #include "Utilities.h"
33  
34  // corecrypto headers don't like C++ (on a deaper level then extern "C" {} can fix
35  // so we need a C "shim" for all our corecrypto use.
36  
37  CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue);
38  CFDataRef oaep_padding_via_c(int desired_message_length, CFDataRef dataValue) CF_RETURNS_RETAINED
39  {
40      size_t pBufferSize = ccn_sizeof_size(desired_message_length);
41  	cc_unit *paddingBuffer = malloc(pBufferSize);
42      if (paddingBuffer == NULL){
43          return (void*)GetNoMemoryErrorAndRetain();
44      }
45      
46  	bzero(paddingBuffer, pBufferSize); // XXX needed??
47  	static dispatch_once_t randomNumberGenneratorInitialzed;
48  	static struct ccrng_system_state rng;
49  	dispatch_once(&randomNumberGenneratorInitialzed, ^{
50          ccrng_system_init(&rng);
51  	});
52  	
53      ccrsa_oaep_encode(ccsha1_di(),
54                        (struct ccrng_state*)&rng,
55                        pBufferSize, (cc_unit*)paddingBuffer,
56                        CFDataGetLength(dataValue), CFDataGetBytePtr(dataValue));
57      ccn_swap(ccn_nof_size(pBufferSize), (cc_unit*)paddingBuffer);
58  	
59      CFDataRef paddedValue = CFDataCreate(NULL, (UInt8*)paddingBuffer, desired_message_length);
60      free(paddingBuffer);
61      return paddedValue ? paddedValue : (void*)GetNoMemoryErrorAndRetain();
62  }
63  
64  CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage);
65  CFDataRef oaep_unpadding_via_c(CFDataRef encodedMessage) CF_RETURNS_RETAINED
66  {
67  	size_t mlen = CFDataGetLength(encodedMessage);
68  	size_t pBufferSize = ccn_sizeof_size(mlen);
69      cc_unit *paddingBuffer = malloc(pBufferSize);
70  	UInt8 *plainText = malloc(mlen);
71      if (plainText == NULL || paddingBuffer == NULL) {
72          free(plainText);
73          free(paddingBuffer);
74          return (void*)GetNoMemoryErrorAndRetain();
75      }
76  	
77  	ccn_read_uint(ccn_nof_size(mlen), paddingBuffer, mlen, CFDataGetBytePtr(encodedMessage));
78  	size_t plainTextLength = mlen;
79      int err = ccrsa_oaep_decode(ccsha1_di(), &plainTextLength, plainText, mlen, paddingBuffer);
80  	
81      if (err) {
82  		// XXX should make a CFError or something.
83          CFErrorRef error = fancy_error(CFSTR("CoreCrypto"), err, CFSTR("OAEP decode error"));
84          CFRetainSafe(error);
85          free(plainText);
86          free(paddingBuffer);
87          return (void*)error;
88      }
89  	
90      CFDataRef result = CFDataCreate(NULL, (UInt8*)plainText, plainTextLength);
91      
92      free(plainText);
93      free(paddingBuffer);
94      
95      return result;
96  }