/ OSX / sec / Security / SecKeyAdaptors.m
SecKeyAdaptors.m
   1  /*
   2   * Copyright (c) 2016 Apple Inc. All Rights Reserved.
   3   *
   4   * @APPLE_LICENSE_HEADER_START@
   5   *
   6   * This file contains Original Code and/or Modifications of Original Code
   7   * as defined in and that are subject to the Apple Public Source License
   8   * Version 2.0 (the 'License'). You may not use this file except in
   9   * compliance with the License. Please obtain a copy of the License at
  10   * http://www.opensource.apple.com/apsl/ and read it before using this
  11   * file.
  12   *
  13   * The Original Code and all software distributed under the License are
  14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  18   * Please see the License for the specific language governing rights and
  19   * limitations under the License.
  20   *
  21   * @APPLE_LICENSE_HEADER_END@
  22   */
  23  
  24  /*
  25   * SecKeyAdaptors.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().
  29   */
  30  
  31  #import <Foundation/Foundation.h>
  32  
  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>
  38  
  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>
  45  
  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>
  54  
  55  
  56  #pragma mark Algorithm constants value definitions
  57  
  58  const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRaw = CFSTR("algid:sign:RSA:raw");
  59  const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureRawCCUnit = CFSTR("algid:sign:RSA:raw-cc");
  60  
  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");
  73  
  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");
  85  
  86  const SecKeyAlgorithm kSecKeyAlgorithmECDSASignatureRFC4754 = CFSTR("algid:sign:ECDSA:RFC4754");
  87  
  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");
  94  
  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");
 100  
 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");
 109  
 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");
 115  
 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");
 121  
 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");
 127  
 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");
 132  
 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");
 137  
 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");
 144  
 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");
 151  
 152  const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
 153  
 154  void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
 155      CFReleaseNull(context->algorithm);
 156  }
 157  
 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);
 162          CFRelease(data);
 163      });
 164  }
 165  
 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);
 170      }
 171  
 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);
 176      });
 177      return result;
 178  }
 179  
 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);
 185      }
 186  
 187      if (CFDataGetLength(digest) != (CFIndex)di->output_size) {
 188          SecError(errSecParam, error, CFSTR("bad digest size for signing with algorithm %@"), algorithm);
 189          return NULL;
 190      }
 191  
 192      return SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
 193  }
 194  
 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); \
 200  }
 201  
 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); \
 207  } \
 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); \
 211  }
 212  
 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())
 229  
 230  #undef DIGEST_RSA_ADAPTORS
 231  #undef DIGEST_ECDSA_ADAPTORS
 232  
 233  typedef CF_ENUM(CFIndex, SecKeyECSignatureType) {
 234      kSecKeyECSignatureTypeRFC4754,
 235      kSecKeyECSignatureTypeX962,
 236  };
 237  
 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);
 252          } else {
 253              SecError(errorStatus, error, CFSTR("Wrong ECDSA X962 signature"));
 254          }
 255      } else {
 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"));
 270              }
 271          } else {
 272              SecError(errorStatus, error, CFSTR("Wrong ECDSA RFC4754 signature"));
 273          }
 274      }
 275  
 276      return targetSignature;
 277  }
 278  
 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);
 285      }
 286  
 287      CFDataRef signature = SecKeyRunAlgorithmAndCopyResult(context, digest, in2, error);
 288      if (signature == NULL || CFEqual(signature, kCFNull)) {
 289          return signature;
 290      }
 291  
 292      // Convert the signature.
 293      CFAssignRetained(signature, SecKeyCopyConvertedECDSASignature(context, signatureType, signature, errSecParam, error));
 294      return signature;
 295  }
 296  
 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);
 304      }
 305  
 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);
 311      }
 312      return result;
 313  }
 314  
 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);
 318  }
 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);
 322  }
 323  
 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);
 327  }
 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);
 331  }
 332  
 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) {
 338              size = dataSize;
 339          }
 340          result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, ccn_sizeof_size(size));
 341          ccn_read_uint(ccn_nof_size(size), (cc_unit *)CFDataGetMutableBytePtr(result), dataSize, CFDataGetBytePtr(bigEndian));
 342      }
 343      return result;
 344  }
 345  
 346  static void PerformWithBigEndianToCCUnit(CFDataRef bigEndian, size_t size, void (^operation)(CFDataRef ccunits)) {
 347      if (bigEndian == NULL) {
 348          return operation(NULL);
 349      }
 350      size_t dataSize = CFDataGetLength(bigEndian);
 351      if (dataSize > size) {
 352          size = dataSize;
 353      }
 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));
 356          operation(data);
 357      });
 358  }
 359  
 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));
 367      }
 368      return result;
 369  }
 370  
 371  static void PerformWithCCUnitToBigEndian(CFDataRef ccunits, size_t size, void (^operation)(CFDataRef bigEndian)) {
 372      if (ccunits == NULL) {
 373          return operation(NULL);
 374      }
 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);
 379          operation(data);
 380      });
 381  }
 382  
 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;
 387  
 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);
 393  
 394      if (pss) {
 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),
 400                                        blockSize * 8));
 401      }
 402  
 403      if (!pss && di != NULL) {
 404          CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw);
 405      }
 406  
 407      CFArrayAppendValue(context->algorithm, kSecKeyAlgorithmRSASignatureRawCCUnit);
 408      if (context->mode == kSecKeyOperationModeCheckIfSupported) {
 409          return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
 410      }
 411  
 412      size_t size = SecKeyGetBlockSize(context->key);
 413      if (size == 0) {
 414          SecError(errSecParam, error, CFSTR("expecting RSA key"));
 415          return NULL;
 416      }
 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")));
 420          if (pss) {
 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")));
 429          } else {
 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")));
 432          }
 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)));
 436      out:;
 437      });
 438  
 439  out:
 440      CFReleaseSafe(parameters);
 441      return result;
 442  }
 443  
 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); \
 448  }
 449  
 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())
 462  
 463  #undef RSA_EMSA_SIGN_ADAPTOR
 464  
 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);
 469      }
 470  
 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)));
 476          }
 477      });
 478      return result;
 479  }
 480  
 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);
 485      }
 486  
 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)));
 492          }
 493      });
 494      return result;
 495  }
 496  
 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);
 501  }
 502  
 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);
 507  }
 508  
 509  static bool SecKeyVerifyBadSignature(CFErrorRef *error) {
 510      return SecError(errSecVerifyFailed, error, CFSTR("RSA signature verification failed, no match"));
 511  }
 512  
 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);
 522          } else {
 523              CFRetainAssign(result, kCFBooleanFalse);
 524              SecKeyVerifyBadSignature(error);
 525          }
 526      }
 527      return result;
 528  }
 529  
 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) {
 537              data++;
 538              length--;
 539          }
 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;
 542      });
 543  };
 544  
 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; \
 552      }); \
 553  }
 554  
 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; \
 561      }); \
 562  }
 563  
 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)
 571  
 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())
 577  
 578  #undef PKCS1v15_EMSA_VERIFY_ADAPTOR
 579  #undef PSS_EMSA_VERIFY_ADAPTOR
 580  
 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);
 585  }
 586  
 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);
 591  }
 592  
 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) {
 599          return kCFNull;
 600      }
 601      if (context->mode == kSecKeyOperationModeCheckIfSupported) {
 602          return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
 603      }
 604  
 605      __block CFTypeRef result = NULL;
 606      PerformWithCFDataBuffer(ccn_sizeof_size(size), ^(uint8_t *buffer, CFDataRef data) {
 607          int err;
 608          if (di != NULL) {
 609              err = ccrsa_oaep_encode(di, ccrng_seckey, size, (cc_unit *)buffer,
 610                                      CFDataGetLength(in1), CFDataGetBytePtr(in1));
 611          } else {
 612              err = ccrsa_eme_pkcs1v15_encode(ccrng_seckey, size, (cc_unit *)buffer,
 613                                              CFDataGetLength(in1), CFDataGetBytePtr(in1));
 614          }
 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)));
 620      out:;
 621      });
 622      return result;
 623  }
 624  
 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) {
 630          return kCFNull;
 631      }
 632      if (context->mode == kSecKeyOperationModeCheckIfSupported) {
 633          return SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error);
 634      }
 635  
 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);
 642          int err;
 643          if (di != NULL) {
 644              err = ccrsa_oaep_decode(di, &size, CFDataGetMutableBytePtr(result),
 645                                      size, (cc_unit *)CFDataGetBytePtr(cc_result));
 646          } else {
 647              err = ccrsa_eme_pkcs1v15_decode(&size, CFDataGetMutableBytePtr(result),
 648                                              size, (cc_unit *)CFDataGetBytePtr(cc_result));
 649          }
 650          require_noerr_action_quiet(err, out, (CFReleaseNull(result),
 651                                                SecError(errSecParam, error, CFSTR("RSAdecrypt wrong input (err %d)"), err)));
 652          CFDataSetLength(result, size);
 653      out:
 654          CFReleaseSafe(cc_result);
 655      });
 656      return result;
 657  }
 658  
 659  static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
 660                                                                               CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
 661      return SecKeyRSACopyEncryptedWithPadding(context, NULL, in1, error);
 662  }
 663  
 664  static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1(SecKeyOperationContext *context,
 665                                                                               CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
 666      return SecKeyRSACopyDecryptedWithPadding(context, NULL, in1, error);
 667  }
 668  
 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); \
 673  } \
 674  static CFTypeRef SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEP ## name( \
 675          SecKeyOperationContext *context, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { \
 676      return SecKeyRSACopyDecryptedWithPadding(context, di, in1, error); \
 677  }
 678  
 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());
 684  
 685  #undef RSA_OAEP_CRYPT_ADAPTOR
 686  
 687  const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
 688  const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
 689  
 690  const CFStringRef kSecKeyEncryptionParameterSymmetricKeySizeInBits = CFSTR("symKeySize");
 691  const CFStringRef kSecKeyEncryptionParameterSymmetricAAD = CFSTR("aad");
 692  const CFStringRef kSecKeyEncryptionParameterRecryptParameters = CFSTR("recryptParams");
 693  const CFStringRef kSecKeyEncryptionParameterRecryptCertificate = CFSTR("recryptCert");
 694  
 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);
 699  
 700      if (context->mode == kSecKeyOperationModePerform) {
 701          // Parse params.
 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);
 714          }
 715  
 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);
 722      } else {
 723          // In test-only mode, propagate result (YES/NO) of underlying operation.
 724          CFRetainAssign(result, sharedSecret);
 725      }
 726  out:
 727      CFReleaseNull(sharedSecret);
 728      return result;
 729  }
 730  
 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); \
 736  }
 737  
 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)
 748  
 749  #undef ECDH_X963_ADAPTOR
 750  
 751  // Extract number value of either CFNumber or CFString.
 752  static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
 753      CFIndex result = 0;
 754      if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
 755          if (!CFNumberGetValue(ref, kCFNumberCFIndexType, &result)) {
 756              result = 0;
 757          }
 758      } else if (CFGetTypeID(ref) == CFStringGetTypeID()) {
 759          result = CFStringGetIntValue(ref);
 760      }
 761      return result;
 762  }
 763  
 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);
 767  
 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;
 778  
 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);
 783  
 784      // Generate ephemeral key.
 785      require_quiet(pubKeyData = SecKeyCopyExternalRepresentation(context->key, error), out);
 786      CFAssignRetained(parameters, CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
 787  #if TARGET_OS_OSX
 788                                                                kSecUseDataProtectionKeychain, kCFBooleanTrue,
 789  #endif
 790                                                                kSecAttrKeyType, CFDictionaryGetValue(parameters, kSecAttrKeyType),
 791                                                                kSecAttrKeySizeInBits, CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits),
 792                                                                NULL));
 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);
 797  
 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);
 806      } else {
 807          result = CFRetain(keyExchangeResult);
 808      }
 809  
 810  out:
 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;
 819      return result;
 820  }
 821  
 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;
 832      CFIndex keySize = 0;
 833  
 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);
 838  
 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;
 847  
 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);
 851      }
 852  
 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),
 859                                                   kCFAllocatorNull);
 860          require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, in2, error), out);
 861      } else {
 862          result = CFRetain(keyExchangeResult);
 863      }
 864  
 865  out:
 866      CFReleaseSafe(parameters);
 867      CFReleaseSafe(ephemeralPubKeyData);
 868      CFReleaseSafe(keyExchangeResult);
 869      CFReleaseSafe(pubKeyData);
 870      CFReleaseSafe(pubKey);
 871      CFReleaseSafe(ciphertext);
 872      return result;
 873  }
 874  
 875  static const CFIndex kSecKeyIESTagLength = 16;
 876  static const UInt8 kSecKeyIESIV[16] = { 0 };
 877  
 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;
 882      NSData *result;
 883      NSMutableData *sharedInfoForKeyExchange;
 884  
 885      CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
 886      context->operation = kSecKeyOperationTypeKeyExchange;
 887  
 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);
 894                  return NULL;
 895              }
 896              keySize = keySizeObject.integerValue / 8;
 897          } else {
 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);
 901          }
 902  
 903          if (variableIV) {
 904              keySize += sizeof(kSecKeyIESIV);
 905          }
 906  
 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];
 912          }
 913          parametersForKeyExchange = @{ (__bridge id)kSecKeyKeyExchangeParameterSharedInfo: sharedInfoForKeyExchange,
 914                                        (__bridge id)kSecKeyKeyExchangeParameterRequestedSize: @(keySize) };
 915      }
 916  
 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];
 923      }
 924      return CFBridgingRetain(result);
 925  }
 926  
 927  static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
 928                                                    CFMutableDataRef result, CFErrorRef *error) {
 929      Boolean res = FALSE;
 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")));
 944      res = TRUE;
 945  out:
 946      return res;
 947  }
 948  
 949  static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
 950                                                      CFErrorRef *error) {
 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);
 970  out:
 971      CFReleaseSafe(plaintext);
 972      CFReleaseSafe(tag);
 973      return result;
 974  }
 975  
 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); \
 981  } \
 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); \
 986  }
 987  
 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)
 998  
 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)
1007  
1008  #undef ECIES_X963_ADAPTOR
1009  
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));
1025      }
1026      return result;
1027  }
1028  
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));
1036      return result;
1037  }
1038  
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,
1044                                          in1, in2, error);
1045  }
1046  
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;
1053  
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);
1058  
1059      CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
1060      require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
1061                           result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
1062  
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")));
1068  
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);
1076  
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);
1087  
1088  out:
1089      CFReleaseSafe(parameters);
1090      CFReleaseSafe(pubKeyData);
1091      CFReleaseSafe(wrappedKey);
1092      CFReleaseSafe(sessionKey);
1093      CFReleaseSafe(ciphertext);
1094      return result;
1095  }
1096  
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;
1104  
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);
1109  
1110      CFArrayAppendValue(context->algorithm, keyWrapAlgorithm);
1111      require_action_quiet(context->mode == kSecKeyOperationModePerform, out,
1112                           result = SecKeyRunAlgorithmAndCopyResult(context, NULL, NULL, error));
1113  
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);
1118  
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);
1123  
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")));
1131  
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);
1147  
1148  out:
1149      CFReleaseSafe(parameters);
1150      CFReleaseSafe(sessionKey);
1151      CFReleaseSafe(tag);
1152      CFReleaseSafe(pubKeyData);
1153      CFReleaseSafe(pubKey);
1154      CFReleaseSafe(plaintext);
1155      return result;
1156  }
1157  
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); \
1162  } \
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); \
1166  }
1167  
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)
1173  
1174  #undef RSA_OAEP_AESGCM_ADAPTOR
1175  
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,
1188  
1189              kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
1190              kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
1191              kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
1192              kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
1193              kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
1194  
1195              kSecKeyAlgorithmRSASignatureRaw,
1196              kSecKeyAlgorithmRSASignatureRawCCUnit,
1197  
1198              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1199              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1200              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1201              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1202              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1203              kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
1204  
1205              kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
1206              kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
1207              kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
1208              kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
1209              kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
1210  
1211              kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
1212              kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
1213              kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
1214              kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
1215              kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
1216  
1217              kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
1218              kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
1219              kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
1220              kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
1221              kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
1222  
1223              kSecKeyAlgorithmECDSASignatureRFC4754,
1224              kSecKeyAlgorithmECDSASignatureDigestX962,
1225          };
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,
1234  
1235              SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA1,
1236              SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA224,
1237              SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA256,
1238              SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA384,
1239              SecKeyAlgorithmAdaptorCopyResult_Sign_RSASignatureDigestPSSSHA512,
1240  
1241              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRaw,
1242              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureRawCCUnit,
1243  
1244              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
1245              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
1246              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
1247              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
1248              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
1249              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
1250  
1251              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
1252              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
1253              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
1254              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
1255              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
1256  
1257              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
1258              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
1259              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
1260              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
1261              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
1262  
1263              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
1264              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
1265              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
1266              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
1267              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
1268  
1269              SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureRFC4754,
1270              SecKeyAlgorithmAdaptorCopyResult_Sign_ECDSASignatureDigestX962,
1271          };
1272          check_compile_time(array_size(signKeys) == array_size(signValues));
1273          adaptors[kSecKeyOperationTypeSign] = CFDictionaryCreate(kCFAllocatorDefault, signKeys, signValues,
1274                                                                  array_size(signKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1275  
1276          const void *verifyKeys[] = {
1277              kSecKeyAlgorithmRSASignatureRaw,
1278  
1279              kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1,
1280              kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224,
1281              kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256,
1282              kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384,
1283              kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512,
1284              kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw,
1285              kSecKeyAlgorithmRSASignatureDigestPKCS1v15MD5,
1286  
1287              kSecKeyAlgorithmRSASignatureDigestPSSSHA1,
1288              kSecKeyAlgorithmRSASignatureDigestPSSSHA224,
1289              kSecKeyAlgorithmRSASignatureDigestPSSSHA256,
1290              kSecKeyAlgorithmRSASignatureDigestPSSSHA384,
1291              kSecKeyAlgorithmRSASignatureDigestPSSSHA512,
1292  
1293              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1,
1294              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224,
1295              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256,
1296              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384,
1297              kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512,
1298              kSecKeyAlgorithmRSASignatureMessagePKCS1v15MD5,
1299  
1300              kSecKeyAlgorithmRSASignatureMessagePSSSHA1,
1301              kSecKeyAlgorithmRSASignatureMessagePSSSHA224,
1302              kSecKeyAlgorithmRSASignatureMessagePSSSHA256,
1303              kSecKeyAlgorithmRSASignatureMessagePSSSHA384,
1304              kSecKeyAlgorithmRSASignatureMessagePSSSHA512,
1305  
1306              kSecKeyAlgorithmECDSASignatureMessageX962SHA1,
1307              kSecKeyAlgorithmECDSASignatureMessageX962SHA224,
1308              kSecKeyAlgorithmECDSASignatureMessageX962SHA256,
1309              kSecKeyAlgorithmECDSASignatureMessageX962SHA384,
1310              kSecKeyAlgorithmECDSASignatureMessageX962SHA512,
1311  
1312              kSecKeyAlgorithmECDSASignatureDigestX962SHA1,
1313              kSecKeyAlgorithmECDSASignatureDigestX962SHA224,
1314              kSecKeyAlgorithmECDSASignatureDigestX962SHA256,
1315              kSecKeyAlgorithmECDSASignatureDigestX962SHA384,
1316              kSecKeyAlgorithmECDSASignatureDigestX962SHA512,
1317  
1318              kSecKeyAlgorithmECDSASignatureRFC4754,
1319              kSecKeyAlgorithmECDSASignatureDigestX962,
1320          };
1321          const void *verifyValues[] = {
1322              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureRaw,
1323  
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,
1331  
1332              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA1,
1333              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA224,
1334              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA256,
1335              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA384,
1336              SecKeyAlgorithmAdaptorCopyResult_Verify_RSASignatureDigestPSSSHA512,
1337  
1338              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA1,
1339              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA224,
1340              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA256,
1341              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA384,
1342              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15SHA512,
1343              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePKCS1v15MD5,
1344  
1345              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA1,
1346              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA224,
1347              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA256,
1348              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA384,
1349              SecKeyAlgorithmAdaptorCopyResult_SignVerify_RSASignatureMessagePSSSHA512,
1350  
1351              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA1,
1352              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA224,
1353              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA256,
1354              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA384,
1355              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureMessageX962SHA512,
1356  
1357              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA1,
1358              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA224,
1359              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA256,
1360              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA384,
1361              SecKeyAlgorithmAdaptorCopyResult_SignVerify_ECDSASignatureDigestX962SHA512,
1362  
1363              SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureRFC4754,
1364              SecKeyAlgorithmAdaptorCopyResult_Verify_ECDSASignatureDigestX962,
1365          };
1366          check_compile_time(array_size(verifyKeys) == array_size(verifyValues));
1367          adaptors[kSecKeyOperationTypeVerify] = CFDictionaryCreate(kCFAllocatorDefault, verifyKeys, verifyValues,
1368                                                                    array_size(verifyKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1369  
1370          const void *encryptKeys[] = {
1371              kSecKeyAlgorithmRSAEncryptionRaw,
1372              kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1373  
1374              kSecKeyAlgorithmRSAEncryptionPKCS1,
1375              kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1376              kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1377              kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1378              kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1379              kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1380  
1381              kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1382              kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1383              kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1384              kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1385              kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1386  
1387              kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1388              kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1389              kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1390              kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1391              kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1392  
1393              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1394              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1395              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1396              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1397              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1398  
1399              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
1400              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
1401              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
1402              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
1403  
1404              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
1405              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
1406              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
1407              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
1408          };
1409          const void *encryptValues[] = {
1410              SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1411              SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1412  
1413              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionPKCS1,
1414              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1,
1415              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224,
1416              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256,
1417              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384,
1418              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512,
1419  
1420              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA1AESGCM,
1421              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA224AESGCM,
1422              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA256AESGCM,
1423              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA384AESGCM,
1424              SecKeyAlgorithmAdaptorCopyResult_Encrypt_RSAEncryptionOAEPSHA512AESGCM,
1425  
1426              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA1,
1427              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA224,
1428              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA256,
1429              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA384,
1430              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardX963SHA512,
1431  
1432              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA1,
1433              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA224,
1434              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA256,
1435              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA384,
1436              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorX963SHA512,
1437  
1438              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA224,
1439              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA256,
1440              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA384,
1441              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESStandardVariableIVX963SHA512,
1442  
1443              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA224,
1444              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA256,
1445              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA384,
1446              SecKeyAlgorithmAdaptorCopyResult_Encrypt_ECIESCofactorVariableIVX963SHA512,
1447          };
1448          check_compile_time(array_size(encryptKeys) == array_size(encryptValues));
1449          adaptors[kSecKeyOperationTypeEncrypt] = CFDictionaryCreate(kCFAllocatorDefault, encryptKeys, encryptValues,
1450                                                                     array_size(encryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1451  
1452          const void *decryptKeys[] = {
1453              kSecKeyAlgorithmRSAEncryptionRaw,
1454              kSecKeyAlgorithmRSAEncryptionRawCCUnit,
1455  
1456              kSecKeyAlgorithmRSAEncryptionPKCS1,
1457              kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
1458              kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
1459              kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
1460              kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
1461              kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
1462  
1463              kSecKeyAlgorithmRSAEncryptionOAEPSHA1AESGCM,
1464              kSecKeyAlgorithmRSAEncryptionOAEPSHA224AESGCM,
1465              kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM,
1466              kSecKeyAlgorithmRSAEncryptionOAEPSHA384AESGCM,
1467              kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM,
1468  
1469              kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM,
1470              kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM,
1471              kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM,
1472              kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM,
1473              kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM,
1474  
1475              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM,
1476              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM,
1477              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM,
1478              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM,
1479              kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM,
1480  
1481              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM,
1482              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM,
1483              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM,
1484              kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM,
1485  
1486              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM,
1487              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM,
1488              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM,
1489              kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM,
1490  
1491              kSecKeyAlgorithmECIESEncryptionAKSSmartCard,
1492          };
1493          const void *decryptValues[] = {
1494              SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRaw,
1495              SecKeyAlgorithmAdaptorCopyResult_EncryptDecrypt_RSAEncryptionRawCCUnit,
1496  
1497              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionPKCS1,
1498              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1,
1499              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224,
1500              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256,
1501              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384,
1502              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512,
1503  
1504              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA1AESGCM,
1505              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA224AESGCM,
1506              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA256AESGCM,
1507              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA384AESGCM,
1508              SecKeyAlgorithmAdaptorCopyResult_Decrypt_RSAEncryptionOAEPSHA512AESGCM,
1509  
1510              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA1,
1511              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA224,
1512              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA256,
1513              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA384,
1514              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardX963SHA512,
1515  
1516              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA1,
1517              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA224,
1518              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA256,
1519              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA384,
1520              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorX963SHA512,
1521  
1522              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA224,
1523              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA256,
1524              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA384,
1525              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESStandardVariableIVX963SHA512,
1526  
1527              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA224,
1528              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA256,
1529              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA384,
1530              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIESCofactorVariableIVX963SHA512,
1531  
1532              SecKeyAlgorithmAdaptorCopyResult_Decrypt_ECIES_Standard_SHA256_2PubKeys,
1533          };
1534          check_compile_time(array_size(decryptKeys) == array_size(decryptValues));
1535          adaptors[kSecKeyOperationTypeDecrypt] = CFDictionaryCreate(kCFAllocatorDefault, decryptKeys, decryptValues,
1536                                                                     array_size(decryptKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1537  
1538          const void *keyExchangeKeys[] = {
1539              kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1,
1540              kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224,
1541              kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256,
1542              kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384,
1543              kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512,
1544  
1545              kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1,
1546              kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224,
1547              kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256,
1548              kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384,
1549              kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512,
1550          };
1551          const void *keyExchangeValues[] = {
1552  
1553              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA1,
1554              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA224,
1555              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA256,
1556              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA384,
1557              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHStandardX963SHA512,
1558  
1559              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA1,
1560              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA224,
1561              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA256,
1562              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA384,
1563              SecKeyAlgorithmAdaptorCopyResult_KeyExchange_ECDHCofactorX963SHA512,
1564          };
1565          check_compile_time(array_size(keyExchangeKeys) == array_size(keyExchangeKeys));
1566          adaptors[kSecKeyOperationTypeKeyExchange] = CFDictionaryCreate(kCFAllocatorDefault, keyExchangeKeys, keyExchangeValues,
1567                                                                         array_size(keyExchangeKeys), &kCFTypeDictionaryKeyCallBacks, NULL);
1568      });
1569      
1570      return CFDictionaryGetValue(adaptors[operation], algorithm);
1571  }