user16780334
user16780334

Reputation: 502

How does the IV is getting prefixed in the CommonCrypto Objective-C aes?

I am implementing the AES/CBC encryption using the CommonCrypto library for Objective C code base and i found a code as answered by Zaph in which he recommends to prefix the IV with the encrypted text which we receive at the end of CommonCrypto's kCCEncrypt operation method zaph's answer. The bunch of code for AES encryption as suggested by him in one of his answer looks like this :

if (key.length != 16 && key.length != 24 && key.length != 32) {
        *error = [NSError errorWithDomain:@"keyLengthError" code:-1 userInfo:nil];
        return nil;
    }

CCCryptorStatus ccStatus   = kCCSuccess;
int             ivLength   = kCCBlockSizeAES128;
size_t          cryptBytes = 0;
NSMutableData  *dataOut     = [NSMutableData dataWithLength:ivLength + data.length + kCCBlockSizeAES128];

int status = SecRandomCopyBytes(kSecRandomDefault, ivLength, dataOut.mutableBytes);
if (status != 0) {
    *error = [NSError errorWithDomain:@"ivError" code:status userInfo:nil];
    return nil;
}
ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding,
                   key.bytes, key.length,
                   dataOut.bytes,
                   data.bytes, 
                   data.length,
                   dataOut.mutableBytes + ivLength, 
                   dataOut.length,
                   &cryptBytes);

if (ccStatus == kCCSuccess) {
    dataOut.length = cryptBytes + ivLength;
}
else {
    if (error) {
        *error = [NSError errorWithDomain:@"kEncryptionError" code:ccStatus userInfo:nil];
    }
    dataOut = nil;
}

return dataOut;

My doubt is at which line and how the IV is getting prefixed with the Encrypted text in the above code? Any help in understanding the code will help me a lot.

Upvotes: 0

Views: 145

Answers (1)

user16780334
user16780334

Reputation: 502

Dear all after much head scratching and slacking with the help of a wonderful person i am able to decode what the above code is doing .

There are four parts to it.

   1) The NSMutableData is initialized to size that's big enough to
    hold the ciphertext and the IV (IV length + data length + block
    size)
    
    2) The random IV is generated in place, at the beginning of the
    data, using SecRandomCopyBytes.
    
    3) Using a tiny bit of pointer arithmetics, the ciphertext is also
    written into the same Data, but the starting pointer is moved after
    the IV (dataOut.mutableBytes + ivLength). Technically it means that the dataOut.mutableBytes pointer is moved forward by ivLength
bytes (so it points at immediately after the IV in the large buffer)
    
    4) And finally, any excess noise is cut off by setting the length of
    the Data to the ivLength + the length of the ciphertext that CCCrypt
    reported

Final interpretation : When dataOut.bytes is passed as IV in CCCrypt then it means the CCCRypt gets the IV from the dataOut by its pointer as it has already the random IV in it which is generated by SecRandomCopyBytes . Also dataOut.mutableBytes + ivLength means the pointer is moved forward by ivLength bytes (so it points at immediately after the IV in the large buffer) of dataOut for storing cipher text as it has already the IV till that position.

cryptBytes which is returned just contains the length of the ciphered text. Thus the ciphered text as explained above is stored from the pointer position which was moved. Thus in short the NSMutableData was initialised with enough space by the code NSMutableData *dataOut = [NSMutableData dataWithLength:ivLength + data.length + kCCBlockSizeAES128];for writing IV and Ciphered text, in the next line of code int status = SecRandomCopyBytes(kSecRandomDefault, ivLength, dataOut.mutableBytes);the random IV of length 16 is written to dataOut.mutableBytes buffer. Now the NSMutableData has IV bytes in it. Next in CCCrypt dataOut.bytes can be passed as IV parameter as NSMutableData already has IV bytes. Moving next we have to give the buffer position for writing the crypted text , thus we are writing to NSMutableData by moving the pointer position defined by dataOut.mutableBytes + ivLength so this is actually the buffer position from where we have to write ciphered text after IV. At last cryptoBytes returns the length of the ciphered text(it does not has length of IV included as starting pointer was moved by +ivLength )

So finally NSMutableData has IV(length of 16 bytes) and Ciphered text(length given by cryptBytes) in it and thus the extra buffer space in NSMutableData is trimmed of by giving the length of dataOut as dataOut.length = cryptBytes + ivLength;So final dataOut variable has IV plus ciphered text and it is returned in return dataOut;

Note : it's important to consider that CCCrypt is a C function, it doesn't work on objects like NSData or NSStrings, but pointers to memory addresses. in other words, it doesn't care where you feed it inputs from and where it will write its output, as long as the pointed addresses are valid and there's enough space starting from that address allocated. (and of course, for inputs, the actual data is already there).

Upvotes: 0

Related Questions