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

Commit dd0b8bf6 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9657362 from bc4e5137 to udc-release

Change-Id: Ia02f213f49785b7e3aaf9db8bd29f77acd036f4b
parents fe47f3dc bc4e5137
Loading
Loading
Loading
Loading
+0 −20
Original line number Diff line number Diff line
@@ -1698,26 +1698,6 @@ TEST_P(InputStreamTest, GetInputFramesLost) {
    ASSERT_EQ(0U, framesLost);
}

TEST_P(InputStreamTest, getCapturePosition) {
    doc::test(
        "The capture position of a non prepared stream should not be "
        "retrievable or 0");
    uint64_t frames;
    uint64_t time;
    ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
    // Although 'getCapturePosition' is mandatory in V7, legacy implementations
    // may return -ENOSYS (which is translated to NOT_SUPPORTED) in cases when
    // the capture position can't be retrieved, e.g. when the stream isn't
    // running. Because of this, we don't fail when getting NOT_SUPPORTED
    // in this test. Behavior of 'getCapturePosition' for running streams is
    // tested in 'PcmOnlyConfigInputStreamTest' for V7.
    ASSERT_RESULT(okOrInvalidStateOrNotSupported, res);
    if (res == Result::OK) {
        ASSERT_EQ(0U, frames);
        ASSERT_LE(0U, time);
    }
}

//////////////////////////////////////////////////////////////////////////////
///////////////////////////////// StreamOut //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+21 −21
Original line number Diff line number Diff line
@@ -108,27 +108,6 @@ bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel,
    return true;
}

// Extract attestation record from cert. Returned object is still part of cert; don't free it
// separately.
ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
    EXPECT_TRUE(!!oid.get());
    if (!oid.get()) return nullptr;

    int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
    EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
    if (location == -1) return nullptr;

    X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
    EXPECT_TRUE(!!attest_rec_ext)
            << "Found attestation extension but couldn't retrieve it?  Probably a BoringSSL bug.";
    if (!attest_rec_ext) return nullptr;

    ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
    EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
    return attest_rec;
}

void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
    // Version numbers in attestation extensions should be a multiple of 100.
    EXPECT_EQ(attestation_version % 100, 0);
@@ -1901,6 +1880,27 @@ X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
    return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
}

// Extract attestation record from cert. Returned object is still part of cert; don't free it
// separately.
ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
    EXPECT_TRUE(!!oid.get());
    if (!oid.get()) return nullptr;

    int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
    EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
    if (location == -1) return nullptr;

    X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
    EXPECT_TRUE(!!attest_rec_ext)
            << "Found attestation extension but couldn't retrieve it?  Probably a BoringSSL bug.";
    if (!attest_rec_ext) return nullptr;

    ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
    EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
    return attest_rec;
}

vector<uint8_t> make_name_from_str(const string& name) {
    X509_NAME_Ptr x509_name(X509_NAME_new());
    EXPECT_TRUE(x509_name.get() != nullptr);
+1 −0
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ bool verify_attestation_record(int aidl_version, //

string bin2hex(const vector<uint8_t>& data);
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
ASN1_OCTET_STRING* get_attestation_record(X509* certificate);
vector<uint8_t> make_name_from_str(const string& name);
void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
                        vector<uint8_t>* payload_value);
+123 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <gmock/gmock.h>
#include <keymaster/cppcose/cppcose.h>
@@ -797,6 +798,128 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequest_testKeyInProdCert) {
              BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
}

void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
                         vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
                         bool* device_locked, vector<uint8_t>* verified_boot_hash) {
    X509_Ptr cert(parse_cert_blob(attestation_cert));
    ASSERT_TRUE(cert.get());

    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
    ASSERT_TRUE(attest_rec);

    auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
                                     verified_boot_state, device_locked, verified_boot_hash);
    ASSERT_EQ(error, ErrorCode::OK);
}

/**
 * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
 */
TEST_P(CertificateRequestV2Test, DeviceInfo) {
    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
    std::shared_ptr<IKeyMintDevice> keyMint;
    if (!matching_keymint_device(GetParam(), &keyMint)) {
        // No matching IKeyMintDevice.
        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
        return;
    }
    KeyMintHardwareInfo info;
    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());

    // Get IDs attested by KeyMint.
    MacedPublicKey macedPubKey;
    bytevec privateKeyBlob;
    auto irpcStatus =
            provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
    ASSERT_TRUE(irpcStatus.isOk());

    AttestationKey attestKey;
    attestKey.keyBlob = std::move(privateKeyBlob);
    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");

    // Generate an ECDSA key that is attested by the generated P256 keypair.
    AuthorizationSet keyDesc = AuthorizationSetBuilder()
                                       .Authorization(TAG_NO_AUTH_REQUIRED)
                                       .EcdsaSigningKey(EcCurve::P_256)
                                       .AttestationChallenge("foo")
                                       .AttestationApplicationId("bar")
                                       .Digest(Digest::NONE)
                                       .SetDefaultValidity();
    KeyCreationResult creationResult;
    auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
    ASSERT_TRUE(kmStatus.isOk());

    vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
    vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
    // We didn't provision the attestation key.
    ASSERT_EQ(key_cert_chain.size(), 1);

    // Parse attested patch levels.
    auto auths = HwEnforcedAuthorizations(key_characteristics);

    auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
    auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
    auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);

    ASSERT_TRUE(attestedSystemPatchLevel.has_value());
    ASSERT_TRUE(attestedVendorPatchLevel.has_value());
    ASSERT_TRUE(attestedBootPatchLevel.has_value());

    // Parse attested AVB values.
    vector<uint8_t> key;
    VerifiedBoot attestedVbState;
    bool attestedBootloaderState;
    vector<uint8_t> attestedVbmetaDigest;
    parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
                        &attestedBootloaderState, &attestedVbmetaDigest);

    // Get IDs from DeviceInfo.
    bytevec csr;
    irpcStatus =
            provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
    ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();

    auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
    ASSERT_TRUE(result) << result.message();

    std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
    ASSERT_TRUE(csrPayload);

    auto deviceInfo = csrPayload->get(2)->asMap();
    ASSERT_TRUE(deviceInfo);

    auto vbState = deviceInfo->get("vb_state")->asTstr();
    auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
    auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
    auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
    auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
    auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
    auto securityLevel = deviceInfo->get("security_level")->asTstr();

    ASSERT_TRUE(vbState);
    ASSERT_TRUE(bootloaderState);
    ASSERT_TRUE(vbmetaDigest);
    ASSERT_TRUE(systemPatchLevel);
    ASSERT_TRUE(vendorPatchLevel);
    ASSERT_TRUE(bootPatchLevel);
    ASSERT_TRUE(securityLevel);

    auto kmDeviceName = device_suffix(GetParam());

    // Compare DeviceInfo against IDs attested by KeyMint.
    ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
                (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
    ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
                (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
                (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
    ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
                (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
    ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
    ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
    ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
    ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
}

INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);

using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
+0 −2
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ package android.hardware.wifi;
 * Byte array representing a Mac Address. Use when we need to
 * pass an array of Mac Addresses to a method, as variable-sized
 * 2D arrays are not supported in AIDL.
 *
 * TODO (b/210705533): Replace this type with a 2D byte array.
 */
@VintfStability
parcelable MacAddress {
Loading