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.
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.
Final interpretation : When
dataOut.bytesis passed as IV inCCCryptthen it means theCCCRyptgets the IV from the dataOut by its pointer as it has already the random IV in it which is generated bySecRandomCopyBytes. AlsodataOut.mutableBytes + ivLengthmeans the pointer is moved forward by ivLength bytes (so it points at immediately after the IV in the large buffer) ofdataOutfor storing cipher text as it has already the IV till that position.cryptByteswhich 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 codeNSMutableData *dataOut = [NSMutableData dataWithLength:ivLength + data.length + kCCBlockSizeAES128];for writing IV and Ciphered text, in the next line of codeint status = SecRandomCopyBytes(kSecRandomDefault, ivLength, dataOut.mutableBytes);the random IV of length 16 is written todataOut.mutableBytesbuffer. Now the NSMutableData has IV bytes in it. Next in CCCryptdataOut.bytescan 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 bydataOut.mutableBytes + ivLengthso this is actually the buffer position from where we have to write ciphered text after IV. At lastcryptoBytesreturns 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
dataOutasdataOut.length = cryptBytes + ivLength;So final dataOut variable has IV plus ciphered text and it is returned inreturn 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).