]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecKeyAdaptors.c
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / sec / Security / SecKeyAdaptors.c
1 /*
2 * Copyright (c) 2016 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 * SecKeyAdaptors.c - Implementation of assorted algorithm adaptors for SecKey.
26 * Algorithm adaptor is able to perform some transformation on provided input and calculated results and invoke
27 * underlying operation with different algorithm. Typical adaptors are message->digest or unpadded->padded.
28 * To invoke underlying operation, add algorithm to the context algorithm array and invoke SecKeyRunAlgorithmAndCopyResult().
29 */
30
31 #include <Security/SecBase.h>
32 #include <Security/SecKeyInternal.h>
33 #include <Security/SecItem.h>
34 #include <Security/SecCFAllocator.h>
35
36 #include <AssertMacros.h>
37 #include <utilities/SecCFWrappers.h>
38 #include <utilities/array_size.h>
39 #include <utilities/debugging.h>
40 #include <utilities/SecCFError.h>
41 #include <utilities/SecBuffer.h>
42
43 #include <corecrypto/ccsha1.h>
44 #include <corecrypto/ccsha2.h>
45 #include <corecrypto/ccmd5.h>
46 #include <corecrypto/ccrsa_priv.h>
47 #include <corecrypto/ccansikdf.h>
48 #include <corecrypto/ccmode.h>
49 #include <corecrypto/ccaes.h>
50
51 #pragma mark Algorithm constants value definitions
52
53 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw = CFSTR("algid:sign:RSA:raw");
54 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit = CFSTR("algid:sign:RSA:raw-cc");
55
56 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw = CFSTR("algid:sign:RSA:digest-PKCS1v15");
57 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5 = CFSTR("algid:sign:RSA:digest-PKCS1v15:MD5");
58 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA1");
59 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA224");
60 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA256");
61 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA384");
62 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA512");
63
64 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5 = CFSTR("algid:sign:RSA:message-PKCS1v15:MD5");
65 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA1");
66 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA224");
67 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA256");
68 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA384");
69 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA512");
70
71 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754 = CFSTR("algid:sign:ECDSA:RFC4754");
72
73 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962 = CFSTR("algid:sign:ECDSA:digest-X962");
74 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA1 = CFSTR("algid:sign:ECDSA:digest-X962:SHA1");
75 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA224 = CFSTR("algid:sign:ECDSA:digest-X962:SHA224");
76 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA256 = CFSTR("algid:sign:ECDSA:digest-X962:SHA256");
77 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA384 = CFSTR("algid:sign:ECDSA:digest-X962:SHA384");
78 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA512 = CFSTR("algid:sign:ECDSA:digest-X962:SHA512");
79
80 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA1 = CFSTR("algid:sign:ECDSA:message-X962:SHA1");
81 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA224 = CFSTR("algid:sign:ECDSA:message-X962:SHA224");
82 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA256 = CFSTR("algid:sign:ECDSA:message-X962:SHA256");
83 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA384 = CFSTR("algid:sign:ECDSA:message-X962:SHA384");
84 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA512 = CFSTR("algid:sign:ECDSA:message-X962:SHA512");
85
86 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRaw = CFSTR("algid:encrypt:RSA:raw");
87 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRawCCUnit = CFSTR("algid:encrypt:RSA:raw-cc");
88 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionPKCS1 = CFSTR("algid:encrypt:RSA:PKCS1");
89 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1 = CFSTR("algid:encrypt:RSA:OAEP:SHA1");
90 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224 = CFSTR("algid:encrypt:RSA:OAEP:SHA224");
91 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256 = CFSTR("algid:encrypt:RSA:OAEP:SHA256");
92 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384 = CFSTR("algid:encrypt:RSA:OAEP:SHA384");
93 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512 = CFSTR("algid:encrypt:RSA:OAEP:SHA512");
94
95 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA1:AESGCM");
96 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA224:AESGCM");
97 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA256:AESGCM");
98 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA384:AESGCM");
99 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA512:AESGCM");
100
101 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA1:AESGCM");
102 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM");
103 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM");
104 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM");
105 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM");
106
107 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA1:AESGCM");
108 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM");
109 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM");
110 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM");
111 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM");
112
113 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandard = CFSTR("algid:keyexchange:ECDH");
114 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA1");
115 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA224");
116 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA256");
117 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA384");
118 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA512");
119
120 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactor = CFSTR("algid:keyexchange:ECDHC");
121 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA1");
122 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA224");
123 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA256");
124 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA384");
125 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA512");
126
127 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
128
129 void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
130 CFReleaseNull(context->algorithm);
131 }
132
133 static void PerformWithCFDataBuffer(CFIndex size, void (^operation)(uint8_t *buffer, CFDataRef data)) {
134 PerformWithBuffer(size, ^(size_t size, uint8_t *buffer) {
135 CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)buffer, size, kCFAllocatorNull);
136 operation(buffer, data);
137 CFRelease(data);
138 });
139 }
140
141 static CF_RETURNS_RETAINED CFDataRef SecKeyMessageToDigestAdaptor(SecKeyOperationContext *context, CFDataRef message, CFDataRef in2,
142 const struct ccdigest_info *di, CFErrorRef *error) {
143 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
144 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
145 }
146
147 __block CFTypeRef result;
148 PerformWithCFDataBuffer(di->output_size, ^(uint8_t *buffer, CFDataRef data) {
149 ccdigest(di, CFDataGetLength(message), CFDataGetBytePtr(message), buffer);
150 result = SecKeyRunAlgorithmAndCopyResult(context, data, in2, error);
151 });
152 return result;
153 }
154
155 #define SECKEY_DIGEST_RSA_ADAPTORS(name, di) \
156 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15 ## name( \
157 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
158 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15 ## name); \
159 return SecKeyMessageToDigestAdaptor(context, in1, in2, di, error); \
160 }
161
162 #define SECKEY_DIGEST_ADAPTORS(name, di) SECKEY_DIGEST_RSA_ADAPTORS(name, di) \
163 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962 ## name( \
164 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
165 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigestX962 ## name); \
166 return SecKeyMessageToDigestAdaptor(context, in1, in2, di, error); \
167 } \
168 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962 ## name( \
169 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
170 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigestX962); \
171 return SecKeyRunAlgorithmAndCopyResult(context, in1, in2, error); \
172 }
173
174 SECKEY_DIGEST_ADAPTORS(SHA1, ccsha1_di())
175 SECKEY_DIGEST_ADAPTORS(SHA224, ccsha224_di())
176 SECKEY_DIGEST_ADAPTORS(SHA256, ccsha256_di())
177 SECKEY_DIGEST_ADAPTORS(SHA384, ccsha384_di())
178 SECKEY_DIGEST_ADAPTORS(SHA512, ccsha512_di())
179 SECKEY_DIGEST_RSA_ADAPTORS(MD5, ccmd5_di())
180
181 #undef SECKEY_DIGEST_RSA_ADAPTORS
182 #undef SECKEY_DIGEST_ADAPTORS
183
184 static CFDataRef SecKeyRSACopyBigEndianToCCUnit(CFDataRef bigEndian, size_t size) {
185 CFMutableDataRef result = NULL;
186 if (bigEndian != NULL) {
187 size_t dataSize = CFDataGetLength(bigEndian);
188 if (dataSize > size) {
189 size = dataSize;
190 }
191 result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, ccrsa_sizeof_n_from_size(size));
192 ccn_read_uint(ccn_nof_size(size), (cc_unit *)CFDataGetMutableBytePtr(result), dataSize, CFDataGetBytePtr(bigEndian));
193 }
194 return result;
195 }
196
197 static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian, size_t size, void (^operation)(CFDataRef ccunits)) {
198 if (bigEndian == NULL) {
199 return operation(NULL);
200 }
201 size_t dataSize = CFDataGetLength(bigEndian);
202 if (dataSize > size) {
203 size = dataSize;
204 }
205 PerformWithCFDataBuffer(ccrsa_sizeof_n_from_size(size), ^(uint8_t *buffer, CFDataRef data) {
206 ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, dataSize, CFDataGetBytePtr(bigEndian));
207 operation(data);
208 });
209 }
210
211 static CFDataRef SecKeyRSACopyCCUnitToBigEndian(CFDataRef ccunits, size_t size) {
212 CFMutableDataRef result = NULL;
213 if (ccunits != NULL) {
214 cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
215 const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
216 result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, size);
217 ccn_write_uint_padded(n, s, CFDataGetLength(result), CFDataGetMutableBytePtr(result));
218 }
219 return result;
220 }
221
222 static void PerformWithCCUnitToBigEndian(CFDataRef ccunits, size_t size, void (^operation)(CFDataRef bigEndian)) {
223 if (ccunits == NULL) {
224 return operation(NULL);
225 }
226 PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
227 cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
228 const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
229 ccn_write_uint_padded(n, s, size, buffer);
230 operation(data);
231 });
232 }
233
234 static CFTypeRef SecKeyRSACopyPKCS1EMSASignature(SecKeyOperationContext *context,
235 CFDataRef in1, CFDataRef in2, CFErrorRef *error, const uint8_t *oid) {
236 if (oid != NULL) {
237 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw);
238 }
239 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
240 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
241 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
242 }
243
244 __block CFTypeRef result = NULL;
245 size_t size = SecKeyGetBlockSize(context->key);
246 if (size == 0) {
247 SecError(errSecParam, error, CFSTR("expecting RSA key"));
248 return NULL;
249 }
250 PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
251 uint8_t s[size];
252 int err = ccrsa_emsa_pkcs1v15_encode(size, s, CFDataGetLength(in1), CFDataGetBytePtr(in1), oid);
253 require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSAsign wrong input data length")));
254 ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s);
255 require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
256 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
257 out:;
258 });
259 return result;
260 }
261
262 #define seckey_ccoid_md5 ((unsigned char *)"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05")
263
264 #define PKCS1v15_EMSA_SIGN_ADAPTOR(name, oid) \
265 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15 ## name( \
266 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
267 return SecKeyRSACopyPKCS1EMSASignature(context, in1, in2, error, oid); \
268 }
269
270 PKCS1v15_EMSA_SIGN_ADAPTOR(SHA1, ccoid_sha1)
271 PKCS1v15_EMSA_SIGN_ADAPTOR(SHA224, ccoid_sha224)
272 PKCS1v15_EMSA_SIGN_ADAPTOR(SHA256, ccoid_sha256)
273 PKCS1v15_EMSA_SIGN_ADAPTOR(SHA384, ccoid_sha384)
274 PKCS1v15_EMSA_SIGN_ADAPTOR(SHA512, ccoid_sha512)
275 PKCS1v15_EMSA_SIGN_ADAPTOR(Raw, NULL)
276 PKCS1v15_EMSA_SIGN_ADAPTOR(MD5, seckey_ccoid_md5)
277
278 #undef PKCS1v15_EMSA_SIGN_ADAPTOR
279
280 static CFTypeRef SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(SecKeyOperationContext *context,
281 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
282 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
283 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
284 }
285
286 __block CFTypeRef result = NULL;
287 PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
288 result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, in2, error);
289 if (result != NULL) {
290 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
291 }
292 });
293 return result;
294 }
295
296 static CFTypeRef SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(SecKeyOperationContext *context,
297 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
298 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
299 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
300 }
301
302 __block CFTypeRef result = NULL;
303 PerformWithCCUnitToBigEndian(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef bigEndian) {
304 result = SecKeyRunAlgorithmAndCopyResult(context, bigEndian, in2, error);
305 if (result != NULL) {
306 CFAssignRetained(result, SecKeyRSACopyBigEndianToCCUnit(result, SecKeyGetBlockSize(context->key)));
307 }
308 });
309 return result;
310 }
311
312 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw(SecKeyOperationContext *context,
313 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
314 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
315 return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
316 }
317
318 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit(SecKeyOperationContext *context,
319 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
320 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRaw);
321 return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
322 }
323
324 static bool SecKeyVerifyBadSignature(CFErrorRef *error) {
325 return SecError(errSecVerifyFailed, error, CFSTR("RSA signature verification failed, no match"));
326 }
327
328 static CFTypeRef SecKeyRSAVerifyAdaptorCopyResult(SecKeyOperationContext *context, CFTypeRef signature, CFErrorRef *error,
329 Boolean (^verifyBlock)(CFDataRef decrypted)) {
330 CFTypeRef result = NULL;
331 context->operation = kSecKeyOperationTypeDecrypt;
332 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
333 result = SecKeyRunAlgorithmAndCopyResult(context, signature, NULL, error);
334 if (context->mode == kSecKeyOperationModePerform && result != NULL) {
335 if (verifyBlock(result)) {
336 CFRetainAssign(result, kCFBooleanTrue);
337 } else {
338 CFRetainAssign(result, kCFBooleanFalse);
339 SecKeyVerifyBadSignature(error);
340 }
341 }
342 return result;
343 }
344
345 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw(SecKeyOperationContext *context,
346 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
347 return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) {
348 // Skip zero-padding from the beginning of the decrypted signature.
349 const UInt8 *data = CFDataGetBytePtr(decrypted);
350 CFIndex length = CFDataGetLength(decrypted);
351 while (*data == 0x00 && length > 0) {
352 data++;
353 length--;
354 }
355 // The rest of the decrypted signature must be the same as input data.
356 return length == CFDataGetLength(in1) && memcmp(CFDataGetBytePtr(in1), data, length) == 0;
357 });
358 };
359
360 #define PKCS1v15_EMSA_VERIFY_ADAPTOR(name, oid) \
361 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15 ## name( \
362 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
363 return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
364 return ccrsa_emsa_pkcs1v15_verify(CFDataGetLength(decrypted), \
365 (uint8_t *)CFDataGetBytePtr(decrypted), \
366 CFDataGetLength(in1), CFDataGetBytePtr(in1), oid) == 0; \
367 }); \
368 }
369
370 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA1, ccoid_sha1)
371 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA224, ccoid_sha224)
372 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA256, ccoid_sha256)
373 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA384, ccoid_sha384)
374 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA512, ccoid_sha512)
375 PKCS1v15_EMSA_VERIFY_ADAPTOR(Raw, NULL)
376 PKCS1v15_EMSA_VERIFY_ADAPTOR(MD5, seckey_ccoid_md5)
377
378 #undef PKCS1v15_EMSA_VERIFY_ADAPTOR
379
380 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw(SecKeyOperationContext *context,
381 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
382 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
383 return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
384 }
385
386 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit(SecKeyOperationContext *context,
387 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
388 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
389 return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
390 }
391
392 static CFTypeRef SecKeyRSACopyEncryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
393 CFDataRef in1, CFErrorRef *error) {
394 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
395 size_t size = SecKeyGetBlockSize(context->key);
396 size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
397 if (size < minSize) {
398 return kCFNull;
399 }
400 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
401 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
402 }
403
404 __block CFTypeRef result = NULL;
405 PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
406 int err;
407 if (di != NULL) {
408 err = ccrsa_oaep_encode(di, ccrng_seckey, size, (cc_unit *)buffer,
409 CFDataGetLength(in1), CFDataGetBytePtr(in1));
410 } else {
411 err = ccrsa_eme_pkcs1v15_encode(ccrng_seckey, size, (cc_unit *)buffer,
412 CFDataGetLength(in1), CFDataGetBytePtr(in1));
413 }
414 require_noerr_action_quiet(err, out, SecError(errSecParam, error,
415 CFSTR("RSAencrypt wrong input size (err %d)"), err));
416 require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
417 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
418 out:;
419 });
420 return result;
421 }
422
423 static CFTypeRef SecKeyRSACopyDecryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
424 CFDataRef in1, CFErrorRef *error) {
425 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
426 size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
427 if (SecKeyGetBlockSize(context->key) < minSize) {
428 return kCFNull;
429 }
430 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
431 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
432 }
433
434 __block CFMutableDataRef result = NULL;
435 PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
436 CFDataRef cc_result = NULL;
437 require_quiet(cc_result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, NULL, error), out);
438 size_t size = CFDataGetLength(cc_result);
439 result = CFDataCreateMutableWithScratch(NULL, size);
440 int err;
441 if (di != NULL) {
442 err = ccrsa_oaep_decode(di, &size, CFDataGetMutableBytePtr(result),
443 CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
444 } else {
445 err = ccrsa_eme_pkcs1v15_decode(&size, CFDataGetMutableBytePtr(result),
446 CFDataGetLength(cc_result), (cc_unit *)CFDataGetBytePtr(cc_result));
447 }
448 require_noerr_action_quiet(err, out, (CFReleaseNull(result),
449 SecError(errSecParam, error, CFSTR("RSAdecrypt wrong input (err %d)"), err)));
450 CFDataSetLength(result, size);
451 out:
452 CFReleaseSafe(cc_result);
453 });
454 return result;
455 }
456
457 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
458 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
459 return SecKeyRSACopyEncryptedWithPadding(context, NULL, in1, error);
460 }
461
462 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
463 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
464 return SecKeyRSACopyDecryptedWithPadding(context, NULL, in1, error);
465 }
466
467 #define RSA_OAEP_CRYPT_ADAPTOR(name, di) \
468 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## name( \
469 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
470 return SecKeyRSACopyEncryptedWithPadding(context, di, in1, error); \
471 } \
472 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
473 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
474 return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
475 }
476
477 RSA_OAEP_CRYPT_ADAPTOR(SHA1, ccsha1_di());
478 RSA_OAEP_CRYPT_ADAPTOR(SHA224, ccsha224_di());
479 RSA_OAEP_CRYPT_ADAPTOR(SHA256, ccsha256_di());
480 RSA_OAEP_CRYPT_ADAPTOR(SHA384, ccsha384_di());
481 RSA_OAEP_CRYPT_ADAPTOR(SHA512, ccsha512_di());
482
483 #undef RSA_OAEP_CRYPT_ADAPTOR
484
485 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
486 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
487
488 static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
489 CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
490 CFTypeRef result = NULL;
491 require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, in1, NULL, error), out);
492
493 if (context->mode == kSecKeyOperationModePerform) {
494 // Parse params.
495 CFTypeRef value = NULL;
496 CFIndex requestedSize = 0;
497 require_action_quiet((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterRequestedSize)) != NULL
498 && CFGetTypeID(value) == CFNumberGetTypeID() &&
499 CFNumberGetValue(value, kCFNumberCFIndexType, &requestedSize), out,
500 SecError(errSecParam, error, CFSTR("kSecKeyKeyExchangeParameterRequestedSize is missing")));
501 size_t sharedInfoLength = 0;
502 const void *sharedInfo = NULL;
503 if ((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterSharedInfo)) != NULL &&
504 CFGetTypeID(value) == CFDataGetTypeID()) {
505 sharedInfo = CFDataGetBytePtr(value);
506 sharedInfoLength = CFDataGetLength(value);
507 }
508
509 CFMutableDataRef kdfResult = CFDataCreateMutableWithScratch(kCFAllocatorDefault, requestedSize);
510 int err = ccansikdf_x963(di, CFDataGetLength(result), CFDataGetBytePtr(result), sharedInfoLength, sharedInfo,
511 requestedSize, CFDataGetMutableBytePtr(kdfResult));
512 CFAssignRetained(result, kdfResult);
513 require_noerr_action_quiet(err, out, (CFReleaseNull(result),
514 SecError(errSecParam, error, CFSTR("ECDHKeyExchange wrong input (%d)"), err)));
515 }
516 out:
517 return result;
518 }
519
520 #define ECDH_X963_ADAPTOR(hashname, di, cofactor) \
521 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDH ## cofactor ## X963 ## hashname( \
522 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
523 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDHKeyExchange ## cofactor); \
524 return SecKeyECDHCopyX963Result(context, di, in1, in2, error); \
525 }
526
527 ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Standard)
528 ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Standard)
529 ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Standard)
530 ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Standard)
531 ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Standard)
532 ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Cofactor)
533 ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Cofactor)
534 ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Cofactor)
535 ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Cofactor)
536 ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Cofactor)
537
538 #undef ECDH_X963_ADAPTOR
539
540 // Extract number value of either CFNumber or CFString.
541 static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
542 CFIndex result = 0;
543 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
544 if (!CFNumberGetValue(ref, kCFNumberCFIndexType, &result)) {
545 result = 0;
546 }
547 } else if (CFGetTypeID(ref) == CFStringGetTypeID()) {
548 result = CFStringGetIntValue(ref);
549 }
550 return result;
551 }
552
553 typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, CFErrorRef *error);
554 typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result, CFErrorRef *error);
555 typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error);
556
557 static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
558 SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
559 SecKeyECIESEncryptCopyResult encryptCopyResult,
560 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
561 CFDictionaryRef parameters = NULL;
562 SecKeyRef ephemeralPrivateKey = NULL, ephemeralPublicKey = NULL;
563 CFDataRef pubKeyData = NULL, ephemeralPubKeyData = NULL, keyExchangeResult = NULL;
564 CFTypeRef result = NULL;
565 SecKeyRef originalKey = context->key;
566 CFMutableDataRef ciphertext = NULL;
567
568 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
569 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
570 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
571 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
572
573 // Generate ephemeral key.
574 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
575 CFAssignRetained(parameters, CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
576 kSecAttrKeyType, CFDictionaryGetValue(parameters, kSecAttrKeyType),
577 kSecAttrKeySizeInBits, CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits),
578 NULL));
579 require_quiet(ephemeralPrivateKey = SecKeyCreateRandomKey(parameters, error), out);
580 require_action_quiet(ephemeralPublicKey = SecKeyCopyPublicKey(ephemeralPrivateKey), out,
581 SecError(errSecParam, error, CFSTR("Unable to get public key from generated ECkey")));
582 require_quiet(ephemeralPubKeyData = SecKeyCopyExternalRepresentation(ephemeralPublicKey, error), out);
583
584 context->key = ephemeralPrivateKey;
585 require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
586 ephemeralPubKeyData, pubKeyData, error), out);
587 if (context->mode == kSecKeyOperationModePerform) {
588 // Encrypt input data using AES-GCM.
589 ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
590 require_quiet(encryptCopyResult(keyExchangeResult, in1, ciphertext, error), out);
591 result = CFRetain(ciphertext);
592 } else {
593 result = CFRetain(keyExchangeResult);
594 }
595
596 out:
597 CFReleaseSafe(parameters);
598 CFReleaseSafe(ephemeralPrivateKey);
599 CFReleaseSafe(ephemeralPublicKey);
600 CFReleaseSafe(pubKeyData);
601 CFReleaseSafe(ephemeralPubKeyData);
602 CFReleaseSafe(keyExchangeResult);
603 CFReleaseSafe(ciphertext);
604 context->key = originalKey;
605 return result;
606 }
607
608 static CFTypeRef SecKeyECIESCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
609 SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
610 SecKeyECIESDecryptCopyResult decryptCopyResult,
611 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
612 CFTypeRef result = NULL;
613 CFDictionaryRef parameters = NULL;
614 CFDataRef ephemeralPubKeyData = NULL, keyExchangeResult = NULL, pubKeyData = NULL;
615 SecKeyRef pubKey = NULL;
616 CFDataRef ciphertext = NULL;
617 const UInt8 *ciphertextBuffer = NULL;
618 CFIndex keySize = 0;
619
620 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
621 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
622 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
623 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
624
625 if (context->mode == kSecKeyOperationModePerform) {
626 // Extract ephemeral public key from the packet.
627 keySize = (SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits)) + 7) / 8;
628 require_action_quiet(CFDataGetLength(in1) >= keySize * 2 + 1, out,
629 SecError(errSecParam, error, CFSTR("%@: too small input packet for ECIES decrypt"), context->key));
630 ciphertextBuffer = CFDataGetBytePtr(in1);
631 ephemeralPubKeyData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, keySize * 2 + 1, kCFAllocatorNull);
632 ciphertextBuffer += keySize * 2 + 1;
633
634 require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
635 SecError(errSecParam, error, CFSTR("%@: Unable to get public key"), context->key));
636 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
637 }
638
639 // Perform keyExchange operation.
640 require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
641 ephemeralPubKeyData, pubKeyData, error), out);
642 if (context->mode == kSecKeyOperationModePerform) {
643 // Decrypt ciphertext using AES-GCM.
644 ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
645 kCFAllocatorNull);
646 require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, error), out);
647 } else {
648 result = CFRetain(keyExchangeResult);
649 }
650
651 out:
652 CFReleaseSafe(parameters);
653 CFReleaseSafe(ephemeralPubKeyData);
654 CFReleaseSafe(keyExchangeResult);
655 CFReleaseSafe(pubKeyData);
656 CFReleaseSafe(pubKey);
657 CFReleaseSafe(ciphertext);
658 return result;
659 }
660
661 static const CFIndex kSecKeyIESTagLength = 16;
662 static const UInt8 kSecKeyIESIV[16] = { 0 };
663
664 static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
665 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey,
666 CFErrorRef *error) {
667 CFDictionaryRef parameters = NULL;
668 CFNumberRef keySizeRef = NULL;
669 CFDataRef result = NULL;
670
671 CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
672 context->operation = kSecKeyOperationTypeKeyExchange;
673
674 if (context->mode == kSecKeyOperationModePerform) {
675 // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
676 CFIndex keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
677 keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
678
679 // Generate shared secret using KDF.
680 keySizeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &keySize);
681 parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
682 kSecKeyKeyExchangeParameterSharedInfo, ephemeralPubKey,
683 kSecKeyKeyExchangeParameterRequestedSize, keySizeRef,
684 NULL);
685 }
686
687 result = SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, parameters, error);
688 CFReleaseSafe(parameters);
689 CFReleaseSafe(keySizeRef);
690 return result;
691 }
692
693 static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result,
694 CFErrorRef *error) {
695 Boolean res = FALSE;
696 CFIndex prefix = CFDataGetLength(result);
697 CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
698 UInt8 *resultBuffer = CFDataGetMutableBytePtr(result) + prefix;
699 UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
700 require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
701 CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
702 sizeof(kSecKeyIESIV), kSecKeyIESIV,
703 0, NULL,
704 CFDataGetLength(inData), CFDataGetBytePtr(inData),
705 resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
706 SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
707 res = TRUE;
708 out:
709 return res;
710 }
711
712 static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
713 CFDataRef result = NULL;
714 CFMutableDataRef plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
715 CFMutableDataRef tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
716 CFDataGetBytes(inData, CFRangeMake(CFDataGetLength(inData) - kSecKeyIESTagLength, kSecKeyIESTagLength),
717 CFDataGetMutableBytePtr(tag));
718 require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
719 CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
720 sizeof(kSecKeyIESIV), kSecKeyIESIV,
721 0, NULL,
722 CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
723 kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
724 SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
725 result = CFRetain(plaintext);
726 out:
727 CFReleaseSafe(plaintext);
728 CFReleaseSafe(tag);
729 return result;
730 }
731
732 #define ECIES_X963_ADAPTOR(hashname, cofactor) \
733 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIES ## cofactor ## X963 ## hashname( \
734 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
735 return SecKeyECIESCopyEncryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
736 SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESEncryptAESGCMCopyResult, in1, in2, error); \
737 } \
738 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES ## cofactor ## X963 ## hashname( \
739 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
740 return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
741 SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESDecryptAESGCMCopyResult, in1, in2, error); \
742 }
743
744 ECIES_X963_ADAPTOR(SHA1, Standard)
745 ECIES_X963_ADAPTOR(SHA224, Standard)
746 ECIES_X963_ADAPTOR(SHA256, Standard)
747 ECIES_X963_ADAPTOR(SHA384, Standard)
748 ECIES_X963_ADAPTOR(SHA512, Standard)
749 ECIES_X963_ADAPTOR(SHA1, Cofactor)
750 ECIES_X963_ADAPTOR(SHA224, Cofactor)
751 ECIES_X963_ADAPTOR(SHA256, Cofactor)
752 ECIES_X963_ADAPTOR(SHA384, Cofactor)
753 ECIES_X963_ADAPTOR(SHA512, Cofactor)
754
755 #undef ECIES_X963_ADAPTOR
756
757 static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
758 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey,
759 CFErrorRef *error) {
760 CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
761 context->operation = kSecKeyOperationTypeKeyExchange;
762 CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
763 if (result != NULL && context->mode == kSecKeyOperationModePerform) {
764 const struct ccdigest_info *di = ccsha256_di();
765 ccdigest_di_decl(di, ctx);
766 ccdigest_init(di, ctx);
767 ccdigest_update(di, ctx, CFDataGetLength(result), CFDataGetBytePtr(result));
768 ccdigest_update(di, ctx, CFDataGetLength(ephemeralPubKey), CFDataGetBytePtr(ephemeralPubKey));
769 ccdigest_update(di, ctx, CFDataGetLength(pubKey), CFDataGetBytePtr(pubKey));
770 CFAssignRetained(result, CFDataCreateMutableWithScratch(kCFAllocatorDefault, di->output_size));
771 ccdigest_final(di, ctx, CFDataGetMutableBytePtr(result));
772 }
773 return result;
774 }
775
776 static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
777 CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
778 cccbc_one_shot(ccaes_cbc_decrypt_mode(),
779 CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
780 NULL, CFDataGetLength(keyExchangeResult) / CCAES_BLOCK_SIZE,
781 CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(result));
782 return result;
783 }
784
785 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys(
786 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
787 return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchangeStandard,
788 SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult,
789 SecKeyECIESDecryptAESCBCCopyResult,
790 in1, in2, error);
791 }
792
793 static CFTypeRef SecKeyRSAAESGCMCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
794 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
795 CFTypeRef result = NULL;
796 CFDictionaryRef parameters = NULL;
797 CFDataRef pubKeyData = NULL, wrappedKey = NULL, sessionKey = NULL;
798 CFMutableDataRef ciphertext = NULL;
799
800 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
801 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
802 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
803 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
804
805 CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
806 require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
807 result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
808
809 // Generate session key. Use 128bit AES for RSA keys < 4096bit, 256bit AES for larger keys.
810 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
811 CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
812 require_action_quiet(sessionKey = CFDataCreateWithRandomBytes((keySize >= 4096) ? (256 / 8) : (128 / 8)), out,
813 SecError(errSecParam, error, CFSTR("Failed to generate session key")));
814
815 // Encrypt session key using wrapping algorithm and store at the beginning of the result packet.
816 require_action_quiet(wrappedKey = SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error), out,
817 CFReleaseNull(result));
818 ciphertext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(wrappedKey) + CFDataGetLength(in1) + kSecKeyIESTagLength);
819 UInt8 *resultBuffer = CFDataGetMutableBytePtr(ciphertext);
820 CFDataGetBytes(wrappedKey, CFRangeMake(0, CFDataGetLength(wrappedKey)), resultBuffer);
821 resultBuffer += CFDataGetLength(wrappedKey);
822
823 // Encrypt input data using AES-GCM.
824 UInt8 *tagBuffer = resultBuffer + CFDataGetLength(in1);
825 require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
826 CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
827 sizeof(kSecKeyIESIV), kSecKeyIESIV,
828 CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
829 CFDataGetLength(in1), CFDataGetBytePtr(in1), resultBuffer,
830 kSecKeyIESTagLength, tagBuffer) == 0, out,
831 SecError(errSecParam, error, CFSTR("RSAWRAP: Failed to aes-gcm encrypt data")));
832 result = CFRetain(ciphertext);
833
834 out:
835 CFReleaseSafe(parameters);
836 CFReleaseSafe(pubKeyData);
837 CFReleaseSafe(wrappedKey);
838 CFReleaseSafe(sessionKey);
839 CFReleaseSafe(ciphertext);
840 return result;
841 }
842
843 static CFTypeRef SecKeyRSAAESGCMCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
844 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
845 CFTypeRef result = NULL;
846 CFDictionaryRef parameters = NULL;
847 CFMutableDataRef plaintext = NULL, tag = NULL;
848 CFDataRef pubKeyData = NULL, sessionKey = NULL;
849 SecKeyRef pubKey = NULL;
850
851 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
852 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
853 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
854 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
855
856 CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
857 require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
858 result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
859
860 // Extract encrypted session key.
861 require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
862 SecError(errSecParam, error, CFSTR("%@: unable to get public key"), context->key));
863 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
864
865 CFIndex wrappedKeySize = SecKeyGetBlockSize(context->key);
866 require_action_quiet(CFDataGetLength(in1) >= wrappedKeySize + kSecKeyIESTagLength, out,
867 SecError(errSecParam, error, CFSTR("RSA-WRAP too short input data")));
868 sessionKey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(in1), wrappedKeySize, kCFAllocatorNull);
869
870 // Decrypt session key.
871 CFAssignRetained(sessionKey, SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error));
872 require_quiet(sessionKey, out);
873 CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
874 keySize = (keySize >= 4096) ? (256 / 8) : (128 / 8);
875 require_action_quiet(CFDataGetLength(sessionKey) == keySize, out,
876 SecError(errSecParam, error, CFSTR("RSA-WRAP bad ciphertext, unexpected session key size")));
877
878 // Decrypt ciphertext using AES-GCM.
879 plaintext = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), CFDataGetLength(in1) - wrappedKeySize - kSecKeyIESTagLength);
880 tag = CFDataCreateMutableWithScratch(kCFAllocatorDefault, kSecKeyIESTagLength);
881 CFDataGetBytes(in1, CFRangeMake(CFDataGetLength(in1) - kSecKeyIESTagLength, kSecKeyIESTagLength),
882 CFDataGetMutableBytePtr(tag));
883 const UInt8 *ciphertextBuffer = CFDataGetBytePtr(in1);
884 ciphertextBuffer += wrappedKeySize;
885 require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
886 CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
887 sizeof(kSecKeyIESIV), kSecKeyIESIV,
888 CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
889 CFDataGetLength(plaintext), ciphertextBuffer, CFDataGetMutableBytePtr(plaintext),
890 kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
891 SecError(errSecParam, error, CFSTR("RSA-WRAP: Failed to aes-gcm decrypt data")));
892 result = CFRetain(plaintext);
893
894 out:
895 CFReleaseSafe(parameters);
896 CFReleaseSafe(sessionKey);
897 CFReleaseSafe(tag);
898 CFReleaseSafe(pubKeyData);
899 CFReleaseSafe(pubKey);
900 CFReleaseSafe(plaintext);
901 return result;
902 }
903
904 #define RSA_OAEP_AESGCM_ADAPTOR(hashname) \
905 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
906 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
907 return SecKeyRSAAESGCMCopyEncryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
908 } \
909 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
910 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
911 return SecKeyRSAAESGCMCopyDecryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
912 }
913
914 RSA_OAEP_AESGCM_ADAPTOR(SHA1)
915 RSA_OAEP_AESGCM_ADAPTOR(SHA224)
916 RSA_OAEP_AESGCM_ADAPTOR(SHA256)
917 RSA_OAEP_AESGCM_ADAPTOR(SHA384)
918 RSA_OAEP_AESGCM_ADAPTOR(SHA512)
919
920 #undef RSA_OAEP_AESGCM_ADAPTOR
921
922 SecKeyAlgorithmAdaptor SecKeyGetAlgorithmAdaptor(SecKeyOperationType operation, SecKeyAlgorithm algorithm) {
923 static CFDictionaryRef adaptors[kSecKeyOperationTypeCount];
924 static dispatch_once_t onceToken;
925 dispatch_once(&onceToken, ^{
926 const void *signKeys[] = {
927 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
928 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
929 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
930 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
931 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
932 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
933 kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
934
935 kSecKeyAlgorithmRSASignatureRaw,
936 kSecKeyAlgorithmRSASignatureRawCCUnit,
937
938 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
939 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
940 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
941 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
942 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
943 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
944
945 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
946 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
947 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
948 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
949 kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
950
951 kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
952 kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
953 kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
954 kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
955 kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
956 };
957 const void *signValues[] = {
958 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA1,
959 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA224,
960 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA256,
961 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA384,
962 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA512,
963 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15Raw,
964 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15MD5,
965
966 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw,
967 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit,
968
969 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
970 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
971 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
972 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
973 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
974 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
975
976 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
977 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
978 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
979 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
980 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
981
982 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
983 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
984 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
985 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
986 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
987 };
988 check_compile_time(array_size(signKeys) == array_size(signValues));
989 adaptors[kSecKeyOperationTypeSign] = CFDictionaryCreate(kCFAllocatorDefault, signKeys, signValues,
990 array_size(signKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
991
992 const void *verifyKeys[] = {
993 kSecKeyAlgorithmRSASignatureRaw,
994
995 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
996 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
997 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
998 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
999 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1000 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
1001 kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
1002
1003 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1004 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1005 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1006 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1007 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1008 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
1009
1010 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
1011 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
1012 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
1013 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
1014 kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
1015
1016 kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
1017 kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
1018 kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
1019 kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
1020 kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
1021 };
1022 const void *verifyValues[] = {
1023 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw,
1024
1025 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA1,
1026 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA224,
1027 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA256,
1028 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA384,
1029 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA512,
1030 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15Raw,
1031 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15MD5,
1032
1033 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
1034 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
1035 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
1036 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
1037 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
1038 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
1039
1040 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
1041 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
1042 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
1043 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
1044 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
1045
1046 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
1047 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
1048 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
1049 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
1050 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
1051 };
1052 check_compile_time(array_size(verifyKeys) == array_size(verifyValues));
1053 adaptors[kSecKeyOperationTypeVerify] = CFDictionaryCreate(kCFAllocatorDefault, verifyKeys, verifyValues,
1054 array_size(verifyKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1055
1056 const void *encryptKeys[] = {
1057 kSecKeyAlgorithmRSAEncryptionRaw,
1058 kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1059
1060 kSecKeyAlgorithmRSAEncryptionPKCS1,
1061 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1062 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1063 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1064 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1065 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1066
1067 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1068 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1069 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1070 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1071 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1072
1073 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1074 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1075 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1076 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1077 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1078
1079 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1080 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1081 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1082 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1083 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1084 };
1085 const void *encryptValues[] = {
1086 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1087 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1088
1089 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1,
1090 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1,
1091 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224,
1092 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256,
1093 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384,
1094 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512,
1095
1096 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM,
1097 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM,
1098 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM,
1099 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM,
1100 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM,
1101
1102 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1,
1103 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224,
1104 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256,
1105 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384,
1106 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512,
1107
1108 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1,
1109 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224,
1110 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256,
1111 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384,
1112 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512,
1113 };
1114 check_compile_time(array_size(encryptKeys) == array_size(encryptValues));
1115 adaptors[kSecKeyOperationTypeEncrypt] = CFDictionaryCreate(kCFAllocatorDefault, encryptKeys, encryptValues,
1116 array_size(encryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1117
1118 const void *decryptKeys[] = {
1119 kSecKeyAlgorithmRSAEncryptionRaw,
1120 kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1121
1122 kSecKeyAlgorithmRSAEncryptionPKCS1,
1123 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1124 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1125 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1126 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1127 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1128
1129 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1130 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1131 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1132 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1133 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1134
1135 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1136 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1137 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1138 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1139 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1140
1141 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1142 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1143 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1144 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1145 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1146
1147 kSecKeyAlgorithmECIESEncryptionAKSSmartCard,
1148 };
1149 const void *decryptValues[] = {
1150 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1151 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1152
1153 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1,
1154 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1,
1155 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224,
1156 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256,
1157 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384,
1158 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512,
1159
1160 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM,
1161 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM,
1162 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM,
1163 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM,
1164 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM,
1165
1166 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1,
1167 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224,
1168 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256,
1169 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384,
1170 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512,
1171
1172 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1,
1173 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224,
1174 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256,
1175 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384,
1176 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512,
1177
1178 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys,
1179 };
1180 check_compile_time(array_size(decryptKeys) == array_size(decryptValues));
1181 adaptors[kSecKeyOperationTypeDecrypt] = CFDictionaryCreate(kCFAllocatorDefault, decryptKeys, decryptValues,
1182 array_size(decryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1183
1184 const void *keyExchangeKeys[] = {
1185 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
1186 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
1187 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
1188 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
1189 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
1190
1191 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
1192 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
1193 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
1194 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
1195 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
1196 };
1197 const void *keyExchangeValues[] = {
1198
1199 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1,
1200 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224,
1201 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256,
1202 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384,
1203 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512,
1204
1205 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1,
1206 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224,
1207 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256,
1208 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384,
1209 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512,
1210 };
1211 check_compile_time(array_size(keyExchangeKeys) == array_size(keyExchangeKeys));
1212 adaptors[kSecKeyOperationTypeKeyExchange] = CFDictionaryCreate(kCFAllocatorDefault, keyExchangeKeys, keyExchangeValues,
1213 array_size(keyExchangeKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1214 });
1215
1216 return CFDictionaryGetValue(adaptors[operation], algorithm);
1217 }