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