#import "CryptoToolsTest.h" #import "Util.h" #import "CryptoTools.h" #import "TestUtil.h" @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]; int n = sizeof(uint32_t); // extremely unlikely to fail if any reasonable amount of entropy is going into d and d2 test(!(a==b==c==d)); } -(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