Merge branch 'charlesmchen/cleanupFormatting2'

pull/1/head
Matthew Chen 7 years ago
commit 55158e2a59

@ -12,11 +12,11 @@ def shared_pods
# pod 'AxolotlKit', path: '../SignalProtocolKit' # pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'SignalServiceKit', path: '.' pod 'SignalServiceKit', path: '.'
pod 'AxolotlKit', git: 'https://github.com/signalapp/SignalProtocolKit.git' pod 'AxolotlKit', git: 'https://github.com/signalapp/SignalProtocolKit.git'
#pod 'AxolotlKit', path: '../SignalProtocolKit' # pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'HKDFKit', git: 'https://github.com/signalapp/HKDFKit.git', branch: 'mkirk/framework-friendly' pod 'HKDFKit', git: 'https://github.com/signalapp/HKDFKit.git'
#pod 'HKDFKit', path: '../HKDFKit' # pod 'HKDFKit', path: '../HKDFKit'
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit', branch: 'mkirk/framework-friendly' pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit'
#pod 'Curve25519Kit', path: '../Curve25519Kit' # pod 'Curve25519Kit', path: '../Curve25519Kit'
pod 'GRKOpenSSLFramework', git: 'https://github.com/signalapp/GRKOpenSSLFramework' pod 'GRKOpenSSLFramework', git: 'https://github.com/signalapp/GRKOpenSSLFramework'
#pod 'GRKOpenSSLFramework', path: '../GRKOpenSSLFramework' #pod 'GRKOpenSSLFramework', path: '../GRKOpenSSLFramework'

@ -140,9 +140,9 @@ DEPENDENCIES:
- AFNetworking - AFNetworking
- ATAppUpdater - ATAppUpdater
- AxolotlKit (from `https://github.com/signalapp/SignalProtocolKit.git`) - AxolotlKit (from `https://github.com/signalapp/SignalProtocolKit.git`)
- Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit`, branch `mkirk/framework-friendly`) - Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit`)
- GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`) - GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`)
- HKDFKit (from `https://github.com/signalapp/HKDFKit.git`, branch `mkirk/framework-friendly`) - HKDFKit (from `https://github.com/signalapp/HKDFKit.git`)
- Mantle - Mantle
- PureLayout - PureLayout
- Reachability - Reachability
@ -173,12 +173,10 @@ EXTERNAL SOURCES:
AxolotlKit: AxolotlKit:
:git: https://github.com/signalapp/SignalProtocolKit.git :git: https://github.com/signalapp/SignalProtocolKit.git
Curve25519Kit: Curve25519Kit:
:branch: mkirk/framework-friendly
:git: https://github.com/signalapp/Curve25519Kit :git: https://github.com/signalapp/Curve25519Kit
GRKOpenSSLFramework: GRKOpenSSLFramework:
:git: https://github.com/signalapp/GRKOpenSSLFramework :git: https://github.com/signalapp/GRKOpenSSLFramework
HKDFKit: HKDFKit:
:branch: mkirk/framework-friendly
:git: https://github.com/signalapp/HKDFKit.git :git: https://github.com/signalapp/HKDFKit.git
SignalServiceKit: SignalServiceKit:
:path: "." :path: "."
@ -194,16 +192,16 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS: CHECKOUT OPTIONS:
AxolotlKit: AxolotlKit:
:commit: b523c0b82e76295726ded8afec2715328d63213c :commit: 54d5f90558578bb96ebfa9688b3905093b489e31
:git: https://github.com/signalapp/SignalProtocolKit.git :git: https://github.com/signalapp/SignalProtocolKit.git
Curve25519Kit: Curve25519Kit:
:commit: 03a19c80aafc10a3464f0c086b1eb38239c507ac :commit: ced146699622ebd3d282bbfce3d492db4456e9aa
:git: https://github.com/signalapp/Curve25519Kit :git: https://github.com/signalapp/Curve25519Kit
GRKOpenSSLFramework: GRKOpenSSLFramework:
:commit: b799c27e7927e5304ec1e4ad53c6d33c6fd1cae7 :commit: b799c27e7927e5304ec1e4ad53c6d33c6fd1cae7
:git: https://github.com/signalapp/GRKOpenSSLFramework :git: https://github.com/signalapp/GRKOpenSSLFramework
HKDFKit: HKDFKit:
:commit: d2e2e50990e88537d6c4e38cc32a6f6debd83446 :commit: 780f980b8ff3c4a24baf19088162f13605c0b272
:git: https://github.com/signalapp/HKDFKit.git :git: https://github.com/signalapp/HKDFKit.git
SocketRocket: SocketRocket:
:commit: 9f9563a83cd8960503074aa8de72206f83fb7a69 :commit: 9f9563a83cd8960503074aa8de72206f83fb7a69
@ -238,6 +236,6 @@ SPEC CHECKSUMS:
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4 YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
PODFILE CHECKSUM: dfec9ac3c4b7b32878c1b2cc2a27eb1e22574cda PODFILE CHECKSUM: aa9ff0d7d6d50852127963f4b8aa60d8d1eff8d3
COCOAPODS: 1.5.3 COCOAPODS: 1.5.3

@ -1 +1 @@
Subproject commit 320f4799d7f42af97da309fe7f59d5a6cb83cd28 Subproject commit 716524e3d03351f6a26a3883650e40991c9efdbe

@ -8,7 +8,6 @@
#import "OWSLinkedDevicesTableViewController.h" #import "OWSLinkedDevicesTableViewController.h"
#import "Signal-Swift.h" #import "Signal-Swift.h"
#import <SignalMessaging/OWSProfileManager.h> #import <SignalMessaging/OWSProfileManager.h>
#import <SignalServiceKit/ECKeyPair+OWSPrivateKey.h>
#import <SignalServiceKit/OWSDevice.h> #import <SignalServiceKit/OWSDevice.h>
#import <SignalServiceKit/OWSDeviceProvisioner.h> #import <SignalServiceKit/OWSDeviceProvisioner.h>
#import <SignalServiceKit/OWSIdentityManager.h> #import <SignalServiceKit/OWSIdentityManager.h>
@ -151,7 +150,7 @@ NS_ASSUME_NONNULL_BEGIN
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair]; ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
OWSAssert(identityKeyPair); OWSAssert(identityKeyPair);
NSData *myPublicKey = identityKeyPair.publicKey; NSData *myPublicKey = identityKeyPair.publicKey;
NSData *myPrivateKey = identityKeyPair.ows_privateKey; NSData *myPrivateKey = identityKeyPair.privateKey;
NSString *accountIdentifier = [TSAccountManager localNumber]; NSString *accountIdentifier = [TSAccountManager localNumber];
NSData *myProfileKeyData = self.profileManager.localProfileKey.keyData; NSData *myProfileKeyData = self.profileManager.localProfileKey.keyData;
BOOL areReadReceiptsEnabled = self.readReceiptManager.areReadReceiptsEnabled; BOOL areReadReceiptsEnabled = self.readReceiptManager.areReadReceiptsEnabled;

@ -206,21 +206,20 @@ static const compression_algorithm SignalCompressionAlgorithm = COMPRESSION_LZMA
} }
size_t srcLength = [srcData length]; size_t srcLength = [srcData length];
const uint8_t *srcBuffer = (const uint8_t *)[srcData bytes];
if (!srcBuffer) {
return nil;
}
// This assumes that dst will always be smaller than src. // This assumes that dst will always be smaller than src.
// //
// We slightly pad the buffer size to account for the worst case. // We slightly pad the buffer size to account for the worst case.
size_t dstBufferLength = srcLength + 64 * 1024; size_t dstBufferLength = srcLength + 64 * 1024;
uint8_t *dstBuffer = malloc(sizeof(uint8_t) * dstBufferLength); NSMutableData *dstBufferData = [NSMutableData dataWithLength:dstBufferLength];
if (!dstBuffer) { if (!dstBufferData) {
OWSFail(@"%@ Failed to allocate buffer.", self.logTag);
return nil; return nil;
} }
size_t dstLength = compression_encode_buffer( size_t dstLength = compression_encode_buffer(
dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, SignalCompressionAlgorithm); dstBufferData.mutableBytes, dstBufferLength, srcData.bytes, srcLength, NULL, SignalCompressionAlgorithm);
NSData *compressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES]; NSData *compressedData = [dstBufferData subdataWithRange:NSMakeRange(0, dstLength)];
DDLogVerbose(@"%@ compressed %zd -> %zd = %0.2f", DDLogVerbose(@"%@ compressed %zd -> %zd = %0.2f",
self.logTag, self.logTag,
@ -244,19 +243,18 @@ static const compression_algorithm SignalCompressionAlgorithm = COMPRESSION_LZMA
} }
size_t srcLength = [srcData length]; size_t srcLength = [srcData length];
const uint8_t *srcBuffer = (const uint8_t *)[srcData bytes];
if (!srcBuffer) {
return nil;
}
// We pad the buffer to be defensive. // We pad the buffer to be defensive.
size_t dstBufferLength = uncompressedDataLength + 1024; size_t dstBufferLength = uncompressedDataLength + 1024;
uint8_t *dstBuffer = malloc(sizeof(uint8_t) * dstBufferLength); NSMutableData *dstBufferData = [NSMutableData dataWithLength:dstBufferLength];
if (!dstBuffer) { if (!dstBufferData) {
OWSFail(@"%@ Failed to allocate buffer.", self.logTag);
return nil; return nil;
} }
size_t dstLength = compression_decode_buffer( size_t dstLength = compression_decode_buffer(
dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, SignalCompressionAlgorithm); dstBufferData.mutableBytes, dstBufferLength, srcData.bytes, srcLength, NULL, SignalCompressionAlgorithm);
NSData *decompressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES]; NSData *decompressedData = [dstBufferData subdataWithRange:NSMakeRange(0, dstLength)];
OWSAssert(decompressedData.length == uncompressedDataLength); OWSAssert(decompressedData.length == uncompressedDataLength);
DDLogVerbose(@"%@ decompressed %zd -> %zd = %0.2f", DDLogVerbose(@"%@ decompressed %zd -> %zd = %0.2f",
self.logTag, self.logTag,

@ -1,12 +1,12 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSProvisioningCipher.h" #import "OWSProvisioningCipher.h"
#import <CommonCrypto/CommonCrypto.h>
#import <Curve25519Kit/Curve25519.h> #import <Curve25519Kit/Curve25519.h>
#import <HKDFKit/HKDFKit.h> #import <HKDFKit/HKDFKit.h>
#import <SignalServiceKit/Cryptography.h> #import <SignalServiceKit/Cryptography.h>
#import <CommonCrypto/CommonCrypto.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
#pragma mark -
@implementation OWSProvisioningCipher @implementation OWSProvisioningCipher
- (instancetype)initWithTheirPublicKey:(NSData *)theirPublicKey - (instancetype)initWithTheirPublicKey:(NSData *)theirPublicKey
@ -67,13 +69,17 @@ NS_ASSUME_NONNULL_BEGIN
NSData *_Nullable cipherText = [self encrypt:dataToEncrypt withKey:cipherKey]; NSData *_Nullable cipherText = [self encrypt:dataToEncrypt withKey:cipherKey];
if (cipherText == nil) { if (cipherText == nil) {
OWSFail(@"Provisioning cipher failed."); OWSFail(@"%@ Provisioning cipher failed.", self.logTag);
return nil; return nil;
} }
[message appendData:cipherText]; [message appendData:cipherText];
NSData *mac = [self macForMessage:message withKey:macKey]; NSData *_Nullable mac = [self macForMessage:message withKey:macKey];
if (mac == nil) {
OWSFail(@"%@ mac failed.", self.logTag);
return nil;
}
[message appendData:mac]; [message appendData:mac];
return [message copy]; return [message copy];
@ -83,24 +89,20 @@ NS_ASSUME_NONNULL_BEGIN
{ {
NSData *iv = self.initializationVector; NSData *iv = self.initializationVector;
if (iv.length != kCCBlockSizeAES128) { if (iv.length != kCCBlockSizeAES128) {
OWSFail(@"Unexpected length for iv"); OWSFail(@"%@ Unexpected length for iv", self.logTag);
return nil;
}
if (dataToEncrypt.length >= SIZE_MAX - (kCCBlockSizeAES128 + iv.length)) {
OWSFail(@"%@ data is too long to encrypt.", self.logTag);
return nil; return nil;
} }
// allow space for message + padding any incomplete block. PKCS7 padding will always add at least one byte. // allow space for message + padding any incomplete block. PKCS7 padding will always add at least one byte.
size_t ciphertextBufferSize = dataToEncrypt.length + kCCBlockSizeAES128; size_t ciphertextBufferSize = dataToEncrypt.length + kCCBlockSizeAES128;
// message format is (iv || ciphertext) NSMutableData *ciphertextData = [[NSMutableData alloc] initWithLength:ciphertextBufferSize];
NSMutableData *encryptedMessage = [NSMutableData dataWithLength:iv.length + ciphertextBufferSize];
// write the iv
[encryptedMessage replaceBytesInRange:NSMakeRange(0, iv.length) withBytes:iv.bytes];
// cipher text follows iv
char *ciphertextBuffer = encryptedMessage.mutableBytes + iv.length;
size_t bytesEncrypted = 0; size_t bytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES, kCCAlgorithmAES,
kCCOptionPKCS7Padding, kCCOptionPKCS7Padding,
@ -109,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
iv.bytes, iv.bytes,
dataToEncrypt.bytes, dataToEncrypt.bytes,
dataToEncrypt.length, dataToEncrypt.length,
ciphertextBuffer, ciphertextData.mutableBytes,
ciphertextBufferSize, ciphertextBufferSize,
&bytesEncrypted); &bytesEncrypted);
@ -118,19 +120,18 @@ NS_ASSUME_NONNULL_BEGIN
return nil; return nil;
} }
return [encryptedMessage subdataWithRange:NSMakeRange(0, iv.length + bytesEncrypted)]; // message format is (iv || ciphertext)
NSMutableData *encryptedMessage = [NSMutableData new];
[encryptedMessage appendData:iv];
[encryptedMessage appendData:[ciphertextData subdataWithRange:NSMakeRange(0, bytesEncrypted)]];
return [encryptedMessage copy];
} }
- (NSData *)macForMessage:(NSData *)message withKey:(NSData *)macKey - (nullable NSData *)macForMessage:(NSData *)message withKey:(NSData *)macKey
{ {
NSMutableData *hmac = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; return [Cryptography computeSHA256HMAC:message withHMACKey:macKey];
CCHmac(kCCHmacAlgSHA256, macKey.bytes, macKey.length, message.bytes, message.length, hmac.mutableBytes);
return [hmac copy];
} }
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -1,15 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Curve25519Kit/Curve25519.h>
NS_ASSUME_NONNULL_BEGIN
@interface ECKeyPair (OWSPrivateKey)
- (NSData *)ows_privateKey;
@end
NS_ASSUME_NONNULL_END

@ -1,16 +0,0 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "ECKeyPair+OWSPrivateKey.h"
NS_ASSUME_NONNULL_BEGIN
@implementation ECKeyPair (OWSPrivateKey)
- (NSData *)ows_privateKey
{
return [NSData dataWithBytes:self->privateKey length:32];
}
@end
NS_ASSUME_NONNULL_END

@ -213,12 +213,20 @@ static uint32_t const OWSFingerprintDefaultHashIterations = 5200;
[hash appendData:publicKey]; [hash appendData:publicKey];
[hash appendData:stableIdData]; [hash appendData:stableIdData];
uint8_t digest[CC_SHA512_DIGEST_LENGTH]; NSMutableData *_Nullable digestData = [[NSMutableData alloc] initWithLength:CC_SHA512_DIGEST_LENGTH];
if (!digestData) {
@throw [NSException exceptionWithName:NSGenericException reason:@"Couldn't allocate buffer." userInfo:nil];
}
for (int i = 0; i < self.hashIterations; i++) { for (int i = 0; i < self.hashIterations; i++) {
[hash appendData:publicKey]; [hash appendData:publicKey];
CC_SHA512(hash.bytes, (unsigned int)hash.length, digest);
if (hash.length >= UINT32_MAX) {
@throw [NSException exceptionWithName:@"Oversize Data" reason:@"Oversize hash." userInfo:nil];
}
CC_SHA512(hash.bytes, (uint32_t)hash.length, digestData.mutableBytes);
// TODO get rid of this loop-allocation // TODO get rid of this loop-allocation
hash = [NSMutableData dataWithBytes:digest length:CC_SHA512_DIGEST_LENGTH]; hash = [digestData copy];
} }
return [hash copy]; return [hash copy];

@ -69,6 +69,8 @@ typedef NS_ENUM(NSInteger, TSMACType) {
+ (nullable NSData *)decryptAppleMessagePayload:(NSData *)payload withSignalingKey:(NSString *)signalingKeyString; + (nullable NSData *)decryptAppleMessagePayload:(NSData *)payload withSignalingKey:(NSString *)signalingKeyString;
+ (nullable NSData *)computeSHA256HMAC:(NSData *)data withHMACKey:(NSData *)HMACKey;
#pragma mark encrypt and decrypt attachment data #pragma mark encrypt and decrypt attachment data
// Though digest can and will be nil for legacy clients, we now reject attachments lacking a digest. // Though digest can and will be nil for legacy clients, we now reject attachments lacking a digest.

@ -198,10 +198,13 @@ const NSUInteger kAES256_KeyByteLength = 32;
} }
uint32_t dataLength = (uint32_t)data.length; uint32_t dataLength = (uint32_t)data.length;
uint8_t digest[CC_SHA256_DIGEST_LENGTH]; NSMutableData *_Nullable digestData = [[NSMutableData alloc] initWithLength:CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, dataLength, digest); if (!digestData) {
return OWSFail(@"%@ could not allocate buffer.", self.logTag);
[[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH] subdataWithRange:NSMakeRange(0, truncatedBytes)]; return nil;
}
CC_SHA256(data.bytes, dataLength, digestData.mutableBytes);
return [digestData subdataWithRange:NSMakeRange(0, truncatedBytes)];
} }
#pragma mark - HMAC/SHA256 #pragma mark - HMAC/SHA256
@ -219,9 +222,13 @@ const NSUInteger kAES256_KeyByteLength = 32;
} }
size_t hmacKeyLength = (size_t)HMACKey.length; size_t hmacKeyLength = (size_t)HMACKey.length;
uint8_t ourHmac[CC_SHA256_DIGEST_LENGTH] = {0}; NSMutableData *_Nullable ourHmacData = [[NSMutableData alloc] initWithLength:CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, [HMACKey bytes], hmacKeyLength, [data bytes], dataLength, ourHmac); if (!ourHmacData) {
return [NSData dataWithBytes:ourHmac length:CC_SHA256_DIGEST_LENGTH]; OWSFail(@"%@ could not allocate buffer.", self.logTag);
return nil;
}
CCHmac(kCCHmacAlgSHA256, [HMACKey bytes], hmacKeyLength, [data bytes], dataLength, ourHmacData.mutableBytes);
return [ourHmacData copy];
} }
+ (nullable NSData *)computeSHA1HMAC:(NSData *)data withHMACKey:(NSData *)HMACKey + (nullable NSData *)computeSHA1HMAC:(NSData *)data withHMACKey:(NSData *)HMACKey
@ -237,19 +244,32 @@ const NSUInteger kAES256_KeyByteLength = 32;
} }
size_t hmacKeyLength = (size_t)HMACKey.length; size_t hmacKeyLength = (size_t)HMACKey.length;
uint8_t ourHmac[CC_SHA256_DIGEST_LENGTH] = {0}; NSMutableData *_Nullable ourHmacData = [[NSMutableData alloc] initWithLength:CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, [HMACKey bytes], hmacKeyLength, [data bytes], dataLength, ourHmac); if (!ourHmacData) {
return [NSData dataWithBytes:ourHmac length:CC_SHA256_DIGEST_LENGTH]; OWSFail(@"%@ could not allocate buffer.", self.logTag);
return nil;
}
CCHmac(kCCHmacAlgSHA1, [HMACKey bytes], hmacKeyLength, [data bytes], dataLength, ourHmacData.mutableBytes);
return [ourHmacData copy];
} }
+ (nullable NSData *)truncatedSHA1HMAC:(NSData *)dataToHMAC withHMACKey:(NSData *)HMACKey truncation:(NSUInteger)bytes + (nullable NSData *)truncatedSHA1HMAC:(NSData *)dataToHMAC
withHMACKey:(NSData *)HMACKey
truncation:(NSUInteger)truncation
{ {
return [[Cryptography computeSHA1HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, bytes)]; OWSAssert(truncation >= CC_SHA1_DIGEST_LENGTH);
return [[Cryptography computeSHA1HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, truncation)];
} }
+ (nullable NSData *)truncatedSHA256HMAC:(NSData *)dataToHMAC withHMACKey:(NSData *)HMACKey truncation:(NSUInteger)bytes + (nullable NSData *)truncatedSHA256HMAC:(NSData *)dataToHMAC
withHMACKey:(NSData *)HMACKey
truncation:(NSUInteger)truncation
{ {
return [[Cryptography computeSHA256HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, bytes)]; OWSAssert(truncation >= CC_SHA256_DIGEST_LENGTH);
return
[[Cryptography computeSHA256HMAC:dataToHMAC withHMACKey:HMACKey] subdataWithRange:NSMakeRange(0, truncation)];
} }
#pragma mark - AES CBC Mode #pragma mark - AES CBC Mode
@ -322,30 +342,28 @@ const NSUInteger kAES256_KeyByteLength = 32;
// decrypt // decrypt
size_t bufferSize = [dataToDecrypt length] + kCCBlockSizeAES128; size_t bufferSize = [dataToDecrypt length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize); NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:bufferSize];
if (!bufferData) {
if (buffer == NULL) { DDLogError(@"%@ Failed to allocate buffer.", self.logTag);
DDLogError(@"%@ Failed to allocate memory.", self.logTag);
return nil; return nil;
} }
size_t bytesDecrypted = 0; size_t bytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128, kCCAlgorithmAES128,
kCCOptionPKCS7Padding, kCCOptionPKCS7Padding,
[key bytes], [key bytes],
[key length], [key length],
[iv bytes], [iv bytes],
[dataToDecrypt bytes], [dataToDecrypt bytes],
[dataToDecrypt length], [dataToDecrypt length],
buffer, bufferData.mutableBytes,
bufferSize, bufferSize,
&bytesDecrypted); &bytesDecrypted);
if (cryptStatus == kCCSuccess) { if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:bytesDecrypted freeWhenDone:YES]; return [bufferData subdataWithRange:NSMakeRange(0, bytesDecrypted)];
} else { } else {
DDLogError(@"%@ Failed CBC decryption", self.logTag); DDLogError(@"%@ Failed CBC decryption", self.logTag);
free(buffer);
} }
return nil; return nil;
@ -358,28 +376,41 @@ const NSUInteger kAES256_KeyByteLength = 32;
OWSAssert(payload); OWSAssert(payload);
OWSAssert(signalingKeyString); OWSAssert(signalingKeyString);
unsigned char version[1]; size_t versionLength = 1;
unsigned char iv[16]; size_t ivLength = 16;
NSUInteger ciphertext_length = ([payload length] - 10 - 17) * sizeof(char); size_t macLength = 10;
unsigned char *ciphertext = (unsigned char *)malloc(ciphertext_length); size_t nonCiphertextLength = versionLength + ivLength + macLength;
unsigned char mac[10]; size_t ciphertextLength = payload.length - nonCiphertextLength;
[payload getBytes:version range:NSMakeRange(0, 1)];
[payload getBytes:iv range:NSMakeRange(1, 16)]; if (payload.length < nonCiphertextLength) {
[payload getBytes:ciphertext range:NSMakeRange(17, [payload length] - 10 - 17)]; OWSFail(@"%@ Invalid payload", self.logTag);
[payload getBytes:mac range:NSMakeRange([payload length] - 10, 10)]; return nil;
}
if (payload.length >= MIN(SIZE_MAX, NSUIntegerMax) - nonCiphertextLength) {
OWSFail(@"%@ Invalid payload", self.logTag);
return nil;
}
NSUInteger cursor = 0;
NSData *versionData = [payload subdataWithRange:NSMakeRange(cursor, versionLength)];
cursor += versionLength;
NSData *ivData = [payload subdataWithRange:NSMakeRange(cursor, ivLength)];
cursor += ivLength;
NSData *ciphertextData = [payload subdataWithRange:NSMakeRange(cursor, ciphertextLength)];
cursor += ciphertextLength;
NSData *macData = [payload subdataWithRange:NSMakeRange(cursor, macLength)];
NSData *signalingKey = [NSData dataFromBase64String:signalingKeyString]; NSData *signalingKey = [NSData dataFromBase64String:signalingKeyString];
NSData *signalingKeyAESKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(0, 32)]; NSData *signalingKeyAESKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(0, 32)];
NSData *signalingKeyHMACKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(32, 20)]; NSData *signalingKeyHMACKeyMaterial = [signalingKey subdataWithRange:NSMakeRange(32, 20)];
return return [Cryptography decryptCBCMode:ciphertextData
[Cryptography decryptCBCMode:[NSData dataWithBytesNoCopy:ciphertext length:ciphertext_length freeWhenDone:YES] key:signalingKeyAESKeyMaterial
key:signalingKeyAESKeyMaterial IV:ivData
IV:[NSData dataWithBytes:iv length:16] version:versionData
version:[NSData dataWithBytes:version length:1] HMACKey:signalingKeyHMACKeyMaterial
HMACKey:signalingKeyHMACKeyMaterial HMACType:TSHMACSHA256Truncated10Bytes
HMACType:TSHMACSHA256Truncated10Bytes matchingHMAC:macData
matchingHMAC:[NSData dataWithBytes:mac length:10] digest:nil];
digest:nil];
} }
+ (nullable NSData *)decryptAttachment:(NSData *)dataToDecrypt + (nullable NSData *)decryptAttachment:(NSData *)dataToDecrypt
@ -496,33 +527,31 @@ const NSUInteger kAES256_KeyByteLength = 32;
// Encrypt // Encrypt
size_t bufferSize = [paddedAttachmentData length] + kCCBlockSizeAES128; size_t bufferSize = [paddedAttachmentData length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize); NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:bufferSize];
if (!bufferData) {
if (buffer == NULL) { DDLogError(@"%@ Failed to allocate buffer.", self.logTag);
DDLogError(@"%@ Failed to allocate memory.", self.logTag);
return nil; return nil;
} }
size_t bytesEncrypted = 0; size_t bytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128, kCCAlgorithmAES128,
kCCOptionPKCS7Padding, kCCOptionPKCS7Padding,
[encryptionKey bytes], [encryptionKey bytes],
[encryptionKey length], [encryptionKey length],
[iv bytes], [iv bytes],
[paddedAttachmentData bytes], [paddedAttachmentData bytes],
[paddedAttachmentData length], [paddedAttachmentData length],
buffer, bufferData.mutableBytes,
bufferSize, bufferSize,
&bytesEncrypted); &bytesEncrypted);
if (cryptStatus != kCCSuccess) { if (cryptStatus != kCCSuccess) {
DDLogError(@"%@ %s CCCrypt failed with status: %d", self.logTag, __PRETTY_FUNCTION__, (int32_t)cryptStatus); DDLogError(@"%@ %s CCCrypt failed with status: %d", self.logTag, __PRETTY_FUNCTION__, (int32_t)cryptStatus);
free(buffer);
return nil; return nil;
} }
NSData *cipherText = [NSData dataWithBytesNoCopy:buffer length:bytesEncrypted freeWhenDone:YES]; NSData *cipherText = [bufferData subdataWithRange:NSMakeRange(0, bytesEncrypted)];
NSMutableData *encryptedPaddedData = [NSMutableData data]; NSMutableData *encryptedPaddedData = [NSMutableData data];
[encryptedPaddedData appendData:iv]; [encryptedPaddedData appendData:iv];

Loading…
Cancel
Save