diff --git a/TunnelKit/Sources/Core/CryptoAEAD.m b/TunnelKit/Sources/Core/CryptoAEAD.m index cff34d2..ed6f537 100644 --- a/TunnelKit/Sources/Core/CryptoAEAD.m +++ b/TunnelKit/Sources/Core/CryptoAEAD.m @@ -115,24 +115,6 @@ const NSInteger CryptoAEADTagLength = 16; [self prepareIV:self.cipherIVEnc withHMACKey:hmacKey]; } -- (NSData *)encryptData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - NSParameterAssert(data); - NSParameterAssert(extra); - - const uint8_t *bytes = data.bytes + offset; - const int length = (int)(data.length - offset); - const int maxOutputSize = (int)safe_crypto_capacity(data.length, self.overheadLength); - - NSMutableData *dest = [[NSMutableData alloc] initWithLength:maxOutputSize]; - NSInteger encryptedLength = INT_MAX; - if (![self encryptBytes:bytes length:length dest:dest.mutableBytes destLength:&encryptedLength extra:extra error:error]) { - return nil; - } - dest.length = encryptedLength; - return dest; -} - - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { NSParameterAssert(extra); @@ -179,24 +161,6 @@ const NSInteger CryptoAEADTagLength = 16; [self prepareIV:self.cipherIVDec withHMACKey:hmacKey]; } -- (NSData *)decryptData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - NSParameterAssert(data); - NSParameterAssert(extra); - - const uint8_t *bytes = data.bytes + offset; - const int length = (int)(data.length - offset); - const int maxOutputSize = (int)safe_crypto_capacity(data.length, self.overheadLength); - - NSMutableData *dest = [[NSMutableData alloc] initWithLength:maxOutputSize]; - NSInteger decryptedLength; - if (![self decryptBytes:bytes length:length dest:dest.mutableBytes destLength:&decryptedLength extra:extra error:error]) { - return nil; - } - dest.length = decryptedLength; - return dest; -} - - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { NSParameterAssert(extra); @@ -225,15 +189,9 @@ const NSInteger CryptoAEADTagLength = 16; TUNNEL_CRYPTO_RETURN_STATUS(code) } -- (BOOL)verifyData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - NSAssert(NO, @"Verification not supported"); - return NO; -} - - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { - NSAssert(NO, @"Verification not supported"); + [NSException raise:NSInvalidArgumentException format:@"Verification not supported"]; return NO; } diff --git a/TunnelKit/Sources/Core/CryptoCBC.m b/TunnelKit/Sources/Core/CryptoCBC.m index b7227a4..70753ad 100644 --- a/TunnelKit/Sources/Core/CryptoCBC.m +++ b/TunnelKit/Sources/Core/CryptoCBC.m @@ -138,23 +138,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100; HMAC_Init_ex(self.hmacCtxEnc, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); } -- (NSData *)encryptData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - NSParameterAssert(data); - - const uint8_t *bytes = data.bytes + offset; - const int length = (int)(data.length - offset); - const int maxOutputSize = (int)safe_crypto_capacity(data.length, self.overheadLength); - - NSMutableData *dest = [[NSMutableData alloc] initWithLength:maxOutputSize]; - NSInteger encryptedLength = INT_MAX; - if (![self encryptBytes:bytes length:length dest:dest.mutableBytes destLength:&encryptedLength extra:extra error:error]) { - return nil; - } - dest.length = encryptedLength; - return dest; -} - - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { uint8_t *outIV = dest + self.digestLength; @@ -214,24 +197,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100; HMAC_Init_ex(self.hmacCtxDec, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); } -- (NSData *)decryptData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - NSAssert(self.cipher, @"No cipher provided"); - NSParameterAssert(data); - - const uint8_t *bytes = data.bytes + offset; - const int length = (int)(data.length - offset); - const int maxOutputSize = (int)safe_crypto_capacity(data.length, self.overheadLength); - - NSMutableData *dest = [[NSMutableData alloc] initWithLength:maxOutputSize]; - NSInteger decryptedLength; - if (![self decryptBytes:bytes length:length dest:dest.mutableBytes destLength:&decryptedLength extra:extra error:error]) { - return nil; - } - dest.length = decryptedLength; - return dest; -} - - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { NSAssert(self.cipher, @"No cipher provided"); @@ -261,11 +226,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100; TUNNEL_CRYPTO_RETURN_STATUS(code) } -- (BOOL)verifyData:(NSData *)data offset:(NSInteger)offset extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error -{ - return [self verifyBytes:data.bytes length:data.length extra:extra error:error]; -} - - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error { int l1 = 0; diff --git a/TunnelKit/Sources/Core/Encryption.h b/TunnelKit/Sources/Core/Encryption.h index 333544c..2c9d662 100644 --- a/TunnelKit/Sources/Core/Encryption.h +++ b/TunnelKit/Sources/Core/Encryption.h @@ -51,7 +51,6 @@ NS_ASSUME_NONNULL_BEGIN - (int)overheadLength; - (int)extraLength; -- (nullable NSData *)encryptData:(NSData *)data offset:(NSInteger)offset extra:(nullable const uint8_t *)extra error:(NSError **)error; - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(nullable const uint8_t *)extra error:(NSError **)error; - (id)dataPathEncrypter; @@ -66,10 +65,8 @@ NS_ASSUME_NONNULL_BEGIN - (int)overheadLength; - (int)extraLength; -- (nullable NSData *)decryptData:(NSData *)data offset:(NSInteger)offset extra:(nullable const uint8_t *)extra error:(NSError **)error; - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8_t *)dest destLength:(NSInteger *)destLength extra:(nullable const uint8_t *)extra error:(NSError **)error; -- (BOOL)verifyData:(NSData *)data offset:(NSInteger)offset extra:(nullable const uint8_t *)extra error:(NSError **)error; -- (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length extra:(const uint8_t *)extra error:(NSError **)error; +- (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length extra:(nullable const uint8_t *)extra error:(NSError **)error; - (id)dataPathDecrypter; diff --git a/TunnelKit/Sources/Core/ZeroingData.h b/TunnelKit/Sources/Core/ZeroingData.h index 3e2fe3d..8298c5a 100644 --- a/TunnelKit/Sources/Core/ZeroingData.h +++ b/TunnelKit/Sources/Core/ZeroingData.h @@ -66,6 +66,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSString *)nullTerminatedStringFromOffset:(NSInteger)from; - (BOOL)isEqualToData:(NSData *)data; +- (NSData *)toData; // XXX: unsafe - (NSString *)toHex; @end diff --git a/TunnelKit/Sources/Core/ZeroingData.m b/TunnelKit/Sources/Core/ZeroingData.m index 2cab776..672418a 100644 --- a/TunnelKit/Sources/Core/ZeroingData.m +++ b/TunnelKit/Sources/Core/ZeroingData.m @@ -276,6 +276,11 @@ return !memcmp(_bytes, data.bytes, _count); } +- (NSData *)toData +{ + return [NSData dataWithBytes:_bytes length:_count]; +} + - (NSString *)toHex { const NSUInteger capacity = _count * 2; diff --git a/TunnelKitTests/DataManipulationTests.swift b/TunnelKitTests/DataManipulationTests.swift index 56df9a0..05f29c7 100644 --- a/TunnelKitTests/DataManipulationTests.swift +++ b/TunnelKitTests/DataManipulationTests.swift @@ -69,8 +69,8 @@ class DataManipulationTests: XCTestCase { let z2 = z1.withOffset(2, count: 3) // 5678ab let z3 = z2.appending(Z(Data(hex: "aaddcc"))) // 5678abaaddcc - XCTAssertEqual(z1.data, Data(hex: "12345678abcdef")) - XCTAssertEqual(z2.data, Data(hex: "5678ab")) - XCTAssertEqual(z3.data, Data(hex: "5678abaaddcc")) + XCTAssertEqual(z1.toData(), Data(hex: "12345678abcdef")) + XCTAssertEqual(z2.toData(), Data(hex: "5678ab")) + XCTAssertEqual(z3.toData(), Data(hex: "5678abaaddcc")) } } diff --git a/TunnelKitTests/EncryptionPerformanceTests.swift b/TunnelKitTests/EncryptionPerformanceTests.swift index 90f8e46..645c781 100644 --- a/TunnelKitTests/EncryptionPerformanceTests.swift +++ b/TunnelKitTests/EncryptionPerformanceTests.swift @@ -72,7 +72,7 @@ class EncryptionPerformanceTests: XCTestCase { let suite = TestUtils.generateDataSuite(1000, 100000) measure { for data in suite { - let _ = try! self.cbcEncrypter.encryptData(data, offset: 0, extra: nil) + let _ = try! self.cbcEncrypter.encryptData(data, extra: nil) } } } @@ -83,7 +83,7 @@ class EncryptionPerformanceTests: XCTestCase { let extra: [UInt8] = [0x11, 0x22, 0x33, 0x44] measure { for data in suite { - let _ = try! self.gcmEncrypter.encryptData(data, offset: 0, extra: extra) + let _ = try! self.gcmEncrypter.encryptData(data, extra: extra) } } } diff --git a/TunnelKitTests/EncryptionTests.swift b/TunnelKitTests/EncryptionTests.swift index aa1899d..4026c9d 100644 --- a/TunnelKitTests/EncryptionTests.swift +++ b/TunnelKitTests/EncryptionTests.swift @@ -55,43 +55,38 @@ class EncryptionTests: XCTestCase { func testCBC() { let cbc = CryptoBox(cipherAlgorithm: "aes-128-cbc", digestAlgorithm: "sha256") - try! cbc.configure(withCipherEncKey: cipherKey, cipherDecKey: cipherKey, hmacEncKey: hmacKey, hmacDecKey: hmacKey) + XCTAssertNoThrow(try cbc.configure(withCipherEncKey: cipherKey, cipherDecKey: cipherKey, hmacEncKey: hmacKey, hmacDecKey: hmacKey)) let enc = cbc.encrypter() let dec = cbc.decrypter() let plain = Data(hex: "00112233445566778899") - let encrypted = try! enc.encryptData(plain, offset: 0, extra: nil) - let decrypted = try! dec.decryptData(encrypted, offset: 0, extra: nil) + let encrypted = try! enc.encryptData(plain, extra: nil) + let decrypted = try! dec.decryptData(encrypted, extra: nil) XCTAssertEqual(plain, decrypted) } func testHMAC() { let cbc = CryptoBox(cipherAlgorithm: nil, digestAlgorithm: "sha256") - try! cbc.configure(withCipherEncKey: nil, cipherDecKey: nil, hmacEncKey: hmacKey, hmacDecKey: hmacKey) + XCTAssertNoThrow(try cbc.configure(withCipherEncKey: nil, cipherDecKey: nil, hmacEncKey: hmacKey, hmacDecKey: hmacKey)) let enc = cbc.encrypter() let dec = cbc.decrypter() let plain = Data(hex: "00112233445566778899") - let encrypted = try! enc.encryptData(plain, offset: 0, extra: nil) - do { - try dec.verifyData(encrypted, offset: 0, extra: nil) - XCTAssert(true) - } catch { - XCTAssert(false) - } + let encrypted = try! enc.encryptData(plain, extra: nil) + XCTAssertNoThrow(try dec.verifyData(encrypted, extra: nil)) } func testGCM() { let gcm = CryptoBox(cipherAlgorithm: "aes-256-gcm", digestAlgorithm: nil) - try! gcm.configure(withCipherEncKey: cipherKey, cipherDecKey: cipherKey, hmacEncKey: hmacKey, hmacDecKey: hmacKey) + XCTAssertNoThrow(try gcm.configure(withCipherEncKey: cipherKey, cipherDecKey: cipherKey, hmacEncKey: hmacKey, hmacDecKey: hmacKey)) let enc = gcm.encrypter() let dec = gcm.decrypter() // let packetId: UInt32 = 0x56341200 let extra: [UInt8] = [0x00, 0x12, 0x34, 0x56] let plain = Data(hex: "00112233445566778899") - let encrypted = try! enc.encryptData(plain, offset: 0, extra: extra) - let decrypted = try! dec.decryptData(encrypted, offset: 0, extra: extra) + let encrypted = try! enc.encryptData(plain, extra: extra) + let decrypted = try! dec.decryptData(encrypted, extra: extra) XCTAssertEqual(plain, decrypted) } diff --git a/TunnelKitTests/TestUtils.swift b/TunnelKitTests/TestUtils.swift index a481fe5..8e516a5 100644 --- a/TunnelKitTests/TestUtils.swift +++ b/TunnelKitTests/TestUtils.swift @@ -56,8 +56,35 @@ class TestUtils { } } -extension ZeroingData { - var data: Data { - return Data(bytes: bytes, count: count) +extension Encrypter { + func encryptData(_ data: Data, extra: [UInt8]?) throws -> Data { + let srcLength = data.count + var dest: [UInt8] = Array(repeating: 0, count: srcLength + 256) + var destLength = 0 + try data.withUnsafeBytes { + try encryptBytes($0, length: srcLength, dest: &dest, destLength: &destLength, extra: extra) + } + dest.removeSubrange(destLength.. Data { + let srcLength = data.count + var dest: [UInt8] = Array(repeating: 0, count: srcLength + 256) + var destLength = 0 + try data.withUnsafeBytes { + try decryptBytes($0, length: srcLength, dest: &dest, destLength: &destLength, extra: extra) + } + dest.removeSubrange(destLength..