SecKeyDecrypt error -9809

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.

Replies

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];
    } 
}