From ae3727bf45a785837c5f092b4a1e8c021754f52e Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 11 Nov 2021 09:00:14 +0000 Subject: [PATCH] KeyMint VTS: test default MGF_DIGEST behaviour KeyMint supports the specification of a separate MGF digest when performing RSA-OAEP decryption, with a default value of SHA-1. Test the expected behaviour here: - SHA-1 is used if nothing specified in key characteristics. - If something is specified in key characteristics, the operation parameter value has to be one of those values. Bug: 203688354 Test: VtsAidlKeyMintTargetTest Change-Id: Ic2dd3641be732a273724faa20cf4edf8a1752506 --- .../vts/functional/KeyMintAidlTestBase.cpp | 2 +- .../aidl/vts/functional/KeyMintTest.cpp | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 46db4f0c78..37371c0427 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -981,7 +981,7 @@ string KeyMintAidlTestBase::LocalRsaEncryptMessage(const string& message, // Retrieve relevant tags. Digest digest = Digest::NONE; - Digest mgf_digest = Digest::NONE; + Digest mgf_digest = Digest::SHA1; PaddingMode padding = PaddingMode::NONE; auto digest_tag = params.GetTagValue(TAG_DIGEST); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 7c398d3eb4..3930074b47 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -5168,6 +5168,79 @@ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) { } } +/* + * EncryptionOperationsTest.RsaOaepMGFDigestDefaultSuccess + * + * Verifies that RSA-OAEP decryption operations work when no MGF digest is + * specified, defaulting to SHA-1. + */ +TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultSuccess) { + size_t key_size = 2048; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaEncryptionKey(key_size, 65537) + .Padding(PaddingMode::RSA_OAEP) + .Digest(Digest::SHA_2_256) + .SetDefaultValidity())); + + // Do local RSA encryption using the default MGF digest of SHA-1. + string message = "Hello"; + auto params = + AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP); + string ciphertext = LocalRsaEncryptMessage(message, params); + EXPECT_EQ(key_size / 8, ciphertext.size()); + + // Do KeyMint RSA decryption also using the default MGF digest of SHA-1. + string plaintext = DecryptMessage(ciphertext, params); + EXPECT_EQ(message, plaintext) << "RSA-OAEP failed with default digest"; + + // Decrypting corrupted ciphertext should fail. + size_t offset_to_corrupt = random() % ciphertext.size(); + char corrupt_byte; + do { + corrupt_byte = static_cast(random() % 256); + } while (corrupt_byte == ciphertext[offset_to_corrupt]); + ciphertext[offset_to_corrupt] = corrupt_byte; + + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params)); + string result; + EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext, &result)); + EXPECT_EQ(0U, result.size()); +} + +/* + * EncryptionOperationsTest.RsaOaepMGFDigestDefaultFail + * + * Verifies that RSA-OAEP decryption operations fail when no MGF digest is + * specified on begin (thus defaulting to SHA-1), but the key characteristics + * has an explicit set of values for MGF_DIGEST that do not contain SHA-1. + */ +TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultFail) { + size_t key_size = 2048; + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_256) + .RsaEncryptionKey(key_size, 65537) + .Padding(PaddingMode::RSA_OAEP) + .Digest(Digest::SHA_2_256) + .SetDefaultValidity())); + + // Do local RSA encryption using the default MGF digest of SHA-1. + string message = "Hello"; + auto params = + AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP); + string ciphertext = LocalRsaEncryptMessage(message, params); + EXPECT_EQ(key_size / 8, ciphertext.size()); + + // begin() params do not include MGF_DIGEST, so a default of SHA1 is assumed. + // Key characteristics *do* include values for MGF_DIGEST, so the SHA1 value + // is checked against those values, and found absent. + auto result = Begin(KeyPurpose::DECRYPT, params); + EXPECT_TRUE(result == ErrorCode::UNSUPPORTED_MGF_DIGEST || + result == ErrorCode::INCOMPATIBLE_MGF_DIGEST); +} + /* * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest *