Merge branch 'refactor-encryption'

This commit is contained in:
Davide De Rosa 2018-09-20 23:21:43 +02:00
commit 1ba7e73e9c
19 changed files with 129 additions and 202 deletions

View File

@ -11,8 +11,8 @@
0E07596020EF6D1400F38FD8 /* CryptoCBC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */; }; 0E07596020EF6D1400F38FD8 /* CryptoCBC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */; };
0E07596320EF733F00F38FD8 /* CryptoMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596120EF733F00F38FD8 /* CryptoMacros.h */; }; 0E07596320EF733F00F38FD8 /* CryptoMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596120EF733F00F38FD8 /* CryptoMacros.h */; };
0E07596420EF733F00F38FD8 /* CryptoMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596120EF733F00F38FD8 /* CryptoMacros.h */; }; 0E07596420EF733F00F38FD8 /* CryptoMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596120EF733F00F38FD8 /* CryptoMacros.h */; };
0E07596B20EF79AB00F38FD8 /* Encryption.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596A20EF79AB00F38FD8 /* Encryption.h */; }; 0E07596B20EF79AB00F38FD8 /* Crypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596A20EF79AB00F38FD8 /* Crypto.h */; };
0E07596C20EF79AB00F38FD8 /* Encryption.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596A20EF79AB00F38FD8 /* Encryption.h */; }; 0E07596C20EF79AB00F38FD8 /* Crypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596A20EF79AB00F38FD8 /* Crypto.h */; };
0E07596E20EF79B400F38FD8 /* CryptoCBC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596D20EF79B400F38FD8 /* CryptoCBC.h */; }; 0E07596E20EF79B400F38FD8 /* CryptoCBC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596D20EF79B400F38FD8 /* CryptoCBC.h */; };
0E07596F20EF79B400F38FD8 /* CryptoCBC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596D20EF79B400F38FD8 /* CryptoCBC.h */; }; 0E07596F20EF79B400F38FD8 /* CryptoCBC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596D20EF79B400F38FD8 /* CryptoCBC.h */; };
0E07597E20F0060E00F38FD8 /* CryptoAEAD.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */; }; 0E07597E20F0060E00F38FD8 /* CryptoAEAD.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */; };
@ -185,7 +185,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoCBC.m; sourceTree = "<group>"; }; 0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoCBC.m; sourceTree = "<group>"; };
0E07596120EF733F00F38FD8 /* CryptoMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoMacros.h; sourceTree = "<group>"; }; 0E07596120EF733F00F38FD8 /* CryptoMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoMacros.h; sourceTree = "<group>"; };
0E07596A20EF79AB00F38FD8 /* Encryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Encryption.h; sourceTree = "<group>"; }; 0E07596A20EF79AB00F38FD8 /* Crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crypto.h; sourceTree = "<group>"; };
0E07596D20EF79B400F38FD8 /* CryptoCBC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoCBC.h; sourceTree = "<group>"; }; 0E07596D20EF79B400F38FD8 /* CryptoCBC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoCBC.h; sourceTree = "<group>"; };
0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAEAD.h; sourceTree = "<group>"; }; 0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAEAD.h; sourceTree = "<group>"; };
0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoAEAD.m; sourceTree = "<group>"; }; 0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoAEAD.m; sourceTree = "<group>"; };
@ -236,7 +236,7 @@
0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+CompressionFraming.swift"; sourceTree = "<group>"; }; 0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+CompressionFraming.swift"; sourceTree = "<group>"; };
0EE7A79420F61EDC00B42E6A /* PacketMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketMacros.h; sourceTree = "<group>"; }; 0EE7A79420F61EDC00B42E6A /* PacketMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketMacros.h; sourceTree = "<group>"; };
0EE7A79720F6296F00B42E6A /* PacketMacros.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PacketMacros.m; sourceTree = "<group>"; }; 0EE7A79720F6296F00B42E6A /* PacketMacros.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PacketMacros.m; sourceTree = "<group>"; };
0EE7A79D20F6488400B42E6A /* DataPathEncryption.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataPathEncryption.h; sourceTree = "<group>"; }; 0EE7A79D20F6488400B42E6A /* DataPathCrypto.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataPathCrypto.h; sourceTree = "<group>"; };
0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataPathEncryptionTests.swift; sourceTree = "<group>"; }; 0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataPathEncryptionTests.swift; sourceTree = "<group>"; };
0EEC49DB20B5E732008FEB91 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; }; 0EEC49DB20B5E732008FEB91 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+EncryptionBridge.swift"; sourceTree = "<group>"; }; 0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+EncryptionBridge.swift"; sourceTree = "<group>"; };
@ -440,6 +440,7 @@
0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */, 0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */,
0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */, 0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */,
0EFEB44A2006D3C800F81029 /* CoreConfiguration.swift */, 0EFEB44A2006D3C800F81029 /* CoreConfiguration.swift */,
0E07596A20EF79AB00F38FD8 /* Crypto.h */,
0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */, 0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */,
0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */, 0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */,
0EFEB4402006D3C800F81029 /* CryptoBox.h */, 0EFEB4402006D3C800F81029 /* CryptoBox.h */,
@ -450,8 +451,7 @@
0EFEB4432006D3C800F81029 /* Data+Manipulation.swift */, 0EFEB4432006D3C800F81029 /* Data+Manipulation.swift */,
0EFEB4352006D3C800F81029 /* DataPath.h */, 0EFEB4352006D3C800F81029 /* DataPath.h */,
0EFEB44C2006D3C800F81029 /* DataPath.m */, 0EFEB44C2006D3C800F81029 /* DataPath.m */,
0EE7A79D20F6488400B42E6A /* DataPathEncryption.h */, 0EE7A79D20F6488400B42E6A /* DataPathCrypto.h */,
0E07596A20EF79AB00F38FD8 /* Encryption.h */,
0EFEB4362006D3C800F81029 /* Errors.h */, 0EFEB4362006D3C800F81029 /* Errors.h */,
0EFEB44B2006D3C800F81029 /* Errors.m */, 0EFEB44B2006D3C800F81029 /* Errors.m */,
0EFEB4452006D3C800F81029 /* IOInterface.swift */, 0EFEB4452006D3C800F81029 /* IOInterface.swift */,
@ -539,7 +539,7 @@
0E07596E20EF79B400F38FD8 /* CryptoCBC.h in Headers */, 0E07596E20EF79B400F38FD8 /* CryptoCBC.h in Headers */,
0E07596320EF733F00F38FD8 /* CryptoMacros.h in Headers */, 0E07596320EF733F00F38FD8 /* CryptoMacros.h in Headers */,
0EFEB46E2006D3C800F81029 /* TLSBox.h in Headers */, 0EFEB46E2006D3C800F81029 /* TLSBox.h in Headers */,
0E07596B20EF79AB00F38FD8 /* Encryption.h in Headers */, 0E07596B20EF79AB00F38FD8 /* Crypto.h in Headers */,
0EFEB46B2006D3C800F81029 /* CryptoBox.h in Headers */, 0EFEB46B2006D3C800F81029 /* CryptoBox.h in Headers */,
0EFEB4592006D3C800F81029 /* Allocation.h in Headers */, 0EFEB4592006D3C800F81029 /* Allocation.h in Headers */,
0EFEB4582006D3C800F81029 /* MSS.h in Headers */, 0EFEB4582006D3C800F81029 /* MSS.h in Headers */,
@ -561,7 +561,7 @@
0E07596F20EF79B400F38FD8 /* CryptoCBC.h in Headers */, 0E07596F20EF79B400F38FD8 /* CryptoCBC.h in Headers */,
0E07596420EF733F00F38FD8 /* CryptoMacros.h in Headers */, 0E07596420EF733F00F38FD8 /* CryptoMacros.h in Headers */,
0EEC49EA20B5F7F6008FEB91 /* ZeroingData.h in Headers */, 0EEC49EA20B5F7F6008FEB91 /* ZeroingData.h in Headers */,
0E07596C20EF79AB00F38FD8 /* Encryption.h in Headers */, 0E07596C20EF79AB00F38FD8 /* Crypto.h in Headers */,
0EEC49E120B5F7EA008FEB91 /* Allocation.h in Headers */, 0EEC49E120B5F7EA008FEB91 /* Allocation.h in Headers */,
0EEC49E320B5F7F6008FEB91 /* DataPath.h in Headers */, 0EEC49E320B5F7F6008FEB91 /* DataPath.h in Headers */,
0EF5CF282141E183004FF1BD /* CompressionFramingNative.h in Headers */, 0EF5CF282141E183004FF1BD /* CompressionFramingNative.h in Headers */,

View File

@ -50,15 +50,15 @@ extension ControlChannel {
var offset = start var offset = start
let end = end ?? packet.count let end = end ?? packet.count
guard end >= offset + PacketHeaderLength else { guard end >= offset + PacketOpcodeLength else {
throw ControlChannelError("Missing header") throw ControlChannelError("Missing opcode")
} }
let codeValue = packet[offset] >> 3 let codeValue = packet[offset] >> 3
guard let code = PacketCode(rawValue: codeValue) else { guard let code = PacketCode(rawValue: codeValue) else {
throw ControlChannelError("Unknown code: \(codeValue))") throw ControlChannelError("Unknown code: \(codeValue))")
} }
let key = packet[offset] & 0b111 let key = packet[offset] & 0b111
offset += PacketHeaderLength offset += PacketOpcodeLength
log.debug("Control: Try read packet with code \(code) and key \(key)") log.debug("Control: Try read packet with code \(code) and key \(key)")

View File

@ -52,7 +52,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, readonly) NSData *_Nullable payload; @property (nonatomic, strong, readonly) NSData *_Nullable payload;
@property (nonatomic, strong) NSDate *_Nullable sentDate; @property (nonatomic, strong) NSDate *_Nullable sentDate;
- (NSInteger)serializeTo:(nullable uint8_t *)to; - (NSInteger)capacity;
- (NSInteger)serializeTo:(uint8_t *)to;
- (NSData *)serialized; - (NSData *)serialized;
@end @end

View File

@ -80,7 +80,7 @@
const BOOL isAck = self.isAck; const BOOL isAck = self.isAck;
const NSUInteger ackLength = self.ackIds.count; const NSUInteger ackLength = self.ackIds.count;
NSCAssert(!isAck || ackLength > 0, @"Ack packet must provide positive ackLength"); NSCAssert(!isAck || ackLength > 0, @"Ack packet must provide positive ackLength");
NSInteger n = PacketHeaderLength + PacketSessionIdLength; NSInteger n = PacketOpcodeLength + PacketSessionIdLength;
n += PacketAckLengthLength; n += PacketAckLengthLength;
if (ackLength > 0) { if (ackLength > 0) {
n += ackLength * PacketIdLength + PacketSessionIdLength; n += ackLength * PacketIdLength + PacketSessionIdLength;
@ -95,9 +95,6 @@
// Ruby: send_ctrl // Ruby: send_ctrl
- (NSInteger)serializeTo:(uint8_t *)to - (NSInteger)serializeTo:(uint8_t *)to
{ {
if (!to) {
return [self capacity];
}
uint8_t *ptr = to; uint8_t *ptr = to;
ptr += PacketHeaderSet(ptr, self.code, self.key, self.sessionId.bytes); ptr += PacketHeaderSet(ptr, self.code, self.key, self.sessionId.bytes);
if (self.ackIds.count > 0) { if (self.ackIds.count > 0) {
@ -124,7 +121,7 @@
ptr += self.payload.length; ptr += self.payload.length;
} }
} }
return (int)(ptr - to); return ptr - to;
} }
- (NSData *)serialized - (NSData *)serialized

View File

@ -1,5 +1,5 @@
// //
// Encryption.h // Crypto.h
// TunnelKit // TunnelKit
// //
// Created by Davide De Rosa on 3/3/17. // Created by Davide De Rosa on 3/3/17.
@ -48,10 +48,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureEncryptionWithCipherKey:(nullable ZeroingData *)cipherKey hmacKey:(nullable ZeroingData *)hmacKey; - (void)configureEncryptionWithCipherKey:(nullable ZeroingData *)cipherKey hmacKey:(nullable ZeroingData *)hmacKey;
- (int)digestLength; - (int)digestLength;
- (int)overheadLength;
- (int)extraLength;
- (nullable NSData *)encryptData:(NSData *)data offset:(NSInteger)offset extra:(nullable const uint8_t *)extra error:(NSError **)error; - (NSInteger)encryptionCapacityWithLength:(NSInteger)length;
- (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; - (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>)dataPathEncrypter; - (id<DataPathEncrypter>)dataPathEncrypter;
@ -63,13 +61,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureDecryptionWithCipherKey:(nullable ZeroingData *)cipherKey hmacKey:(nullable ZeroingData *)hmacKey; - (void)configureDecryptionWithCipherKey:(nullable ZeroingData *)cipherKey hmacKey:(nullable ZeroingData *)hmacKey;
- (int)digestLength; - (int)digestLength;
- (int)overheadLength;
- (int)extraLength;
- (nullable NSData *)decryptData:(NSData *)data offset:(NSInteger)offset extra:(nullable const uint8_t *)extra error:(NSError **)error; - (NSInteger)encryptionCapacityWithLength:(NSInteger)length;
- (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)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:(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;
- (id<DataPathDecrypter>)dataPathDecrypter; - (id<DataPathDecrypter>)dataPathDecrypter;

View File

@ -36,8 +36,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "Encryption.h" #import "Crypto.h"
#import "DataPathEncryption.h" #import "DataPathCrypto.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -50,7 +50,6 @@ const NSInteger CryptoAEADTagLength = 16;
@property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher; @property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher;
@property (nonatomic, assign) int cipherKeyLength; @property (nonatomic, assign) int cipherKeyLength;
@property (nonatomic, assign) int cipherIVLength; // 12 (AD packetId + HMAC key) @property (nonatomic, assign) int cipherIVLength; // 12 (AD packetId + HMAC key)
@property (nonatomic, assign) int overheadLength;
@property (nonatomic, assign) int extraPacketIdOffset; @property (nonatomic, assign) int extraPacketIdOffset;
@property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc;
@ -73,7 +72,6 @@ const NSInteger CryptoAEADTagLength = 16;
self.cipherKeyLength = EVP_CIPHER_key_length(self.cipher); self.cipherKeyLength = EVP_CIPHER_key_length(self.cipher);
self.cipherIVLength = EVP_CIPHER_iv_length(self.cipher); self.cipherIVLength = EVP_CIPHER_iv_length(self.cipher);
self.overheadLength = CryptoAEADTagLength;
self.extraLength = PacketIdLength; self.extraLength = PacketIdLength;
self.extraPacketIdOffset = 0; self.extraPacketIdOffset = 0;
@ -102,6 +100,11 @@ const NSInteger CryptoAEADTagLength = 16;
return 0; return 0;
} }
- (NSInteger)encryptionCapacityWithLength:(NSInteger)length
{
return safe_crypto_capacity(length, CryptoAEADTagLength);
}
#pragma mark Encrypter #pragma mark Encrypter
- (void)configureEncryptionWithCipherKey:(ZeroingData *)cipherKey hmacKey:(ZeroingData *)hmacKey - (void)configureEncryptionWithCipherKey:(ZeroingData *)cipherKey hmacKey:(ZeroingData *)hmacKey
@ -115,24 +118,6 @@ const NSInteger CryptoAEADTagLength = 16;
[self prepareIV:self.cipherIVEnc withHMACKey:hmacKey]; [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 - (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); NSParameterAssert(extra);
@ -179,24 +164,6 @@ const NSInteger CryptoAEADTagLength = 16;
[self prepareIV:self.cipherIVDec withHMACKey:hmacKey]; [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 - (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); NSParameterAssert(extra);
@ -225,15 +192,9 @@ const NSInteger CryptoAEADTagLength = 16;
TUNNEL_CRYPTO_RETURN_STATUS(code) 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 - (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; return NO;
} }
@ -276,17 +237,12 @@ const NSInteger CryptoAEADTagLength = 16;
#pragma mark DataPathChannel #pragma mark DataPathChannel
- (int)overheadLength
{
return self.crypto.overheadLength;
}
- (void)setPeerId:(uint32_t)peerId - (void)setPeerId:(uint32_t)peerId
{ {
peerId &= 0xffffff; peerId &= 0xffffff;
if (peerId == PacketPeerIdDisabled) { if (peerId == PacketPeerIdDisabled) {
self.headerLength = 1; self.headerLength = PacketOpcodeLength;
self.crypto.extraLength = PacketIdLength; self.crypto.extraLength = PacketIdLength;
self.crypto.extraPacketIdOffset = 0; self.crypto.extraPacketIdOffset = 0;
self.setDataHeader = ^(uint8_t *to, uint8_t key) { self.setDataHeader = ^(uint8_t *to, uint8_t key) {
@ -295,7 +251,7 @@ const NSInteger CryptoAEADTagLength = 16;
self.checkPeerId = NULL; self.checkPeerId = NULL;
} }
else { else {
self.headerLength = 4; self.headerLength = PacketOpcodeLength + PacketPeerIdLength;
self.crypto.extraLength = self.headerLength + PacketIdLength; self.crypto.extraLength = self.headerLength + PacketIdLength;
self.crypto.extraPacketIdOffset = self.headerLength; self.crypto.extraPacketIdOffset = self.headerLength;
self.setDataHeader = ^(uint8_t *to, uint8_t key) { self.setDataHeader = ^(uint8_t *to, uint8_t key) {
@ -307,6 +263,11 @@ const NSInteger CryptoAEADTagLength = 16;
} }
} }
- (NSInteger)encryptionCapacityWithLength:(NSInteger)length
{
return [self.crypto encryptionCapacityWithLength:length];
}
#pragma mark DataPathEncrypter #pragma mark DataPathEncrypter
- (void)assembleDataPacketWithBlock:(DataPathAssembleBlock)block packetId:(uint32_t)packetId payload:(NSData *)payload into:(uint8_t *)packetBytes length:(NSInteger *)packetLength - (void)assembleDataPacketWithBlock:(DataPathAssembleBlock)block packetId:(uint32_t)packetId payload:(NSData *)payload into:(uint8_t *)packetBytes length:(NSInteger *)packetLength
@ -324,7 +285,7 @@ const NSInteger CryptoAEADTagLength = 16;
- (NSData *)encryptedDataPacketWithKey:(uint8_t)key packetId:(uint32_t)packetId packetBytes:(const uint8_t *)packetBytes packetLength:(NSInteger)packetLength error:(NSError *__autoreleasing *)error - (NSData *)encryptedDataPacketWithKey:(uint8_t)key packetId:(uint32_t)packetId packetBytes:(const uint8_t *)packetBytes packetLength:(NSInteger)packetLength error:(NSError *__autoreleasing *)error
{ {
const int capacity = self.headerLength + PacketIdLength + (int)safe_crypto_capacity(packetLength, self.crypto.overheadLength); const int capacity = self.headerLength + PacketIdLength + (int)[self.crypto encryptionCapacityWithLength:packetLength];
NSMutableData *encryptedPacket = [[NSMutableData alloc] initWithLength:capacity]; NSMutableData *encryptedPacket = [[NSMutableData alloc] initWithLength:capacity];
uint8_t *ptr = encryptedPacket.mutableBytes; uint8_t *ptr = encryptedPacket.mutableBytes;
NSInteger encryptedPacketLength = INT_MAX; NSInteger encryptedPacketLength = INT_MAX;

View File

@ -36,8 +36,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "Encryption.h" #import "Crypto.h"
#import "DataPathEncryption.h" #import "DataPathCrypto.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -54,7 +54,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
@property (nonatomic, assign) int cipherIVLength; @property (nonatomic, assign) int cipherIVLength;
@property (nonatomic, assign) int hmacKeyLength; @property (nonatomic, assign) int hmacKeyLength;
@property (nonatomic, assign) int digestLength; @property (nonatomic, assign) int digestLength;
@property (nonatomic, assign) int overheadLength;
@property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxEnc;
@property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxDec; @property (nonatomic, unsafe_unretained) EVP_CIPHER_CTX *cipherCtxDec;
@ -87,7 +86,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
// as seen in OpenVPN's crypto_openssl.c:md_kt_size() // as seen in OpenVPN's crypto_openssl.c:md_kt_size()
self.hmacKeyLength = EVP_MD_size(self.digest); self.hmacKeyLength = EVP_MD_size(self.digest);
self.digestLength = EVP_MD_size(self.digest); self.digestLength = EVP_MD_size(self.digest);
self.overheadLength = self.cipherIVLength + self.digestLength;
if (cipherName) { if (cipherName) {
self.cipherCtxEnc = EVP_CIPHER_CTX_new(); self.cipherCtxEnc = EVP_CIPHER_CTX_new();
@ -120,6 +118,11 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
return 0; return 0;
} }
- (NSInteger)encryptionCapacityWithLength:(NSInteger)length
{
return safe_crypto_capacity(length, self.digestLength + self.cipherIVLength);
}
#pragma mark Encrypter #pragma mark Encrypter
- (void)configureEncryptionWithCipherKey:(ZeroingData *)cipherKey hmacKey:(ZeroingData *)hmacKey - (void)configureEncryptionWithCipherKey:(ZeroingData *)cipherKey hmacKey:(ZeroingData *)hmacKey
@ -138,23 +141,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
HMAC_Init_ex(self.hmacCtxEnc, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); 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 - (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; uint8_t *outIV = dest + self.digestLength;
@ -214,24 +200,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
HMAC_Init_ex(self.hmacCtxDec, hmacKey.bytes, self.hmacKeyLength, self.digest, NULL); 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 - (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"); NSAssert(self.cipher, @"No cipher provided");
@ -261,11 +229,6 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
TUNNEL_CRYPTO_RETURN_STATUS(code) 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 - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length extra:(const uint8_t *)extra error:(NSError *__autoreleasing *)error
{ {
int l1 = 0; int l1 = 0;
@ -316,24 +279,19 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
#pragma mark DataPathChannel #pragma mark DataPathChannel
- (int)overheadLength
{
return self.crypto.overheadLength;
}
- (void)setPeerId:(uint32_t)peerId - (void)setPeerId:(uint32_t)peerId
{ {
peerId &= 0xffffff; peerId &= 0xffffff;
if (peerId == PacketPeerIdDisabled) { if (peerId == PacketPeerIdDisabled) {
self.headerLength = 1; self.headerLength = PacketOpcodeLength;
self.setDataHeader = ^(uint8_t *to, uint8_t key) { self.setDataHeader = ^(uint8_t *to, uint8_t key) {
PacketHeaderSet(to, PacketCodeDataV1, key, nil); PacketHeaderSet(to, PacketCodeDataV1, key, nil);
}; };
self.checkPeerId = NULL; self.checkPeerId = NULL;
} }
else { else {
self.headerLength = 4; self.headerLength = PacketOpcodeLength + PacketPeerIdLength;
self.setDataHeader = ^(uint8_t *to, uint8_t key) { self.setDataHeader = ^(uint8_t *to, uint8_t key) {
PacketHeaderSetDataV2(to, key, peerId); PacketHeaderSetDataV2(to, key, peerId);
}; };
@ -343,6 +301,11 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
} }
} }
- (NSInteger)encryptionCapacityWithLength:(NSInteger)length
{
return [self.crypto encryptionCapacityWithLength:length];
}
#pragma mark DataPathEncrypter #pragma mark DataPathEncrypter
- (void)assembleDataPacketWithBlock:(DataPathAssembleBlock)block packetId:(uint32_t)packetId payload:(NSData *)payload into:(uint8_t *)packetBytes length:(NSInteger *)packetLength - (void)assembleDataPacketWithBlock:(DataPathAssembleBlock)block packetId:(uint32_t)packetId payload:(NSData *)payload into:(uint8_t *)packetBytes length:(NSInteger *)packetLength
@ -363,7 +326,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
- (NSData *)encryptedDataPacketWithKey:(uint8_t)key packetId:(uint32_t)packetId packetBytes:(const uint8_t *)packetBytes packetLength:(NSInteger)packetLength error:(NSError *__autoreleasing *)error - (NSData *)encryptedDataPacketWithKey:(uint8_t)key packetId:(uint32_t)packetId packetBytes:(const uint8_t *)packetBytes packetLength:(NSInteger)packetLength error:(NSError *__autoreleasing *)error
{ {
const int capacity = self.headerLength + (int)safe_crypto_capacity(packetLength, self.crypto.overheadLength); const int capacity = self.headerLength + (int)[self.crypto encryptionCapacityWithLength:packetLength];
NSMutableData *encryptedPacket = [[NSMutableData alloc] initWithLength:capacity]; NSMutableData *encryptedPacket = [[NSMutableData alloc] initWithLength:capacity];
uint8_t *ptr = encryptedPacket.mutableBytes; uint8_t *ptr = encryptedPacket.mutableBytes;
NSInteger encryptedPacketLength = INT_MAX; NSInteger encryptedPacketLength = INT_MAX;

View File

@ -37,7 +37,7 @@
#import <arpa/inet.h> #import <arpa/inet.h>
#import "DataPath.h" #import "DataPath.h"
#import "DataPathEncryption.h" #import "DataPathCrypto.h"
#import "MSS.h" #import "MSS.h"
#import "ReplayProtector.h" #import "ReplayProtector.h"
#import "Allocation.h" #import "Allocation.h"
@ -120,7 +120,7 @@
- (void)adjustEncBufferToPacketSize:(int)size - (void)adjustEncBufferToPacketSize:(int)size
{ {
const int neededCapacity = DataPathByteAlignment + (int)safe_crypto_capacity(size, self.encrypter.overheadLength); const int neededCapacity = DataPathByteAlignment + (int)[self.encrypter encryptionCapacityWithLength:size];
if (self.encBufferCapacity >= neededCapacity) { if (self.encBufferCapacity >= neededCapacity) {
return; return;
} }
@ -132,7 +132,7 @@
- (void)adjustDecBufferToPacketSize:(int)size - (void)adjustDecBufferToPacketSize:(int)size
{ {
const int neededCapacity = DataPathByteAlignment + (int)safe_crypto_capacity(size, self.decrypter.overheadLength); const int neededCapacity = DataPathByteAlignment + (int)[self.decrypter encryptionCapacityWithLength:size];
if (self.decBufferCapacity >= neededCapacity) { if (self.decBufferCapacity >= neededCapacity) {
return; return;
} }

View File

@ -1,5 +1,5 @@
// //
// DataPathEncryption.h // DataPathCrypto.h
// TunnelKit // TunnelKit
// //
// Created by Davide De Rosa on 7/11/18. // Created by Davide De Rosa on 7/11/18.
@ -43,8 +43,8 @@ typedef void (^DataPathParseBlock)(uint8_t *payload, NSInteger *payloadOffset, N
@protocol DataPathChannel @protocol DataPathChannel
- (int)overheadLength;
- (void)setPeerId:(uint32_t)peerId; - (void)setPeerId:(uint32_t)peerId;
- (NSInteger)encryptionCapacityWithLength:(NSInteger)length;
@end @end

View File

@ -39,7 +39,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
#define PacketHeaderLength ((NSInteger)1) #define PacketOpcodeLength ((NSInteger)1)
#define PacketIdLength ((NSInteger)4) #define PacketIdLength ((NSInteger)4)
#define PacketSessionIdLength ((NSInteger)8) #define PacketSessionIdLength ((NSInteger)8)
#define PacketAckLengthLength ((NSInteger)1) #define PacketAckLengthLength ((NSInteger)1)
@ -66,7 +66,7 @@ extern const uint8_t DataPacketPingData[16];
static inline int PacketHeaderSet(uint8_t *to, PacketCode code, uint8_t key, const uint8_t *_Nullable sessionId) static inline int PacketHeaderSet(uint8_t *to, PacketCode code, uint8_t key, const uint8_t *_Nullable sessionId)
{ {
*(uint8_t *)to = (code << 3) | (key & 0b111); *(uint8_t *)to = (code << 3) | (key & 0b111);
int offset = PacketHeaderLength; int offset = PacketOpcodeLength;
if (sessionId) { if (sessionId) {
memcpy(to + offset, sessionId, PacketSessionIdLength); memcpy(to + offset, sessionId, PacketSessionIdLength);
offset += PacketSessionIdLength; offset += PacketSessionIdLength;
@ -77,7 +77,7 @@ static inline int PacketHeaderSet(uint8_t *to, PacketCode code, uint8_t key, con
static inline int PacketHeaderSetDataV2(uint8_t *to, uint8_t key, uint32_t peerId) static inline int PacketHeaderSetDataV2(uint8_t *to, uint8_t key, uint32_t peerId)
{ {
*(uint32_t *)to = ((PacketCodeDataV2 << 3) | (key & 0b111)) | htonl(peerId & 0xffffff); *(uint32_t *)to = ((PacketCodeDataV2 << 3) | (key & 0b111)) | htonl(peerId & 0xffffff);
return PacketHeaderLength + PacketPeerIdLength; return PacketOpcodeLength + PacketPeerIdLength;
} }
static inline int PacketHeaderGetDataV2PeerId(const uint8_t *from) static inline int PacketHeaderGetDataV2PeerId(const uint8_t *from)

View File

@ -66,6 +66,7 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSString *)nullTerminatedStringFromOffset:(NSInteger)from; - (nullable NSString *)nullTerminatedStringFromOffset:(NSInteger)from;
- (BOOL)isEqualToData:(NSData *)data; - (BOOL)isEqualToData:(NSData *)data;
- (NSData *)toData; // XXX: unsafe
- (NSString *)toHex; - (NSString *)toHex;
@end @end

View File

@ -276,6 +276,11 @@
return !memcmp(_bytes, data.bytes, _count); return !memcmp(_bytes, data.bytes, _count);
} }
- (NSData *)toData
{
return [NSData dataWithBytes:_bytes length:_count];
}
- (NSString *)toHex - (NSString *)toHex
{ {
const NSUInteger capacity = _count * 2; const NSUInteger capacity = _count * 2;

View File

@ -38,14 +38,14 @@ module __TunnelKitNative {
header "Errors.h" header "Errors.h"
header "ZeroingData.h" header "ZeroingData.h"
header "TLSBox.h" header "TLSBox.h"
header "Crypto.h"
header "CryptoBox.h" header "CryptoBox.h"
header "Encryption.h"
header "MSS.h" header "MSS.h"
header "PacketMacros.h" header "PacketMacros.h"
header "ControlPacket.h" header "ControlPacket.h"
header "ReplayProtector.h" header "ReplayProtector.h"
header "CompressionFramingNative.h" header "CompressionFramingNative.h"
header "DataPath.h" header "DataPath.h"
header "DataPathEncryption.h" header "DataPathCrypto.h"
export * export *
} }

View File

@ -69,8 +69,8 @@ class DataManipulationTests: XCTestCase {
let z2 = z1.withOffset(2, count: 3) // 5678ab let z2 = z1.withOffset(2, count: 3) // 5678ab
let z3 = z2.appending(Z(Data(hex: "aaddcc"))) // 5678abaaddcc let z3 = z2.appending(Z(Data(hex: "aaddcc"))) // 5678abaaddcc
XCTAssertEqual(z1.data, Data(hex: "12345678abcdef")) XCTAssertEqual(z1.toData(), Data(hex: "12345678abcdef"))
XCTAssertEqual(z2.data, Data(hex: "5678ab")) XCTAssertEqual(z2.toData(), Data(hex: "5678ab"))
XCTAssertEqual(z3.data, Data(hex: "5678abaaddcc")) XCTAssertEqual(z3.toData(), Data(hex: "5678abaaddcc"))
} }
} }

View File

@ -72,7 +72,7 @@ class EncryptionPerformanceTests: XCTestCase {
let suite = TestUtils.generateDataSuite(1000, 100000) let suite = TestUtils.generateDataSuite(1000, 100000)
measure { measure {
for data in suite { 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] let extra: [UInt8] = [0x11, 0x22, 0x33, 0x44]
measure { measure {
for data in suite { for data in suite {
let _ = try! self.gcmEncrypter.encryptData(data, offset: 0, extra: extra) let _ = try! self.gcmEncrypter.encryptData(data, extra: extra)
} }
} }
} }

View File

@ -40,13 +40,19 @@ import XCTest
@testable import __TunnelKitNative @testable import __TunnelKitNative
class EncryptionTests: XCTestCase { class EncryptionTests: XCTestCase {
private var cipherKey: ZeroingData! private var cipherEncKey: ZeroingData!
private var hmacKey: ZeroingData! private var cipherDecKey: ZeroingData!
private var hmacEncKey: ZeroingData!
private var hmacDecKey: ZeroingData!
override func setUp() { override func setUp() {
cipherKey = try! SecureRandom.safeData(length: 32) cipherEncKey = try! SecureRandom.safeData(length: 32)
hmacKey = try! SecureRandom.safeData(length: 32) cipherDecKey = try! SecureRandom.safeData(length: 32)
hmacEncKey = try! SecureRandom.safeData(length: 32)
hmacDecKey = try! SecureRandom.safeData(length: 32)
} }
override func tearDown() { override func tearDown() {
@ -54,67 +60,38 @@ class EncryptionTests: XCTestCase {
} }
func testCBC() { func testCBC() {
let cbc = CryptoBox(cipherAlgorithm: "aes-128-cbc", digestAlgorithm: "sha256") let (client, server) = clientServer("aes-128-cbc", "sha256")
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 plain = Data(hex: "00112233445566778899")
let encrypted = try! enc.encryptData(plain, offset: 0, extra: nil) let encrypted = try! client.encrypter().encryptData(plain, extra: nil)
let decrypted = try! dec.decryptData(encrypted, offset: 0, extra: nil) let decrypted = try! server.decrypter().decryptData(encrypted, extra: nil)
XCTAssertEqual(plain, decrypted) XCTAssertEqual(plain, decrypted)
} }
func testHMAC() { func testHMAC() {
let cbc = CryptoBox(cipherAlgorithm: nil, digestAlgorithm: "sha256") let (client, server) = clientServer(nil, "sha256")
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 plain = Data(hex: "00112233445566778899")
let encrypted = try! enc.encryptData(plain, offset: 0, extra: nil) let encrypted = try! client.encrypter().encryptData(plain, extra: nil)
do { XCTAssertNoThrow(try server.decrypter().verifyData(encrypted, extra: nil))
try dec.verifyData(encrypted, offset: 0, extra: nil)
XCTAssert(true)
} catch {
XCTAssert(false)
}
} }
func testGCM() { func testGCM() {
let gcm = CryptoBox(cipherAlgorithm: "aes-256-gcm", digestAlgorithm: nil) let (client, server) = clientServer("aes-256-gcm", nil)
try! gcm.configure(withCipherEncKey: cipherKey, cipherDecKey: cipherKey, hmacEncKey: hmacKey, hmacDecKey: hmacKey)
let enc = gcm.encrypter()
let dec = gcm.decrypter()
// let packetId: UInt32 = 0x56341200 // let packetId: UInt32 = 0x56341200
let extra: [UInt8] = [0x00, 0x12, 0x34, 0x56] let extra: [UInt8] = [0x00, 0x12, 0x34, 0x56]
let plain = Data(hex: "00112233445566778899") let plain = Data(hex: "00112233445566778899")
let encrypted = try! enc.encryptData(plain, offset: 0, extra: extra) let encrypted = try! client.encrypter().encryptData(plain, extra: extra)
let decrypted = try! dec.decryptData(encrypted, offset: 0, extra: extra) let decrypted = try! server.decrypter().decryptData(encrypted, extra: extra)
XCTAssertEqual(plain, decrypted) XCTAssertEqual(plain, decrypted)
} }
// func testCryptoOperation() { private func clientServer(_ c: String?, _ d: String?) -> (CryptoBox, CryptoBox) {
// let data = Data(hex: "aabbccddeeff") let client = CryptoBox(cipherAlgorithm: c, digestAlgorithm: d)
// let server = CryptoBox(cipherAlgorithm: c, digestAlgorithm: d)
// print("Original : \(data.toHex())") XCTAssertNoThrow(try client.configure(withCipherEncKey: cipherEncKey, cipherDecKey: cipherDecKey, hmacEncKey: hmacEncKey, hmacDecKey: hmacDecKey))
// var enc: Data XCTAssertNoThrow(try server.configure(withCipherEncKey: cipherDecKey, cipherDecKey: cipherEncKey, hmacEncKey: hmacDecKey, hmacDecKey: hmacEncKey))
// var dec: Data return (client, server)
// }
// enc = Data()
// enc.append(try! encrypter.encryptData(data, offset: 0, packetId: 0))
// print("Encrypted: \(enc.toHex())")
// dec = try! decrypter.decryptData(enc, offset: 0, packetId: 0)
// print("Decrypted: \(dec.toHex())")
// XCTAssert(dec == data)
//
// let prefix = "abcdef"
// enc = Data(hex: prefix)
// enc.append(try! encrypter.encryptData(data, offset: 0, packetId: 0))
// print("Encrypted: \(enc.toHex())")
// dec = try! decrypter.decryptData(enc, offset: (prefix.count / 2), packetId: 0)
// print("Decrypted: \(dec.toHex())")
// XCTAssert(dec == data)
// }
} }

View File

@ -56,8 +56,35 @@ class TestUtils {
} }
} }
extension ZeroingData { extension Encrypter {
var data: Data { func encryptData(_ data: Data, extra: [UInt8]?) throws -> Data {
return Data(bytes: bytes, count: count) 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..<dest.count)
return Data(dest)
}
}
extension Decrypter {
func decryptData(_ 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 decryptBytes($0, length: srcLength, dest: &dest, destLength: &destLength, extra: extra)
}
dest.removeSubrange(destLength..<dest.count)
return Data(dest)
}
func verifyData(_ data: Data, extra: [UInt8]?) throws {
let srcLength = data.count
try data.withUnsafeBytes {
try verifyBytes($0, length: srcLength, extra: extra)
}
} }
} }