Merge branch 'mkirk-2.18.0/handle-padded-attachments' into release/2.18.0

pull/1/head
Michael Kirk 8 years ago
commit aee6b3c0cf

@ -250,6 +250,7 @@ static const CGFloat kAttachmentDownloadProgressTheta = 0.001f;
NSData *plaintext = [Cryptography decryptAttachment:cipherText
withKey:attachment.encryptionKey
digest:attachment.digest
unpaddedSize:attachment.byteCount
error:&decryptError];
if (decryptError) {

@ -59,6 +59,7 @@ typedef NS_ENUM(NSInteger, TSMACType) {
+ (NSData *)decryptAttachment:(NSData *)dataToDecrypt
withKey:(NSData *)key
digest:(nullable NSData *)digest
unpaddedSize:(UInt32)unpaddedSize
error:(NSError **)error;
+ (NSData *)encryptAttachmentData:(NSData *)attachmentData

@ -297,6 +297,7 @@ const NSUInteger kAES256_KeyByteLength = 32;
+ (NSData *)decryptAttachment:(NSData *)dataToDecrypt
withKey:(NSData *)key
digest:(nullable NSData *)digest
unpaddedSize:(UInt32)unpaddedSize
error:(NSError **)error;
{
if (digest.length <= 0) {
@ -328,14 +329,51 @@ const NSUInteger kAES256_KeyByteLength = 32;
NSData *hmac = [dataToDecrypt
subdataWithRange:NSMakeRange([dataToDecrypt length] - HMAC256_OUTPUT_LENGTH, HMAC256_OUTPUT_LENGTH)];
return [Cryptography decryptCBCMode:encryptedAttachment
key:encryptionKey
IV:iv
version:nil
HMACKey:hmacKey
HMACType:TSHMACSHA256AttachementType
matchingHMAC:hmac
digest:digest];
NSData *paddedPlainText = [Cryptography decryptCBCMode:encryptedAttachment
key:encryptionKey
IV:iv
version:nil
HMACKey:hmacKey
HMACType:TSHMACSHA256AttachementType
matchingHMAC:hmac
digest:digest];
if (unpaddedSize == 0) {
// Work around for legacy iOS client's which weren't setting padding size.
// Since we know those clients pre-date attachment padding we return the entire data.
DDLogWarn(@"%@ Decrypted attachment with unspecified size.", self.tag);
return paddedPlainText;
} else {
if (unpaddedSize > paddedPlainText.length) {
*error = OWSErrorWithCodeDescription(
OWSErrorCodeFailedToDecryptMessage, NSLocalizedString(@"ERROR_MESSAGE_INVALID_MESSAGE", @""));
return nil;
}
if (unpaddedSize == paddedPlainText.length) {
DDLogInfo(@"%@ decrypted unpadded attachment.", self.tag);
return [paddedPlainText copy];
} else {
unsigned long paddingSize = paddedPlainText.length - unpaddedSize;
DDLogInfo(@"%@ decrypted padded attachment with unpaddedSize: %u, paddingSize: %lu",
self.tag,
unpaddedSize,
paddingSize);
return [paddedPlainText subdataWithRange:NSMakeRange(0, unpaddedSize)];
}
}
}
+ (unsigned long)paddedSize:(unsigned long)unpaddedSize
{
// Don't enable this until clients are sufficiently rolled out.
BOOL shouldPad = NO;
if (shouldPad) {
// Note: This just rounds up to the nearsest power of two,
// but the actual padding scheme is TBD
return pow(2, ceil( log2( unpaddedSize )));
} else {
return unpaddedSize;
}
}
+ (NSData *)encryptAttachmentData:(NSData *)attachmentData
@ -352,8 +390,13 @@ const NSUInteger kAES256_KeyByteLength = 32;
[attachmentKey appendData:hmacKey];
*outKey = [attachmentKey copy];
// Apply any padding
unsigned long desiredSize = [self paddedSize:attachmentData.length];
NSMutableData *paddedAttachmentData = [attachmentData mutableCopy];
paddedAttachmentData.length = desiredSize;
// Encrypt
size_t bufferSize = [attachmentData length] + kCCBlockSizeAES128;
size_t bufferSize = [paddedAttachmentData length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
if (buffer == NULL) {
@ -368,8 +411,8 @@ const NSUInteger kAES256_KeyByteLength = 32;
[encryptionKey bytes],
[encryptionKey length],
[iv bytes],
[attachmentData bytes],
[attachmentData length],
[paddedAttachmentData bytes],
[paddedAttachmentData length],
buffer,
bufferSize,
&bytesEncrypted);
@ -382,22 +425,22 @@ const NSUInteger kAES256_KeyByteLength = 32;
NSData *cipherText = [NSData dataWithBytesNoCopy:buffer length:bytesEncrypted freeWhenDone:YES];
NSMutableData *encryptedAttachmentData = [NSMutableData data];
[encryptedAttachmentData appendData:iv];
[encryptedAttachmentData appendData:cipherText];
NSMutableData *encryptedPaddedData = [NSMutableData data];
[encryptedPaddedData appendData:iv];
[encryptedPaddedData appendData:cipherText];
// compute hmac of: iv || encrypted data
NSData *hmac =
[Cryptography truncatedSHA256HMAC:encryptedAttachmentData withHMACKey:hmacKey truncation:HMAC256_OUTPUT_LENGTH];
[Cryptography truncatedSHA256HMAC:encryptedPaddedData withHMACKey:hmacKey truncation:HMAC256_OUTPUT_LENGTH];
DDLogVerbose(@"%@ computed hmac: %@", self.tag, hmac);
[encryptedAttachmentData appendData:hmac];
[encryptedPaddedData appendData:hmac];
// compute digest of: iv || encrypted data || hmac
*outDigest = [self computeSHA256Digest:encryptedAttachmentData];
*outDigest = [self computeSHA256Digest:encryptedPaddedData];
DDLogVerbose(@"%@ computed digest: %@", self.tag, *outDigest);
return [encryptedAttachmentData copy];
return [encryptedPaddedData copy];
}
+ (nullable NSData *)encryptAESGCMWithData:(NSData *)plaintext key:(OWSAES256Key *)key

Loading…
Cancel
Save