Merge "Don't call ERR_error_string in keymaster"
diff --git a/Android.bp b/Android.bp
index c3ab924..0cccde3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,12 +14,30 @@
// libkeymaster_messages contains just the code necessary to communicate with a
// AndroidKeymaster implementation, e.g. one running in TrustZone.
+cc_defaults {
+ name: "keymaster_defaults",
+ vendor_available: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wunused",
+ ],
+ clang: true,
+ clang_cflags: [
+ "-Wno-error=unused-const-variable",
+ "-Wno-error=unused-private-field",
+ "-Wimplicit-fallthrough",
+ // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
+ // Currently, if enabled, these flags will cause an internal error in Clang.
+ "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
+ ],
+ sanitize: {
+ integer_overflow: false,
+ },
+}
+
cc_library_shared {
name: "libkeymaster_messages",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
srcs: [
"android_keymaster/android_keymaster_messages.cpp",
"android_keymaster/android_keymaster_utils.cpp",
@@ -30,24 +48,19 @@
"android_keymaster/keymaster_stl.cpp",
],
header_libs: ["libhardware_headers"],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
+ defaults: ["keymaster_defaults" ],
+ clang_cflags: [
"-DKEYMASTER_NAME_TAGS",
],
stl: "none",
- clang: true,
- clang_cflags: [
- "-Wimplicit-fallthrough",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
export_include_dirs: ["include"],
- sanitize: {
- integer_overflow: false,
+ host_supported: true,
+ target: {
+ host: {
+ clang_cflags: [
+ "-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
+ ],
+ },
},
}
@@ -57,10 +70,6 @@
// the function-based keymaster HAL API to the message-based AndroidKeymaster API.
cc_library {
name: "libkeymaster_portable",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
srcs: [
"android_keymaster/android_keymaster.cpp",
"android_keymaster/android_keymaster_messages.cpp",
@@ -114,10 +123,8 @@
],
header_libs: ["libhardware_headers"],
export_header_lib_headers: ["libhardware_headers"],
+ defaults: ["keymaster_defaults" ],
cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
"-DBORINGSSL_NO_CXX",
],
// NOTE: libkeymaster_portable must run unchanged in the trusty runtime environment.
@@ -125,19 +132,14 @@
// weakly defines the subset of stl symbols required for this library to work
// and which are also available in the trusty context.
stl: "none",
- clang: true,
- clang_cflags: [
- "-Wno-error=unused-const-variable",
- "-Wno-error=unused-private-field",
- "-Wimplicit-fallthrough",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
+ host_supported: true,
export_include_dirs: ["include"],
- sanitize: {
- integer_overflow: false,
+ target: {
+ host: {
+ clang_cflags: [
+ "-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
+ ],
+ },
},
}
@@ -146,10 +148,6 @@
// not support the request.
cc_library {
name: "libsoftkeymasterdevice",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
srcs: [
"android_keymaster/keymaster_configuration.cpp",
"legacy_support/ec_keymaster0_key.cpp",
@@ -161,81 +159,88 @@
"legacy_support/rsa_keymaster1_key.cpp",
"legacy_support/rsa_keymaster1_operation.cpp",
"legacy_support/keymaster1_legacy_support.cpp",
- "contexts/soft_attestation_cert.cpp",
"contexts/soft_keymaster_context.cpp",
"contexts/pure_soft_keymaster_context.cpp",
"contexts/soft_keymaster_device.cpp",
"km_openssl/soft_keymaster_enforcement.cpp",
"contexts/soft_keymaster_logger.cpp",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- ],
- clang: true,
- clang_cflags: [
- "-Wno-error=unused-const-variable",
- "-Wno-error=unused-private-field",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
+ defaults: ["keymaster_defaults"],
shared_libs: [
"libkeymaster_messages",
"libkeymaster_portable",
+ "libsoft_attestation_cert",
"liblog",
"libbase",
"libcrypto",
"libcutils",
],
+ export_include_dirs: ["include"],
+}
+cc_library {
+ name: "libsoft_attestation_cert",
+ srcs: [
+ "contexts/soft_attestation_cert.cpp",
+ ],
+ defaults: ["keymaster_defaults"],
+ shared_libs: [
+ "libkeymaster_portable",
+ ],
+
+ host_supported: true,
export_include_dirs: ["include"],
}
cc_library {
name: "libpuresoftkeymasterdevice",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
srcs: [
"android_keymaster/keymaster_configuration.cpp",
- "contexts/soft_attestation_cert.cpp",
"contexts/pure_soft_keymaster_context.cpp",
"contexts/soft_keymaster_logger.cpp",
"km_openssl/soft_keymaster_enforcement.cpp",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- ],
- clang: true,
- clang_cflags: [
- "-Wno-error=unused-const-variable",
- "-Wno-error=unused-private-field",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
+ defaults: ["keymaster_defaults"],
shared_libs: [
"libkeymaster_messages",
"libkeymaster_portable",
+ "libsoft_attestation_cert",
"liblog",
"libcrypto",
"libcutils",
"libbase",
],
+ export_include_dirs: ["include"],
+}
+cc_library {
+ name: "libpuresoftkeymasterdevice_host",
+ srcs: [
+ "contexts/pure_soft_keymaster_context.cpp",
+ "contexts/soft_keymaster_logger.cpp",
+ "km_openssl/soft_keymaster_enforcement.cpp",
+ ],
+ defaults: ["keymaster_defaults"],
+ host_supported: true,
+ device_supported: false,
+ shared_libs: [
+ "libkeymaster_messages",
+ "libkeymaster_portable",
+ "libsoft_attestation_cert",
+ "liblog",
+ "libcrypto",
+ "libcutils",
+ "libbase",
+ ],
+ clang_cflags: [
+ "-DKEYMASTER_NAME_TAGS",
+ "-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
+ ],
export_include_dirs: ["include"],
}
cc_library_shared {
name: "libkeymaster3device",
- vendor: true,
srcs: [
"legacy_support/keymaster_passthrough_key.cpp",
"legacy_support/keymaster_passthrough_engine.cpp",
@@ -254,20 +259,7 @@
"legacy_support/rsa_keymaster1_key.cpp",
"legacy_support/rsa_keymaster1_operation.cpp",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- ],
- clang: true,
- clang_cflags: [
- "-Wno-error=unused-const-variable",
- "-Wno-error=unused-private-field",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
+ defaults: ["keymaster_defaults"],
shared_libs: [
"libkeymaster_messages",
"android.hardware.keymaster@3.0",
@@ -276,17 +268,16 @@
"libbase",
"libhidlbase",
"libkeymaster_portable",
- "libpuresoftkeymasterdevice",
"liblog",
+ "libpuresoftkeymasterdevice",
+ "libsoft_attestation_cert",
"libutils",
],
-
export_include_dirs: ["include", "ng/include"],
}
cc_library_shared {
name: "libkeymaster4",
- vendor_available: true,
srcs: [
"legacy_support/keymaster_passthrough_key.cpp",
"legacy_support/keymaster_passthrough_engine.cpp",
@@ -294,20 +285,7 @@
"ng/AndroidKeymaster4Device.cpp",
"android_keymaster/keymaster_configuration.cpp",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- ],
- clang: true,
- clang_cflags: [
- "-Wno-error=unused-const-variable",
- "-Wno-error=unused-private-field",
- // TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
- // Currently, if enabled, these flags will cause an internal error in Clang.
- "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp"
- ],
-
+ defaults: ["keymaster_defaults"],
shared_libs: [
"libkeymaster_messages",
"android.hardware.keymaster@4.0",
@@ -321,7 +299,32 @@
"libutils",
"libkeymaster4support",
],
+ export_include_dirs: ["ng/include"],
+}
+cc_library_shared {
+ name: "libkeymaster41",
+ vendor_available: true,
+ srcs: [
+ "ng/AndroidKeymaster41Device.cpp",
+ ],
+ defaults: ["keymaster_defaults"],
+ shared_libs: [
+ "android.hardware.keymaster@4.0",
+ "android.hardware.keymaster@4.1",
+ "libbase",
+ "libcrypto",
+ "libcutils",
+ "libhidlbase",
+ "libkeymaster4",
+ "libkeymaster4_1support",
+ "libkeymaster4support",
+ "libkeymaster_messages",
+ "libkeymaster_portable",
+ "liblog",
+ "libpuresoftkeymasterdevice",
+ "libutils",
+ ],
export_include_dirs: ["ng/include"],
}
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/Makefile b/Makefile
index 6d87e06..6b4aa54 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,6 @@
GTEST=$(BASE)/external/googletest/googletest
INCLUDES=$(foreach dir,$(SUBS),-I $(BASE)/$(dir)/include) \
- -I $(BASE)/libnativehelper/include/nativehelper \
-I $(GTEST)/include -isystem $(GTEST) -Iinclude -I$(BASE)/../boringssl/include
ifdef FORCE_32_BIT
@@ -42,8 +41,8 @@
CXXFLAGS +=-std=c++14 -fprofile-arcs -ftest-coverage
CFLAGS += -fprofile-arcs -ftest-coverage
else
-CC=$(BASE)/prebuilts/clang/host/linux-x86/clang-r353983d/bin/clang
-CXX=$(BASE)/prebuilts/clang/host/linux-x86/clang-r353983d/bin/clang++
+CC=$(BASE)/prebuilts/clang/host/linux-x86/clang-r370808/bin/clang
+CXX=$(BASE)/prebuilts/clang/host/linux-x86/clang-r370808/bin/clang++
CXXFLAGS +=-std=c++14 -DKEYMASTER_CLANG_TEST_BUILD
CFLAGS += -DKEYMASTER_CLANG_TEST_BUILD
endif
diff --git a/android_keymaster/android_keymaster.cpp b/android_keymaster/android_keymaster.cpp
index 195a797..045e04f 100644
--- a/android_keymaster/android_keymaster.cpp
+++ b/android_keymaster/android_keymaster.cpp
@@ -224,7 +224,11 @@
if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
!(factory = context_->GetKeyFactory(algorithm)))
response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
- else {
+ else if (context_->enforcement_policy() &&
+ request.key_description.GetTagValue(TAG_EARLY_BOOT_ONLY) &&
+ !context_->enforcement_policy()->in_early_boot()) {
+ response->error = KM_ERROR_EARLY_BOOT_ENDED;
+ } else {
KeymasterKeyBlob key_blob;
response->enforced.Clear();
response->unenforced.Clear();
@@ -529,4 +533,18 @@
}
}
+EarlyBootEndedResponse AndroidKeymaster::EarlyBootEnded() {
+ if (context_->enforcement_policy()) {
+ context_->enforcement_policy()->early_boot_ended();
+ }
+ return EarlyBootEndedResponse(KM_ERROR_OK);
+}
+
+DeviceLockedResponse AndroidKeymaster::DeviceLocked(const DeviceLockedRequest& request) {
+ if (context_->enforcement_policy()) {
+ context_->enforcement_policy()->device_locked(request.passwordOnly);
+ }
+ return DeviceLockedResponse(KM_ERROR_OK);
+}
+
} // namespace keymaster
diff --git a/android_keymaster/android_keymaster_utils.cpp b/android_keymaster/android_keymaster_utils.cpp
index 31fdbf3..fb45fc9 100644
--- a/android_keymaster/android_keymaster_utils.cpp
+++ b/android_keymaster/android_keymaster_utils.cpp
@@ -16,7 +16,7 @@
#include <keymaster/android_keymaster_utils.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/android_keymaster/authorization_set.cpp b/android_keymaster/authorization_set.cpp
index 8c09a12..e09b73c 100644
--- a/android_keymaster/authorization_set.cpp
+++ b/android_keymaster/authorization_set.cpp
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/logger.h>
diff --git a/android_keymaster/keymaster_enforcement.cpp b/android_keymaster/keymaster_enforcement.cpp
index dc533a0..bfaaf08 100644
--- a/android_keymaster/keymaster_enforcement.cpp
+++ b/android_keymaster/keymaster_enforcement.cpp
@@ -292,6 +292,22 @@
}
break;
+ case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
+ if (device_locked_at_ > 0) {
+ const hw_auth_token_t* auth_token;
+ uint32_t token_auth_type;
+ if (!GetAndValidateAuthToken(operation_params, &auth_token, &token_auth_type)) {
+ return KM_ERROR_DEVICE_LOCKED;
+ }
+
+ uint64_t token_timestamp_millis = ntoh(auth_token->timestamp);
+ if (token_timestamp_millis <= device_locked_at_ ||
+ (password_unlock_only_ && !(token_auth_type & HW_AUTH_PASSWORD))) {
+ return KM_ERROR_DEVICE_LOCKED;
+ }
+ }
+ break;
+
case KM_TAG_CALLER_NONCE:
caller_nonce_authorized_by_key = true;
break;
@@ -311,6 +327,7 @@
case KM_TAG_ATTESTATION_ID_MEID:
case KM_TAG_ATTESTATION_ID_MANUFACTURER:
case KM_TAG_ATTESTATION_ID_MODEL:
+ case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
return KM_ERROR_INVALID_KEY_BLOB;
/* Tags used for cryptographic parameters in keygen. Nothing to enforce. */
@@ -337,7 +354,9 @@
/* Informational tags. */
case KM_TAG_CREATION_DATETIME:
case KM_TAG_ORIGIN:
+ case KM_TAG_ROLLBACK_RESISTANCE:
case KM_TAG_ROLLBACK_RESISTANT:
+ case KM_TAG_USER_ID:
/* Tags handled when KM_TAG_USER_SECURE_ID is handled */
case KM_TAG_NO_AUTH_REQUIRED:
@@ -364,14 +383,13 @@
case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
break;
- /* TODO(bcyoung): This is currently handled in keystore, but may move to keymaster in the
- * future */
- case KM_TAG_USER_ID:
- case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
- break;
-
+ case KM_TAG_IDENTITY_CREDENTIAL_KEY:
case KM_TAG_BOOTLOADER_ONLY:
return KM_ERROR_INVALID_KEY_BLOB;
+
+ case KM_TAG_EARLY_BOOT_ONLY:
+ if (!in_early_boot()) return KM_ERROR_EARLY_BOOT_ENDED;
+ break;
}
}
@@ -398,7 +416,7 @@
if (update_access_count) {
if (!access_count_map_) {
- LOG_S("Usage-count limited keys tabel not allocated. Count-limited keys disabled", 0);
+ LOG_S("Usage-count limited keys table not allocated. Count-limited keys disabled", 0);
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
@@ -431,6 +449,38 @@
return key_access_count < max_uses;
}
+bool KeymasterEnforcement::GetAndValidateAuthToken(const AuthorizationSet& operation_params,
+ const hw_auth_token_t** auth_token,
+ uint32_t* token_auth_type) const {
+ keymaster_blob_t auth_token_blob;
+ if (!operation_params.GetTagValue(TAG_AUTH_TOKEN, &auth_token_blob)) {
+ LOG_E("Authentication required, but auth token not provided", 0);
+ return false;
+ }
+
+ if (auth_token_blob.data_length != sizeof(**auth_token)) {
+ LOG_E("Bug: Auth token is the wrong size (%d expected, %d found)", sizeof(hw_auth_token_t),
+ auth_token_blob.data_length);
+ return false;
+ }
+
+ *auth_token = reinterpret_cast<const hw_auth_token_t*>(auth_token_blob.data);
+ if ((*auth_token)->version != HW_AUTH_TOKEN_VERSION) {
+ LOG_E("Bug: Auth token is the version %d (or is not an auth token). Expected %d",
+ (*auth_token)->version, HW_AUTH_TOKEN_VERSION);
+ return false;
+ }
+
+ if (!ValidateTokenSignature(**auth_token)) {
+ LOG_E("Auth token signature invalid", 0);
+ return false;
+ }
+
+ *token_auth_type = ntoh((*auth_token)->authenticator_type);
+
+ return true;
+}
+
bool KeymasterEnforcement::AuthTokenMatches(const AuthProxy& auth_set,
const AuthorizationSet& operation_params,
const uint64_t user_secure_id,
@@ -440,39 +490,18 @@
assert(auth_type_index < static_cast<int>(auth_set.size()));
assert(auth_timeout_index < static_cast<int>(auth_set.size()));
- keymaster_blob_t auth_token_blob;
- if (!operation_params.GetTagValue(TAG_AUTH_TOKEN, &auth_token_blob)) {
- LOG_E("Authentication required, but auth token not provided", 0);
+ const hw_auth_token_t* auth_token;
+ uint32_t token_auth_type;
+ if (!GetAndValidateAuthToken(operation_params, &auth_token, &token_auth_type)) return false;
+
+ if (auth_timeout_index == -1 && op_handle && op_handle != auth_token->challenge) {
+ LOG_E("Auth token has the challenge %llu, need %llu", auth_token->challenge, op_handle);
return false;
}
- if (auth_token_blob.data_length != sizeof(hw_auth_token_t)) {
- LOG_E("Bug: Auth token is the wrong size (%d expected, %d found)", sizeof(hw_auth_token_t),
- auth_token_blob.data_length);
- return false;
- }
-
- hw_auth_token_t auth_token;
- memcpy(&auth_token, auth_token_blob.data, sizeof(hw_auth_token_t));
- if (auth_token.version != HW_AUTH_TOKEN_VERSION) {
- LOG_E("Bug: Auth token is the version %d (or is not an auth token). Expected %d",
- auth_token.version, HW_AUTH_TOKEN_VERSION);
- return false;
- }
-
- if (!ValidateTokenSignature(auth_token)) {
- LOG_E("Auth token signature invalid", 0);
- return false;
- }
-
- if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
- LOG_E("Auth token has the challenge %llu, need %llu", auth_token.challenge, op_handle);
- return false;
- }
-
- if (user_secure_id != auth_token.user_id && user_secure_id != auth_token.authenticator_id) {
- LOG_I("Auth token SIDs %llu and %llu do not match key SID %llu", auth_token.user_id,
- auth_token.authenticator_id, user_secure_id);
+ if (user_secure_id != auth_token->user_id && user_secure_id != auth_token->authenticator_id) {
+ LOG_I("Auth token SIDs %llu and %llu do not match key SID %llu", auth_token->user_id,
+ auth_token->authenticator_id, user_secure_id);
return false;
}
@@ -486,7 +515,6 @@
return false;
uint32_t key_auth_type_mask = auth_set[auth_type_index].integer;
- uint32_t token_auth_type = ntoh(auth_token.authenticator_type);
if ((key_auth_type_mask & token_auth_type) == 0) {
LOG_E("Key requires match of auth type mask 0%uo, but token contained 0%uo",
key_auth_type_mask, token_auth_type);
@@ -498,7 +526,7 @@
if (auth_set[auth_timeout_index].tag != KM_TAG_AUTH_TIMEOUT)
return false;
- if (auth_token_timed_out(auth_token, auth_set[auth_timeout_index].integer)) {
+ if (auth_token_timed_out(*auth_token, auth_set[auth_timeout_index].integer)) {
LOG_E("Auth token has timed out", 0);
return false;
}
diff --git a/android_keymaster/keymaster_stl.cpp b/android_keymaster/keymaster_stl.cpp
index 56296b4..5ca9ed5 100644
--- a/android_keymaster/keymaster_stl.cpp
+++ b/android_keymaster/keymaster_stl.cpp
@@ -15,7 +15,7 @@
** limitations under the License.
*/
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <stdlib.h>
namespace std {
@@ -24,10 +24,10 @@
extern const std::nothrow_t __attribute__((weak)) std::nothrow = {};
-void* __attribute__((weak)) operator new(size_t __sz, const std::nothrow_t&) {
+void* __attribute__((weak)) operator new(size_t __sz, const std::nothrow_t&) _NOEXCEPT {
return malloc(__sz);
}
-void* __attribute__((weak)) operator new[](size_t __sz, const std::nothrow_t&) {
+void* __attribute__((weak)) operator new[](size_t __sz, const std::nothrow_t&) _NOEXCEPT {
return malloc(__sz);
}
diff --git a/android_keymaster/keymaster_tags.cpp b/android_keymaster/keymaster_tags.cpp
index b26d0ee..a92698d 100644
--- a/android_keymaster/keymaster_tags.cpp
+++ b/android_keymaster/keymaster_tags.cpp
@@ -77,6 +77,8 @@
return "KM_TAG_CREATION_DATETIME";
case KM_TAG_ORIGIN:
return "KM_TAG_ORIGIN";
+ case KM_TAG_ROLLBACK_RESISTANCE:
+ return "KM_TAG_ROLLBACK_RESISTANCE";
case KM_TAG_ROLLBACK_RESISTANT:
return "KM_TAG_ROLLBACK_RESISTANT";
case KM_TAG_ROOT_OF_TRUST:
@@ -133,6 +135,12 @@
return "KM_TAG_ATTESTATION_ID_MANUFACTURER";
case KM_TAG_ATTESTATION_ID_MODEL:
return "KM_TAG_ATTESTATION_ID_MODEL";
+ case KM_TAG_EARLY_BOOT_ONLY:
+ return "KM_TAG_EARLY_BOOT_ONLY";
+ case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
+ return "KM_TAG_DEVICE_UNIQUE_ATTESTATION";
+ case KM_TAG_IDENTITY_CREDENTIAL_KEY:
+ return "KM_TAG_IDENTITY_CREDENTIAL_KEY";
}
return "<Unknown>";
}
@@ -164,6 +172,7 @@
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA);
DEFINE_KEYMASTER_TAG(KM_DATE, TAG_CREATION_DATETIME);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANCE);
DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANT);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ROOT_OF_TRUST);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ASSOCIATED_DATA);
@@ -184,6 +193,9 @@
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MODEL);
DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_UNLOCKED_DEVICE_REQUIRED);
DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_TRUSTED_CONFIRMATION_REQUIRED);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_EARLY_BOOT_ONLY);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_DEVICE_UNIQUE_ATTESTATION);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_IDENTITY_CREDENTIAL_KEY);
// DEFINE_KEYMASTER_ENUM_TAG is used to create TypedEnumTag instances for each enum keymaster tag.
diff --git a/android_keymaster/operation_table.cpp b/android_keymaster/operation_table.cpp
index 2e630c8..ff9d2bb 100644
--- a/android_keymaster/operation_table.cpp
+++ b/android_keymaster/operation_table.cpp
@@ -18,7 +18,7 @@
#include <keymaster/operation.h>
#include <keymaster/android_keymaster_utils.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/android_keymaster/serializable.cpp b/android_keymaster/serializable.cpp
index 794cdb1..1f795e2 100644
--- a/android_keymaster/serializable.cpp
+++ b/android_keymaster/serializable.cpp
@@ -18,7 +18,7 @@
#include <assert.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <keymaster/android_keymaster_utils.h>
diff --git a/contexts/keymaster1_passthrough_context.cpp b/contexts/keymaster1_passthrough_context.cpp
index dab8f37..f0fe65d 100644
--- a/contexts/keymaster1_passthrough_context.cpp
+++ b/contexts/keymaster1_passthrough_context.cpp
@@ -17,19 +17,19 @@
#include <keymaster/contexts/keymaster1_passthrough_context.h>
-#include <keymaster/legacy_support/keymaster_passthrough_key.h>
-#include <keymaster/legacy_support/keymaster_passthrough_engine.h>
-#include <keymaster/legacy_support/keymaster1_legacy_support.h>
-#include <keymaster/legacy_support/keymaster1_engine.h>
-#include <keymaster/legacy_support/rsa_keymaster1_key.h>
-#include <keymaster/legacy_support/ec_keymaster1_key.h>
-#include <keymaster/key_blob_utils/software_keyblobs.h>
+#include <keymaster/contexts/soft_attestation_cert.h>
#include <keymaster/key_blob_utils/integrity_assured_key_blob.h>
#include <keymaster/key_blob_utils/ocb_utils.h>
+#include <keymaster/key_blob_utils/software_keyblobs.h>
#include <keymaster/km_openssl/aes_key.h>
-#include <keymaster/km_openssl/hmac_key.h>
#include <keymaster/km_openssl/attestation_utils.h>
-#include "soft_attestation_cert.h"
+#include <keymaster/km_openssl/hmac_key.h>
+#include <keymaster/legacy_support/ec_keymaster1_key.h>
+#include <keymaster/legacy_support/keymaster1_engine.h>
+#include <keymaster/legacy_support/keymaster1_legacy_support.h>
+#include <keymaster/legacy_support/keymaster_passthrough_engine.h>
+#include <keymaster/legacy_support/keymaster_passthrough_key.h>
+#include <keymaster/legacy_support/rsa_keymaster1_key.h>
namespace keymaster {
diff --git a/contexts/pure_soft_keymaster_context.cpp b/contexts/pure_soft_keymaster_context.cpp
index b4d1fb7..33dc6dc 100644
--- a/contexts/pure_soft_keymaster_context.cpp
+++ b/contexts/pure_soft_keymaster_context.cpp
@@ -44,18 +44,18 @@
#include <keymaster/operation.h>
#include <keymaster/wrapped_key.h>
-#include "soft_attestation_cert.h"
+#include <keymaster/contexts/soft_attestation_cert.h>
using std::unique_ptr;
namespace keymaster {
-PureSoftKeymasterContext::PureSoftKeymasterContext()
+PureSoftKeymasterContext::PureSoftKeymasterContext(keymaster_security_level_t security_level)
: rsa_factory_(new RsaKeyFactory(this)), ec_factory_(new EcKeyFactory(this)),
aes_factory_(new AesKeyFactory(this, this)),
tdes_factory_(new TripleDesKeyFactory(this, this)),
hmac_factory_(new HmacKeyFactory(this, this)), os_version_(0), os_patchlevel_(0),
- soft_keymaster_enforcement_(64, 64) {}
+ soft_keymaster_enforcement_(64, 64), security_level_(security_level) {}
PureSoftKeymasterContext::~PureSoftKeymasterContext() {}
@@ -106,20 +106,58 @@
}
keymaster_error_t PureSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description,
- const keymaster_key_origin_t origin,
- const KeymasterKeyBlob& key_material,
- KeymasterKeyBlob* blob,
- AuthorizationSet* hw_enforced,
- AuthorizationSet* sw_enforced) const {
+ const keymaster_key_origin_t origin,
+ const KeymasterKeyBlob& key_material,
+ KeymasterKeyBlob* blob,
+ AuthorizationSet* hw_enforced,
+ AuthorizationSet* sw_enforced) const {
+ if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) {
+ return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE;
+ }
+
+ if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE) {
+ // We're pretending to be some sort of secure hardware. Put relevant tags in hw_enforced.
+ for (auto& entry : key_description) {
+ switch (entry.tag) {
+ case KM_TAG_PURPOSE:
+ case KM_TAG_ALGORITHM:
+ case KM_TAG_KEY_SIZE:
+ case KM_TAG_RSA_PUBLIC_EXPONENT:
+ case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+ case KM_TAG_DIGEST:
+ case KM_TAG_PADDING:
+ case KM_TAG_BLOCK_MODE:
+ case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+ case KM_TAG_MAX_USES_PER_BOOT:
+ case KM_TAG_USER_SECURE_ID:
+ case KM_TAG_NO_AUTH_REQUIRED:
+ case KM_TAG_AUTH_TIMEOUT:
+ case KM_TAG_CALLER_NONCE:
+ case KM_TAG_MIN_MAC_LENGTH:
+ case KM_TAG_KDF:
+ case KM_TAG_EC_CURVE:
+ case KM_TAG_ECIES_SINGLE_HASH_MODE:
+ case KM_TAG_USER_AUTH_TYPE:
+ case KM_TAG_ORIGIN:
+ case KM_TAG_OS_VERSION:
+ case KM_TAG_OS_PATCHLEVEL:
+ case KM_TAG_EARLY_BOOT_ONLY:
+ case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
+ hw_enforced->push_back(entry);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_,
os_patchlevel_, hw_enforced, sw_enforced);
- if (error != KM_ERROR_OK)
- return error;
+ if (error != KM_ERROR_OK) return error;
AuthorizationSet hidden;
error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust);
- if (error != KM_ERROR_OK)
- return error;
+ if (error != KM_ERROR_OK) return error;
return SerializeIntegrityAssuredBlob(key_material, hidden, *hw_enforced, *sw_enforced, blob);
}
@@ -281,7 +319,7 @@
UniquePtr<Key> key;
auto wrapping_key_params = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
- .Digest(KM_DIGEST_SHA1)
+ .Digest(KM_DIGEST_SHA_2_256)
.Padding(KM_PAD_RSA_OAEP)
.Authorization(TAG_PURPOSE, KM_PURPOSE_WRAP)
.build();
@@ -406,4 +444,16 @@
return error;
}
+keymaster_error_t PureSoftKeymasterContext::GetVerifiedBootParams(
+ keymaster_blob_t* verified_boot_key, keymaster_blob_t* verified_boot_hash,
+ keymaster_verified_boot_t* verified_boot_state, bool* device_locked) const {
+ // TODO(swillden): See if there might be some sort of vbmeta data in goldfish/cuttlefish.
+ static std::string fake_vb_key(32, 0);
+ *verified_boot_key = {reinterpret_cast<uint8_t*>(fake_vb_key.data()), fake_vb_key.size()};
+ *verified_boot_hash = {reinterpret_cast<uint8_t*>(fake_vb_key.data()), fake_vb_key.size()};
+ *verified_boot_state = KM_VERIFIED_BOOT_UNVERIFIED;
+ *device_locked = false;
+ return KM_ERROR_OK;
+}
+
} // namespace keymaster
diff --git a/contexts/soft_attestation_cert.cpp b/contexts/soft_attestation_cert.cpp
index cc9d104..c9142e3 100644
--- a/contexts/soft_attestation_cert.cpp
+++ b/contexts/soft_attestation_cert.cpp
@@ -15,12 +15,11 @@
** limitations under the License.
*/
-#include "soft_attestation_cert.h"
+#include <keymaster/contexts/soft_attestation_cert.h>
#include <stdint.h>
#include <hardware/keymaster_defs.h>
#include <keymaster/android_keymaster_utils.h>
-#include <openssl/aes.h>
namespace keymaster {
diff --git a/contexts/soft_keymaster_context.cpp b/contexts/soft_keymaster_context.cpp
index a0a42d3..5003c72 100644
--- a/contexts/soft_keymaster_context.cpp
+++ b/contexts/soft_keymaster_context.cpp
@@ -38,7 +38,7 @@
#include <keymaster/legacy_support/rsa_keymaster1_key.h>
#include <keymaster/logger.h>
-#include "soft_attestation_cert.h"
+#include <keymaster/contexts/soft_attestation_cert.h>
using std::unique_ptr;
@@ -476,4 +476,16 @@
return KM_ERROR_UNIMPLEMENTED;
}
+keymaster_error_t SoftKeymasterContext::GetVerifiedBootParams(
+ keymaster_blob_t* verified_boot_key, keymaster_blob_t* verified_boot_hash,
+ keymaster_verified_boot_t* verified_boot_state, bool* device_locked) const {
+ // TODO(swillden): See if there might be some sort of vbmeta data in goldfish/cuttlefish.
+ static std::string fake_vb_key(32, 0);
+ *verified_boot_key = {reinterpret_cast<uint8_t*>(fake_vb_key.data()), fake_vb_key.size()};
+ *verified_boot_hash = {reinterpret_cast<uint8_t*>(fake_vb_key.data()), fake_vb_key.size()};
+ *verified_boot_state = KM_VERIFIED_BOOT_UNVERIFIED;
+ *device_locked = false;
+ return KM_ERROR_OK;
+}
+
} // namespace keymaster
diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h
index 2836464..383c9da 100644
--- a/include/keymaster/android_keymaster.h
+++ b/include/keymaster/android_keymaster.h
@@ -87,6 +87,9 @@
void FinishOperation(const FinishOperationRequest& request, FinishOperationResponse* response);
void AbortOperation(const AbortOperationRequest& request, AbortOperationResponse* response);
+ EarlyBootEndedResponse EarlyBootEnded();
+ DeviceLockedResponse DeviceLocked(const DeviceLockedRequest& request);
+
bool has_operation(keymaster_operation_handle_t op_handle) const;
private:
diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h
index 116dfc2..4dbabd7 100644
--- a/include/keymaster/android_keymaster_messages.h
+++ b/include/keymaster/android_keymaster_messages.h
@@ -55,6 +55,8 @@
DELETE_ALL_KEYS = 23,
DESTROY_ATTESTATION_IDS = 24,
IMPORT_WRAPPED_KEY = 25,
+ EARLY_BOOT_ENDED = 26,
+ DEVICE_LOCKED = 27,
};
/**
@@ -423,6 +425,10 @@
struct AbortOperationResponse : public KeymasterResponse {
explicit AbortOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+ explicit AbortOperationResponse(keymaster_error_t error_, int32_t ver = MAX_MESSAGE_VERSION)
+ : KeymasterResponse(ver) {
+ error = error_;
+ }
size_t NonErrorSerializedSize() const override { return 0; }
uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t*) const override { return buf; }
@@ -902,6 +908,31 @@
VerificationToken token;
};
+// These return nothing but an error code, like AbortOperationResponse so might as well use that.
+using EarlyBootEndedResponse = AbortOperationResponse;
+using DeviceLockedResponse = AbortOperationResponse;
+
+struct DeviceLockedRequest : public KeymasterMessage {
+ explicit DeviceLockedRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+ explicit DeviceLockedRequest(bool passwordOnly_, VerificationToken&& token_,
+ int32_t ver = MAX_MESSAGE_VERSION)
+ : KeymasterMessage(ver), passwordOnly(passwordOnly_), token(move(token_)) {}
+
+ size_t SerializedSize() const override { return 1; }
+ uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+ if (buf < end) *buf++ = passwordOnly ? 1 : 0;
+ return token.Serialize(buf, end);
+ }
+ bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+ if (*buf_ptr >= end) return false;
+ passwordOnly = !!*(*buf_ptr)++;
+ return token.Deserialize(buf_ptr, end);
+ }
+
+ bool passwordOnly;
+ VerificationToken token;
+};
+
} // namespace keymaster
#endif // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_MESSAGES_H_
diff --git a/include/keymaster/attestation_record.h b/include/keymaster/attestation_record.h
index 1f662d6..17a6429 100644
--- a/include/keymaster/attestation_record.h
+++ b/include/keymaster/attestation_record.h
@@ -25,6 +25,8 @@
namespace keymaster {
+constexpr uint kCurrentKeymasterVersion = 41;
+
struct stack_st_ASN1_TYPE_Delete {
void operator()(stack_st_ASN1_TYPE* p) { sk_ASN1_TYPE_free(p); }
};
@@ -41,7 +43,7 @@
typedef struct km_root_of_trust {
ASN1_OCTET_STRING* verified_boot_key;
- ASN1_BOOLEAN* device_locked;
+ ASN1_BOOLEAN device_locked;
ASN1_ENUMERATED* verified_boot_state;
ASN1_OCTET_STRING* verified_boot_hash;
} KM_ROOT_OF_TRUST;
@@ -79,6 +81,7 @@
ASN1_OCTET_STRING* application_id;
ASN1_INTEGER* creation_date_time;
ASN1_INTEGER* origin;
+ ASN1_NULL* rollback_resistance;
ASN1_NULL* rollback_resistant;
KM_ROOT_OF_TRUST* root_of_trust;
ASN1_INTEGER* os_version;
@@ -92,6 +95,9 @@
ASN1_OCTET_STRING* attestation_id_meid;
ASN1_OCTET_STRING* attestation_id_manufacturer;
ASN1_OCTET_STRING* attestation_id_model;
+ ASN1_NULL* early_boot_only;
+ ASN1_NULL* device_unique_attestation;
+ ASN1_NULL* identity_credential_key;
} KM_AUTH_LIST;
ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -124,6 +130,8 @@
ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER,
TAG_CREATION_DATETIME.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.masked_tag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
+ TAG_ROLLBACK_RESISTANCE.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistant, ASN1_NULL, TAG_ROLLBACK_RESISTANT.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.masked_tag()),
@@ -146,6 +154,11 @@
TAG_ATTESTATION_ID_MANUFACTURER.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MODEL.masked_tag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.masked_tag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL,
+ TAG_DEVICE_UNIQUE_ATTESTATION.masked_tag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential_key, ASN1_NULL,
+ TAG_IDENTITY_CREDENTIAL_KEY.masked_tag()),
} ASN1_SEQUENCE_END(KM_AUTH_LIST);
DECLARE_ASN1_FUNCTIONS(KM_AUTH_LIST);
@@ -215,6 +228,7 @@
*/
virtual keymaster_error_t
GetVerifiedBootParams(keymaster_blob_t* /* verified_boot_key */,
+ keymaster_blob_t* /* verified_boot_hash */,
keymaster_verified_boot_t* /* verified_boot_state */,
bool* /* device_locked */) const {
return KM_ERROR_UNIMPLEMENTED;
@@ -237,6 +251,8 @@
*/
static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17";
+// This build_attestation_record sets the keymaster version to the default
+// value.
keymaster_error_t build_attestation_record(const AuthorizationSet& attestation_params,
AuthorizationSet software_enforced,
AuthorizationSet tee_enforced,
@@ -244,6 +260,14 @@
UniquePtr<uint8_t[]>* asn1_key_desc,
size_t* asn1_key_desc_len);
+// Builds attestation record, same as above, except this allows the keymaster
+// version to be set to different value than the default.
+keymaster_error_t
+build_attestation_record(const AuthorizationSet& attestation_params, AuthorizationSet sw_enforced,
+ AuthorizationSet tee_enforced, const AttestationRecordContext& context,
+ const uint keymaster_version, UniquePtr<uint8_t[]>* asn1_key_desc,
+ size_t* asn1_key_desc_len);
+
/**
* Helper functions for attestation record tests. Caller takes ownership of
* |attestation_challenge->data| and |unique_id->data|, deallocate using delete[].
diff --git a/include/keymaster/authorization_set.h b/include/keymaster/authorization_set.h
index 11ffc30..b4a3b27 100644
--- a/include/keymaster/authorization_set.h
+++ b/include/keymaster/authorization_set.h
@@ -82,6 +82,9 @@
explicit AuthorizationSet(/* NOT const */ AuthorizationSetBuilder& builder);
// Copy constructor.
+ // A copy constructor normal should call a base class copy constructor,
+ // but Serializable is special without copy constructor.
+ // NOLINTNEXTLINE(bugprone-copy-constructor-init)
AuthorizationSet(const AuthorizationSet& set)
: Serializable(), elems_capacity_(0), indirect_data_(nullptr), indirect_data_size_(0),
indirect_data_capacity_(0), error_(OK) {
diff --git a/include/keymaster/contexts/pure_soft_keymaster_context.h b/include/keymaster/contexts/pure_soft_keymaster_context.h
index 3a1156d..66a7b49 100644
--- a/include/keymaster/contexts/pure_soft_keymaster_context.h
+++ b/include/keymaster/contexts/pure_soft_keymaster_context.h
@@ -38,12 +38,14 @@
/**
* SoftKeymasterContext provides the context for a non-secure implementation of AndroidKeymaster.
*/
-class PureSoftKeymasterContext: public KeymasterContext,
- protected SoftwareKeyBlobMaker,
- AttestationRecordContext,
- SoftwareRandomSource {
+class PureSoftKeymasterContext : public KeymasterContext,
+ protected SoftwareKeyBlobMaker,
+ public AttestationRecordContext,
+ SoftwareRandomSource {
public:
- explicit PureSoftKeymasterContext();
+ // Security level must only be used for testing.
+ explicit PureSoftKeymasterContext(
+ keymaster_security_level_t security_level = KM_SECURITY_LEVEL_SOFTWARE);
~PureSoftKeymasterContext() override;
/*********************************************************************************************
@@ -90,6 +92,17 @@
AuthorizationSet* wrapped_key_params, keymaster_key_format_t* wrapped_key_format,
KeymasterKeyBlob* wrapped_key_material) const override;
+ /*********************************************************************************************
+ * Implement AttestationRecordContext
+ */
+
+ keymaster_error_t GetVerifiedBootParams(keymaster_blob_t* verified_boot_key,
+ keymaster_blob_t* verified_boot_hash,
+ keymaster_verified_boot_t* verified_boot_state,
+ bool* device_locked) const override;
+
+ keymaster_security_level_t GetSecurityLevel() const override { return security_level_; }
+
protected:
std::unique_ptr<KeyFactory> rsa_factory_;
std::unique_ptr<KeyFactory> ec_factory_;
@@ -99,6 +112,7 @@
uint32_t os_version_;
uint32_t os_patchlevel_;
SoftKeymasterEnforcement soft_keymaster_enforcement_;
+ keymaster_security_level_t security_level_;
};
} // namespace keymaster
diff --git a/contexts/soft_attestation_cert.h b/include/keymaster/contexts/soft_attestation_cert.h
similarity index 97%
rename from contexts/soft_attestation_cert.h
rename to include/keymaster/contexts/soft_attestation_cert.h
index a508ff8..597c90b 100644
--- a/contexts/soft_attestation_cert.h
+++ b/include/keymaster/contexts/soft_attestation_cert.h
@@ -27,5 +27,5 @@
const keymaster_cert_chain_t* getAttestationChain(keymaster_algorithm_t algorithm,
keymaster_error_t* error);
-}
+} // namespace keymaster
#endif // SOFTWARE_CONTEXT_SOFT_ATTESTATION_CERT_H_
diff --git a/include/keymaster/contexts/soft_keymaster_context.h b/include/keymaster/contexts/soft_keymaster_context.h
index 588e3db..20a10ac 100644
--- a/include/keymaster/contexts/soft_keymaster_context.h
+++ b/include/keymaster/contexts/soft_keymaster_context.h
@@ -104,6 +104,15 @@
AuthorizationSet* sw_enforced) const override;
/*********************************************************************************************/
+ /*********************************************************************************************
+ * Implement AttestationRecordContext
+ */
+
+ keymaster_error_t GetVerifiedBootParams(keymaster_blob_t* verified_boot_key,
+ keymaster_blob_t* verified_boot_hash,
+ keymaster_verified_boot_t* verified_boot_state,
+ bool* device_locked) const override;
+
private:
keymaster_error_t ParseKeymaster1HwBlob(const KeymasterKeyBlob& blob,
const AuthorizationSet& additional_params,
diff --git a/include/keymaster/keymaster_enforcement.h b/include/keymaster/keymaster_enforcement.h
index 4e33aff..8aa9984 100644
--- a/include/keymaster/keymaster_enforcement.h
+++ b/include/keymaster/keymaster_enforcement.h
@@ -133,6 +133,11 @@
virtual uint64_t get_current_time_ms() const = 0;
/*
+ * Get whether or not we're in early boot. See early_boot_ended() below.
+ */
+ bool in_early_boot() const { return in_early_boot_; }
+
+ /*
* Get current time in seconds from some starting point. This value is used to compute relative
* times between events. It must be monotonically increasing, and must not skip or lag. It
* need not have any relation to any external time standard (other than the duration of
@@ -179,6 +184,22 @@
*/
virtual bool CreateKeyId(const keymaster_key_blob_t& key_blob, km_id_t* keyid) const = 0;
+ /*
+ * Inform the KeymasterEnforcement object that early boot stage has ended.
+ */
+ void early_boot_ended() { in_early_boot_ = false; }
+
+ /*
+ * Inform the KeymasterEnforcement object that the device is locked, so it knows not to permit
+ * UNLOCKED_DEVICE_REQUIRED keys to be used until a fresh (later than "now") auth token is
+ * provided. If password_only is true, the fresh auth token must additionally be a password
+ * auth token.
+ */
+ void device_locked(bool password_only) {
+ device_locked_at_ = get_current_time_ms();
+ password_unlock_only_ = password_only;
+ }
+
private:
keymaster_error_t AuthorizeUpdateOrFinish(const AuthProxy& auth_set,
const AuthorizationSet& operation_params,
@@ -186,6 +207,8 @@
bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
+ bool GetAndValidateAuthToken(const AuthorizationSet& operation_params,
+ const hw_auth_token_t** token, uint32_t* token_auth_type) const;
bool AuthTokenMatches(const AuthProxy& auth_set, const AuthorizationSet& operation_params,
const uint64_t user_secure_id, const int auth_type_index,
const int auth_timeout_index,
@@ -194,6 +217,9 @@
AccessTimeMap* access_time_map_;
AccessCountMap* access_count_map_;
+ bool in_early_boot_ = false; // TODO(swillden): default to true when vold sends signal.
+ uint64_t device_locked_at_ = 0;
+ bool password_unlock_only_ = false;
};
}; /* namespace keymaster */
diff --git a/include/keymaster/keymaster_tags.h b/include/keymaster/keymaster_tags.h
index daa7b19..321e92f 100644
--- a/include/keymaster/keymaster_tags.h
+++ b/include/keymaster/keymaster_tags.h
@@ -159,6 +159,7 @@
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA);
DECLARE_KEYMASTER_TAG(KM_DATE, TAG_CREATION_DATETIME);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANCE);
DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANT);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ROOT_OF_TRUST);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ASSOCIATED_DATA);
@@ -179,6 +180,9 @@
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MEID);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MANUFACTURER);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MODEL);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_EARLY_BOOT_ONLY);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_DEVICE_UNIQUE_ATTESTATION);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_IDENTITY_CREDENTIAL_KEY);
// DECLARE_KEYMASTER_ENUM_TAG is used to declare TypedEnumTag instances for each enum keymaster tag.
#define DECLARE_KEYMASTER_ENUM_TAG(type, name, enumtype) \
diff --git a/include/keymaster/km_openssl/attestation_utils.h b/include/keymaster/km_openssl/attestation_utils.h
index 063fb2c..e30d90f 100644
--- a/include/keymaster/km_openssl/attestation_utils.h
+++ b/include/keymaster/km_openssl/attestation_utils.h
@@ -31,12 +31,39 @@
class AttestationRecordContext;
class AsymmetricKey;
-
+// Generate attestation certificate base on the AsymmetricKey key and other parameters
+// passed in. In attest_params, we expect the challenge, active time and expiration
+// time, and app id.
+//
+// The active time and expiration time are expected in milliseconds.
+//
+// Hardware and software enforced AuthorizationSet are expected to be built into the AsymmetricKey
+// input. In hardware enforced AuthorizationSet, we expect hardware related tags such as
+// TAG_IDENTITY_CREDENTIAL_KEY.
keymaster_error_t generate_attestation(const AsymmetricKey& key,
const AuthorizationSet& attest_params, const keymaster_cert_chain_t& attestation_chain,
const keymaster_key_blob_t& attestation_signing_key,
const AttestationRecordContext& context, CertChainPtr* cert_chain_out);
+// Generate attestation certificate based on the EVP key and other parameters
+// passed in. Note that due to sub sub sub call setup, there are 3 AuthorizationSet passed in,
+// hardware, software, and general. In attest_params, we expect the challenge,
+// active time and expiration time, and app id. In hw_enforced, we expect
+// hardware related tags such as TAG_IDENTITY_CREDENTIAL_KEY.
+//
+// The active time and expiration time are expected in milliseconds since Jan 1,
+// 1970.
+keymaster_error_t generate_attestation_from_EVP(
+ const EVP_PKEY* evp_key, // input
+ const AuthorizationSet& sw_enforced, // input
+ const AuthorizationSet& hw_enforced, // input
+ const AuthorizationSet& attest_params, // input. Sub function require app id to be set here.
+ const AttestationRecordContext& context, // input
+ const uint keymaster_version, // input
+ const keymaster_cert_chain_t& attestation_chain, // input
+ const keymaster_key_blob_t& attestation_signing_key, // input
+ CertChainPtr* cert_chain_out); // Output.
+
} // namespace keymaster
#endif // KM_OPENSSL_ATTESTATION_UTILS_H_
diff --git a/include/keymaster/new b/include/keymaster/new.h
similarity index 97%
rename from include/keymaster/new
rename to include/keymaster/new.h
index b4786db..17537e0 100644
--- a/include/keymaster/new
+++ b/include/keymaster/new.h
@@ -23,7 +23,7 @@
namespace std {
struct nothrow_t;
extern const nothrow_t nothrow;
-}
+} // namespace std
#ifndef _NOEXCEPT
#define _NOEXCEPT
diff --git a/include/keymaster/serializable.h b/include/keymaster/serializable.h
index 9f69f44..575b691 100644
--- a/include/keymaster/serializable.h
+++ b/include/keymaster/serializable.h
@@ -21,8 +21,8 @@
#include <stdlib.h>
#include <string.h>
+#include <keymaster/new.h>
#include <stddef.h>
-#include <keymaster/new>
// #include <new>
#include <keymaster/UniquePtr.h>
diff --git a/key_blob_utils/integrity_assured_key_blob.cpp b/key_blob_utils/integrity_assured_key_blob.cpp
index 35b5390..014855e 100644
--- a/key_blob_utils/integrity_assured_key_blob.cpp
+++ b/key_blob_utils/integrity_assured_key_blob.cpp
@@ -24,8 +24,7 @@
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/authorization_set.h>
#include <keymaster/km_openssl/openssl_err.h>
-#include <keymaster/new>
-
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/key_blob_utils/ocb_utils.cpp b/key_blob_utils/ocb_utils.cpp
index 409029c..d58d2df 100644
--- a/key_blob_utils/ocb_utils.cpp
+++ b/key_blob_utils/ocb_utils.cpp
@@ -23,11 +23,10 @@
#include <hardware/keymaster_defs.h>
-#include <keymaster/authorization_set.h>
#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
#include <keymaster/km_openssl/openssl_err.h>
-#include <keymaster/new>
-
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/key_blob_utils/software_keyblobs.cpp b/key_blob_utils/software_keyblobs.cpp
index c490631..60719bb 100644
--- a/key_blob_utils/software_keyblobs.cpp
+++ b/key_blob_utils/software_keyblobs.cpp
@@ -292,10 +292,16 @@
}
}
- sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(nullptr)));
- sw_enforced->push_back(TAG_ORIGIN, origin);
- sw_enforced->push_back(TAG_OS_VERSION, os_version);
- sw_enforced->push_back(TAG_OS_PATCHLEVEL, os_patchlevel);
+ // If hw_enforced is non-empty, we're pretending to be some sort of secure hardware.
+ AuthorizationSet* pseudo_hw_enforced = (hw_enforced->empty()) ? sw_enforced : hw_enforced;
+ pseudo_hw_enforced->push_back(TAG_ORIGIN, origin);
+ pseudo_hw_enforced->push_back(TAG_OS_VERSION, os_version);
+ pseudo_hw_enforced->push_back(TAG_OS_PATCHLEVEL, os_patchlevel);
+
+ // Honor caller creation, if provided.
+ if (!sw_enforced->Contains(TAG_CREATION_DATETIME)) {
+ sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(nullptr)));
+ }
return TranslateAuthorizationSetError(sw_enforced->is_valid());
}
diff --git a/km_openssl/aes_key.cpp b/km_openssl/aes_key.cpp
index 5bb6a24..0e1a756 100644
--- a/km_openssl/aes_key.cpp
+++ b/km_openssl/aes_key.cpp
@@ -18,7 +18,7 @@
#include <assert.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <openssl/err.h>
#include <openssl/rand.h>
diff --git a/km_openssl/asymmetric_key.cpp b/km_openssl/asymmetric_key.cpp
index 7e459a0..511e43a 100644
--- a/km_openssl/asymmetric_key.cpp
+++ b/km_openssl/asymmetric_key.cpp
@@ -16,7 +16,7 @@
#include <keymaster/km_openssl/asymmetric_key.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <openssl/asn1.h>
#include <openssl/stack.h>
diff --git a/km_openssl/attestation_record.cpp b/km_openssl/attestation_record.cpp
index 35114ca..4f70138 100644
--- a/km_openssl/attestation_record.cpp
+++ b/km_openssl/attestation_record.cpp
@@ -26,8 +26,7 @@
namespace keymaster {
-constexpr uint kCurrentKeymasterVersion = 4;
-constexpr uint kCurrentAttestationVersion = 3;
+constexpr uint kCurrentAttestationVersion = 4;
constexpr size_t kMaximumAttestationChallengeLength = 128;
IMPLEMENT_ASN1_FUNCTIONS(KM_ROOT_OF_TRUST);
@@ -53,6 +52,10 @@
void operator()(KM_KEY_DESCRIPTION* p) { KM_KEY_DESCRIPTION_free(p); }
};
+struct KM_ROOT_OF_TRUST_Delete {
+ void operator()(KM_ROOT_OF_TRUST* p) { KM_ROOT_OF_TRUST_free(p); }
+};
+
static uint32_t get_uint32_value(const keymaster_key_param_t& param) {
switch (keymaster_tag_get_type(param.tag)) {
case KM_ENUM:
@@ -220,6 +223,9 @@
case KM_TAG_ROLLBACK_RESISTANT:
bool_ptr = &record->rollback_resistant;
break;
+ case KM_TAG_ROLLBACK_RESISTANCE:
+ bool_ptr = &record->rollback_resistance;
+ break;
case KM_TAG_ALLOW_WHILE_ON_BODY:
bool_ptr = &record->allow_while_on_body;
break;
@@ -232,6 +238,15 @@
case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
bool_ptr = &record->trusted_confirmation_required;
break;
+ case KM_TAG_EARLY_BOOT_ONLY:
+ bool_ptr = &record->early_boot_only;
+ break;
+ case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
+ bool_ptr = &record->device_unique_attestation;
+ break;
+ case KM_TAG_IDENTITY_CREDENTIAL_KEY:
+ bool_ptr = &record->identity_credential_key;
+ break;
/* Byte arrays*/
case KM_TAG_APPLICATION_ID:
@@ -364,69 +379,55 @@
// Construct an ASN1.1 DER-encoded attestation record containing the values from sw_enforced and
// tee_enforced.
-keymaster_error_t build_attestation_record(const AuthorizationSet& attestation_params,
- AuthorizationSet sw_enforced,
- AuthorizationSet tee_enforced,
- const AttestationRecordContext& context,
- UniquePtr<uint8_t[]>* asn1_key_desc,
- size_t* asn1_key_desc_len) {
+keymaster_error_t
+build_attestation_record(const AuthorizationSet& attestation_params, AuthorizationSet sw_enforced,
+ AuthorizationSet tee_enforced, const AttestationRecordContext& context,
+ const uint keymaster_version, UniquePtr<uint8_t[]>* asn1_key_desc,
+ size_t* asn1_key_desc_len) {
assert(asn1_key_desc && asn1_key_desc_len);
UniquePtr<KM_KEY_DESCRIPTION, KM_KEY_DESCRIPTION_Delete> key_desc(KM_KEY_DESCRIPTION_new());
if (!key_desc.get())
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
- keymaster_security_level_t keymaster_security_level;
- uint32_t keymaster_version = UINT32_MAX;
- if (tee_enforced.empty()) {
- // Software key.
- keymaster_security_level = KM_SECURITY_LEVEL_SOFTWARE;
- keymaster_version = kCurrentKeymasterVersion;
+ KM_ROOT_OF_TRUST* root_of_trust = nullptr;
+ if (context.GetSecurityLevel() == KM_SECURITY_LEVEL_SOFTWARE) {
+ key_desc->software_enforced->root_of_trust = KM_ROOT_OF_TRUST_new();
+ root_of_trust = key_desc->software_enforced->root_of_trust;
} else {
- keymaster_security_level = KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT;
- switch (context.GetSecurityLevel()) {
- case KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT: {
- keymaster_version = kCurrentKeymasterVersion;
+ key_desc->tee_enforced->root_of_trust = KM_ROOT_OF_TRUST_new();
+ root_of_trust = key_desc->tee_enforced->root_of_trust;
+ }
- // Root of trust is only available in TEE
- KM_AUTH_LIST* tee_record = key_desc->tee_enforced;
- tee_record->root_of_trust = KM_ROOT_OF_TRUST_new();
- keymaster_blob_t verified_boot_key;
- keymaster_verified_boot_t verified_boot_state;
- bool device_locked;
- keymaster_error_t error = context.GetVerifiedBootParams(
- &verified_boot_key, &verified_boot_state, &device_locked);
- if (error != KM_ERROR_OK)
- return error;
- if (verified_boot_key.data_length &&
- !ASN1_OCTET_STRING_set(tee_record->root_of_trust->verified_boot_key,
- verified_boot_key.data, verified_boot_key.data_length))
- return TranslateLastOpenSslError();
- tee_record->root_of_trust->device_locked = (int*)device_locked;
- if (!ASN1_ENUMERATED_set(tee_record->root_of_trust->verified_boot_state,
- verified_boot_state))
- return TranslateLastOpenSslError();
- break;
- }
- case KM_SECURITY_LEVEL_SOFTWARE:
- // We're running in software, wrapping some KM hardware. Is it KM0 or KM1? KM1 keys
- // have the purpose in the tee_enforced list. It's possible that a key could be created
- // without a purpose, which would fool this test into reporting it's a KM0 key. That
- // corner case doesn't matter much, because purpose-less keys are not usable anyway.
- // Also, KM1 TEEs should disappear rapidly.
- keymaster_version = tee_enforced.Contains(TAG_PURPOSE) ? 1 : 0;
- break;
- }
+ keymaster_blob_t verified_boot_key;
+ keymaster_blob_t verified_boot_hash;
+ keymaster_verified_boot_t verified_boot_state;
+ bool device_locked;
+ keymaster_error_t error = context.GetVerifiedBootParams(&verified_boot_key, &verified_boot_hash,
+ &verified_boot_state, &device_locked);
+ if (error != KM_ERROR_OK) return error;
+ if (verified_boot_key.data_length &&
+ !ASN1_OCTET_STRING_set(root_of_trust->verified_boot_key, verified_boot_key.data,
+ verified_boot_key.data_length)) {
+ return TranslateLastOpenSslError();
+ }
+ if (verified_boot_hash.data_length &&
+ !ASN1_OCTET_STRING_set(root_of_trust->verified_boot_hash, verified_boot_hash.data,
+ verified_boot_hash.data_length)) {
+ return TranslateLastOpenSslError();
+ }
- if (keymaster_version == UINT32_MAX)
- return KM_ERROR_UNKNOWN_ERROR;
+ root_of_trust->device_locked = device_locked ? 0xFF : 0x00;
+ if (!ASN1_ENUMERATED_set(root_of_trust->verified_boot_state, verified_boot_state)) {
+ return TranslateLastOpenSslError();
}
if (!ASN1_INTEGER_set(key_desc->attestation_version, kCurrentAttestationVersion) ||
!ASN1_ENUMERATED_set(key_desc->attestation_security_level, context.GetSecurityLevel()) ||
!ASN1_INTEGER_set(key_desc->keymaster_version, keymaster_version) ||
- !ASN1_ENUMERATED_set(key_desc->keymaster_security_level, keymaster_security_level))
+ !ASN1_ENUMERATED_set(key_desc->keymaster_security_level, context.GetSecurityLevel())) {
return TranslateLastOpenSslError();
+ }
keymaster_blob_t attestation_challenge = {nullptr, 0};
if (!attestation_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge))
@@ -444,8 +445,9 @@
return KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING;
sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, attestation_app_id);
- keymaster_error_t error = context.VerifyAndCopyDeviceIds(attestation_params,
- keymaster_security_level == KM_SECURITY_LEVEL_SOFTWARE ? &sw_enforced : &tee_enforced);
+ error = context.VerifyAndCopyDeviceIds(
+ attestation_params,
+ context.GetSecurityLevel() == KM_SECURITY_LEVEL_SOFTWARE ? &sw_enforced : &tee_enforced);
if (error == KM_ERROR_UNIMPLEMENTED) {
// The KeymasterContext implementation does not support device ID attestation. Bail out if
// device ID attestation is being attempted.
@@ -458,6 +460,11 @@
return error;
}
+ if (attestation_params.Contains(TAG_DEVICE_UNIQUE_ATTESTATION) &&
+ context.GetSecurityLevel() == KM_SECURITY_LEVEL_STRONGBOX) {
+ tee_enforced.push_back(TAG_DEVICE_UNIQUE_ATTESTATION);
+ };
+
error = build_auth_list(sw_enforced, key_desc->software_enforced);
if (error != KM_ERROR_OK)
return error;
@@ -509,6 +516,14 @@
return KM_ERROR_OK;
}
+keymaster_error_t
+build_attestation_record(const AuthorizationSet& attestation_params, AuthorizationSet sw_enforced,
+ AuthorizationSet tee_enforced, const AttestationRecordContext& context,
+ UniquePtr<uint8_t[]>* asn1_key_desc, size_t* asn1_key_desc_len) {
+ return build_attestation_record(attestation_params, sw_enforced, tee_enforced, context,
+ kCurrentKeymasterVersion, asn1_key_desc, asn1_key_desc_len);
+}
+
// Copy all enumerated values with the specified tag from stack to auth_list.
static bool get_repeated_enums(const ASN1_INTEGER_SET* stack, keymaster_tag_t tag,
AuthorizationSet* auth_list) {
@@ -630,6 +645,10 @@
record->attestation_application_id->length))
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ // identity credential key
+ if (record->identity_credential_key && !auth_list->push_back(TAG_IDENTITY_CREDENTIAL_KEY))
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
// Creation date time
if (!get_ulong(record->creation_date_time, TAG_CREATION_DATETIME, auth_list))
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
@@ -717,6 +736,13 @@
}
}
+ // Early boot only
+ if (record->early_boot_only) {
+ if (!auth_list->push_back(TAG_EARLY_BOOT_ONLY)) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ }
+
return KM_ERROR_OK;
}
diff --git a/km_openssl/attestation_utils.cpp b/km_openssl/attestation_utils.cpp
index e6754a2..1ed523b 100644
--- a/km_openssl/attestation_utils.cpp
+++ b/km_openssl/attestation_utils.cpp
@@ -165,12 +165,12 @@
return result;
}
-
keymaster_error_t build_attestation_extension(const AuthorizationSet& attest_params,
- const AuthorizationSet& tee_enforced,
- const AuthorizationSet& sw_enforced,
- const AttestationRecordContext& context,
- X509_EXTENSION_Ptr* extension) {
+ const AuthorizationSet& tee_enforced,
+ const AuthorizationSet& sw_enforced,
+ const uint keymaster_version,
+ const AttestationRecordContext& context,
+ X509_EXTENSION_Ptr* extension) {
ASN1_OBJECT_Ptr oid(
OBJ_txt2obj(kAttestionRecordOid, 1 /* accept numerical dotted string form only */));
if (!oid.get())
@@ -178,8 +178,9 @@
UniquePtr<uint8_t[]> attest_bytes;
size_t attest_bytes_len;
- keymaster_error_t error = build_attestation_record(attest_params, sw_enforced, tee_enforced,
- context, &attest_bytes, &attest_bytes_len);
+ keymaster_error_t error =
+ build_attestation_record(attest_params, sw_enforced, tee_enforced, context,
+ keymaster_version, &attest_bytes, &attest_bytes_len);
if (error != KM_ERROR_OK)
return error;
@@ -266,8 +267,8 @@
return KM_ERROR_OK;
}
-bool add_public_key(EVP_PKEY* key, X509* certificate, keymaster_error_t* error) {
- if (!X509_set_pubkey(certificate, key)) {
+bool add_public_key(const EVP_PKEY* key, X509* certificate, keymaster_error_t* error) {
+ if (!X509_set_pubkey(certificate, (EVP_PKEY*)key)) {
*error = TranslateLastOpenSslError();
return false;
}
@@ -275,14 +276,14 @@
}
bool add_attestation_extension(const AuthorizationSet& attest_params,
- const AuthorizationSet& tee_enforced,
- const AuthorizationSet& sw_enforced,
- const AttestationRecordContext& context,
- X509* certificate,
- keymaster_error_t* error) {
+ const AuthorizationSet& tee_enforced,
+ const AuthorizationSet& sw_enforced,
+ const AttestationRecordContext& context,
+ const uint keymaster_version, X509* certificate,
+ keymaster_error_t* error) {
X509_EXTENSION_Ptr attest_extension;
- *error = build_attestation_extension(attest_params, tee_enforced, sw_enforced, context,
- &attest_extension);
+ *error = build_attestation_extension(attest_params, tee_enforced, sw_enforced,
+ keymaster_version, context, &attest_extension);
if (*error != KM_ERROR_OK)
return false;
@@ -297,26 +298,29 @@
} // anonymous namespace
-keymaster_error_t generate_attestation(const AsymmetricKey& key,
- const AuthorizationSet& attest_params, const keymaster_cert_chain_t& attestation_chain,
- const keymaster_key_blob_t& attestation_signing_key,
- const AttestationRecordContext& context, CertChainPtr* cert_chain_out) {
+keymaster_error_t generate_attestation_common(
+ const EVP_PKEY* evp_key, // input
+ const AuthorizationSet& sw_enforced, // input
+ const AuthorizationSet& hw_enforced, // input
+ const AuthorizationSet& attest_params, // input. Sub function require app id to be set here.
+ uint64_t
+ activeDateTimeMilliSeconds, // input, certificate active time in milliseconds since epoch
+ uint64_t usageExpireDateTimeMilliSeconds, // Input, certificate expire time in milliseconds
+ // since epoch
+ const uint keymaster_version,
+ const AttestationRecordContext& context, // input
+ const keymaster_cert_chain_t& attestation_chain, // input
+ const keymaster_key_blob_t& attestation_signing_key, // input
+ CertChainPtr* cert_chain_out) { // Output.
- if (!cert_chain_out)
+ if (!cert_chain_out) {
return KM_ERROR_UNEXPECTED_NULL_POINTER;
-
- keymaster_algorithm_t sign_algorithm;
- if ((!key.sw_enforced().GetTagValue(TAG_ALGORITHM, &sign_algorithm) &&
- !key.hw_enforced().GetTagValue(TAG_ALGORITHM, &sign_algorithm)))
- return KM_ERROR_UNKNOWN_ERROR;
-
- EVP_PKEY_Ptr pkey(EVP_PKEY_new());
- if (!key.InternalToEvp(pkey.get()))
- return TranslateLastOpenSslError();
+ }
X509_Ptr certificate(X509_new());
- if (!certificate.get())
+ if (!certificate.get()) {
return TranslateLastOpenSslError();
+ }
if (!X509_set_version(certificate.get(), 2 /* version 3, but zero-based */))
return TranslateLastOpenSslError();
@@ -328,53 +332,58 @@
X509_NAME_Ptr subjectName(X509_NAME_new());
if (!subjectName.get() ||
- !X509_NAME_add_entry_by_txt(subjectName.get(), "CN", MBSTRING_ASC,
+ !X509_NAME_add_entry_by_txt(subjectName.get(), //
+ "CN", //
+ MBSTRING_ASC,
reinterpret_cast<const uint8_t*>("Android Keystore Key"),
- -1 /* len */, -1 /* loc */, 0 /* set */) ||
+ -1, // len
+ -1, // loc
+ 0 /* set */) ||
!X509_set_subject_name(certificate.get(), subjectName.get() /* Don't release; copied */))
return TranslateLastOpenSslError();
ASN1_TIME_Ptr notBefore(ASN1_TIME_new());
- uint64_t activeDateTime = 0;
- key.authorizations().GetTagValue(TAG_ACTIVE_DATETIME, &activeDateTime);
- if (!notBefore.get() || !ASN1_TIME_set(notBefore.get(), activeDateTime / 1000) ||
+
+ if (!notBefore.get() || !ASN1_TIME_set(notBefore.get(), activeDateTimeMilliSeconds / 1000) ||
!X509_set_notBefore(certificate.get(), notBefore.get() /* Don't release; copied */))
return TranslateLastOpenSslError();
ASN1_TIME_Ptr notAfter(ASN1_TIME_new());
- uint64_t usageExpireDateTime = UINT64_MAX;
- key.authorizations().GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &usageExpireDateTime);
+
// TODO(swillden): When trusty can use the C++ standard library change the calculation of
- // notAfterTime to use std::numeric_limits<time_t>::max(), rather than assuming that time_t is
- // 32 bits.
- time_t notAfterTime =
- (time_t)min(static_cast<uint64_t>(UINT32_MAX), usageExpireDateTime / 1000);
+ // notAfterTime to use std::numeric_limits<time_t>::max(), rather than assuming that time_t
+ // is 32 bits.
+ time_t notAfterTime;
+ notAfterTime =
+ (time_t)min(static_cast<uint64_t>(UINT32_MAX), usageExpireDateTimeMilliSeconds / 1000);
+
if (!notAfter.get() || !ASN1_TIME_set(notAfter.get(), notAfterTime) ||
!X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */))
return TranslateLastOpenSslError();
- keymaster_error_t error = add_key_usage_extension(key.hw_enforced(), key.sw_enforced(), certificate.get());
+ keymaster_error_t error = add_key_usage_extension(hw_enforced, sw_enforced, certificate.get());
if (error != KM_ERROR_OK) {
return error;
}
- // We have established above that it is one of the two. So if it is not RSA its EC.
- int evp_key_type = (sign_algorithm == KM_ALGORITHM_RSA) ? EVP_PKEY_RSA : EVP_PKEY_EC;
+ int evp_key_type = EVP_PKEY_type(evp_key->type);
const uint8_t* key_material = attestation_signing_key.key_material;
- EVP_PKEY_Ptr sign_key(
- d2i_PrivateKey(evp_key_type, nullptr,
- const_cast<const uint8_t**>(&key_material),
- attestation_signing_key.key_material_size));
- if (!sign_key.get()) return TranslateLastOpenSslError();
+ EVP_PKEY_Ptr sign_key(d2i_PrivateKey(evp_key_type, nullptr, &key_material,
+ attestation_signing_key.key_material_size));
- if (!add_public_key(pkey.get(), certificate.get(), &error) ||
- !add_attestation_extension(attest_params, key.hw_enforced(), key.sw_enforced(),
- context, certificate.get(), &error))
+ if (!sign_key.get()) {
+ return TranslateLastOpenSslError();
+ }
+
+ if (!add_public_key(evp_key, certificate.get(), &error) ||
+ !add_attestation_extension(attest_params, hw_enforced, sw_enforced, context,
+ keymaster_version, certificate.get(), &error))
return error;
if (attestation_chain.entry_count < 1) {
- // the attestation chain must have at least the cert for the key that signs the new cert.
+ // the attestation chain must have at least the cert for the key that signs the new
+ // cert.
return KM_ERROR_UNKNOWN_ERROR;
}
@@ -389,34 +398,100 @@
if (!issuerSubject) {
return KM_ERROR_UNKNOWN_ERROR;
}
+
if (!X509_set_issuer_name(certificate.get(), issuerSubject)) {
return TranslateLastOpenSslError();
}
- UniquePtr<X509V3_CTX> x509v3_ctx(new(std::nothrow) X509V3_CTX);
- if (!x509v3_ctx.get())
+ UniquePtr<X509V3_CTX> x509v3_ctx(new (std::nothrow) X509V3_CTX);
+ if (!x509v3_ctx.get()) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
- *x509v3_ctx = {};
- X509V3_set_ctx(x509v3_ctx.get(), signing_cert.get(), certificate.get(), nullptr /* req */,
- nullptr /* crl */, 0 /* flags */);
-
- X509_EXTENSION_Ptr auth_key_id(X509V3_EXT_nconf_nid(nullptr /* conf */, x509v3_ctx.get(),
- NID_authority_key_identifier,
- const_cast<char*>("keyid:always")));
- if (!auth_key_id.get() ||
- !X509_add_ext(certificate.get(), auth_key_id.get() /* Don't release; copied */,
- -1 /* insert at end */)) {
- return TranslateLastOpenSslError();
}
+ *x509v3_ctx = {};
+ X509V3_set_ctx(x509v3_ctx.get(), //
+ signing_cert.get(), // signing certificate
+ certificate.get(), //
+ nullptr, // req
+ nullptr, // crl
+ 0 /* flags */);
+
if (!X509_sign(certificate.get(), sign_key.get(), EVP_sha256()))
return TranslateLastOpenSslError();
- *cert_chain_out = makeCertChain(certificate.get(), attestation_chain);
- if (!cert_chain_out->get())
- return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ if (attest_params.Contains(TAG_DEVICE_UNIQUE_ATTESTATION)) {
+ // When we're pretending to be a StrongBox doing device-unique attestation, we don't chain
+ // back to anything, but just return the plain certificate.
+ *cert_chain_out = makeCertChain(certificate.get());
+ } else {
+ *cert_chain_out = makeCertChain(certificate.get(), attestation_chain);
+ }
+ if (!cert_chain_out->get()) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
return KM_ERROR_OK;
}
+// Generate attestation certificate base on the AsymmetricKey key and other parameters
+// passed in. In attest_params, we expects the challenge, active time and expiration
+// time, and app id.
+//
+// The active time and expiration time are expected in milliseconds.
+//
+// Hardware and software enforced AuthorizationSet are expected to be built into the AsymmetricKey
+// input. In hardware enforced AuthorizationSet, we expects hardware related tags such as
+// TAG_IDENTITY_CREDENTIAL_KEY.
+keymaster_error_t generate_attestation(const AsymmetricKey& key,
+ const AuthorizationSet& attest_params,
+ const keymaster_cert_chain_t& attestation_chain,
+ const keymaster_key_blob_t& attestation_signing_key,
+ const AttestationRecordContext& context,
+ CertChainPtr* cert_chain_out) {
-} // namespace keymaster
+ // assume the conversion to EVP key correctly encodes the key type such
+ // that EVP_PKEY_type(evp_key->type) returns correctly.
+ EVP_PKEY_Ptr pkey(EVP_PKEY_new());
+ if (!key.InternalToEvp(pkey.get())) {
+ return TranslateLastOpenSslError();
+ }
+
+ uint64_t activeDateTime = 0;
+ key.authorizations().GetTagValue(TAG_ACTIVE_DATETIME, &activeDateTime);
+
+ uint64_t usageExpireDateTime = UINT64_MAX;
+ key.authorizations().GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &usageExpireDateTime);
+
+ return generate_attestation_common(pkey.get(), key.sw_enforced(), key.hw_enforced(),
+ attest_params, activeDateTime, usageExpireDateTime,
+ kCurrentKeymasterVersion, context, attestation_chain,
+ attestation_signing_key, cert_chain_out);
+}
+
+// Generate attestation certificate base on the EVP key and other parameters
+// passed in. Note that due to sub sub sub function call setup, there are 3 AuthorizationSet
+// passed in, hardware, software, and attest_params. In attest_params, we expects the
+// challenge, active time and expiration time, and app id. In hw_enforced, we expects
+// hardware related tags such as TAG_IDENTITY_CREDENTIAL_KEY.
+//
+// The active time and expiration time are expected in milliseconds.
+keymaster_error_t generate_attestation_from_EVP(
+ const EVP_PKEY* evp_key, // input
+ const AuthorizationSet& sw_enforced, // input
+ const AuthorizationSet& hw_enforced, // input
+ const AuthorizationSet& attest_params, // input. Sub function require app id to be set here.
+ const AttestationRecordContext& context, // input
+ const uint keymaster_version, // input
+ const keymaster_cert_chain_t& attestation_chain, // input
+ const keymaster_key_blob_t& attestation_signing_key, // input
+ CertChainPtr* cert_chain_out) { // Output.
+
+ uint64_t activeDateTime = 0;
+ attest_params.GetTagValue(TAG_ACTIVE_DATETIME, &activeDateTime);
+
+ uint64_t usageExpireDateTime = UINT64_MAX;
+ attest_params.GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &usageExpireDateTime);
+
+ return generate_attestation_common(
+ evp_key, sw_enforced, hw_enforced, attest_params, activeDateTime, usageExpireDateTime,
+ keymaster_version, context, attestation_chain, attestation_signing_key, cert_chain_out);
+}
+
+} // namespace keymaster
diff --git a/km_openssl/block_cipher_operation.cpp b/km_openssl/block_cipher_operation.cpp
index 7ba3707..ba75785 100644
--- a/km_openssl/block_cipher_operation.cpp
+++ b/km_openssl/block_cipher_operation.cpp
@@ -18,7 +18,7 @@
#include <stdio.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <keymaster/UniquePtr.h>
diff --git a/km_openssl/hkdf.cpp b/km_openssl/hkdf.cpp
index e7142d2..7ac49b9 100644
--- a/km_openssl/hkdf.cpp
+++ b/km_openssl/hkdf.cpp
@@ -18,7 +18,7 @@
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/km_openssl/hmac.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/km_openssl/hmac_key.cpp b/km_openssl/hmac_key.cpp
index 3883274..b2757b6 100644
--- a/km_openssl/hmac_key.cpp
+++ b/km_openssl/hmac_key.cpp
@@ -16,7 +16,7 @@
#include <keymaster/km_openssl/hmac_key.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <openssl/err.h>
#include <openssl/rand.h>
diff --git a/km_openssl/hmac_operation.cpp b/km_openssl/hmac_operation.cpp
index 30edf36..ce80cfc 100644
--- a/km_openssl/hmac_operation.cpp
+++ b/km_openssl/hmac_operation.cpp
@@ -16,7 +16,7 @@
#include "hmac_operation.h"
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
diff --git a/km_openssl/rsa_key_factory.cpp b/km_openssl/rsa_key_factory.cpp
index 30bb9fb..05029bb 100644
--- a/km_openssl/rsa_key_factory.cpp
+++ b/km_openssl/rsa_key_factory.cpp
@@ -21,7 +21,7 @@
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymaster/km_openssl/rsa_key.h>
#include <keymaster/km_openssl/rsa_operation.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/km_openssl/rsa_operation.cpp b/km_openssl/rsa_operation.cpp
index 7e9bae8..3e3e082 100644
--- a/km_openssl/rsa_operation.cpp
+++ b/km_openssl/rsa_operation.cpp
@@ -24,7 +24,7 @@
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymaster/km_openssl/rsa_key.h>
#include <keymaster/logger.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
namespace keymaster {
diff --git a/km_openssl/triple_des_key.cpp b/km_openssl/triple_des_key.cpp
index d515d96..654e40e 100644
--- a/km_openssl/triple_des_key.cpp
+++ b/km_openssl/triple_des_key.cpp
@@ -18,7 +18,7 @@
#include <assert.h>
-#include <keymaster/new>
+#include <keymaster/new.h>
#include <openssl/err.h>
#include <openssl/rand.h>
diff --git a/ng/AndroidKeymaster41Device.cpp b/ng/AndroidKeymaster41Device.cpp
new file mode 100644
index 0000000..8d57fd2
--- /dev/null
+++ b/ng/AndroidKeymaster41Device.cpp
@@ -0,0 +1,61 @@
+/*
+ **
+ ** Copyright 2019, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.keymaster@4.1 ref impl"
+#include <log/log.h>
+
+#include "include/AndroidKeymaster41Device.h"
+
+#include <keymaster/android_keymaster.h>
+
+namespace keymaster::V4_1 {
+
+using V4_0::ng::hidlKeyParams2Km;
+
+namespace {
+
+inline V41ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
+ return static_cast<V41ErrorCode>(value);
+}
+
+} // namespace
+
+IKeymasterDevice* CreateKeymasterDevice(SecurityLevel securityLevel) {
+ return new AndroidKeymaster41Device(securityLevel);
+}
+
+Return<V41ErrorCode>
+AndroidKeymaster41Device::deviceLocked(bool passwordOnly,
+ const VerificationToken& verificationToken) {
+ keymaster::VerificationToken serializableToken;
+ serializableToken.challenge = verificationToken.challenge;
+ serializableToken.timestamp = verificationToken.timestamp;
+ serializableToken.parameters_verified.Reinitialize(
+ hidlKeyParams2Km(verificationToken.parametersVerified));
+ serializableToken.security_level =
+ static_cast<keymaster_security_level_t>(verificationToken.securityLevel);
+ serializableToken.mac =
+ KeymasterBlob(verificationToken.mac.data(), verificationToken.mac.size());
+ return legacy_enum_conversion(
+ impl_->DeviceLocked(DeviceLockedRequest(passwordOnly, std::move(serializableToken))).error);
+}
+
+Return<V41ErrorCode> AndroidKeymaster41Device::earlyBootEnded() {
+ return legacy_enum_conversion(impl_->EarlyBootEnded().error);
+}
+
+} // namespace keymaster::V4_1
diff --git a/ng/AndroidKeymaster4Device.cpp b/ng/AndroidKeymaster4Device.cpp
index 70060d6..9a71360 100644
--- a/ng/AndroidKeymaster4Device.cpp
+++ b/ng/AndroidKeymaster4Device.cpp
@@ -21,6 +21,7 @@
#include "include/AndroidKeymaster4Device.h"
#include <keymasterV4_0/authorization_set.h>
+#include <keymasterV4_0/keymaster_utils.h>
#include <keymaster/android_keymaster.h>
#include <keymaster/android_keymaster_messages.h>
@@ -30,6 +31,8 @@
#include <keymaster/keymaster_enforcement.h>
#include <keymaster/km_openssl/soft_keymaster_enforcement.h>
+using android::hardware::keymaster::V4_0::support::authToken2HidlVec;
+
namespace keymaster {
namespace V4_0 {
namespace ng {
@@ -72,46 +75,8 @@
class KmParamSet : public keymaster_key_param_set_t {
public:
- explicit KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
- params = new keymaster_key_param_t[keyParams.size()];
- length = keyParams.size();
- for (size_t i = 0; i < keyParams.size(); ++i) {
- auto tag = legacy_enum_conversion(keyParams[i].tag);
- switch (typeFromTag(tag)) {
- case KM_ENUM:
- case KM_ENUM_REP:
- params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
- break;
- case KM_UINT:
- case KM_UINT_REP:
- params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
- break;
- case KM_ULONG:
- case KM_ULONG_REP:
- params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
- break;
- case KM_DATE:
- params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
- break;
- case KM_BOOL:
- if (keyParams[i].f.boolValue)
- params[i] = keymaster_param_bool(tag);
- else
- params[i].tag = KM_TAG_INVALID;
- break;
- case KM_BIGNUM:
- case KM_BYTES:
- params[i] =
- keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
- break;
- case KM_INVALID:
- default:
- params[i].tag = KM_TAG_INVALID;
- /* just skip */
- break;
- }
- }
- }
+ explicit KmParamSet(const hidl_vec<KeyParameter>& keyParams)
+ : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {}
KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} {
other.length = 0;
other.params = nullptr;
@@ -209,14 +174,62 @@
} // anonymous namespace
+keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec<KeyParameter>& keyParams) {
+ keymaster_key_param_set_t set;
+
+ set.params = new keymaster_key_param_t[keyParams.size()];
+ set.length = keyParams.size();
+
+ for (size_t i = 0; i < keyParams.size(); ++i) {
+ auto tag = legacy_enum_conversion(keyParams[i].tag);
+ switch (typeFromTag(tag)) {
+ case KM_ENUM:
+ case KM_ENUM_REP:
+ set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
+ break;
+ case KM_UINT:
+ case KM_UINT_REP:
+ set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
+ break;
+ case KM_ULONG:
+ case KM_ULONG_REP:
+ set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
+ break;
+ case KM_DATE:
+ set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
+ break;
+ case KM_BOOL:
+ if (keyParams[i].f.boolValue)
+ set.params[i] = keymaster_param_bool(tag);
+ else
+ set.params[i].tag = KM_TAG_INVALID;
+ break;
+ case KM_BIGNUM:
+ case KM_BYTES:
+ set.params[i] =
+ keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
+ break;
+ case KM_INVALID:
+ default:
+ set.params[i].tag = KM_TAG_INVALID;
+ /* just skip */
+ break;
+ }
+ }
+
+ return set;
+}
+
AndroidKeymaster4Device::AndroidKeymaster4Device(SecurityLevel securityLevel)
: impl_(new ::keymaster::AndroidKeymaster(
- []() -> auto {
- auto context = new PureSoftKeymasterContext();
+ [&]() -> auto {
+ auto context = new PureSoftKeymasterContext(
+ static_cast<keymaster_security_level_t>(securityLevel));
context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel());
return context;
}(),
- kOperationTableSize)), securityLevel_(securityLevel) {}
+ kOperationTableSize)),
+ securityLevel_(securityLevel) {}
AndroidKeymaster4Device::~AndroidKeymaster4Device() {}
@@ -478,21 +491,22 @@
Return<void> AndroidKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
const hidl_vec<KeyParameter>& inParams,
- const HardwareAuthToken& /* authToken */,
- begin_cb _hidl_cb) {
+ const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
BeginOperationRequest request;
request.purpose = legacy_enum_conversion(purpose);
request.SetKeyMaterial(key.data(), key.size());
request.additional_params.Reinitialize(KmParamSet(inParams));
+ hidl_vec<uint8_t> hidl_vec_token = authToken2HidlVec(authToken);
+ request.additional_params.push_back(
+ TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(hidl_vec_token.data()), hidl_vec_token.size());
+
BeginOperationResponse response;
impl_->BeginOperation(request, &response);
hidl_vec<KeyParameter> resultParams;
- if (response.error == KM_ERROR_OK) {
- resultParams = kmParamSet2Hidl(response.output_params);
- }
+ if (response.error == KM_ERROR_OK) resultParams = kmParamSet2Hidl(response.output_params);
_hidl_cb(legacy_enum_conversion(response.error), resultParams, response.op_handle);
return Void();
diff --git a/ng/include/AndroidKeymaster41Device.h b/ng/include/AndroidKeymaster41Device.h
new file mode 100644
index 0000000..68bbcf6
--- /dev/null
+++ b/ng/include/AndroidKeymaster41Device.h
@@ -0,0 +1,183 @@
+/*
+ **
+ ** Copyright 2019, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef HIDL_android_hardware_keymaster_V4_1_AndroidKeymaster4Device_H_
+#define HIDL_android_hardware_keymaster_V4_1_AndroidKeymaster4Device_H_
+
+#include <android/hardware/keymaster/4.1/IKeymasterDevice.h>
+#include <android/hardware/keymaster/4.1/types.h>
+#include <hidl/Status.h>
+
+#include "AndroidKeymaster4Device.h"
+
+namespace keymaster {
+class AndroidKeymaster;
+class KeymasterContext;
+
+namespace V4_1 {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::keymaster::V4_0::ErrorCode;
+using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType;
+using ::android::hardware::keymaster::V4_0::HardwareAuthToken;
+using ::android::hardware::keymaster::V4_0::HmacSharingParameters;
+using ::android::hardware::keymaster::V4_0::KeyCharacteristics;
+using ::android::hardware::keymaster::V4_0::KeyFormat;
+using ::android::hardware::keymaster::V4_0::KeyParameter;
+using ::android::hardware::keymaster::V4_0::KeyPurpose;
+using ::android::hardware::keymaster::V4_0::OperationHandle;
+using ::android::hardware::keymaster::V4_0::SecurityLevel;
+using ::android::hardware::keymaster::V4_0::VerificationToken;
+using ::android::hardware::keymaster::V4_1::IKeymasterDevice;
+using ::android::hardware::keymaster::V4_1::Tag;
+
+using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode;
+
+V41ErrorCode convert(ErrorCode error_code) {
+ return static_cast<V41ErrorCode>(error_code);
+}
+
+ErrorCode convert(V41ErrorCode error_code) {
+ return static_cast<ErrorCode>(error_code);
+}
+
+class AndroidKeymaster41Device : public IKeymasterDevice, public V4_0::ng::AndroidKeymaster4Device {
+ using super = V4_0::ng::AndroidKeymaster4Device;
+
+ public:
+ explicit AndroidKeymaster41Device(SecurityLevel securityLevel) : super(securityLevel) {}
+ virtual ~AndroidKeymaster41Device() {}
+
+ Return<V41ErrorCode> deviceLocked(bool /* passwordOnly */,
+ const VerificationToken& /* verificationToken */) override;
+ Return<V41ErrorCode> earlyBootEnded() override;
+
+ Return<void> getHardwareInfo(super::getHardwareInfo_cb _hidl_cb) override {
+ return super::getHardwareInfo(_hidl_cb);
+ }
+
+ Return<void> getHmacSharingParameters(super::getHmacSharingParameters_cb _hidl_cb) override {
+ return super::getHmacSharingParameters(_hidl_cb);
+ }
+
+ Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>& params,
+ super::computeSharedHmac_cb _hidl_cb) override {
+ return super::computeSharedHmac(params, _hidl_cb);
+ }
+
+ Return<void> verifyAuthorization(uint64_t challenge,
+ const hidl_vec<KeyParameter>& parametersToVerify,
+ const HardwareAuthToken& authToken,
+ super::verifyAuthorization_cb _hidl_cb) override {
+ return super::verifyAuthorization(challenge, parametersToVerify, authToken, _hidl_cb);
+ }
+
+ Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override {
+ return super::addRngEntropy(data);
+ }
+
+ Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+ super::generateKey_cb _hidl_cb) override {
+ return super::generateKey(keyParams, _hidl_cb);
+ }
+
+ Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ super::getKeyCharacteristics_cb _hidl_cb) override {
+ return super::getKeyCharacteristics(keyBlob, clientId, appData, _hidl_cb);
+ }
+
+ Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData,
+ super::importKey_cb _hidl_cb) override {
+ return super::importKey(params, keyFormat, keyData, _hidl_cb);
+ }
+
+ Return<void> importWrappedKey(const hidl_vec<uint8_t>& wrappedKeyData,
+ const hidl_vec<uint8_t>& wrappingKeyBlob,
+ const hidl_vec<uint8_t>& maskingKey,
+ const hidl_vec<KeyParameter>& unwrappingParams,
+ uint64_t passwordSid, uint64_t biometricSid,
+ super::importWrappedKey_cb _hidl_cb) override {
+ return super::importWrappedKey(wrappedKeyData, wrappingKeyBlob, maskingKey,
+ unwrappingParams, passwordSid, biometricSid, _hidl_cb);
+ }
+
+ Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+ super::exportKey_cb _hidl_cb) override {
+ return super::exportKey(exportFormat, keyBlob, clientId, appData, _hidl_cb);
+ }
+
+ Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ super::attestKey_cb _hidl_cb) override {
+ return super::attestKey(keyToAttest, attestParams, _hidl_cb);
+ }
+
+ Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ super::upgradeKey_cb _hidl_cb) override {
+ return super::upgradeKey(keyBlobToUpgrade, upgradeParams, _hidl_cb);
+ }
+
+ Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override {
+ return super::deleteKey(keyBlob);
+ }
+
+ Return<ErrorCode> deleteAllKeys() override { return super::deleteAllKeys(); }
+
+ Return<ErrorCode> destroyAttestationIds() override { return super::destroyAttestationIds(); }
+
+ Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
+ super::begin_cb _hidl_cb) override {
+ return super::begin(purpose, key, inParams, authToken, _hidl_cb);
+ }
+
+ Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken,
+ super::update_cb _hidl_cb) override {
+ return super::update(operationHandle, inParams, input, authToken, verificationToken,
+ _hidl_cb);
+ }
+
+ Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+ const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken,
+ super::finish_cb _hidl_cb) override {
+ return super::finish(operationHandle, inParams, input, signature, authToken,
+ verificationToken, _hidl_cb);
+ }
+
+ Return<ErrorCode> abort(uint64_t operationHandle) override {
+ return super::abort(operationHandle);
+ }
+};
+
+IKeymasterDevice* CreateKeymasterDevice(SecurityLevel securityLevel);
+
+} // namespace V4_1
+} // namespace keymaster
+
+#endif // HIDL_android_hardware_keymaster_V4_1_AndroidKeymaster4Device_H_
diff --git a/ng/include/AndroidKeymaster4Device.h b/ng/include/AndroidKeymaster4Device.h
index 688d08a..8bf0914 100644
--- a/ng/include/AndroidKeymaster4Device.h
+++ b/ng/include/AndroidKeymaster4Device.h
@@ -20,6 +20,7 @@
#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <hardware/keymaster_defs.h>
#include <hidl/Status.h>
namespace keymaster {
@@ -98,11 +99,16 @@
const VerificationToken& verificationToken, finish_cb _hidl_cb) override;
Return<ErrorCode> abort(uint64_t operationHandle) override;
- private:
+ protected:
std::unique_ptr<::keymaster::AndroidKeymaster> impl_;
SecurityLevel securityLevel_;
};
+// Convert HIDL key parametes to old keymaster param set. Note that this does *not* copy the blobs
+// from keyParams, only pointers to them. The keyParams instance retains ownership and must
+// continue to exist.
+keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec<KeyParameter>& keyParams);
+
IKeymasterDevice* CreateKeymasterDevice(SecurityLevel securityLevel);
} // namespace ng