I'm trying to use CommonCrypto for crypting with AES-CTR and PKCS7 padding.
I am aware that CTR does not need padding in order to work correctly, there are uses for padding beyond that. Quoting RFC 3686:
For this reason, AES-CTR does not require the plaintext to be padded to a multiple of the block size. However, to provide limited traffic flow confidentiality, padding MAY be included, as specified in ESP.
Section 2.4 of the referenced document is relevant, and lists several uses of padding.
Therefore, I figure CommonCrypto should be able to apply padding to any cipher (mode). The code seems straight forward, breaking down to something like this:
CCCryptorRef cryptor = nil;
NSData* input = [NSMutableData dataWithLength:3];
NSData* key = [NSMutableData dataWithLength:32];
NSMutableData* output = [NSMutableData dataWithLength:32];
CCCryptorCreateWithMode(
kCCEncrypt, kCCModeCTR, kCCAlgorithmAES, ccPKCS7Padding,
nil,
key.bytes, key.length,
nil, 0, 0,
kCCModeOptionCTR_BE,
&cryptor
);
size_t written = 0;
CCCryptorUpdate(
cryptor,
input.bytes, input.length,
output.mutableBytes, output.length,
&written
);
size_t writtenF = 0;
CCCryptorFinal(
cryptor,
output.mutableBytes + written, output.length - written,
&writtenF);
CCCryptorRelease(cryptor);
output.length = written + writtenF;
NSLog(@"Expected: 16 bytes");
NSLog(@"Actual: %i bytes", output.length);
The output is:
Expected: 16 bytes
Actual: 3 bytes
If you check the status codes, you'll find there there are no errors.
I can decrypt the output just fine okay, so encryption itself seems to work just fine. But clearly no padding happens.
I can not debug into the implementations, so I have no idea what's going wrong. Am I using the options incorrectly?
Nota bene: I can make CCCrypt
apply padding with kCCOptionPKCS7Padding
, but then I don't see a way to select CTR mode.
This is a different use of padding. It is not PKCS#7 padding used in block ciphers. Its is RFC 2406 padding placed in the ESP packet behind the payload data (see below).
The confusion has taken you down a rabbit hole. It does not intersect with CommonCrypto like you are thinking. Stop now :)
From page 2 of RFC 2406: