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 45 AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size) 46 : context_(context), operation_table_(new OperationTable(operation_table_size)) {} 47 48 AndroidKeymaster::~AndroidKeymaster() {} 49 50 struct AE_CTX_Delete { 51 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> 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 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 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> 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 117 void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request, 118 SupportedBlockModesResponse* response) { 119 GetSupported(*context_, request.algorithm, request.purpose, 120 &OperationFactory::SupportedBlockModes, response); 121 } 122 123 void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request, 124 SupportedPaddingModesResponse* response) { 125 GetSupported(*context_, request.algorithm, request.purpose, 126 &OperationFactory::SupportedPaddingModes, response); 127 } 128 129 void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request, 130 SupportedDigestsResponse* response) { 131 GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests, 132 response); 133 } 134 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 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 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 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 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 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 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 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 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 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 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 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 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 389 void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) { 390 if (!response) 391 return; 392 response->error = context_->DeleteAllKeys(); 393 } 394 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