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