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 static const size_t kMaxChunkSize = 256;
     43 
     44 class Operation {
     45 public:
     46     Operation(Algorithm algorithm) : _algorithm(algorithm), _buffer{} {
     47         switch (_algorithm) {
     48         case Algorithm::AES:
     49             _blockSize = 16;
     50             break;
     51         case Algorithm::TRIPLE_DES:
     52             _blockSize = 8;
     53             break;
     54         case Algorithm::RSA:
     55         case Algorithm::EC:
     56         case Algorithm::HMAC:
     57             _blockSize = 0;
     58         default:
     59             break;
     60         }
     61     }
     62 
     63     size_t remaining() const {
     64         return _buffer.size();
     65     }
     66 
     67     void append(const hidl_vec<uint8_t>& input, uint32_t *consumed) {
     68         _buffer.insert(_buffer.end(), input.begin(), input.end());
     69         *consumed = input.size();
     70     }
     71 
     72     void peek(hidl_vec<uint8_t> *data) {
     73         // Retain at least one full block; this is done so that when
     74         // either GCM mode or PKCS7 padding are in use, the last block
     75         // will be available to be consumed by final().
     76         if (_buffer.size() <= _blockSize) {
     77             *data = vector<uint8_t>();
     78             return;
     79         }
     80 
     81         size_t retain;
     82         if (_blockSize == 0) {
     83             retain = 0;
     84         } else {
     85             retain = (_buffer.size() % _blockSize) + _blockSize;
     86         }
     87         const size_t count = std::min(_buffer.size() - retain, kMaxChunkSize);
     88         *data = vector<uint8_t>(_buffer.begin(), _buffer.begin() + count);
     89     }
     90 
     91     ErrorCode advance(size_t count) {
     92         if (count > _buffer.size()) {
     93             LOG(ERROR) << "Attempt to advance " << count
     94                        << " bytes, where occupancy is " << _buffer.size();
     95             return ErrorCode::UNKNOWN_ERROR;
     96         }
     97         _buffer.erase(_buffer.begin(), _buffer.begin() + count);
     98         return ErrorCode::OK;
     99     }
    100 
    101     void final(hidl_vec<uint8_t> *data) {
    102         if (data != NULL) {
    103             *data = _buffer;
    104         }
    105         _buffer.clear();
    106     }
    107 
    108 private:
    109     Algorithm _algorithm;
    110     size_t _blockSize;
    111     vector<uint8_t> _buffer;
    112 };
    113 
    114 static map<uint64_t, Operation>  buffer_map;
    115 typedef map<uint64_t, Operation>::iterator  buffer_item;
    116 
    117 ErrorCode buffer_begin(uint64_t handle, Algorithm algorithm)
    118 {
    119     if (buffer_map.find(handle) != buffer_map.end()) {
    120         LOG(ERROR) << "Duplicate operation handle " << handle
    121                    << "returned by begin()";
    122         // Final the existing op to potential mishandling of data.
    123         buffer_final(handle, NULL);
    124         return ErrorCode::UNKNOWN_ERROR;
    125     }
    126 
    127     buffer_map.insert(
    128         pair<uint64_t, Operation>(handle, Operation(algorithm)));
    129     return ErrorCode::OK;
    130 }
    131 
    132 size_t buffer_remaining(uint64_t handle) {
    133     if (buffer_map.find(handle) == buffer_map.end()) {
    134         LOG(ERROR) << "Remaining requested on absent operation: " << handle;
    135         return 0;
    136     }
    137 
    138     const Operation &op = buffer_map.find(handle)->second;
    139     return op.remaining();
    140 }
    141 
    142 ErrorCode buffer_append(uint64_t handle,
    143                         const hidl_vec<uint8_t>& input,
    144                         uint32_t *consumed)
    145 {
    146     if (buffer_map.find(handle) == buffer_map.end()) {
    147         LOG(ERROR) << "Append requested on absent operation: " << handle;
    148         return ErrorCode::UNKNOWN_ERROR;
    149     }
    150 
    151     Operation *op = &buffer_map.find(handle)->second;
    152     op->append(input, consumed);
    153     return ErrorCode::OK;
    154 }
    155 
    156 ErrorCode buffer_peek(uint64_t handle,
    157                       hidl_vec<uint8_t> *data)
    158 {
    159     if (buffer_map.find(handle) == buffer_map.end()) {
    160         LOG(ERROR) << "Read requested on absent operation: " << handle;
    161         return ErrorCode::UNKNOWN_ERROR;
    162     }
    163 
    164     Operation *op = &buffer_map.find(handle)->second;
    165     op->peek(data);
    166     return ErrorCode::OK;
    167 }
    168 
    169 ErrorCode buffer_advance(uint64_t handle, size_t count)
    170 {
    171     if (buffer_map.find(handle) == buffer_map.end()) {
    172         LOG(ERROR) << "Read requested on absent operation: " << handle;
    173         return ErrorCode::UNKNOWN_ERROR;
    174     }
    175 
    176     Operation *op = &buffer_map.find(handle)->second;
    177     return op->advance(count);
    178 }
    179 
    180 ErrorCode buffer_final(uint64_t handle,
    181                    hidl_vec<uint8_t> *data)
    182 {
    183     if (buffer_map.find(handle) == buffer_map.end()) {
    184         LOG(ERROR) << "Final requested on absent operation: " << handle;
    185         return ErrorCode::UNKNOWN_ERROR;
    186     }
    187     Operation *op = &buffer_map.find(handle)->second;
    188     op->final(data);
    189     buffer_map.erase(handle);
    190     return ErrorCode::OK;
    191 }
    192 
    193 }  // namespace keymaster
    194 }  // hardware
    195 }  // android
    196