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

Commit 531a72d7 authored by Selene Huang's avatar Selene Huang
Browse files

Implement device unique attestation vts tests for keymint.

Test: atest VtsAidlKeyMintTargetTest
Change-Id: If271c915d33cece035ab67b9149ae4ba762648b4
parent be01266c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ cc_test {
    ],
    srcs: [
        "AttestKeyTest.cpp",
        "DeviceUniqueAttestationTest.cpp",
        "KeyMintTest.cpp",
    ],
    shared_libs: [
+193 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 */

#define LOG_TAG "keymint_1_attest_key_test"

#include <cutils/log.h>
#include <cutils/properties.h>
#include <keymint_support/key_param_output.h>
#include <keymint_support/openssl_utils.h>

#include "KeyMintAidlTestBase.h"

namespace aidl::android::hardware::security::keymint::test {

class DeviceUniqueAttestationTest : public KeyMintAidlTestBase {
  protected:
    void CheckUniqueAttestationResults(const vector<uint8_t>& key_blob,
                                       const vector<KeyCharacteristics>& key_characteristics,
                                       const AuthorizationSet& hw_enforced, int key_size) {
        ASSERT_GT(cert_chain_.size(), 0);

        if (KeyMintAidlTestBase::dump_Attestations) {
            std::cout << bin2hex(cert_chain_[0].encodedCertificate) << std::endl;
        }

        ASSERT_GT(key_blob.size(), 0U);

        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);

        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) << "Key size missing";

        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
        ASSERT_GT(cert_chain_.size(), 0);

        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
        EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
                                              SecLevel(), cert_chain_[0].encodedCertificate));
    }
};

/*
 * DeviceUniqueAttestationTest.RsaNonStrongBoxUnimplemented
 *
 * Verifies that non strongbox implementations do not implement Rsa device unique
 * attestation.
 */
TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
    if (SecLevel() == SecurityLevel::STRONGBOX) return;

    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> key_characteristics;

    // Check RSA implementation
    auto result = GenerateKey(AuthorizationSetBuilder()
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .RsaSigningKey(2048, 65537)
                                      .Digest(Digest::SHA_2_256)
                                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .AttestationChallenge("challenge")
                                      .AttestationApplicationId("foo")
                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                              &key_blob, &key_characteristics);

    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_TAG);
}

/*
 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
 *
 * Verifies that non strongbox implementations do not implement Ecdsa device unique
 * attestation.
 */
TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
    if (SecLevel() == SecurityLevel::STRONGBOX) return;

    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> key_characteristics;

    // Check Ecdsa implementation
    auto result = GenerateKey(AuthorizationSetBuilder()
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .EcdsaSigningKey(EcCurve::P_256)
                                      .Digest(Digest::SHA_2_256)
                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
                                      .AttestationChallenge("challenge")
                                      .AttestationApplicationId("foo")
                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                              &key_blob, &key_characteristics);

    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_TAG);
}

/*
 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
 *
 * Verifies that strongbox implementations of Rsa implements device unique
 * attestation correctly, if implemented.
 */
TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
    if (SecLevel() != SecurityLevel::STRONGBOX) return;

    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> key_characteristics;
    int key_size = 2048;

    auto result = GenerateKey(AuthorizationSetBuilder()
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .RsaSigningKey(key_size, 65537)
                                      .Digest(Digest::SHA_2_256)
                                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .AttestationChallenge("challenge")
                                      .AttestationApplicationId("foo")
                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                              &key_blob, &key_characteristics);

    // It is optional for Strong box to support DeviceUniqueAttestation.
    if (result == ErrorCode::CANNOT_ATTEST_IDS) return;

    ASSERT_EQ(ErrorCode::OK, result);

    AuthorizationSet hw_enforced = AuthorizationSetBuilder()
                                           .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
                                           .Authorization(TAG_NO_AUTH_REQUIRED)
                                           .RsaSigningKey(2048, 65537)
                                           .Digest(Digest::SHA_2_256)
                                           .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
                                           .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
                                           .Authorization(TAG_OS_VERSION, os_version())
                                           .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());

    CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size);
}

/*
 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
 *
 * Verifies that strongbox implementations of Rsa implements device unique
 * attestation correctly, if implemented.
 */
TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
    if (SecLevel() != SecurityLevel::STRONGBOX) return;

    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> key_characteristics;
    int key_size = 256;

    auto result = GenerateKey(AuthorizationSetBuilder()
                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                      .EcdsaSigningKey(256)
                                      .Digest(Digest::SHA_2_256)
                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
                                      .AttestationChallenge("challenge")
                                      .AttestationApplicationId("foo")
                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                              &key_blob, &key_characteristics);

    // It is optional for Strong box to support DeviceUniqueAttestation.
    if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
    ASSERT_EQ(ErrorCode::OK, result);

    AuthorizationSet hw_enforced = AuthorizationSetBuilder()
                                           .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
                                           .Authorization(TAG_NO_AUTH_REQUIRED)
                                           .EcdsaSigningKey(EcCurve::P_256)
                                           .Digest(Digest::SHA_2_256)
                                           .Authorization(TAG_EC_CURVE, EcCurve::P_256)
                                           .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
                                           .Authorization(TAG_OS_VERSION, os_version())
                                           .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());

    CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size);
}

INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);

}  // namespace aidl::android::hardware::security::keymint::test