KeyMint VTS: police Ed25519 msg size limit

Ed25519 signing operations require the secure world to accumulate the
entirety of the message; consequently, impose a limit on message size
for this operation.

Bug: 194358913
Test: VtsAidlKeyMintTargetTest
Change-Id: Ibfb6a54c1d546b5b4e51f42795d2bb4660add772
This commit is contained in:
David Drysdale
2022-01-06 15:46:23 +00:00
parent 42fe189633
commit feab5d932f
3 changed files with 103 additions and 2 deletions

View File

@@ -96,7 +96,9 @@ import android.hardware.security.secureclock.TimeStampToken;
* - TRUSTED_ENVRIONMENT IKeyMintDevices must support curve 25519 for Purpose::SIGN (Ed25519,
* as specified in RFC 8032), Purpose::ATTEST_KEY (Ed25519) or for KeyPurpose::AGREE_KEY
* (X25519, as specified in RFC 7748). However, a key must have exactly one of these
* purpose values; the same key cannot be used for multiple purposes.
* purpose values; the same key cannot be used for multiple purposes. Signing operations
* (Purpose::SIGN) have a message size limit of 16 KiB; operations on messages longer than
* this limit must fail with ErrorCode::INVALID_INPUT_LENGTH.
* STRONGBOX IKeyMintDevices do not support curve 25519.
*
* o AES

View File

@@ -559,7 +559,12 @@ ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) {
std::vector<uint8_t> o_put;
result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
if (result.isOk()) output->append(o_put.begin(), o_put.end());
if (result.isOk()) {
output->append(o_put.begin(), o_put.end());
} else {
// Failure always terminates the operation.
op_ = {};
}
return GetReturnErrorCode(result);
}

View File

@@ -70,6 +70,9 @@ namespace aidl::android::hardware::security::keymint::test {
namespace {
// Maximum supported Ed25519 message size.
const size_t MAX_ED25519_MSG_SIZE = 16 * 1024;
// Whether to check that BOOT_PATCHLEVEL is populated.
bool check_boot_pl = true;
@@ -3126,6 +3129,97 @@ TEST_P(SigningOperationsTest, EcdsaCurve25519) {
CheckedDeleteKey();
}
/*
* SigningOperationsTest.EcdsaCurve25519MaxSize
*
* Verifies that EDDSA operations with curve25519 under the maximum message size succeed.
*/
TEST_P(SigningOperationsTest, EcdsaCurve25519MaxSize) {
if (!Curve25519Supported()) {
GTEST_SKIP() << "Test not applicable to device that is not expected to support curve 25519";
}
EcCurve curve = EcCurve::CURVE_25519;
ErrorCode error = GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(curve)
.Digest(Digest::NONE)
.SetDefaultValidity());
ASSERT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with curve " << curve;
auto params = AuthorizationSetBuilder().Digest(Digest::NONE);
for (size_t msg_size : {MAX_ED25519_MSG_SIZE - 1, MAX_ED25519_MSG_SIZE}) {
SCOPED_TRACE(testing::Message() << "-msg-size=" << msg_size);
string message(msg_size, 'a');
// Attempt to sign via Begin+Finish.
AuthorizationSet out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_, params, &out_params));
EXPECT_TRUE(out_params.empty());
string signature;
auto result = Finish(message, &signature);
EXPECT_EQ(result, ErrorCode::OK);
LocalVerifyMessage(message, signature, params);
// Attempt to sign via Begin+Update+Finish
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_, params, &out_params));
EXPECT_TRUE(out_params.empty());
string output;
result = Update(message, &output);
EXPECT_EQ(result, ErrorCode::OK);
EXPECT_EQ(output.size(), 0);
string signature2;
EXPECT_EQ(ErrorCode::OK, Finish({}, &signature2));
LocalVerifyMessage(message, signature2, params);
}
CheckedDeleteKey();
}
/*
* SigningOperationsTest.EcdsaCurve25519MaxSizeFail
*
* Verifies that EDDSA operations with curve25519 fail when message size is too large.
*/
TEST_P(SigningOperationsTest, EcdsaCurve25519MaxSizeFail) {
if (!Curve25519Supported()) {
GTEST_SKIP() << "Test not applicable to device that is not expected to support curve 25519";
}
EcCurve curve = EcCurve::CURVE_25519;
ErrorCode error = GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(curve)
.Digest(Digest::NONE)
.SetDefaultValidity());
ASSERT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with curve " << curve;
auto params = AuthorizationSetBuilder().Digest(Digest::NONE);
for (size_t msg_size : {MAX_ED25519_MSG_SIZE + 1, MAX_ED25519_MSG_SIZE * 2}) {
SCOPED_TRACE(testing::Message() << "-msg-size=" << msg_size);
string message(msg_size, 'a');
// Attempt to sign via Begin+Finish.
AuthorizationSet out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_, params, &out_params));
EXPECT_TRUE(out_params.empty());
string signature;
auto result = Finish(message, &signature);
EXPECT_EQ(result, ErrorCode::INVALID_INPUT_LENGTH);
// Attempt to sign via Begin+Update (but never get to Finish)
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, key_blob_, params, &out_params));
EXPECT_TRUE(out_params.empty());
string output;
result = Update(message, &output);
EXPECT_EQ(result, ErrorCode::INVALID_INPUT_LENGTH);
}
CheckedDeleteKey();
}
/*
* SigningOperationsTest.EcdsaNoDigestHugeData
*