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