1 /*
2  * Copyright 2014 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 <keymaster/android_keymaster.h>
18 
19 #include <assert.h>
20 #include <string.h>
21 
22 #include <cstddef>
23 
24 #include <openssl/rand.h>
25 #include <openssl/x509.h>
26 
27 #include <UniquePtr.h>
28 
29 #include <keymaster/android_keymaster_utils.h>
30 #include <keymaster/key_factory.h>
31 #include <keymaster/keymaster_context.h>
32 
33 #include "ae.h"
34 #include "key.h"
35 #include "openssl_err.h"
36 #include "operation.h"
37 #include "operation_table.h"
38 
39 namespace keymaster {
40 
41 const uint8_t MAJOR_VER = 1;
42 const uint8_t MINOR_VER = 1;
43 const uint8_t SUBMINOR_VER = 0;
44 
AndroidKeymaster(KeymasterContext * context,size_t operation_table_size)45 AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
46     : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
47 
~AndroidKeymaster()48 AndroidKeymaster::~AndroidKeymaster() {}
49 
50 struct AE_CTX_Delete {
operator ()keymaster::AE_CTX_Delete51     void operator()(ae_ctx* ctx) const { ae_free(ctx); }
52 };
53 typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
54 
55 // TODO(swillden): Unify support analysis.  Right now, we have per-keytype methods that determine if
56 // specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
57 // methods that return the same information.  They'll get out of sync.  Best to put the knowledge in
58 // the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
59 // information.
60 
61 template <typename T>
check_supported(const KeymasterContext & context,keymaster_algorithm_t algorithm,SupportedResponse<T> * response)62 bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
63                      SupportedResponse<T>* response) {
64     if (context.GetKeyFactory(algorithm) == NULL) {
65         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
66         return false;
67     }
68     return true;
69 }
70 
GetVersion(const GetVersionRequest &,GetVersionResponse * rsp)71 void AndroidKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
72     if (rsp == NULL)
73         return;
74 
75     rsp->major_ver = MAJOR_VER;
76     rsp->minor_ver = MINOR_VER;
77     rsp->subminor_ver = SUBMINOR_VER;
78     rsp->error = KM_ERROR_OK;
79 }
80 
SupportedAlgorithms(const SupportedAlgorithmsRequest &,SupportedAlgorithmsResponse * response)81 void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
82                                            SupportedAlgorithmsResponse* response) {
83     if (response == NULL)
84         return;
85 
86     response->error = KM_ERROR_OK;
87 
88     size_t algorithm_count = 0;
89     const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
90     if (algorithm_count == 0)
91         return;
92     response->results_length = algorithm_count;
93     response->results = dup_array(algorithms, algorithm_count);
94     if (!response->results)
95         response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
96 }
97 
98 template <typename T>
GetSupported(const KeymasterContext & context,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,const T * (OperationFactory::* get_supported_method)(size_t * count)const,SupportedResponse<T> * response)99 void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
100                   keymaster_purpose_t purpose,
101                   const T* (OperationFactory::*get_supported_method)(size_t* count) const,
102                   SupportedResponse<T>* response) {
103     if (response == NULL || !check_supported(context, algorithm, response))
104         return;
105 
106     const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
107     if (!factory) {
108         response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
109         return;
110     }
111 
112     size_t count;
113     const T* supported = (factory->*get_supported_method)(&count);
114     response->SetResults(supported, count);
115 }
116 
SupportedBlockModes(const SupportedBlockModesRequest & request,SupportedBlockModesResponse * response)117 void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
118                                            SupportedBlockModesResponse* response) {
119     GetSupported(*context_, request.algorithm, request.purpose,
120                  &OperationFactory::SupportedBlockModes, response);
121 }
122 
SupportedPaddingModes(const SupportedPaddingModesRequest & request,SupportedPaddingModesResponse * response)123 void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
124                                              SupportedPaddingModesResponse* response) {
125     GetSupported(*context_, request.algorithm, request.purpose,
126                  &OperationFactory::SupportedPaddingModes, response);
127 }
128 
SupportedDigests(const SupportedDigestsRequest & request,SupportedDigestsResponse * response)129 void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
130                                         SupportedDigestsResponse* response) {
131     GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
132                  response);
133 }
134 
SupportedImportFormats(const SupportedImportFormatsRequest & request,SupportedImportFormatsResponse * response)135 void AndroidKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
136                                               SupportedImportFormatsResponse* response) {
137     if (response == NULL || !check_supported(*context_, request.algorithm, response))
138         return;
139 
140     size_t count;
141     const keymaster_key_format_t* formats =
142         context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
143     response->SetResults(formats, count);
144 }
145 
SupportedExportFormats(const SupportedExportFormatsRequest & request,SupportedExportFormatsResponse * response)146 void AndroidKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
147                                               SupportedExportFormatsResponse* response) {
148     if (response == NULL || !check_supported(*context_, request.algorithm, response))
149         return;
150 
151     size_t count;
152     const keymaster_key_format_t* formats =
153         context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
154     response->SetResults(formats, count);
155 }
156 
AddRngEntropy(const AddEntropyRequest & request,AddEntropyResponse * response)157 void AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request,
158                                      AddEntropyResponse* response) {
159     response->error = context_->AddRngEntropy(request.random_data.peek_read(),
160                                               request.random_data.available_read());
161 }
162 
GenerateKey(const GenerateKeyRequest & request,GenerateKeyResponse * response)163 void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
164                                    GenerateKeyResponse* response) {
165     if (response == NULL)
166         return;
167 
168     keymaster_algorithm_t algorithm;
169     KeyFactory* factory = 0;
170     UniquePtr<Key> key;
171     if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
172         !(factory = context_->GetKeyFactory(algorithm)))
173         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
174     else {
175         KeymasterKeyBlob key_blob;
176         response->enforced.Clear();
177         response->unenforced.Clear();
178         response->error = factory->GenerateKey(request.key_description, &key_blob,
179                                                &response->enforced, &response->unenforced);
180         if (response->error == KM_ERROR_OK)
181             response->key_blob = key_blob.release();
182     }
183 }
184 
GetKeyCharacteristics(const GetKeyCharacteristicsRequest & request,GetKeyCharacteristicsResponse * response)185 void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
186                                              GetKeyCharacteristicsResponse* response) {
187     if (response == NULL)
188         return;
189 
190     KeymasterKeyBlob key_material;
191     response->error =
192         context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
193                                &key_material, &response->enforced, &response->unenforced);
194     if (response->error != KM_ERROR_OK)
195         return;
196 }
197 
GetKeyFactory(const KeymasterContext & context,const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced,keymaster_algorithm_t * algorithm,keymaster_error_t * error)198 static KeyFactory* GetKeyFactory(const KeymasterContext& context,
199                                  const AuthorizationSet& hw_enforced,
200                                  const AuthorizationSet& sw_enforced,
201                                  keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
202     *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
203     if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
204         !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
205         return nullptr;
206     KeyFactory* factory = context.GetKeyFactory(*algorithm);
207     if (factory)
208         *error = KM_ERROR_OK;
209     return factory;
210 }
211 
BeginOperation(const BeginOperationRequest & request,BeginOperationResponse * response)212 void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
213                                       BeginOperationResponse* response) {
214     if (response == NULL)
215         return;
216     response->op_handle = 0;
217 
218     AuthorizationSet hw_enforced;
219     AuthorizationSet sw_enforced;
220     const KeyFactory* key_factory;
221     UniquePtr<Key> key;
222     response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
223                               &sw_enforced, &key_factory, &key);
224     if (response->error != KM_ERROR_OK)
225         return;
226 
227     response->error = KM_ERROR_UNKNOWN_ERROR;
228     keymaster_algorithm_t key_algorithm;
229     if (!key->authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm))
230         return;
231 
232     response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
233     OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
234     if (!factory)
235         return;
236 
237     UniquePtr<Operation> operation(
238         factory->CreateOperation(*key, request.additional_params, &response->error));
239     if (operation.get() == NULL)
240         return;
241 
242     if (context_->enforcement_policy()) {
243         km_id_t key_id;
244         response->error = KM_ERROR_UNKNOWN_ERROR;
245         if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id))
246             return;
247         operation->set_key_id(key_id);
248         response->error = context_->enforcement_policy()->AuthorizeOperation(
249             request.purpose, key_id, key->authorizations(), request.additional_params,
250             0 /* op_handle */, true /* is_begin_operation */);
251         if (response->error != KM_ERROR_OK)
252             return;
253     }
254 
255     response->output_params.Clear();
256     response->error = operation->Begin(request.additional_params, &response->output_params);
257     if (response->error != KM_ERROR_OK)
258         return;
259 
260     operation->SetAuthorizations(key->authorizations());
261     response->error = operation_table_->Add(operation.release(), &response->op_handle);
262 }
263 
UpdateOperation(const UpdateOperationRequest & request,UpdateOperationResponse * response)264 void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
265                                        UpdateOperationResponse* response) {
266     if (response == NULL)
267         return;
268 
269     response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
270     Operation* operation = operation_table_->Find(request.op_handle);
271     if (operation == NULL)
272         return;
273 
274     if (context_->enforcement_policy()) {
275         response->error = context_->enforcement_policy()->AuthorizeOperation(
276             operation->purpose(), operation->key_id(), operation->authorizations(),
277             request.additional_params, request.op_handle, false /* is_begin_operation */);
278         if (response->error != KM_ERROR_OK)
279             return;
280     }
281 
282     response->error =
283         operation->Update(request.additional_params, request.input, &response->output_params,
284                           &response->output, &response->input_consumed);
285     if (response->error != KM_ERROR_OK) {
286         // Any error invalidates the operation.
287         operation_table_->Delete(request.op_handle);
288     }
289 }
290 
FinishOperation(const FinishOperationRequest & request,FinishOperationResponse * response)291 void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
292                                        FinishOperationResponse* response) {
293     if (response == NULL)
294         return;
295 
296     response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
297     Operation* operation = operation_table_->Find(request.op_handle);
298     if (operation == NULL)
299         return;
300 
301     if (context_->enforcement_policy()) {
302         response->error = context_->enforcement_policy()->AuthorizeOperation(
303             operation->purpose(), operation->key_id(), operation->authorizations(),
304             request.additional_params, request.op_handle, false /* is_begin_operation */);
305         if (response->error != KM_ERROR_OK)
306             return;
307     }
308 
309     response->error = operation->Finish(request.additional_params, request.signature,
310                                         &response->output_params, &response->output);
311     operation_table_->Delete(request.op_handle);
312 }
313 
AbortOperation(const AbortOperationRequest & request,AbortOperationResponse * response)314 void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
315                                       AbortOperationResponse* response) {
316     if (!response)
317         return;
318 
319     Operation* operation = operation_table_->Find(request.op_handle);
320     if (!operation) {
321         response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
322         return;
323     }
324 
325     response->error = operation->Abort();
326     operation_table_->Delete(request.op_handle);
327 }
328 
ExportKey(const ExportKeyRequest & request,ExportKeyResponse * response)329 void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
330     if (response == NULL)
331         return;
332 
333     AuthorizationSet hw_enforced;
334     AuthorizationSet sw_enforced;
335     KeymasterKeyBlob key_material;
336     response->error =
337         context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
338                                &key_material, &hw_enforced, &sw_enforced);
339     if (response->error != KM_ERROR_OK)
340         return;
341 
342     keymaster_algorithm_t algorithm;
343     KeyFactory* key_factory =
344         GetKeyFactory(*context_, hw_enforced, sw_enforced, &algorithm, &response->error);
345     if (!key_factory)
346         return;
347 
348     UniquePtr<Key> key;
349     response->error = key_factory->LoadKey(key_material, hw_enforced, sw_enforced, &key);
350     if (response->error != KM_ERROR_OK)
351         return;
352 
353     UniquePtr<uint8_t[]> out_key;
354     size_t size;
355     response->error = key->formatted_key_material(request.key_format, &out_key, &size);
356     if (response->error == KM_ERROR_OK) {
357         response->key_data = out_key.release();
358         response->key_data_length = size;
359     }
360 }
361 
ImportKey(const ImportKeyRequest & request,ImportKeyResponse * response)362 void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
363     if (response == NULL)
364         return;
365 
366     keymaster_algorithm_t algorithm;
367     KeyFactory* factory = 0;
368     UniquePtr<Key> key;
369     if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
370         !(factory = context_->GetKeyFactory(algorithm)))
371         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
372     else {
373         keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
374         KeymasterKeyBlob key_blob;
375         response->error = factory->ImportKey(request.key_description, request.key_format,
376                                              KeymasterKeyBlob(key_material), &key_blob,
377                                              &response->enforced, &response->unenforced);
378         if (response->error == KM_ERROR_OK)
379             response->key_blob = key_blob.release();
380     }
381 }
382 
DeleteKey(const DeleteKeyRequest & request,DeleteKeyResponse * response)383 void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
384     if (!response)
385         return;
386     response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
387 }
388 
DeleteAllKeys(const DeleteAllKeysRequest &,DeleteAllKeysResponse * response)389 void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
390     if (!response)
391         return;
392     response->error = context_->DeleteAllKeys();
393 }
394 
LoadKey(const keymaster_key_blob_t & key_blob,const AuthorizationSet & additional_params,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,const KeyFactory ** factory,UniquePtr<Key> * key)395 keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
396                                             const AuthorizationSet& additional_params,
397                                             AuthorizationSet* hw_enforced,
398                                             AuthorizationSet* sw_enforced,
399                                             const KeyFactory** factory, UniquePtr<Key>* key) {
400     KeymasterKeyBlob key_material;
401     keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
402                                                      &key_material, hw_enforced, sw_enforced);
403     if (error != KM_ERROR_OK)
404         return error;
405 
406     keymaster_algorithm_t algorithm;
407     *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
408     if (error != KM_ERROR_OK)
409         return error;
410 
411     return (*factory)->LoadKey(key_material, *hw_enforced, *sw_enforced, key);
412 }
413 
414 }  // namespace keymaster
415