Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "buffer.h"
     18 #include "proto_utils.h"
     19 
     20 #include <keymasterV4_0/key_param_output.h>
     21 
     22 #include <android-base/logging.h>
     23 
     24 #include <openssl/rsa.h>
     25 
     26 #include <map>
     27 #include <vector>
     28 
     29 namespace android {
     30 namespace hardware {
     31 namespace keymaster {
     32 
     33 // HAL
     34 using ::android::hardware::keymaster::V4_0::Algorithm;
     35 using ::android::hardware::keymaster::V4_0::ErrorCode;
     36 
     37 // std
     38 using std::map;
     39 using std::pair;
     40 using std::vector;
     41 
     42 /* Stack space constrains the input/output size to RSA_MAX_BYTES (3k) */
     43 static const size_t kMaxChunkSize = 384;
     44 
     45 class Operation {
     46 public:
     47     Operation(Algorithm algorithm) : _algorithm(algorithm), _buffer{} {
     48         switch (_algorithm) {
     49         case Algorithm::AES:
     50             _blockSize = 16;
     51             break;
     52         case Algorithm::TRIPLE_DES:
     53             _blockSize = 8;
     54             break;
     55         case Algorithm::RSA:
     56         case Algorithm::EC:
     57         case Algorithm::HMAC:
     58             _blockSize = 0;
     59             break;
     60         default:
     61             break;
     62         }
     63     }
     64 
     65     size_t remaining() const {
     66         return _buffer.size();
     67     }
     68 
     69     void append(const hidl_vec<uint8_t>& input, uint32_t *consumed) {
     70         const size_t count = std::min(
     71             kMaxChunkSize - _buffer.size(), input.size());
     72         _buffer.insert(_buffer.end(), input.begin(), input.begin() + count);
     73         *consumed = count;
     74     }
     75 
     76     void peek(hidl_vec<uint8_t> *data) {
     77         // Retain at least one full block; this is done so that when
     78         // either GCM mode or PKCS7 padding are in use, the last block
     79         // will be available to be consumed by final().
     80         if (_buffer.size() <= _blockSize) {
     81             *data = vector<uint8_t>();
     82             return;
     83         }
     84 
     85         size_t retain;
     86         if (_blockSize == 0) {
     87             retain = 0;
     88         } else {
     89             retain = (_buffer.size() % _blockSize) + _blockSize;
     90         }
     91         const size_t count = _buffer.size() - retain;
     92         *data = vector<uint8_t>(_buffer.begin(), _buffer.begin() + count);
     93     }
     94 
     95     ErrorCode advance(size_t count) {
     96         if (count > _buffer.size()) {
     97             LOG(ERROR) << "Attempt to advance " << count
     98                        << " bytes, where occupancy is " << _buffer.size();
     99             return ErrorCode::UNKNOWN_ERROR;
    100         }
    101         _buffer.erase(_buffer.begin(), _buffer.begin() + count);
    102         return ErrorCode::OK;
    103     }
    104 
    105     void final(hidl_vec<uint8_t> *data) {
    106         if (data != NULL) {
    107             *data = _buffer;
    108         }
    109         _buffer.clear();
    110     }
    111 
    112     Algorithm algorithm(void) {
    113         return _algorithm;
    114     }
    115 
    116 private:
    117     Algorithm _algorithm;
    118     size_t _blockSize;
    119     vector<uint8_t> _buffer;
    120 };
    121 
    122 static map<uint64_t, Operation>  buffer_map;
    123 typedef map<uint64_t, Operation>::iterator  buffer_item;
    124 
    125 ErrorCode buffer_begin(uint64_t handle, Algorithm algorithm)
    126 {
    127     if (buffer_map.find(handle) != buffer_map.end()) {
    128         LOG(ERROR) << "Duplicate operation handle " << handle
    129                    << "returned by begin()";
    130         // Final the existing op to potential mishandling of data.
    131         buffer_final(handle, NULL);
    132         return ErrorCode::UNKNOWN_ERROR;
    133     }
    134 
    135     buffer_map.insert(
    136         pair<uint64_t, Operation>(handle, Operation(algorithm)));
    137     return ErrorCode::OK;
    138 }
    139 
    140 size_t buffer_remaining(uint64_t handle) {
    141     if (buffer_map.find(handle) == buffer_map.end()) {
    142         LOG(ERROR) << "Remaining requested on absent operation: " << handle;
    143         return 0;
    144     }
    145 
    146     const Operation &op = buffer_map.find(handle)->second;
    147     return op.remaining();
    148 }
    149 
    150 ErrorCode buffer_append(uint64_t handle,
    151                         const hidl_vec<uint8_t>& input,
    152                         uint32_t *consumed)
    153 {
    154     if (buffer_map.find(handle) == buffer_map.end()) {
    155         LOG(ERROR) << "Append requested on absent operation: " << handle;
    156         return ErrorCode::UNKNOWN_ERROR;
    157     }
    158 
    159     Operation *op = &buffer_map.find(handle)->second;
    160     op->append(input, consumed);
    161     return ErrorCode::OK;
    162 }
    163 
    164 ErrorCode buffer_peek(uint64_t handle,
    165                       hidl_vec<uint8_t> *data)
    166 {
    167     if (buffer_map.find(handle) == buffer_map.end()) {
    168         LOG(ERROR) << "Read requested on absent operation: " << handle;
    169         return ErrorCode::UNKNOWN_ERROR;
    170     }
    171 
    172     Operation *op = &buffer_map.find(handle)->second;
    173     op->peek(data);
    174     return ErrorCode::OK;
    175 }
    176 
    177 ErrorCode buffer_advance(uint64_t handle, size_t count)
    178 {
    179     if (buffer_map.find(handle) == buffer_map.end()) {
    180         LOG(ERROR) << "Read requested on absent operation: " << handle;
    181         return ErrorCode::UNKNOWN_ERROR;
    182     }
    183 
    184     Operation *op = &buffer_map.find(handle)->second;
    185     return op->advance(count);
    186 }
    187 
    188 ErrorCode buffer_final(uint64_t handle,
    189                    hidl_vec<uint8_t> *data)
    190 {
    191     if (buffer_map.find(handle) == buffer_map.end()) {
    192         LOG(ERROR) << "Final requested on absent operation: " << handle;
    193         return ErrorCode::UNKNOWN_ERROR;
    194     }
    195     Operation *op = &buffer_map.find(handle)->second;
    196     op->final(data);
    197     buffer_map.erase(handle);
    198     return ErrorCode::OK;
    199 }
    200 
    201 ErrorCode buffer_algorithm(uint64_t handle, Algorithm *algorithm)
    202 {
    203     if (buffer_map.find(handle) == buffer_map.end()) {
    204         LOG(ERROR) << "Algorithm requested on absent operation: " << handle;
    205         return ErrorCode::UNKNOWN_ERROR;
    206     }
    207     Operation *op = &buffer_map.find(handle)->second;
    208     *algorithm = op->algorithm();
    209     return ErrorCode::OK;
    210 }
    211 
    212 }  // namespace keymaster
    213 }  // hardware
    214 }  // android
    215