Merge branch 'refactor-encryption'
This commit is contained in:
commit
1ba7e73e9c
|
@ -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 */,
|
||||||
|
|
|
@ -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)")
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 *
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue