| /* |
| * |
| * Copyright (c) 2016-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * This file implements a Wrapper for C++ implementation of key derivation functionality |
| * for pin encryption. |
| * |
| */ |
| |
| #import "NLHKDF.h" |
| |
| #include <Weave/Support/NLDLLUtil.h> |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Support/crypto/HMAC.h> |
| #include <Weave/Support/crypto/HashAlgos.h> |
| #include <Weave/Support/crypto/HKDF.h> |
| |
| NSString *const NLHKDFErrorDomain = @"NLHKDFErrorDomain"; |
| |
| @implementation NLHKDF |
| |
| + (NSData *) deriveKey: (NSString *) alg |
| salt: (NSData *) salt |
| keyMaterial1: (NSData *) keyMaterial1 |
| keyMaterial2: (NSData *) keyMaterial2 |
| info: (NSData *) info |
| requestedKeyLen: (NSUInteger) requestedKeyLen |
| error: (NSError **) errOut { |
| |
| if (![alg isEqualToString:@"HKDFSHA1" ]) { |
| if (errOut) { |
| *errOut = [NSError errorWithDomain:NLHKDFErrorDomain |
| code:NLHKDFErrorDomainAlgNotSupported userInfo:nil]; |
| } |
| return nil; |
| } |
| |
| NSMutableData * data = [[NSMutableData alloc] initWithLength:requestedKeyLen]; |
| |
| WEAVE_ERROR err = nl::Weave::Crypto::HKDFSHA1::DeriveKey( |
| (salt != nil) ? (unsigned char *) [salt bytes] : NULL, |
| (salt != nil) ? [salt length] : 0, |
| (unsigned char *) [keyMaterial1 bytes], |
| [keyMaterial1 length], |
| (unsigned char *) [keyMaterial2 bytes], |
| [keyMaterial2 length], |
| (unsigned char *) [info bytes], |
| [info length], |
| (unsigned char *) [data mutableBytes], |
| requestedKeyLen, |
| requestedKeyLen); |
| |
| if (err != WEAVE_NO_ERROR){ |
| if (err == WEAVE_ERROR_BUFFER_TOO_SMALL) { |
| *errOut = [NSError errorWithDomain:NLHKDFErrorDomain |
| code:NLHKDFErrorDomainKeyBuffSizeInsufficient userInfo:nil]; |
| } else if (err == WEAVE_ERROR_INVALID_ARGUMENT) { |
| *errOut = [NSError errorWithDomain:NLHKDFErrorDomain |
| code:NLHKDFErrorDomainKeyInvalidRequestedKeySize userInfo:nil]; |
| } else { |
| NSString *failureReason = [NSString stringWithFormat:NSLocalizedString(@"DeriveKey error: %d", @""), err]; |
| NSDictionary *userInfo = @{ NSLocalizedFailureReasonErrorKey: failureReason }; |
| *errOut = [NSError errorWithDomain:NLHKDFErrorDomain |
| code:NLHKDFErrorDomainDeriveKeyFailure userInfo: userInfo]; |
| } |
| return nil; |
| } |
| |
| return data; |
| } |
| |
| @end |