Compare commits
No commits in common. "master" and "mkirk/framework-friendly" have entirely different histories.
master
...
mkirk/fram
@ -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
36
.gitignore
vendored
@ -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/
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
BIN
HKDFKit/HKDFKit.xcodeproj/project.xcworkspace/xcuserdata/fred.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
HKDFKit/HKDFKit.xcodeproj/project.xcworkspace/xcuserdata/fred.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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");
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user