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

Commit f86c2c3c authored by David Zeuthen's avatar David Zeuthen Committed by Automerger Merge Worker
Browse files

Merge "Add support and VTS test for RSA OAEP MGF1." am: 19086060 am: 5e5edfeb am: f51241af

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1533662

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: If420bbaabc26d7df497ae7bc1199274ca81e5527
parents 32f3c77a f51241af
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ enum ErrorCode {
  ATTESTATION_IDS_NOT_PROVISIONED = -75,
  INVALID_OPERATION = -76,
  STORAGE_KEY_UNSUPPORTED = -77,
  INCOMPATIBLE_MGF_DIGEST = -78,
  UNSUPPORTED_MGF_DIGEST = -79,
  UNIMPLEMENTED = -100,
  VERSION_MISMATCH = -101,
  UNKNOWN_ERROR = -1000,
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ enum Tag {
  EC_CURVE = 268435466,
  RSA_PUBLIC_EXPONENT = 1342177480,
  INCLUDE_UNIQUE_ID = 1879048394,
  RSA_OAEP_MGF_DIGEST = 536871115,
  BLOB_USAGE_REQUIREMENTS = 268435757,
  BOOTLOADER_ONLY = 1879048494,
  ROLLBACK_RESISTANCE = 1879048495,
+2 −0
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ enum ErrorCode {
    ATTESTATION_IDS_NOT_PROVISIONED = -75,
    INVALID_OPERATION = -76,
    STORAGE_KEY_UNSUPPORTED = -77,
    INCOMPATIBLE_MGF_DIGEST = -78,
    UNSUPPORTED_MGF_DIGEST = -79,

    UNIMPLEMENTED = -100,
    VERSION_MISMATCH = -101,
+16 −0
Original line number Diff line number Diff line
@@ -187,6 +187,22 @@ enum Tag {
     */
    INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202,

     /**
      * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with
      * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP
      * and this tag is absent then SHA1 digest is selected by default for MGF1.
      *
      * This tag is repeatable for key generation/import.  If this tag is present in the key
      * characteristics with one or more values from @4.0::Digest, then for RSA cipher
      * operations with OAEP Padding, the caller must specify a digest in the additionalParams
      * argument of begin operation. If this tag is missing or the specified digest is not in
      * the digests associated with the key then begin operation must fail with
      * ErrorCode::INCOMPATIBLE_MGF_DIGEST.
      *
      * Must be hardware-enforced.
      */
     RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203,

    /**
     * TODO(seleneh) this tag needs to be deleted from all codes.
     *
+101 −0
Original line number Diff line number Diff line
@@ -2055,6 +2055,107 @@ TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) {
    EXPECT_EQ(0U, result.size());
}

/*
 * EncryptionOperationsTest.RsaOaepWithMGFDigestSuccess
 *
 * Verifies that RSA-OAEP encryption operations work, with all SHA 256 digests and all type of MGF1
 * digests.
 */
TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) {
    auto digests = ValidDigests(false /* withNone */, true /* withMD5 */);

    size_t key_size = 2048;  // Need largish key for SHA-512 test.
    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                 .OaepMGFDigest(digests)
                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
                                                 .RsaEncryptionKey(key_size, 65537)
                                                 .Padding(PaddingMode::RSA_OAEP)
                                                 .Digest(Digest::SHA_2_256)));

    string message = "Hello";

    for (auto digest : digests) {
        auto params = AuthorizationSetBuilder()
                              .Authorization(TAG_RSA_OAEP_MGF_DIGEST, digest)
                              .Digest(Digest::SHA_2_256)
                              .Padding(PaddingMode::RSA_OAEP);
        string ciphertext1 = EncryptMessage(message, params);
        if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl;
        EXPECT_EQ(key_size / 8, ciphertext1.size());

        string ciphertext2 = EncryptMessage(message, params);
        EXPECT_EQ(key_size / 8, ciphertext2.size());

        // OAEP randomizes padding so every result should be different (with astronomically high
        // probability).
        EXPECT_NE(ciphertext1, ciphertext2);

        string plaintext1 = DecryptMessage(ciphertext1, params);
        EXPECT_EQ(message, plaintext1) << "RSA-OAEP failed with digest " << digest;
        string plaintext2 = DecryptMessage(ciphertext2, params);
        EXPECT_EQ(message, plaintext2) << "RSA-OAEP failed with digest " << digest;

        // Decrypting corrupted ciphertext should fail.
        size_t offset_to_corrupt = random() % ciphertext1.size();
        char corrupt_byte;
        do {
            corrupt_byte = static_cast<char>(random() % 256);
        } while (corrupt_byte == ciphertext1[offset_to_corrupt]);
        ciphertext1[offset_to_corrupt] = corrupt_byte;

        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
        string result;
        EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext1, &result));
        EXPECT_EQ(0U, result.size());
    }
}

/*
 * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest
 *
 * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
 * with incompatible MGF digest.
 */
TEST_P(EncryptionOperationsTest, RsaOaepWithMGFIncompatibleDigest) {
    ASSERT_EQ(ErrorCode::OK,
              GenerateKey(AuthorizationSetBuilder()
                                  .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_256)
                                  .Authorization(TAG_NO_AUTH_REQUIRED)
                                  .RsaEncryptionKey(2048, 65537)
                                  .Padding(PaddingMode::RSA_OAEP)
                                  .Digest(Digest::SHA_2_256)));
    string message = "Hello World!";

    auto params = AuthorizationSetBuilder()
                          .Padding(PaddingMode::RSA_OAEP)
                          .Digest(Digest::SHA_2_256)
                          .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_224);
    EXPECT_EQ(ErrorCode::INCOMPATIBLE_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params));
}

/*
 * EncryptionOperationsTest.RsaOaepWithMGFUnsupportedDigest
 *
 * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
 * with unsupported MGF digest.
 */
TEST_P(EncryptionOperationsTest, RsaOaepWithMGFUnsupportedDigest) {
    ASSERT_EQ(ErrorCode::OK,
              GenerateKey(AuthorizationSetBuilder()
                                  .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_256)
                                  .Authorization(TAG_NO_AUTH_REQUIRED)
                                  .RsaEncryptionKey(2048, 65537)
                                  .Padding(PaddingMode::RSA_OAEP)
                                  .Digest(Digest::SHA_2_256)));
    string message = "Hello World!";

    auto params = AuthorizationSetBuilder()
                          .Padding(PaddingMode::RSA_OAEP)
                          .Digest(Digest::SHA_2_256)
                          .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::NONE);
    EXPECT_EQ(ErrorCode::UNSUPPORTED_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params));
}

/*
 * EncryptionOperationsTest.RsaPkcs1Success
 *
Loading