mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Objective-C
		
	
//
 | 
						|
//  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#import "ChainKey.h"
 | 
						|
#import "TSDerivedSecrets.h"
 | 
						|
#import <CommonCrypto/CommonCrypto.h>
 | 
						|
#import <Curve25519Kit/Curve25519.h>
 | 
						|
#import <SessionProtocolKit/OWSAsserts.h>
 | 
						|
 | 
						|
NS_ASSUME_NONNULL_BEGIN
 | 
						|
 | 
						|
@implementation ChainKey
 | 
						|
 | 
						|
static NSString *const kCoderKey = @"kCoderKey";
 | 
						|
static NSString *const kCoderIndex = @"kCoderIndex";
 | 
						|
 | 
						|
#define kTSKeySeedLength 1
 | 
						|
 | 
						|
static uint8_t kMessageKeySeed[kTSKeySeedLength] = { 01 };
 | 
						|
static uint8_t kChainKeySeed[kTSKeySeedLength] = { 02 };
 | 
						|
 | 
						|
+ (BOOL)supportsSecureCoding
 | 
						|
{
 | 
						|
    return YES;
 | 
						|
}
 | 
						|
 | 
						|
- (nullable id)initWithCoder:(NSCoder *)aDecoder
 | 
						|
{
 | 
						|
    NSData *key = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCoderKey];
 | 
						|
    int index = [aDecoder decodeIntForKey:kCoderIndex];
 | 
						|
 | 
						|
    return [self initWithData:key index:index];
 | 
						|
}
 | 
						|
 | 
						|
- (void)encodeWithCoder:(NSCoder *)aCoder
 | 
						|
{
 | 
						|
    [aCoder encodeObject:_key forKey:kCoderKey];
 | 
						|
    [aCoder encodeInt:_index forKey:kCoderIndex];
 | 
						|
}
 | 
						|
 | 
						|
- (instancetype)initWithData:(NSData *)chainKey index:(int)index
 | 
						|
{
 | 
						|
    OWSAssert(chainKey.length == 32);
 | 
						|
    OWSAssert(index >= 0);
 | 
						|
 | 
						|
    self = [super init];
 | 
						|
 | 
						|
    if (self) {
 | 
						|
        _key = chainKey;
 | 
						|
        _index = index;
 | 
						|
    }
 | 
						|
 | 
						|
    return self;
 | 
						|
}
 | 
						|
 | 
						|
- (instancetype)nextChainKey
 | 
						|
{
 | 
						|
    NSData *nextCK = [self baseMaterial:[NSData dataWithBytes:kChainKeySeed length:kTSKeySeedLength]];
 | 
						|
    OWSAssert(nextCK.length == 32);
 | 
						|
 | 
						|
    int nextIndex;
 | 
						|
    ows_add_overflow(self.index, 1, &nextIndex);
 | 
						|
    return [[ChainKey alloc] initWithData:nextCK index:nextIndex];
 | 
						|
}
 | 
						|
 | 
						|
- (MessageKeys *)throws_messageKeys
 | 
						|
{
 | 
						|
    NSData *inputKeyMaterial = [self baseMaterial:[NSData dataWithBytes:kMessageKeySeed length:kTSKeySeedLength]];
 | 
						|
    TSDerivedSecrets *derivedSecrets = [TSDerivedSecrets throws_derivedMessageKeysWithData:inputKeyMaterial];
 | 
						|
    return [[MessageKeys alloc] initWithCipherKey:derivedSecrets.cipherKey
 | 
						|
                                           macKey:derivedSecrets.macKey
 | 
						|
                                               iv:derivedSecrets.iv
 | 
						|
                                            index:self.index];
 | 
						|
}
 | 
						|
 | 
						|
- (NSData *)baseMaterial:(NSData *)seed
 | 
						|
{
 | 
						|
    OWSAssert(self.key);
 | 
						|
    OWSAssert(self.key.length == 32);
 | 
						|
    OWSAssert(seed);
 | 
						|
    OWSAssert(seed.length == kTSKeySeedLength);
 | 
						|
 | 
						|
    NSMutableData *_Nullable bufferData = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
 | 
						|
    OWSAssert(bufferData);
 | 
						|
 | 
						|
    CCHmacContext ctx;
 | 
						|
    CCHmacInit(&ctx, kCCHmacAlgSHA256, [self.key bytes], [self.key length]);
 | 
						|
    CCHmacUpdate(&ctx, [seed bytes], [seed length]);
 | 
						|
    CCHmacFinal(&ctx, bufferData.mutableBytes);
 | 
						|
    return [bufferData copy];
 | 
						|
}
 | 
						|
 | 
						|
@end
 | 
						|
 | 
						|
NS_ASSUME_NONNULL_END
 |