12beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden/* 22beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * Copyright 2015 The Android Open Source Project 32beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * 42beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 52beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * you may not use this file except in compliance with the License. 62beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * You may obtain a copy of the License at 72beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * 82beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 92beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * 102beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * Unless required by applicable law or agreed to in writing, software 112beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 122beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * See the License for the specific language governing permissions and 142beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden * limitations under the License. 152beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden */ 162beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 172beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include "integrity_assured_key_blob.h" 182beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 192beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include <assert.h> 202beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 210f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <new> 220f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 232beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include <openssl/hmac.h> 242beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include <openssl/mem.h> 252beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 262beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include <keymaster/android_keymaster_utils.h> 272beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include <keymaster/authorization_set.h> 282beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 292beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden#include "openssl_err.h" 302beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 312beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdennamespace keymaster { 322beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 332beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenstatic const uint8_t BLOB_VERSION = 0; 342beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenstatic const size_t HMAC_SIZE = 8; 352beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenstatic const char HMAC_KEY[] = "IntegrityAssuredBlob0"; 362beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 372beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdeninline size_t min(size_t a, size_t b) { 382beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (a < b) 392beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return a; 402beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return b; 412beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden} 422beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 432beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenclass HmacCleanup { 442beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden public: 4503d4b6d531eb8c2ebcb4d572a3bf118c70a83ff6Chih-Hung Hsieh explicit HmacCleanup(HMAC_CTX* ctx) : ctx_(ctx) {} 462beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden ~HmacCleanup() { HMAC_CTX_cleanup(ctx_); } 472beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 482beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden private: 492beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden HMAC_CTX* ctx_; 502beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden}; 512beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 5236d41e230417ac3b86a1425ebf60fff6d92377ecShawn Willdenstatic keymaster_error_t ComputeHmac(const uint8_t* serialized_data, size_t serialized_data_size, 5301d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden const AuthorizationSet& hidden, uint8_t hmac[HMAC_SIZE]) { 542beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden size_t hidden_bytes_size = hidden.SerializedSize(); 5501d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden UniquePtr<uint8_t[]> hidden_bytes(new (std::nothrow) uint8_t[hidden_bytes_size]); 560f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!hidden_bytes.get()) 570f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 582beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden hidden.Serialize(hidden_bytes.get(), hidden_bytes.get() + hidden_bytes_size); 592beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 602beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden HMAC_CTX ctx; 612beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden HMAC_CTX_init(&ctx); 622beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const EVP_MD* md = EVP_sha256(); 632beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (!HMAC_Init_ex(&ctx, HMAC_KEY, sizeof(HMAC_KEY), md, NULL /* engine */)) 642beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return TranslateLastOpenSslError(); 652beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden HmacCleanup cleanup(&ctx); 662beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 672beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden uint8_t tmp[EVP_MAX_MD_SIZE]; 682beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden unsigned tmp_len; 692beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (!HMAC_Update(&ctx, serialized_data, serialized_data_size) || 702beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden !HMAC_Update(&ctx, hidden_bytes.get(), hidden_bytes_size) || // 712beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden !HMAC_Final(&ctx, tmp, &tmp_len)) 722beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return TranslateLastOpenSslError(); 732beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 742beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden assert(tmp_len >= HMAC_SIZE); 752beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden memcpy(hmac, tmp, min(HMAC_SIZE, tmp_len)); 762beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 772beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_OK; 782beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden} 792beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 802beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenkeymaster_error_t SerializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_material, 812beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const AuthorizationSet& hidden, 822beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const AuthorizationSet& hw_enforced, 832beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const AuthorizationSet& sw_enforced, 842beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden KeymasterKeyBlob* key_blob) { 852beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden size_t size = 1 /* version */ + // 862beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden key_material.SerializedSize() + // 872beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden hw_enforced.SerializedSize() + // 882beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden sw_enforced.SerializedSize() + // 892beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden HMAC_SIZE; 902beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 912beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (!key_blob->Reset(size)) 922beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 932beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 942beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden uint8_t* p = key_blob->writable_data(); 952beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden *p++ = BLOB_VERSION; 962beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden p = key_material.Serialize(p, key_blob->end()); 972beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden p = hw_enforced.Serialize(p, key_blob->end()); 982beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden p = sw_enforced.Serialize(p, key_blob->end()); 992beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1002beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return ComputeHmac(key_blob->key_material, p - key_blob->key_material, hidden, p); 1012beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden} 1022beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1032beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willdenkeymaster_error_t DeserializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_blob, 1042beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const AuthorizationSet& hidden, 1052beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden KeymasterKeyBlob* key_material, 1062beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden AuthorizationSet* hw_enforced, 1072beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden AuthorizationSet* sw_enforced) { 1082beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const uint8_t* p = key_blob.begin(); 1092beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden const uint8_t* end = key_blob.end(); 1102beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 11101d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden if (p > end || p + HMAC_SIZE > end) 1120f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 1130f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 1142beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden uint8_t computed_hmac[HMAC_SIZE]; 1152beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden keymaster_error_t error = ComputeHmac(key_blob.begin(), key_blob.key_material_size - HMAC_SIZE, 1162beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden hidden, computed_hmac); 1172beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (error != KM_ERROR_OK) 1182beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return error; 1192beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1202beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (CRYPTO_memcmp(key_blob.end() - HMAC_SIZE, computed_hmac, HMAC_SIZE) != 0) 1212beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 1222beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 12301d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden return DeserializeIntegrityAssuredBlob_NoHmacCheck(key_blob, key_material, hw_enforced, 12401d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden sw_enforced); 12501d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden} 12601d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden 12701d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willdenkeymaster_error_t DeserializeIntegrityAssuredBlob_NoHmacCheck(const KeymasterKeyBlob& key_blob, 12801d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden KeymasterKeyBlob* key_material, 12901d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden AuthorizationSet* hw_enforced, 13001d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden AuthorizationSet* sw_enforced) { 13101d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden const uint8_t* p = key_blob.begin(); 13201d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden const uint8_t* end = key_blob.end() - HMAC_SIZE; 13301d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden 13401d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden if (p > end) 13501d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 13601d8f24c45067bc3d909e3aae9a72582f3c985a1Shawn Willden 1372beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (*p != BLOB_VERSION) 1382beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 1392beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden ++p; 1402beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1412beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden if (!key_material->Deserialize(&p, end) || // 1422beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden !hw_enforced->Deserialize(&p, end) || // 1432beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden !sw_enforced->Deserialize(&p, end)) 1442beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 1452beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1462beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden return KM_ERROR_OK; 1472beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden} 1482beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden 1492beb628bfefae72fa6bb84a6235da7e3de532823Shawn Willden} // namespace keymaster; 150