10a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* 20a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Copyright 2014 The Android Open Source Project 30a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 40a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 50a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * you may not use this file except in compliance with the License. 60a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * You may obtain a copy of the License at 70a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 80a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 90a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Unless required by applicable law or agreed to in writing, software 110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * See the License for the specific language governing permissions and 140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * limitations under the License. 150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden */ 160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <assert.h> 180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <string.h> 190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <cstddef> 210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <openssl/rand.h> 230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <openssl/x509.h> 240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <UniquePtr.h> 260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <keymaster/google_keymaster.h> 280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <keymaster/google_keymaster_utils.h> 290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <keymaster/key_blob.h> 300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "ae.h" 320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "key.h" 330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "operation.h" 340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdennamespace keymaster { 360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::GoogleKeymaster(size_t operation_table_size, Logger* logger) 380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden : operation_table_(new OpTableEntry[operation_table_size]), 390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden operation_table_size_(operation_table_size), logger_(logger) { 400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (operation_table_.get() == NULL) 410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden operation_table_size_ = 0; 420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::~GoogleKeymaster() { 440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (size_t i = 0; i < operation_table_size_; ++i) 450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (operation_table_[i].operation != NULL) 460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden delete operation_table_[i].operation; 470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenstruct AE_CTX_Delete { 500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden void operator()(ae_ctx* ctx) const { ae_free(ctx); } 510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}; 520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdentypedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx; 530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_algorithm_t supported_algorithms[] = { 550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA, 560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}; 570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdentemplate <typename T> 590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) { 600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!array_contains(supported_algorithms, algorithm)) { 610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_UNSUPPORTED_ALGORITHM; 620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return false; 630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return true; 650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid 680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const { 690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->SetResults(supported_algorithms); 720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid 750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::SupportedBlockModes(keymaster_algorithm_t algorithm, 760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SupportedResponse<keymaster_block_mode_t>* response) const { 770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL || !check_supported(algorithm, response)) 780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_padding_t supported_padding[] = {KM_PAD_NONE}; 830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid 840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::SupportedPaddingModes(keymaster_algorithm_t algorithm, 850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SupportedResponse<keymaster_padding_t>* response) const { 860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL || !check_supported(algorithm, response)) 870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (algorithm) { 910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_RSA: 920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_DSA: 930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_ECDSA: 940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->SetResults(supported_padding); 950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->results_length = 0; 980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_digest_t supported_digests[] = {KM_DIGEST_NONE}; 1030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::SupportedDigests(keymaster_algorithm_t algorithm, 1040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SupportedResponse<keymaster_digest_t>* response) const { 1050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL || !check_supported(algorithm, response)) 1060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 1090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (algorithm) { 1100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_RSA: 1110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_DSA: 1120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_ECDSA: 1130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->SetResults(supported_digests); 1140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 1160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->results_length = 0; 1170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8}; 1220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid 1230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::SupportedImportFormats(keymaster_algorithm_t algorithm, 1240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SupportedResponse<keymaster_key_format_t>* response) const { 1250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL || !check_supported(algorithm, response)) 1260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 1290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (algorithm) { 1300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_RSA: 1310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_DSA: 1320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_ECDSA: 1330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->SetResults(supported_import_formats); 1340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 1360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->results_length = 0; 1370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509}; 1420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid 1430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::SupportedExportFormats(keymaster_algorithm_t algorithm, 1440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SupportedResponse<keymaster_key_format_t>* response) const { 1450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL || !check_supported(algorithm, response)) 1460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 1490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (algorithm) { 1500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_RSA: 1510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_DSA: 1520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_ALGORITHM_ECDSA: 1530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->SetResults(supported_export_formats); 1540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 1560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->results_length = 0; 1570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 1580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::GenerateKey(const GenerateKeyRequest& request, 1620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GenerateKeyResponse* response) { 1630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 1640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Key> key(Key::GenerateKey(request.key_description, logger(), &response->error)); 1670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response->error != KM_ERROR_OK) 1680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = SerializeKey(key.get(), origin(), &response->key_blob, &response->enforced, 1710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden &response->unenforced); 1720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request, 1750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GetKeyCharacteristicsResponse* response) { 1760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 1770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_UNKNOWN_ERROR; 1790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<KeyBlob> blob( 1810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden LoadKeyBlob(request.key_blob, request.additional_params, &(response->error))); 1820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (blob.get() == NULL) 1830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->enforced.Reinitialize(blob->enforced()); 1860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->unenforced.Reinitialize(blob->unenforced()); 1870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_OK; 1880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::BeginOperation(const BeginOperationRequest& request, 1910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden BeginOperationResponse* response) { 1920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 1930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->op_handle = 0; 1950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Key> key(LoadKey(request.key_blob, request.additional_params, &response->error)); 1970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (key.get() == NULL) 1980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 1990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Operation> operation(key->CreateOperation(request.purpose, &response->error)); 2010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (operation.get() == NULL) 2020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = operation->Begin(); 2050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response->error != KM_ERROR_OK) 2060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = AddOperation(operation.release(), &response->op_handle); 2090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::UpdateOperation(const UpdateOperationRequest& request, 2120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UpdateOperationResponse* response) { 2130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden OpTableEntry* entry = FindOperation(request.op_handle); 2140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (entry == NULL) { 2150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_INVALID_OPERATION_HANDLE; 2160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = entry->operation->Update(request.input, &response->output); 2200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response->error != KM_ERROR_OK) { 2210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Any error invalidates the operation. 2220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden DeleteOperation(entry); 2230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::FinishOperation(const FinishOperationRequest& request, 2270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden FinishOperationResponse* response) { 2280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden OpTableEntry* entry = FindOperation(request.op_handle); 2290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (entry == NULL) { 2300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = KM_ERROR_INVALID_OPERATION_HANDLE; 2310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = entry->operation->Finish(request.signature, &response->output); 2350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden DeleteOperation(entry); 2360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GoogleKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) { 2390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden OpTableEntry* entry = FindOperation(op_handle); 2400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (entry == NULL) 2410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_INVALID_OPERATION_HANDLE; 2420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden DeleteOperation(entry); 2430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 2440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool GoogleKeymaster::is_supported_export_format(keymaster_key_format_t test_format) { 2470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden unsigned int index; 2480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (index = 0; index < array_length(supported_export_formats); index++) { 2490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (test_format == supported_export_formats[index]) { 2500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return true; 2510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return false; 2550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool GoogleKeymaster::is_supported_import_format(keymaster_key_format_t test_format) { 2580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden unsigned int index; 2590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (index = 0; index < array_length(supported_import_formats); index++) { 2600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (test_format == supported_import_formats[index]) { 2610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return true; 2620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return false; 2660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) { 2690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 2700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Key> to_export( 2730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden LoadKey(request.key_blob, request.additional_params, &response->error)); 2740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (to_export.get() == NULL) 2750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]> out_key; 2780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden size_t size; 2790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = to_export->formatted_key_material(request.key_format, &out_key, &size); 2800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response->error == KM_ERROR_OK) { 2810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->key_data = out_key.release(); 2820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->key_data_length = size; 2830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) { 2870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response == NULL) 2880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Key> key(Key::ImportKey(request.key_description, request.key_format, request.key_data, 2910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden request.key_data_length, logger(), &response->error)); 2920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (response->error != KM_ERROR_OK) 2930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return; 2940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden response->error = SerializeKey(key.get(), KM_ORIGIN_IMPORTED, &response->key_blob, 2960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden &response->enforced, &response->unenforced); 2970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GoogleKeymaster::SerializeKey(const Key* key, keymaster_key_origin_t origin, 3000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_key_blob_t* keymaster_blob, 3010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* enforced, 3020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* unenforced) { 3030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_error_t error; 3040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden error = SetAuthorizations(key->authorizations(), origin, enforced, unenforced); 3060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error != KM_ERROR_OK) 3070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return error; 3080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet hidden_auths; 3100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden error = BuildHiddenAuthorizations(key->authorizations(), &hidden_auths); 3110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error != KM_ERROR_OK) 3120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return error; 3130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]> key_material; 3150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden size_t key_material_size; 3160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden error = key->key_material(&key_material, &key_material_size); 3170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error != KM_ERROR_OK) 3180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return error; 3190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint8_t nonce[KeyBlob::NONCE_LENGTH]; 3210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GenerateNonce(nonce, array_size(nonce)); 3220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_key_blob_t key_data = {key_material.get(), key_material_size}; 3240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<KeyBlob> blob( 3250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden new KeyBlob(*enforced, *unenforced, hidden_auths, key_data, MasterKey(), nonce)); 3260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (blob.get() == NULL) 3270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 3280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (blob->error() != KM_ERROR_OK) 3290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return blob->error(); 3300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden size_t size = blob->SerializedSize(); 3320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]); 3330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (blob_bytes.get() == NULL) 3340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 3350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden blob->Serialize(blob_bytes.get(), blob_bytes.get() + size); 3370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob->key_material_size = size; 3380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob->key_material = blob_bytes.release(); 3390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 3410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenKey* GoogleKeymaster::LoadKey(const keymaster_key_blob_t& key, 3440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const AuthorizationSet& client_params, keymaster_error_t* error) { 3450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<KeyBlob> blob(LoadKeyBlob(key, client_params, error)); 3460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*error != KM_ERROR_OK) 3470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return Key::CreateKey(*blob, logger(), error); 3490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenKeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key, 3520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const AuthorizationSet& client_params, 3530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_error_t* error) { 3540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet hidden; 3550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden BuildHiddenAuthorizations(client_params, &hidden); 3560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<KeyBlob> blob(new KeyBlob(key, hidden, MasterKey())); 3570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (blob.get() == NULL) { 3580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 3590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else if (blob->error() != KM_ERROR_OK) { 3610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = blob->error(); 3620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_OK; 3650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return blob.release(); 3660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenstatic keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) { 3690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (err) { 3700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case AuthorizationSet::OK: 3710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 3720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case AuthorizationSet::ALLOCATION_FAILURE: 3730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 3740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case AuthorizationSet::MALFORMED_DATA: 3750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 3760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 3780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GoogleKeymaster::SetAuthorizations(const AuthorizationSet& key_description, 3810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_key_origin_t origin, 3820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* enforced, 3830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* unenforced) { 3840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (size_t i = 0; i < key_description.size(); ++i) { 3850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (key_description[i].tag) { 3860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // These cannot be specified by the client. 3870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_TAG_ROOT_OF_TRUST: 3880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_TAG_ORIGIN: 3890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_INVALID_TAG; 3900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // These don't work. 3920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_TAG_ROLLBACK_RESISTANT: 3930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNSUPPORTED_TAG; 3940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // These are hidden. 3960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_TAG_APPLICATION_ID: 3970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_TAG_APPLICATION_DATA: 3980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 3990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Everything else we just copy into the appropriate set. 4010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 4020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AddAuthorization(key_description[i], enforced, unenforced); 4030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 4040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), enforced, 4080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden unenforced); 4090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AddAuthorization(Authorization(TAG_ORIGIN, origin), enforced, unenforced); 4100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (enforced->is_valid() != AuthorizationSet::OK) 4120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return TranslateAuthorizationSetError(enforced->is_valid()); 4130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return TranslateAuthorizationSetError(unenforced->is_valid()); 4150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GoogleKeymaster::BuildHiddenAuthorizations(const AuthorizationSet& input_set, 4180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* hidden) { 4190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t entry; 4200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry)) 4210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length); 4220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry)) 4230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length); 4240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden hidden->push_back(RootOfTrustTag()); 4250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return TranslateAuthorizationSetError(hidden->is_valid()); 4270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth, 4300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* enforced, AuthorizationSet* unenforced) { 4310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (is_enforced(auth.tag)) 4320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden enforced->push_back(auth); 4330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden else 4340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden unenforced->push_back(auth); 4350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GoogleKeymaster::AddOperation(Operation* operation, 4380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_operation_handle_t* op_handle) { 4390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<Operation> op(operation); 4400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0) 4410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 4420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*op_handle == 0) { 4430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Statistically this is vanishingly unlikely, which means if it ever happens in practice, 4440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // it indicates a broken RNG. 4450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 4460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (size_t i = 0; i < operation_table_size_; ++i) { 4480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (operation_table_[i].operation == NULL) { 4490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden operation_table_[i].operation = op.release(); 4500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden operation_table_[i].handle = *op_handle; 4510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 4520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_TOO_MANY_OPERATIONS; 4550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::OpTableEntry* 4580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenGoogleKeymaster::FindOperation(keymaster_operation_handle_t op_handle) { 4590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (op_handle == 0) 4600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden for (size_t i = 0; i < operation_table_size_; ++i) { 4630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (operation_table_[i].handle == op_handle) 4640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return operation_table_.get() + i; 4650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenvoid GoogleKeymaster::DeleteOperation(OpTableEntry* entry) { 4700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden delete entry->operation; 4710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden entry->operation = NULL; 4720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden entry->handle = 0; 4730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} // namespace keymaster 476