Add optional additional entropy to finish
If provided the extra entropy will be added to the device before calling
finish. If entropy is provided and the device does not support supplying
additional entropy then finish will fail with KM_ERROR_UNIMPLEMENTED.
(cherry-picked from commit 8cfb8ac6e9bd291e9d861a32de2719e3bc797191)
Change-Id: If26be118bf382604f6f8e96e833b76e6f9e94d58
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index fc0b8da..9d19b46 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -1129,7 +1129,9 @@
}
virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
- const uint8_t* signature, size_t signatureLength, OperationResult* result)
+ const uint8_t* signature, size_t signatureLength,
+ const uint8_t* entropy, size_t entropyLength,
+ OperationResult* result)
{
if (!result) {
return;
@@ -1140,6 +1142,7 @@
data.writeInt32(1);
params.writeToParcel(&data);
data.writeByteArray(signatureLength, signature);
+ data.writeByteArray(entropyLength, entropy);
status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
if (status != NO_ERROR) {
ALOGD("finish() could not contact remote: %d\n", status);
@@ -1681,11 +1684,14 @@
if (data.readInt32() != 0) {
args.readFromParcel(data);
}
- const uint8_t* buf = NULL;
- size_t bufLength = 0;
- readByteArray(data, &buf, &bufLength);
+ const uint8_t* signature = NULL;
+ size_t signatureLength = 0;
+ readByteArray(data, &signature, &signatureLength);
+ const uint8_t* entropy = NULL;
+ size_t entropyLength = 0;
+ readByteArray(data, &entropy, &entropyLength);
OperationResult result;
- finish(token, args, buf, bufLength, &result);
+ finish(token, args, signature, signatureLength, entropy, entropyLength, &result);
reply->writeNoException();
reply->writeInt32(1);
result.writeToParcel(reply);
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 6ad752e..c136dfd 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -218,6 +218,7 @@
virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
const uint8_t* signature, size_t signatureLength,
+ const uint8_t* entropy, size_t entropyLength,
OperationResult* result) = 0;
virtual int32_t abort(const sp<IBinder>& handle) = 0;
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 2208936..5be31eb 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -2671,7 +2671,8 @@
}
void finish(const sp<IBinder>& token, const KeymasterArguments& params,
- const uint8_t* signature, size_t signatureLength, OperationResult* result) {
+ const uint8_t* signature, size_t signatureLength,
+ const uint8_t* entropy, size_t entropyLength, OperationResult* result) {
if (!checkAllowedOperationParams(params.params)) {
result->resultCode = KM_ERROR_INVALID_ARGUMENT;
return;
@@ -2688,12 +2689,24 @@
result->resultCode = authResult;
return;
}
+ keymaster_error_t err;
+ if (entropy) {
+ if (dev->add_rng_entropy) {
+ err = dev->add_rng_entropy(dev, entropy, entropyLength);
+ } else {
+ err = KM_ERROR_UNIMPLEMENTED;
+ }
+ if (err) {
+ result->resultCode = err;
+ return;
+ }
+ }
keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
keymaster_blob_t input = {signature, signatureLength};
keymaster_blob_t output = {NULL, 0};
keymaster_key_param_set_t outParams = {NULL, 0};
- keymaster_error_t err = dev->finish(dev, handle, &inParams, &input, &outParams, &output);
+ err = dev->finish(dev, handle, &inParams, &input, &outParams, &output);
// Remove the operation regardless of the result
mOperationMap.removeOperation(token);
mAuthTokenTable.MarkCompleted(handle);