• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Operation(Algorithm algorithm)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 
remaining() const65     size_t remaining() const {
66         return _buffer.size();
67     }
68 
append(const hidl_vec<uint8_t> & input,uint32_t * consumed)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 
peek(hidl_vec<uint8_t> * data)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 
advance(size_t count)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 
final(hidl_vec<uint8_t> * data)105     void final(hidl_vec<uint8_t> *data) {
106         if (data != NULL) {
107             *data = _buffer;
108         }
109         _buffer.clear();
110     }
111 
algorithm(void)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 
buffer_begin(uint64_t handle,Algorithm algorithm)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 
buffer_remaining(uint64_t handle)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 
buffer_append(uint64_t handle,const hidl_vec<uint8_t> & input,uint32_t * consumed)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 
buffer_peek(uint64_t handle,hidl_vec<uint8_t> * data)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 
buffer_advance(uint64_t handle,size_t count)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 
buffer_final(uint64_t handle,hidl_vec<uint8_t> * data)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 
buffer_algorithm(uint64_t handle,Algorithm * algorithm)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