123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden/* 223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * Copyright (C) 2015 The Android Open Source Project 323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * 423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * you may not use this file except in compliance with the License. 623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * You may obtain a copy of the License at 723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * 823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * 1023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * Unless required by applicable law or agreed to in writing, software 1123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 1223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * See the License for the specific language governing permissions and 1423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden * limitations under the License. 1523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden */ 1623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 1723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden#include "operation_table.h" 1823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 19f38a002624126ca837865826f948edc9100d6e8aJanis Danisevskis#include <keymaster/new> 200f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden 2123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden#include <openssl/rand.h> 2223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 2323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden#include "openssl_err.h" 2423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden#include "operation.h" 2523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 2623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willdennamespace keymaster { 2723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 2823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn WilldenOperationTable::Entry::~Entry() { 2923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden delete operation; 3023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden operation = NULL; 3123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden handle = 0; 3223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden} 3323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 34e30b8536b0d94874a2c0a9cc53df48a41ddf043bShawn Willdenkeymaster_error_t OperationTable::Add(Operation* operation, const KeymasterContext& context, 3523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden keymaster_operation_handle_t* op_handle) { 3623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (!table_.get()) { 370f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden table_.reset(new (std::nothrow) Entry[table_size_]); 3823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (!table_.get()) 3923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 4023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 4123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 4223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden UniquePtr<Operation> op(operation); 43e30b8536b0d94874a2c0a9cc53df48a41ddf043bShawn Willden keymaster_error_t error = operation->CreateOperationHandle(context, op_handle); 44e30b8536b0d94874a2c0a9cc53df48a41ddf043bShawn Willden if (error != KM_ERROR_OK) 45e30b8536b0d94874a2c0a9cc53df48a41ddf043bShawn Willden return error; 4623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (*op_handle == 0) { 4723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden // Statistically this is vanishingly unlikely, which means if it ever happens in practice, 4823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden // it indicates a broken RNG. 4923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 5023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 5123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 5223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden for (size_t i = 0; i < table_size_; ++i) { 5323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (table_[i].operation == NULL) { 5423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden table_[i].operation = op.release(); 5523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden table_[i].handle = *op_handle; 5623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return KM_ERROR_OK; 5723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 5823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 5923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return KM_ERROR_TOO_MANY_OPERATIONS; 6023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden} 6123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 6223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn WilldenOperation* OperationTable::Find(keymaster_operation_handle_t op_handle) { 6323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (op_handle == 0) 6423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return NULL; 6523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 6623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (!table_.get()) 6723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return NULL; 6823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 6923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden for (size_t i = 0; i < table_size_; ++i) { 7023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (table_[i].handle == op_handle) 7123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return table_[i].operation; 7223d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 7323d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return NULL; 7423d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden} 7523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 7623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willdenbool OperationTable::Delete(keymaster_operation_handle_t op_handle) { 7723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (!table_.get()) 7823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return false; 7923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 8023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden for (size_t i = 0; i < table_size_; ++i) { 8123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden if (table_[i].handle == op_handle) { 826f49e5f4e0e9698357417ea8ea26f3b86a2793dbChad Brubaker delete table_[i].operation; 836f49e5f4e0e9698357417ea8ea26f3b86a2793dbChad Brubaker table_[i].operation = NULL; 846f49e5f4e0e9698357417ea8ea26f3b86a2793dbChad Brubaker table_[i].handle = 0; 8523d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return true; 8623d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 8723d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden } 8823d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden return false; 8923d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden} 9023d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden 9123d4a742109fa29d6be20d3dc56a1b48797fe7b2Shawn Willden} // namespace keymaster 92