1f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen/* 2f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * Copyright 2015 The Android Open Source Project 3f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * 4f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * Licensed under the Apache License, Version 2.0 (the "License"); 5f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * you may not use this file except in compliance with the License. 6f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * You may obtain a copy of the License at 7f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * 8f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * http://www.apache.org/licenses/LICENSE-2.0 9f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * 10f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * Unless required by applicable law or agreed to in writing, software 11f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * distributed under the License is distributed on an "AS IS" BASIS, 12f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * See the License for the specific language governing permissions and 14f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen * limitations under the License. 15f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen */ 16f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 17f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen#include "iso18033kdf.h" 18f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen#include "openssl_utils.h" 19f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 20f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen#include <algorithm> 21f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 22f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen#include <openssl/evp.h> 23f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 24f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyennamespace keymaster { 25f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 26f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyeninline size_t min(size_t a, size_t b) { 27f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return (a < b) ? a : b; 28f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen} 29f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 30f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyenbool Iso18033Kdf::GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output, 31f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen size_t output_len) { 32f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!is_initialized_ || output == nullptr) 33f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 34f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 35f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen /* Check whether output length is too long as specified in ISO/IEC 18033-2. */ 36f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if ((0xFFFFFFFFULL + start_counter_) * digest_size_ < (uint64_t)output_len) 37f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 38f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 39f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen EVP_MD_CTX ctx; 40f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen EvpMdCtxCleaner ctxCleaner(&ctx); 41f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen EVP_MD_CTX_init(&ctx); 42f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 43f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen size_t num_blocks = (output_len + digest_size_ - 1) / digest_size_; 44f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen UniquePtr<uint8_t[]> counter(new uint8_t[4]); 45f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen UniquePtr<uint8_t[]> digest_result(new uint8_t[digest_size_]); 46f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (counter.get() == nullptr || digest_result.get() == nullptr) 47f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 48f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen for (size_t block = 0; block < num_blocks; block++) { 49f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen switch (digest_type_) { 50f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen case KM_DIGEST_SHA1: 51f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), nullptr /* default digest */)) 52f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 53f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen break; 54f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen case KM_DIGEST_SHA_2_256: 55f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), nullptr /* default digest */)) 56f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 57f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen break; 58f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen default: 59f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 60f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen } 61f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 62f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!EVP_DigestUpdate(&ctx, secret_key_.get(), secret_key_len_) || 63f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen !Uint32ToBigEndianByteArray(block + start_counter_, counter.get()) || 64f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen !EVP_DigestUpdate(&ctx, counter.get(), 4)) 65f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 66f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 67f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (info != nullptr && info_len > 0) { 68f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!EVP_DigestUpdate(&ctx, info, info_len)) 69f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 70f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen } 71f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 72f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen /* OpenSSL does not accept size_t parameter. */ 73f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen uint32_t uint32_digest_size_ = digest_size_; 74f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen if (!EVP_DigestFinal_ex(&ctx, digest_result.get(), &uint32_digest_size_) || 75f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen uint32_digest_size_ != digest_size_) 76f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return false; 77f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 78f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen size_t block_start = digest_size_ * block; 79f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen size_t block_length = min(digest_size_, output_len - block_start); 80f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen memcpy(output + block_start, digest_result.get(), block_length); 81f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen } 82f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen return true; 83f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen} 84f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen 85f7538e0127ec2cb5202b0cbc64ad8305aae6243bQuan Nguyen} // namespace keymaster 86