Separate updateAad from update & other cleanups

Test: VtsKeyMintAidlTargetTest
Change-Id: Ib4ab43dbf2604a7642fb2b551646fd7f0adac615
This commit is contained in:
Shawn Willden
2021-02-19 07:31:55 -07:00
parent 58a8db2148
commit 92d79c093f
20 changed files with 211 additions and 581 deletions

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2020 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.
*////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.security.keymint;
@VintfStability
parcelable ByteArray {
byte[] data;
}

View File

@@ -36,7 +36,7 @@ parcelable HardwareAuthToken {
long challenge;
long userId;
long authenticatorId;
android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType;
android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType = android.hardware.security.keymint.HardwareAuthenticatorType.NONE;
android.hardware.security.secureclock.Timestamp timestamp;
byte[] mac;
}

View File

@@ -33,7 +33,8 @@
package android.hardware.security.keymint;
@VintfStability
interface IKeyMintOperation {
int update(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken inAuthToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams, out @nullable android.hardware.security.keymint.ByteArray output);
byte[] finish(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable byte[] inSignature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams);
void updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
byte[] update(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
byte[] finish(in @nullable byte[] input, in @nullable byte[] signature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken, in @nullable byte[] confirmationToken);
void abort();
}

View File

@@ -33,6 +33,6 @@
package android.hardware.security.keymint;
@VintfStability
parcelable KeyCharacteristics {
android.hardware.security.keymint.SecurityLevel securityLevel;
android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
android.hardware.security.keymint.KeyParameter[] authorizations;
}

View File

@@ -34,7 +34,7 @@ package android.hardware.security.keymint;
@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
parcelable KeyMintHardwareInfo {
int versionNumber;
android.hardware.security.keymint.SecurityLevel securityLevel;
android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
@utf8InCpp String keyMintName;
@utf8InCpp String keyMintAuthorName;
boolean timestampTokenRequired;

View File

@@ -33,6 +33,6 @@
package android.hardware.security.keymint;
@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
parcelable KeyParameter {
android.hardware.security.keymint.Tag tag;
android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID;
android.hardware.security.keymint.KeyParameterValue value;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2020 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.
*////////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.security.keymint;
@VintfStability
parcelable KeyParameterArray {
android.hardware.security.keymint.KeyParameter[] params;
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2020 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.hardware.security.keymint;
/**
* This is used to contain a byte[], to make out parameters of byte arrays
* more convenient for callers.
*/
@VintfStability
parcelable ByteArray {
byte[] data;
}

View File

@@ -16,17 +16,17 @@
package android.hardware.security.keymint;
import android.hardware.security.secureclock.Timestamp;
import android.hardware.security.keymint.HardwareAuthenticatorType;
import android.hardware.security.secureclock.Timestamp;
/**
* HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
*
* HardwareAuthTokens are produced by other secure environment applications, notably GateKeeper and
* biometric authenticators, in response to successful user authentication events. These tokens are passed to
* begin(), update(), and finish() to prove that authentication occurred. See those methods for
* more details. It is up to the caller to determine which of the generated auth tokens is
* appropriate for a given key operation.
* biometric authenticators, in response to successful user authentication events. These tokens are
* passed to begin(), update(), and finish() to prove that authentication occurred. See those
* methods for more details. It is up to the caller to determine which of the generated auth tokens
* is appropriate for a given key operation.
*/
@VintfStability
@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
@@ -55,7 +55,7 @@ parcelable HardwareAuthToken {
* authenticatorType describes the type of authentication that took place, e.g. password or
* fingerprint.
*/
HardwareAuthenticatorType authenticatorType;
HardwareAuthenticatorType authenticatorType = HardwareAuthenticatorType.NONE;
/**
* timestamp indicates when the user authentication took place, in milliseconds since some

View File

@@ -18,7 +18,6 @@ package android.hardware.security.keymint;
import android.hardware.security.keymint.AttestationKey;
import android.hardware.security.keymint.BeginResult;
import android.hardware.security.keymint.ByteArray;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.IKeyMintOperation;
import android.hardware.security.keymint.KeyCreationResult;

View File

@@ -16,14 +16,74 @@
package android.hardware.security.keymint;
import android.hardware.security.keymint.ByteArray;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyParameterArray;
import android.hardware.security.secureclock.TimeStampToken;
@VintfStability
interface IKeyMintOperation {
/**
* Provides additional authentication data (AAD) to a cryptographic operation begun with
* begin(), provided in the input argument. This method only applies to AEAD modes. This
* method may be called multiple times, supplying the AAD in chunks, but may not be called after
* update() is called. If updateAad() is called after update(), it must return
* ErrorCode::INVALID_TAG.
*
* If operation is in an invalid state (was aborted or had an error) update() must return
* ErrorCode::INVALID_OPERATION_HANDLE.
*
* If this method returns an error code other than ErrorCode::OK, the operation is aborted and
* the operation handle must be invalidated. Any future use of the handle, with this method,
* finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
*
* == Authorization Enforcement ==
*
* Key authorization enforcement is performed primarily in begin(). The one exception is the
* case where the key has:
*
* o One or more Tag::USER_SECURE_IDs, and
*
* o Does not have a Tag::AUTH_TIMEOUT
*
* In this case, the key requires an authorization per operation, and the update method must
* receive a non-null and valid HardwareAuthToken. For the auth token to be valid, all of the
* following has to be true:
*
* o The HMAC field must validate correctly.
*
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
* the secure ID values in the token.
*
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
*
* o The challenge field in the auth token must contain the operationHandle
*
* If any of these conditions are not met, update() must return
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
*
* The caller must provide the auth token on every call to updateAad(), update() and finish().
*
*
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
* @param input Additional Authentication Data to be processed.
*
* @param authToken Authentication token. Can be nullable if not provided.
*
* @param timeStampToken timestamp token, certifies the freshness of an auth token in case
* the security domain of this KeyMint instance has a different clock than the
* authenticator issuing the auth token.
*
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
* ErrorCode enum in ErrorCode.aidl.
*/
void updateAad(in byte[] input, in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timeStampToken);
/**
* Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
* with begin().
@@ -96,53 +156,28 @@ interface IKeyMintOperation {
*
* -- AES keys --
*
* AES GCM mode supports "associated authentication data," provided via the Tag::ASSOCIATED_DATA
* tag in the inParams argument. The associated data may be provided in repeated calls
* (important if the data is too large to send in a single block) but must always precede data
* to be encrypted or decrypted. An update call may receive both associated data and data to
* encrypt/decrypt, but subsequent updates must not include associated data. If the caller
* provides associated data to an update call after a call that includes data to
* encrypt/decrypt, update() must return ErrorCode::INVALID_TAG.
*
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
* TODO: update() needs to be refactored b/168665179.
*
* @param inParams Additional parameters for the operation. For AEAD modes, this is used to
* specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in multiple
* calls to update(), but only until input data has been provided.
*
* @param input Data to be processed. Note that update() may or may not consume all of the data
* provided. See return value.
*
* @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
* the security domain of this KeyMint instance has a different clock than the
* authenticator issuing the auth token.
* @param authToken Authentication token. Can be nullable if not provided.
*
* @param timeStampToken certifies the freshness of an auth token in case the security domain of
* this KeyMint instance has a different clock than the authenticator issuing the auth
* token.
*
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
* ErrorCode enum in ErrorCode.aidl.
*
* @return int Amount of data that was consumed by update(). If this is less than the
* amount provided, the caller may provide the remainder in a subsequent call to
* update() or finish(). Every call to update must consume at least one byte, unless
* the input is empty, and implementations should consume as much data as reasonably
* possible for each call.
*
* @return outParams returns the updated key parameters from the blob, if needed.
* operation.
*
* @return out variable output The output data, if any.
* @return byte[] The output data, if any.
*/
int update(in @nullable KeyParameterArray inParams,
in @nullable byte[] input,
in @nullable HardwareAuthToken inAuthToken,
in @nullable TimeStampToken inTimeStampToken,
out @nullable KeyParameterArray outParams,
out @nullable ByteArray output);
byte[] update(in byte[] input, in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timeStampToken);
/**
* Finalizes a cryptographic operation begun with begin() and invalidates operation.
@@ -229,8 +264,7 @@ interface IKeyMintOperation {
*
* TODO: update() will need to be refactored into 2 function. b/168665179.
*
* @param inParams Additional parameters for the operation. For AEAD modes, this is used to
* specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
* @param inParams Additional parameters for the operation.
*
* @param input Data to be processed, per the parameters established in the call to begin().
* finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
@@ -240,19 +274,21 @@ interface IKeyMintOperation {
*
* @param authToken Authentication token. Can be nullable if not provided.
*
* @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
* the security domain of this KeyMint instance has a different clock than the
* authenticator issuing the auth token.
* @param timestampToken certifies the freshness of an auth token in case the security domain of
* this KeyMint instance has a different clock than the authenticator issuing the auth
* token.
*
* @return outParams Any output parameters generated by finish().
* @param confirmationToken is the confirmation token required by keys with
* Tag::TRUSTED_CONFIRMATION_REQUIRED.
*
* @return The output data, if any.
*
* @return outParams Any output parameters generated by finish().
*/
byte[] finish(in @nullable KeyParameterArray inParams, in @nullable byte[] input,
in @nullable byte[] inSignature,
in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken inTimeStampToken,
out @nullable KeyParameterArray outParams);
byte[] finish(in @nullable byte[] input, in @nullable byte[] signature,
in @nullable HardwareAuthToken authToken,
in @nullable TimeStampToken timestampToken,
in @nullable byte[] confirmationToken);
/**
* Aborts a cryptographic operation begun with begin(), freeing all internal resources. If an

View File

@@ -31,6 +31,6 @@ import android.hardware.security.keymint.SecurityLevel;
*/
@VintfStability
parcelable KeyCharacteristics {
SecurityLevel securityLevel;
SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
KeyParameter[] authorizations;
}

View File

@@ -34,7 +34,7 @@ parcelable KeyMintHardwareInfo {
/* securityLevel is the security level of the IKeyMintDevice implementation accessed
* through this aidl package. */
SecurityLevel securityLevel;
SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
/* keyMintName is the name of the IKeyMintDevice implementation. */
@utf8InCpp String keyMintName;

View File

@@ -16,8 +16,8 @@
package android.hardware.security.keymint;
import android.hardware.security.keymint.Tag;
import android.hardware.security.keymint.KeyParameterValue;
import android.hardware.security.keymint.Tag;
/**
* Identifies the key authorization parameters to be used with keyMint. This is usually
@@ -26,6 +26,6 @@ import android.hardware.security.keymint.KeyParameterValue;
@VintfStability
@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
parcelable KeyParameter {
Tag tag;
Tag tag = Tag.INVALID;
KeyParameterValue value;
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2020 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.hardware.security.keymint;
import android.hardware.security.keymint.KeyParameter;
/**
* Identifies the key authorization parameters to be used with keyMint. This is usually
* provided as an array of KeyParameters to IKeyMintDevice or Operation.
*/
@VintfStability
parcelable KeyParameterArray {
/**
* Identify list of key parameters corresponding to a particular key blob.
*/
KeyParameter[] params;
}

View File

@@ -883,11 +883,7 @@ enum Tag {
STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722,
/**
* Tag::ASSOCIATED_DATA Provides "associated data" for AES-GCM encryption or decryption. This
* tag is provided to update and specifies data that is not encrypted/decrypted, but is used in
* computing the GCM tag.
*
* Must never appear KeyCharacteristics.
* TODO: Delete when keystore1 is deleted.
*/
ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000,

View File

@@ -386,122 +386,50 @@ ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet&
return result;
}
ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input,
AuthorizationSet* out_params, string* output,
int32_t* input_consumed) {
ErrorCode KeyMintAidlTestBase::UpdateAad(const string& input) {
return GetReturnErrorCode(op_->updateAad(vector<uint8_t>(input.begin(), input.end()),
{} /* hardwareAuthToken */,
{} /* verificationToken */));
}
ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) {
SCOPED_TRACE("Update");
Status result;
EXPECT_NE(op_, nullptr);
if (!op_) {
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
KeyParameterArray key_params;
key_params.params = in_params.vector_data();
std::vector<uint8_t> o_put;
result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
KeyParameterArray in_keyParams;
in_keyParams.params = in_params.vector_data();
optional<KeyParameterArray> out_keyParams;
optional<ByteArray> o_put;
result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
&out_keyParams, &o_put, input_consumed);
if (result.isOk()) {
if (o_put) {
output->append(o_put->data.begin(), o_put->data.end());
}
if (out_keyParams) {
out_params->push_back(AuthorizationSet(out_keyParams->params));
}
}
if (result.isOk()) output->append(o_put.begin(), o_put.end());
return GetReturnErrorCode(result);
}
ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) {
SCOPED_TRACE("Update");
AuthorizationSet out_params;
ErrorCode result =
Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed);
EXPECT_TRUE(out_params.empty());
return result;
}
ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input,
const string& signature, AuthorizationSet* out_params,
ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
string* output) {
SCOPED_TRACE("Finish");
Status result;
EXPECT_NE(op_, nullptr);
if (!op_) {
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
KeyParameterArray key_params;
key_params.params = in_params.vector_data();
KeyParameterArray in_keyParams;
in_keyParams.params = in_params.vector_data();
optional<KeyParameterArray> out_keyParams;
optional<vector<uint8_t>> o_put;
if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
vector<uint8_t> oPut;
result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
vector<uint8_t>(signature.begin(), signature.end()), {}, {},
&out_keyParams, &oPut);
result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
{} /* timestampToken */, {} /* confirmationToken */, &oPut);
if (result.isOk()) {
if (out_keyParams) {
out_params->push_back(AuthorizationSet(out_keyParams->params));
}
if (result.isOk()) output->append(oPut.begin(), oPut.end());
output->append(oPut.begin(), oPut.end());
}
op_.reset();
op_ = {};
return GetReturnErrorCode(result);
}
ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) {
SCOPED_TRACE("Finish");
AuthorizationSet out_params;
string finish_output;
ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */,
&out_params, output);
if (result != ErrorCode::OK) {
return result;
}
EXPECT_EQ(0U, out_params.size());
return result;
}
ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature,
string* output) {
SCOPED_TRACE("Finish");
AuthorizationSet out_params;
ErrorCode result =
Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output);
if (result != ErrorCode::OK) {
return result;
}
EXPECT_EQ(0U, out_params.size());
return result;
}
ErrorCode KeyMintAidlTestBase::Abort(const std::shared_ptr<IKeyMintOperation>& op) {
SCOPED_TRACE("Abort");
EXPECT_NE(op, nullptr);
if (!op) {
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
if (!op) return ErrorCode::UNEXPECTED_NULL_POINTER;
Status retval = op->abort();
EXPECT_TRUE(retval.isOk());
@@ -512,9 +440,7 @@ ErrorCode KeyMintAidlTestBase::Abort() {
SCOPED_TRACE("Abort");
EXPECT_NE(op_, nullptr);
if (!op_) {
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
Status retval = op_->abort();
return static_cast<ErrorCode>(retval.getServiceSpecificError());
@@ -530,30 +456,13 @@ void KeyMintAidlTestBase::AbortIfNeeded() {
auto KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params)
-> std::tuple<ErrorCode, string, AuthorizationSet /* out_params */> {
-> std::tuple<ErrorCode, string> {
AuthorizationSet begin_out_params;
ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
AuthorizationSet out_params(std::move(begin_out_params));
if (result != ErrorCode::OK) {
return {result, {}, out_params};
}
if (result != ErrorCode::OK) return {result, {}};
string output;
int32_t consumed = 0;
AuthorizationSet update_params;
AuthorizationSet update_out_params;
result = Update(update_params, message, &update_out_params, &output, &consumed);
out_params.push_back(update_out_params);
if (result != ErrorCode::OK) {
return {result, output, out_params};
}
string unused;
AuthorizationSet finish_params;
AuthorizationSet finish_out_params;
result = Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output);
out_params.push_back(finish_out_params);
return {result, output, out_params};
return {Finish(message, &output), output};
}
string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
@@ -561,30 +470,14 @@ string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyP
AuthorizationSet* out_params) {
SCOPED_TRACE("ProcessMessage");
AuthorizationSet begin_out_params;
ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
ErrorCode result = Begin(operation, key_blob, in_params, out_params);
EXPECT_EQ(ErrorCode::OK, result);
if (result != ErrorCode::OK) {
return "";
}
string output;
int32_t consumed = 0;
AuthorizationSet update_params;
AuthorizationSet update_out_params;
result = Update(update_params, message, &update_out_params, &output, &consumed);
EXPECT_EQ(ErrorCode::OK, result);
if (result != ErrorCode::OK) {
return "";
}
string unused;
AuthorizationSet finish_params;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK,
Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output));
out_params->push_back(begin_out_params);
out_params->push_back(finish_out_params);
EXPECT_EQ(ErrorCode::OK, Finish(message, &output));
return output;
}
@@ -674,21 +567,9 @@ void KeyMintAidlTestBase::VerifyMessage(const vector<uint8_t>& key_blob, const s
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params));
string output;
AuthorizationSet update_params;
AuthorizationSet update_out_params;
int32_t consumed;
ASSERT_EQ(ErrorCode::OK,
Update(update_params, message, &update_out_params, &output, &consumed));
EXPECT_TRUE(output.empty());
EXPECT_GT(consumed, 0U);
string unused;
AuthorizationSet finish_params;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature,
&finish_out_params, &output));
op_.reset();
EXPECT_EQ(ErrorCode::OK, Finish(message, signature, &output));
EXPECT_TRUE(output.empty());
op_ = {};
}
void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature,
@@ -955,14 +836,14 @@ AuthorizationSet KeyMintAidlTestBase::SwEnforcedAuthorizations(
}
ErrorCode KeyMintAidlTestBase::UseAesKey(const vector<uint8_t>& aesKeyBlob) {
auto [result, ciphertext, out_params] = ProcessMessage(
auto [result, ciphertext] = ProcessMessage(
aesKeyBlob, KeyPurpose::ENCRYPT, "1234567890123456",
AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE));
return result;
}
ErrorCode KeyMintAidlTestBase::UseHmacKey(const vector<uint8_t>& hmacKeyBlob) {
auto [result, mac, out_params] = ProcessMessage(
auto [result, mac] = ProcessMessage(
hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
AuthorizationSetBuilder().Authorization(TAG_MAC_LENGTH, 128).Digest(Digest::SHA_2_256));
return result;
@@ -970,16 +851,15 @@ ErrorCode KeyMintAidlTestBase::UseHmacKey(const vector<uint8_t>& hmacKeyBlob) {
ErrorCode KeyMintAidlTestBase::UseRsaKey(const vector<uint8_t>& rsaKeyBlob) {
std::string message(2048 / 8, 'a');
auto [result, signature, out_params] = ProcessMessage(
auto [result, signature] = ProcessMessage(
rsaKeyBlob, KeyPurpose::SIGN, message,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
return result;
}
ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob) {
auto [result, signature, out_params] =
ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
auto [result, signature] = ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
return result;
}

View File

@@ -112,15 +112,14 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
AuthorizationSet* out_params);
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
ErrorCode Update(const AuthorizationSet& in_params, const string& input,
AuthorizationSet* out_params, string* output, int32_t* input_consumed);
ErrorCode Update(const string& input, string* out, int32_t* input_consumed);
ErrorCode UpdateAad(const string& input);
ErrorCode Update(const string& input, string* output);
ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
const string& signature, AuthorizationSet* out_params, string* output);
ErrorCode Finish(const string& message, string* output);
ErrorCode Finish(const string& message, const string& signature, string* output);
ErrorCode Finish(string* output) { return Finish(string(), output); }
ErrorCode Finish(const string& message, string* output) {
return Finish(message, {} /* signature */, output);
}
ErrorCode Finish(string* output) { return Finish({} /* message */, output); }
ErrorCode Abort();
ErrorCode Abort(const shared_ptr<IKeyMintOperation>& op);
@@ -129,9 +128,9 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params,
AuthorizationSet* out_params);
std::tuple<ErrorCode, std::string /* processedMessage */, AuthorizationSet /* out_params */>
ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const std::string& message, const AuthorizationSet& in_params);
std::tuple<ErrorCode, std::string /* processedMessage */> ProcessMessage(
const vector<uint8_t>& key_blob, KeyPurpose operation, const std::string& message,
const AuthorizationSet& in_params);
string SignMessage(const vector<uint8_t>& key_blob, const string& message,
const AuthorizationSet& params);
string SignMessage(const string& message, const AuthorizationSet& params);

View File

@@ -2751,39 +2751,22 @@ TEST_P(EncryptionOperationsTest, AesIncremental) {
for (int increment = 1; increment <= 240; ++increment) {
for (auto block_mode : block_modes) {
string message(240, 'a');
auto params = AuthorizationSetBuilder()
.BlockMode(block_mode)
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
auto params =
AuthorizationSetBuilder().BlockMode(block_mode).Padding(PaddingMode::NONE);
if (block_mode == BlockMode::GCM) {
params.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
}
AuthorizationSet output_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));
string ciphertext;
int32_t input_consumed;
string to_send;
for (size_t i = 0; i < message.size(); i += increment) {
to_send.append(message.substr(i, increment));
EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed));
EXPECT_EQ(to_send.length(), input_consumed);
to_send = to_send.substr(input_consumed);
EXPECT_EQ(0U, to_send.length());
switch (block_mode) {
case BlockMode::ECB:
case BlockMode::CBC:
// Implementations must take as many blocks as possible, leaving less
// than a block.
EXPECT_LE(to_send.length(), 16U);
break;
case BlockMode::GCM:
case BlockMode::CTR:
// Implementations must always take all the data.
EXPECT_EQ(0U, to_send.length());
break;
}
EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
}
EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send;
EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext))
<< "Error sending " << to_send << " with block mode " << block_mode;
switch (block_mode) {
case BlockMode::GCM:
@@ -2818,9 +2801,7 @@ TEST_P(EncryptionOperationsTest, AesIncremental) {
string plaintext;
for (size_t i = 0; i < ciphertext.size(); i += increment) {
to_send.append(ciphertext.substr(i, increment));
EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed));
to_send = to_send.substr(input_consumed);
EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
}
ErrorCode error = Finish(to_send, &plaintext);
ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
@@ -3077,17 +3058,13 @@ TEST_P(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto update_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
// Encrypt
AuthorizationSet begin_out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
<< "Begin encrypt";
string ciphertext;
AuthorizationSet update_out_params;
ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
ASSERT_EQ(ciphertext.length(), message.length() + 16);
// Grab nonce
@@ -3095,12 +3072,9 @@ TEST_P(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
// Decrypt.
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
int32_t input_consumed;
ASSERT_EQ(ErrorCode::OK,
Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_EQ(message.length(), plaintext.length());
EXPECT_EQ(message, plaintext);
}
@@ -3127,17 +3101,15 @@ TEST_P(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto update_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
// Encrypt
AuthorizationSet begin_out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
<< "Begin encrypt";
string ciphertext;
AuthorizationSet update_out_params;
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
sleep(5);
ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
ASSERT_EQ(ciphertext.length(), message.length() + 16);
@@ -3147,11 +3119,9 @@ TEST_P(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) {
// Decrypt.
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
string plaintext;
int32_t input_consumed;
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
sleep(5);
ASSERT_EQ(ErrorCode::OK,
Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
ASSERT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
sleep(5);
EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
EXPECT_EQ(message.length(), plaintext.length());
@@ -3230,9 +3200,6 @@ TEST_P(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto finish_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
@@ -3241,8 +3208,8 @@ TEST_P(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
AuthorizationSet finish_out_params;
string ciphertext;
EXPECT_EQ(ErrorCode::OK,
Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
params = AuthorizationSetBuilder()
.Authorizations(begin_out_params)
@@ -3326,16 +3293,13 @@ TEST_P(EncryptionOperationsTest, AesGcmAadNoData) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto finish_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
string ciphertext;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK, Finish(finish_params, "" /* input */, "" /* signature */,
&finish_out_params, &ciphertext));
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
EXPECT_TRUE(finish_out_params.empty());
// Grab nonce
@@ -3343,9 +3307,9 @@ TEST_P(EncryptionOperationsTest, AesGcmAadNoData) {
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
EXPECT_EQ(ErrorCode::OK, Finish(finish_params, ciphertext, "" /* signature */,
&finish_out_params, &plaintext));
EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_TRUE(finish_out_params.empty());
@@ -3374,43 +3338,26 @@ TEST_P(EncryptionOperationsTest, AesGcmMultiPartAad) {
.Authorization(TAG_MAC_LENGTH, tag_bits);
AuthorizationSet begin_out_params;
auto update_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
// No data, AAD only.
EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
string ciphertext;
int32_t input_consumed;
AuthorizationSet update_out_params;
EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
&input_consumed));
EXPECT_EQ(0U, input_consumed);
EXPECT_EQ(0U, ciphertext.size());
EXPECT_TRUE(update_out_params.empty());
EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
// AAD and data.
EXPECT_EQ(ErrorCode::OK,
Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
EXPECT_EQ(message.size(), input_consumed);
EXPECT_TRUE(update_out_params.empty());
EXPECT_EQ(ErrorCode::OK, Finish("" /* input */, &ciphertext));
// Expect 128-bit (16-byte) tag appended to ciphertext.
EXPECT_EQ(message.size() + (tag_bits >> 3), ciphertext.size());
EXPECT_EQ(message.size() + (tag_bits / 8), ciphertext.size());
// Grab nonce.
begin_params.push_back(begin_out_params);
// Decrypt
update_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foofoo", (size_t)6);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad("foofoo"));
string plaintext;
EXPECT_EQ(ErrorCode::OK, Finish(update_params, ciphertext, "" /* signature */,
&update_out_params, &plaintext));
EXPECT_TRUE(update_out_params.empty());
EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_EQ(message, plaintext);
}
@@ -3434,32 +3381,14 @@ TEST_P(EncryptionOperationsTest, AesGcmAadOutOfOrder) {
.Authorization(TAG_MAC_LENGTH, 128);
AuthorizationSet begin_out_params;
auto update_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
// No data, AAD only.
EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
string ciphertext;
int32_t input_consumed;
AuthorizationSet update_out_params;
EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
&input_consumed));
EXPECT_EQ(0U, input_consumed);
EXPECT_EQ(0U, ciphertext.size());
EXPECT_TRUE(update_out_params.empty());
EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
EXPECT_EQ(ErrorCode::INVALID_TAG, UpdateAad("foo"));
// AAD and data.
EXPECT_EQ(ErrorCode::OK,
Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
EXPECT_EQ(message.size(), input_consumed);
EXPECT_TRUE(update_out_params.empty());
// More AAD
EXPECT_EQ(ErrorCode::INVALID_TAG,
Update(update_params, "", &update_out_params, &ciphertext, &input_consumed));
op_.reset();
op_ = {};
}
/*
@@ -3481,28 +3410,21 @@ TEST_P(EncryptionOperationsTest, AesGcmBadAad) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto finish_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string ciphertext;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK,
Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Grab nonce
begin_params.push_back(begin_out_params);
finish_params = AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA,
"barfoo" /* Wrong AAD */, (size_t)6);
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad("barfoo"));
string plaintext;
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
&finish_out_params, &plaintext));
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
}
/*
@@ -3524,25 +3446,22 @@ TEST_P(EncryptionOperationsTest, AesGcmWrongNonce) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto finish_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string ciphertext;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK,
Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Wrong nonce
begin_params.push_back(TAG_NONCE, AidlBuf("123456789012"));
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string plaintext;
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
&finish_out_params, &plaintext));
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
// With wrong nonce, should have gotten garbage plaintext (or none).
EXPECT_NE(message, plaintext);
@@ -3569,17 +3488,12 @@ TEST_P(EncryptionOperationsTest, AesGcmCorruptTag) {
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
auto finish_params =
AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
string ciphertext;
AuthorizationSet finish_out_params;
EXPECT_EQ(ErrorCode::OK,
Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
EXPECT_TRUE(finish_out_params.empty());
EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Corrupt tag
++(*ciphertext.rbegin());
@@ -3589,10 +3503,9 @@ TEST_P(EncryptionOperationsTest, AesGcmCorruptTag) {
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
&finish_out_params, &plaintext));
EXPECT_TRUE(finish_out_params.empty());
EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
}
/*
@@ -3704,9 +3617,7 @@ TEST_P(EncryptionOperationsTest, TripleDesEcbPkcs7PaddingCorrupted) {
begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
int32_t input_consumed;
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
}
@@ -4020,9 +3931,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) {
.Authorization(TAG_NONCE, iv);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
int32_t input_consumed;
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
EXPECT_EQ(ciphertext.size(), input_consumed);
EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
}
@@ -4046,10 +3955,8 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcIncrementalNoPadding) {
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
string ciphertext;
int32_t input_consumed;
for (size_t i = 0; i < message.size(); i += increment)
EXPECT_EQ(ErrorCode::OK,
Update(message.substr(i, increment), &ciphertext, &input_consumed));
EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
EXPECT_EQ(message.size(), ciphertext.size());
@@ -4062,8 +3969,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcIncrementalNoPadding) {
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
string plaintext;
for (size_t i = 0; i < ciphertext.size(); i += increment)
EXPECT_EQ(ErrorCode::OK,
Update(ciphertext.substr(i, increment), &plaintext, &input_consumed));
EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
EXPECT_EQ(ErrorCode::OK, Finish(&plaintext));
EXPECT_EQ(ciphertext.size(), plaintext.size());
EXPECT_EQ(message, plaintext);

View File

@@ -206,41 +206,15 @@ class KeyMintBenchmarkTest {
return std::move(builder);
}
optional<string> Process(const string& message, const AuthorizationSet& /*in_params*/,
AuthorizationSet* out_params, const string& signature = "") {
static const int HIDL_BUFFER_LIMIT = 1 << 14; // 16KB
optional<string> Process(const string& message, const string& signature = "") {
ErrorCode result;
// Update
AuthorizationSet update_params;
AuthorizationSet update_out_params;
string output;
string aidl_output;
int32_t input_consumed = 0;
int32_t aidl_input_consumed = 0;
while (message.length() - input_consumed > 0) {
result = Update(update_params, message.substr(input_consumed, HIDL_BUFFER_LIMIT),
&update_out_params, &aidl_output, &aidl_input_consumed);
if (result != ErrorCode::OK) {
error_ = result;
return {};
}
output.append(aidl_output);
input_consumed += aidl_input_consumed;
aidl_output.clear();
}
// Finish
AuthorizationSet finish_params;
AuthorizationSet finish_out_params;
result = Finish(finish_params, message.substr(input_consumed), signature,
&finish_out_params, &aidl_output);
result = Finish(message, signature, &output);
if (result != ErrorCode::OK) {
error_ = result;
return {};
}
output.append(aidl_output);
out_params->push_back(finish_out_params);
return output;
}
@@ -296,66 +270,36 @@ class KeyMintBenchmarkTest {
name_.assign(info.keyMintName.begin(), info.keyMintName.end());
}
ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
const string& signature, AuthorizationSet* out_params, string* output) {
Status result;
ErrorCode Finish(const string& input, const string& signature, string* output) {
if (!op_) {
std::cerr << "Finish: Operation is nullptr" << std::endl;
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
KeyParameterArray key_params;
key_params.params = in_params.vector_data();
KeyParameterArray in_keyParams;
in_keyParams.params = in_params.vector_data();
std::optional<KeyParameterArray> out_keyParams;
std::optional<vector<uint8_t>> o_put;
vector<uint8_t> oPut;
result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
vector<uint8_t>(signature.begin(), signature.end()), {}, {},
&out_keyParams, &oPut);
Status result =
op_->finish(vector<uint8_t>(input.begin(), input.end()),
vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
{} /* timestampToken */, {} /* confirmationToken */, &oPut);
if (result.isOk()) output->append(oPut.begin(), oPut.end());
if (result.isOk()) {
if (out_keyParams) {
out_params->push_back(AuthorizationSet(out_keyParams->params));
}
output->append(oPut.begin(), oPut.end());
}
op_.reset();
return GetReturnErrorCode(result);
}
ErrorCode Update(const AuthorizationSet& in_params, const string& input,
AuthorizationSet* out_params, string* output, int32_t* input_consumed) {
ErrorCode Update(const string& input, string* output) {
Status result;
if (!op_) {
std::cerr << "Update: Operation is nullptr" << std::endl;
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
KeyParameterArray key_params;
key_params.params = in_params.vector_data();
KeyParameterArray in_keyParams;
in_keyParams.params = in_params.vector_data();
std::optional<KeyParameterArray> out_keyParams;
std::optional<ByteArray> o_put;
result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
&out_keyParams, &o_put, input_consumed);
if (result.isOk()) {
if (o_put) {
output->append(o_put->data.begin(), o_put->data.end());
}
if (out_keyParams) {
out_params->push_back(AuthorizationSet(out_keyParams->params));
}
}
std::vector<uint8_t> o_put;
result = op_->update(vector<uint8_t>(input.begin(), input.end()), {} /* authToken */,
{} /* timestampToken */, &o_put);
if (result.isOk() && output) *output = {o_put.begin(), o_put.end()};
return GetReturnErrorCode(result);
}
@@ -493,7 +437,7 @@ static void sign(benchmark::State& state, string transform, int keySize, int msg
}
state.ResumeTiming();
out_params.Clear();
if (!keymintTest->Process(message, in_params, &out_params)) {
if (!keymintTest->Process(message)) {
state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
break;
}
@@ -516,7 +460,7 @@ static void verify(benchmark::State& state, string transform, int keySize, int m
("Error beginning sign, " + std::to_string(keymintTest->getError())).c_str());
return;
}
std::optional<string> signature = keymintTest->Process(message, in_params, &out_params);
std::optional<string> signature = keymintTest->Process(message);
if (!signature) {
state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
return;
@@ -534,7 +478,7 @@ static void verify(benchmark::State& state, string transform, int keySize, int m
return;
}
state.ResumeTiming();
if (!keymintTest->Process(message, in_params, &out_params, *signature)) {
if (!keymintTest->Process(message, *signature)) {
state.SkipWithError(
("Verify error, " + std::to_string(keymintTest->getError())).c_str());
break;
@@ -612,7 +556,7 @@ static void encrypt(benchmark::State& state, string transform, int keySize, int
}
out_params.Clear();
state.ResumeTiming();
if (!keymintTest->Process(message, in_params, &out_params)) {
if (!keymintTest->Process(message)) {
state.SkipWithError(
("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
break;
@@ -636,7 +580,7 @@ static void decrypt(benchmark::State& state, string transform, int keySize, int
("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
return;
}
auto encryptedMessage = keymintTest->Process(message, in_params, &out_params);
auto encryptedMessage = keymintTest->Process(message);
if (!encryptedMessage) {
state.SkipWithError(
("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
@@ -653,7 +597,7 @@ static void decrypt(benchmark::State& state, string transform, int keySize, int
return;
}
state.ResumeTiming();
if (!keymintTest->Process(*encryptedMessage, in_params, &out_params)) {
if (!keymintTest->Process(*encryptedMessage)) {
state.SkipWithError(
("Decryption error, " + std::to_string(keymintTest->getError())).c_str());
break;