Strange SecKeyEncrypt Behavior

I am trying to implement RSA encryption using the PKCS1 add-on using the SecKeyEncrypt function.

The following code:

NSData *encryptText(NSString *text, SecKeyRef publicKey)
{
    NSCParameterAssert(text.length > 0);
    NSCParameterAssert(publicKey != NULL);
    NSData *dataToEncrypt = [text dataUsingEncoding:NSUTF8StringEncoding];
    const uint8_t *bytesToEncrypt = dataToEncrypt.bytes;

    size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
    NSCAssert(cipherBufferSize > 11, @"block size is too small: %zd", cipherBufferSize);

    const size_t inputBlockSize = cipherBufferSize - 11; // since we'll use PKCS1 padding
    uint8_t *cipherBuffer = (uint8_t *) malloc(sizeof(uint8_t) * cipherBufferSize);

    NSMutableData *accumulator = [[NSMutableData alloc] init];

    @try {

        for (size_t block = 0; block * inputBlockSize < dataToEncrypt.length; block++) {
            size_t blockOffset = block * inputBlockSize;
            const uint8_t *chunkToEncrypt = (bytesToEncrypt + block * inputBlockSize);
            const size_t remainingSize = dataToEncrypt.length - blockOffset;
            const size_t subsize = remainingSize < inputBlockSize ? remainingSize : inputBlockSize;

            size_t actualOutputSize = cipherBufferSize;
            OSStatus status = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, chunkToEncrypt, subsize, cipherBuffer, &actualOutputSize);

            if (status != noErr) {
                NSLog(@"Cannot encrypt data, last SecKeyEncrypt status: %ld", status);
                return nil;
            }

            [accumulator appendBytes:cipherBuffer length:actualOutputSize];
        }

        return [accumulator copy];
    }
    @finally {
        free(cipherBuffer);
    }
}

It works fine on iOS 6, but crashes on iOS 5, SecKeyEncrypt returns -50( errSecParam). It will work on iOS 5 if I change 11-12 in inputBlockSize = cipherBufferSize - 11. Apple doc says that input block length should be less than or equal SecKeyGetBlockSize() - 11if PKCS1 add-on is used. But on iOS 5, it definitely requires a shorter input.

The size of my key block is 64, so the maximum length of the input block is 53, according to the docs. On iOS 5, only 52 or less will work.

What is wrong with this code? Or is it an iOS 5 Security.framework bug?

UPD: 512- . 1024- , iOS 5 11

Apple doc: http://developer.apple.com/library/ios/documentation/Security/Reference/certifkeytrustservices/Reference/reference.html#//apple_ref/c/func/SecKeyEncrypt

+5

All Articles