2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecKeyAdaptors.m - 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().
31 #import <Foundation/Foundation.h>
33 #include <Security/SecBase.h>
34 #include <Security/SecKeyInternal.h>
35 #include <Security/SecItem.h>
36 #include <Security/SecItemPriv.h>
37 #include <Security/SecCFAllocator.h>
39 #include <AssertMacros.h>
40 #include <utilities/SecCFWrappers.h>
41 #include <utilities/array_size.h>
42 #include <utilities/debugging.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecBuffer.h>
46 #include <corecrypto/ccsha1.h>
47 #include <corecrypto/ccsha2.h>
48 #include <corecrypto/ccmd5.h>
49 #include <corecrypto/ccrsa_priv.h>
50 #include <corecrypto/ccansikdf.h>
51 #include <corecrypto/ccmode.h>
52 #include <corecrypto/ccaes.h>
53 #include <corecrypto/ccder.h>
56 #pragma mark Algorithm constants value definitions
58 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw = CFSTR("algid:sign:RSA:raw");
59 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit = CFSTR("algid:sign:RSA:raw-cc");
61 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw = CFSTR("algid:sign:RSA:digest-PKCS1v15");
62 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5 = CFSTR("algid:sign:RSA:digest-PKCS1v15:MD5");
63 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA1");
64 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA224");
65 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA256");
66 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA384");
67 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512 = CFSTR("algid:sign:RSA:digest-PKCS1v15:SHA512");
68 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA1 = CFSTR("algid:sign:RSA:digest-PSS:SHA1:SHA1:20");
69 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA224 = CFSTR("algid:sign:RSA:digest-PSS:SHA224:SHA224:24");
70 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA256 = CFSTR("algid:sign:RSA:digest-PSS:SHA256:SHA256:32");
71 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA384 = CFSTR("algid:sign:RSA:digest-PSS:SHA384:SHA384:48");
72 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA512 = CFSTR("algid:sign:RSA:digest-PSS:SHA512:SHA512:64");
74 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5 = CFSTR("algid:sign:RSA:message-PKCS1v15:MD5");
75 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA1");
76 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA224");
77 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA256");
78 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA384");
79 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512 = CFSTR("algid:sign:RSA:message-PKCS1v15:SHA512");
80 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA1 = CFSTR("algid:sign:RSA:message-PSS:SHA1:SHA1:20");
81 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA224 = CFSTR("algid:sign:RSA:message-PSS:SHA224:SHA224:24");
82 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA256 = CFSTR("algid:sign:RSA:message-PSS:SHA256:SHA256:32");
83 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA384 = CFSTR("algid:sign:RSA:message-PSS:SHA384:SHA384:48");
84 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureMessagePSSSHA512 = CFSTR("algid:sign:RSA:message-PSS:SHA512:SHA512:64");
86 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754 = CFSTR("algid:sign:ECDSA:RFC4754");
88 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962 = CFSTR("algid:sign:ECDSA:digest-X962");
89 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA1 = CFSTR("algid:sign:ECDSA:digest-X962:SHA1");
90 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA224 = CFSTR("algid:sign:ECDSA:digest-X962:SHA224");
91 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA256 = CFSTR("algid:sign:ECDSA:digest-X962:SHA256");
92 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA384 = CFSTR("algid:sign:ECDSA:digest-X962:SHA384");
93 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureDigestX962SHA512 = CFSTR("algid:sign:ECDSA:digest-X962:SHA512");
95 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA1 = CFSTR("algid:sign:ECDSA:message-X962:SHA1");
96 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA224 = CFSTR("algid:sign:ECDSA:message-X962:SHA224");
97 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA256 = CFSTR("algid:sign:ECDSA:message-X962:SHA256");
98 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA384 = CFSTR("algid:sign:ECDSA:message-X962:SHA384");
99 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureMessageX962SHA512 = CFSTR("algid:sign:ECDSA:message-X962:SHA512");
101 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRaw = CFSTR("algid:encrypt:RSA:raw");
102 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionRawCCUnit = CFSTR("algid:encrypt:RSA:raw-cc");
103 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionPKCS1 = CFSTR("algid:encrypt:RSA:PKCS1");
104 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1 = CFSTR("algid:encrypt:RSA:OAEP:SHA1");
105 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224 = CFSTR("algid:encrypt:RSA:OAEP:SHA224");
106 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256 = CFSTR("algid:encrypt:RSA:OAEP:SHA256");
107 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384 = CFSTR("algid:encrypt:RSA:OAEP:SHA384");
108 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512 = CFSTR("algid:encrypt:RSA:OAEP:SHA512");
110 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA1:AESGCM");
111 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA224:AESGCM");
112 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA256:AESGCM");
113 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA384:AESGCM");
114 const SecKeyAlgorithm kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM = CFSTR("algid:encrypt:RSA:OAEP:SHA512:AESGCM");
116 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA1:AESGCM");
117 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM");
118 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM");
119 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM");
120 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM");
122 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA1:AESGCM");
123 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM");
124 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM");
125 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM");
126 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM");
128 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA224:AESGCM-KDFIV");
129 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA256:AESGCM-KDFIV");
130 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA384:AESGCM-KDFIV");
131 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDH:KDFX963:SHA512:AESGCM-KDFIV");
133 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA224:AESGCM-KDFIV");
134 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV");
135 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA384:AESGCM-KDFIV");
136 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM = CFSTR("algid:encrypt:ECIES:ECDHC:KDFX963:SHA512:AESGCM-KDFIV");
138 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandard = CFSTR("algid:keyexchange:ECDH");
139 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA1");
140 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA224");
141 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA256");
142 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA384");
143 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512 = CFSTR("algid:keyexchange:ECDH:KDFX963:SHA512");
145 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactor = CFSTR("algid:keyexchange:ECDHC");
146 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA1");
147 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA224");
148 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA256");
149 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA384");
150 const SecKeyAlgorithm kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512 = CFSTR("algid:keyexchange:ECDHC:KDFX963:SHA512");
152 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
154 void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
155 CFReleaseNull(context->algorithm);
158 static void PerformWithCFDataBuffer(CFIndex size, void (^operation)(uint8_t *buffer, CFDataRef data)) {
159 PerformWithBuffer(size, ^(size_t size, uint8_t *buffer) {
160 CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)buffer, size, kCFAllocatorNull);
161 operation(buffer, data);
166 static CFDataRef SecKeyCopyDigestForMessage(SecKeyOperationContext *context, CFDataRef message, CFDataRef in2,
167 const struct ccdigest_info *di, CFErrorRef *error) {
168 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
169 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
172 __block CFTypeRef result;
173 PerformWithCFDataBuffer(di->output_size, ^(uint8_t *buffer, CFDataRef data) {
174 ccdigest(di, CFDataGetLength(message), CFDataGetBytePtr(message), buffer);
175 result = SecKeyRunAlgorithmAndCopyResult(context, data, in2, error);
180 static CFTypeRef SecKeyCopyECDSASignatureForDigest(SecKeyOperationContext *context, CFDataRef digest, CFDataRef in2,
181 SecKeyAlgorithm algorithm, const struct ccdigest_info *di, CFErrorRef *error) {
182 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigestX962);
183 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
184 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
187 if (CFDataGetLength(digest) != (CFIndex)di->output_size) {
188 SecError(errSecParam, error, CFSTR("bad digest size for signing with algorithm %@"), algorithm);
192 return SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
195 #define DIGEST_RSA_ADAPTORS(name, di) \
196 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessage ## name( \
197 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
198 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigest ## name); \
199 return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
202 #define DIGEST_ECDSA_ADAPTORS(name, di) \
203 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessage ## name( \
204 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
205 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDSASignatureDigest ## name); \
206 return SecKeyCopyDigestForMessage(context, in1, in2, di, error); \
208 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigest ## name( \
209 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
210 return SecKeyCopyECDSASignatureForDigest(context, in1, in2, kSecKeyAlgorithmECDSASignatureDigest ## name, di, error); \
213 DIGEST_RSA_ADAPTORS(PKCS1v15SHA1, ccsha1_di())
214 DIGEST_RSA_ADAPTORS(PKCS1v15SHA224, ccsha224_di())
215 DIGEST_RSA_ADAPTORS(PKCS1v15SHA256, ccsha256_di())
216 DIGEST_RSA_ADAPTORS(PKCS1v15SHA384, ccsha384_di())
217 DIGEST_RSA_ADAPTORS(PKCS1v15SHA512, ccsha512_di())
218 DIGEST_RSA_ADAPTORS(PKCS1v15MD5, ccmd5_di())
219 DIGEST_RSA_ADAPTORS(PSSSHA1, ccsha1_di())
220 DIGEST_RSA_ADAPTORS(PSSSHA224, ccsha224_di())
221 DIGEST_RSA_ADAPTORS(PSSSHA256, ccsha256_di())
222 DIGEST_RSA_ADAPTORS(PSSSHA384, ccsha384_di())
223 DIGEST_RSA_ADAPTORS(PSSSHA512, ccsha512_di())
224 DIGEST_ECDSA_ADAPTORS(X962SHA1, ccsha1_di())
225 DIGEST_ECDSA_ADAPTORS(X962SHA224, ccsha224_di())
226 DIGEST_ECDSA_ADAPTORS(X962SHA256, ccsha256_di())
227 DIGEST_ECDSA_ADAPTORS(X962SHA384, ccsha384_di())
228 DIGEST_ECDSA_ADAPTORS(X962SHA512, ccsha512_di())
230 #undef DIGEST_RSA_ADAPTORS
231 #undef DIGEST_ECDSA_ADAPTORS
233 typedef CF_ENUM(CFIndex, SecKeyECSignatureType) {
234 kSecKeyECSignatureTypeRFC4754,
235 kSecKeyECSignatureTypeX962,
238 static CFDataRef SecKeyCopyConvertedECDSASignature(SecKeyOperationContext *context, SecKeyECSignatureType targetType, CFDataRef sourceSignature, OSStatus errorStatus, CFErrorRef *error) {
239 CFMutableDataRef targetSignature = NULL;
240 CFIndex keySize = SecKeyGetBlockSize(context->key);
241 cc_size ccn = ccn_nof_size(keySize);
242 cc_unit ccr[ccn], ccs[ccn];
243 const uint8_t *data = CFDataGetBytePtr(sourceSignature);
244 if (targetType == kSecKeyECSignatureTypeRFC4754) {
245 // Extract ASN.1 DER signature and create raw r-s big-endian encoded signature.
246 const uint8_t *der_end = data + CFDataGetLength(sourceSignature);
247 if (ccder_decode_seqii(ccn, ccr, ccs, data, der_end) == der_end) {
248 targetSignature = CFDataCreateMutableWithScratch(kCFAllocatorDefault, keySize * 2);
249 uint8_t *target = CFDataGetMutableBytePtr(targetSignature);
250 ccn_write_uint_padded(ccn, ccr, keySize, target);
251 ccn_write_uint_padded(ccn, ccs, keySize, target + keySize);
253 SecError(errorStatus, error, CFSTR("Wrong ECDSA X962 signature"));
256 // Extract raw r-s big-endian encoded signature and encode ASN.1 DER signature.
257 if (CFDataGetLength(sourceSignature) == 2 * (CFIndex)keySize &&
258 ccn_read_uint(ccn, ccr, keySize, data) == 0 && ccn_read_uint(ccn, ccs, keySize, data + keySize) == 0) {
259 size_t s_len = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE,
260 ccder_sizeof_integer(ccn, ccr) +
261 ccder_sizeof_integer(ccn, ccs));
262 targetSignature = CFDataCreateMutableWithScratch(kCFAllocatorDefault, s_len);
263 uint8_t *der = CFDataGetMutableBytePtr(targetSignature);
264 uint8_t *der_end = der + s_len;
265 if (ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
266 ccder_encode_integer(ccn, ccr, der,
267 ccder_encode_integer(ccn, ccs, der, der_end))) == NULL) {
268 CFReleaseNull(targetSignature);
269 SecError(errSecInternal, error, CFSTR("Failed to encode X962 signature"));
272 SecError(errorStatus, error, CFSTR("Wrong ECDSA RFC4754 signature"));
276 return targetSignature;
279 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureConvert(SecKeyOperationContext *context,
280 SecKeyECSignatureType signatureType,
281 CFTypeRef digest, CFTypeRef in2, CFErrorRef *error) {
282 CFArrayAppendValue(context->algorithm, signatureType == kSecKeyECSignatureTypeRFC4754 ? kSecKeyAlgorithmECDSASignatureDigestX962 : kSecKeyAlgorithmECDSASignatureRFC4754);
283 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
284 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
287 CFDataRef signature = SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
288 if (signature == NULL || CFEqual(signature, kCFNull)) {
292 // Convert the signature.
293 CFAssignRetained(signature, SecKeyCopyConvertedECDSASignature(context, signatureType, signature, errSecParam, error));
297 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureConvert(SecKeyOperationContext *context,
298 SecKeyECSignatureType signatureType,
299 CFTypeRef digest, CFTypeRef signature, CFErrorRef *error) {
300 SecKeyECSignatureType targetSignatureType = (signatureType == kSecKeyECSignatureTypeRFC4754) ? kSecKeyECSignatureTypeX962 : kSecKeyECSignatureTypeRFC4754;
301 CFArrayAppendValue(context->algorithm, targetSignatureType == kSecKeyECSignatureTypeRFC4754 ? kSecKeyAlgorithmECDSASignatureRFC4754 : kSecKeyAlgorithmECDSASignatureDigestX962);
302 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
303 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
306 CFDataRef convertedSignature = SecKeyCopyConvertedECDSASignature(context, targetSignatureType, signature, errSecVerifyFailed, error);
307 CFTypeRef result = NULL;
308 if (convertedSignature != NULL) {
309 result = SecKeyRunAlgorithmAndCopyResult(context, digest, convertedSignature, error);
310 CFReleaseNull(convertedSignature);
315 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureRFC4754(SecKeyOperationContext *context,
316 CFTypeRef digest, CFTypeRef signature, CFErrorRef *error) {
317 return SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureConvert(context, kSecKeyECSignatureTypeRFC4754, digest, signature, error);
319 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureDigestX962(SecKeyOperationContext *context,
320 CFTypeRef digest, CFTypeRef signature, CFErrorRef *error) {
321 return SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureConvert(context, kSecKeyECSignatureTypeX962, digest, signature, error);
324 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureRFC4754(SecKeyOperationContext *context,
325 CFTypeRef digest, CFTypeRef signature, CFErrorRef *error) {
326 return SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureConvert(context, kSecKeyECSignatureTypeRFC4754, digest, signature, error);
328 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureDigestX962(SecKeyOperationContext *context,
329 CFTypeRef digest, CFTypeRef signature, CFErrorRef *error) {
330 return SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureConvert(context, kSecKeyECSignatureTypeX962, digest, signature, error);
333 static CFDataRef SecKeyRSACopyBigEndianToCCUnit(CFDataRef bigEndian, size_t size) {
334 CFMutableDataRef result = NULL;
335 if (bigEndian != NULL) {
336 size_t dataSize = CFDataGetLength(bigEndian);
337 if (dataSize > size) {
340 result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, ccn_sizeof_size(size));
341 ccn_read_uint(ccn_nof_size(size), (cc_unit *)CFDataGetMutableBytePtr(result), dataSize, CFDataGetBytePtr(bigEndian));
346 static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian, size_t size, void (^operation)(CFDataRef ccunits)) {
347 if (bigEndian == NULL) {
348 return operation(NULL);
350 size_t dataSize = CFDataGetLength(bigEndian);
351 if (dataSize > size) {
354 PerformWithCFDataBuffer(ccn_sizeof_size(size), ^(uint8_t *buffer, CFDataRef data) {
355 ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, dataSize, CFDataGetBytePtr(bigEndian));
360 static CFDataRef SecKeyRSACopyCCUnitToBigEndian(CFDataRef ccunits, size_t size) {
361 CFMutableDataRef result = NULL;
362 if (ccunits != NULL) {
363 cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
364 const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
365 result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, size);
366 ccn_write_uint_padded(n, s, CFDataGetLength(result), CFDataGetMutableBytePtr(result));
371 static void PerformWithCCUnitToBigEndian(CFDataRef ccunits, size_t size, void (^operation)(CFDataRef bigEndian)) {
372 if (ccunits == NULL) {
373 return operation(NULL);
375 PerformWithCFDataBuffer(size, ^(uint8_t *buffer, CFDataRef data) {
376 cc_size n = ccn_nof_size(CFDataGetLength(ccunits));
377 const cc_unit *s = (const cc_unit *)CFDataGetBytePtr(ccunits);
378 ccn_write_uint_padded(n, s, size, buffer);
383 static CFTypeRef SecKeyRSACopyEMSASignature(SecKeyOperationContext *context,
384 CFDataRef in1, CFDataRef in2, CFErrorRef *error, bool pss, const struct ccdigest_info *di) {
385 CFDictionaryRef parameters = NULL;
386 __block CFTypeRef result = NULL;
388 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
389 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
390 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
391 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
392 CFReleaseNull(parameters);
395 // Verify that algorithm is compatible with the modulus size.
396 size_t blockSize = SecKeyGetBlockSize(context->key);
397 require_action_quiet(blockSize >= di->output_size * 2 + 2, out,
398 SecError(errSecParam, error, CFSTR("algorithm %@ incompatible with %lubit RSA key"),
399 CFArrayGetValueAtIndex(context->algorithm, CFArrayGetCount(context->algorithm) - 1),
403 if (!pss && di != NULL) {
404 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw);
407 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
408 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
409 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
412 size_t size = SecKeyGetBlockSize(context->key);
414 SecError(errSecParam, error, CFSTR("expecting RSA key"));
417 PerformWithCFDataBuffer(ccn_sizeof_size(size), ^(uint8_t *buffer, CFDataRef data) {
418 NSMutableData *s = [NSMutableData dataWithLength:size];
419 require_action_quiet(s != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory")));
421 NSMutableData *salt = [NSMutableData dataWithLength:di->output_size];
422 require_action_quiet(salt != nil, out, SecError(errSecAllocate, error, CFSTR("out of memory")));
423 int err = ccrng_generate(ccrng_seckey, di->output_size, salt.mutableBytes);
424 require_noerr_action_quiet(err, out, SecError(errSecInternal, error, CFSTR("PSS salt gen fail (%zu bytes), err %d"),
425 di->output_size, err));
426 err = ccrsa_emsa_pss_encode(di, di, di->output_size, salt.bytes,
427 CFDataGetLength(in1), CFDataGetBytePtr(in1), size * 8 - 1, s.mutableBytes);
428 require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSASSA-PSS incompatible algorithm for key size")));
430 int err = ccrsa_emsa_pkcs1v15_encode(size, s.mutableBytes, CFDataGetLength(in1), CFDataGetBytePtr(in1), di ? di->oid : NULL);
431 require_noerr_action_quiet(err, out, SecError(errSecParam, error, CFSTR("RSAsign wrong input data length")));
433 ccn_read_uint(ccn_nof_size(size), (cc_unit *)buffer, size, s.bytes);
434 require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
435 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
440 CFReleaseSafe(parameters);
444 #define RSA_EMSA_SIGN_ADAPTOR(name, pss, di) \
445 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigest ## name( \
446 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
447 return SecKeyRSACopyEMSASignature(context, in1, in2, error, pss, di); \
450 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA1, false, ccsha1_di())
451 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA224, false, ccsha224_di())
452 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA256, false, ccsha256_di())
453 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA384, false, ccsha384_di())
454 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15SHA512, false, ccsha512_di())
455 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15Raw, false, NULL)
456 RSA_EMSA_SIGN_ADAPTOR(PKCS1v15MD5, false, ccmd5_di())
457 RSA_EMSA_SIGN_ADAPTOR(PSSSHA1, true, ccsha1_di())
458 RSA_EMSA_SIGN_ADAPTOR(PSSSHA224, true, ccsha224_di())
459 RSA_EMSA_SIGN_ADAPTOR(PSSSHA256, true, ccsha256_di())
460 RSA_EMSA_SIGN_ADAPTOR(PSSSHA384, true, ccsha384_di())
461 RSA_EMSA_SIGN_ADAPTOR(PSSSHA512, true, ccsha512_di())
463 #undef RSA_EMSA_SIGN_ADAPTOR
465 static CFTypeRef SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(SecKeyOperationContext *context,
466 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
467 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
468 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
471 __block CFTypeRef result = NULL;
472 PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
473 result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, in2, error);
474 if (result != NULL) {
475 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
481 static CFTypeRef SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(SecKeyOperationContext *context,
482 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
483 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
484 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
487 __block CFTypeRef result = NULL;
488 PerformWithCCUnitToBigEndian(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef bigEndian) {
489 result = SecKeyRunAlgorithmAndCopyResult(context, bigEndian, in2, error);
490 if (result != NULL) {
491 CFAssignRetained(result, SecKeyRSACopyBigEndianToCCUnit(result, SecKeyGetBlockSize(context->key)));
497 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw(SecKeyOperationContext *context,
498 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
499 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
500 return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
503 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit(SecKeyOperationContext *context,
504 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
505 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRaw);
506 return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
509 static bool SecKeyVerifyBadSignature(CFErrorRef *error) {
510 return SecError(errSecVerifyFailed, error, CFSTR("RSA signature verification failed, no match"));
513 static CFTypeRef SecKeyRSAVerifyAdaptorCopyResult(SecKeyOperationContext *context, CFTypeRef signature, CFErrorRef *error,
514 Boolean (^verifyBlock)(CFDataRef decrypted)) {
515 CFTypeRef result = NULL;
516 context->operation = kSecKeyOperationTypeDecrypt;
517 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
518 result = SecKeyRunAlgorithmAndCopyResult(context, signature, NULL, error);
519 if (context->mode == kSecKeyOperationModePerform && result != NULL) {
520 if (verifyBlock(result)) {
521 CFRetainAssign(result, kCFBooleanTrue);
523 CFRetainAssign(result, kCFBooleanFalse);
524 SecKeyVerifyBadSignature(error);
530 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw(SecKeyOperationContext *context,
531 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
532 return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) {
533 // Skip zero-padding from the beginning of the decrypted signature.
534 const UInt8 *data = CFDataGetBytePtr(decrypted);
535 CFIndex length = CFDataGetLength(decrypted);
536 while (*data == 0x00 && length > 0) {
540 // The rest of the decrypted signature must be the same as input data.
541 return length == CFDataGetLength(in1) && memcmp(CFDataGetBytePtr(in1), data, length) == 0;
545 #define PKCS1v15_EMSA_VERIFY_ADAPTOR(name, oid) \
546 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15 ## name( \
547 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
548 return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
549 return ccrsa_emsa_pkcs1v15_verify(CFDataGetLength(decrypted), \
550 (uint8_t *)CFDataGetBytePtr(decrypted), \
551 CFDataGetLength(in1), CFDataGetBytePtr(in1), oid) == 0; \
555 #define PSS_EMSA_VERIFY_ADAPTOR(name, di) \
556 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSS ## name( \
557 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
558 return SecKeyRSAVerifyAdaptorCopyResult(context, in2, error, ^Boolean(CFDataRef decrypted) { \
559 return ccrsa_emsa_pss_decode(di, di, di->output_size, CFDataGetLength(in1), CFDataGetBytePtr(in1), \
560 CFDataGetLength(decrypted) * 8 - 1, (uint8_t *)CFDataGetBytePtr(decrypted)) == 0; \
564 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di()->oid)
565 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di()->oid)
566 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di()->oid)
567 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di()->oid)
568 PKCS1v15_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di()->oid)
569 PKCS1v15_EMSA_VERIFY_ADAPTOR(Raw, NULL)
570 PKCS1v15_EMSA_VERIFY_ADAPTOR(MD5, ccmd5_di()->oid)
572 PSS_EMSA_VERIFY_ADAPTOR(SHA1, ccsha1_di())
573 PSS_EMSA_VERIFY_ADAPTOR(SHA224, ccsha224_di())
574 PSS_EMSA_VERIFY_ADAPTOR(SHA256, ccsha256_di())
575 PSS_EMSA_VERIFY_ADAPTOR(SHA384, ccsha384_di())
576 PSS_EMSA_VERIFY_ADAPTOR(SHA512, ccsha512_di())
578 #undef PKCS1v15_EMSA_VERIFY_ADAPTOR
579 #undef PSS_EMSA_VERIFY_ADAPTOR
581 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw(SecKeyOperationContext *context,
582 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
583 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
584 return SecKeyAlgorithmAdaptorCopyBigEndianToCCUnit(context, in1, in2, error);
587 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit(SecKeyOperationContext *context,
588 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
589 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRaw);
590 return SecKeyAlgorithmAdaptorCopyCCUnitToBigEndian(context, in1, in2, error);
593 static CFTypeRef SecKeyRSACopyEncryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
594 CFDataRef in1, CFErrorRef *error) {
595 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
596 size_t size = SecKeyGetBlockSize(context->key);
597 size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
598 if (size < minSize) {
601 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
602 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
605 __block CFTypeRef result = NULL;
606 PerformWithCFDataBuffer(ccn_sizeof_size(size), ^(uint8_t *buffer, CFDataRef data) {
609 err = ccrsa_oaep_encode(di, ccrng_seckey, size, (cc_unit *)buffer,
610 CFDataGetLength(in1), CFDataGetBytePtr(in1));
612 err = ccrsa_eme_pkcs1v15_encode(ccrng_seckey, size, (cc_unit *)buffer,
613 CFDataGetLength(in1), CFDataGetBytePtr(in1));
615 require_noerr_action_quiet(err, out, SecError(errSecParam, error,
616 CFSTR("RSAencrypt wrong input size (err %d)"), err));
617 cc_clear(ccn_sizeof_size(size) - size, buffer + size);
618 require_quiet(result = SecKeyRunAlgorithmAndCopyResult(context, data, NULL, error), out);
619 CFAssignRetained(result, SecKeyRSACopyCCUnitToBigEndian(result, SecKeyGetBlockSize(context->key)));
625 static CFTypeRef SecKeyRSACopyDecryptedWithPadding(SecKeyOperationContext *context, const struct ccdigest_info *di,
626 CFDataRef in1, CFErrorRef *error) {
627 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSAEncryptionRawCCUnit);
628 size_t minSize = (di != NULL) ? di->output_size * 2 + 2 : 11;
629 if (SecKeyGetBlockSize(context->key) < minSize) {
632 if (context->mode == kSecKeyOperationModeCheckIfSupported) {
633 return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
636 __block CFMutableDataRef result = NULL;
637 PerformWithBigEndianToCCUnit(in1, SecKeyGetBlockSize(context->key), ^(CFDataRef ccunits) {
638 CFDataRef cc_result = NULL;
639 require_quiet(cc_result = SecKeyRunAlgorithmAndCopyResult(context, ccunits, NULL, error), out);
640 size_t size = SecKeyGetBlockSize(context->key);
641 result = CFDataCreateMutableWithScratch(NULL, size);
644 err = ccrsa_oaep_decode(di, &size, CFDataGetMutableBytePtr(result),
645 size, (cc_unit *)CFDataGetBytePtr(cc_result));
647 err = ccrsa_eme_pkcs1v15_decode(&size, CFDataGetMutableBytePtr(result),
648 size, (cc_unit *)CFDataGetBytePtr(cc_result));
650 require_noerr_action_quiet(err, out, (CFReleaseNull(result),
651 SecError(errSecParam, error, CFSTR("RSAdecrypt wrong input (err %d)"), err)));
652 CFDataSetLength(result, size);
654 CFReleaseSafe(cc_result);
659 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
660 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
661 return SecKeyRSACopyEncryptedWithPadding(context, NULL, in1, error);
664 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
665 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
666 return SecKeyRSACopyDecryptedWithPadding(context, NULL, in1, error);
669 #define RSA_OAEP_CRYPT_ADAPTOR(name, di) \
670 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## name( \
671 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
672 return SecKeyRSACopyEncryptedWithPadding(context, di, in1, error); \
674 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
675 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
676 return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
679 RSA_OAEP_CRYPT_ADAPTOR(SHA1, ccsha1_di());
680 RSA_OAEP_CRYPT_ADAPTOR(SHA224, ccsha224_di());
681 RSA_OAEP_CRYPT_ADAPTOR(SHA256, ccsha256_di());
682 RSA_OAEP_CRYPT_ADAPTOR(SHA384, ccsha384_di());
683 RSA_OAEP_CRYPT_ADAPTOR(SHA512, ccsha512_di());
685 #undef RSA_OAEP_CRYPT_ADAPTOR
687 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
688 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
690 const CFStringRef kSecKeyEncryptionParameterSymmetricKeySizeInBits = CFSTR("symKeySize");
691 const CFStringRef kSecKeyEncryptionParameterSymmetricAAD = CFSTR("aad");
692 const CFStringRef kSecKeyEncryptionParameterRecryptParameters = CFSTR("recryptParams");
693 const CFStringRef kSecKeyEncryptionParameterRecryptCertificate = CFSTR("recryptCert");
695 static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
696 CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
697 CFTypeRef result = NULL, sharedSecret;
698 require_quiet(sharedSecret = SecKeyRunAlgorithmAndCopyResult(context, in1, NULL, error), out);
700 if (context->mode == kSecKeyOperationModePerform) {
702 CFTypeRef value = NULL;
703 CFIndex requestedSize = 0;
704 require_action_quiet((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterRequestedSize)) != NULL
705 && CFGetTypeID(value) == CFNumberGetTypeID() &&
706 CFNumberGetValue(value, kCFNumberCFIndexType, &requestedSize), out,
707 SecError(errSecParam, error, CFSTR("kSecKeyKeyExchangeParameterRequestedSize is missing")));
708 size_t sharedInfoLength = 0;
709 const void *sharedInfo = NULL;
710 if ((value = CFDictionaryGetValue(params, kSecKeyKeyExchangeParameterSharedInfo)) != NULL) {
711 require_action_quiet(CFGetTypeID(value) == CFDataGetTypeID(), out, SecError(errSecParam, error, CFSTR("ECDHKeyExchange wrong sharedInfo type (must be CFData/NSData)")));
712 sharedInfo = CFDataGetBytePtr(value);
713 sharedInfoLength = CFDataGetLength(value);
716 CFMutableDataRef kdfResult = CFDataCreateMutableWithScratch(kCFAllocatorDefault, requestedSize);
717 int err = ccansikdf_x963(di, CFDataGetLength(sharedSecret), CFDataGetBytePtr(sharedSecret), sharedInfoLength, sharedInfo,
718 requestedSize, CFDataGetMutableBytePtr(kdfResult));
719 require_noerr_action_quiet(err, out, (CFReleaseNull(kdfResult),
720 SecError(errSecParam, error, CFSTR("ECDHKeyExchange wrong input (%d)"), err)));
721 CFAssignRetained(result, kdfResult);
723 // In test-only mode, propagate result (YES/NO) of underlying operation.
724 CFRetainAssign(result, sharedSecret);
727 CFReleaseNull(sharedSecret);
731 #define ECDH_X963_ADAPTOR(hashname, di, cofactor) \
732 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDH ## cofactor ## X963 ## hashname( \
733 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
734 CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmECDHKeyExchange ## cofactor); \
735 return SecKeyECDHCopyX963Result(context, di, in1, in2, error); \
738 ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Standard)
739 ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Standard)
740 ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Standard)
741 ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Standard)
742 ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Standard)
743 ECDH_X963_ADAPTOR(SHA1, ccsha1_di(), Cofactor)
744 ECDH_X963_ADAPTOR(SHA224, ccsha224_di(), Cofactor)
745 ECDH_X963_ADAPTOR(SHA256, ccsha256_di(), Cofactor)
746 ECDH_X963_ADAPTOR(SHA384, ccsha384_di(), Cofactor)
747 ECDH_X963_ADAPTOR(SHA512, ccsha512_di(), Cofactor)
749 #undef ECDH_X963_ADAPTOR
751 // Extract number value of either CFNumber or CFString.
752 static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
754 if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
755 if (!CFNumberGetValue(ref, kCFNumberCFIndexType, &result)) {
758 } else if (CFGetTypeID(ref) == CFStringGetTypeID()) {
759 result = CFStringGetIntValue(ref);
764 typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV, CFDictionaryRef inParams, CFErrorRef *error);
765 typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams, CFMutableDataRef result, CFErrorRef *error);
766 typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams, CFErrorRef *error);
768 static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
769 SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
770 SecKeyECIESEncryptCopyResult encryptCopyResult, bool variableIV,
771 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
772 CFDictionaryRef parameters = NULL;
773 SecKeyRef ephemeralPrivateKey = NULL, ephemeralPublicKey = NULL;
774 CFDataRef pubKeyData = NULL, ephemeralPubKeyData = NULL, keyExchangeResult = NULL;
775 CFTypeRef result = NULL;
776 SecKeyRef originalKey = context->key;
777 CFMutableDataRef ciphertext = NULL;
779 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
780 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
781 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
782 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
784 // Generate ephemeral key.
785 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
786 CFAssignRetained(parameters, CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
788 kSecUseDataProtectionKeychain, kCFBooleanTrue,
790 kSecAttrKeyType, CFDictionaryGetValue(parameters, kSecAttrKeyType),
791 kSecAttrKeySizeInBits, CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits),
793 require_quiet(ephemeralPrivateKey = SecKeyCreateRandomKey(parameters, error), out);
794 require_action_quiet(ephemeralPublicKey = SecKeyCopyPublicKey(ephemeralPrivateKey), out,
795 SecError(errSecParam, error, CFSTR("Unable to get public key from generated ECkey")));
796 require_quiet(ephemeralPubKeyData = SecKeyCopyExternalRepresentation(ephemeralPublicKey, error), out);
798 context->key = ephemeralPrivateKey;
799 require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
800 ephemeralPubKeyData, pubKeyData, variableIV, in2, error), out);
801 if (context->mode == kSecKeyOperationModePerform) {
802 // Encrypt input data using AES-GCM.
803 ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
804 require_quiet(encryptCopyResult(keyExchangeResult, in1, in2, ciphertext, error), out);
805 result = CFRetain(ciphertext);
807 result = CFRetain(keyExchangeResult);
811 CFReleaseSafe(parameters);
812 CFReleaseSafe(ephemeralPrivateKey);
813 CFReleaseSafe(ephemeralPublicKey);
814 CFReleaseSafe(pubKeyData);
815 CFReleaseSafe(ephemeralPubKeyData);
816 CFReleaseSafe(keyExchangeResult);
817 CFReleaseSafe(ciphertext);
818 context->key = originalKey;
822 static CFTypeRef SecKeyECIESCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
823 SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
824 SecKeyECIESDecryptCopyResult decryptCopyResult, bool variableIV,
825 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
826 CFTypeRef result = NULL;
827 CFDictionaryRef parameters = NULL;
828 CFDataRef ephemeralPubKeyData = NULL, keyExchangeResult = NULL, pubKeyData = NULL;
829 SecKeyRef pubKey = NULL;
830 CFDataRef ciphertext = NULL;
831 const UInt8 *ciphertextBuffer = NULL;
834 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
835 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
836 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeECSECPrimeRandom), out, result = kCFNull);
837 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
839 if (context->mode == kSecKeyOperationModePerform) {
840 // Extract ephemeral public key from the packet.
841 keySize = (SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits)) + 7) / 8;
842 require_action_quiet(CFDataGetLength(in1) >= keySize * 2 + 1, out,
843 SecError(errSecParam, error, CFSTR("%@: too small input packet for ECIES decrypt"), context->key));
844 ciphertextBuffer = CFDataGetBytePtr(in1);
845 ephemeralPubKeyData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, keySize * 2 + 1, kCFAllocatorNull);
846 ciphertextBuffer += keySize * 2 + 1;
848 require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
849 SecError(errSecParam, error, CFSTR("%@: Unable to get public key"), context->key));
850 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
853 // Perform keyExchange operation.
854 require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
855 ephemeralPubKeyData, pubKeyData, variableIV, in2, error), out);
856 if (context->mode == kSecKeyOperationModePerform) {
857 // Decrypt ciphertext using AES-GCM.
858 ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
860 require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, in2, error), out);
862 result = CFRetain(keyExchangeResult);
866 CFReleaseSafe(parameters);
867 CFReleaseSafe(ephemeralPubKeyData);
868 CFReleaseSafe(keyExchangeResult);
869 CFReleaseSafe(pubKeyData);
870 CFReleaseSafe(pubKey);
871 CFReleaseSafe(ciphertext);
875 static const CFIndex kSecKeyIESTagLength = 16;
876 static const UInt8 kSecKeyIESIV[16] = { 0 };
878 static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
879 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
880 CFDictionaryRef inParams, CFErrorRef *error) {
881 NSDictionary *parametersForKeyExchange, *inputParameters = (__bridge NSDictionary *)inParams;
883 NSMutableData *sharedInfoForKeyExchange;
885 CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
886 context->operation = kSecKeyOperationTypeKeyExchange;
888 if (context->mode == kSecKeyOperationModePerform) {
889 NSInteger keySize = 0;
890 NSNumber *keySizeObject = inputParameters[(__bridge id)kSecKeyEncryptionParameterSymmetricKeySizeInBits];
891 if (keySizeObject != nil) {
892 if (![keySizeObject isKindOfClass:NSNumber.class]) {
893 SecError(errSecParam, error, CFSTR("Bad requested kSecKeyEncryptionParameterSymmetricKeySizeInBits: %@"), keySizeObject);
896 keySize = keySizeObject.integerValue / 8;
898 // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
899 keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
900 keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
904 keySize += sizeof(kSecKeyIESIV);
907 // Generate shared secret using KDF.
908 sharedInfoForKeyExchange = ((__bridge NSData *)ephemeralPubKey).mutableCopy;
909 NSData *sharedInfo = inputParameters[(__bridge id)kSecKeyKeyExchangeParameterSharedInfo];
910 if (sharedInfo != nil) {
911 [sharedInfoForKeyExchange appendData:sharedInfo];
913 parametersForKeyExchange = @{ (__bridge id)kSecKeyKeyExchangeParameterSharedInfo: sharedInfoForKeyExchange,
914 (__bridge id)kSecKeyKeyExchangeParameterRequestedSize: @(keySize) };
917 result = CFBridgingRelease(SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, (__bridge CFDictionaryRef)parametersForKeyExchange, error));
918 if (context->mode == kSecKeyOperationModePerform && !variableIV && result != NULL) {
919 // Append all-zero IV to the result.
920 NSMutableData *data = result.mutableCopy;
921 [data appendBytes:kSecKeyIESIV length:sizeof(kSecKeyIESIV)];
922 result = [NSData dataWithData:data];
924 return CFBridgingRetain(result);
927 static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
928 CFMutableDataRef result, CFErrorRef *error) {
930 CFIndex prefix = CFDataGetLength(result);
931 CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
932 UInt8 *resultBuffer = CFDataGetMutableBytePtr(result) + prefix;
933 UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
934 CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
935 const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
936 CFDataRef aad = inParams ? CFDictionaryGetValue(inParams, kSecKeyEncryptionParameterSymmetricAAD) : NULL;
937 require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
938 aesKeySize, CFDataGetBytePtr(keyExchangeResult),
939 sizeof(kSecKeyIESIV), ivBuffer,
940 aad ? CFDataGetLength(aad) : 0, aad ? CFDataGetBytePtr(aad) : NULL,
941 CFDataGetLength(inData), CFDataGetBytePtr(inData),
942 resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
943 SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
949 static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
951 CFDataRef result = NULL;
952 CFMutableDataRef plaintext = NULL;
953 CFMutableDataRef tag = NULL;
954 require_action_quiet(CFDataGetLength(inData) >= kSecKeyIESTagLength, out, SecError(errSecParam, error, CFSTR("ECIES: Input data too short")));
955 plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
956 tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
957 CFDataGetBytes(inData, CFRangeMake(CFDataGetLength(inData) - kSecKeyIESTagLength, kSecKeyIESTagLength),
958 CFDataGetMutableBytePtr(tag));
959 CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
960 const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
961 CFDataRef aad = inParams ? CFDictionaryGetValue(inParams, kSecKeyEncryptionParameterSymmetricAAD) : NULL;
962 require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
963 aesKeySize, CFDataGetBytePtr(keyExchangeResult),
964 sizeof(kSecKeyIESIV), ivBuffer,
965 aad ? CFDataGetLength(aad) : 0, aad ? CFDataGetBytePtr(aad) : NULL,
966 CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
967 kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
968 SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
969 result = CFRetain(plaintext);
971 CFReleaseSafe(plaintext);
976 #define ECIES_X963_ADAPTOR(hashname, cofactor, namepart, variableIV) \
977 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIES ## cofactor ## namepart ## hashname( \
978 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
979 return SecKeyECIESCopyEncryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
980 SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESEncryptAESGCMCopyResult, variableIV, in1, in2, error); \
982 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES ## cofactor ## namepart ## hashname( \
983 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
984 return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchange ## cofactor ## X963 ## hashname, \
985 SecKeyECIESKeyExchangeKDFX963CopyResult, SecKeyECIESDecryptAESGCMCopyResult, variableIV, in1, in2, error); \
988 ECIES_X963_ADAPTOR(SHA1, Standard, X963, false)
989 ECIES_X963_ADAPTOR(SHA224, Standard, X963, false)
990 ECIES_X963_ADAPTOR(SHA256, Standard, X963, false)
991 ECIES_X963_ADAPTOR(SHA384, Standard, X963, false)
992 ECIES_X963_ADAPTOR(SHA512, Standard, X963, false)
993 ECIES_X963_ADAPTOR(SHA1, Cofactor, X963, false)
994 ECIES_X963_ADAPTOR(SHA224, Cofactor, X963, false)
995 ECIES_X963_ADAPTOR(SHA256, Cofactor, X963, false)
996 ECIES_X963_ADAPTOR(SHA384, Cofactor, X963, false)
997 ECIES_X963_ADAPTOR(SHA512, Cofactor, X963, false)
999 ECIES_X963_ADAPTOR(SHA224, Standard, VariableIVX963, true)
1000 ECIES_X963_ADAPTOR(SHA256, Standard, VariableIVX963, true)
1001 ECIES_X963_ADAPTOR(SHA384, Standard, VariableIVX963, true)
1002 ECIES_X963_ADAPTOR(SHA512, Standard, VariableIVX963, true)
1003 ECIES_X963_ADAPTOR(SHA224, Cofactor, VariableIVX963, true)
1004 ECIES_X963_ADAPTOR(SHA256, Cofactor, VariableIVX963, true)
1005 ECIES_X963_ADAPTOR(SHA384, Cofactor, VariableIVX963, true)
1006 ECIES_X963_ADAPTOR(SHA512, Cofactor, VariableIVX963, true)
1008 #undef ECIES_X963_ADAPTOR
1010 static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
1011 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
1012 CFDictionaryRef inParams, CFErrorRef *error) {
1013 CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
1014 context->operation = kSecKeyOperationTypeKeyExchange;
1015 CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
1016 if (result != NULL && context->mode == kSecKeyOperationModePerform) {
1017 const struct ccdigest_info *di = ccsha256_di();
1018 ccdigest_di_decl(di, ctx);
1019 ccdigest_init(di, ctx);
1020 ccdigest_update(di, ctx, CFDataGetLength(result), CFDataGetBytePtr(result));
1021 ccdigest_update(di, ctx, CFDataGetLength(ephemeralPubKey), CFDataGetBytePtr(ephemeralPubKey));
1022 ccdigest_update(di, ctx, CFDataGetLength(pubKey), CFDataGetBytePtr(pubKey));
1023 CFAssignRetained(result, CFDataCreateMutableWithScratch(kCFAllocatorDefault, di->output_size));
1024 ccdigest_final(di, ctx, CFDataGetMutableBytePtr(result));
1029 static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
1030 CFErrorRef *error) {
1031 CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
1032 cccbc_one_shot(ccaes_cbc_decrypt_mode(),
1033 CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
1034 NULL, CFDataGetLength(keyExchangeResult) / CCAES_BLOCK_SIZE,
1035 CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(result));
1039 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys(
1040 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
1041 return SecKeyECIESCopyDecryptedData(context, kSecKeyAlgorithmECDHKeyExchangeStandard,
1042 SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult,
1043 SecKeyECIESDecryptAESCBCCopyResult, false,
1047 static CFTypeRef SecKeyRSAAESGCMCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
1048 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
1049 CFTypeRef result = NULL;
1050 CFDictionaryRef parameters = NULL;
1051 CFDataRef pubKeyData = NULL, wrappedKey = NULL, sessionKey = NULL;
1052 CFMutableDataRef ciphertext = NULL;
1054 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
1055 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
1056 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
1057 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPublic), out, result = kCFNull);
1059 CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
1060 require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
1061 result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
1063 // Generate session key. Use 128bit AES for RSA keys < 4096bit, 256bit AES for larger keys.
1064 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
1065 CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
1066 require_action_quiet(sessionKey = CFDataCreateWithRandomBytes((keySize >= 4096) ? (256 / 8) : (128 / 8)), out,
1067 SecError(errSecParam, error, CFSTR("Failed to generate session key")));
1069 // Encrypt session key using wrapping algorithm and store at the beginning of the result packet.
1070 require_action_quiet(wrappedKey = SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error), out,
1071 CFReleaseNull(result));
1072 ciphertext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(wrappedKey) + CFDataGetLength(in1) + kSecKeyIESTagLength);
1073 UInt8 *resultBuffer = CFDataGetMutableBytePtr(ciphertext);
1074 CFDataGetBytes(wrappedKey, CFRangeMake(0, CFDataGetLength(wrappedKey)), resultBuffer);
1075 resultBuffer += CFDataGetLength(wrappedKey);
1077 // Encrypt input data using AES-GCM.
1078 UInt8 *tagBuffer = resultBuffer + CFDataGetLength(in1);
1079 require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
1080 CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
1081 sizeof(kSecKeyIESIV), kSecKeyIESIV,
1082 CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
1083 CFDataGetLength(in1), CFDataGetBytePtr(in1), resultBuffer,
1084 kSecKeyIESTagLength, tagBuffer) == 0, out,
1085 SecError(errSecParam, error, CFSTR("RSAWRAP: Failed to aes-gcm encrypt data")));
1086 result = CFRetain(ciphertext);
1089 CFReleaseSafe(parameters);
1090 CFReleaseSafe(pubKeyData);
1091 CFReleaseSafe(wrappedKey);
1092 CFReleaseSafe(sessionKey);
1093 CFReleaseSafe(ciphertext);
1097 static CFTypeRef SecKeyRSAAESGCMCopyDecryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyWrapAlgorithm,
1098 CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
1099 CFTypeRef result = NULL;
1100 CFDictionaryRef parameters = NULL;
1101 CFMutableDataRef plaintext = NULL, tag = NULL;
1102 CFDataRef pubKeyData = NULL, sessionKey = NULL;
1103 SecKeyRef pubKey = NULL;
1105 require_action_quiet(parameters = SecKeyCopyAttributes(context->key), out,
1106 SecError(errSecParam, error, CFSTR("Unable to export key parameters")));
1107 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyType), kSecAttrKeyTypeRSA), out, result = kCFNull);
1108 require_action_quiet(CFEqual(CFDictionaryGetValue(parameters, kSecAttrKeyClass), kSecAttrKeyClassPrivate), out, result = kCFNull);
1110 CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
1111 require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
1112 result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
1114 // Extract encrypted session key.
1115 require_action_quiet(pubKey = SecKeyCopyPublicKey(context->key), out,
1116 SecError(errSecParam, error, CFSTR("%@: unable to get public key"), context->key));
1117 require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(pubKey, error), out);
1119 CFIndex wrappedKeySize = SecKeyGetBlockSize(context->key);
1120 require_action_quiet(CFDataGetLength(in1) >= wrappedKeySize + kSecKeyIESTagLength, out,
1121 SecError(errSecParam, error, CFSTR("RSA-WRAP too short input data")));
1122 sessionKey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(in1), wrappedKeySize, kCFAllocatorNull);
1124 // Decrypt session key.
1125 CFAssignRetained(sessionKey, SecKeyRunAlgorithmAndCopyResult(context, sessionKey, NULL, error));
1126 require_quiet(sessionKey, out);
1127 CFIndex keySize = SecKeyGetCFIndexFromRef(CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits));
1128 keySize = (keySize >= 4096) ? (256 / 8) : (128 / 8);
1129 require_action_quiet(CFDataGetLength(sessionKey) == keySize, out,
1130 SecError(errSecParam, error, CFSTR("RSA-WRAP bad ciphertext, unexpected session key size")));
1132 // Decrypt ciphertext using AES-GCM.
1133 plaintext = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), CFDataGetLength(in1) - wrappedKeySize - kSecKeyIESTagLength);
1134 tag = CFDataCreateMutableWithScratch(kCFAllocatorDefault, kSecKeyIESTagLength);
1135 CFDataGetBytes(in1, CFRangeMake(CFDataGetLength(in1) - kSecKeyIESTagLength, kSecKeyIESTagLength),
1136 CFDataGetMutableBytePtr(tag));
1137 const UInt8 *ciphertextBuffer = CFDataGetBytePtr(in1);
1138 ciphertextBuffer += wrappedKeySize;
1139 require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
1140 CFDataGetLength(sessionKey), CFDataGetBytePtr(sessionKey),
1141 sizeof(kSecKeyIESIV), kSecKeyIESIV,
1142 CFDataGetLength(pubKeyData), CFDataGetBytePtr(pubKeyData),
1143 CFDataGetLength(plaintext), ciphertextBuffer, CFDataGetMutableBytePtr(plaintext),
1144 kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
1145 SecError(errSecParam, error, CFSTR("RSA-WRAP: Failed to aes-gcm decrypt data")));
1146 result = CFRetain(plaintext);
1149 CFReleaseSafe(parameters);
1150 CFReleaseSafe(sessionKey);
1152 CFReleaseSafe(pubKeyData);
1153 CFReleaseSafe(pubKey);
1154 CFReleaseSafe(plaintext);
1158 #define RSA_OAEP_AESGCM_ADAPTOR(hashname) \
1159 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
1160 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
1161 return SecKeyRSAAESGCMCopyEncryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
1163 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## hashname ## AESGCM( \
1164 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
1165 return SecKeyRSAAESGCMCopyDecryptedData(context, kSecKeyAlgorithmRSAEncryptionOAEP ## hashname, in1, in2, error); \
1168 RSA_OAEP_AESGCM_ADAPTOR(SHA1)
1169 RSA_OAEP_AESGCM_ADAPTOR(SHA224)
1170 RSA_OAEP_AESGCM_ADAPTOR(SHA256)
1171 RSA_OAEP_AESGCM_ADAPTOR(SHA384)
1172 RSA_OAEP_AESGCM_ADAPTOR(SHA512)
1174 #undef RSA_OAEP_AESGCM_ADAPTOR
1176 SecKeyAlgorithmAdaptor SecKeyGetAlgorithmAdaptor(SecKeyOperationType operation, SecKeyAlgorithm algorithm) {
1177 static CFDictionaryRef adaptors[kSecKeyOperationTypeCount];
1178 static dispatch_once_t onceToken;
1179 dispatch_once(&onceToken, ^{
1180 const void *signKeys[] = {
1181 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1182 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1183 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1184 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1185 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1186 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
1187 kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
1189 kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
1190 kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
1191 kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
1192 kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
1193 kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
1195 kSecKeyAlgorithmRSASignatureRaw,
1196 kSecKeyAlgorithmRSASignatureRawCCUnit,
1198 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1199 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1200 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1201 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1202 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1203 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
1205 kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
1206 kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
1207 kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
1208 kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
1209 kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
1211 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
1212 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
1213 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
1214 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
1215 kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
1217 kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
1218 kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
1219 kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
1220 kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
1221 kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
1223 kSecKeyAlgorithmECDSASignatureRFC4754,
1224 kSecKeyAlgorithmECDSASignatureDigestX962,
1226 const void *signValues[] = {
1227 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA1,
1228 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA224,
1229 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA256,
1230 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA384,
1231 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15SHA512,
1232 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15Raw,
1233 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPKCS1v15MD5,
1235 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA1,
1236 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA224,
1237 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA256,
1238 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA384,
1239 SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA512,
1241 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw,
1242 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit,
1244 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
1245 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
1246 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
1247 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
1248 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
1249 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
1251 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
1252 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
1253 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
1254 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
1255 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
1257 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
1258 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
1259 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
1260 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
1261 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
1263 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
1264 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
1265 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
1266 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
1267 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
1269 SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureRFC4754,
1270 SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureDigestX962,
1272 check_compile_time(array_size(signKeys) == array_size(signValues));
1273 adaptors[kSecKeyOperationTypeSign] = CFDictionaryCreate(kCFAllocatorDefault, signKeys, signValues,
1274 array_size(signKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1276 const void *verifyKeys[] = {
1277 kSecKeyAlgorithmRSASignatureRaw,
1279 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1280 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1281 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1282 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1283 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1284 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
1285 kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
1287 kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
1288 kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
1289 kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
1290 kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
1291 kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
1293 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1294 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1295 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1296 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1297 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1298 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
1300 kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
1301 kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
1302 kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
1303 kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
1304 kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
1306 kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
1307 kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
1308 kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
1309 kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
1310 kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
1312 kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
1313 kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
1314 kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
1315 kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
1316 kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
1318 kSecKeyAlgorithmECDSASignatureRFC4754,
1319 kSecKeyAlgorithmECDSASignatureDigestX962,
1321 const void *verifyValues[] = {
1322 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw,
1324 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA1,
1325 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA224,
1326 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA256,
1327 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA384,
1328 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15SHA512,
1329 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15Raw,
1330 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPKCS1v15MD5,
1332 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA1,
1333 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA224,
1334 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA256,
1335 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA384,
1336 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA512,
1338 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
1339 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
1340 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
1341 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
1342 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
1343 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
1345 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
1346 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
1347 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
1348 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
1349 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
1351 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
1352 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
1353 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
1354 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
1355 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
1357 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
1358 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
1359 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
1360 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
1361 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
1363 SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureRFC4754,
1364 SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureDigestX962,
1366 check_compile_time(array_size(verifyKeys) == array_size(verifyValues));
1367 adaptors[kSecKeyOperationTypeVerify] = CFDictionaryCreate(kCFAllocatorDefault, verifyKeys, verifyValues,
1368 array_size(verifyKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1370 const void *encryptKeys[] = {
1371 kSecKeyAlgorithmRSAEncryptionRaw,
1372 kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1374 kSecKeyAlgorithmRSAEncryptionPKCS1,
1375 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1376 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1377 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1378 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1379 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1381 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1382 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1383 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1384 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1385 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1387 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1388 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1389 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1390 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1391 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1393 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1394 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1395 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1396 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1397 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1399 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
1400 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
1401 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
1402 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
1404 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
1405 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
1406 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
1407 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
1409 const void *encryptValues[] = {
1410 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1411 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1413 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1,
1414 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1,
1415 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224,
1416 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256,
1417 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384,
1418 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512,
1420 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM,
1421 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM,
1422 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM,
1423 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM,
1424 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM,
1426 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1,
1427 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224,
1428 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256,
1429 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384,
1430 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512,
1432 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1,
1433 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224,
1434 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256,
1435 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384,
1436 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512,
1438 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA224,
1439 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA256,
1440 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA384,
1441 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA512,
1443 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA224,
1444 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA256,
1445 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA384,
1446 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA512,
1448 check_compile_time(array_size(encryptKeys) == array_size(encryptValues));
1449 adaptors[kSecKeyOperationTypeEncrypt] = CFDictionaryCreate(kCFAllocatorDefault, encryptKeys, encryptValues,
1450 array_size(encryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1452 const void *decryptKeys[] = {
1453 kSecKeyAlgorithmRSAEncryptionRaw,
1454 kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1456 kSecKeyAlgorithmRSAEncryptionPKCS1,
1457 kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1458 kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1459 kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1460 kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1461 kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1463 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1464 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1465 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1466 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1467 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1469 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1470 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1471 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1472 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1473 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1475 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1476 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1477 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1478 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1479 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1481 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
1482 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
1483 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
1484 kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
1486 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
1487 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
1488 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
1489 kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
1491 kSecKeyAlgorithmECIESEncryptionAKSSmartCard,
1493 const void *decryptValues[] = {
1494 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1495 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1497 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1,
1498 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1,
1499 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224,
1500 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256,
1501 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384,
1502 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512,
1504 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM,
1505 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM,
1506 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM,
1507 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM,
1508 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM,
1510 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1,
1511 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224,
1512 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256,
1513 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384,
1514 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512,
1516 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1,
1517 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224,
1518 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256,
1519 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384,
1520 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512,
1522 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA224,
1523 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA256,
1524 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA384,
1525 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA512,
1527 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA224,
1528 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA256,
1529 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA384,
1530 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA512,
1532 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys,
1534 check_compile_time(array_size(decryptKeys) == array_size(decryptValues));
1535 adaptors[kSecKeyOperationTypeDecrypt] = CFDictionaryCreate(kCFAllocatorDefault, decryptKeys, decryptValues,
1536 array_size(decryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1538 const void *keyExchangeKeys[] = {
1539 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
1540 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
1541 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
1542 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
1543 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
1545 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
1546 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
1547 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
1548 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
1549 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
1551 const void *keyExchangeValues[] = {
1553 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1,
1554 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224,
1555 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256,
1556 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384,
1557 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512,
1559 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1,
1560 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224,
1561 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256,
1562 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384,
1563 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512,
1565 check_compile_time(array_size(keyExchangeKeys) == array_size(keyExchangeKeys));
1566 adaptors[kSecKeyOperationTypeKeyExchange] = CFDictionaryCreate(kCFAllocatorDefault, keyExchangeKeys, keyExchangeValues,
1567 array_size(keyExchangeKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1570 return CFDictionaryGetValue(adaptors[operation], algorithm);