Separate updateAad from update & other cleanups
Test: VtsKeyMintAidlTargetTest
Change-Id: Ibdce297ed630caf88a5d78991f30eef4c0f8b0aa
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index b25cb0c..c506d8b 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -241,26 +241,31 @@
return static_cast<V4_0_KeyFormat>(kf);
}
-static V4_0_HardwareAuthToken convertAuthTokenToLegacy(const HardwareAuthToken& at) {
+static V4_0_HardwareAuthToken convertAuthTokenToLegacy(const std::optional<HardwareAuthToken>& at) {
+ if (!at) return {};
+
V4_0_HardwareAuthToken legacyAt;
- legacyAt.challenge = at.challenge;
- legacyAt.userId = at.userId;
- legacyAt.authenticatorId = at.authenticatorId;
+ legacyAt.challenge = at->challenge;
+ legacyAt.userId = at->userId;
+ legacyAt.authenticatorId = at->authenticatorId;
legacyAt.authenticatorType =
static_cast<::android::hardware::keymaster::V4_0::HardwareAuthenticatorType>(
- at.authenticatorType);
- legacyAt.timestamp = at.timestamp.milliSeconds;
- legacyAt.mac = at.mac;
+ at->authenticatorType);
+ legacyAt.timestamp = at->timestamp.milliSeconds;
+ legacyAt.mac = at->mac;
return legacyAt;
}
-static V4_0_VerificationToken convertTimestampTokenToLegacy(const TimeStampToken& tst) {
+static V4_0_VerificationToken
+convertTimestampTokenToLegacy(const std::optional<TimeStampToken>& tst) {
+ if (!tst) return {};
+
V4_0_VerificationToken legacyVt;
- legacyVt.challenge = tst.challenge;
- legacyVt.timestamp = tst.timestamp.milliSeconds;
+ legacyVt.challenge = tst->challenge;
+ legacyVt.timestamp = tst->timestamp.milliSeconds;
// Legacy verification tokens were always minted by TEE.
legacyVt.securityLevel = V4_0::SecurityLevel::TRUSTED_ENVIRONMENT;
- legacyVt.mac = tst.mac;
+ legacyVt.mac = tst->mac;
return legacyVt;
}
@@ -530,81 +535,85 @@
}
}
-ScopedAStatus KeyMintOperation::update(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<HardwareAuthToken>& in_inAuthToken,
- const std::optional<TimeStampToken>& in_inTimeStampToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::optional<ByteArray>* out_output,
- int32_t* _aidl_return) {
- std::vector<V4_0_KeyParameter> legacyParams;
- if (in_inParams.has_value()) {
- legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
- }
- auto input = in_input.value_or(std::vector<uint8_t>());
- V4_0_HardwareAuthToken authToken;
- if (in_inAuthToken.has_value()) {
- authToken = convertAuthTokenToLegacy(in_inAuthToken.value());
- }
- V4_0_VerificationToken verificationToken;
- if (in_inTimeStampToken.has_value()) {
- verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
- }
+ScopedAStatus KeyMintOperation::updateAad(const std::vector<uint8_t>& input,
+ const std::optional<HardwareAuthToken>& optAuthToken,
+ const std::optional<TimeStampToken>& optTimeStampToken) {
+ V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(optAuthToken);
+ V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(optTimeStampToken);
KMV1::ErrorCode errorCode;
auto result = mDevice->update(
- mOperationHandle, legacyParams, input, authToken, verificationToken,
- [&](V4_0_ErrorCode error, uint32_t inputConsumed,
- const hidl_vec<V4_0_KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
- errorCode = convert(error);
- out_outParams->emplace();
- out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
- out_output->emplace();
- out_output->value().data = output;
- *_aidl_return = inputConsumed;
- });
+ mOperationHandle, {V4_0::makeKeyParameter(V4_0::TAG_ASSOCIATED_DATA, input)}, input,
+ authToken, verificationToken,
+ [&](V4_0_ErrorCode error, auto, auto, auto) { errorCode = convert(error); });
if (!result.isOk()) {
LOG(ERROR) << __func__ << " transaction failed. " << result.description();
errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != KMV1::ErrorCode::OK) {
- mOperationSlot.freeSlot();
- }
+ if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
+
return convertErrorCode(errorCode);
}
-ScopedAStatus KeyMintOperation::finish(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<std::vector<uint8_t>>& in_inSignature,
- const std::optional<HardwareAuthToken>& in_authToken,
- const std::optional<TimeStampToken>& in_inTimeStampToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::vector<uint8_t>* _aidl_return) {
- KMV1::ErrorCode errorCode;
- std::vector<V4_0_KeyParameter> legacyParams;
- if (in_inParams.has_value()) {
- legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
+ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
+ const std::optional<HardwareAuthToken>& optAuthToken,
+ const std::optional<TimeStampToken>& optTimeStampToken,
+ std::vector<uint8_t>* out_output) {
+ V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(optAuthToken);
+ V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(optTimeStampToken);
+
+ size_t inputPos = 0;
+ *out_output = {};
+ KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+
+ while (inputPos < input.size() && errorCode == KMV1::ErrorCode::OK) {
+ auto result =
+ mDevice->update(mOperationHandle, {} /* inParams */,
+ {input.begin() + inputPos, input.end()}, authToken, verificationToken,
+ [&](V4_0_ErrorCode error, uint32_t inputConsumed, auto /* outParams */,
+ const hidl_vec<uint8_t>& output) {
+ errorCode = convert(error);
+ out_output->insert(out_output->end(), output.begin(), output.end());
+ inputPos += inputConsumed;
+ });
+
+ if (!result.isOk()) {
+ LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+ }
}
+
+ if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
+
+ return convertErrorCode(errorCode);
+}
+
+ScopedAStatus
+KeyMintOperation::finish(const std::optional<std::vector<uint8_t>>& in_input,
+ const std::optional<std::vector<uint8_t>>& in_signature,
+ const std::optional<HardwareAuthToken>& in_authToken,
+ const std::optional<TimeStampToken>& in_timeStampToken,
+ const std::optional<std::vector<uint8_t>>& in_confirmationToken,
+ std::vector<uint8_t>* out_output) {
auto input = in_input.value_or(std::vector<uint8_t>());
- auto signature = in_inSignature.value_or(std::vector<uint8_t>());
- V4_0_HardwareAuthToken authToken;
- if (in_authToken.has_value()) {
- authToken = convertAuthTokenToLegacy(in_authToken.value());
+ auto signature = in_signature.value_or(std::vector<uint8_t>());
+ V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(in_authToken);
+ V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(in_timeStampToken);
+
+ std::vector<V4_0_KeyParameter> inParams;
+ if (in_confirmationToken) {
+ inParams.push_back(makeKeyParameter(V4_0::TAG_CONFIRMATION_TOKEN, *in_confirmationToken));
}
- V4_0_VerificationToken verificationToken;
- if (in_inTimeStampToken.has_value()) {
- verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
- }
+
+ KMV1::ErrorCode errorCode;
auto result = mDevice->finish(
- mOperationHandle, legacyParams, input, signature, authToken, verificationToken,
- [&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
- const hidl_vec<uint8_t>& output) {
+ mOperationHandle, {} /* inParams */, input, signature, authToken, verificationToken,
+ [&](V4_0_ErrorCode error, auto /* outParams */, const hidl_vec<uint8_t>& output) {
errorCode = convert(error);
- out_outParams->emplace();
- out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
- *_aidl_return = output;
+ *out_output = output;
});
+
mOperationSlot.freeSlot();
if (!result.isOk()) {
LOG(ERROR) << __func__ << " transaction failed. " << result.description();
@@ -881,18 +890,14 @@
errorCode = toErrorCode(error);
return std::vector<uint8_t>();
}
- std::optional<KeyParameterArray> outParams;
- std::optional<ByteArray> outByte;
- int32_t status;
- error = beginResult.operation->update(std::nullopt, dataVec, std::nullopt, std::nullopt,
- &outParams, &outByte, &status);
- if (!error.isOk()) {
- errorCode = toErrorCode(error);
- return std::vector<uint8_t>();
- }
+
std::vector<uint8_t> result;
- error = beginResult.operation->finish(std::nullopt, std::nullopt, std::nullopt,
- std::nullopt, std::nullopt, &outParams, &result);
+ error = beginResult.operation->finish(dataVec, //
+ {} /* signature */, //
+ {} /* authToken */, //
+ {} /* timestampToken */, //
+ {} /* confirmationToken */, //
+ &result);
if (!error.isOk()) {
errorCode = toErrorCode(error);
return std::vector<uint8_t>();
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 57a7bbd..bfd993a 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -30,7 +30,6 @@
using ::aidl::android::hardware::security::keymint::AttestationKey;
using ::aidl::android::hardware::security::keymint::BeginResult;
-using ::aidl::android::hardware::security::keymint::ByteArray;
using ::aidl::android::hardware::security::keymint::Certificate;
using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
using ::aidl::android::hardware::security::keymint::KeyCharacteristics;
@@ -38,7 +37,6 @@
using ::aidl::android::hardware::security::keymint::KeyFormat;
using ::aidl::android::hardware::security::keymint::KeyMintHardwareInfo;
using ::aidl::android::hardware::security::keymint::KeyParameter;
-using ::aidl::android::hardware::security::keymint::KeyParameterArray;
using ::aidl::android::hardware::security::keymint::KeyPurpose;
using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel;
using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
@@ -142,19 +140,22 @@
: mDevice(device), mOperationHandle(operationHandle), mOperationSlot(slots, isActive) {}
~KeyMintOperation();
- ScopedAStatus update(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<HardwareAuthToken>& in_inAuthToken,
- const std::optional<TimeStampToken>& in_inTimestampToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::optional<ByteArray>* out_output, int32_t* _aidl_return);
- ScopedAStatus finish(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<std::vector<uint8_t>>& in_inSignature,
- const std::optional<HardwareAuthToken>& in_authToken,
- const std::optional<TimeStampToken>& in_inTimestampToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::vector<uint8_t>* _aidl_return);
+ ScopedAStatus updateAad(const std::vector<uint8_t>& input,
+ const std::optional<HardwareAuthToken>& authToken,
+ const std::optional<TimeStampToken>& timestampToken) override;
+
+ ScopedAStatus update(const std::vector<uint8_t>& input,
+ const std::optional<HardwareAuthToken>& authToken,
+ const std::optional<TimeStampToken>& timestampToken,
+ std::vector<uint8_t>* output) override;
+
+ ScopedAStatus finish(const std::optional<std::vector<uint8_t>>& input,
+ const std::optional<std::vector<uint8_t>>& signature,
+ const std::optional<HardwareAuthToken>& authToken,
+ const std::optional<TimeStampToken>& timeStampToken,
+ const std::optional<std::vector<uint8_t>>& confirmationToken,
+ std::vector<uint8_t>* output) override;
+
ScopedAStatus abort();
};
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index 22ddc31..6e27b5c 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -31,8 +31,8 @@
Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
ErrorCode::ErrorCode, HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
- KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue,
- KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
+ KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+ SecurityLevel::SecurityLevel, Tag::Tag,
};
use android_hardware_security_keymint::binder::{self, Strong};
use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
@@ -283,41 +283,53 @@
let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
let operation = begin_result.operation.unwrap();
- let params = KeyParameterArray {
- params: vec![KeyParameter {
- tag: Tag::ASSOCIATED_DATA,
- value: KeyParameterValue::Blob(b"foobar".to_vec()),
- }],
- };
+
+ let update_aad_result = operation.updateAad(
+ &b"foobar".to_vec(),
+ None, /* authToken */
+ None, /* timestampToken */
+ );
+ assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
+
let message = [42; 128];
- let mut out_params = None;
- let result =
- operation.finish(Some(¶ms), Some(&message), None, None, None, &mut out_params);
+ let result = operation.finish(
+ Some(&message),
+ None, /* signature */
+ None, /* authToken */
+ None, /* timestampToken */
+ None, /* confirmationToken */
+ );
assert!(result.is_ok(), "{:?}", result);
let ciphertext = result.unwrap();
assert!(!ciphertext.is_empty());
- assert!(out_params.is_some());
let begin_result =
begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
+
let operation = begin_result.operation.unwrap();
- let mut out_params = None;
- let mut output = None;
+
+ let update_aad_result = operation.updateAad(
+ &b"foobar".to_vec(),
+ None, /* authToken */
+ None, /* timestampToken */
+ );
+ assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
+
let result = operation.update(
- Some(¶ms),
- Some(&ciphertext),
- None,
- None,
- &mut out_params,
- &mut output,
+ &ciphertext,
+ None, /* authToken */
+ None, /* timestampToken */
);
assert!(result.is_ok(), "{:?}", result);
- assert_eq!(result.unwrap(), message.len() as i32);
- assert!(output.is_some());
- assert_eq!(output.unwrap().data, message.to_vec());
- let result = operation.finish(Some(¶ms), None, None, None, None, &mut out_params);
+ assert_eq!(result.unwrap(), message);
+ let result = operation.finish(
+ None, /* input */
+ None, /* signature */
+ None, /* authToken */
+ None, /* timestampToken */
+ None, /* confirmationToken */
+ );
assert!(result.is_ok(), "{:?}", result);
- assert!(out_params.is_some());
}
#[test]
diff --git a/keystore2/src/km_compat/slot_test.cpp b/keystore2/src/km_compat/slot_test.cpp
index 37e7b36..43f3bc6 100644
--- a/keystore2/src/km_compat/slot_test.cpp
+++ b/keystore2/src/km_compat/slot_test.cpp
@@ -24,7 +24,6 @@
using ::aidl::android::hardware::security::keymint::Algorithm;
using ::aidl::android::hardware::security::keymint::BlockMode;
-using ::aidl::android::hardware::security::keymint::ByteArray;
using ::aidl::android::hardware::security::keymint::Certificate;
using ::aidl::android::hardware::security::keymint::Digest;
using ::aidl::android::hardware::security::keymint::ErrorCode;
@@ -100,18 +99,19 @@
// Calling finish should free up a slot.
auto last = operations.back();
operations.pop_back();
- std::optional<KeyParameterArray> kpa;
std::vector<uint8_t> byteVec;
- auto status = last->finish(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
- &kpa, &byteVec);
+ auto status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+ std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+ std::nullopt /* confirmationToken */, &byteVec);
ASSERT_TRUE(status.isOk());
result = begin(device, true);
ASSERT_TRUE(std::holds_alternative<BeginResult>(result));
operations.push_back(std::get<BeginResult>(result).operation);
// Calling finish and abort on an already-finished operation should not free up another slot.
- status = last->finish(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
- &kpa, &byteVec);
+ status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+ std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+ std::nullopt /* confirmationToken */, &byteVec);
ASSERT_TRUE(!status.isOk());
status = last->abort();
ASSERT_TRUE(!status.isOk());
@@ -130,8 +130,9 @@
operations.push_back(std::get<BeginResult>(result).operation);
// Calling finish and abort on an already-aborted operation should not free up another slot.
- status = last->finish(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
- &kpa, &byteVec);
+ status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+ std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+ std::nullopt /* confirmationToken */, &byteVec);
ASSERT_TRUE(!status.isOk());
status = last->abort();
ASSERT_TRUE(!status.isOk());
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index c98a76b..b6bb6ff 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -129,9 +129,7 @@
use crate::error::{map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
use crate::utils::Asp;
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
- ByteArray::ByteArray, IKeyMintOperation::IKeyMintOperation,
- KeyParameter::KeyParameter as KmParam, KeyParameterArray::KeyParameterArray,
- KeyParameterValue::KeyParameterValue as KmParamValue, Tag::Tag,
+ IKeyMintOperation::IKeyMintOperation,
};
use android_system_keystore2::aidl::android::system::keystore2::{
IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
@@ -325,16 +323,6 @@
Self::check_input_length(aad_input).context("In update_aad")?;
self.touch();
- let params = KeyParameterArray {
- params: vec![KmParam {
- tag: Tag::ASSOCIATED_DATA,
- value: KmParamValue::Blob(aad_input.into()),
- }],
- };
-
- let mut out_params: Option<KeyParameterArray> = None;
- let mut output: Option<ByteArray> = None;
-
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
@@ -347,14 +335,7 @@
self.update_outcome(
&mut *outcome,
- map_km_error(km_op.update(
- Some(¶ms),
- None,
- hat.as_ref(),
- tst.as_ref(),
- &mut out_params,
- &mut output,
- )),
+ map_km_error(km_op.updateAad(aad_input, hat.as_ref(), tst.as_ref())),
)
.context("In update_aad: KeyMint::update failed.")?;
@@ -368,8 +349,6 @@
Self::check_input_length(input).context("In update")?;
self.touch();
- let mut out_params: Option<KeyParameterArray> = None;
-
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
@@ -380,39 +359,17 @@
.before_update()
.context("In update: Trying to get auth tokens.")?;
- let mut result: Option<Vec<u8>> = None;
- let mut consumed = 0usize;
- loop {
- let mut output: Option<ByteArray> = None;
- consumed += self
- .update_outcome(
- &mut *outcome,
- map_km_error(km_op.update(
- None,
- Some(&input[consumed..]),
- hat.as_ref(),
- tst.as_ref(),
- &mut out_params,
- &mut output,
- )),
- )
- .context("In update: KeyMint::update failed.")? as usize;
+ let output = self
+ .update_outcome(
+ &mut *outcome,
+ map_km_error(km_op.update(input, hat.as_ref(), tst.as_ref())),
+ )
+ .context("In update: KeyMint::update failed.")?;
- match (output, &mut result) {
- (Some(blob), None) => {
- if !blob.data.is_empty() {
- result = Some(blob.data)
- }
- }
- (Some(mut blob), Some(ref mut result)) => {
- result.append(&mut blob.data);
- }
- (None, _) => {}
- }
-
- if consumed == input.len() {
- return Ok(result);
- }
+ if output.is_empty() {
+ Ok(None)
+ } else {
+ Ok(Some(output))
}
}
@@ -425,8 +382,6 @@
}
self.touch();
- let mut out_params: Option<KeyParameterArray> = None;
-
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
@@ -437,23 +392,15 @@
.before_finish()
.context("In finish: Trying to get auth tokens.")?;
- let in_params = confirmation_token.map(|token| KeyParameterArray {
- params: vec![KmParam {
- tag: Tag::CONFIRMATION_TOKEN,
- value: KmParamValue::Blob(token),
- }],
- });
-
let output = self
.update_outcome(
&mut *outcome,
map_km_error(km_op.finish(
- in_params.as_ref(),
input,
signature,
hat.as_ref(),
tst.as_ref(),
- &mut out_params,
+ confirmation_token.as_deref(),
)),
)
.context("In finish: KeyMint::finish failed.")?;