summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:21:56 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:21:56 +0000
commit67e09e075d9d321bbf07a49c9fb3523de60d08a1 (patch)
tree36a8203bcf89af38aa9dd0020fb3089a7c813e13
parentffe15a3ef9fc4cf0ad6b5b2a1e9e538921eab265 (diff)
parentace296d7654032423ceb3d7f5c3305aa21733ff4 (diff)
downloadkeymaster-android14-mainline-sdkext-release.tar.gz
Snap for 10453563 from ace296d7654032423ceb3d7f5c3305aa21733ff4 to mainline-sdkext-releaseaml_sdk_341510000aml_sdk_341410000aml_sdk_341110080aml_sdk_341110000aml_sdk_341010000aml_sdk_340912010android14-mainline-sdkext-release
Change-Id: I01ffedfe1113572b871078488df8b33552ef3035
-rw-r--r--Android.bp44
-rw-r--r--android_keymaster/android_keymaster.cpp116
-rw-r--r--android_keymaster/android_keymaster_messages.cpp60
-rw-r--r--android_keymaster/keymaster_enforcement.cpp1
-rw-r--r--android_keymaster/keymaster_tags.cpp3
-rw-r--r--android_keymaster/operation_table.cpp4
-rw-r--r--android_keymaster/remote_provisioning_utils.cpp4
-rw-r--r--contexts/keymaster1_passthrough_context.cpp6
-rw-r--r--contexts/keymaster2_passthrough_context.cpp6
-rw-r--r--contexts/pure_soft_keymaster_context.cpp23
-rw-r--r--contexts/pure_soft_remote_provisioning_context.cpp38
-rw-r--r--contexts/soft_keymaster_context.cpp4
-rw-r--r--contexts/soft_keymaster_logger.cpp3
-rw-r--r--cppcose/cppcose.cpp124
-rw-r--r--fuzzer/Android.bp83
-rw-r--r--fuzzer/README.md56
-rw-r--r--fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp265
-rw-r--r--fuzzer/k4_keymaster_configuration_fuzzer.cpp29
-rw-r--r--include/keymaster/android_keymaster.h5
-rw-r--r--include/keymaster/android_keymaster_messages.h110
-rw-r--r--include/keymaster/android_keymaster_utils.h7
-rw-r--r--include/keymaster/authorization_set.h14
-rw-r--r--include/keymaster/contexts/pure_soft_remote_provisioning_context.h5
-rw-r--r--include/keymaster/cppcose/cppcose.h22
-rw-r--r--include/keymaster/key.h10
-rw-r--r--include/keymaster/keymaster_context.h19
-rw-r--r--include/keymaster/keymaster_tags.h5
-rw-r--r--include/keymaster/km_openssl/aes_key.h5
-rw-r--r--include/keymaster/km_openssl/asymmetric_key.h4
-rw-r--r--include/keymaster/km_openssl/attestation_record.h22
-rw-r--r--include/keymaster/km_openssl/curve25519_key.h6
-rw-r--r--include/keymaster/km_openssl/ec_key.h10
-rw-r--r--include/keymaster/km_openssl/ecdh_operation.h7
-rw-r--r--include/keymaster/km_openssl/ecdsa_operation.h18
-rw-r--r--include/keymaster/km_openssl/hmac_key.h5
-rw-r--r--include/keymaster/km_openssl/rsa_key.h10
-rw-r--r--include/keymaster/km_openssl/rsa_operation.h36
-rw-r--r--include/keymaster/km_openssl/triple_des_key.h5
-rw-r--r--include/keymaster/km_version.h1
-rw-r--r--include/keymaster/legacy_support/ec_keymaster1_key.h4
-rw-r--r--include/keymaster/legacy_support/keymaster1_legacy_support.h27
-rw-r--r--include/keymaster/legacy_support/keymaster_passthrough_key.h6
-rw-r--r--include/keymaster/legacy_support/rsa_keymaster1_key.h4
-rw-r--r--include/keymaster/mem.h3
-rw-r--r--include/keymaster/operation.h5
-rw-r--r--include/keymaster/remote_provisioning_context.h6
-rw-r--r--include/keymaster/remote_provisioning_utils.h3
-rw-r--r--include/keymaster/serializable.h5
-rw-r--r--key_blob_utils/auth_encrypted_key_blob.cpp4
-rw-r--r--key_blob_utils/software_keyblobs.cpp5
-rw-r--r--km_openssl/aes_key.cpp5
-rw-r--r--km_openssl/asymmetric_key_factory.cpp7
-rw-r--r--km_openssl/attestation_record.cpp68
-rw-r--r--km_openssl/attestation_utils.cpp8
-rw-r--r--km_openssl/block_cipher_operation.cpp7
-rw-r--r--km_openssl/block_cipher_operation.h6
-rw-r--r--km_openssl/certificate_utils.cpp15
-rw-r--r--km_openssl/ec_key_factory.cpp28
-rw-r--r--km_openssl/ecdh_operation.cpp14
-rw-r--r--km_openssl/hmac_key.cpp5
-rw-r--r--km_openssl/hmac_operation.cpp6
-rw-r--r--km_openssl/openssl_utils.cpp8
-rw-r--r--km_openssl/rsa_key_factory.cpp12
-rw-r--r--km_openssl/rsa_operation.cpp6
-rw-r--r--km_openssl/soft_keymaster_enforcement.cpp8
-rw-r--r--km_openssl/symmetric_key.cpp6
-rw-r--r--km_openssl/triple_des_key.cpp5
-rw-r--r--legacy_support/ec_keymaster1_key.cpp6
-rw-r--r--legacy_support/ecdsa_keymaster1_operation.h4
-rw-r--r--legacy_support/keymaster1_engine.cpp2
-rw-r--r--legacy_support/keymaster1_legacy_support.cpp13
-rw-r--r--legacy_support/keymaster_passthrough_key.cpp7
-rw-r--r--legacy_support/keymaster_passthrough_operation.cpp3
-rw-r--r--legacy_support/rsa_keymaster1_key.cpp9
-rw-r--r--legacy_support/rsa_keymaster1_operation.h4
-rw-r--r--ng/AndroidKeyMintDevice.cpp7
-rw-r--r--ng/AndroidKeyMintOperation.cpp21
-rw-r--r--ng/AndroidRemotelyProvisionedComponentDevice.cpp39
-rw-r--r--ng/KeyMintAidlUtils.cpp24
-rw-r--r--ng/KeyMintUtils.cpp29
-rw-r--r--ng/include/AndroidRemotelyProvisionedComponentDevice.h4
-rw-r--r--tests/android_keymaster_messages_test.cpp92
-rw-r--r--tests/key_blob_test.cpp3
83 files changed, 1420 insertions, 328 deletions
diff --git a/Android.bp b/Android.bp
index 6e84ec2..0323aa2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -52,15 +52,12 @@ cc_defaults {
"-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"
+ "-fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp",
],
tidy: true,
tidy_checks: [
@@ -69,6 +66,11 @@ cc_defaults {
sanitize: {
integer_overflow: false,
},
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
}
cc_library_shared {
@@ -82,15 +84,15 @@ cc_library_shared {
"android_keymaster/serializable.cpp",
],
header_libs: ["libhardware_headers"],
- defaults: ["keymaster_defaults" ],
- clang_cflags: [
+ defaults: ["keymaster_defaults"],
+ cflags: [
"-DKEYMASTER_NAME_TAGS",
],
export_include_dirs: ["include"],
host_supported: true,
target: {
host: {
- clang_cflags: [
+ cflags: [
"-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
],
},
@@ -163,12 +165,12 @@ cc_library {
export_shared_lib_headers: ["libcppbor_external"],
header_libs: ["libhardware_headers"],
export_header_lib_headers: ["libhardware_headers"],
- defaults: ["keymaster_defaults" ],
+ defaults: ["keymaster_defaults"],
host_supported: true,
export_include_dirs: ["include"],
target: {
host: {
- clang_cflags: [
+ cflags: [
"-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
],
},
@@ -273,7 +275,7 @@ cc_library {
"libcutils",
"libbase",
],
- clang_cflags: [
+ cflags: [
"-DKEYMASTER_NAME_TAGS",
"-fno-rtti", // TODO(b/156427382): Remove workaround when possible.
],
@@ -311,10 +313,13 @@ cc_library_shared {
"libsoft_attestation_cert",
"libutils",
],
- export_include_dirs: ["include", "ng/include"],
+ export_include_dirs: [
+ "include",
+ "ng/include",
+ ],
}
-cc_library_shared {
+cc_library {
name: "libkeymaster4",
srcs: [
"legacy_support/keymaster_passthrough_key.cpp",
@@ -339,7 +344,7 @@ cc_library_shared {
],
export_include_dirs: [
"ng/include",
- "include"
+ "include",
],
}
@@ -409,6 +414,7 @@ cc_library {
],
shared_libs: [
"libhidlbase",
+ "android.hardware.security.rkp-V3-ndk",
"android.hardware.security.secureclock-V1-ndk",
"android.hardware.security.sharedsecret-V1-ndk",
"lib_android_keymaster_keymint_utils",
@@ -423,7 +429,10 @@ cc_library {
"libpuresoftkeymasterdevice",
"libutils",
],
- export_include_dirs: ["include", "ng/include"],
+ export_include_dirs: [
+ "include",
+ "ng/include",
+ ],
}
cc_library {
@@ -441,6 +450,11 @@ cc_library {
"libcrypto",
"liblog",
],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
}
cc_defaults {
@@ -462,7 +476,7 @@ cc_defaults {
host_supported: true,
target: {
host: {
- clang_cflags: [
+ cflags: [
"-fno-rtti", // TODO(b/156427382): Remove when default library removes this
],
},
diff --git a/android_keymaster/android_keymaster.cpp b/android_keymaster/android_keymaster.cpp
index 420bbf2..f4e1dd9 100644
--- a/android_keymaster/android_keymaster.cpp
+++ b/android_keymaster/android_keymaster.cpp
@@ -16,6 +16,7 @@
#include <keymaster/android_keymaster.h>
+#include <utility>
#include <vector>
#include <assert.h>
@@ -133,6 +134,7 @@ std::pair<const uint8_t*, size_t> blob2Pair(const keymaster_blob_t& blob) {
return {blob.data, blob.data_length};
}
+constexpr int kMaxChallengeSizeV2 = 64;
constexpr int kP256AffinePointSize = 32;
constexpr int kRoTVersion1 = 40001;
@@ -140,13 +142,13 @@ constexpr int kRoTVersion1 = 40001;
AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size,
int32_t message_version)
- : context_(context), operation_table_(new (std::nothrow) OperationTable(operation_table_size)),
+ : context_(context), operation_table_(new(std::nothrow) OperationTable(operation_table_size)),
message_version_(message_version) {}
AndroidKeymaster::~AndroidKeymaster() {}
AndroidKeymaster::AndroidKeymaster(AndroidKeymaster&& other)
- : context_(move(other.context_)), operation_table_(move(other.operation_table_)),
+ : context_(std::move(other.context_)), operation_table_(std::move(other.operation_table_)),
message_version_(other.message_version_) {}
// TODO(swillden): Unify support analysis. Right now, we have per-keytype methods that determine if
@@ -350,7 +352,7 @@ void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
response->enforced.Clear();
response->unenforced.Clear();
response->error = factory->GenerateKey(request.key_description,
- move(attest_key), //
+ std::move(attest_key), //
request.issuer_subject,
&response->key_blob, //
&response->enforced,
@@ -358,16 +360,25 @@ void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
&response->certificate_chain);
}
+constexpr int kRkpVersionWithoutSuperencryption = 3;
+
void AndroidKeymaster::GenerateRkpKey(const GenerateRkpKeyRequest& request,
GenerateRkpKeyResponse* response) {
if (response == nullptr) return;
auto rem_prov_ctx = context_->GetRemoteProvisioningContext();
- if (rem_prov_ctx == nullptr) {
+ if (!rem_prov_ctx) {
response->error = static_cast<keymaster_error_t>(kStatusFailed);
return;
}
+ GetHwInfoResponse hwInfo(message_version());
+ rem_prov_ctx->GetHwInfo(&hwInfo);
+ if (hwInfo.version >= kRkpVersionWithoutSuperencryption && request.test_mode) {
+ response->error = static_cast<keymaster_error_t>(kStatusRemoved);
+ return;
+ }
+
// Generate the keypair that will become the attestation key.
GenerateKeyRequest gen_key_request(message_version_);
gen_key_request.key_description.Reinitialize(kKeyMintEcdsaP256Params,
@@ -424,12 +435,19 @@ void AndroidKeymaster::GenerateCsr(const GenerateCsrRequest& request,
if (response == nullptr) return;
auto rem_prov_ctx = context_->GetRemoteProvisioningContext();
- if (rem_prov_ctx == nullptr) {
+ if (!rem_prov_ctx) {
LOG_E("Couldn't get a pointer to the remote provisioning context, returned null.", 0);
response->error = static_cast<keymaster_error_t>(kStatusFailed);
return;
}
+ GetHwInfoResponse hwInfo(message_version());
+ rem_prov_ctx->GetHwInfo(&hwInfo);
+ if (hwInfo.version >= kRkpVersionWithoutSuperencryption) {
+ response->error = static_cast<keymaster_error_t>(kStatusRemoved);
+ return;
+ }
+
auto macFunction = getMacFunction(request.test_mode, rem_prov_ctx);
auto pubKeysToSign = validateAndExtractPubkeys(request.test_mode, request.num_keys,
request.keys_to_sign_array, macFunction);
@@ -450,8 +468,8 @@ void AndroidKeymaster::GenerateCsr(const GenerateCsrRequest& request,
return cppcose::generateHmacSha256(ephemeral_mac_key, input);
};
- auto pubKeysToSignMac =
- generateCoseMac0Mac(ephemeral_mac_function, std::vector<uint8_t>{}, *pubKeysToSign);
+ auto pubKeysToSignMac = generateCoseMac0Mac(ephemeral_mac_function, std::vector<uint8_t>{},
+ pubKeysToSign->encode());
if (!pubKeysToSignMac) {
LOG_E("Failed to generate COSE_Mac0 over the public keys to sign.", 0);
response->error = static_cast<keymaster_error_t>(kStatusFailed);
@@ -459,7 +477,8 @@ void AndroidKeymaster::GenerateCsr(const GenerateCsrRequest& request,
}
response->keys_to_sign_mac = KeymasterBlob(pubKeysToSignMac->data(), pubKeysToSignMac->size());
- std::unique_ptr<cppbor::Map> device_info_map = rem_prov_ctx->CreateDeviceInfo();
+ std::unique_ptr<cppbor::Map> device_info_map =
+ rem_prov_ctx->CreateDeviceInfo(2 /* csrVersion */);
std::vector<uint8_t> device_info = device_info_map->encode();
response->device_info_blob = KeymasterBlob(device_info.data(), device_info.size());
auto protectedDataPayload = rem_prov_ctx->BuildProtectedDataPayload(
@@ -518,6 +537,48 @@ void AndroidKeymaster::GenerateCsr(const GenerateCsrRequest& request,
response->error = KM_ERROR_OK;
}
+void AndroidKeymaster::GenerateCsrV2(const GenerateCsrV2Request& request,
+ GenerateCsrV2Response* response) {
+
+ if (response == nullptr) return;
+
+ if (request.challenge.size() > kMaxChallengeSizeV2) {
+ LOG_E("Challenge is too large. %zu expected. %zu actual.",
+ kMaxChallengeSizeV2, //
+ request.challenge.size()); //
+ response->error = static_cast<keymaster_error_t>(kStatusFailed);
+ return;
+ }
+
+ auto rem_prov_ctx = context_->GetRemoteProvisioningContext();
+ if (rem_prov_ctx == nullptr) {
+ LOG_E("Couldn't get a pointer to the remote provisioning context, returned null.", 0);
+ response->error = static_cast<keymaster_error_t>(kStatusFailed);
+ return;
+ }
+
+ auto macFunction = getMacFunction(false /* test_mode */, rem_prov_ctx);
+ auto pubKeys = validateAndExtractPubkeys(false /* test_mode */, request.num_keys,
+ request.keys_to_sign_array, macFunction);
+ if (!pubKeys.isOk()) {
+ LOG_E("Failed to validate and extract the public keys for the CSR", 0);
+ response->error = static_cast<keymaster_error_t>(pubKeys.moveError());
+ return;
+ }
+
+ auto csr = rem_prov_ctx->BuildCsr(
+ std::vector(request.challenge.begin(), request.challenge.end()), std::move(*pubKeys));
+ if (!csr) {
+ LOG_E("Failed to build CSR", 0);
+ response->error = static_cast<keymaster_error_t>(kStatusFailed);
+ return;
+ }
+
+ auto csr_blob = csr->encode();
+ response->csr = KeymasterBlob(csr_blob.data(), csr_blob.size());
+ response->error = KM_ERROR_OK;
+}
+
void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
GetKeyCharacteristicsResponse* response) {
if (response == nullptr) return;
@@ -528,8 +589,8 @@ void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest&
if (response->error != KM_ERROR_OK) return;
// scavenge the key object for the auth lists
- response->enforced = move(key->hw_enforced());
- response->unenforced = move(key->sw_enforced());
+ response->enforced = std::move(key->hw_enforced());
+ response->unenforced = std::move(key->sw_enforced());
response->error = CheckVersionInfo(response->enforced, response->unenforced, *context_);
}
@@ -553,7 +614,7 @@ void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
uint32_t sd_slot = key->secure_deletion_slot();
OperationPtr operation(
- factory->CreateOperation(move(*key), request.additional_params, &response->error));
+ factory->CreateOperation(std::move(*key), request.additional_params, &response->error));
if (operation.get() == nullptr) return;
operation->set_secure_deletion_slot(sd_slot);
@@ -581,7 +642,7 @@ void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
if (response->error != KM_ERROR_OK) return;
response->op_handle = operation->operation_handle();
- response->error = operation_table_->Add(move(operation));
+ response->error = operation_table_->Add(std::move(operation));
}
void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
@@ -799,7 +860,7 @@ void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyRespo
response->error = factory->ImportKey(request.key_description, //
request.key_format, //
request.key_data, //
- move(attest_key), //
+ std::move(attest_key), //
request.issuer_subject, //
&response->key_blob, //
&response->enforced, //
@@ -998,4 +1059,33 @@ GetRootOfTrustResponse AndroidKeymaster::GetRootOfTrust(const GetRootOfTrustRequ
return response;
}
+GetHwInfoResponse AndroidKeymaster::GetHwInfo() {
+ GetHwInfoResponse response(message_version());
+
+ auto rem_prov_ctx = context_->GetRemoteProvisioningContext();
+ if (!rem_prov_ctx) {
+ LOG_E("Couldn't get a pointer to the remote provisioning context, returned null.", 0);
+ response.error = static_cast<keymaster_error_t>(kStatusFailed);
+ return response;
+ }
+
+ rem_prov_ctx->GetHwInfo(&response);
+ response.error = KM_ERROR_OK;
+ return response;
+}
+
+SetAttestationIdsResponse
+AndroidKeymaster::SetAttestationIds(const SetAttestationIdsRequest& request) {
+ SetAttestationIdsResponse response(message_version());
+ response.error = context_->SetAttestationIds(request);
+ return response;
+}
+
+SetAttestationIdsKM3Response
+AndroidKeymaster::SetAttestationIdsKM3(const SetAttestationIdsKM3Request& request) {
+ SetAttestationIdsKM3Response response(message_version());
+ response.error = context_->SetAttestationIdsKM3(request);
+ return response;
+}
+
} // namespace keymaster
diff --git a/android_keymaster/android_keymaster_messages.cpp b/android_keymaster/android_keymaster_messages.cpp
index 3dfd529..78553ea 100644
--- a/android_keymaster/android_keymaster_messages.cpp
+++ b/android_keymaster/android_keymaster_messages.cpp
@@ -310,6 +310,66 @@ bool GenerateCsrResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uin
deserialize_blob(&protected_data_blob, buf_ptr, end);
}
+size_t GenerateCsrV2Request::SerializedSize() const {
+ size_t size = sizeof(uint32_t); /* num_keys */
+ for (size_t i = 0; i < num_keys; i++) {
+ size += blob_size(keys_to_sign_array[i]);
+ }
+ size += blob_size(challenge);
+ return size;
+}
+
+uint8_t* GenerateCsrV2Request::Serialize(uint8_t* buf, const uint8_t* end) const {
+ buf = append_uint32_to_buf(buf, end, num_keys);
+ for (size_t i = 0; i < num_keys; i++) {
+ buf = serialize_blob(keys_to_sign_array[i], buf, end);
+ }
+ return serialize_blob(challenge, buf, end);
+}
+
+bool GenerateCsrV2Request::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+ if (!copy_from_buf(buf_ptr, end, &num_keys, sizeof(uint32_t))) return false;
+
+ keys_to_sign_array = new (std::nothrow) KeymasterBlob[num_keys];
+ if (!keys_to_sign_array) return false;
+ for (size_t i = 0; i < num_keys; i++) {
+ if (!deserialize_blob(&keys_to_sign_array[i], buf_ptr, end)) return false;
+ }
+ return deserialize_blob(&challenge, buf_ptr, end);
+}
+
+bool GenerateCsrV2Request::InitKeysToSign(uint32_t count) {
+ num_keys = count;
+ keys_to_sign_array = new (std::nothrow) KeymasterBlob[count];
+ if (!keys_to_sign_array) {
+ return false;
+ }
+ return true;
+}
+
+void GenerateCsrV2Request::SetKeyToSign(uint32_t index, const void* data, size_t length) {
+ if (index >= num_keys) {
+ return;
+ }
+ set_blob(&keys_to_sign_array[index], data, length);
+}
+
+void GenerateCsrV2Request::SetChallenge(const void* data, size_t length) {
+ set_blob(&challenge, data, length);
+}
+
+size_t GenerateCsrV2Response::NonErrorSerializedSize() const {
+ return blob_size(csr);
+}
+
+uint8_t* GenerateCsrV2Response::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+ return serialize_blob(csr, buf, end);
+}
+
+bool GenerateCsrV2Response::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+ return deserialize_blob(&csr, buf_ptr, end);
+}
+
GetKeyCharacteristicsRequest::~GetKeyCharacteristicsRequest() {
delete[] key_blob.key_material;
}
diff --git a/android_keymaster/keymaster_enforcement.cpp b/android_keymaster/keymaster_enforcement.cpp
index de768cb..5c3bf01 100644
--- a/android_keymaster/keymaster_enforcement.cpp
+++ b/android_keymaster/keymaster_enforcement.cpp
@@ -313,6 +313,7 @@ keymaster_error_t KeymasterEnforcement::AuthorizeBegin(const keymaster_purpose_t
case KM_TAG_ATTESTATION_ID_PRODUCT:
case KM_TAG_ATTESTATION_ID_SERIAL:
case KM_TAG_ATTESTATION_ID_IMEI:
+ case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
case KM_TAG_ATTESTATION_ID_MEID:
case KM_TAG_ATTESTATION_ID_MANUFACTURER:
case KM_TAG_ATTESTATION_ID_MODEL:
diff --git a/android_keymaster/keymaster_tags.cpp b/android_keymaster/keymaster_tags.cpp
index dc42061..f1aafea 100644
--- a/android_keymaster/keymaster_tags.cpp
+++ b/android_keymaster/keymaster_tags.cpp
@@ -131,6 +131,8 @@ const char* StringifyTag(keymaster_tag_t tag) {
return "KM_TAG_ATTESTATION_ID_SERIAL";
case KM_TAG_ATTESTATION_ID_IMEI:
return "KM_TAG_ATTESTATION_ID_IMEI";
+ case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
+ return "KM_TAG_ATTESTATION_ID_SECOND_IMEI";
case KM_TAG_ATTESTATION_ID_MEID:
return "KM_TAG_ATTESTATION_ID_MEID";
case KM_TAG_ATTESTATION_ID_MANUFACTURER:
@@ -214,6 +216,7 @@ DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_DEVICE);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_PRODUCT);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_SERIAL);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_IMEI);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_SECOND_IMEI);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MEID);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MANUFACTURER);
DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MODEL);
diff --git a/android_keymaster/operation_table.cpp b/android_keymaster/operation_table.cpp
index 50d47f5..0d8b431 100644
--- a/android_keymaster/operation_table.cpp
+++ b/android_keymaster/operation_table.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <utility>
+
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/operation.h>
#include <keymaster/operation_table.h>
@@ -27,7 +29,7 @@ keymaster_error_t OperationTable::Add(OperationPtr&& operation) {
}
for (size_t i = 0; i < table_size_; ++i) {
if (!table_[i]) {
- table_[i] = move(operation);
+ table_[i] = std::move(operation);
return KM_ERROR_OK;
}
}
diff --git a/android_keymaster/remote_provisioning_utils.cpp b/android_keymaster/remote_provisioning_utils.cpp
index 78a058a..5a5ab80 100644
--- a/android_keymaster/remote_provisioning_utils.cpp
+++ b/android_keymaster/remote_provisioning_utils.cpp
@@ -124,7 +124,7 @@ validateAndExtractEekPubAndId(bool testMode, const KeymasterBlob& endpointEncryp
eek->getBstrValue(CoseKey::KEY_ID).value());
}
-StatusOr<std::vector<uint8_t> /* pubkeys */>
+StatusOr<cppbor::Array /* pubkeys */>
validateAndExtractPubkeys(bool testMode, uint32_t numKeys, KeymasterBlob* keysToSign,
const cppcose::HmacSha256Function& macFunction) {
auto pubKeysToMac = cppbor::Array();
@@ -186,7 +186,7 @@ validateAndExtractPubkeys(bool testMode, uint32_t numKeys, KeymasterBlob* keysTo
pubKeysToMac.add(pubKey->moveMap());
}
- return pubKeysToMac.encode();
+ return pubKeysToMac;
}
cppbor::Array buildCertReqRecipients(const std::vector<uint8_t>& pubkey,
diff --git a/contexts/keymaster1_passthrough_context.cpp b/contexts/keymaster1_passthrough_context.cpp
index 02c4623..8dcd5cf 100644
--- a/contexts/keymaster1_passthrough_context.cpp
+++ b/contexts/keymaster1_passthrough_context.cpp
@@ -17,6 +17,8 @@
#include <keymaster/contexts/keymaster1_passthrough_context.h>
+#include <utility>
+
#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>
@@ -171,8 +173,8 @@ Keymaster1PassthroughContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
}
auto factory = GetKeyFactory(algorithm);
- return factory->LoadKey(move(key_material), additional_params, move(hw_enforced),
- move(sw_enforced), key);
+ return factory->LoadKey(std::move(key_material), additional_params, std::move(hw_enforced),
+ std::move(sw_enforced), key);
}
keymaster_error_t Keymaster1PassthroughContext::DeleteKey(const KeymasterKeyBlob& blob) const {
diff --git a/contexts/keymaster2_passthrough_context.cpp b/contexts/keymaster2_passthrough_context.cpp
index 75ed9b6..23fc145 100644
--- a/contexts/keymaster2_passthrough_context.cpp
+++ b/contexts/keymaster2_passthrough_context.cpp
@@ -17,6 +17,8 @@
#include <keymaster/contexts/keymaster2_passthrough_context.h>
+#include <utility>
+
#include <keymaster/legacy_support/keymaster_passthrough_engine.h>
#include <keymaster/legacy_support/keymaster_passthrough_key.h>
@@ -105,8 +107,8 @@ Keymaster2PassthroughContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
KeymasterKeyBlob key_material = blob;
auto factory = GetKeyFactory(algorithm);
- return factory->LoadKey(move(key_material), additional_params, move(hw_enforced),
- move(sw_enforced), key);
+ return factory->LoadKey(std::move(key_material), additional_params, std::move(hw_enforced),
+ std::move(sw_enforced), key);
}
keymaster_error_t Keymaster2PassthroughContext::DeleteKey(const KeymasterKeyBlob& blob) const {
diff --git a/contexts/pure_soft_keymaster_context.cpp b/contexts/pure_soft_keymaster_context.cpp
index 937238b..d68ce05 100644
--- a/contexts/pure_soft_keymaster_context.cpp
+++ b/contexts/pure_soft_keymaster_context.cpp
@@ -18,6 +18,7 @@
#include <assert.h>
#include <memory>
+#include <utility>
#include <openssl/aes.h>
#include <openssl/evp.h>
@@ -324,8 +325,8 @@ keymaster_error_t PureSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob&
}
auto factory = GetKeyFactory(algorithm);
- return factory->LoadKey(move(key_material), additional_params, move(hw_enforced),
- move(sw_enforced), key);
+ return factory->LoadKey(std::move(key_material), additional_params, std::move(hw_enforced),
+ std::move(sw_enforced), key);
};
AuthorizationSet hidden;
@@ -416,7 +417,8 @@ PureSoftKeymasterContext::GenerateAttestation(const Key& key,
AttestKeyInfo attest_key_info(attest_key, &issuer_subject, error);
if (*error != KM_ERROR_OK) return {};
- return generate_attestation(asymmetric_key, attest_params, move(attest_key_info), *this, error);
+ return generate_attestation(asymmetric_key, attest_params, std::move(attest_key_info), *this,
+ error);
}
CertificateChain PureSoftKeymasterContext::GenerateSelfSignedCertificate(
@@ -452,8 +454,10 @@ keymaster::Buffer PureSoftKeymasterContext::GenerateUniqueId(uint64_t creation_d
// The secret must contain at least 128 bits of entropy and be unique to the individual device"
const std::vector<uint8_t> fake_hbk = {'M', 'u', 's', 't', 'B', 'e', 'R', 'a',
'n', 'd', 'o', 'm', 'B', 'i', 't', 's'};
- return keymaster::generate_unique_id(fake_hbk, creation_date_time, application_id,
- reset_since_rotation);
+ Buffer unique_id;
+ *error = keymaster::generate_unique_id(fake_hbk, creation_date_time, application_id,
+ reset_since_rotation, &unique_id);
+ return unique_id;
}
static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
@@ -508,7 +512,7 @@ keymaster_error_t PureSoftKeymasterContext::UnwrapKey(
AuthorizationSet out_params;
OperationPtr operation(
- operation_factory->CreateOperation(move(*key), wrapping_key_params, &error));
+ operation_factory->CreateOperation(std::move(*key), wrapping_key_params, &error));
if (!operation.get()) return error;
error = operation->Begin(wrapping_key_params, &out_params);
@@ -559,15 +563,16 @@ keymaster_error_t PureSoftKeymasterContext::UnwrapKey(
if (!aes_factory) return KM_ERROR_UNKNOWN_ERROR;
UniquePtr<Key> aes_key;
- error = aes_factory->LoadKey(move(key_material), gcm_params, move(transit_key_authorizations),
- AuthorizationSet(), &aes_key);
+ error = aes_factory->LoadKey(std::move(key_material), gcm_params,
+ std::move(transit_key_authorizations), AuthorizationSet(),
+ &aes_key);
if (error != KM_ERROR_OK) return error;
auto aes_operation_factory = GetOperationFactory(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT);
if (!aes_operation_factory) return KM_ERROR_UNKNOWN_ERROR;
OperationPtr aes_operation(
- aes_operation_factory->CreateOperation(move(*aes_key), gcm_params, &error));
+ aes_operation_factory->CreateOperation(std::move(*aes_key), gcm_params, &error));
if (!aes_operation.get()) return error;
error = aes_operation->Begin(gcm_params, &out_params);
diff --git a/contexts/pure_soft_remote_provisioning_context.cpp b/contexts/pure_soft_remote_provisioning_context.cpp
index 6919458..fcafec4 100644
--- a/contexts/pure_soft_remote_provisioning_context.cpp
+++ b/contexts/pure_soft_remote_provisioning_context.cpp
@@ -71,7 +71,8 @@ PureSoftRemoteProvisioningContext::DeriveBytesFromHbk(const std::string& context
return result;
}
-std::unique_ptr<cppbor::Map> PureSoftRemoteProvisioningContext::CreateDeviceInfo() const {
+std::unique_ptr<cppbor::Map>
+PureSoftRemoteProvisioningContext::CreateDeviceInfo(uint32_t csrVersion) const {
auto result = std::make_unique<cppbor::Map>(cppbor::Map());
// The following placeholders show how the DeviceInfo map would be populated.
@@ -101,7 +102,10 @@ std::unique_ptr<cppbor::Map> PureSoftRemoteProvisioningContext::CreateDeviceInfo
if (vendor_patchlevel_) {
result->add(cppbor::Tstr("vendor_patch_level"), cppbor::Uint(*vendor_patchlevel_));
}
- result->add(cppbor::Tstr("version"), cppbor::Uint(2));
+ // "version" field was removed from DeviceInfo in CSR v3.
+ if (csrVersion < 3) {
+ result->add(cppbor::Tstr("version"), cppbor::Uint(csrVersion));
+ }
result->add(cppbor::Tstr("fused"), cppbor::Uint(0));
// "software" security level is not supported, so lie and say we're a TEE
@@ -137,7 +141,6 @@ PureSoftRemoteProvisioningContext::GenerateBcc(bool testMode) const {
.add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
.add(CoseKey::ALGORITHM, EDDSA)
.add(CoseKey::CURVE, ED25519)
- .add(CoseKey::KEY_OPS, VERIFY)
.add(CoseKey::PUBKEY_X, pubKey)
.canonicalize();
auto sign1Payload = cppbor::Map()
@@ -193,6 +196,35 @@ PureSoftRemoteProvisioningContext::GenerateHmacSha256(const cppcose::bytevec& in
return *result;
}
+void PureSoftRemoteProvisioningContext::GetHwInfo(GetHwInfoResponse* hwInfo) const {
+ hwInfo->version = 3;
+ hwInfo->rpcAuthorName = "Google";
+ hwInfo->supportedEekCurve = 2 /* CURVE_25519 */;
+ hwInfo->uniqueId = "default keymint";
+ hwInfo->supportedNumKeysInCsr = 20;
+}
+
+cppcose::ErrMsgOr<cppbor::Array>
+PureSoftRemoteProvisioningContext::BuildCsr(const std::vector<uint8_t>& challenge,
+ cppbor::Array keysToSign) const {
+ LazyInitProdBcc();
+ uint32_t csrVersion = 3;
+ auto deviceInfo = std::move(*CreateDeviceInfo(csrVersion));
+ auto csrPayload = cppbor::Array()
+ .add(csrVersion)
+ .add("keymint" /* CertificateType */)
+ .add(std::move(deviceInfo))
+ .add(std::move(keysToSign));
+ auto signedDataPayload = cppbor::Array().add(challenge).add(cppbor::Bstr(csrPayload.encode()));
+ auto signedData = constructCoseSign1(devicePrivKey_, signedDataPayload.encode(), {} /* aad */);
+
+ return cppbor::Array()
+ .add(1 /* version */)
+ .add(cppbor::Map() /* UdsCerts */)
+ .add(std::move(*bcc_.clone()->asArray()) /* DiceCertChain */)
+ .add(std::move(*signedData) /* SignedData */);
+}
+
void PureSoftRemoteProvisioningContext::SetSystemVersion(uint32_t os_version,
uint32_t os_patchlevel) {
os_version_ = os_version;
diff --git a/contexts/soft_keymaster_context.cpp b/contexts/soft_keymaster_context.cpp
index 66c1a57..ed216b1 100644
--- a/contexts/soft_keymaster_context.cpp
+++ b/contexts/soft_keymaster_context.cpp
@@ -273,8 +273,8 @@ keymaster_error_t SoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blo
return KM_ERROR_INVALID_ARGUMENT;
}
auto factory = GetKeyFactory(algorithm);
- return factory->LoadKey(move(key_material), additional_params, move(hw_enforced),
- move(sw_enforced), key);
+ return factory->LoadKey(std::move(key_material), additional_params, std::move(hw_enforced),
+ std::move(sw_enforced), key);
};
error = BuildHiddenAuthorizations(additional_params, &hidden, root_of_trust_);
diff --git a/contexts/soft_keymaster_logger.cpp b/contexts/soft_keymaster_logger.cpp
index 4940e45..e6b3730 100644
--- a/contexts/soft_keymaster_logger.cpp
+++ b/contexts/soft_keymaster_logger.cpp
@@ -17,7 +17,10 @@
#include <keymaster/soft_keymaster_logger.h>
#include <stdarg.h>
+
+#ifndef _WIN32
#include <syslog.h>
+#endif
#define LOG_TAG "SoftKeymaster"
#include <log/log.h>
diff --git a/cppcose/cppcose.cpp b/cppcose/cppcose.cpp
index 411dc01..2eb39de 100644
--- a/cppcose/cppcose.cpp
+++ b/cppcose/cppcose.cpp
@@ -27,6 +27,7 @@
namespace cppcose {
constexpr int kP256AffinePointSize = 32;
+constexpr int kP384AffinePointSize = 48;
using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>;
@@ -58,7 +59,7 @@ ErrMsgOr<bssl::UniquePtr<EVP_CIPHER_CTX>> aesGcmInitAndProcessAad(const bytevec&
return std::move(ctx);
}
-ErrMsgOr<bytevec> signEcdsaDigest(const bytevec& key, const bytevec& data) {
+ErrMsgOr<bytevec> signP256Digest(const bytevec& key, const bytevec& data) {
auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
if (bn.get() == nullptr) {
return "Error creating BIGNUM";
@@ -141,19 +142,17 @@ ErrMsgOr<bytevec> ecdh(const bytevec& publicKey, const bytevec& privateKey) {
return sharedSecret;
}
-} // namespace
-
-ErrMsgOr<bytevec> ecdsaCoseSignatureToDer(const bytevec& ecdsaCoseSignature) {
- if (ecdsaCoseSignature.size() != 64) {
+ErrMsgOr<bytevec> ecdsaCoseSignatureToDer(int point_size, const bytevec& ecdsaCoseSignature) {
+ if (ecdsaCoseSignature.size() != (size_t)(point_size * 2)) {
return "COSE signature wrong length";
}
- auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
+ auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), point_size, nullptr));
if (rBn.get() == nullptr) {
return "Error creating BIGNUM for r";
}
- auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
+ auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + point_size, point_size, nullptr));
if (sBn.get() == nullptr) {
return "Error creating BIGNUM for s";
}
@@ -169,23 +168,58 @@ ErrMsgOr<bytevec> ecdsaCoseSignatureToDer(const bytevec& ecdsaCoseSignature) {
return derSignature;
}
-ErrMsgOr<bytevec> ecdsaDerSignatureToCose(const bytevec& ecdsaSignature) {
+ErrMsgOr<bytevec> ecdsaDerSignatureToCose(int point_size, const bytevec& ecdsaSignature) {
const unsigned char* p = ecdsaSignature.data();
auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, ecdsaSignature.size()));
if (sig == nullptr) {
return "Error decoding DER signature";
}
- bytevec ecdsaCoseSignature(64, 0);
- if (BN_bn2binpad(ECDSA_SIG_get0_r(sig.get()), ecdsaCoseSignature.data(), 32) != 32) {
+ bytevec ecdsaCoseSignature(point_size * 2, 0);
+ if (BN_bn2binpad(ECDSA_SIG_get0_r(sig.get()), ecdsaCoseSignature.data(), point_size) !=
+ point_size) {
return "Error encoding r";
}
- if (BN_bn2binpad(ECDSA_SIG_get0_s(sig.get()), ecdsaCoseSignature.data() + 32, 32) != 32) {
+ if (BN_bn2binpad(ECDSA_SIG_get0_s(sig.get()), ecdsaCoseSignature.data() + point_size,
+ point_size) != point_size) {
return "Error encoding s";
}
return ecdsaCoseSignature;
}
+bool verifyEcdsaDigest(int curve_nid, const bytevec& key, const bytevec& digest,
+ const bytevec& signature) {
+ const unsigned char* p = (unsigned char*)signature.data();
+ auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
+ if (sig.get() == nullptr) {
+ return false;
+ }
+
+ auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(curve_nid));
+ auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+ if (EC_POINT_oct2point(group.get(), point.get(), key.data(), key.size(), nullptr) != 1) {
+ return false;
+ }
+ auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+ if (ecKey.get() == nullptr) {
+ return false;
+ }
+ if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+ return false;
+ }
+ if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+ return false;
+ }
+
+ int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
+ if (rc != 1) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
ErrMsgOr<HmacSha256> generateHmacSha256(const bytevec& key, const bytevec& data) {
HmacSha256 digest;
unsigned int outLen;
@@ -275,10 +309,10 @@ ErrMsgOr<bytevec> createECDSACoseSign1Signature(const bytevec& key, const byteve
.add(aad)
.add(payload)
.encode();
- auto ecdsaSignature = signEcdsaDigest(key, sha256(signatureInput));
+ auto ecdsaSignature = signP256Digest(key, sha256(signatureInput));
if (!ecdsaSignature) return ecdsaSignature.moveMessage();
- return ecdsaDerSignatureToCose(*ecdsaSignature);
+ return ecdsaDerSignatureToCose(kP256AffinePointSize, *ecdsaSignature);
}
ErrMsgOr<bytevec> createCoseSign1Signature(const bytevec& key, const bytevec& protectedParams,
@@ -354,7 +388,8 @@ ErrMsgOr<bytevec> verifyAndParseCoseSign1(const cppbor::Array* coseSign1,
auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
if (!algorithm || !algorithm->asInt() ||
- !(algorithm->asInt()->value() == EDDSA || algorithm->asInt()->value() == ES256)) {
+ !(algorithm->asInt()->value() == EDDSA || algorithm->asInt()->value() == ES256 ||
+ algorithm->asInt()->value() == ES384)) {
return "Unsupported signature algorithm";
}
@@ -376,7 +411,7 @@ ErrMsgOr<bytevec> verifyAndParseCoseSign1(const cppbor::Array* coseSign1,
key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
return "Signature verification failed";
}
- } else { // P256
+ } else if (algorithm->asInt()->value() == ES256) {
auto key = CoseKey::parseP256(selfSigned ? payload->value() : signingCoseKey);
if (!key || key->getBstrValue(CoseKey::PUBKEY_X)->empty() ||
key->getBstrValue(CoseKey::PUBKEY_Y)->empty()) {
@@ -385,13 +420,33 @@ ErrMsgOr<bytevec> verifyAndParseCoseSign1(const cppbor::Array* coseSign1,
auto publicKey = key->getEcPublicKey();
if (!publicKey) return publicKey.moveMessage();
- auto ecdsaDerSignature = ecdsaCoseSignatureToDer(signature->value());
+ auto ecdsaDerSignature = ecdsaCoseSignatureToDer(kP256AffinePointSize, signature->value());
+ if (!ecdsaDerSignature) return ecdsaDerSignature.moveMessage();
+
+ // convert public key to uncompressed form by prepending 0x04 at begin.
+ publicKey->insert(publicKey->begin(), 0x04);
+
+ if (!verifyEcdsaDigest(NID_X9_62_prime256v1, publicKey.moveValue(), sha256(signatureInput),
+ *ecdsaDerSignature)) {
+ return "Signature verification failed";
+ }
+ } else { // ES384
+ auto key = CoseKey::parseP384(selfSigned ? payload->value() : signingCoseKey);
+ if (!key || key->getBstrValue(CoseKey::PUBKEY_X)->empty() ||
+ key->getBstrValue(CoseKey::PUBKEY_Y)->empty()) {
+ return "Bad signing key: " + key.moveMessage();
+ }
+ auto publicKey = key->getEcPublicKey();
+ if (!publicKey) return publicKey.moveMessage();
+
+ auto ecdsaDerSignature = ecdsaCoseSignatureToDer(kP384AffinePointSize, signature->value());
if (!ecdsaDerSignature) return ecdsaDerSignature.moveMessage();
// convert public key to uncompressed form by prepending 0x04 at begin.
publicKey->insert(publicKey->begin(), 0x04);
- if (!verifyEcdsaDigest(publicKey.moveValue(), sha256(signatureInput), *ecdsaDerSignature)) {
+ if (!verifyEcdsaDigest(NID_secp384r1, publicKey.moveValue(), sha384(signatureInput),
+ *ecdsaDerSignature)) {
return "Signature verification failed";
}
}
@@ -708,34 +763,13 @@ bytevec sha256(const bytevec& data) {
return ret;
}
-bool verifyEcdsaDigest(const bytevec& key, const bytevec& digest, const bytevec& signature) {
- const unsigned char* p = (unsigned char*)signature.data();
- auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
- if (sig.get() == nullptr) {
- return false;
- }
-
- auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
- auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
- if (EC_POINT_oct2point(group.get(), point.get(), key.data(), key.size(), nullptr) != 1) {
- return false;
- }
- auto ecKey = EC_KEY_Ptr(EC_KEY_new());
- if (ecKey.get() == nullptr) {
- return false;
- }
- if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
- return false;
- }
- if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
- return false;
- }
-
- int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
- if (rc != 1) {
- return false;
- }
- return true;
+bytevec sha384(const bytevec& data) {
+ bytevec ret(SHA384_DIGEST_LENGTH);
+ SHA512_CTX ctx;
+ SHA384_Init(&ctx);
+ SHA384_Update(&ctx, data.data(), data.size());
+ SHA384_Final((unsigned char*)ret.data(), &ctx);
+ return ret;
}
} // namespace cppcose
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..75af40f
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_keymaster_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_keymaster_license"],
+}
+
+cc_defaults {
+ name: "libkeymaster4_fuzzer_defaults",
+ static_libs: [
+ "libbase",
+ "liblog",
+ "libkeymaster4",
+ "libutils",
+ ],
+ shared_libs: [
+ "android.hardware.keymaster@4.0",
+ "libcrypto",
+ "libhidlbase",
+ "libkeymaster_messages",
+ "libcutils",
+ "libkeymaster_portable",
+ "libpuresoftkeymasterdevice",
+ "libkeymaster4support",
+ "libvndksupport",
+ ],
+ include_dirs: [
+ "system/keymaster/legacy_support",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 533764,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libkeymaster4",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
+}
+
+cc_fuzz {
+ name: "k4_AndroidKeymaster4Device_fuzzer",
+ defaults: [
+ "libkeymaster4_fuzzer_defaults",
+ ],
+ srcs: [
+ "k4_AndroidKeymaster4Device_fuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "k4_keymaster_configuration_fuzzer",
+ defaults: [
+ "libkeymaster4_fuzzer_defaults",
+ ],
+ srcs: [
+ "k4_keymaster_configuration_fuzzer.cpp",
+ ],
+}
diff --git a/fuzzer/README.md b/fuzzer/README.md
new file mode 100644
index 0000000..04f972c
--- /dev/null
+++ b/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzers for libkeymaster4
+
+## Plugin Design Considerations
+The fuzzer plugins for libkeymaster4 are designed based on the understanding of the
+source code and try to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzers.
+
+libkeymaster4 supports the following parameters:
+1. Security Level (parameter name: `securityLevel`)
+2. Padding Mode (parameter name: `paddingMode`)
+3. Digest (parameter name: `digest`)
+4. Key Format (parameter name: `keyFormat`)
+5. Key Purpose (parameter name: `keyPurpose`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `securityLevel` | 0.`SecurityLevel::SOFTWARE` 1.`SecurityLevel::TRUSTED_ENVIRONMENT` 2.`SecurityLevel::STRONGBOX`| Value obtained from FuzzedDataProvider|
+| `paddingMode` | 0.`PaddingMode::NONE` 1.`PaddingMode::RSA_OAEP` 2.`PaddingMode::RSA_PSS` 3. `PaddingMode::RSA_PKCS1_1_5_ENCRYPT` 4.`PaddingMode::RSA_PKCS1_1_5_SIGN` 5.`PaddingMode::PKCS7`| Value obtained from FuzzedDataProvider|
+| `digest` | 1. `Digest::NONE` 2.`Digest::MD5` 3.`Digest::SHA1` 4.`Digest::SHA_2_224` 5.`Digest::SHA_2_256` 6.`Digest::SHA_2_384` 7.`Digest::SHA_2_512`| Value obtained from FuzzedDataProvider|
+| `keyFormat` | 1. `KeyFormat::X509` 2.`KeyFormat::PKCS8` 3.`KeyFormat::RAW`| Value obtained from FuzzedDataProvider|
+| `keyPurpose` | 1. `KeyPurpose::ENCRYPT` 2.`KeyPurpose::DECRYPT` 3.`KeyPurpose::SIGN` 4. `KeyPurpose::VERIFY` 5. `KeyPurpose::WRAP_KEY`| Value obtained from FuzzedDataProvider|
+
+This also ensures that the plugins are always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugins feed the entire input data to the module.
+This ensures that the plugins tolerate any kind of input (empty, huge,
+malformed, etc) and dont `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build k4_AndroidKeymaster4Device_fuzzer and k4_keymaster_configuration_fuzzer binaries
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm k4_AndroidKeymaster4Device_fuzzer
+ $ mm k4_keymaster_configuration_fuzzer
+```
+#### Steps to run
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/${TARGET_ARCH}/k4_AndroidKeymaster4Device_fuzzer/k4_AndroidKeymaster4Device_fuzzer
+ $ adb shell /data/fuzz/${TARGET_ARCH}/k4_keymaster_configuration_fuzzer/k4_keymaster_configuration_fuzzer
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp b/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp
new file mode 100644
index 0000000..be60b75
--- /dev/null
+++ b/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+#include <AndroidKeymaster4Device.h>
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <keymasterV4_0/authorization_set.h>
+
+namespace keymaster::V4_0::ng::fuzzer {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::keymaster::V4_0::AuthorizationSet;
+using ::android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
+using ::android::hardware::keymaster::V4_0::Digest;
+using ::android::hardware::keymaster::V4_0::KeyFormat;
+using ::android::hardware::keymaster::V4_0::KeyPurpose;
+using ::android::hardware::keymaster::V4_0::PaddingMode;
+
+constexpr SecurityLevel kSecurityLevel[] = {
+ SecurityLevel::SOFTWARE,
+ SecurityLevel::TRUSTED_ENVIRONMENT,
+ SecurityLevel::STRONGBOX,
+};
+
+constexpr PaddingMode kPaddingMode[] = {
+ PaddingMode::NONE,
+ PaddingMode::RSA_OAEP,
+ PaddingMode::RSA_PSS,
+ PaddingMode::RSA_PKCS1_1_5_ENCRYPT,
+ PaddingMode::RSA_PKCS1_1_5_SIGN,
+ PaddingMode::PKCS7,
+};
+
+constexpr Digest kDigest[] = {
+ Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224,
+ Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512,
+};
+
+constexpr KeyFormat kKeyFormat[] = {
+ KeyFormat::X509,
+ KeyFormat::PKCS8,
+ KeyFormat::RAW,
+};
+
+constexpr KeyPurpose kKeyPurpose[] = {
+ KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT, KeyPurpose::SIGN,
+ KeyPurpose::VERIFY, KeyPurpose::WRAP_KEY,
+};
+
+constexpr uint32_t kRSAKeySize[] = {1024, 2048, 3072, 4096};
+constexpr uint32_t kECCKeySize[] = {224, 256, 384, 521};
+constexpr size_t kMinBytes = 0;
+constexpr size_t kMaxBytes = 100;
+
+class KeyMaster4DeviceFuzzer {
+ public:
+ bool init(const uint8_t* data, size_t size);
+ void process();
+
+ private:
+ AuthorizationSet getAuthorizationSet();
+ sp<IKeymasterDevice> mKeymaster = nullptr;
+ std::unique_ptr<FuzzedDataProvider> mFdp = nullptr;
+};
+
+AuthorizationSet KeyMaster4DeviceFuzzer::getAuthorizationSet() {
+ auto keyMasterFunction = mFdp->PickValueInArray<
+ const std::function<android::hardware::keymaster::V4_0::AuthorizationSet()>>({
+ [&]() {
+ return AuthorizationSetBuilder()
+ .RsaSigningKey(mFdp->PickValueInArray(kRSAKeySize),
+ mFdp->ConsumeIntegral<uint32_t>())
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .EcdsaKey(mFdp->PickValueInArray(kECCKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .AesKey(mFdp->PickValueInArray(kECCKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .TripleDesKey(mFdp->PickValueInArray(kRSAKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .HmacKey(mFdp->PickValueInArray(kRSAKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .RsaEncryptionKey(mFdp->PickValueInArray(kRSAKeySize),
+ mFdp->ConsumeIntegral<uint64_t>())
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .EcdsaSigningKey(mFdp->PickValueInArray(kRSAKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .AesEncryptionKey(mFdp->PickValueInArray(kECCKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .TripleDesEncryptionKey(mFdp->PickValueInArray(kRSAKeySize))
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ [&]() {
+ return AuthorizationSetBuilder()
+ .RsaKey(mFdp->PickValueInArray(kRSAKeySize), mFdp->ConsumeIntegral<uint64_t>())
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ });
+ return keyMasterFunction();
+}
+
+bool KeyMaster4DeviceFuzzer::init(const uint8_t* data, size_t size) {
+ mFdp = std::make_unique<FuzzedDataProvider>(data, size);
+ mKeymaster = CreateKeymasterDevice(mFdp->PickValueInArray(kSecurityLevel));
+ if (!mKeymaster) {
+ return false;
+ }
+ return true;
+}
+
+void KeyMaster4DeviceFuzzer::process() {
+ std::vector<uint8_t> dataVec =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->addRngEntropy(dataVec);
+
+ hidl_vec<uint8_t> keyBlob = {};
+ mKeymaster->generateKey(getAuthorizationSet().hidl_data(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {
+ keyBlob = hidlKeyBlob;
+ });
+
+ mKeymaster->attestKey(
+ keyBlob, getAuthorizationSet().hidl_data(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<hidl_vec<uint8_t>>& hidlCertificateChain) {});
+
+ mKeymaster->upgradeKey(keyBlob, hidl_vec<KeyParameter>(),
+ [&]([[maybe_unused]] ErrorCode error,
+ [[maybe_unused]] const hidl_vec<uint8_t>& upgraded_blob) {});
+
+ std::vector<uint8_t> clientId =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> appData =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->getKeyCharacteristics(
+ keyBlob, clientId, appData,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {});
+
+ KeyFormat keyFormat = mFdp->PickValueInArray(kKeyFormat);
+ std::vector<uint8_t> keyData;
+ keyData =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ ErrorCode importKeyError;
+ if (mKeymaster
+ ->importKey(getAuthorizationSet().hidl_data(), keyFormat, keyData,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {
+ importKeyError = hidlError;
+ })
+ .isOk()) {
+ if (importKeyError == ErrorCode::OK) {
+ abort();
+ }
+ }
+
+ std::vector<uint8_t> wrappedKey, wrappingKey, maskingKey;
+ wrappedKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ wrappingKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ maskingKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ uint64_t passwordSid = mFdp->ConsumeIntegral<uint64_t>();
+ uint64_t biometricSid = mFdp->ConsumeIntegral<uint64_t>();
+ mKeymaster->importWrappedKey(
+ wrappedKey, wrappingKey, maskingKey, getAuthorizationSet().hidl_data(), passwordSid,
+ biometricSid,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {});
+
+ std::vector<uint8_t> keyBlobExportKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->exportKey(keyFormat, keyBlobExportKey, clientId, appData,
+ [&]([[maybe_unused]] ErrorCode hidlErrorCode,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyMaterial) {});
+
+ KeyPurpose keyPurpose = mFdp->PickValueInArray(kKeyPurpose);
+ mKeymaster->begin(keyPurpose, keyBlob, getAuthorizationSet().hidl_data(), HardwareAuthToken(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] uint64_t hidlOpHandle) {});
+
+ uint64_t operationHandle = mFdp->ConsumeIntegral<uint64_t>();
+ std::vector<uint8_t> input =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->update(operationHandle, getAuthorizationSet().hidl_data(), input,
+ HardwareAuthToken(), VerificationToken(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] uint32_t hidlInputConsumed,
+ [[maybe_unused]] const hidl_vec<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlOutput) {});
+
+ std::vector<uint8_t> signature =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->finish(operationHandle, getAuthorizationSet().hidl_data(), input, signature,
+ HardwareAuthToken(), VerificationToken(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlOutput) {});
+
+ mKeymaster->deleteKey(keyBlob);
+ mKeymaster->deleteAllKeys();
+ mKeymaster->abort(mFdp->ConsumeIntegral<uint64_t>());
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ KeyMaster4DeviceFuzzer km4DeviceFuzzer;
+ if (km4DeviceFuzzer.init(data, size)) {
+ km4DeviceFuzzer.process();
+ }
+ return 0;
+}
+} // namespace keymaster::V4_0::ng::fuzzer
diff --git a/fuzzer/k4_keymaster_configuration_fuzzer.cpp b/fuzzer/k4_keymaster_configuration_fuzzer.cpp
new file mode 100644
index 0000000..06403bb
--- /dev/null
+++ b/fuzzer/k4_keymaster_configuration_fuzzer.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 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.
+ *
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <keymaster/keymaster_configuration.h>
+
+constexpr size_t kMaxCharacters = 100;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ keymaster::GetOsVersion(fdp.ConsumeRandomLengthString(kMaxCharacters).c_str());
+ keymaster::GetOsPatchlevel(fdp.ConsumeRandomLengthString(kMaxCharacters).c_str());
+
+ return 0;
+}
diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h
index 6c3acc5..1e51def 100644
--- a/include/keymaster/android_keymaster.h
+++ b/include/keymaster/android_keymaster.h
@@ -16,6 +16,7 @@
#pragma once
+#include "android_keymaster_messages.h"
#include <keymaster/android_keymaster_messages.h>
#include <keymaster/authorization_set.h>
@@ -75,6 +76,7 @@ class AndroidKeymaster {
void GenerateKey(const GenerateKeyRequest& request, GenerateKeyResponse* response);
void GenerateRkpKey(const GenerateRkpKeyRequest& request, GenerateRkpKeyResponse* response);
void GenerateCsr(const GenerateCsrRequest& request, GenerateCsrResponse* response);
+ void GenerateCsrV2(const GenerateCsrV2Request& request, GenerateCsrV2Response* response);
void GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
GetKeyCharacteristicsResponse* response);
void ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response);
@@ -100,6 +102,9 @@ class AndroidKeymaster {
ConfigureVerifiedBootInfoResponse
ConfigureVerifiedBootInfo(const ConfigureVerifiedBootInfoRequest& request);
GetRootOfTrustResponse GetRootOfTrust(const GetRootOfTrustRequest& request);
+ GetHwInfoResponse GetHwInfo();
+ SetAttestationIdsResponse SetAttestationIds(const SetAttestationIdsRequest& request);
+ SetAttestationIdsKM3Response SetAttestationIdsKM3(const SetAttestationIdsKM3Request& request);
bool has_operation(keymaster_operation_handle_t op_handle) const;
diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h
index 6e38860..01ff5ff 100644
--- a/include/keymaster/android_keymaster_messages.h
+++ b/include/keymaster/android_keymaster_messages.h
@@ -23,6 +23,7 @@
#include <string>
#include <string_view>
+#include <utility>
#include <vector>
#include <keymaster/android_keymaster_utils.h>
@@ -69,6 +70,10 @@ enum AndroidKeymasterCommand : uint32_t {
CONFIGURE_BOOT_PATCHLEVEL = 33,
CONFIGURE_VERIFIED_BOOT_INFO = 34,
GET_ROOT_OF_TRUST = 35,
+ GET_HW_INFO = 36,
+ GENERATE_CSR_V2 = 37,
+ SET_ATTESTATION_IDS = 38,
+ SET_ATTESTATION_IDS_KM3 = 39,
};
/**
@@ -131,6 +136,7 @@ inline int32_t MessageVersion(KmVersion version, uint32_t /* km_date */ = 0) {
return 3;
case KmVersion::KEYMINT_1:
case KmVersion::KEYMINT_2:
+ case KmVersion::KEYMINT_3:
return 4;
}
return kInvalidMessageVersion;
@@ -427,6 +433,33 @@ struct GenerateCsrResponse : public KeymasterResponse {
KeymasterBlob protected_data_blob;
};
+struct GenerateCsrV2Request : public KeymasterMessage {
+ explicit GenerateCsrV2Request(int32_t ver) : KeymasterMessage(ver) {}
+
+ ~GenerateCsrV2Request() override { delete[] keys_to_sign_array; }
+
+ size_t SerializedSize() const override;
+ uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+ bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+ bool InitKeysToSign(uint32_t count);
+ void SetKeyToSign(uint32_t index, const void* data, size_t length);
+ void SetChallenge(const void* data, size_t length);
+
+ uint32_t num_keys = 0;
+ KeymasterBlob* keys_to_sign_array = nullptr;
+ KeymasterBlob challenge;
+};
+
+struct GenerateCsrV2Response : public KeymasterResponse {
+ explicit GenerateCsrV2Response(int32_t ver) : KeymasterResponse(ver) {}
+
+ size_t NonErrorSerializedSize() const override;
+ uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+ bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+ KeymasterBlob csr;
+};
+
struct GetKeyCharacteristicsRequest : public KeymasterMessage {
explicit GetKeyCharacteristicsRequest(int32_t ver) : KeymasterMessage(ver) {
key_blob.key_material = nullptr;
@@ -768,11 +801,11 @@ using ConfigureResponse = EmptyKeymasterResponse;
struct HmacSharingParameters : public Serializable {
HmacSharingParameters() : seed({}) { memset(nonce, 0, sizeof(nonce)); }
HmacSharingParameters(HmacSharingParameters&& other) {
- seed = move(other.seed);
+ seed = std::move(other.seed);
memcpy(nonce, other.nonce, sizeof(nonce));
}
- void SetSeed(KeymasterBlob&& value) { seed = move(value); }
+ void SetSeed(KeymasterBlob&& value) { seed = std::move(value); }
size_t SerializedSize() const override;
uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
@@ -808,9 +841,9 @@ struct GetHmacSharingParametersRequest : public EmptyKeymasterRequest {
struct GetHmacSharingParametersResponse : public KeymasterResponse {
explicit GetHmacSharingParametersResponse(int32_t ver) : KeymasterResponse(ver) {}
GetHmacSharingParametersResponse(GetHmacSharingParametersResponse&& other)
- : KeymasterResponse(other.message_version), params(move(other.params)) {}
+ : KeymasterResponse(other.message_version), params(std::move(other.params)) {}
- void SetSeed(KeymasterBlob&& seed_data) { params.SetSeed(move(seed_data)); }
+ void SetSeed(KeymasterBlob&& seed_data) { params.SetSeed(std::move(seed_data)); }
size_t NonErrorSerializedSize() const override { return params.SerializedSize(); }
uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override {
@@ -841,7 +874,7 @@ struct ComputeSharedHmacResponse : public KeymasterResponse {
explicit ComputeSharedHmacResponse(int32_t ver) : KeymasterResponse(ver) {}
ComputeSharedHmacResponse(ComputeSharedHmacResponse&& other)
: KeymasterResponse(other.message_version) {
- sharing_check = move(other.sharing_check);
+ sharing_check = std::move(other.sharing_check);
}
size_t NonErrorSerializedSize() const override;
@@ -901,7 +934,7 @@ struct HardwareAuthToken : public Serializable {
authenticator_id = other.authenticator_id;
authenticator_type = other.authenticator_type;
timestamp = other.timestamp;
- mac = move(other.mac);
+ mac = std::move(other.mac);
}
size_t SerializedSize() const override;
@@ -921,9 +954,9 @@ struct VerificationToken : public Serializable {
VerificationToken(VerificationToken&& other) {
challenge = other.challenge;
timestamp = other.timestamp;
- parameters_verified = move(other.parameters_verified);
+ parameters_verified = std::move(other.parameters_verified);
security_level = other.security_level;
- mac = move(other.mac);
+ mac = std::move(other.mac);
}
size_t SerializedSize() const override;
@@ -996,7 +1029,7 @@ struct EarlyBootEndedResponse : public KeymasterResponse {
struct DeviceLockedRequest : public KeymasterMessage {
explicit DeviceLockedRequest(int32_t ver) : KeymasterMessage(ver) {}
explicit DeviceLockedRequest(int32_t ver, bool passwordOnly_, VerificationToken&& token_)
- : KeymasterMessage(ver), passwordOnly(passwordOnly_), token(move(token_)) {}
+ : KeymasterMessage(ver), passwordOnly(passwordOnly_), token(std::move(token_)) {}
size_t SerializedSize() const override { return 1; }
uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
@@ -1059,7 +1092,7 @@ struct TimestampToken : public Serializable {
challenge = other.challenge;
timestamp = other.timestamp;
security_level = other.security_level;
- mac = move(other.mac);
+ mac = std::move(other.mac);
}
size_t SerializedSize() const override {
return sizeof(challenge) + sizeof(timestamp) + sizeof(security_level) +
@@ -1153,6 +1186,29 @@ struct SetAttestationIdsRequest : public KeymasterMessage {
using SetAttestationIdsResponse = EmptyKeymasterResponse;
+struct SetAttestationIdsKM3Request : public KeymasterMessage {
+ explicit SetAttestationIdsKM3Request(int32_t ver) : KeymasterMessage(ver), base(ver) {}
+ size_t SerializedSize() const override {
+ return base.SerializedSize() //
+ + second_imei.SerializedSize();
+ }
+
+ uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+ buf = base.Serialize(buf, end);
+ return second_imei.Serialize(buf, end);
+ }
+
+ bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+ return base.Deserialize(buf_ptr, end) //
+ && second_imei.Deserialize(buf_ptr, end); //
+ }
+
+ SetAttestationIdsRequest base;
+ Buffer second_imei;
+};
+
+using SetAttestationIdsKM3Response = EmptyKeymasterResponse;
+
struct ConfigureVendorPatchlevelRequest : public KeymasterMessage {
explicit ConfigureVendorPatchlevelRequest(int32_t ver) : KeymasterMessage(ver) {}
@@ -1249,4 +1305,38 @@ struct GetRootOfTrustResponse : public KeymasterResponse {
std::vector<uint8_t> rootOfTrust;
};
+struct GetHwInfoRequest : public EmptyKeymasterRequest {
+ explicit GetHwInfoRequest(int32_t ver) : EmptyKeymasterRequest(ver) {}
+};
+
+struct GetHwInfoResponse : public KeymasterResponse {
+ explicit GetHwInfoResponse(int32_t ver) : KeymasterResponse(ver) {}
+
+ size_t NonErrorSerializedSize() const override {
+ return sizeof(version) + sizeof(uint32_t) + rpcAuthorName.size() +
+ sizeof(supportedEekCurve) + sizeof(uint32_t) + uniqueId.size() +
+ sizeof(supportedNumKeysInCsr);
+ }
+ uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override {
+ buf = append_uint32_to_buf(buf, end, version);
+ buf = append_collection_to_buf(buf, end, rpcAuthorName);
+ buf = append_uint32_to_buf(buf, end, supportedEekCurve);
+ buf = append_collection_to_buf(buf, end, uniqueId);
+ return append_uint32_to_buf(buf, end, supportedNumKeysInCsr);
+ }
+ bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+ return copy_uint32_from_buf(buf_ptr, end, &version) &&
+ copy_collection_from_buf(buf_ptr, end, &rpcAuthorName) &&
+ copy_uint32_from_buf(buf_ptr, end, &supportedEekCurve) &&
+ copy_collection_from_buf(buf_ptr, end, &uniqueId) &&
+ copy_uint32_from_buf(buf_ptr, end, &supportedNumKeysInCsr);
+ }
+
+ uint32_t version;
+ std::string rpcAuthorName;
+ uint32_t supportedEekCurve;
+ std::string uniqueId;
+ uint32_t supportedNumKeysInCsr;
+};
+
} // namespace keymaster
diff --git a/include/keymaster/android_keymaster_utils.h b/include/keymaster/android_keymaster_utils.h
index 324287a..519bd82 100644
--- a/include/keymaster/android_keymaster_utils.h
+++ b/include/keymaster/android_keymaster_utils.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <stdint.h>
#include <time.h> // for time_t.
@@ -253,7 +255,7 @@ keymaster_error_t EcCurveToKeySize(keymaster_ec_curve_t curve, uint32_t* key_siz
template <class F> class final_action {
public:
- explicit final_action(F f) : f_(move(f)) {}
+ explicit final_action(F f) : f_(std::move(f)) {}
~final_action() { f_(); }
private:
@@ -280,7 +282,8 @@ struct CertificateChain : public keymaster_cert_chain_t {
}
}
- CertificateChain(CertificateChain&& other) : keymaster_cert_chain_t{} { *this = move(other); }
+ CertificateChain(CertificateChain&& other) : keymaster_cert_chain_t{}
+ { *this = std::move(other); }
~CertificateChain() { Clear(); }
diff --git a/include/keymaster/authorization_set.h b/include/keymaster/authorization_set.h
index ce3ef75..6fff0d3 100644
--- a/include/keymaster/authorization_set.h
+++ b/include/keymaster/authorization_set.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <keymaster/UniquePtr.h>
#include <hardware/keymaster_defs.h>
@@ -692,18 +694,18 @@ class AuthProxy {
: hw_enforced_(hw_enforced), sw_enforced_(sw_enforced) {}
template <typename... ARGS> bool Contains(ARGS&&... args) const {
- return hw_enforced_.Contains(forward<ARGS>(args)...) ||
- sw_enforced_.Contains(forward<ARGS>(args)...);
+ return hw_enforced_.Contains(std::forward<ARGS>(args)...) ||
+ sw_enforced_.Contains(std::forward<ARGS>(args)...);
}
template <typename... ARGS> bool GetTagValue(ARGS&&... args) const {
- return hw_enforced_.GetTagValue(forward<ARGS>(args)...) ||
- sw_enforced_.GetTagValue(forward<ARGS>(args)...);
+ return hw_enforced_.GetTagValue(std::forward<ARGS>(args)...) ||
+ sw_enforced_.GetTagValue(std::forward<ARGS>(args)...);
}
template <typename... ARGS> bool GetTagCount(ARGS&&... args) const {
- return hw_enforced_.GetTagCount(forward<ARGS>(args)...) ||
- sw_enforced_.GetTagCount(forward<ARGS>(args)...);
+ return hw_enforced_.GetTagCount(std::forward<ARGS>(args)...) ||
+ sw_enforced_.GetTagCount(std::forward<ARGS>(args)...);
}
AuthProxyIterator begin() const { return AuthProxyIterator(hw_enforced_, sw_enforced_); }
diff --git a/include/keymaster/contexts/pure_soft_remote_provisioning_context.h b/include/keymaster/contexts/pure_soft_remote_provisioning_context.h
index 90cd79f..7d7e51e 100644
--- a/include/keymaster/contexts/pure_soft_remote_provisioning_context.h
+++ b/include/keymaster/contexts/pure_soft_remote_provisioning_context.h
@@ -38,13 +38,16 @@ class PureSoftRemoteProvisioningContext : public RemoteProvisioningContext {
~PureSoftRemoteProvisioningContext() override = default;
std::vector<uint8_t> DeriveBytesFromHbk(const std::string& context,
size_t numBytes) const override;
- std::unique_ptr<cppbor::Map> CreateDeviceInfo() const override;
+ std::unique_ptr<cppbor::Map> CreateDeviceInfo(uint32_t csrVersion) const override;
cppcose::ErrMsgOr<std::vector<uint8_t>>
BuildProtectedDataPayload(bool isTestMode, //
const std::vector<uint8_t>& macKey, //
const std::vector<uint8_t>& aad) const override;
std::optional<cppcose::HmacSha256>
GenerateHmacSha256(const cppcose::bytevec& input) const override;
+ void GetHwInfo(GetHwInfoResponse* hwInfo) const override;
+ cppcose::ErrMsgOr<cppbor::Array> BuildCsr(const std::vector<uint8_t>& challenge,
+ cppbor::Array keysToSign) const override;
void SetSystemVersion(uint32_t os_version, uint32_t os_patchlevel);
void SetVendorPatchlevel(uint32_t vendor_patchlevel);
diff --git a/include/keymaster/cppcose/cppcose.h b/include/keymaster/cppcose/cppcose.h
index c000ebe..fa5916f 100644
--- a/include/keymaster/cppcose/cppcose.h
+++ b/include/keymaster/cppcose/cppcose.h
@@ -81,9 +81,10 @@ enum CoseKeyAlgorithm : int {
ES256 = -7, // ECDSA with SHA-256
EDDSA = -8,
ECDH_ES_HKDF_256 = -25,
+ ES384 = -35, // ECDSA with SHA-384
};
-enum CoseKeyCurve : int { P256 = 1, X25519 = 4, ED25519 = 6 };
+enum CoseKeyCurve : int { P256 = 1, P384 = 2, X25519 = 4, ED25519 = 6 };
enum CoseKeyType : int { OCTET_KEY_PAIR = 1, EC2 = 2, SYMMETRIC_KEY = 4 };
enum CoseKeyOps : int { SIGN = 1, VERIFY = 2, ENCRYPT = 3, DECRYPT = 4 };
@@ -213,6 +214,20 @@ class CoseKey {
return key;
}
+ static ErrMsgOr<CoseKey> parseP384(const bytevec& coseKey) {
+ auto key = parse(coseKey, EC2, ES384, P384);
+ if (!key) return key;
+
+ auto& pubkey_x = key->getMap().get(PUBKEY_X);
+ auto& pubkey_y = key->getMap().get(PUBKEY_Y);
+ if (!pubkey_x || !pubkey_y || !pubkey_x->asBstr() || !pubkey_y->asBstr() ||
+ pubkey_x->asBstr()->value().size() != 48 || pubkey_y->asBstr()->value().size() != 48) {
+ return "Invalid P384 public key";
+ }
+
+ return key;
+ }
+
static ErrMsgOr<bytevec> getEcPublicKey(const bytevec& pubX, const bytevec& pubY) {
if (pubX.empty() || pubY.empty()) {
return "Missing input parameters";
@@ -285,9 +300,6 @@ ErrMsgOr<cppbor::Array> constructECDSACoseSign1(const bytevec& key,
cppbor::Map extraProtectedFields,
const bytevec& payload, const bytevec& aad);
-ErrMsgOr<bytevec> ecdsaCoseSignatureToDer(const bytevec& ecdsaCoseSignature);
-
-ErrMsgOr<bytevec> ecdsaDerSignatureToCose(const bytevec& ecdsaSignature);
/**
* Verify and parse a COSE_Sign1 message, returning the payload.
*
@@ -320,8 +332,8 @@ ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& senderPubKey, const bytev
const bytevec& recipientPubKey, bool senderIsA);
ErrMsgOr<bytevec> ECDH_HKDF_DeriveKey(const bytevec& pubKeyA, const bytevec& privKeyA,
const bytevec& pubKeyB, bool senderIsA);
-bool verifyEcdsaDigest(const bytevec& key, const bytevec& digest, const bytevec& signature);
bytevec sha256(const bytevec& data);
+bytevec sha384(const bytevec& data);
ErrMsgOr<bytevec /* ciphertextWithTag */> aesGcmEncrypt(const bytevec& key, const bytevec& nonce,
const bytevec& aad,
const bytevec& plaintext);
diff --git a/include/keymaster/key.h b/include/keymaster/key.h
index eb0f026..2653e24 100644
--- a/include/keymaster/key.h
+++ b/include/keymaster/key.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_KEY_H_
#define SYSTEM_KEYMASTER_KEY_H_
+#include <utility>
+
#include <assert.h>
#include <hardware/keymaster_defs.h>
@@ -53,9 +55,9 @@ class Key {
// Methods to move data out of the key. These could be overloads of the methods above, with ref
// qualifiers, but naming them differently makes it harder to accidentally make a temporary copy
// when we mean to move.
- AuthorizationSet&& hw_enforced_move() { return move(hw_enforced_); }
- AuthorizationSet&& sw_enforced_move() { return move(sw_enforced_); }
- KeymasterKeyBlob&& key_material_move() { return move(key_material_); }
+ AuthorizationSet&& hw_enforced_move() { return std::move(hw_enforced_); }
+ AuthorizationSet&& sw_enforced_move() { return std::move(sw_enforced_); }
+ KeymasterKeyBlob&& key_material_move() { return std::move(key_material_); }
const KeyFactory* key_factory() const { return key_factory_; }
const KeyFactory*& key_factory() { return key_factory_; }
@@ -66,7 +68,7 @@ class Key {
protected:
Key(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
const KeyFactory* key_factory)
- : hw_enforced_(move(hw_enforced)), sw_enforced_(move(sw_enforced)),
+ : hw_enforced_(std::move(hw_enforced)), sw_enforced_(std::move(sw_enforced)),
key_factory_(key_factory) {}
protected:
diff --git a/include/keymaster/keymaster_context.h b/include/keymaster/keymaster_context.h
index 8c4bb57..f4d01dc 100644
--- a/include/keymaster/keymaster_context.h
+++ b/include/keymaster/keymaster_context.h
@@ -24,6 +24,7 @@
#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_messages.h>
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/keymaster_enforcement.h>
#include <keymaster/km_version.h>
@@ -272,6 +273,24 @@ class KeymasterContext {
*/
virtual std::optional<uint32_t> GetBootPatchlevel() const { return std::nullopt; }
+ /**
+ * Sets attestation IDs for the implementation. On physical devices (as opposed to emulators)
+ * attestation IDs should only be set during provisioning process.
+ */
+ virtual keymaster_error_t SetAttestationIds(const SetAttestationIdsRequest& /* request */) {
+ return KM_ERROR_UNIMPLEMENTED;
+ }
+
+ /**
+ * Sets KM3 attestation IDs for the implementation. On physical
+ * devices (as opposed to emulators) attestation ID should only be set
+ * during provisioning process.
+ */
+ virtual keymaster_error_t
+ SetAttestationIdsKM3(const SetAttestationIdsKM3Request& /* request */) {
+ return KM_ERROR_UNIMPLEMENTED;
+ }
+
private:
// Uncopyable.
KeymasterContext(const KeymasterContext&);
diff --git a/include/keymaster/keymaster_tags.h b/include/keymaster/keymaster_tags.h
index f620dfb..29eae7c 100644
--- a/include/keymaster/keymaster_tags.h
+++ b/include/keymaster/keymaster_tags.h
@@ -108,7 +108,7 @@ template <keymaster_tag_type_t tag_type, keymaster_tag_t tag> class TypedTag {
// NOLINTNEXTLINE(google-explicit-constructor)
inline operator keymaster_tag_t() { return tag; }
// NOLINTNEXTLINE(google-runtime-int)
- inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); }
+ inline int masked_tag() { return static_cast<int>(keymaster_tag_mask_type(tag)); }
};
template <keymaster_tag_type_t tag_type, keymaster_tag_t tag, typename KeymasterEnum>
@@ -126,7 +126,7 @@ class TypedEnumTag {
// NOLINTNEXTLINE(google-explicit-constructor)
inline operator keymaster_tag_t() { return tag; }
// NOLINTNEXTLINE(google-runtime-int)
- inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); }
+ inline int masked_tag() { return static_cast<int>(keymaster_tag_mask_type(tag)); }
};
#ifdef KEYMASTER_NAME_TAGS
@@ -180,6 +180,7 @@ DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_DEVICE);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_PRODUCT);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_SERIAL);
DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_IMEI);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_SECOND_IMEI);
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);
diff --git a/include/keymaster/km_openssl/aes_key.h b/include/keymaster/km_openssl/aes_key.h
index f00a665..95cfc5f 100644
--- a/include/keymaster/km_openssl/aes_key.h
+++ b/include/keymaster/km_openssl/aes_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <openssl/aes.h>
#include "symmetric_key.h"
@@ -52,7 +54,8 @@ class AesKey : public SymmetricKey {
public:
AesKey(KeymasterKeyBlob&& key_material, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory)
- : SymmetricKey(move(key_material), move(hw_enforced), move(sw_enforced), key_factory) {}
+ : SymmetricKey(std::move(key_material), std::move(hw_enforced), std::move(sw_enforced),
+ key_factory) {}
};
} // namespace keymaster
diff --git a/include/keymaster/km_openssl/asymmetric_key.h b/include/keymaster/km_openssl/asymmetric_key.h
index b523116..816930e 100644
--- a/include/keymaster/km_openssl/asymmetric_key.h
+++ b/include/keymaster/km_openssl/asymmetric_key.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_ASYMMETRIC_KEY_H
#define SYSTEM_KEYMASTER_ASYMMETRIC_KEY_H
+#include <utility>
+
#include <openssl/evp.h>
#include <keymaster/key.h>
@@ -28,7 +30,7 @@ class AsymmetricKey : public Key {
public:
AsymmetricKey(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
const KeyFactory* key_factory)
- : Key(move(hw_enforced), move(sw_enforced), key_factory) {}
+ : Key(std::move(hw_enforced), std::move(sw_enforced), key_factory) {}
virtual ~AsymmetricKey() {}
virtual int evp_key_type() const = 0;
diff --git a/include/keymaster/km_openssl/attestation_record.h b/include/keymaster/km_openssl/attestation_record.h
index f9ab811..35b9956 100644
--- a/include/keymaster/km_openssl/attestation_record.h
+++ b/include/keymaster/km_openssl/attestation_record.h
@@ -121,6 +121,7 @@ typedef struct km_auth_list {
ASN1_INTEGER* boot_patch_level;
ASN1_NULL* device_unique_attestation;
ASN1_NULL* identity_credential_key;
+ ASN1_OCTET_STRING* attestation_id_second_imei;
} KM_AUTH_LIST;
ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -191,6 +192,8 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = {
TAG_DEVICE_UNIQUE_ATTESTATION.masked_tag()),
ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential_key, ASN1_NULL,
TAG_IDENTITY_CREDENTIAL_KEY.masked_tag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_second_imei, ASN1_OCTET_STRING,
+ TAG_ATTESTATION_ID_SECOND_IMEI.masked_tag()),
} ASN1_SEQUENCE_END(KM_AUTH_LIST);
DECLARE_ASN1_FUNCTIONS(KM_AUTH_LIST);
@@ -347,13 +350,14 @@ keymaster_error_t build_eat_record(const AuthorizationSet& attestation_params,
std::vector<uint8_t>* eat_token);
// Builds the input to HMAC-SHA256 for unique ID generation.
-std::vector<uint8_t> build_unique_id_input(uint64_t creation_date_time,
- const keymaster_blob_t& application_id,
- bool reset_since_rotation);
+keymaster_error_t build_unique_id_input(uint64_t creation_date_time,
+ const keymaster_blob_t& application_id,
+ bool reset_since_rotation, Buffer* input_data);
// Builds a unique ID of size UNIQUE_ID_SIZE from the given inputs.
-Buffer generate_unique_id(const std::vector<uint8_t>& hbk, uint64_t creation_date_time,
- const keymaster_blob_t& application_id, bool reset_since_rotation);
+keymaster_error_t generate_unique_id(const std::vector<uint8_t>& hbk, uint64_t creation_date_time,
+ const keymaster_blob_t& application_id,
+ bool reset_since_rotation, Buffer* unique_id);
/**
* Helper functions for attestation record tests. Caller takes ownership of
@@ -400,7 +404,7 @@ keymaster_error_t extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet
/**
* Convert a KeymasterContext::Version to the keymaster version number used in attestations.
*/
-inline static uint version_to_attestation_km_version(KmVersion version) {
+inline static uint32_t version_to_attestation_km_version(KmVersion version) {
switch (version) {
default:
case KmVersion::KEYMASTER_1:
@@ -418,13 +422,15 @@ inline static uint version_to_attestation_km_version(KmVersion version) {
return 100;
case KmVersion::KEYMINT_2:
return 200;
+ case KmVersion::KEYMINT_3:
+ return 300;
}
}
/**
* Convert a KeymasterContext::Version to the corresponding attestation format version number.
*/
-inline static uint version_to_attestation_version(KmVersion version) {
+inline static uint32_t version_to_attestation_version(KmVersion version) {
switch (version) {
default:
case KmVersion::KEYMASTER_1:
@@ -441,6 +447,8 @@ inline static uint version_to_attestation_version(KmVersion version) {
return 100;
case KmVersion::KEYMINT_2:
return 200;
+ case KmVersion::KEYMINT_3:
+ return 300;
}
}
diff --git a/include/keymaster/km_openssl/curve25519_key.h b/include/keymaster/km_openssl/curve25519_key.h
index f5f168e..c1aedef 100644
--- a/include/keymaster/km_openssl/curve25519_key.h
+++ b/include/keymaster/km_openssl/curve25519_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <keymaster/km_openssl/asymmetric_key.h>
#include <keymaster/km_openssl/openssl_utils.h>
@@ -36,10 +38,10 @@ class Curve25519Key : public AsymmetricKey {
public:
Curve25519Key(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced,
const KeyFactory* factory)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory) {}
Curve25519Key(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced,
const KeyFactory* factory, const KeymasterKeyBlob& key_material)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory) {
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory) {
key_material_ = key_material;
}
diff --git a/include/keymaster/km_openssl/ec_key.h b/include/keymaster/km_openssl/ec_key.h
index 9ad5c70..e7feb1e 100644
--- a/include/keymaster/km_openssl/ec_key.h
+++ b/include/keymaster/km_openssl/ec_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <openssl/ec.h>
#include <keymaster/km_openssl/asymmetric_key.h>
@@ -28,10 +30,11 @@ class EcdsaOperationFactory;
class EcKey : public AsymmetricKey {
public:
EcKey(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced, const KeyFactory* factory)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory) {}
EcKey(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced, const KeyFactory* factory,
EC_KEY_Ptr ec_key)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory), ec_key_(move(ec_key)) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory),
+ ec_key_(std::move(ec_key)) {}
int evp_key_type() const override { return EVP_PKEY_EC; }
@@ -43,7 +46,8 @@ class EcKey : public AsymmetricKey {
protected:
EcKey(EC_KEY* ec_key, AuthorizationSet hw_enforced, AuthorizationSet sw_enforced,
const KeyFactory* key_factory)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), key_factory), ec_key_(ec_key) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), key_factory),
+ ec_key_(ec_key) {}
private:
EC_KEY_Ptr ec_key_;
diff --git a/include/keymaster/km_openssl/ecdh_operation.h b/include/keymaster/km_openssl/ecdh_operation.h
index 6a96009..00b8a2c 100644
--- a/include/keymaster/km_openssl/ecdh_operation.h
+++ b/include/keymaster/km_openssl/ecdh_operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_ECDH_OPERATION_H_
#define SYSTEM_KEYMASTER_ECDH_OPERATION_H_
+#include <utility>
+
#include <openssl/ec.h>
#include <openssl/evp.h>
@@ -31,7 +33,8 @@ namespace keymaster {
class EcdhOperation : public Operation {
public:
EcdhOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, EVP_PKEY* key)
- : Operation(KM_PURPOSE_AGREE_KEY, move(hw_enforced), move(sw_enforced)), ecdh_key_(key) {}
+ : Operation(KM_PURPOSE_AGREE_KEY, std::move(hw_enforced), std::move(sw_enforced)),
+ ecdh_key_(key) {}
keymaster_error_t Abort() override { return KM_ERROR_OK; }
@@ -51,7 +54,7 @@ class EcdhOperation : public Operation {
class X25519Operation : public EcdhOperation {
public:
X25519Operation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, EVP_PKEY* key)
- : EcdhOperation(move(hw_enforced), move(sw_enforced), key) {}
+ : EcdhOperation(std::move(hw_enforced), std::move(sw_enforced), key) {}
keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
const Buffer& signature, AuthorizationSet* output_params,
diff --git a/include/keymaster/km_openssl/ecdsa_operation.h b/include/keymaster/km_openssl/ecdsa_operation.h
index 457c381..f423bef 100644
--- a/include/keymaster/km_openssl/ecdsa_operation.h
+++ b/include/keymaster/km_openssl/ecdsa_operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
#define SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
+#include <utility>
+
#include <openssl/ec.h>
#include <openssl/evp.h>
@@ -32,7 +34,7 @@ class EcdsaOperation : public Operation {
public:
EcdsaOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_purpose_t purpose, keymaster_digest_t digest, EVP_PKEY* key)
- : Operation(purpose, move(hw_enforced), move(sw_enforced)), digest_(digest),
+ : Operation(purpose, std::move(hw_enforced), std::move(sw_enforced)), digest_(digest),
digest_algorithm_(nullptr), ecdsa_key_(key) {
EVP_MD_CTX_init(&digest_ctx_);
}
@@ -55,7 +57,8 @@ class EcdsaSignOperation : public EcdsaOperation {
public:
EcdsaSignOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, EVP_PKEY* key)
- : EcdsaOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_SIGN, digest, key) {}
+ : EcdsaOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_SIGN, digest,
+ key) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
@@ -70,7 +73,8 @@ class EcdsaVerifyOperation : public EcdsaOperation {
public:
EcdsaVerifyOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, EVP_PKEY* key)
- : EcdsaOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_VERIFY, digest, key) {}
+ : EcdsaOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_VERIFY, digest,
+ key) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
@@ -85,7 +89,7 @@ class Ed25519SignOperation : public EcdsaSignOperation {
public:
Ed25519SignOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, EVP_PKEY* key)
- : EcdsaSignOperation(move(hw_enforced), move(sw_enforced), digest, key) {}
+ : EcdsaSignOperation(std::move(hw_enforced), std::move(sw_enforced), digest, key) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
@@ -119,10 +123,10 @@ class EcdsaSignOperationFactory : public EcdsaOperationFactory {
keymaster_digest_t digest, EVP_PKEY* key) override {
if (IsEd25519Key(hw_enforced, sw_enforced)) {
return new (std::nothrow)
- Ed25519SignOperation(move(hw_enforced), move(sw_enforced), digest, key);
+ Ed25519SignOperation(std::move(hw_enforced), std::move(sw_enforced), digest, key);
} else {
return new (std::nothrow)
- EcdsaSignOperation(move(hw_enforced), move(sw_enforced), digest, key);
+ EcdsaSignOperation(std::move(hw_enforced), std::move(sw_enforced), digest, key);
}
}
};
@@ -133,7 +137,7 @@ class EcdsaVerifyOperationFactory : public EcdsaOperationFactory {
Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, EVP_PKEY* key) override {
return new (std::nothrow)
- EcdsaVerifyOperation(move(hw_enforced), move(sw_enforced), digest, key);
+ EcdsaVerifyOperation(std::move(hw_enforced), std::move(sw_enforced), digest, key);
}
};
diff --git a/include/keymaster/km_openssl/hmac_key.h b/include/keymaster/km_openssl/hmac_key.h
index 55d802a..3e2df2b 100644
--- a/include/keymaster/km_openssl/hmac_key.h
+++ b/include/keymaster/km_openssl/hmac_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include "symmetric_key.h"
namespace keymaster {
@@ -50,7 +52,8 @@ class HmacKey : public SymmetricKey {
public:
HmacKey(KeymasterKeyBlob&& key_material, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory)
- : SymmetricKey(move(key_material), move(hw_enforced), move(sw_enforced), key_factory) {}
+ : SymmetricKey(std::move(key_material), std::move(hw_enforced), std::move(sw_enforced),
+ key_factory) {}
};
} // namespace keymaster
diff --git a/include/keymaster/km_openssl/rsa_key.h b/include/keymaster/km_openssl/rsa_key.h
index 3cd7c3a..6ea6919 100644
--- a/include/keymaster/km_openssl/rsa_key.h
+++ b/include/keymaster/km_openssl/rsa_key.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_RSA_KEY_H_
#define SYSTEM_KEYMASTER_RSA_KEY_H_
+#include <utility>
+
#include <openssl/rsa.h>
#include <keymaster/km_openssl/openssl_utils.h>
@@ -28,10 +30,11 @@ namespace keymaster {
class RsaKey : public AsymmetricKey {
public:
RsaKey(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced, const KeyFactory* factory)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory) {}
RsaKey(AuthorizationSet hw_enforced, AuthorizationSet sw_enforced, const KeyFactory* factory,
RSA_Ptr rsa_key)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), factory), rsa_key_(move(rsa_key)) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), factory),
+ rsa_key_(std::move(rsa_key)) {}
int evp_key_type() const override { return EVP_PKEY_RSA; }
@@ -46,7 +49,8 @@ class RsaKey : public AsymmetricKey {
protected:
RsaKey(RSA* rsa, AuthorizationSet hw_enforced, AuthorizationSet sw_enforced,
const KeyFactory* key_factory)
- : AsymmetricKey(move(hw_enforced), move(sw_enforced), key_factory), rsa_key_(rsa) {}
+ : AsymmetricKey(std::move(hw_enforced), std::move(sw_enforced), key_factory), rsa_key_(rsa)
+ {}
private:
RSA_Ptr rsa_key_;
diff --git a/include/keymaster/km_openssl/rsa_operation.h b/include/keymaster/km_openssl/rsa_operation.h
index 99004f2..cb4422f 100644
--- a/include/keymaster/km_openssl/rsa_operation.h
+++ b/include/keymaster/km_openssl/rsa_operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_RSA_OPERATION_H_
#define SYSTEM_KEYMASTER_RSA_OPERATION_H_
+#include <utility>
+
#include <keymaster/UniquePtr.h>
#include <openssl/evp.h>
@@ -36,7 +38,7 @@ class RsaOperation : public Operation {
RsaOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_purpose_t purpose, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key)
- : Operation(purpose, move(hw_enforced), move(sw_enforced)), rsa_key_(key),
+ : Operation(purpose, std::move(hw_enforced), std::move(sw_enforced)), rsa_key_(key),
padding_(padding), digest_(digest), digest_algorithm_(nullptr) {}
~RsaOperation();
@@ -91,8 +93,8 @@ class RsaSignOperation : public RsaDigestingOperation {
public:
RsaSignOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
- : RsaDigestingOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_SIGN, digest,
- padding, key) {}
+ : RsaDigestingOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_SIGN,
+ digest, padding, key) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
@@ -115,8 +117,8 @@ class RsaVerifyOperation : public RsaDigestingOperation {
public:
RsaVerifyOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
- : RsaDigestingOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_VERIFY, digest,
- padding, key) {}
+ : RsaDigestingOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_VERIFY,
+ digest, padding, key) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
@@ -140,7 +142,8 @@ class RsaCryptOperation : public RsaOperation {
RsaCryptOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_purpose_t purpose, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key)
- : RsaOperation(move(hw_enforced), move(sw_enforced), purpose, digest, padding, key),
+ : RsaOperation(std::move(hw_enforced), std::move(sw_enforced), purpose, digest, padding,
+ key),
mgf_digest_(KM_DIGEST_SHA1), mgf_digest_algorithm_(nullptr) {}
keymaster_digest_t oaepMgfDigest() { return mgf_digest_; }
void setOaepMgfDigest(keymaster_digest_t mgf_digest) { mgf_digest_ = mgf_digest; }
@@ -165,8 +168,8 @@ class RsaEncryptOperation : public RsaCryptOperation {
public:
RsaEncryptOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
- : RsaCryptOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_ENCRYPT, digest,
- padding, key) {}
+ : RsaCryptOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_ENCRYPT,
+ digest, padding, key) {}
keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
const Buffer& signature, AuthorizationSet* output_params,
Buffer* output) override;
@@ -179,8 +182,8 @@ class RsaDecryptOperation : public RsaCryptOperation {
public:
RsaDecryptOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
- : RsaCryptOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_DECRYPT, digest,
- padding, key) {}
+ : RsaCryptOperation(std::move(hw_enforced), std::move(sw_enforced), KM_PURPOSE_DECRYPT,
+ digest, padding, key) {}
keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
const Buffer& signature, AuthorizationSet* output_params,
Buffer* output) override;
@@ -197,7 +200,7 @@ class RsaOperationFactory : public OperationFactory {
OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params,
keymaster_error_t* error) override {
- return OperationPtr(CreateRsaOperation(move(key), begin_params, error));
+ return OperationPtr(CreateRsaOperation(std::move(key), begin_params, error));
}
const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
@@ -246,7 +249,7 @@ class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
AuthorizationSet&& sw_enforced, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key) override {
return new (std::nothrow)
- RsaSignOperation(move(hw_enforced), move(sw_enforced), digest, padding, key);
+ RsaSignOperation(std::move(hw_enforced), std::move(sw_enforced), digest, padding, key);
}
};
@@ -259,7 +262,8 @@ class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
AuthorizationSet&& sw_enforced, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key) override {
return new (std::nothrow)
- RsaVerifyOperation(move(hw_enforced), move(sw_enforced), digest, padding, key);
+ RsaVerifyOperation(std::move(hw_enforced), std::move(sw_enforced), digest, padding,
+ key);
}
};
@@ -272,7 +276,8 @@ class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
AuthorizationSet&& sw_enforced, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key) override {
return new (std::nothrow)
- RsaEncryptOperation(move(hw_enforced), move(sw_enforced), digest, padding, key);
+ RsaEncryptOperation(std::move(hw_enforced), std::move(sw_enforced), digest, padding,
+ key);
}
};
@@ -285,7 +290,8 @@ class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
AuthorizationSet&& sw_enforced, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key) override {
return new (std::nothrow)
- RsaDecryptOperation(move(hw_enforced), move(sw_enforced), digest, padding, key);
+ RsaDecryptOperation(std::move(hw_enforced), std::move(sw_enforced), digest, padding,
+ key);
}
};
diff --git a/include/keymaster/km_openssl/triple_des_key.h b/include/keymaster/km_openssl/triple_des_key.h
index a03d595..5e8f3fc 100644
--- a/include/keymaster/km_openssl/triple_des_key.h
+++ b/include/keymaster/km_openssl/triple_des_key.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_TRIPLE_DES_KEY_H_
#define SYSTEM_KEYMASTER_TRIPLE_DES_KEY_H_
+#include <utility>
+
#include <openssl/des.h>
#include "symmetric_key.h"
@@ -53,7 +55,8 @@ class TripleDesKey : public SymmetricKey {
public:
TripleDesKey(KeymasterKeyBlob&& key_material, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory)
- : SymmetricKey(move(key_material), move(hw_enforced), move(sw_enforced), key_factory) {}
+ : SymmetricKey(std::move(key_material), std::move(hw_enforced), std::move(sw_enforced),
+ key_factory) {}
};
} // namespace keymaster
diff --git a/include/keymaster/km_version.h b/include/keymaster/km_version.h
index 122d045..6287aa3 100644
--- a/include/keymaster/km_version.h
+++ b/include/keymaster/km_version.h
@@ -32,6 +32,7 @@ enum class KmVersion {
KEYMASTER_4_1 = 41,
KEYMINT_1 = 100,
KEYMINT_2 = 200,
+ KEYMINT_3 = 300,
};
}; // namespace keymaster
diff --git a/include/keymaster/legacy_support/ec_keymaster1_key.h b/include/keymaster/legacy_support/ec_keymaster1_key.h
index d695c74..88adf64 100644
--- a/include/keymaster/legacy_support/ec_keymaster1_key.h
+++ b/include/keymaster/legacy_support/ec_keymaster1_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <openssl/ecdsa.h>
#include <hardware/keymaster1.h>
@@ -77,7 +79,7 @@ class EcdsaKeymaster1Key : public EcKey {
public:
EcdsaKeymaster1Key(EC_KEY* ecdsa_key, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory)
- : EcKey(ecdsa_key, move(hw_enforced), move(sw_enforced), key_factory) {}
+ : EcKey(ecdsa_key, std::move(hw_enforced), std::move(sw_enforced), key_factory) {}
};
} // namespace keymaster
diff --git a/include/keymaster/legacy_support/keymaster1_legacy_support.h b/include/keymaster/legacy_support/keymaster1_legacy_support.h
index a09b5e5..531f1a1 100644
--- a/include/keymaster/legacy_support/keymaster1_legacy_support.h
+++ b/include/keymaster/legacy_support/keymaster1_legacy_support.h
@@ -18,6 +18,7 @@
#pragma once
#include <map>
+#include <utility>
#include <vector>
#include <hardware/keymaster1.h>
@@ -61,7 +62,7 @@ template <typename KM1_SOFTDIGEST_FACTORY> class Keymaster1ArbitrationFactory :
Keymaster1ArbitrationFactory(const KeymasterPassthroughEngine* ptengine,
keymaster_algorithm_t algorithm, const keymaster1_device_t* dev,
SOFT_FACTORY_CONSRUCTOR_ARGS&&... args)
- : software_digest_factory_(forward<SOFT_FACTORY_CONSRUCTOR_ARGS>(args)...),
+ : software_digest_factory_(std::forward<SOFT_FACTORY_CONSRUCTOR_ARGS>(args)...),
passthrough_factory_(ptengine, algorithm), legacy_support_(dev) {}
keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
UniquePtr<Key> attest_key, //
@@ -71,11 +72,11 @@ template <typename KM1_SOFTDIGEST_FACTORY> class Keymaster1ArbitrationFactory :
AuthorizationSet* sw_enforced,
CertificateChain* cert_chain) const {
if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
- return software_digest_factory_.GenerateKey(key_description, move(attest_key),
+ return software_digest_factory_.GenerateKey(key_description, std::move(attest_key),
issuer_subject, key_blob, hw_enforced,
sw_enforced, cert_chain);
} else {
- return passthrough_factory_.GenerateKey(key_description, move(attest_key),
+ return passthrough_factory_.GenerateKey(key_description, std::move(attest_key),
issuer_subject, key_blob, hw_enforced,
sw_enforced, cert_chain);
}
@@ -91,12 +92,14 @@ template <typename KM1_SOFTDIGEST_FACTORY> class Keymaster1ArbitrationFactory :
AuthorizationSet* sw_enforced, CertificateChain* cert_chain) const {
if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
return software_digest_factory_.ImportKey(
- key_description, input_key_material_format, input_key_material, move(attest_key),
- issuer_subject, output_key_blob, hw_enforced, sw_enforced, cert_chain);
+ key_description, input_key_material_format, input_key_material,
+ std::move(attest_key), issuer_subject, output_key_blob, hw_enforced, sw_enforced,
+ cert_chain);
} else {
return passthrough_factory_.ImportKey(
- key_description, input_key_material_format, input_key_material, move(attest_key),
- issuer_subject, output_key_blob, hw_enforced, sw_enforced, cert_chain);
+ key_description, input_key_material_format, input_key_material,
+ std::move(attest_key), issuer_subject, output_key_blob, hw_enforced, sw_enforced,
+ cert_chain);
}
}
@@ -111,11 +114,13 @@ template <typename KM1_SOFTDIGEST_FACTORY> class Keymaster1ArbitrationFactory :
if (legacy_support_.RequiresSoftwareDigesting(digest,
AuthProxy(hw_enforced, sw_enforced))) {
- return software_digest_factory_.LoadKey(move(key_material), additional_params,
- move(hw_enforced), move(sw_enforced), key);
+ return software_digest_factory_.LoadKey(std::move(key_material), additional_params,
+ std::move(hw_enforced), std::move(sw_enforced),
+ key);
} else {
- return passthrough_factory_.LoadKey(move(key_material), additional_params,
- move(hw_enforced), move(sw_enforced), key);
+ return passthrough_factory_.LoadKey(std::move(key_material), additional_params,
+ std::move(hw_enforced), std::move(sw_enforced),
+ key);
}
}
diff --git a/include/keymaster/legacy_support/keymaster_passthrough_key.h b/include/keymaster/legacy_support/keymaster_passthrough_key.h
index e262181..859a864 100644
--- a/include/keymaster/legacy_support/keymaster_passthrough_key.h
+++ b/include/keymaster/legacy_support/keymaster_passthrough_key.h
@@ -17,6 +17,8 @@
#pragma once
+#include <utility>
+
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/authorization_set.h>
#include <keymaster/key.h>
@@ -84,9 +86,9 @@ class KeymasterPassthroughKey : public Key {
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory,
keymaster_error_t* error, const AuthorizationSet& additional_parameters,
const KeymasterPassthroughEngine* engine)
- : Key(move(hw_enforced), move(sw_enforced), key_factory),
+ : Key(std::move(hw_enforced), std::move(sw_enforced), key_factory),
additional_parameters_(additional_parameters), engine_(engine) {
- key_material_ = move(key_material);
+ key_material_ = std::move(key_material);
if (*error != KM_ERROR_OK) return;
if (additional_parameters.is_valid() != additional_parameters_.is_valid() &&
additional_parameters_.is_valid() == AuthorizationSet::ALLOCATION_FAILURE) {
diff --git a/include/keymaster/legacy_support/rsa_keymaster1_key.h b/include/keymaster/legacy_support/rsa_keymaster1_key.h
index e114aef..939f9d8 100644
--- a/include/keymaster/legacy_support/rsa_keymaster1_key.h
+++ b/include/keymaster/legacy_support/rsa_keymaster1_key.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <openssl/rsa.h>
#include <keymaster/km_openssl/rsa_key.h>
@@ -79,7 +81,7 @@ class RsaKeymaster1Key : public RsaKey {
public:
RsaKeymaster1Key(RSA* rsa_key, AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
const KeyFactory* key_factory)
- : RsaKey(rsa_key, move(hw_enforced), move(sw_enforced), key_factory) {}
+ : RsaKey(rsa_key, std::move(hw_enforced), std::move(sw_enforced), key_factory) {}
};
} // namespace keymaster
diff --git a/include/keymaster/mem.h b/include/keymaster/mem.h
index 6d5de1b..6593099 100644
--- a/include/keymaster/mem.h
+++ b/include/keymaster/mem.h
@@ -18,9 +18,6 @@
namespace keymaster {
-using std::forward;
-using std::move;
-
/*
* Array Manipulation functions. This set of templated inline functions provides some nice tools
* for operating on c-style arrays. C-style arrays actually do have a defined size associated with
diff --git a/include/keymaster/operation.h b/include/keymaster/operation.h
index aa02599..5643595 100644
--- a/include/keymaster/operation.h
+++ b/include/keymaster/operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_OPERATION_H_
#define SYSTEM_KEYMASTER_OPERATION_H_
+#include <utility>
+
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
@@ -93,7 +95,8 @@ class Operation {
public:
explicit Operation(keymaster_purpose_t purpose, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced)
- : purpose_(purpose), hw_enforced_(move(hw_enforced)), sw_enforced_(move(sw_enforced)) {}
+ : purpose_(purpose), hw_enforced_(std::move(hw_enforced)),
+ sw_enforced_(std::move(sw_enforced)) {}
virtual ~Operation() {}
Operation(const Operation&) = delete;
diff --git a/include/keymaster/remote_provisioning_context.h b/include/keymaster/remote_provisioning_context.h
index fee1d44..cc65502 100644
--- a/include/keymaster/remote_provisioning_context.h
+++ b/include/keymaster/remote_provisioning_context.h
@@ -23,6 +23,7 @@
#include <vector>
#include <cppbor.h>
+#include <keymaster/android_keymaster_messages.h>
#include <keymaster/cppcose/cppcose.h>
namespace keymaster {
@@ -33,7 +34,7 @@ class RemoteProvisioningContext {
virtual ~RemoteProvisioningContext(){};
virtual std::vector<uint8_t> DeriveBytesFromHbk(const std::string& context,
size_t numBytes) const = 0;
- virtual std::unique_ptr<cppbor::Map> CreateDeviceInfo() const = 0;
+ virtual std::unique_ptr<cppbor::Map> CreateDeviceInfo(uint32_t csrVersion) const = 0;
virtual cppcose::ErrMsgOr<std::vector<uint8_t>>
BuildProtectedDataPayload(bool testMode, //
const std::vector<uint8_t>& macKey, //
@@ -42,6 +43,9 @@ class RemoteProvisioningContext {
// input hasn't changed across multiple calls to the remote provisioning HAL.
virtual std::optional<cppcose::HmacSha256>
GenerateHmacSha256(const cppcose::bytevec& input) const = 0;
+ virtual void GetHwInfo(GetHwInfoResponse* hwInfo) const = 0;
+ virtual cppcose::ErrMsgOr<cppbor::Array> BuildCsr(const std::vector<uint8_t>& challenge,
+ cppbor::Array keysToSign) const = 0;
private:
// Uncopyable.
diff --git a/include/keymaster/remote_provisioning_utils.h b/include/keymaster/remote_provisioning_utils.h
index 9fc0d2e..e51d418 100644
--- a/include/keymaster/remote_provisioning_utils.h
+++ b/include/keymaster/remote_provisioning_utils.h
@@ -30,6 +30,7 @@ constexpr keymaster_error_t kStatusInvalidMac = static_cast<keymaster_error_t>(-
constexpr keymaster_error_t kStatusProductionKeyInTestRequest = static_cast<keymaster_error_t>(-3);
constexpr keymaster_error_t kStatusTestKeyInProductionRequest = static_cast<keymaster_error_t>(-4);
constexpr keymaster_error_t kStatusInvalidEek = static_cast<keymaster_error_t>(-5);
+constexpr keymaster_error_t kStatusRemoved = static_cast<keymaster_error_t>(-6);
template <typename T> class StatusOr {
public:
@@ -68,7 +69,7 @@ template <typename T> class StatusOr {
StatusOr<std::pair<std::vector<uint8_t> /* EEK pub */, std::vector<uint8_t> /* EEK ID */>>
validateAndExtractEekPubAndId(bool testMode, const KeymasterBlob& endpointEncryptionCertChain);
-StatusOr<std::vector<uint8_t> /* pubkeys */>
+StatusOr<cppbor::Array /* pubkeys */>
validateAndExtractPubkeys(bool testMode, uint32_t numKeys, KeymasterBlob* keysToSign,
const cppcose::HmacSha256Function& macFunction);
diff --git a/include/keymaster/serializable.h b/include/keymaster/serializable.h
index f043574..09e98b1 100644
--- a/include/keymaster/serializable.h
+++ b/include/keymaster/serializable.h
@@ -22,6 +22,7 @@
#include <string.h>
#include <iterator>
+#include <utility>
#include <keymaster/UniquePtr.h>
#include <keymaster/logger.h>
@@ -251,14 +252,14 @@ class Buffer : public Serializable {
Buffer() : buffer_(nullptr), buffer_size_(0), read_position_(0), write_position_(0) {}
explicit Buffer(size_t size) : buffer_(nullptr) { Reinitialize(size); }
Buffer(const void* buf, size_t size) : buffer_(nullptr) { Reinitialize(buf, size); }
- Buffer(Buffer&& b) { *this = move(b); }
+ Buffer(Buffer&& b) { *this = std::move(b); }
Buffer(const Buffer&) = delete;
~Buffer() { Clear(); }
Buffer& operator=(Buffer&& other) {
if (this == &other) return *this;
- buffer_ = move(other.buffer_);
+ buffer_ = std::move(other.buffer_);
buffer_size_ = other.buffer_size_;
other.buffer_size_ = 0;
read_position_ = other.read_position_;
diff --git a/key_blob_utils/auth_encrypted_key_blob.cpp b/key_blob_utils/auth_encrypted_key_blob.cpp
index 3cdcf5c..c726d4d 100644
--- a/key_blob_utils/auth_encrypted_key_blob.cpp
+++ b/key_blob_utils/auth_encrypted_key_blob.cpp
@@ -16,6 +16,8 @@
#include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>
+#include <utility>
+
#include <openssl/digest.h>
#include <openssl/evp.h>
#include <openssl/hkdf.h>
@@ -139,7 +141,7 @@ KmErrorOr<EncryptedKey> AesGcmEncryptKey(const AuthorizationSet& hw_enforced,
EncryptedKey retval;
retval.format = format;
retval.ciphertext = KeymasterKeyBlob(ciphertext_len);
- retval.nonce = move(nonce);
+ retval.nonce = std::move(nonce);
retval.tag = Buffer(kAesGcmTagLength);
if (!(EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr /* engine */, kek->peek_read(),
diff --git a/key_blob_utils/software_keyblobs.cpp b/key_blob_utils/software_keyblobs.cpp
index 8897545..3a2929e 100644
--- a/key_blob_utils/software_keyblobs.cpp
+++ b/key_blob_utils/software_keyblobs.cpp
@@ -95,7 +95,7 @@ keymaster_error_t FakeKeyAuthorizations(EVP_PKEY* pubkey, AuthorizationSet* hw_e
hw_enforced->Clear();
sw_enforced->Clear();
- switch (EVP_PKEY_type(pubkey->type)) {
+ switch (EVP_PKEY_id(pubkey)) {
case EVP_PKEY_RSA: {
hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
@@ -196,7 +196,7 @@ keymaster_error_t ParseOldSoftkeymasterBlob(const KeymasterKeyBlob& blob,
}
p += publicLen;
- if (end - p < 2) {
+ if (end - p < sizeof(type)) {
LOG_W("key blob appears to be truncated (if an old SW key)", 0);
return KM_ERROR_INVALID_KEY_BLOB;
}
@@ -318,6 +318,7 @@ keymaster_error_t SetKeyBlobAuthorizations(const AuthorizationSet& key_descripti
case KM_TAG_ATTESTATION_ID_BRAND:
case KM_TAG_ATTESTATION_ID_DEVICE:
case KM_TAG_ATTESTATION_ID_IMEI:
+ case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
case KM_TAG_ATTESTATION_ID_MANUFACTURER:
case KM_TAG_ATTESTATION_ID_MEID:
case KM_TAG_ATTESTATION_ID_MODEL:
diff --git a/km_openssl/aes_key.cpp b/km_openssl/aes_key.cpp
index 5df9e9e..04fa087 100644
--- a/km_openssl/aes_key.cpp
+++ b/km_openssl/aes_key.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/aes_key.h>
+#include <utility>
+
#include <assert.h>
#include <openssl/err.h>
@@ -60,7 +62,8 @@ keymaster_error_t AesKeyFactory::LoadKey(KeymasterKeyBlob&& key_material,
keymaster_error_t error = KM_ERROR_OK;
key->reset(new (std::nothrow)
- AesKey(move(key_material), move(hw_enforced), move(sw_enforced), this));
+ AesKey(std::move(key_material), std::move(hw_enforced), std::move(sw_enforced),
+ this));
if (!key->get()) error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
return error;
}
diff --git a/km_openssl/asymmetric_key_factory.cpp b/km_openssl/asymmetric_key_factory.cpp
index 963694c..2fa1018 100644
--- a/km_openssl/asymmetric_key_factory.cpp
+++ b/km_openssl/asymmetric_key_factory.cpp
@@ -16,6 +16,8 @@
#include <keymaster/asymmetric_key_factory.h>
+#include <utility>
+
#include <keymaster/android_keymaster_utils.h>
#include <keymaster/km_openssl/asymmetric_key.h>
@@ -44,11 +46,12 @@ keymaster_error_t AsymmetricKeyFactory::LoadKey(KeymasterKeyBlob&& key_material,
AuthorizationSet&& sw_enforced,
UniquePtr<Key>* key) const {
UniquePtr<AsymmetricKey> asym_key;
- keymaster_error_t error = CreateEmptyKey(move(hw_enforced), move(sw_enforced), &asym_key);
+ keymaster_error_t error = CreateEmptyKey(std::move(hw_enforced), std::move(sw_enforced),
+ &asym_key);
if (error != KM_ERROR_OK) return error;
const uint8_t* tmp = key_material.key_material;
- asym_key->key_material() = move(key_material);
+ asym_key->key_material() = std::move(key_material);
EVP_PKEY* pkey = d2i_PrivateKey(asym_key->evp_key_type(), nullptr /* pkey */, &tmp,
asym_key->key_material().key_material_size);
diff --git a/km_openssl/attestation_record.cpp b/km_openssl/attestation_record.cpp
index f413064..36cf320 100644
--- a/km_openssl/attestation_record.cpp
+++ b/km_openssl/attestation_record.cpp
@@ -47,10 +47,11 @@ IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
IMPLEMENT_ASN1_FUNCTIONS(KM_KEY_DESCRIPTION);
static const keymaster_tag_t kDeviceAttestationTags[] = {
- KM_TAG_ATTESTATION_ID_BRAND, KM_TAG_ATTESTATION_ID_DEVICE, KM_TAG_ATTESTATION_ID_PRODUCT,
- KM_TAG_ATTESTATION_ID_SERIAL, KM_TAG_ATTESTATION_ID_IMEI, KM_TAG_ATTESTATION_ID_MEID,
+ KM_TAG_ATTESTATION_ID_BRAND, KM_TAG_ATTESTATION_ID_DEVICE,
+ KM_TAG_ATTESTATION_ID_PRODUCT, KM_TAG_ATTESTATION_ID_SERIAL,
+ KM_TAG_ATTESTATION_ID_IMEI, KM_TAG_ATTESTATION_ID_MEID,
KM_TAG_ATTESTATION_ID_MANUFACTURER, KM_TAG_ATTESTATION_ID_MODEL,
-};
+ KM_TAG_ATTESTATION_ID_SECOND_IMEI};
struct KM_AUTH_LIST_Delete {
void operator()(KM_AUTH_LIST* p) { KM_AUTH_LIST_free(p); }
@@ -679,6 +680,9 @@ keymaster_error_t build_auth_list(const AuthorizationSet& auth_list, KM_AUTH_LIS
case KM_TAG_ATTESTATION_ID_IMEI:
string_ptr = &record->attestation_id_imei;
break;
+ case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
+ string_ptr = &record->attestation_id_second_imei;
+ break;
case KM_TAG_ATTESTATION_ID_MEID:
string_ptr = &record->attestation_id_meid;
break;
@@ -936,31 +940,47 @@ keymaster_error_t build_eat_record(const AuthorizationSet& attestation_params,
return KM_ERROR_OK;
}
-std::vector<uint8_t> build_unique_id_input(uint64_t creation_date_time,
- const keymaster_blob_t& application_id,
- bool reset_since_rotation) {
+keymaster_error_t build_unique_id_input(uint64_t creation_date_time,
+ const keymaster_blob_t& application_id,
+ bool reset_since_rotation, Buffer* input_data) {
+ if (input_data == nullptr) {
+ return KM_ERROR_UNEXPECTED_NULL_POINTER;
+ }
uint64_t rounded_date = creation_date_time / 2592000000LLU;
uint8_t* serialized_date = reinterpret_cast<uint8_t*>(&rounded_date);
+ uint8_t reset_byte = (reset_since_rotation ? 1 : 0);
- std::vector<uint8_t> input;
- input.insert(input.end(), serialized_date, serialized_date + sizeof(rounded_date));
- input.insert(input.end(), application_id.data,
- application_id.data + application_id.data_length);
- input.push_back(reset_since_rotation ? 1 : 0);
- return input;
+ if (!input_data->Reinitialize(sizeof(rounded_date) + application_id.data_length + 1) ||
+ !input_data->write(serialized_date, sizeof(rounded_date)) ||
+ !input_data->write(application_id.data, application_id.data_length) ||
+ !input_data->write(&reset_byte, 1)) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ return KM_ERROR_OK;
}
-Buffer generate_unique_id(const std::vector<uint8_t>& hbk, uint64_t creation_date_time,
- const keymaster_blob_t& application_id, bool reset_since_rotation) {
+keymaster_error_t generate_unique_id(const std::vector<uint8_t>& hbk, uint64_t creation_date_time,
+ const keymaster_blob_t& application_id,
+ bool reset_since_rotation, Buffer* unique_id) {
+ if (unique_id == nullptr) {
+ return KM_ERROR_UNEXPECTED_NULL_POINTER;
+ }
HmacSha256 hmac;
hmac.Init(hbk.data(), hbk.size());
- std::vector<uint8_t> input =
- build_unique_id_input(creation_date_time, application_id, reset_since_rotation);
- Buffer unique_id(UNIQUE_ID_SIZE);
- hmac.Sign(input.data(), input.size(), unique_id.peek_write(), unique_id.available_write());
- unique_id.advance_write(UNIQUE_ID_SIZE);
- return unique_id;
+ Buffer input;
+ keymaster_error_t error =
+ build_unique_id_input(creation_date_time, application_id, reset_since_rotation, &input);
+ if (error != KM_ERROR_OK) {
+ return error;
+ }
+ if (!unique_id->Reinitialize(UNIQUE_ID_SIZE)) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ hmac.Sign(input.peek_read(), input.available_read(), unique_id->peek_write(),
+ unique_id->available_write());
+ unique_id->advance_write(UNIQUE_ID_SIZE);
+ return KM_ERROR_OK;
}
// Construct an ASN1.1 DER-encoded attestation record containing the values from sw_enforced and
@@ -1388,6 +1408,14 @@ keymaster_error_t extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
+ // Second IMEI
+ if (record->attestation_id_second_imei &&
+ !auth_list->push_back(TAG_ATTESTATION_ID_SECOND_IMEI,
+ record->attestation_id_second_imei->data,
+ record->attestation_id_second_imei->length)) {
+ 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 e9a6aa3..a288446 100644
--- a/km_openssl/attestation_utils.cpp
+++ b/km_openssl/attestation_utils.cpp
@@ -15,6 +15,8 @@
** limitations under the License.
*/
+#include <utility>
+
#include <openssl/evp.h>
#include <openssl/x509v3.h>
@@ -146,7 +148,7 @@ keymaster_error_t make_attestation_cert(const EVP_PKEY* evp_pkey, const X509_NAM
return error;
}
- *cert_out = move(certificate);
+ *cert_out = std::move(certificate);
return KM_ERROR_OK;
}
@@ -266,7 +268,7 @@ CertificateChain generate_attestation(const AsymmetricKey& key,
}
return generate_attestation(pkey.get(), key.sw_enforced(), key.hw_enforced(), attest_params,
- move(attest_key), context, error);
+ std::move(attest_key), context, error);
}
CertificateChain generate_attestation(const EVP_PKEY* evp_key, //
@@ -317,7 +319,7 @@ CertificateChain generate_attestation(const EVP_PKEY* evp_key, //
*error = sign_cert(certificate.get(), signing_key_ptr);
if (*error != KM_ERROR_OK) return {};
- return make_cert_chain(certificate.get(), move(cert_chain), error);
+ return make_cert_chain(certificate.get(), std::move(cert_chain), error);
}
} // namespace keymaster
diff --git a/km_openssl/block_cipher_operation.cpp b/km_openssl/block_cipher_operation.cpp
index a381e75..296cb9c 100644
--- a/km_openssl/block_cipher_operation.cpp
+++ b/km_openssl/block_cipher_operation.cpp
@@ -16,6 +16,8 @@
#include "block_cipher_operation.h"
+#include <utility>
+
#include <stdio.h>
#include <keymaster/UniquePtr.h>
@@ -117,11 +119,12 @@ OperationPtr BlockCipherOperationFactory::CreateOperation(Key&& key,
switch (purpose_) {
case KM_PURPOSE_ENCRYPT:
op.reset(new (std::nothrow) BlockCipherEvpEncryptOperation( //
- block_mode, padding, caller_nonce, tag_length, move(key), GetCipherDescription()));
+ block_mode, padding, caller_nonce, tag_length, std::move(key),
+ GetCipherDescription()));
break;
case KM_PURPOSE_DECRYPT:
op.reset(new (std::nothrow) BlockCipherEvpDecryptOperation(
- block_mode, padding, tag_length, move(key), GetCipherDescription()));
+ block_mode, padding, tag_length, std::move(key), GetCipherDescription()));
break;
default:
*error = KM_ERROR_UNSUPPORTED_PURPOSE;
diff --git a/km_openssl/block_cipher_operation.h b/km_openssl/block_cipher_operation.h
index 9c25bda..cd78805 100644
--- a/km_openssl/block_cipher_operation.h
+++ b/km_openssl/block_cipher_operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_
#define SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_
+#include <utility>
+
#include <openssl/evp.h>
#include <keymaster/operation.h>
@@ -121,7 +123,7 @@ class BlockCipherEvpEncryptOperation : public BlockCipherEvpOperation {
bool caller_iv, size_t tag_length, Key&& key,
const EvpCipherDescription& cipher_description)
: BlockCipherEvpOperation(KM_PURPOSE_ENCRYPT, block_mode, padding, caller_iv, tag_length,
- move(key), cipher_description) {}
+ std::move(key), cipher_description) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
AuthorizationSet* output_params) override;
@@ -141,7 +143,7 @@ class BlockCipherEvpDecryptOperation : public BlockCipherEvpOperation {
size_t tag_length, Key&& key,
const EvpCipherDescription& cipher_description)
: BlockCipherEvpOperation(KM_PURPOSE_DECRYPT, block_mode, padding,
- false /* caller_iv -- don't care */, tag_length, move(key),
+ false /* caller_iv -- don't care */, tag_length, std::move(key),
cipher_description) {}
keymaster_error_t Begin(const AuthorizationSet& input_params,
diff --git a/km_openssl/certificate_utils.cpp b/km_openssl/certificate_utils.cpp
index 9118c68..17a34b0 100644
--- a/km_openssl/certificate_utils.cpp
+++ b/km_openssl/certificate_utils.cpp
@@ -15,6 +15,7 @@
*/
#include <iostream>
+#include <utility>
#include <openssl/asn1.h>
#include <openssl/evp.h>
@@ -40,7 +41,7 @@ constexpr int kKeyAgreementKeyUsageBit = 4;
constexpr int kMaxKeyUsageBit = 8;
template <typename T> T&& min(T&& a, T&& b) {
- return (a < b) ? forward<T>(a) : forward<T>(b);
+ return (a < b) ? std::forward<T>(a) : std::forward<T>(b);
}
keymaster_error_t fake_sign_cert(X509* cert) {
@@ -76,7 +77,7 @@ keymaster_error_t make_name_from_str(const char name[], X509_NAME_Ptr* name_out)
0 /* set */)) {
return TranslateLastOpenSslError();
}
- *name_out = move(x509_name);
+ *name_out = std::move(x509_name);
return KM_ERROR_OK;
}
@@ -89,7 +90,7 @@ keymaster_error_t make_name_from_der(const keymaster_blob_t& name, X509_NAME_Ptr
return TranslateLastOpenSslError();
}
- *name_out = move(x509_name);
+ *name_out = std::move(x509_name);
return KM_ERROR_OK;
}
@@ -124,7 +125,7 @@ keymaster_error_t get_certificate_params(const AuthorizationSet& caller_params,
// Default serial is one.
BN_one(serial.get());
}
- cert_params->serial = move(serial);
+ cert_params->serial = std::move(serial);
cert_params->active_date_time = 0;
cert_params->expire_date_time = kUndefinedExpirationDateTime;
@@ -228,7 +229,7 @@ keymaster_error_t make_key_usage_extension(bool is_signing_key, bool is_encrypti
return TranslateLastOpenSslError();
}
- *usage_extension_out = move(key_usage_extension);
+ *usage_extension_out = std::move(key_usage_extension);
return KM_ERROR_OK;
}
@@ -285,7 +286,7 @@ keymaster_error_t make_cert_rump(const X509_NAME* issuer,
return TranslateLastOpenSslError();
}
- *cert_out = move(certificate);
+ *cert_out = std::move(certificate);
return KM_ERROR_OK;
}
@@ -315,7 +316,7 @@ keymaster_error_t make_cert(const EVP_PKEY* evp_pkey, const X509_NAME* issuer,
return TranslateLastOpenSslError();
}
- *cert_out = move(certificate);
+ *cert_out = std::move(certificate);
return KM_ERROR_OK;
}
diff --git a/km_openssl/ec_key_factory.cpp b/km_openssl/ec_key_factory.cpp
index 4ec3175..087ca63 100644
--- a/km_openssl/ec_key_factory.cpp
+++ b/km_openssl/ec_key_factory.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/ec_key_factory.h>
+#include <utility>
+
#include <openssl/curve25519.h>
#include <openssl/evp.h>
@@ -178,14 +180,14 @@ keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_descript
} else if (is_x25519) {
key.reset(new (std::nothrow) X25519Key(*hw_enforced, *sw_enforced, this, key_material));
} else {
- key.reset(new (std::nothrow) EcKey(*hw_enforced, *sw_enforced, this, move(ec_key)));
+ key.reset(new (std::nothrow) EcKey(*hw_enforced, *sw_enforced, this, std::move(ec_key)));
}
if (key == nullptr) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
if (key_description.Contains(TAG_ATTESTATION_CHALLENGE)) {
- *cert_chain = context_.GenerateAttestation(*key, key_description, move(attest_key),
+ *cert_chain = context_.GenerateAttestation(*key, key_description, std::move(attest_key),
issuer_subject, &error);
} else if (attest_key.get() != nullptr) {
return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
@@ -207,8 +209,8 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio
AuthorizationSet* sw_enforced,
CertificateChain* cert_chain) const {
if (input_key_material_format == KM_KEY_FORMAT_RAW) {
- return ImportRawKey(key_description, input_key_material, move(attest_key), issuer_subject,
- output_key_blob, hw_enforced, sw_enforced, cert_chain);
+ return ImportRawKey(key_description, input_key_material, std::move(attest_key),
+ issuer_subject, output_key_blob, hw_enforced, sw_enforced, cert_chain);
}
if (!output_key_blob || !hw_enforced || !sw_enforced) return KM_ERROR_OUTPUT_PARAMETER_NULL;
@@ -231,7 +233,7 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio
if (error != KM_ERROR_OK) return error;
std::unique_ptr<AsymmetricKey> key;
- switch (EVP_PKEY_type(pkey->type)) {
+ switch (EVP_PKEY_id(pkey.get())) {
case EVP_PKEY_ED25519:
key.reset(new (std::nothrow) Ed25519Key(*hw_enforced, *sw_enforced, this));
if (key.get() == nullptr) {
@@ -254,7 +256,7 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio
EC_KEY_Ptr ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
if (!ec_key.get()) return KM_ERROR_INVALID_ARGUMENT;
- key.reset(new (std::nothrow) EcKey(*hw_enforced, *sw_enforced, this, move(ec_key)));
+ key.reset(new (std::nothrow) EcKey(*hw_enforced, *sw_enforced, this, std::move(ec_key)));
if (key.get() == nullptr) {
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
}
@@ -268,7 +270,7 @@ keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_descriptio
}
if (key_description.Contains(KM_TAG_ATTESTATION_CHALLENGE)) {
- *cert_chain = context_.GenerateAttestation(*key, key_description, move(attest_key),
+ *cert_chain = context_.GenerateAttestation(*key, key_description, std::move(attest_key),
issuer_subject, &error);
} else if (attest_key.get() != nullptr) {
return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
@@ -359,7 +361,7 @@ keymaster_error_t EcKeyFactory::ImportRawKey(const AuthorizationSet& key_descrip
}
if (key_description.Contains(KM_TAG_ATTESTATION_CHALLENGE)) {
- *cert_chain = context_.GenerateAttestation(*key, key_description, move(attest_key),
+ *cert_chain = context_.GenerateAttestation(*key, key_description, std::move(attest_key),
issuer_subject, &error);
} else if (attest_key.get() != nullptr) {
return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
@@ -392,7 +394,7 @@ keymaster_error_t EcKeyFactory::UpdateImportKeyDescription(const AuthorizationSe
return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
}
- switch (EVP_PKEY_type(pkey->type)) {
+ switch (EVP_PKEY_id(pkey.get())) {
case EVP_PKEY_EC: {
UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
if (!ec_key.get()) return TranslateLastOpenSslError();
@@ -509,11 +511,13 @@ keymaster_error_t EcKeyFactory::CreateEmptyKey(AuthorizationSet&& hw_enforced,
if (is_x25519) {
return KM_ERROR_INCOMPATIBLE_PURPOSE;
}
- key->reset(new (std::nothrow) Ed25519Key(move(hw_enforced), move(sw_enforced), this));
+ key->reset(new (std::nothrow) Ed25519Key(std::move(hw_enforced), std::move(sw_enforced),
+ this));
} else if (is_x25519) {
- key->reset(new (std::nothrow) X25519Key(move(hw_enforced), move(sw_enforced), this));
+ key->reset(new (std::nothrow) X25519Key(std::move(hw_enforced), std::move(sw_enforced),
+ this));
} else {
- key->reset(new (std::nothrow) EcKey(move(hw_enforced), move(sw_enforced), this));
+ key->reset(new (std::nothrow) EcKey(std::move(hw_enforced), std::move(sw_enforced), this));
}
if (!(*key)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
return KM_ERROR_OK;
diff --git a/km_openssl/ecdh_operation.cpp b/km_openssl/ecdh_operation.cpp
index 47f7361..1fa68df 100644
--- a/km_openssl/ecdh_operation.cpp
+++ b/km_openssl/ecdh_operation.cpp
@@ -16,13 +16,15 @@
#include <keymaster/km_openssl/ecdh_operation.h>
+#include <utility>
+#include <vector>
+
#include <keymaster/km_openssl/ec_key.h>
#include <keymaster/km_openssl/openssl_err.h>
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymaster/logger.h>
#include <openssl/curve25519.h>
#include <openssl/err.h>
-#include <vector>
namespace keymaster {
@@ -149,14 +151,14 @@ OperationPtr EcdhOperationFactory::CreateOperation(Key&& key,
*error = KM_ERROR_OK;
EcdhOperation* op = nullptr;
- switch (EVP_PKEY_type(pkey->type)) {
+ switch (EVP_PKEY_id(pkey.get())) {
case EVP_PKEY_X25519:
- op = new (std::nothrow) X25519Operation(move(key.hw_enforced_move()),
- move(key.sw_enforced_move()), pkey.release());
+ op = new (std::nothrow) X25519Operation(std::move(key.hw_enforced_move()),
+ std::move(key.sw_enforced_move()), pkey.release());
break;
case EVP_PKEY_EC:
- op = new (std::nothrow) EcdhOperation(move(key.hw_enforced_move()),
- move(key.sw_enforced_move()), pkey.release());
+ op = new (std::nothrow) EcdhOperation(std::move(key.hw_enforced_move()),
+ std::move(key.sw_enforced_move()), pkey.release());
break;
default:
*error = KM_ERROR_UNKNOWN_ERROR;
diff --git a/km_openssl/hmac_key.cpp b/km_openssl/hmac_key.cpp
index d74ff37..c8f2444 100644
--- a/km_openssl/hmac_key.cpp
+++ b/km_openssl/hmac_key.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/hmac_key.h>
+#include <utility>
+
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -52,7 +54,8 @@ keymaster_error_t HmacKeyFactory::LoadKey(KeymasterKeyBlob&& key_material,
}
key->reset(new (std::nothrow)
- HmacKey(move(key_material), move(hw_enforced), move(sw_enforced), this));
+ HmacKey(std::move(key_material), std::move(hw_enforced), std::move(sw_enforced),
+ this));
if (!key->get()) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
return KM_ERROR_OK;
}
diff --git a/km_openssl/hmac_operation.cpp b/km_openssl/hmac_operation.cpp
index 759ca12..a05e200 100644
--- a/km_openssl/hmac_operation.cpp
+++ b/km_openssl/hmac_operation.cpp
@@ -16,6 +16,8 @@
#include "hmac_operation.h"
+#include <utility>
+
#include <openssl/evp.h>
#include <openssl/hmac.h>
@@ -69,7 +71,7 @@ OperationPtr HmacOperationFactory::CreateOperation(Key&& key, const Authorizatio
}
UniquePtr<HmacOperation> op(new (std::nothrow) HmacOperation(
- move(key), purpose(), digest, mac_length_bits / 8, min_mac_length_bits / 8));
+ std::move(key), purpose(), digest, mac_length_bits / 8, min_mac_length_bits / 8));
if (!op.get())
*error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
else
@@ -77,7 +79,7 @@ OperationPtr HmacOperationFactory::CreateOperation(Key&& key, const Authorizatio
if (*error != KM_ERROR_OK) return nullptr;
- return move(op);
+ return std::move(op);
}
static keymaster_digest_t supported_digests[] = {KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
diff --git a/km_openssl/openssl_utils.cpp b/km_openssl/openssl_utils.cpp
index 2672cdc..6b91ecc 100644
--- a/km_openssl/openssl_utils.cpp
+++ b/km_openssl/openssl_utils.cpp
@@ -80,7 +80,7 @@ keymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_
// Check the key type detected from the PKCS8 blob matches the KM algorithm we expect.
keymaster_algorithm_t got_algorithm;
- switch (EVP_PKEY_type((*pkey)->type)) {
+ switch (EVP_PKEY_id(pkey->get())) {
case EVP_PKEY_RSA:
got_algorithm = KM_ALGORITHM_RSA;
break;
@@ -91,13 +91,13 @@ keymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_
break;
default:
LOG_E("EVP key algorithm was unknown (type %d), not the expected %d",
- EVP_PKEY_type((*pkey)->type), expected_algorithm);
+ EVP_PKEY_id(pkey->get()), expected_algorithm);
return KM_ERROR_INVALID_KEY_BLOB;
}
if (expected_algorithm != got_algorithm) {
LOG_E("EVP key algorithm was %d (from type %d), not the expected %d", got_algorithm,
- EVP_PKEY_type((*pkey)->type), expected_algorithm);
+ EVP_PKEY_id(pkey->get()), expected_algorithm);
return KM_ERROR_INVALID_KEY_BLOB;
}
@@ -115,7 +115,7 @@ keymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
}
keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* pkey, KeymasterKeyBlob* key_blob) {
- switch (EVP_PKEY_type(pkey->type)) {
+ switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_ED25519:
case EVP_PKEY_X25519: {
// BoringSSL's i2d_PrivateKey does not handle curve 25519 keys.
diff --git a/km_openssl/rsa_key_factory.cpp b/km_openssl/rsa_key_factory.cpp
index ed7162d..27f64e4 100644
--- a/km_openssl/rsa_key_factory.cpp
+++ b/km_openssl/rsa_key_factory.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/rsa_key_factory.h>
+#include <utility>
+
#include <keymaster/keymaster_context.h>
#include <keymaster/km_openssl/openssl_err.h>
#include <keymaster/km_openssl/openssl_utils.h>
@@ -101,9 +103,9 @@ keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_descrip
if (context_.GetKmVersion() < KmVersion::KEYMINT_1) return KM_ERROR_OK;
if (!cert_chain) return KM_ERROR_UNEXPECTED_NULL_POINTER;
- RsaKey key(*hw_enforced, *sw_enforced, this, move(rsa_key));
+ RsaKey key(*hw_enforced, *sw_enforced, this, std::move(rsa_key));
if (key_description.Contains(TAG_ATTESTATION_CHALLENGE)) {
- *cert_chain = context_.GenerateAttestation(key, key_description, move(attest_key),
+ *cert_chain = context_.GenerateAttestation(key, key_description, std::move(attest_key),
issuer_subject, &error);
} else if (attest_key.get() != nullptr) {
return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
@@ -148,9 +150,9 @@ keymaster_error_t RsaKeyFactory::ImportKey(const AuthorizationSet& key_descripti
RSA_Ptr rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
if (!rsa_key.get()) return KM_ERROR_INVALID_ARGUMENT;
- RsaKey key(*hw_enforced, *sw_enforced, this, move(rsa_key));
+ RsaKey key(*hw_enforced, *sw_enforced, this, std::move(rsa_key));
if (key_description.Contains(KM_TAG_ATTESTATION_CHALLENGE)) {
- *cert_chain = context_.GenerateAttestation(key, key_description, move(attest_key),
+ *cert_chain = context_.GenerateAttestation(key, key_description, std::move(attest_key),
issuer_subject, &error);
} else if (attest_key.get() != nullptr) {
return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
@@ -212,7 +214,7 @@ keymaster_error_t RsaKeyFactory::UpdateImportKeyDescription(const AuthorizationS
keymaster_error_t RsaKeyFactory::CreateEmptyKey(AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced,
UniquePtr<AsymmetricKey>* key) const {
- key->reset(new (std::nothrow) RsaKey(move(hw_enforced), move(sw_enforced), this));
+ key->reset(new (std::nothrow) RsaKey(std::move(hw_enforced), std::move(sw_enforced), this));
if (!(*key)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
return KM_ERROR_OK;
}
diff --git a/km_openssl/rsa_operation.cpp b/km_openssl/rsa_operation.cpp
index a4710d4..e445321 100644
--- a/km_openssl/rsa_operation.cpp
+++ b/km_openssl/rsa_operation.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/rsa_operation.h>
+#include <utility>
+
#include <limits.h>
#include <openssl/err.h>
@@ -98,7 +100,7 @@ RsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(Key&& key,
*error = GetAndValidateMgfDigest(begin_params, key, &mgf_digest);
if (*error != KM_ERROR_OK) return nullptr;
UniquePtr<RsaOperation> op(
- RsaOperationFactory::CreateRsaOperation(move(key), begin_params, error));
+ RsaOperationFactory::CreateRsaOperation(std::move(key), begin_params, error));
if (op.get()) {
switch (op->padding()) {
case KM_PAD_NONE:
@@ -240,7 +242,7 @@ RsaDigestingOperation::RsaDigestingOperation(AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced,
keymaster_purpose_t purpose, keymaster_digest_t digest,
keymaster_padding_t padding, EVP_PKEY* key)
- : RsaOperation(move(hw_enforced), move(sw_enforced), purpose, digest, padding, key) {
+ : RsaOperation(std::move(hw_enforced), std::move(sw_enforced), purpose, digest, padding, key) {
EVP_MD_CTX_init(&digest_ctx_);
}
RsaDigestingOperation::~RsaDigestingOperation() {
diff --git a/km_openssl/soft_keymaster_enforcement.cpp b/km_openssl/soft_keymaster_enforcement.cpp
index 0a3c2f6..0f5df6e 100644
--- a/km_openssl/soft_keymaster_enforcement.cpp
+++ b/km_openssl/soft_keymaster_enforcement.cpp
@@ -29,6 +29,10 @@
#include <keymaster/km_openssl/openssl_err.h>
#include <keymaster/km_openssl/openssl_utils.h>
+#ifdef _WIN32
+#include <sysinfoapi.h>
+#endif
+
namespace keymaster {
namespace {
@@ -52,11 +56,15 @@ class EvpMdCtx {
} // anonymous namespace
uint64_t SoftKeymasterEnforcement::get_current_time_ms() const {
+#ifdef _WIN32
+ return GetTickCount64();
+#else
struct timespec tp;
int err = clock_gettime(CLOCK_BOOTTIME, &tp);
if (err || tp.tv_sec < 0) return 0;
return static_cast<uint64_t>(tp.tv_sec) * 1000 + static_cast<uint64_t>(tp.tv_nsec) / 1000000;
+#endif
}
bool SoftKeymasterEnforcement::CreateKeyId(const keymaster_key_blob_t& key_blob,
diff --git a/km_openssl/symmetric_key.cpp b/km_openssl/symmetric_key.cpp
index 1b89d66..d60d9f8 100644
--- a/km_openssl/symmetric_key.cpp
+++ b/km_openssl/symmetric_key.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/symmetric_key.h>
+#include <utility>
+
#include <assert.h>
#include <openssl/err.h>
@@ -105,8 +107,8 @@ SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const {
SymmetricKey::SymmetricKey(KeymasterKeyBlob&& key_material, AuthorizationSet&& hw_enforced,
AuthorizationSet&& sw_enforced, const KeyFactory* key_factory)
- : Key(move(hw_enforced), move(sw_enforced), key_factory) {
- key_material_ = move(key_material);
+ : Key(std::move(hw_enforced), std::move(sw_enforced), key_factory) {
+ key_material_ = std::move(key_material);
}
SymmetricKey::~SymmetricKey() {}
diff --git a/km_openssl/triple_des_key.cpp b/km_openssl/triple_des_key.cpp
index 8c267e6..d60d204 100644
--- a/km_openssl/triple_des_key.cpp
+++ b/km_openssl/triple_des_key.cpp
@@ -16,6 +16,8 @@
#include <keymaster/km_openssl/triple_des_key.h>
+#include <utility>
+
#include <assert.h>
#include <openssl/err.h>
@@ -48,7 +50,8 @@ keymaster_error_t TripleDesKeyFactory::LoadKey(KeymasterKeyBlob&& key_material,
keymaster_error_t error = KM_ERROR_OK;
key->reset(new (std::nothrow)
- TripleDesKey(move(key_material), move(hw_enforced), move(sw_enforced), this));
+ TripleDesKey(std::move(key_material), std::move(hw_enforced),
+ std::move(sw_enforced), this));
if (!key->get()) error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
return error;
}
diff --git a/legacy_support/ec_keymaster1_key.cpp b/legacy_support/ec_keymaster1_key.cpp
index ddb3725..64c6916 100644
--- a/legacy_support/ec_keymaster1_key.cpp
+++ b/legacy_support/ec_keymaster1_key.cpp
@@ -17,6 +17,7 @@
#include <keymaster/legacy_support/ec_keymaster1_key.h>
#include <memory>
+#include <utility>
#include <keymaster/km_openssl/ecdsa_operation.h>
#include <keymaster/logger.h>
@@ -112,10 +113,11 @@ keymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(KeymasterKeyBlob&& key_mate
if (!ecdsa) return error;
key->reset(new (std::nothrow)
- EcdsaKeymaster1Key(ecdsa.release(), move(hw_enforced), move(sw_enforced), this));
+ EcdsaKeymaster1Key(ecdsa.release(), std::move(hw_enforced),
+ std::move(sw_enforced), this));
if (!(*key)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
- (*key)->key_material() = move(key_material);
+ (*key)->key_material() = std::move(key_material);
return KM_ERROR_OK;
}
diff --git a/legacy_support/ecdsa_keymaster1_operation.h b/legacy_support/ecdsa_keymaster1_operation.h
index e52deae..2b6d2b8 100644
--- a/legacy_support/ecdsa_keymaster1_operation.h
+++ b/legacy_support/ecdsa_keymaster1_operation.h
@@ -17,6 +17,8 @@
#ifndef SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_OPERATION_H_
#define SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_OPERATION_H_
+#include <utility>
+
#include <openssl/evp.h>
#include <hardware/keymaster1.h>
@@ -56,7 +58,7 @@ template <typename BaseOperation> class EcdsaKeymaster1Operation : public BaseOp
EcdsaKeymaster1Operation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, EVP_PKEY* key,
const Keymaster1Engine* engine)
- : BaseOperation(move(hw_enforced), move(sw_enforced), digest, key),
+ : BaseOperation(std::move(hw_enforced), std::move(sw_enforced), digest, key),
wrapped_operation_(super::purpose(), engine) {
// Shouldn't be instantiated for public key operations.
assert(super::purpose() != KM_PURPOSE_VERIFY);
diff --git a/legacy_support/keymaster1_engine.cpp b/legacy_support/keymaster1_engine.cpp
index 4cd16e5..10bfc57 100644
--- a/legacy_support/keymaster1_engine.cpp
+++ b/legacy_support/keymaster1_engine.cpp
@@ -203,7 +203,7 @@ EC_KEY* Keymaster1Engine::BuildEcKey(const KeymasterKeyBlob& blob,
}
Keymaster1Engine::KeyData* Keymaster1Engine::GetData(EVP_PKEY* key) const {
- switch (EVP_PKEY_type(key->type)) {
+ switch (EVP_PKEY_id(key)) {
case EVP_PKEY_RSA: {
unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(key));
return GetData(rsa.get());
diff --git a/legacy_support/keymaster1_legacy_support.cpp b/legacy_support/keymaster1_legacy_support.cpp
index 3fd5cb4..b327ce3 100644
--- a/legacy_support/keymaster1_legacy_support.cpp
+++ b/legacy_support/keymaster1_legacy_support.cpp
@@ -23,6 +23,7 @@
#include <algorithm>
#include <vector>
+#include <utility>
namespace keymaster {
@@ -228,7 +229,7 @@ keymaster_error_t Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::Gener
AuthorizationSet* sw_enforced, //
CertificateChain* cert_chain) const {
if (legacy_support_.RequiresSoftwareDigesting(key_description)) {
- return software_digest_factory_.GenerateKey(key_description, move(attest_key),
+ return software_digest_factory_.GenerateKey(key_description, std::move(attest_key),
issuer_subject, key_blob, hw_enforced,
sw_enforced, cert_chain);
} else {
@@ -252,7 +253,7 @@ keymaster_error_t Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::Gener
}
}
- return passthrough_factory_.GenerateKey(mutable_key_description, move(attest_key),
+ return passthrough_factory_.GenerateKey(mutable_key_description, std::move(attest_key),
issuer_subject, key_blob, hw_enforced, sw_enforced,
cert_chain);
}
@@ -268,8 +269,8 @@ keymaster_error_t Keymaster1ArbitrationFactory<EcdsaKeymaster1KeyFactory>::LoadK
}
bool requires_software_digesting =
legacy_support_.RequiresSoftwareDigesting(digest, AuthProxy(hw_enforced, sw_enforced));
- auto rc = software_digest_factory_.LoadKey(move(key_material), additional_params,
- move(hw_enforced), move(sw_enforced), key);
+ auto rc = software_digest_factory_.LoadKey(std::move(key_material), additional_params,
+ std::move(hw_enforced), std::move(sw_enforced), key);
if (rc != KM_ERROR_OK) return rc;
if (!requires_software_digesting) {
(*key)->key_factory() = &passthrough_factory_;
@@ -287,8 +288,8 @@ keymaster_error_t Keymaster1ArbitrationFactory<RsaKeymaster1KeyFactory>::LoadKey
}
bool requires_software_digesting =
legacy_support_.RequiresSoftwareDigesting(digest, AuthProxy(hw_enforced, sw_enforced));
- auto rc = software_digest_factory_.LoadKey(move(key_material), additional_params,
- move(hw_enforced), move(sw_enforced), key);
+ auto rc = software_digest_factory_.LoadKey(std::move(key_material), additional_params,
+ std::move(hw_enforced), std::move(sw_enforced), key);
if (rc != KM_ERROR_OK) return rc;
if (!requires_software_digesting) {
(*key)->key_factory() = &passthrough_factory_;
diff --git a/legacy_support/keymaster_passthrough_key.cpp b/legacy_support/keymaster_passthrough_key.cpp
index 52b56e8..b649684 100644
--- a/legacy_support/keymaster_passthrough_key.cpp
+++ b/legacy_support/keymaster_passthrough_key.cpp
@@ -17,6 +17,8 @@
#include <keymaster/legacy_support/keymaster_passthrough_key.h>
+#include <utility>
+
namespace keymaster {
keymaster_error_t KeymasterPassthroughKeyFactory::LoadKey(KeymasterKeyBlob&& key_material,
@@ -28,8 +30,9 @@ keymaster_error_t KeymasterPassthroughKeyFactory::LoadKey(KeymasterKeyBlob&& key
if (!key) return KM_ERROR_OUTPUT_PARAMETER_NULL;
key->reset(new (std::nothrow)
- KeymasterPassthroughKey(move(key_material), move(hw_enforced), move(sw_enforced),
- this, &error, additional_params, engine_));
+ KeymasterPassthroughKey(std::move(key_material), std::move(hw_enforced),
+ std::move(sw_enforced), this, &error, additional_params,
+ engine_));
if (!key->get()) error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
return error;
diff --git a/legacy_support/keymaster_passthrough_operation.cpp b/legacy_support/keymaster_passthrough_operation.cpp
index 7b10722..c98449d 100644
--- a/legacy_support/keymaster_passthrough_operation.cpp
+++ b/legacy_support/keymaster_passthrough_operation.cpp
@@ -17,6 +17,7 @@
#include "keymaster_passthrough_operation.h"
#include <keymaster/android_keymaster_utils.h>
+#include <utility>
#include <vector>
namespace keymaster {
@@ -85,7 +86,7 @@ keymaster_error_t KeymasterPassthroughOperation<keymaster1_device_t>::Finish(
}
accumulated_out_params.Deduplicate();
- if (output_params) *output_params = move(accumulated_out_params);
+ if (output_params) *output_params = std::move(accumulated_out_params);
return KM_ERROR_OK;
}
diff --git a/legacy_support/rsa_keymaster1_key.cpp b/legacy_support/rsa_keymaster1_key.cpp
index ff5576c..89ed859 100644
--- a/legacy_support/rsa_keymaster1_key.cpp
+++ b/legacy_support/rsa_keymaster1_key.cpp
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-#include <keymaster/contexts/soft_keymaster_context.h>
#include <keymaster/legacy_support/rsa_keymaster1_key.h>
+#include <utility>
+
+#include <keymaster/contexts/soft_keymaster_context.h>
#include <keymaster/km_openssl/openssl_utils.h>
#include <keymaster/logger.h>
@@ -121,10 +123,11 @@ keymaster_error_t RsaKeymaster1KeyFactory::LoadKey(KeymasterKeyBlob&& key_materi
if (!rsa.get()) return error;
key->reset(new (std::nothrow)
- RsaKeymaster1Key(rsa.release(), move(hw_enforced), move(sw_enforced), this));
+ RsaKeymaster1Key(rsa.release(), std::move(hw_enforced), std::move(sw_enforced),
+ this));
if (!(*key)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
- (*key)->key_material() = move(key_material);
+ (*key)->key_material() = std::move(key_material);
return KM_ERROR_OK;
}
diff --git a/legacy_support/rsa_keymaster1_operation.h b/legacy_support/rsa_keymaster1_operation.h
index 124c4b7..fb0eda9 100644
--- a/legacy_support/rsa_keymaster1_operation.h
+++ b/legacy_support/rsa_keymaster1_operation.h
@@ -16,6 +16,8 @@
#pragma once
+#include <utility>
+
#include <openssl/evp.h>
#include <hardware/keymaster1.h>
@@ -55,7 +57,7 @@ template <typename BaseOperation> class RsaKeymaster1Operation : public BaseOper
RsaKeymaster1Operation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced,
keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key,
const Keymaster1Engine* engine)
- : BaseOperation(move(hw_enforced), move(sw_enforced), digest, padding, key),
+ : BaseOperation(std::move(hw_enforced), std::move(sw_enforced), digest, padding, key),
wrapped_operation_(super::purpose(), engine) {
// Shouldn't be instantiated for public key operations.
assert(super::purpose() != KM_PURPOSE_VERIFY);
diff --git a/ng/AndroidKeyMintDevice.cpp b/ng/AndroidKeyMintDevice.cpp
index 25ad463..fb7b632 100644
--- a/ng/AndroidKeyMintDevice.cpp
+++ b/ng/AndroidKeyMintDevice.cpp
@@ -108,6 +108,7 @@ vector<KeyCharacteristics> convertKeyCharacteristics(SecurityLevel keyMintSecuri
case KM_TAG_ATTESTATION_ID_BRAND:
case KM_TAG_ATTESTATION_ID_DEVICE:
case KM_TAG_ATTESTATION_ID_IMEI:
+ case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
case KM_TAG_ATTESTATION_ID_MANUFACTURER:
case KM_TAG_ATTESTATION_ID_MEID:
case KM_TAG_ATTESTATION_ID_MODEL:
@@ -213,10 +214,10 @@ void addClientAndAppData(const std::vector<uint8_t>& appId, const std::vector<ui
constexpr size_t kOperationTableSize = 16;
AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel)
- : impl_(new (std::nothrow)::keymaster::AndroidKeymaster(
+ : impl_(new(std::nothrow)::keymaster::AndroidKeymaster(
[&]() -> auto{
auto context = new (std::nothrow) PureSoftKeymasterContext(
- KmVersion::KEYMINT_2, static_cast<keymaster_security_level_t>(securityLevel));
+ KmVersion::KEYMINT_3, static_cast<keymaster_security_level_t>(securityLevel));
context->SetSystemVersion(::keymaster::GetOsVersion(),
::keymaster::GetOsPatchlevel());
context->SetVendorPatchlevel(::keymaster::GetVendorPatchlevel());
@@ -241,7 +242,7 @@ AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel)
AndroidKeyMintDevice::~AndroidKeyMintDevice() {}
ScopedAStatus AndroidKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
- info->versionNumber = 2;
+ info->versionNumber = 3;
info->securityLevel = securityLevel_;
info->keyMintName = "FakeKeyMintDevice";
info->keyMintAuthorName = "Google";
diff --git a/ng/AndroidKeyMintOperation.cpp b/ng/AndroidKeyMintOperation.cpp
index 17f6b33..b886bd7 100644
--- a/ng/AndroidKeyMintOperation.cpp
+++ b/ng/AndroidKeyMintOperation.cpp
@@ -50,11 +50,16 @@ AndroidKeyMintOperation::~AndroidKeyMintOperation() {
ScopedAStatus
AndroidKeyMintOperation::updateAad(const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& /* authToken */,
+ const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>& /* timestampToken */) {
UpdateOperationRequest request(impl_->message_version());
request.op_handle = opHandle_;
request.additional_params.push_back(TAG_ASSOCIATED_DATA, input.data(), input.size());
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
+ tokenAsVec.size());
+ }
UpdateOperationResponse response(impl_->message_version());
impl_->UpdateOperation(request, &response);
@@ -63,7 +68,7 @@ AndroidKeyMintOperation::updateAad(const vector<uint8_t>& input,
}
ScopedAStatus AndroidKeyMintOperation::update(const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& /* authToken */,
+ const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>&
/* timestampToken */,
vector<uint8_t>* output) {
@@ -72,6 +77,11 @@ ScopedAStatus AndroidKeyMintOperation::update(const vector<uint8_t>& input,
UpdateOperationRequest request(impl_->message_version());
request.op_handle = opHandle_;
request.input.Reinitialize(input.data(), input.size());
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
+ tokenAsVec.size());
+ }
UpdateOperationResponse response(impl_->message_version());
impl_->UpdateOperation(request, &response);
@@ -88,7 +98,7 @@ ScopedAStatus AndroidKeyMintOperation::update(const vector<uint8_t>& input,
ScopedAStatus
AndroidKeyMintOperation::finish(const optional<vector<uint8_t>>& input, //
const optional<vector<uint8_t>>& signature, //
- const optional<HardwareAuthToken>& /* authToken */,
+ const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>& /* timestampToken */,
const optional<vector<uint8_t>>& /* confirmationToken */,
vector<uint8_t>* output) {
@@ -102,6 +112,11 @@ AndroidKeyMintOperation::finish(const optional<vector<uint8_t>>& input, //
request.op_handle = opHandle_;
if (input) request.input.Reinitialize(input->data(), input->size());
if (signature) request.signature.Reinitialize(signature->data(), signature->size());
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN, tokenAsVec.data(),
+ tokenAsVec.size());
+ }
FinishOperationResponse response(impl_->message_version());
impl_->FinishOperation(request, &response);
diff --git a/ng/AndroidRemotelyProvisionedComponentDevice.cpp b/ng/AndroidRemotelyProvisionedComponentDevice.cpp
index 54ea70c..c8d4070 100644
--- a/ng/AndroidRemotelyProvisionedComponentDevice.cpp
+++ b/ng/AndroidRemotelyProvisionedComponentDevice.cpp
@@ -35,8 +35,12 @@ namespace aidl::android::hardware::security::keymint {
using keymaster::GenerateCsrRequest;
using keymaster::GenerateCsrResponse;
+using keymaster::GenerateCsrV2Request;
+using keymaster::GenerateCsrV2Response;
using keymaster::GenerateRkpKeyRequest;
using keymaster::GenerateRkpKeyResponse;
+using keymaster::GetHwInfoRequest;
+using keymaster::GetHwInfoResponse;
using keymaster::KeymasterBlob;
using ::std::string;
using ::std::unique_ptr;
@@ -83,10 +87,16 @@ AndroidRemotelyProvisionedComponentDevice::AndroidRemotelyProvisionedComponentDe
}
ScopedAStatus AndroidRemotelyProvisionedComponentDevice::getHardwareInfo(RpcHardwareInfo* info) {
- info->versionNumber = 2;
- info->rpcAuthorName = "Google";
- info->supportedEekCurve = RpcHardwareInfo::CURVE_25519;
- info->uniqueId = "default keymint";
+ GetHwInfoResponse response = impl_->GetHwInfo();
+ if (response.error != KM_ERROR_OK) {
+ return Status(-static_cast<int32_t>(response.error), "Failed to get hardware info.");
+ }
+
+ info->versionNumber = response.version;
+ info->rpcAuthorName = response.rpcAuthorName;
+ info->supportedEekCurve = response.supportedEekCurve;
+ info->uniqueId = response.uniqueId;
+ info->supportedNumKeysInCsr = response.supportedNumKeysInCsr;
return ScopedAStatus::ok();
}
@@ -133,4 +143,25 @@ ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateCertificateRequ
return ScopedAStatus::ok();
}
+ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateCertificateRequestV2(
+ const std::vector<MacedPublicKey>& keysToSign, const std::vector<uint8_t>& challenge,
+ std::vector<uint8_t>* csr) {
+ GenerateCsrV2Request request(impl_->message_version());
+ if (!request.InitKeysToSign(keysToSign.size())) {
+ return km_utils::kmError2ScopedAStatus(static_cast<keymaster_error_t>(STATUS_FAILED));
+ }
+ for (size_t i = 0; i < keysToSign.size(); i++) {
+ request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size());
+ }
+ request.SetChallenge(challenge.data(), challenge.size());
+ GenerateCsrV2Response response(impl_->message_version());
+ impl_->GenerateCsrV2(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ return Status(-static_cast<int32_t>(response.error), "Failure in CSR v2 generation.");
+ }
+ *csr = km_utils::kmBlob2vector(response.csr);
+ return ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::security::keymint
diff --git a/ng/KeyMintAidlUtils.cpp b/ng/KeyMintAidlUtils.cpp
index 28b5744..8f78027 100644
--- a/ng/KeyMintAidlUtils.cpp
+++ b/ng/KeyMintAidlUtils.cpp
@@ -24,30 +24,6 @@ namespace keymint {
using namespace ::keymaster;
-vector<uint8_t> authToken2AidlVec(const HardwareAuthToken& token) {
- static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
- sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
- sizeof(token.timestamp) + 32 /* HMAC size */
- == sizeof(hw_auth_token_t),
- "HardwareAuthToken content size does not match hw_auth_token_t size");
-
- vector<uint8_t> result;
-
- if (token.mac.size() <= 32) return result;
-
- result.resize(sizeof(hw_auth_token_t));
- auto pos = result.begin();
- *pos++ = 0; // Version byte
- pos = copy_bytes_to_iterator(token.challenge, pos);
- pos = copy_bytes_to_iterator(token.userId, pos);
- pos = copy_bytes_to_iterator(token.authenticatorId, pos);
- pos = copy_bytes_to_iterator(token.authenticatorType, pos);
- pos = copy_bytes_to_iterator(token.timestamp, pos);
- pos = std::copy(token.mac.data(), token.mac.data() + token.mac.size(), pos);
-
- return result;
-}
-
// TODO(seleneh): This needs to be modified depends on how aidl support for union came out to
// be.
vector<KeyParameter> kmParamSet2Aidl(const keymaster_key_param_set_t& set) {
diff --git a/ng/KeyMintUtils.cpp b/ng/KeyMintUtils.cpp
index 45967fd..98763fd 100644
--- a/ng/KeyMintUtils.cpp
+++ b/ng/KeyMintUtils.cpp
@@ -39,6 +39,12 @@ KeyParameter kmEnumParam2Aidl(const keymaster_key_param_t& param) {
case KM_TAG_DIGEST:
return KeyParameter{Tag::DIGEST, KeyParameterValue::make<KeyParameterValue::digest>(
static_cast<Digest>(param.enumerated))};
+
+ case KM_TAG_RSA_OAEP_MGF_DIGEST:
+ return KeyParameter{Tag::RSA_OAEP_MGF_DIGEST,
+ KeyParameterValue::make<KeyParameterValue::digest>(
+ static_cast<Digest>(param.enumerated))};
+
case KM_TAG_PADDING:
return KeyParameter{Tag::PADDING, KeyParameterValue::make<KeyParameterValue::paddingMode>(
static_cast<PaddingMode>(param.enumerated))};
@@ -52,10 +58,17 @@ KeyParameter kmEnumParam2Aidl(const keymaster_key_param_t& param) {
case KM_TAG_ORIGIN:
return KeyParameter{Tag::ORIGIN, KeyParameterValue::make<KeyParameterValue::origin>(
static_cast<KeyOrigin>(param.enumerated))};
+
case KM_TAG_BLOB_USAGE_REQUIREMENTS:
case KM_TAG_KDF:
- default:
return KeyParameter{Tag::INVALID, false};
+
+ default:
+ // Unknown tag. We can't represent it properly because it's some unknown enum. But KeyMint
+ // specs require us to return unknown tags. Pretending it's an integer value is the best we
+ // can do. Upstream will have to deal with it.
+ return KeyParameter{static_cast<Tag>(param.tag),
+ KeyParameterValue::make<KeyParameterValue::integer>(param.enumerated)};
}
}
@@ -90,9 +103,11 @@ keymaster_key_param_t aidlEnumParam2Km(const KeyParameter& param) {
return aidlEnumVal2Km<KeyParameterValue::origin>(tag, param.value);
case KM_TAG_BLOB_USAGE_REQUIREMENTS:
case KM_TAG_KDF:
+ CHECK(false) << "Unused enum tag: Something is broken";
+ return keymaster_param_enum(KM_TAG_INVALID, false);
default:
- CHECK(false) << "Unknown or unused enum tag: Something is broken";
- return keymaster_param_enum(tag, false);
+ // Unknown tag. This can happen when system is newer than secure world. Pass it through.
+ return keymaster_param_enum(tag, param.value.get<KeyParameterValue::integer>());
}
}
@@ -108,7 +123,7 @@ vector<uint8_t> authToken2AidlVec(const std::optional<HardwareAuthToken>& token)
vector<uint8_t> result;
if (!token.has_value()) return result;
- if (token->mac.size() < 32) return result;
+ if (token->mac.size() != 32) return result;
result.resize(sizeof(hw_auth_token_t));
auto pos = result.begin();
@@ -129,7 +144,6 @@ KeyParameter kmParam2Aidl(const keymaster_key_param_t& param) {
case KM_ENUM:
case KM_ENUM_REP:
return kmEnumParam2Aidl(param);
- break;
case KM_UINT:
case KM_UINT_REP:
@@ -140,28 +154,23 @@ KeyParameter kmParam2Aidl(const keymaster_key_param_t& param) {
case KM_ULONG_REP:
return KeyParameter{
tag, KeyParameterValue::make<KeyParameterValue::longInteger>(param.long_integer)};
- break;
case KM_DATE:
return KeyParameter{tag,
KeyParameterValue::make<KeyParameterValue::dateTime>(param.date_time)};
- break;
case KM_BOOL:
return KeyParameter{tag, param.boolean};
- break;
case KM_BIGNUM:
case KM_BYTES:
return {tag, KeyParameterValue::make<KeyParameterValue::blob>(
std::vector(param.blob.data, param.blob.data + param.blob.data_length))};
- break;
case KM_INVALID:
default:
CHECK(false) << "Unknown or unused tag type: Something is broken";
return KeyParameter{Tag::INVALID, false};
- break;
}
}
diff --git a/ng/include/AndroidRemotelyProvisionedComponentDevice.h b/ng/include/AndroidRemotelyProvisionedComponentDevice.h
index eef81f3..9879a94 100644
--- a/ng/include/AndroidRemotelyProvisionedComponentDevice.h
+++ b/ng/include/AndroidRemotelyProvisionedComponentDevice.h
@@ -46,6 +46,10 @@ class AndroidRemotelyProvisionedComponentDevice : public BnRemotelyProvisionedCo
DeviceInfo* deviceInfo, ProtectedData* protectedData,
std::vector<uint8_t>* keysToSignMac) override;
+ ScopedAStatus generateCertificateRequestV2(const std::vector<MacedPublicKey>& keysToSign,
+ const std::vector<uint8_t>& challenge,
+ std::vector<uint8_t>* csr) override;
+
private:
std::shared_ptr<::keymaster::AndroidKeymaster> impl_;
};
diff --git a/tests/android_keymaster_messages_test.cpp b/tests/android_keymaster_messages_test.cpp
index 6b873b4..fc0923e 100644
--- a/tests/android_keymaster_messages_test.cpp
+++ b/tests/android_keymaster_messages_test.cpp
@@ -249,6 +249,46 @@ TEST(RoundTrip, GenerateCsrResponse) {
}
}
+TEST(RoundTrip, GenerateCsrV2Request) {
+ for (int ver = 0; ver <= kMaxMessageVersion; ++ver) {
+ GenerateCsrV2Request req(ver);
+ EXPECT_TRUE(req.InitKeysToSign(2));
+ for (size_t i = 0; i < req.num_keys; i++) {
+ req.SetKeyToSign(i, dup_array(TEST_DATA), array_length(TEST_DATA));
+ }
+ req.SetChallenge(dup_array(TEST_DATA), array_length(TEST_DATA));
+ UniquePtr<GenerateCsrV2Request> deserialized(round_trip(ver, req, 49));
+ EXPECT_EQ(deserialized->num_keys, req.num_keys);
+ for (int i = 0; i < (int)req.num_keys; i++) {
+ EXPECT_EQ(deserialized->keys_to_sign_array[i].data_length,
+ req.keys_to_sign_array[i].data_length);
+ EXPECT_EQ(0, std::memcmp(deserialized->keys_to_sign_array[i].data,
+ req.keys_to_sign_array[i].data,
+ req.keys_to_sign_array[i].data_length));
+ }
+ EXPECT_EQ(deserialized->challenge.data_length, req.challenge.data_length);
+ EXPECT_EQ(0, std::memcmp(deserialized->challenge.data, req.challenge.data,
+ req.challenge.data_length));
+ }
+}
+
+TEST(RoundTrip, GenerateCsrV2Response) {
+ for (int ver = 0; ver <= kMaxMessageVersion; ++ver) {
+ GenerateCsrV2Response rsp(ver);
+ rsp.error = KM_ERROR_OK;
+ rsp.csr.data = dup_array(TEST_DATA);
+ rsp.csr.data_length = array_length(TEST_DATA);
+
+ UniquePtr<GenerateCsrV2Response> deserialized;
+ deserialized.reset(round_trip(ver, rsp, 19));
+
+ EXPECT_EQ(KM_ERROR_OK, deserialized->error);
+ EXPECT_EQ(deserialized->csr.data_length, rsp.csr.data_length);
+ EXPECT_EQ(0,
+ std::memcmp(deserialized->csr.data, rsp.csr.data, deserialized->csr.data_length));
+ }
+}
+
TEST(RoundTrip, GetKeyCharacteristicsRequest) {
for (int ver = 0; ver <= kMaxMessageVersion; ++ver) {
GetKeyCharacteristicsRequest req(ver);
@@ -867,6 +907,28 @@ TEST(RoundTrip, GetRootOfTrustResponse) {
}
}
+TEST(RoundTrip, GetHwInfoResponse) {
+ for (int ver = 0; ver <= kMaxMessageVersion; ++ver) {
+ GetHwInfoResponse rsp(ver);
+ rsp.error = KM_ERROR_OK;
+ rsp.version = 17;
+ rsp.rpcAuthorName = "AAAAA";
+ rsp.supportedEekCurve = 48;
+ rsp.uniqueId = "BBBBB";
+ rsp.supportedNumKeysInCsr = 549;
+
+ UniquePtr<GetHwInfoResponse> deserialized;
+ deserialized.reset(round_trip(ver, rsp, 34));
+
+ EXPECT_EQ(KM_ERROR_OK, deserialized->error);
+ EXPECT_EQ(deserialized->version, rsp.version);
+ EXPECT_EQ(deserialized->rpcAuthorName, rsp.rpcAuthorName);
+ EXPECT_EQ(deserialized->supportedEekCurve, rsp.supportedEekCurve);
+ EXPECT_EQ(deserialized->uniqueId, rsp.uniqueId);
+ EXPECT_EQ(deserialized->supportedNumKeysInCsr, rsp.supportedNumKeysInCsr);
+ }
+}
+
#define SET_ATTESTATION_ID(x) msg.x.Reinitialize(#x, strlen(#x))
void check_id(const Buffer& id, const char* value) {
@@ -900,6 +962,31 @@ TEST(RoundTrip, SetAttestationIdsRequest) {
}
}
+TEST(RoundTrip, SetAttestationIdsKM3Request) {
+ for (int ver = 0; ver <= kMaxMessageVersion; ++ver) {
+ SetAttestationIdsKM3Request msg(ver);
+ SET_ATTESTATION_ID(base.brand);
+ SET_ATTESTATION_ID(base.device);
+ SET_ATTESTATION_ID(base.product);
+ SET_ATTESTATION_ID(base.serial);
+ SET_ATTESTATION_ID(base.imei);
+ SET_ATTESTATION_ID(base.meid);
+ SET_ATTESTATION_ID(base.manufacturer);
+ SET_ATTESTATION_ID(base.model);
+ SET_ATTESTATION_ID(second_imei);
+
+ UniquePtr<SetAttestationIdsKM3Request> deserialized(round_trip(ver, msg, 136));
+ ASSERT_TRUE(deserialized);
+ CHECK_ID(base.brand);
+ CHECK_ID(base.device);
+ CHECK_ID(base.product);
+ CHECK_ID(base.serial);
+ CHECK_ID(base.imei);
+ CHECK_ID(base.model);
+ CHECK_ID(second_imei);
+ }
+}
+
uint8_t msgbuf[] = {
220, 88, 183, 255, 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 173, 0, 0, 0, 228, 174, 98, 187, 191, 135, 253, 200, 51, 230, 114, 247, 151, 109,
@@ -966,7 +1053,9 @@ template <typename Message> void parse_garbage() {
}
#define GARBAGE_TEST(Message) \
- TEST(GarbageTest, Message) { parse_garbage<Message>(); }
+ TEST(GarbageTest, Message) { \
+ parse_garbage<Message>(); \
+ }
GARBAGE_TEST(AbortOperationRequest);
GARBAGE_TEST(EmptyKeymasterResponse);
@@ -994,6 +1083,7 @@ GARBAGE_TEST(UpgradeKeyResponse);
GARBAGE_TEST(GenerateTimestampTokenRequest);
GARBAGE_TEST(GenerateTimestampTokenResponse);
GARBAGE_TEST(SetAttestationIdsRequest);
+GARBAGE_TEST(SetAttestationIdsKM3Request);
GARBAGE_TEST(ConfigureVerifiedBootInfoRequest);
GARBAGE_TEST(GetRootOfTrustRequest);
GARBAGE_TEST(GetRootOfTrustResponse);
diff --git a/tests/key_blob_test.cpp b/tests/key_blob_test.cpp
index f69551b..2c751f1 100644
--- a/tests/key_blob_test.cpp
+++ b/tests/key_blob_test.cpp
@@ -15,6 +15,7 @@
*/
#include <algorithm>
+#include <utility>
#include <gtest/gtest.h>
@@ -79,7 +80,7 @@ class KeyBlobTest : public ::testing::TestWithParam<AuthEncryptedBlobFormat>,
keymaster_error_t Decrypt() {
auto result =
- DecryptKey(move(deserialized_key_), hidden_, secure_deletion_data_, master_key_);
+ DecryptKey(std::move(deserialized_key_), hidden_, secure_deletion_data_, master_key_);
if (!result) return result.error();
decrypted_plaintext_ = std::move(*result);
return KM_ERROR_OK;