Compare commits

..

No commits in common. "master" and "mkirk/framework-friendly" have entirely different histories.

8 changed files with 62 additions and 200 deletions

View File

@ -1,15 +0,0 @@
---
BasedOnStyle: WebKit
AllowShortFunctionsOnASingleLine: false
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 120
IndentCaseLabels: true
MaxEmptyLinesToKeep: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
TabWidth: 8
UseTab: Never
...

36
.gitignore vendored
View File

@ -1,30 +1,8 @@
# Exclude the build directory
build/*
# Exclude temp nibs and swap files
*~.nib
*.swp
# Exclude OS X folder attributes
.DS_Store
# Exclude user-specific XCode 3 and 4 files
xcuserdata
*.xccheckout
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
Index/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control?
#
# Pods/

View File

@ -14,16 +14,9 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/FredericJacobs/HKDFKit.git", :tag => "0.0.3" }
s.source_files = 'HKDFKit/HKDFKit/*.{h,m,mm,swift}', 'HKDFKit/Private/*.{h,m,mm,swift}'
s.source_files = 'HKDFKit/HKDFKit/*{h,m}'
s.public_header_files = 'HKDFKit/HKDFKit/*.h'
s.ios.deployment_target = "10.0"
s.requires_arc = true
s.dependency 'CocoaLumberjack'
s.dependency 'SignalCoreKit'
s.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'HKDFKit/HKDFKitTests/**/*.{h,m,swift}'
end
end

View File

@ -1,11 +1,13 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// HKDFKit.h
// HKDFKit
//
// Created by Frederic Jacobs on 29/03/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface HKDFKit : NSObject
/**
@ -18,15 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return The derived key material
*/
+ (NSData *)throws_deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize NS_SWIFT_UNAVAILABLE("throws objc exceptions");
+ (nullable NSData *)deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize
error:(NSError **)outError;
+ (NSData*)deriveKey:(NSData*)seed info:(NSData*)info salt:(NSData*)salt outputSize:(int)outputSize;
/**
* TextSecure v2 HKDF implementation
@ -38,11 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return The derived key material
*/
+ (NSData *)throws_TextSecureV2deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize NS_SWIFT_UNAVAILABLE("throws objc exceptions");
+ (NSData*)TextSecureV2deriveKey:(NSData*)seed info:(NSData*)info salt:(NSData*)salt outputSize:(int)outputSize;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,111 +1,47 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// HKDFKit.m
// HKDFKit
//
// Created by Frederic Jacobs on 29/03/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import "HKDFKit.h"
#import <CommonCrypto/CommonCrypto.h>
#import <SignalCoreKit/OWSAsserts.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
NS_ASSUME_NONNULL_BEGIN
#define HKDF_HASH_ALG kCCHmacAlgSHA256
#define HKDF_HASH_LEN CC_SHA256_DIGEST_LENGTH
@implementation HKDFKit
+ (nullable NSData *)deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize
error:(NSError **)outError
{
@try {
return [self throws_deriveKey:seed info:info salt:salt outputSize:outputSize];
} @catch (NSException *exception) {
*outError = SCKExceptionWrapperErrorMake(exception);
return nil;
}
+ (NSData *)deriveKey:(NSData *)seed info:(NSData *)info salt:(NSData *)salt outputSize:(int)outputSize{
return [self deriveKey:seed info:info salt:salt outputSize:outputSize offset:1];
}
+ (NSData *)throws_deriveKey:(NSData *)seed info:(nullable NSData *)info salt:(NSData *)salt outputSize:(int)outputSize
{
return [self throws_deriveKey:seed info:info salt:salt outputSize:outputSize offset:1];
}
+ (NSData *)throws_TextSecureV2deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize
{
return [self throws_deriveKey:seed info:info salt:salt outputSize:outputSize offset:0];
+ (NSData*)TextSecureV2deriveKey:(NSData*)seed info:(NSData*)info salt:(NSData*)salt outputSize:(int)outputSize{
return [self deriveKey:seed info:info salt:salt outputSize:outputSize offset:0];
}
#pragma mark Private Methods
+ (NSData *)throws_deriveKey:(NSData *)seed
info:(nullable NSData *)info
salt:(NSData *)salt
outputSize:(int)outputSize
offset:(int)offset
{
NSData *prk = [self throws_extract:seed salt:salt];
NSData *okm = [self throws_expand:prk info:info outputSize:outputSize offset:offset];
+ (NSData *)deriveKey:(NSData *)seed info:(NSData *)info salt:(NSData *)salt outputSize:(int)outputSize offset:(int)offset{
NSData *prk = [self extract:seed salt:salt];
NSData *okm = [self expand:prk info:info outputSize:outputSize offset:offset];
return okm;
}
+ (NSData *)throws_extract:(NSData *)data salt:(NSData *)salt
{
if (!salt) {
OWSRaiseException(NSInvalidArgumentException, @"Missing salt.");
}
if (salt.length >= SIZE_MAX) {
OWSRaiseException(NSInvalidArgumentException, @"Oversize salt.");
}
if (!data) {
OWSRaiseException(NSInvalidArgumentException, @"Missing data.");
}
if (data.length >= SIZE_MAX) {
OWSRaiseException(NSInvalidArgumentException, @"Oversize data.");
}
NSMutableData *_Nullable prkData = [[NSMutableData alloc] initWithLength:HKDF_HASH_LEN];
if (!prkData) {
OWSFail(@"Could not allocate buffer.");
}
CCHmac(HKDF_HASH_ALG, [salt bytes], [salt length], [data bytes], [data length], prkData.mutableBytes);
return [prkData copy];
+ (NSData*)extract:(NSData*)data salt:(NSData*)salt{
char prk[HKDF_HASH_LEN] = {0};
CCHmac(HKDF_HASH_ALG, [salt bytes], [salt length], [data bytes], [data length], prk);
return [NSData dataWithBytes:prk length:sizeof(prk)];
}
+ (NSData *)throws_expand:(NSData *)data info:(nullable NSData *)info outputSize:(int)outputSize offset:(int)offset
{
if (!data) {
OWSRaiseException(NSInvalidArgumentException, @"Missing data.");
}
if (data.length >= SIZE_MAX) {
OWSRaiseException(NSInvalidArgumentException, @"Oversize data.");
}
if (info != nil && info.length >= SIZE_MAX) {
OWSRaiseException(NSInvalidArgumentException, @"Oversize info.");
}
if (outputSize >= NSUIntegerMax) {
OWSRaiseException(NSInvalidArgumentException, @"Oversize outputSize.");
}
if (outputSize < 1) {
OWSRaiseException(NSInvalidArgumentException, @"Invalid outputSize.");
}
+ (NSData*)expand:(NSData*)data info:(NSData*)info outputSize:(int)outputSize offset:(int)offset{
int iterations = (int)ceil((double)outputSize/(double)HKDF_HASH_LEN);
NSData *mixin = [NSData data];
NSMutableData *results = [NSMutableData data];
int iterations = (int)ceil((double)outputSize / (double)HKDF_HASH_LEN);
NSData *mixin = [NSData data];
NSMutableData *results = [NSMutableData data];
NSUInteger generatedLength;
ows_mul_overflow(HKDF_HASH_LEN, iterations, &generatedLength);
int offsetIterations;
ows_add_overflow(iterations, offset, &offsetIterations);
for (int i = offset; i < offsetIterations; i++) {
for (int i=offset; i<(iterations+offset); i++) {
CCHmacContext ctx;
CCHmacInit(&ctx, HKDF_HASH_ALG, [data bytes], [data length]);
CCHmacUpdate(&ctx, [mixin bytes], [mixin length]);
@ -114,19 +50,14 @@ NS_ASSUME_NONNULL_BEGIN
}
unsigned char c = i;
CCHmacUpdate(&ctx, &c, 1);
NSMutableData *_Nullable stepResultData = [[NSMutableData alloc] initWithLength:HKDF_HASH_LEN];
if (!stepResultData) {
OWSFail(@"Could not allocate buffer.");
}
CCHmacFinal(&ctx, stepResultData.mutableBytes);
[results appendData:stepResultData];
mixin = [stepResultData copy];
unsigned char T[HKDF_HASH_LEN];
CCHmacFinal(&ctx, T);
NSData *stepResult = [NSData dataWithBytes:T length:sizeof(T)];
[results appendData:stepResult];
mixin = [stepResult copy];
}
OWSAssert(results.length == generatedLength);
return [results subdataWithRange:NSMakeRange(0, outputSize)];
return [[NSData dataWithData:results] subdataWithRange:NSMakeRange(0, outputSize)];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,16 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import XCTest
// Cocoapods-generated test targets (like this one)
// fail to link if:
//
// * They only contain Obj-C tests.
// * They depend on pods that use Swift.
//
// The work around is to add (this) empty swift file
// to our test target.
//
// See: https://github.com/CocoaPods/CocoaPods/issues/7170

View File

@ -1,9 +1,14 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// HKDFKitTests.m
// HKDFKitTests
//
// Created by Frederic Jacobs on 29/03/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import "HKDFKit.h"
#import <XCTest/XCTest.h>
#import "HKDFKit.h"
@interface HKDFKitTests : XCTestCase
@ -24,12 +29,9 @@
int l = 42;
NSString *OKM = @"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865";
NSData *hkdf = [HKDFKit throws_deriveKey:[self stringToData:IKM]
info:[self stringToData:info]
salt:[self stringToData:salt]
outputSize:l];
NSData *hkdf = [HKDFKit deriveKey:[self stringToData:IKM] info:[self stringToData:info] salt:[self stringToData:salt] outputSize:l];
XCTAssert([hkdf isEqualToData:[self stringToData:OKM]], @"Basic test case with SHA-256");
}
@ -42,12 +44,9 @@
int l = 82;
NSString *OKM = @"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87";
NSData *hkdf = [HKDFKit throws_deriveKey:[self stringToData:IKM]
info:[self stringToData:info]
salt:[self stringToData:salt]
outputSize:l];
NSData *hkdf = [HKDFKit deriveKey:[self stringToData:IKM] info:[self stringToData:info] salt:[self stringToData:salt] outputSize:l];
XCTAssert(([hkdf isEqualToData:[self stringToData:OKM]]), @"Test with SHA-256 and longer inputs/outputs");
}
@ -60,9 +59,9 @@
int l = 42;
NSString *OKM = @"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8";
NSData *hkdf = [HKDFKit throws_deriveKey:[self stringToData:IKM] info:info salt:salt outputSize:l];
NSData *hkdf = [HKDFKit deriveKey:[self stringToData:IKM] info:info salt:salt outputSize:l];
XCTAssert(([hkdf isEqualToData:[self stringToData:OKM]]), @"Test with SHA-256 and zero-length salt/info");
}