diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-07 01:10:31 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-10-07 01:10:31 +0000 |
commit | 6a914116a66f0d348164d813d8ff50de57ecf483 (patch) | |
tree | a3cd6e40eeb957acd070251231ab07999f0f5897 | |
parent | c5d4b5da6f9ca287fe34e1ab932ea31127f8f27f (diff) | |
parent | d20c31e6cdeab7e46ddf85a4e965cf8e8839c5ff (diff) | |
download | security-android12-qpr1-d-s1-release.tar.gz |
Snap for 7800528 from d20c31e6cdeab7e46ddf85a4e965cf8e8839c5ff to sc-qpr1-d-releaseandroid-12.0.0_r32android-12.0.0_r29android-12.0.0_r27android-12.0.0_r21android-12.0.0_r20android-12.0.0_r19android-12.0.0_r18android12-qpr1-d-s3-releaseandroid12-qpr1-d-s2-releaseandroid12-qpr1-d-s1-releaseandroid12-qpr1-d-release
Change-Id: Ie8e18d444ecd3e7a0863781038a659b80d7fc480
-rw-r--r-- | keystore2/src/km_compat/km_compat.cpp | 32 | ||||
-rw-r--r-- | keystore2/src/km_compat/km_compat.h | 24 |
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 { |