summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-07 01:10:21 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-07 01:10:21 +0000
commit5e24f2564e1f3368af0d0498783363311460a16a (patch)
treea3cd6e40eeb957acd070251231ab07999f0f5897
parent7aaa55378a833da311fd3d5adf9a4c1ef6e0e112 (diff)
parentd20c31e6cdeab7e46ddf85a4e965cf8e8839c5ff (diff)
downloadsecurity-android12-qpr1-release.tar.gz
Snap for 7800528 from d20c31e6cdeab7e46ddf85a4e965cf8e8839c5ff to sc-qpr1-releaseandroid-12.0.0_r28android-12.0.0_r26android-12.0.0_r16android12-qpr1-release
Change-Id: I8d9b0e5bfe26b4fb81e3205feb5305be9bb40d99
-rw-r--r--keystore2/src/km_compat/km_compat.cpp32
-rw-r--r--keystore2/src/km_compat/km_compat.h24
2 files changed, 48 insertions, 8 deletions
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 64849c16..8d59a5a7 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -762,7 +762,21 @@ ScopedAStatus KeyMintOperation::updateAad(const std::vector<uint8_t>& input,
return convertErrorCode(errorCode);
}
-ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
+void KeyMintOperation::setUpdateBuffer(std::vector<uint8_t> data) {
+ mUpdateBuffer = std::move(data);
+}
+
+const std::vector<uint8_t>&
+KeyMintOperation::getExtendedUpdateBuffer(const std::vector<uint8_t>& suffix) {
+ if (mUpdateBuffer.empty()) {
+ return suffix;
+ } else {
+ mUpdateBuffer.insert(mUpdateBuffer.end(), suffix.begin(), suffix.end());
+ return mUpdateBuffer;
+ }
+}
+
+ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input_raw,
const std::optional<HardwareAuthToken>& optAuthToken,
const std::optional<TimeStampToken>& optTimeStampToken,
std::vector<uint8_t>* out_output) {
@@ -772,8 +786,10 @@ ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
size_t inputPos = 0;
*out_output = {};
KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+ auto input = getExtendedUpdateBuffer(input_raw);
while (inputPos < input.size() && errorCode == KMV1::ErrorCode::OK) {
+ uint32_t consumed = 0;
auto result =
mDevice->update(mOperationHandle, {} /* inParams */,
{input.begin() + inputPos, input.end()}, authToken, verificationToken,
@@ -781,13 +797,22 @@ ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
const hidl_vec<uint8_t>& output) {
errorCode = convert(error);
out_output->insert(out_output->end(), output.begin(), output.end());
- inputPos += inputConsumed;
+ consumed = inputConsumed;
});
if (!result.isOk()) {
LOG(ERROR) << __func__ << " transaction failed. " << result.description();
errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
+
+ if (errorCode == KMV1::ErrorCode::OK && consumed == 0) {
+ // Some very old KM implementations do not buffer sub blocks in certain block modes,
+ // instead, the simply return consumed == 0. So we buffer the input here in the
+ // hope that we complete the bock in a future call to update.
+ setUpdateBuffer({input.begin() + inputPos, input.end()});
+ return convertErrorCode(errorCode);
+ }
+ inputPos += consumed;
}
if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
@@ -802,7 +827,8 @@ KeyMintOperation::finish(const std::optional<std::vector<uint8_t>>& in_input,
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 input_raw = in_input.value_or(std::vector<uint8_t>());
+ auto input = getExtendedUpdateBuffer(input_raw);
auto signature = in_signature.value_or(std::vector<uint8_t>());
V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(in_authToken);
V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(in_timeStampToken);
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 2d892da4..70c7b863 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -140,11 +140,6 @@ class KeyMintDevice : public aidl::android::hardware::security::keymint::BnKeyMi
};
class KeyMintOperation : public aidl::android::hardware::security::keymint::BnKeyMintOperation {
- private:
- ::android::sp<Keymaster> mDevice;
- uint64_t mOperationHandle;
- OperationSlot mOperationSlot;
-
public:
KeyMintOperation(::android::sp<Keymaster> device, uint64_t operationHandle,
OperationSlots* slots, bool isActive)
@@ -168,6 +163,25 @@ class KeyMintOperation : public aidl::android::hardware::security::keymint::BnKe
std::vector<uint8_t>* output) override;
ScopedAStatus abort();
+
+ private:
+ /**
+ * Sets mUpdateBuffer to the given value.
+ * @param data
+ */
+ void setUpdateBuffer(std::vector<uint8_t> data);
+ /**
+ * If mUpdateBuffer is not empty, suffix is appended to mUpdateBuffer, and a reference to
+ * mUpdateBuffer is returned. Otherwise a reference to suffix is returned.
+ * @param suffix
+ * @return
+ */
+ const std::vector<uint8_t>& getExtendedUpdateBuffer(const std::vector<uint8_t>& suffix);
+
+ std::vector<uint8_t> mUpdateBuffer;
+ ::android::sp<Keymaster> mDevice;
+ uint64_t mOperationHandle;
+ OperationSlot mOperationSlot;
};
class SharedSecret : public aidl::android::hardware::security::sharedsecret::BnSharedSecret {