Skip to content
This repository has been archived by the owner on Sep 29, 2024. It is now read-only.

HMAC breaking due to dangling OSSL_PARAM #405

Merged
merged 4 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- OpenVPN: HMAC breaking due to dangling OSSL_PARAM. [#405](https://github.com/passepartoutvpn/tunnelkit/pull/405)
- OpenVPN: Bad error mapping. [#404](https://github.com/passepartoutvpn/tunnelkit/pull/404)

## 6.3.1 (2024-01-05)
Expand Down
24 changes: 17 additions & 7 deletions Sources/CTunnelKitOpenVPNProtocol/CryptoCBC.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ @interface CryptoCBC ()

@property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher;
@property (nonatomic, unsafe_unretained) const EVP_MD *digest;
@property (nonatomic, unsafe_unretained) const char *utfCipherName;
@property (nonatomic, unsafe_unretained) const char *utfDigestName;
@property (nonatomic, assign) int cipherKeyLength;
@property (nonatomic, assign) int cipherIVLength;
@property (nonatomic, assign) int hmacKeyLength;
Expand All @@ -75,10 +77,14 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString *
self = [super init];
if (self) {
if (cipherName) {
self.cipher = EVP_get_cipherbyname([cipherName cStringUsingEncoding:NSASCIIStringEncoding]);
self.utfCipherName = calloc([cipherName length] + 1, sizeof(char));
strncpy(self.utfCipherName, [cipherName UTF8String], [cipherName length]);
self.cipher = EVP_get_cipherbyname(self.utfCipherName);
NSAssert(self.cipher, @"Unknown cipher '%@'", cipherName);
}
self.digest = EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]);
self.utfDigestName = calloc([digestName length] + 1, sizeof(char));
strncpy(self.utfDigestName, [digestName UTF8String], [digestName length]);
self.digest = EVP_get_digestbyname(self.utfDigestName);
NSAssert(self.digest, @"Unknown digest '%@'", digestName);

if (cipherName) {
Expand All @@ -96,7 +102,7 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString *

self.mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
OSSL_PARAM *macParams = calloc(2, sizeof(OSSL_PARAM));
macParams[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)[digestName cStringUsingEncoding:NSASCIIStringEncoding], 0);
macParams[0] = OSSL_PARAM_construct_utf8_string("digest", self.utfDigestName, 0);
macParams[1] = OSSL_PARAM_construct_end();
self.macParams = macParams;

Expand All @@ -115,7 +121,12 @@ - (void)dealloc
free(self.macParams);
bzero(self.bufferDecHMAC, CryptoCBCMaxHMACLength);
free(self.bufferDecHMAC);


if (self.utfCipherName) {
free(self.utfCipherName);
}
free(self.utfDigestName);

self.cipher = NULL;
self.digest = NULL;
}
Expand Down Expand Up @@ -175,7 +186,6 @@ - (BOOL)encryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8
memcpy(outEncrypted, bytes, length);
l1 = (int)length;
}

EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyEnc.bytes, self.hmacKeyEnc.count, self.macParams);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, outIV, l1 + l2 + self.cipherIVLength);
Expand Down Expand Up @@ -215,7 +225,7 @@ - (BOOL)decryptBytes:(const uint8_t *)bytes length:(NSInteger)length dest:(uint8
const uint8_t *encrypted = bytes + self.digestLength + self.cipherIVLength;
size_t l1 = 0, l2 = 0;
int code = 1;

EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyDec.bytes, self.hmacKeyDec.count, self.macParams);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, bytes + self.digestLength, length - self.digestLength);
Expand Down Expand Up @@ -249,7 +259,7 @@ - (BOOL)verifyBytes:(const uint8_t *)bytes length:(NSInteger)length flags:(const
{
size_t l1 = 0;
int code = 1;

EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(self.mac);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_init(ctx, self.hmacKeyDec.bytes, self.hmacKeyDec.count, self.macParams);
TUNNEL_CRYPTO_TRACK_STATUS(code) EVP_MAC_update(ctx, bytes + self.digestLength, length - self.digestLength);
Expand Down
18 changes: 14 additions & 4 deletions Sources/CTunnelKitOpenVPNProtocol/CryptoCTR.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ @interface CryptoCTR ()

@property (nonatomic, unsafe_unretained) const EVP_CIPHER *cipher;
@property (nonatomic, unsafe_unretained) const EVP_MD *digest;
@property (nonatomic, unsafe_unretained) const char *utfCipherName;
@property (nonatomic, unsafe_unretained) const char *utfDigestName;
@property (nonatomic, assign) int cipherKeyLength;
@property (nonatomic, assign) int cipherIVLength;
@property (nonatomic, assign) int hmacKeyLength;
Expand All @@ -61,9 +63,14 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString *

self = [super init];
if (self) {
self.cipher = EVP_get_cipherbyname([cipherName cStringUsingEncoding:NSASCIIStringEncoding]);
self.utfCipherName = calloc([cipherName length] + 1, sizeof(char));
strncpy(self.utfCipherName, [cipherName UTF8String], [cipherName length]);
self.cipher = EVP_get_cipherbyname(self.utfCipherName);
NSAssert(self.cipher, @"Unknown cipher '%@'", cipherName);
self.digest = EVP_get_digestbyname([digestName cStringUsingEncoding:NSASCIIStringEncoding]);

self.utfDigestName = calloc([digestName length] + 1, sizeof(char));
strncpy(self.utfDigestName, [digestName UTF8String], [digestName length]);
self.digest = EVP_get_digestbyname(self.utfDigestName);
NSAssert(self.digest, @"Unknown digest '%@'", digestName);

self.cipherKeyLength = EVP_CIPHER_key_length(self.cipher);
Expand All @@ -77,7 +84,7 @@ - (instancetype)initWithCipherName:(NSString *)cipherName digestName:(NSString *

self.mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
OSSL_PARAM *macParams = calloc(2, sizeof(OSSL_PARAM));
macParams[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)[digestName cStringUsingEncoding:NSASCIIStringEncoding], 0);
macParams[0] = OSSL_PARAM_construct_utf8_string("digest", self.utfDigestName, 0);
macParams[1] = OSSL_PARAM_construct_end();
self.macParams = macParams;

Expand All @@ -94,7 +101,10 @@ - (void)dealloc
free(self.macParams);
bzero(self.bufferDecHMAC, CryptoCTRTagLength);
free(self.bufferDecHMAC);


free(self.utfCipherName);
free(self.utfDigestName);

self.cipher = NULL;
self.digest = NULL;
}
Expand Down