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
		
	
	
	
		
			Matlab
		
	
		
		
			
		
	
	
			97 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Matlab
		
	
| 
											5 years ago
										 | // | ||
|  | //  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 |