1 Reply
      Latest reply: Oct 17, 2016 2:27 AM by eskimo RSS
      Mihai Damian Level 1 Level 1 (0 points)

        I'm trying to dercypt some data with SecKeyDecrypt. When calling this function it returns the -9809 status code if I use padding type .OAEP. If I use padding type .None I get status 0 but the decrypted result is actually garbage.

         

        Can anyone explain what status code -9809 means? I have not been able to find anything official about it.

        • Re: SecKeyDecrypt error -9809
          eskimo Apple Staff Apple Staff (6,250 points)

          Error -9809 is errSSLCrypto, a general error that’s returned when the Security framework gets an error from the underlying crypto.

          If you haven’t already looked at the CryptoCompatibility sample code, I suggest you do so.  It shows how to implement various crypto algorithms on Apple platforms such that the results match other common crypto toolkits.

          Unfortunately that version of CryptoCompatibility does not support OAEP.  I have new version in the pipeline that does, but it’s not yet on the developer web site.  In the meantime, I’ve pasted in some code below that shows the guts of the QCCRSASmallCryptor operation when using the legacy iOS crypto API (SecKeyDecrypt and friends).  In OAEP mode this operation produces results that are compatible with macOS’s built-in openssl tool when you run it like this:

          $ openssl rsautl -encrypt -oaep -pubin -inkey /path/to/public/key.pem -in /path/to/plaintext.dat
          
          $ openssl rsautl -decrypt -oaep -inkey /path/to/private/key.pem -in /path/to/cyphertext.dat
          

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

          - (void)runUsingRaw {
              OSStatus            err;
              SecPadding          padding;
              NSMutableData *     resultData;
              size_t              resultDataLength;
          
              // Map our padding constant appropriately.
          
              switch (self.padding) {
                  default:
                      assert(NO);
                      // fall through
                  case QCCRSASmallCryptorCompatPaddingPKCS1: {
                      padding = kSecPaddingPKCS1;
                  } break;
                  case QCCRSASmallCryptorCompatPaddingOẠEP: {
                      padding = kSecPaddingOẠEP;
                  } break;
              }
          
              // Do the crypto.
          
              resultData = [[NSMutableData alloc] initWithLength:SecKeyGetBlockSize(self.key)];
              resultDataLength = resultData.length;
              switch (self.op) {
                  default:
                      assert(NO);
                      // fall through
                  case QCCRSASmallCryptorCompatOperationEncrypt: {
                      err = SecKeyEncrypt(
                          self.key,
                          padding,
                          self.smallInputData.bytes, self.smallInputData.length,
                          resultData.mutableBytes, &resultDataLength
                      );
                  } break;
                  case QCCRSASmallCryptorCompatOperationDecrypt: {
                      err = SecKeyDecrypt(
                          self.key,
                          padding,
                          self.smallInputData.bytes, self.smallInputData.length,
                          resultData.mutableBytes, &resultDataLength
                      );
                  } break;
              }
          
              // Set up the result.
          
              if (err == errSecSuccess) {
                  // Set the output length to the value returned by the crypto.  This is necessary because,
                  // in the decrypt case, the padding means we have allocated more space that we need.
                  resultData.length = resultDataLength;
                  self.smallOutputData = resultData;
              } else {
                  self.error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil];
              } 
          }