Add authorization enforcement to AndroidKeymaster.
Note: Moving List.h into system/keymaster is unfortunate, but required
to allow Trusty to use it. b/22088154 tracks cleaning this up.
Bug: 19511945
Change-Id: Ia1dfe5fda5ea78935611b0a7656b323770edcbae
diff --git a/android_keymaster.cpp b/android_keymaster.cpp
index 7ebc8de..2bc6ea7 100644
--- a/android_keymaster.cpp
+++ b/android_keymaster.cpp
@@ -234,21 +234,30 @@
if (!factory)
return;
- response->error = KM_ERROR_INCOMPATIBLE_PURPOSE;
- if (!key->authorizations().Contains(TAG_PURPOSE, request.purpose) &&
- !factory->is_public_key_operation())
- return;
-
UniquePtr<Operation> operation(
factory->CreateOperation(*key, request.additional_params, &response->error));
if (operation.get() == NULL)
return;
+ if (context_->enforcement_policy()) {
+ km_id_t key_id;
+ response->error = KM_ERROR_UNKNOWN_ERROR;
+ if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id))
+ return;
+ operation->set_key_id(key_id);
+ response->error = context_->enforcement_policy()->AuthorizeOperation(
+ request.purpose, key_id, key->authorizations(), request.additional_params,
+ 0 /* op_handle */, true /* is_begin_operation */);
+ if (response->error != KM_ERROR_OK)
+ return;
+ }
+
response->output_params.Clear();
response->error = operation->Begin(request.additional_params, &response->output_params);
if (response->error != KM_ERROR_OK)
return;
+ operation->SetAuthorizations(key->authorizations());
response->error = operation_table_->Add(operation.release(), &response->op_handle);
}
@@ -262,6 +271,14 @@
if (operation == NULL)
return;
+ if (context_->enforcement_policy()) {
+ response->error = context_->enforcement_policy()->AuthorizeOperation(
+ operation->purpose(), operation->key_id(), operation->authorizations(),
+ request.additional_params, request.op_handle, false /* is_begin_operation */);
+ if (response->error != KM_ERROR_OK)
+ return;
+ }
+
response->error =
operation->Update(request.additional_params, request.input, &response->output_params,
&response->output, &response->input_consumed);
@@ -281,6 +298,14 @@
if (operation == NULL)
return;
+ if (context_->enforcement_policy()) {
+ response->error = context_->enforcement_policy()->AuthorizeOperation(
+ operation->purpose(), operation->key_id(), operation->authorizations(),
+ request.additional_params, request.op_handle, false /* is_begin_operation */);
+ if (response->error != KM_ERROR_OK)
+ return;
+ }
+
response->error = operation->Finish(request.additional_params, request.signature,
&response->output_params, &response->output);
operation_table_->Delete(request.op_handle);