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.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().
31 #include <Security/SecBase.h>
32 #include <Security/SecKeyInternal.h>
33 #include <Security/SecItem.h>
34 #include <Security/SecCFAllocator.h>
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>
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>
51 #pragma mark Algorithm constants value definitions
53 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw
= CFSTR("algid:sign:RSA:raw");
54 const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit
= CFSTR("algid:sign:RSA:raw-cc");
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");
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");
71 const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754
= CFSTR("algid:sign:ECDSA:RFC4754");
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");
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");
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");
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");
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");
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");
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");
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");
127 const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard
= CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
129 void SecKeyOperationContextDestroy(SecKeyOperationContext
*context
) {
130 CFReleaseSafe(context
->algorithm
);
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
);
141 static 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
);
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
);
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); \
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); \
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); \
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())
181 #undef SECKEY_DIGEST_RSA_ADAPTORS
182 #undef SECKEY_DIGEST_ADAPTORS
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
) {
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
));
197 static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian
, size_t size
, void (^operation
)(CFDataRef ccunits
)) {
198 if (bigEndian
== NULL
) {
199 return operation(NULL
);
201 size_t dataSize
= CFDataGetLength(bigEndian
);
202 if (dataSize
> size
) {
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
));
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
));
222 static void PerformWithCCUnitToBigEndian(CFDataRef ccunits
, size_t size
, void (^operation
)(CFDataRef bigEndian
)) {
223 if (ccunits
== NULL
) {
224 return operation(NULL
);
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
);
234 static CFTypeRef
SecKeyRSACopyPKCS1EMSASignature(SecKeyOperationContext
*context
,
235 CFDataRef in1
, CFDataRef in2
, CFErrorRef
*error
, const uint8_t *oid
) {
237 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw
);
239 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSASignatureRawCCUnit
);
240 if (context
->mode
== kSecKeyOperationModeCheckIfSupported
) {
241 return SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
);
244 __block CFTypeRef result
= NULL
;
245 size_t size
= SecKeyGetBlockSize(context
->key
);
247 SecError(errSecParam
, error
, CFSTR("expecting RSA key"));
250 PerformWithCFDataBuffer(size
, ^(uint8_t *buffer
, CFDataRef data
) {
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
)));
262 #define seckey_ccoid_md5 ((unsigned char *)"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05")
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); \
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
)
278 #undef PKCS1v15_EMSA_SIGN_ADAPTOR
280 static CFTypeRef
SecKeyAlgorithmAdaptorBigEndianToCCUnit(SecKeyOperationContext
*context
,
281 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
282 if (context
->mode
== kSecKeyOperationModeCheckIfSupported
) {
283 return SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
);
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
)));
296 static CFTypeRef
SecKeyAlgorithmAdaptorCCUnitToBigEndian(SecKeyOperationContext
*context
,
297 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
298 if (context
->mode
== kSecKeyOperationModeCheckIfSupported
) {
299 return SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
);
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
)));
312 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw(SecKeyOperationContext
*context
,
313 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
314 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSASignatureRawCCUnit
);
315 return SecKeyAlgorithmAdaptorBigEndianToCCUnit(context
, in1
, in2
, error
);
318 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit(SecKeyOperationContext
*context
,
319 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
320 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSASignatureRaw
);
321 return SecKeyAlgorithmAdaptorCCUnitToBigEndian(context
, in1
, in2
, error
);
324 static bool SecKeyVerifyBadSignature(CFErrorRef
*error
) {
325 return SecError(errSecVerifyFailed
, error
, CFSTR("RSA signature verification failed, no match"));
328 static CFTypeRef
SecKeyRSAVerifyAdaptor(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
);
338 CFRetainAssign(result
, kCFBooleanFalse
);
339 SecKeyVerifyBadSignature(error
);
345 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw(SecKeyOperationContext
*context
,
346 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
347 return SecKeyRSAVerifyAdaptor(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) {
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;
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 SecKeyRSAVerifyAdaptor(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; \
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
)
378 #undef PKCS1v15_EMSA_VERIFY_ADAPTOR
380 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw(SecKeyOperationContext
*context
,
381 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
382 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSAEncryptionRawCCUnit
);
383 return SecKeyAlgorithmAdaptorBigEndianToCCUnit(context
, in1
, in2
, error
);
386 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit(SecKeyOperationContext
*context
,
387 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
388 CFArrayAppendValue(context
->algorithm
, kSecKeyAlgorithmRSAEncryptionRaw
);
389 return SecKeyAlgorithmAdaptorCCUnitToBigEndian(context
, in1
, in2
, error
);
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
) {
400 if (context
->mode
== kSecKeyOperationModeCheckIfSupported
) {
401 return SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
);
404 __block CFTypeRef result
= NULL
;
405 PerformWithCFDataBuffer(size
, ^(uint8_t *buffer
, CFDataRef data
) {
408 err
= ccrsa_oaep_encode(di
, ccrng_seckey
, size
, (cc_unit
*)buffer
,
409 CFDataGetLength(in1
), CFDataGetBytePtr(in1
));
411 err
= ccrsa_eme_pkcs1v15_encode(ccrng_seckey
, size
, (cc_unit
*)buffer
,
412 CFDataGetLength(in1
), CFDataGetBytePtr(in1
));
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
)));
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
) {
430 if (context
->mode
== kSecKeyOperationModeCheckIfSupported
) {
431 return SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
);
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
);
442 err
= ccrsa_oaep_decode(di
, &size
, CFDataGetMutableBytePtr(result
),
443 CFDataGetLength(cc_result
), (cc_unit
*)CFDataGetBytePtr(cc_result
));
445 err
= ccrsa_eme_pkcs1v15_decode(&size
, CFDataGetMutableBytePtr(result
),
446 CFDataGetLength(cc_result
), (cc_unit
*)CFDataGetBytePtr(cc_result
));
448 require_noerr_action_quiet(err
, out
, (CFReleaseNull(result
),
449 SecError(errSecParam
, error
, CFSTR("RSAdecrypt wrong input (err %d)"), err
)));
450 CFDataSetLength(result
, size
);
452 CFReleaseSafe(cc_result
);
457 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext
*context
,
458 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
459 return SecKeyRSACopyEncryptedWithPadding(context
, NULL
, in1
, error
);
462 static CFTypeRef
SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext
*context
,
463 CFTypeRef in1
, CFTypeRef in2
, CFErrorRef
*error
) {
464 return SecKeyRSACopyDecryptedWithPadding(context
, NULL
, in1
, error
);
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); \
472 static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
473 SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
474 return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
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());
483 #undef RSA_OAEP_CRYPT_ADAPTOR
485 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize
= CFSTR("requestedSize");
486 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo
= CFSTR("sharedInfo");
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
);
493 if (context
->mode
== kSecKeyOperationModePerform
) {
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
);
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
)));
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); \
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
)
538 #undef ECDH_X963_ADAPTOR
540 // Extract number value of either CFNumber or CFString.
541 static CFIndex
SecKeyGetCFIndexFromRef(CFTypeRef ref
) {
543 if (CFGetTypeID(ref
) == CFNumberGetTypeID()) {
544 if (!CFNumberGetValue(ref
, kCFNumberCFIndexType
, &result
)) {
547 } else if (CFGetTypeID(ref
) == CFStringGetTypeID()) {
548 result
= CFStringGetIntValue(ref
);
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
);
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
;
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
);
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
),
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
);
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
);
593 result
= CFRetain(keyExchangeResult
);
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
;
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
;
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
);
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;
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
);
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),
646 require_quiet(result
= decryptCopyResult(keyExchangeResult
, ciphertext
, error
), out
);
648 result
= CFRetain(keyExchangeResult
);
652 CFReleaseSafe(parameters
);
653 CFReleaseSafe(ephemeralPubKeyData
);
654 CFReleaseSafe(keyExchangeResult
);
655 CFReleaseSafe(pubKeyData
);
656 CFReleaseSafe(pubKey
);
657 CFReleaseSafe(ciphertext
);
661 static const CFIndex kSecKeyIESTagLength
= 16;
662 static const UInt8 kSecKeyIESIV
[16] = { 0 };
664 static CFDataRef
SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext
*context
, SecKeyAlgorithm keyExchangeAlgorithm
,
665 bool encrypt
, CFDataRef ephemeralPubKey
, CFDataRef pubKey
,
667 CFDictionaryRef parameters
= NULL
;
668 CFNumberRef keySizeRef
= NULL
;
669 CFDataRef result
= NULL
;
671 CFArrayAppendValue(context
->algorithm
, keyExchangeAlgorithm
);
672 context
->operation
= kSecKeyOperationTypeKeyExchange
;
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);
679 // Generate shared secret using KDF.
680 keySizeRef
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &keySize
);
681 parameters
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
682 kSecKeyKeyExchangeParameterSharedInfo
, ephemeralPubKey
,
683 kSecKeyKeyExchangeParameterRequestedSize
, keySizeRef
,
687 result
= SecKeyRunAlgorithmAndCopyResult(context
, encrypt
? pubKey
: ephemeralPubKey
, parameters
, error
);
688 CFReleaseSafe(parameters
);
689 CFReleaseSafe(keySizeRef
);
693 static Boolean
SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult
, CFDataRef inData
, CFMutableDataRef result
,
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
,
704 CFDataGetLength(inData
), CFDataGetBytePtr(inData
),
705 resultBuffer
, kSecKeyIESTagLength
, tagBuffer
) == 0, out
,
706 SecError(errSecParam
, error
, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
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
,
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
);
727 CFReleaseSafe(plaintext
);
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); \
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); \
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
)
755 #undef ECIES_X963_ADAPTOR
757 static CFDataRef
SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext
*context
, SecKeyAlgorithm keyExchangeAlgorithm
,
758 bool encrypt
, CFDataRef ephemeralPubKey
, CFDataRef pubKey
,
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
));
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
));
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
,
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
;
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
);
805 CFArrayAppendValue(context
->algorithm
, keyWrapAlgorithm
);
806 require_action_quiet(context
->mode
== kSecKeyOperationModePerform
, out
,
807 result
= SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
));
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")));
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
);
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
);
835 CFReleaseSafe(parameters
);
836 CFReleaseSafe(pubKeyData
);
837 CFReleaseSafe(wrappedKey
);
838 CFReleaseSafe(sessionKey
);
839 CFReleaseSafe(ciphertext
);
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
;
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
);
856 CFArrayAppendValue(context
->algorithm
, keyWrapAlgorithm
);
857 require_action_quiet(context
->mode
== kSecKeyOperationModePerform
, out
,
858 result
= SecKeyRunAlgorithmAndCopyResult(context
, NULL
, NULL
, error
));
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
);
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
);
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")));
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
);
895 CFReleaseSafe(parameters
);
896 CFReleaseSafe(sessionKey
);
898 CFReleaseSafe(pubKeyData
);
899 CFReleaseSafe(pubKey
);
900 CFReleaseSafe(plaintext
);
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); \
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); \
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
)
920 #undef RSA_OAEP_AESGCM_ADAPTOR
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
,
935 kSecKeyAlgorithmRSASignatureRaw
,
936 kSecKeyAlgorithmRSASignatureRawCCUnit
,
938 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
939 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
940 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
941 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
942 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
943 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5
,
945 kSecKeyAlgorithmECDSASignatureMessageX962SHA1
,
946 kSecKeyAlgorithmECDSASignatureMessageX962SHA224
,
947 kSecKeyAlgorithmECDSASignatureMessageX962SHA256
,
948 kSecKeyAlgorithmECDSASignatureMessageX962SHA384
,
949 kSecKeyAlgorithmECDSASignatureMessageX962SHA512
,
951 kSecKeyAlgorithmECDSASignatureDigestX962SHA1
,
952 kSecKeyAlgorithmECDSASignatureDigestX962SHA224
,
953 kSecKeyAlgorithmECDSASignatureDigestX962SHA256
,
954 kSecKeyAlgorithmECDSASignatureDigestX962SHA384
,
955 kSecKeyAlgorithmECDSASignatureDigestX962SHA512
,
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
,
966 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw
,
967 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit
,
969 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1
,
970 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224
,
971 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256
,
972 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384
,
973 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512
,
974 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5
,
976 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1
,
977 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224
,
978 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256
,
979 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384
,
980 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512
,
982 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1
,
983 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224
,
984 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256
,
985 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384
,
986 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512
,
988 check_compile_time(array_size(signKeys
) == array_size(signValues
));
989 adaptors
[kSecKeyOperationTypeSign
] = CFDictionaryCreate(kCFAllocatorDefault
, signKeys
, signValues
,
990 array_size(signKeys
), &kCFTypeDictionaryKeyCallBacks
, NULL
);
992 const void *verifyKeys
[] = {
993 kSecKeyAlgorithmRSASignatureRaw
,
995 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
,
996 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224
,
997 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
,
998 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
,
999 kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
,
1000 kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw
,
1001 kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5
,
1003 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1
,
1004 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224
,
1005 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256
,
1006 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384
,
1007 kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512
,
1008 kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5
,
1010 kSecKeyAlgorithmECDSASignatureMessageX962SHA1
,
1011 kSecKeyAlgorithmECDSASignatureMessageX962SHA224
,
1012 kSecKeyAlgorithmECDSASignatureMessageX962SHA256
,
1013 kSecKeyAlgorithmECDSASignatureMessageX962SHA384
,
1014 kSecKeyAlgorithmECDSASignatureMessageX962SHA512
,
1016 kSecKeyAlgorithmECDSASignatureDigestX962SHA1
,
1017 kSecKeyAlgorithmECDSASignatureDigestX962SHA224
,
1018 kSecKeyAlgorithmECDSASignatureDigestX962SHA256
,
1019 kSecKeyAlgorithmECDSASignatureDigestX962SHA384
,
1020 kSecKeyAlgorithmECDSASignatureDigestX962SHA512
,
1022 const void *verifyValues
[] = {
1023 SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw
,
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
,
1033 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1
,
1034 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224
,
1035 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256
,
1036 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384
,
1037 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512
,
1038 SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5
,
1040 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1
,
1041 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224
,
1042 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256
,
1043 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384
,
1044 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512
,
1046 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1
,
1047 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224
,
1048 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256
,
1049 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384
,
1050 SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512
,
1052 check_compile_time(array_size(verifyKeys
) == array_size(verifyValues
));
1053 adaptors
[kSecKeyOperationTypeVerify
] = CFDictionaryCreate(kCFAllocatorDefault
, verifyKeys
, verifyValues
,
1054 array_size(verifyKeys
), &kCFTypeDictionaryKeyCallBacks
, NULL
);
1056 const void *encryptKeys
[] = {
1057 kSecKeyAlgorithmRSAEncryptionRaw
,
1058 kSecKeyAlgorithmRSAEncryptionRawCCUnit
,
1060 kSecKeyAlgorithmRSAEncryptionPKCS1
,
1061 kSecKeyAlgorithmRSAEncryptionOAEPSHA1
,
1062 kSecKeyAlgorithmRSAEncryptionOAEPSHA224
,
1063 kSecKeyAlgorithmRSAEncryptionOAEPSHA256
,
1064 kSecKeyAlgorithmRSAEncryptionOAEPSHA384
,
1065 kSecKeyAlgorithmRSAEncryptionOAEPSHA512
,
1067 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM
,
1068 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM
,
1069 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM
,
1070 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM
,
1071 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM
,
1073 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM
,
1074 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM
,
1075 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM
,
1076 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM
,
1077 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM
,
1079 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM
,
1080 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM
,
1081 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
,
1082 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM
,
1083 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM
,
1085 const void *encryptValues
[] = {
1086 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw
,
1087 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit
,
1089 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1
,
1090 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1
,
1091 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224
,
1092 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256
,
1093 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384
,
1094 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512
,
1096 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM
,
1097 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM
,
1098 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM
,
1099 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM
,
1100 SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM
,
1102 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1
,
1103 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224
,
1104 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256
,
1105 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384
,
1106 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512
,
1108 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1
,
1109 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224
,
1110 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256
,
1111 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384
,
1112 SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512
,
1114 check_compile_time(array_size(encryptKeys
) == array_size(encryptValues
));
1115 adaptors
[kSecKeyOperationTypeEncrypt
] = CFDictionaryCreate(kCFAllocatorDefault
, encryptKeys
, encryptValues
,
1116 array_size(encryptKeys
), &kCFTypeDictionaryKeyCallBacks
, NULL
);
1118 const void *decryptKeys
[] = {
1119 kSecKeyAlgorithmRSAEncryptionRaw
,
1120 kSecKeyAlgorithmRSAEncryptionRawCCUnit
,
1122 kSecKeyAlgorithmRSAEncryptionPKCS1
,
1123 kSecKeyAlgorithmRSAEncryptionOAEPSHA1
,
1124 kSecKeyAlgorithmRSAEncryptionOAEPSHA224
,
1125 kSecKeyAlgorithmRSAEncryptionOAEPSHA256
,
1126 kSecKeyAlgorithmRSAEncryptionOAEPSHA384
,
1127 kSecKeyAlgorithmRSAEncryptionOAEPSHA512
,
1129 kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM
,
1130 kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM
,
1131 kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM
,
1132 kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM
,
1133 kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM
,
1135 kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM
,
1136 kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM
,
1137 kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM
,
1138 kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM
,
1139 kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM
,
1141 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM
,
1142 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM
,
1143 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
,
1144 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM
,
1145 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM
,
1147 kSecKeyAlgorithmECIESEncryptionAKSSmartCard
,
1149 const void *decryptValues
[] = {
1150 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw
,
1151 SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit
,
1153 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1
,
1154 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1
,
1155 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224
,
1156 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256
,
1157 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384
,
1158 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512
,
1160 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM
,
1161 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM
,
1162 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM
,
1163 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM
,
1164 SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM
,
1166 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1
,
1167 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224
,
1168 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256
,
1169 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384
,
1170 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512
,
1172 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1
,
1173 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224
,
1174 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256
,
1175 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384
,
1176 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512
,
1178 SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys
,
1180 check_compile_time(array_size(decryptKeys
) == array_size(decryptValues
));
1181 adaptors
[kSecKeyOperationTypeDecrypt
] = CFDictionaryCreate(kCFAllocatorDefault
, decryptKeys
, decryptValues
,
1182 array_size(decryptKeys
), &kCFTypeDictionaryKeyCallBacks
, NULL
);
1184 const void *keyExchangeKeys
[] = {
1185 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1
,
1186 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224
,
1187 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256
,
1188 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384
,
1189 kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512
,
1191 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1
,
1192 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224
,
1193 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256
,
1194 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384
,
1195 kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512
,
1197 const void *keyExchangeValues
[] = {
1199 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1
,
1200 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224
,
1201 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256
,
1202 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384
,
1203 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512
,
1205 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1
,
1206 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224
,
1207 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256
,
1208 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384
,
1209 SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512
,
1211 check_compile_time(array_size(keyExchangeKeys
) == array_size(keyExchangeKeys
));
1212 adaptors
[kSecKeyOperationTypeKeyExchange
] = CFDictionaryCreate(kCFAllocatorDefault
, keyExchangeKeys
, keyExchangeValues
,
1213 array_size(keyExchangeKeys
), &kCFTypeDictionaryKeyCallBacks
, NULL
);
1216 return CFDictionaryGetValue(adaptors
[operation
], algorithm
);