diff options
author | Selene Huang <seleneh@google.com> | 2021-04-21 15:10:36 -0700 |
---|---|---|
committer | Selene Huang <seleneh@google.com> | 2021-04-24 22:43:13 -0700 |
commit | 8f9494c4f6becc69eea45cbb6b0a09d6ab6a0b5c (patch) | |
tree | 9f80d711ea5f256934c66d7005cbbed351bcb0d3 /security/keymint/aidl/vts/functional/AttestKeyTest.cpp | |
parent | 24c422c48baa79c42148cd47a9e34139ec2eebea (diff) |
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
Diffstat (limited to 'security/keymint/aidl/vts/functional/AttestKeyTest.cpp')
-rw-r--r-- | security/keymint/aidl/vts/functional/AttestKeyTest.cpp | 372 |
1 files changed, 365 insertions, 7 deletions
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index daa3e1871f..4e951d6f51 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -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()) { /* |