session-ios/Signal/test/util/CryptoToolsTest.m

131 lines
6.6 KiB
Objective-C

#import <XCTest/XCTest.h>
#import "Util.h"
#import "CryptoTools.h"
#import "TestUtil.h"
@interface CryptoToolsTest : XCTestCase
@end
@implementation CryptoToolsTest
-(void) testIsEqualToData_TimingSafe {
test([[NSMutableData dataWithLength:0] isEqualToData_TimingSafe:[NSMutableData dataWithLength:0]]);
test([[NSMutableData dataWithLength:1] isEqualToData_TimingSafe:[NSMutableData dataWithLength:1]]);
test(![[NSMutableData dataWithLength:1] isEqualToData_TimingSafe:[NSMutableData dataWithLength:0]]);
test([[@"01020304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"01020305" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"05020305" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"05020304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
test(![[@"01050304" decodedAsHexString] isEqualToData_TimingSafe:[@"01020304" decodedAsHexString]]);
}
-(void) testKnownHmacSha1 {
char* keyText = "key";
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* key = [NSMutableData dataWithBytes:keyText length:strlen(keyText)];
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" decodedAsHexString];
NSData* actual = [val hmacWithSha1WithKey:key];
test([actual isEqualToData:expected]);
}
-(void) testKnownHmacSha256 {
char* keyText = "key";
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* key = [NSMutableData dataWithBytes:keyText length:strlen(keyText)];
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" decodedAsHexString];
NSData* actual = [val hmacWithSha256WithKey:key];
test([actual isEqualToData:expected]);
}
-(void) testAesCipherBlockChainingPadding {
NSData* iv = [@"000102030405060708090A0B0C0D0E0F" decodedAsHexString];
NSData* plain =[@"10b80d8098f0283a820e" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
NSData* cipher = [plain encryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:key andIv:iv];
test(cipher.length % 16 == 0);
NSData* replain = [cipher decryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:key andIv:iv];
test(plain.length == replain.length);
}
-(void) testKnownSha256 {
char* valText = "The quick brown fox jumps over the lazy dog";
NSData* val = [NSMutableData dataWithBytes:valText length:strlen(valText)];
NSData* expected = [@"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" decodedAsHexString];
NSData* actual = [val hashWithSha256];
test([actual isEqualToData:expected]);
}
-(void) testRandomForVariance {
NSData* d = [CryptoTools generateSecureRandomData:8];
NSData* d2 = [CryptoTools generateSecureRandomData:8];
test(5 == [[CryptoTools generateSecureRandomData:5] length]);
test(8 == d.length);
// extremely unlikely to fail if any reasonable amount of entropy is going into d and d2
test(![d isEqualToData:d2]);
}
-(void) testRandomUInt16GenerationForVariance{
uint16_t a = [CryptoTools generateSecureRandomUInt16];
uint16_t b = [CryptoTools generateSecureRandomUInt16];
uint16_t c = [CryptoTools generateSecureRandomUInt16];
uint16_t d = [CryptoTools generateSecureRandomUInt16];
// extremely unlikely to fail if any reasonable amount of entropy is generated
BOOL same =((a==b) && (a==c) && (a==d));
test (!same);
}
-(void) testKnownAesCipherFeedback {
NSData* iv = [@"000102030405060708090a0b0c0d0e0f" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172a" decodedAsHexString];
NSData* cipher =[@"3b3fd92eb72dad20333449f8e83cfb4a" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testPerturbedAesCipherFeedbackInverts {
for (int repeat = 0; repeat < 100; repeat++) {
NSData* iv = generatePseudoRandomData(16);
NSData* input = generatePseudoRandomData(16);
NSData* key = generatePseudoRandomData(16);
test([[[input encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
test([[[input decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
}
}
-(void) testKnownAesCounter {
NSData* iv = [@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172a" decodedAsHexString];
NSData* cipher =[@"874d6191b620e3261bef6864990db6ce" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testAesCounterEndianness {
NSData* iv = [@"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172ab1661dadd153b245034f1fb3655dc560" decodedAsHexString];
NSData* cipher =[@"874d6191b620e3261bef6864990db6ce874d6191b620e3261bef6864990db6ce" decodedAsHexString];
NSData* key =[@"2b7e151628aed2a6abf7158809cf4f3c" decodedAsHexString];
test([[plain encryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:cipher]);
test([[cipher decryptWithAesInCounterModeWithKey:key andIv:iv] isEqualToData:plain]);
}
-(void) testPerturbedAesCounterInverts {
for (int repeat = 0; repeat < 100; repeat++) {
NSData* iv = generatePseudoRandomData(16);
NSData* input = generatePseudoRandomData(16);
NSData* key = generatePseudoRandomData(16);
test([[[input encryptWithAesInCounterModeWithKey:key andIv:iv] decryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
test([[[input decryptWithAesInCounterModeWithKey:key andIv:iv] encryptWithAesInCipherFeedbackModeWithKey:key andIv:iv] isEqualToData:input]);
}
}
-(void) testComputeKnownOtp {
test([[CryptoTools computeOtpWithPassword:@"password" andCounter:123] isEqualToString:@"SiYZc8Xg6KSmCECSImVSmjnRNfc="]);
}
@end