Merge "Don't mark odsign as oneshot." into sc-dev
diff --git a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
index 4a092af..ecdc790 100644
--- a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
+++ b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
@@ -20,6 +20,7 @@
import android.hardware.security.keymint.ProtectedData;
import android.hardware.security.keymint.SecurityLevel;
import android.security.remoteprovisioning.AttestationPoolStatus;
+import android.security.remoteprovisioning.ImplInfo;
/**
* `IRemoteProvisioning` is the interface provided to use the remote provisioning functionality
@@ -127,13 +128,14 @@
void generateKeyPair(in boolean is_test_mode, in SecurityLevel secLevel);
/**
- * This method returns the SecurityLevels of whichever instances of
+ * This method returns implementation information for whichever instances of
* IRemotelyProvisionedComponent are running on the device. The RemoteProvisioner app needs to
- * know which KM instances it should be generating and managing attestation keys for.
+ * know which KM instances it should be generating and managing attestation keys for, and which
+ * EC curves are supported in those instances.
*
- * @return The array of security levels.
+ * @return The array of ImplInfo parcelables.
*/
- SecurityLevel[] getSecurityLevels();
+ ImplInfo[] getImplementationInfo();
/**
* This method deletes all remotely provisioned attestation keys in the database, regardless
diff --git a/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
new file mode 100644
index 0000000..9baeb24
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 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 android.security.remoteprovisioning;
+
+import android.hardware.security.keymint.SecurityLevel;
+
+/**
+ * This parcelable provides information about the underlying IRemotelyProvisionedComponent
+ * implementation.
+ * @hide
+ */
+parcelable ImplInfo {
+ /**
+ * The security level of the underlying implementation: TEE or StrongBox.
+ */
+ SecurityLevel secLevel;
+ /**
+ * An integer denoting which EC curve is supported in the underlying implementation. The current
+ * options are either P256 or 25519, with values defined in
+ * hardware/interfaces/security/keymint/aidl/.../RpcHardwareInfo.aidl
+ */
+ int supportedCurve;
+}
diff --git a/keystore2/src/remote_provisioning.rs b/keystore2/src/remote_provisioning.rs
index 6666f41..1236431 100644
--- a/keystore2/src/remote_provisioning.rs
+++ b/keystore2/src/remote_provisioning.rs
@@ -30,7 +30,7 @@
};
use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
- IRemoteProvisioning::IRemoteProvisioning,
+ IRemoteProvisioning::IRemoteProvisioning, ImplInfo::ImplInfo,
};
use android_security_remoteprovisioning::binder::{BinderFeatures, Strong};
use android_system_keystore2::aidl::android::system::keystore2::{
@@ -180,23 +180,34 @@
// and therefore will not be attested.
Ok(None)
} else {
- match self.get_rem_prov_attest_key(&key, caller_uid, db).context(concat!(
- "In get_remote_provisioning_key_and_certs: Failed to get ",
- "attestation key"
- ))? {
- Some(cert_chain) => Ok(Some((
- AttestationKey {
- keyBlob: cert_chain.private_key.to_vec(),
- attestKeyParams: vec![],
- issuerSubjectName: parse_subject_from_certificate(&cert_chain.batch_cert)
+ match self.get_rem_prov_attest_key(&key, caller_uid, db) {
+ Err(e) => {
+ log::error!(
+ concat!(
+ "In get_remote_provisioning_key_and_certs: Failed to get ",
+ "attestation key. {:?}"
+ ),
+ e
+ );
+ Ok(None)
+ }
+ Ok(v) => match v {
+ Some(cert_chain) => Ok(Some((
+ AttestationKey {
+ keyBlob: cert_chain.private_key.to_vec(),
+ attestKeyParams: vec![],
+ issuerSubjectName: parse_subject_from_certificate(
+ &cert_chain.batch_cert,
+ )
.context(concat!(
- "In get_remote_provisioning_key_and_certs: Failed to ",
- "parse subject."
- ))?,
- },
- Certificate { encodedCertificate: cert_chain.cert_chain },
- ))),
- None => Ok(None),
+ "In get_remote_provisioning_key_and_certs: Failed to ",
+ "parse subject."
+ ))?,
+ },
+ Certificate { encodedCertificate: cert_chain.cert_chain },
+ ))),
+ None => Ok(None),
+ },
}
}
}
@@ -205,6 +216,7 @@
#[derive(Default)]
pub struct RemoteProvisioningService {
device_by_sec_level: HashMap<SecurityLevel, Asp>,
+ curve_by_sec_level: HashMap<SecurityLevel, i32>,
}
impl RemoteProvisioningService {
@@ -227,8 +239,24 @@
let mut result: Self = Default::default();
let dev = get_remotely_provisioned_component(&SecurityLevel::TRUSTED_ENVIRONMENT)
.context("In new_native_binder: Failed to get TEE Remote Provisioner instance.")?;
+ let rkp_tee_dev: Strong<dyn IRemotelyProvisionedComponent> = dev.get_interface()?;
+ result.curve_by_sec_level.insert(
+ SecurityLevel::TRUSTED_ENVIRONMENT,
+ rkp_tee_dev
+ .getHardwareInfo()
+ .context("In new_native_binder: Failed to get hardware info for the TEE.")?
+ .supportedEekCurve,
+ );
result.device_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, dev);
if let Ok(dev) = get_remotely_provisioned_component(&SecurityLevel::STRONGBOX) {
+ let rkp_sb_dev: Strong<dyn IRemotelyProvisionedComponent> = dev.get_interface()?;
+ result.curve_by_sec_level.insert(
+ SecurityLevel::STRONGBOX,
+ rkp_sb_dev
+ .getHardwareInfo()
+ .context("In new_native_binder: Failed to get hardware info for StrongBox.")?
+ .supportedEekCurve,
+ );
result.device_by_sec_level.insert(SecurityLevel::STRONGBOX, dev);
}
Ok(BnRemoteProvisioning::new_binder(result, BinderFeatures::default()))
@@ -355,8 +383,12 @@
/// Checks the security level of each available IRemotelyProvisionedComponent hal and returns
/// all levels in an array to the caller.
- pub fn get_security_levels(&self) -> Result<Vec<SecurityLevel>> {
- Ok(self.device_by_sec_level.keys().cloned().collect())
+ pub fn get_implementation_info(&self) -> Result<Vec<ImplInfo>> {
+ Ok(self
+ .curve_by_sec_level
+ .iter()
+ .map(|(sec_level, curve)| ImplInfo { secLevel: *sec_level, supportedCurve: *curve })
+ .collect())
}
/// Deletes all attestation keys generated by the IRemotelyProvisionedComponent from the device,
@@ -448,9 +480,9 @@
map_or_log_err(self.generate_key_pair(is_test_mode, sec_level), Ok)
}
- fn getSecurityLevels(&self) -> binder::public_api::Result<Vec<SecurityLevel>> {
+ fn getImplementationInfo(&self) -> binder::public_api::Result<Vec<ImplInfo>> {
let _wp = wd::watch_millis("IRemoteProvisioning::getSecurityLevels", 500);
- map_or_log_err(self.get_security_levels(), Ok)
+ map_or_log_err(self.get_implementation_info(), Ok)
}
fn deleteAllKeys(&self) -> binder::public_api::Result<i64> {
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 365f8da..5cb3afc 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -914,7 +914,7 @@
"In convert_storage_key_to_ephemeral: calling convertStorageKeyToEphemeral (2)",
500,
);
- map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
+ map_km_error(km_dev.convertStorageKeyToEphemeral(&upgraded_blob))
}
.context(concat!(
"In convert_storage_key_to_ephemeral: ",
diff --git a/ondevice-signing/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
index 3d5243a..0bb3979 100644
--- a/ondevice-signing/VerityUtils.cpp
+++ b/ondevice-signing/VerityUtils.cpp
@@ -94,7 +94,12 @@
if (ret < 0) {
return ErrnoError() << "Failed to compute fs-verity digest for " << path;
}
- std::vector<uint8_t> digestVector(&digest->digest[0], &digest->digest[32]);
+ int expected_digest_size = libfsverity_get_digest_size(FS_VERITY_HASH_ALG_SHA256);
+ if (digest->digest_size != expected_digest_size) {
+ return Error() << "Digest does not have expected size: " << expected_digest_size
+ << " actual: " << digest->digest_size;
+ }
+ std::vector<uint8_t> digestVector(&digest->digest[0], &digest->digest[expected_digest_size]);
free(digest);
return digestVector;
}
@@ -114,7 +119,7 @@
template <typename T>
static trailing_unique_ptr<T> makeUniqueWithTrailingData(size_t trailing_data_size) {
- uint8_t* memory = new uint8_t[sizeof(T*) + trailing_data_size];
+ uint8_t* memory = new uint8_t[sizeof(T) + trailing_data_size];
T* ptr = new (memory) T;
return trailing_unique_ptr<T>{ptr};
}
diff --git a/provisioner/rkp_factory_extraction_tool.cpp b/provisioner/rkp_factory_extraction_tool.cpp
index 5878d22..c439b99 100644
--- a/provisioner/rkp_factory_extraction_tool.cpp
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -67,19 +67,24 @@
return challenge;
}
-Array composeCertificateRequest(ProtectedData&& protectedData, DeviceInfo&& deviceInfo,
- const std::vector<uint8_t>& challenge) {
- Array emptyMacedKeysToSign;
- emptyMacedKeysToSign
- .add(std::vector<uint8_t>(0)) // empty protected headers as bstr
- .add(Map()) // empty unprotected headers
- .add(Null()) // nil for the payload
- .add(std::vector<uint8_t>(0)); // empty tag as bstr
- Array certificateRequest;
- certificateRequest.add(EncodedItem(std::move(deviceInfo.deviceInfo)))
- .add(challenge)
- .add(EncodedItem(std::move(protectedData.protectedData)))
- .add(std::move(emptyMacedKeysToSign));
+Array composeCertificateRequest(const ProtectedData& protectedData,
+ const DeviceInfo& verifiedDeviceInfo,
+ const std::vector<uint8_t>& challenge,
+ const std::vector<uint8_t>& keysToSignMac) {
+ Array macedKeysToSign = Array()
+ .add(std::vector<uint8_t>(0)) // empty protected headers as bstr
+ .add(Map()) // empty unprotected headers
+ .add(Null()) // nil for the payload
+ .add(keysToSignMac); // MAC as returned from the HAL
+
+ Array deviceInfo =
+ Array().add(EncodedItem(verifiedDeviceInfo.deviceInfo)).add(Map()); // Empty device info
+
+ Array certificateRequest = Array()
+ .add(std::move(deviceInfo))
+ .add(challenge)
+ .add(EncodedItem(protectedData.protectedData))
+ .add(std::move(macedKeysToSign));
return certificateRequest;
}
@@ -134,18 +139,19 @@
std::vector<uint8_t> keysToSignMac;
std::vector<MacedPublicKey> emptyKeys;
- DeviceInfo deviceInfo;
+ DeviceInfo verifiedDeviceInfo;
ProtectedData protectedData;
::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
- FLAGS_test_mode, emptyKeys, getEekChain(), challenge, &deviceInfo, &protectedData,
+ FLAGS_test_mode, emptyKeys, getEekChain(), challenge, &verifiedDeviceInfo, &protectedData,
&keysToSignMac);
if (!status.isOk()) {
std::cerr << "Bundle extraction failed for '" << fullName
<< "'. Error code: " << status.getServiceSpecificError() << "." << std::endl;
exit(-1);
}
- writeOutput(
- composeCertificateRequest(std::move(protectedData), std::move(deviceInfo), challenge));
+ auto request =
+ composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge, keysToSignMac);
+ writeOutput(request);
}
} // namespace