Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit feab5d93 authored by David Drysdale's avatar David Drysdale
Browse files

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
parent 42fe1896
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,9 @@ import android.hardware.security.secureclock.TimeStampToken;
 *      - TRUSTED_ENVRIONMENT IKeyMintDevices must support curve 25519 for Purpose::SIGN (Ed25519,
 *      - 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
 *        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
 *        (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.
 *        STRONGBOX IKeyMintDevices do not support curve 25519.
 *
 *
 * o   AES
 * o   AES
+6 −1
Original line number Original line Diff line number Diff line
@@ -559,7 +559,12 @@ ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) {
    std::vector<uint8_t> o_put;
    std::vector<uint8_t> o_put;
    result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &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);
    return GetReturnErrorCode(result);
}
}
+94 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,9 @@ namespace aidl::android::hardware::security::keymint::test {


namespace {
namespace {


// Maximum supported Ed25519 message size.
const size_t MAX_ED25519_MSG_SIZE = 16 * 1024;

// Whether to check that BOOT_PATCHLEVEL is populated.
// Whether to check that BOOT_PATCHLEVEL is populated.
bool check_boot_pl = true;
bool check_boot_pl = true;


@@ -3126,6 +3129,97 @@ TEST_P(SigningOperationsTest, EcdsaCurve25519) {
    CheckedDeleteKey();
    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
 * SigningOperationsTest.EcdsaNoDigestHugeData
 *
 *