mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-02 06:22:53 +00:00
Added various vts tests for attestKey.
- Added tests for signing attest key with factory chain.
- Added test for signing encryption keys.
- Added tests for chaining many RSA attest keys on the same chain.
- Added tests for chaining many Ec attest keys on the same chain.
- Added tests for alternate chaining of rsa-ec-rsa-ec-rsa attesti
keys on the same chain.
Test: atest VtsAidlKeyMintTargetTest
Change-Id: I9c67e2b928d6bba6cc4074a4b65f639f33c9ec26
This commit is contained in:
@@ -35,6 +35,12 @@ bool IsSelfSigned(const vector<Certificate>& chain) {
|
||||
|
||||
using AttestKeyTest = KeyMintAidlTestBase;
|
||||
|
||||
/*
|
||||
* AttestKeyTest.AllRsaSizes
|
||||
*
|
||||
* This test creates self signed RSA attestation keys of various sizes, and verify they can be
|
||||
* used to sign other RSA and EC keys.
|
||||
*/
|
||||
TEST_P(AttestKeyTest, AllRsaSizes) {
|
||||
for (auto size : ValidKeySizes(Algorithm::RSA)) {
|
||||
/*
|
||||
@@ -54,7 +60,7 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
|
||||
EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size;
|
||||
|
||||
/*
|
||||
* Use attestation key to sign RSA key
|
||||
* Use attestation key to sign RSA signing key
|
||||
*/
|
||||
attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
|
||||
vector<uint8_t> attested_key_blob;
|
||||
@@ -81,14 +87,47 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
if (attest_key_cert_chain.size() > 0) {
|
||||
attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
|
||||
}
|
||||
attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
EXPECT_EQ(attested_key_cert_chain.size(), 2);
|
||||
|
||||
/*
|
||||
* Use attestation key to sign RSA decryption key
|
||||
*/
|
||||
attested_key_characteristics.resize(0);
|
||||
attested_key_cert_chain.resize(0);
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaEncryptionKey(2048, 65537)
|
||||
.Digest(Digest::NONE)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.AttestationChallenge("foo2")
|
||||
.AttestationApplicationId("bar2")
|
||||
.SetDefaultValidity(),
|
||||
attest_key, &attested_key_blob, &attested_key_characteristics,
|
||||
&attested_key_cert_chain));
|
||||
|
||||
CheckedDeleteKey(&attested_key_blob);
|
||||
|
||||
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
|
||||
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record("foo2", "bar2", sw_enforced, hw_enforced, SecLevel(),
|
||||
attested_key_cert_chain[0].encodedCertificate));
|
||||
|
||||
// Attestation by itself is not valid (last entry is not self-signed).
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
EXPECT_EQ(attested_key_cert_chain.size(), 2);
|
||||
|
||||
/*
|
||||
* Use attestation key to sign EC key
|
||||
*/
|
||||
attested_key_characteristics.resize(0);
|
||||
attested_key_cert_chain.resize(0);
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.EcdsaSigningKey(EcCurve::P_256)
|
||||
@@ -111,9 +150,7 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
if (attest_key_cert_chain.size() > 0) {
|
||||
attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
|
||||
}
|
||||
attested_key_cert_chain.push_back(attest_key_cert_chain[0]);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
|
||||
// Bail early if anything failed.
|
||||
@@ -121,6 +158,327 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AttestKeyTest.RsaAttestedAttestKeys
|
||||
*
|
||||
* This test creates an RSA attestation key signed by factory keys, and varifies it can be
|
||||
* used to sign other RSA and EC keys.
|
||||
*/
|
||||
TEST_P(AttestKeyTest, RsaAttestedAttestKeys) {
|
||||
auto challenge = "hello";
|
||||
auto app_id = "foo";
|
||||
|
||||
auto subject = "cert subj 2";
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 66;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
/*
|
||||
* Create attestation key.
|
||||
*/
|
||||
AttestationKey attest_key;
|
||||
vector<KeyCharacteristics> attest_key_characteristics;
|
||||
vector<Certificate> attest_key_cert_chain;
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(2048, 65537)
|
||||
.AttestKey()
|
||||
.AttestationChallenge(challenge)
|
||||
.AttestationApplicationId(app_id)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
{} /* attestation signing key */, &attest_key.keyBlob,
|
||||
&attest_key_characteristics, &attest_key_cert_chain));
|
||||
|
||||
EXPECT_GT(attest_key_cert_chain.size(), 1);
|
||||
verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false);
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(attest_key_cert_chain));
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attest_key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attest_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
|
||||
sw_enforced, hw_enforced, SecLevel(),
|
||||
attest_key_cert_chain[0].encodedCertificate));
|
||||
|
||||
/*
|
||||
* Use attestation key to sign RSA key
|
||||
*/
|
||||
attest_key.issuerSubjectName = subject_der;
|
||||
vector<uint8_t> attested_key_blob;
|
||||
vector<KeyCharacteristics> attested_key_characteristics;
|
||||
vector<Certificate> attested_key_cert_chain;
|
||||
|
||||
auto subject2 = "cert subject";
|
||||
vector<uint8_t> subject_der2(make_name_from_str(subject2));
|
||||
|
||||
uint64_t serial_int2 = 987;
|
||||
vector<uint8_t> serial_blob2(build_serial_blob(serial_int2));
|
||||
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(2048, 65537)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.AttestationChallenge("foo")
|
||||
.AttestationApplicationId("bar")
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob2)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der2)
|
||||
.SetDefaultValidity(),
|
||||
attest_key, &attested_key_blob, &attested_key_characteristics,
|
||||
&attested_key_cert_chain));
|
||||
|
||||
CheckedDeleteKey(&attested_key_blob);
|
||||
CheckedDeleteKey(&attest_key.keyBlob);
|
||||
|
||||
AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
|
||||
AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced2, hw_enforced2, SecLevel(),
|
||||
attested_key_cert_chain[0].encodedCertificate));
|
||||
|
||||
// Attestation by itself is not valid (last entry is not self-signed).
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
attested_key_cert_chain.insert(attested_key_cert_chain.end(), attest_key_cert_chain.begin(),
|
||||
attest_key_cert_chain.end());
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(attested_key_cert_chain));
|
||||
EXPECT_GT(attested_key_cert_chain.size(), 2);
|
||||
verify_subject_and_serial(attested_key_cert_chain[0], serial_int2, subject2, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* AttestKeyTest.RsaAttestKeyChaining
|
||||
*
|
||||
* This test creates a chain of multiple RSA attest keys, each used to sign the next attest key,
|
||||
* with the last attest key signed by the factory chain.
|
||||
*/
|
||||
TEST_P(AttestKeyTest, RsaAttestKeyChaining) {
|
||||
const int chain_size = 6;
|
||||
vector<vector<uint8_t>> key_blob_list(chain_size);
|
||||
vector<vector<Certificate>> cert_chain_list(chain_size);
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
string sub = "attest key chaining ";
|
||||
char index = '1' + i;
|
||||
string subject = sub + index;
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 7000 + i;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
vector<KeyCharacteristics> attested_key_characteristics;
|
||||
AttestationKey attest_key;
|
||||
optional<AttestationKey> attest_key_opt;
|
||||
|
||||
if (i > 0) {
|
||||
attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
|
||||
attest_key.keyBlob = key_blob_list[i - 1];
|
||||
attest_key_opt = attest_key;
|
||||
}
|
||||
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(2048, 65537)
|
||||
.AttestKey()
|
||||
.AttestationChallenge("foo")
|
||||
.AttestationApplicationId("bar")
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.SetDefaultValidity(),
|
||||
attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
|
||||
&cert_chain_list[i]));
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
|
||||
cert_chain_list[i][0].encodedCertificate));
|
||||
|
||||
if (i > 0) {
|
||||
/*
|
||||
* The first key is attestated with factory chain, but all the rest of the keys are
|
||||
* not supposed to be returned in attestation certificate chains.
|
||||
*/
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
cert_chain_list[i].insert(cert_chain_list[i].end(), //
|
||||
cert_chain_list[i - 1].begin(), //
|
||||
cert_chain_list[i - 1].end());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
EXPECT_GT(cert_chain_list[i].size(), i + 1);
|
||||
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
CheckedDeleteKey(&key_blob_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AttestKeyTest.EcAttestKeyChaining
|
||||
*
|
||||
* This test creates a chain of multiple Ec attest keys, each used to sign the next attest key,
|
||||
* with the last attest key signed by the factory chain.
|
||||
*/
|
||||
TEST_P(AttestKeyTest, EcAttestKeyChaining) {
|
||||
const int chain_size = 6;
|
||||
vector<vector<uint8_t>> key_blob_list(chain_size);
|
||||
vector<vector<Certificate>> cert_chain_list(chain_size);
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
string sub = "Ec attest key chaining ";
|
||||
char index = '1' + i;
|
||||
string subject = sub + index;
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 800000 + i;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
vector<KeyCharacteristics> attested_key_characteristics;
|
||||
AttestationKey attest_key;
|
||||
optional<AttestationKey> attest_key_opt;
|
||||
|
||||
if (i > 0) {
|
||||
attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
|
||||
attest_key.keyBlob = key_blob_list[i - 1];
|
||||
attest_key_opt = attest_key;
|
||||
}
|
||||
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.EcdsaSigningKey(224)
|
||||
.AttestKey()
|
||||
.AttestationChallenge("foo")
|
||||
.AttestationApplicationId("bar")
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
|
||||
&cert_chain_list[i]));
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
|
||||
cert_chain_list[i][0].encodedCertificate));
|
||||
|
||||
if (i > 0) {
|
||||
/*
|
||||
* The first key is attestated with factory chain, but all the rest of the keys are
|
||||
* not supposed to be returned in attestation certificate chains.
|
||||
*/
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
cert_chain_list[i].insert(cert_chain_list[i].end(), //
|
||||
cert_chain_list[i - 1].begin(), //
|
||||
cert_chain_list[i - 1].end());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
EXPECT_GT(cert_chain_list[i].size(), i + 1);
|
||||
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
CheckedDeleteKey(&key_blob_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AttestKeyTest.AlternateAttestKeyChaining
|
||||
*
|
||||
* This test creates a chain of multiple attest keys, in the order Ec - RSA - Ec - RSA ....
|
||||
* Each attest key is used to sign the next attest key, with the last attest key signed by
|
||||
* the factory chain. This is to verify different algorithms of attest keys can
|
||||
* cross sign each other and be chained together.
|
||||
*/
|
||||
TEST_P(AttestKeyTest, AlternateAttestKeyChaining) {
|
||||
const int chain_size = 6;
|
||||
vector<vector<uint8_t>> key_blob_list(chain_size);
|
||||
vector<vector<Certificate>> cert_chain_list(chain_size);
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
string sub = "Alt attest key chaining ";
|
||||
char index = '1' + i;
|
||||
string subject = sub + index;
|
||||
vector<uint8_t> subject_der(make_name_from_str(subject));
|
||||
|
||||
uint64_t serial_int = 90000000 + i;
|
||||
vector<uint8_t> serial_blob(build_serial_blob(serial_int));
|
||||
|
||||
vector<KeyCharacteristics> attested_key_characteristics;
|
||||
AttestationKey attest_key;
|
||||
optional<AttestationKey> attest_key_opt;
|
||||
|
||||
if (i > 0) {
|
||||
attest_key.issuerSubjectName = make_name_from_str(sub + (char)(index - 1));
|
||||
attest_key.keyBlob = key_blob_list[i - 1];
|
||||
attest_key_opt = attest_key;
|
||||
}
|
||||
|
||||
if ((i & 0x1) == 1) {
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.EcdsaSigningKey(224)
|
||||
.AttestKey()
|
||||
.AttestationChallenge("foo")
|
||||
.AttestationApplicationId("bar")
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
|
||||
&cert_chain_list[i]));
|
||||
} else {
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
GenerateKey(AuthorizationSetBuilder()
|
||||
.RsaSigningKey(2048, 65537)
|
||||
.AttestKey()
|
||||
.AttestationChallenge("foo")
|
||||
.AttestationApplicationId("bar")
|
||||
.Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
|
||||
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.SetDefaultValidity(),
|
||||
attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
|
||||
&cert_chain_list[i]));
|
||||
}
|
||||
|
||||
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
|
||||
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
|
||||
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
|
||||
cert_chain_list[i][0].encodedCertificate));
|
||||
|
||||
if (i > 0) {
|
||||
/*
|
||||
* The first key is attestated with factory chain, but all the rest of the keys are
|
||||
* not supposed to be returned in attestation certificate chains.
|
||||
*/
|
||||
EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
|
||||
// Appending the attest_key chain to the attested_key_chain should yield a valid chain.
|
||||
cert_chain_list[i].insert(cert_chain_list[i].end(), //
|
||||
cert_chain_list[i - 1].begin(), //
|
||||
cert_chain_list[i - 1].end());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_list[i]));
|
||||
EXPECT_GT(cert_chain_list[i].size(), i + 1);
|
||||
verify_subject_and_serial(cert_chain_list[i][0], serial_int, subject, false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < chain_size; i++) {
|
||||
CheckedDeleteKey(&key_blob_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AttestKeyTest, AllEcCurves) {
|
||||
for (auto curve : ValidCurves()) {
|
||||
/*
|
||||
|
||||
@@ -1142,7 +1142,10 @@ AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain) {
|
||||
string cert_issuer = x509NameToStr(X509_get_issuer_name(key_cert.get()));
|
||||
string signer_subj = x509NameToStr(X509_get_subject_name(signing_cert.get()));
|
||||
if (cert_issuer != signer_subj) {
|
||||
return AssertionFailure() << "Cert " << i << " has wrong issuer.\n" << cert_data.str();
|
||||
return AssertionFailure() << "Cert " << i << " has wrong issuer.\n"
|
||||
<< " Signer subject is " << signer_subj
|
||||
<< " Issuer subject is " << cert_issuer << endl
|
||||
<< cert_data.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user