title: Xcode 12: Implicit declaration of function 'SecKeyEncrypt' is invalid in C99
body: <p>After upgrading to Xcode 12.0.1 my command line Mac app (written in Swift) for file decryption runs into these errors when trying to build:</p>
  <ul>
  <li>Implicit declaration of function 'SecKeyEncrypt' is invalid in C99</li>
  <li>Implicit declaration of function 'SecKeyRawSign' is invalid in C99</li>
  <li>Implicit declaration of function 'SecKeyDecrypt' is invalid in C99</li>
  </ul>
  <p>The en-/de-cryption code (written in Objective C) was taken from <a href="https://github.com/ideawu/Objective-C-RSA" rel="nofollow noreferrer">https://github.com/ideawu/Objective-C-RSA</a> - it worked just fine in Xcode 11.
  It uses this import statement</p>
  <pre><code>#import &lt;Security/Security.h&gt;
  </code></pre>
  <p>&lt;Security/Security.h&gt; has a line</p>
  <pre><code>#include &lt;Security/SecKey.h&gt;
  </code></pre>
  <p>and in this file, the methods are declared:</p>
  <pre><code>#if SEC_OS_IPHONE
  /*!
   @function SecKeyRawSign
   @abstract Given a private key and data to sign, generate a digital
   signature.
   @param key Private key with which to sign.
   @param padding See Padding Types above, typically kSecPaddingPKCS1SHA1.
   @param dataToSign The data to be signed, typically the digest of the
   actual data.
   @param dataToSignLen Length of dataToSign in bytes.
   @param sig Pointer to buffer in which the signature will be returned.
   @param sigLen IN/OUT maximum length of sig buffer on input, actualy
   length of sig on output.
   @result A result code. See &quot;Security Error Codes&quot; (SecBase.h).
   @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding
   will be performed prior to signing. If this argument is kSecPaddingNone,
   the incoming data will be signed &quot;as is&quot;.
  
   When PKCS1 padding is performed, the maximum length of data that can
   be signed is the value returned by SecKeyGetBlockSize() - 11.
  
   NOTE: The behavior this function with kSecPaddingNone is undefined if the
   first byte of dataToSign is zero; there is no way to verify leading zeroes
   as they are discarded during the calculation.
  
   If you want to generate a proper PKCS1 style signature with DER encoding
   of the digest type - and the dataToSign is a SHA1 digest - use
   kSecPaddingPKCS1SHA1.
   */
  OSStatus SecKeyRawSign(
                         SecKeyRef           key,
                         SecPadding          padding,
                         const uint8_t       *dataToSign,
                         size_t              dataToSignLen,
                         uint8_t             *sig,
                         size_t              *sigLen)
  __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
  
  
  /*!
   @function SecKeyRawVerify
   @abstract Given a public key, data which has been signed, and a signature,
   verify the signature.
   @param key Public key with which to verify the signature.
   @param padding See Padding Types above, typically kSecPaddingPKCS1SHA1.
   @param signedData The data over which sig is being verified, typically
   the digest of the actual data.
   @param signedDataLen Length of signedData in bytes.
   @param sig Pointer to the signature to verify.
   @param sigLen Length of sig in  bytes.
   @result A result code. See &quot;Security Error Codes&quot; (SecBase.h).
   @discussion If the padding argument is kSecPaddingPKCS1, PKCS1 padding
   will be checked during verification. If this argument is kSecPaddingNone,
   the incoming data will be compared directly to sig.
  
   If you are verifying a proper PKCS1-style signature, with DER encoding
   of the digest type - and the signedData is a SHA1 digest - use
   kSecPaddingPKCS1SHA1.
   */
  OSStatus SecKeyRawVerify(
                           SecKeyRef           key,
                           SecPadding          padding,
                           const uint8_t       *signedData,
                           size_t              signedDataLen,
                           const uint8_t       *sig,
                           size_t              sigLen)
  __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
  
  
  /*!
   @function SecKeyEncrypt
   @abstract Encrypt a block of plaintext.
   @param key Public key with which to encrypt the data.
   @param padding See Padding Types above, typically kSecPaddingPKCS1.
   @param plainText The data to encrypt.
   @param plainTextLen Length of plainText in bytes, this must be less
   or equal to the value returned by SecKeyGetBlockSize().
   @param cipherText Pointer to the output buffer.
   @param cipherTextLen On input, specifies how much space is available at
   cipherText; on return, it is the actual number of cipherText bytes written.
   @result A result code. See &quot;Security Error Codes&quot; (SecBase.h).
   @discussion If the padding argument is kSecPaddingPKCS1 or kSecPaddingOAEP,
   PKCS1 (respectively kSecPaddingOAEP) padding will be performed prior to encryption.
   If this argument is kSecPaddingNone, the incoming data will be encrypted &quot;as is&quot;.
   kSecPaddingOAEP is the recommended value. Other value are not recommended
   for security reason (Padding attack or malleability).
  
   When PKCS1 padding is performed, the maximum length of data that can
   be encrypted is the value returned by SecKeyGetBlockSize() - 11.
  
   When memory usage is a critical issue, note that the input buffer
   (plainText) can be the same as the output buffer (cipherText).
   */
  OSStatus SecKeyEncrypt(
                         SecKeyRef           key,
                         SecPadding          padding,
                         const uint8_t        *plainText,
                         size_t              plainTextLen,
                         uint8_t             *cipherText,
                         size_t              *cipherTextLen)
  __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
  
  
  /*!
   @function SecKeyDecrypt
   @abstract Decrypt a block of ciphertext.
   @param key Private key with which to decrypt the data.
   @param padding See Padding Types above, typically kSecPaddingPKCS1.
   @param cipherText The data to decrypt.
   @param cipherTextLen Length of cipherText in bytes, this must be less
   or equal to the value returned by SecKeyGetBlockSize().
   @param plainText Pointer to the output buffer.
   @param plainTextLen On input, specifies how much space is available at
   plainText; on return, it is the actual number of plainText bytes written.
   @result A result code. See &quot;Security Error Codes&quot; (SecBase.h).
   @discussion If the padding argument is kSecPaddingPKCS1 or kSecPaddingOAEP,
   the corresponding padding will be removed after decryption.
   If this argument is kSecPaddingNone, the decrypted data will be returned &quot;as is&quot;.
  
   When memory usage is a critical issue, note that the input buffer
   (plainText) can be the same as the output buffer (cipherText).
   */
  OSStatus SecKeyDecrypt(
                         SecKeyRef           key,                /* Private key */
                         SecPadding          padding,         /* kSecPaddingNone,
                                                               kSecPaddingPKCS1,
                                                               kSecPaddingOAEP */
                         const uint8_t       *cipherText,
                         size_t              cipherTextLen,       /* length of cipherText */
                         uint8_t             *plainText,  
                         size_t              *plainTextLen)       /* IN/OUT */
  __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
  
  #endif // SEC_OS_IPHONE
  </code></pre>
  <p>The method for decryption where the error is raised looks like this:</p>
  <pre><code>+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
      const uint8_t *srcbuf = (const uint8_t *)[data bytes];
      size_t srclen = (size_t)data.length;
      
      size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
      UInt8 *outbuf = malloc(block_size);
      size_t src_block_size = block_size;
      
      NSMutableData *ret = [[NSMutableData alloc] init];
      for(int idx=0; idx&lt;srclen; idx+=src_block_size){
          //NSLog(@&quot;%d/%d block_size: %d&quot;, idx, (int)srclen, (int)block_size);
          size_t data_len = srclen - idx;
          if(data_len &gt; src_block_size){
              data_len = src_block_size;
          }
          
          size_t outlen = block_size;
          OSStatus status = noErr;
          status = SecKeyDecrypt(keyRef,   // &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; This raises the error
                                 kSecPaddingNone,
                                 srcbuf + idx,
                                 data_len,
                                 outbuf,
                                 &amp;outlen
                                 );
          if (status != 0) {
              NSLog(@&quot;SecKeyEncrypt fail. Error Code: %d&quot;, status);
              ret = nil;
              break;
          }else{
              //the actual decrypted data is in the middle, locate it!
              int idxFirstZero = -1;
              int idxNextZero = (int)outlen;
              for ( int i = 0; i &lt; outlen; i++ ) {
                  if ( outbuf[i] == 0 ) {
                      if ( idxFirstZero &lt; 0 ) {
                          idxFirstZero = i;
                      } else {
                          idxNextZero = i;
                          break;
                      }
                  }
              }
              
              [ret appendBytes:&amp;outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
          }
      }
      
      free(outbuf);
      CFRelease(keyRef);
      return ret;
  }
  </code></pre>
  <p>It seems that the en-/de-cryption functions cannot be called directly anymore. I am not sure what has changed here - is the problem due to a change in Xcode? And more importantly: how can this problem be fixed? (I am on Catalina 10.15.6)
  Any help is highly appreciated! (Please let me know if some information is missing.)</p>