diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 44b8274540..5359b3b667 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -62,6 +62,9 @@ namespace test { namespace { +// Invalid value for a patchlevel (which is of form YYYYMMDD). +const uint32_t kInvalidPatchlevel = 99998877; + // Overhead for PKCS#1 v1.5 signature padding of undigested messages. Digested messages have // additional overhead, for the digest algorithmIdentifier required by PKCS#1. const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11; @@ -126,10 +129,9 @@ char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', // Attestations don't contain everything in key authorization lists, so we need to filter the key // lists to produce the lists that we expect to match the attestations. auto kTagsToFilter = { - Tag::CREATION_DATETIME, - Tag::EC_CURVE, - Tag::HARDWARE_TYPE, - Tag::INCLUDE_UNIQUE_ID, + Tag::CREATION_DATETIME, + Tag::HARDWARE_TYPE, + Tag::INCLUDE_UNIQUE_ID, }; AuthorizationSet filtered_tags(const AuthorizationSet& set) { @@ -163,6 +165,28 @@ string x509NameToStr(X509_NAME* name) { bool KeyMintAidlTestBase::arm_deleteAllKeys = false; bool KeyMintAidlTestBase::dump_Attestations = false; +uint32_t KeyMintAidlTestBase::boot_patch_level( + const vector& key_characteristics) { + // The boot patchlevel is not available as a property, but should be present + // in the key characteristics of any created key. + AuthorizationSet allAuths; + for (auto& entry : key_characteristics) { + allAuths.push_back(AuthorizationSet(entry.authorizations)); + } + auto patchlevel = allAuths.GetTagValue(TAG_BOOT_PATCHLEVEL); + if (patchlevel.has_value()) { + return patchlevel.value(); + } else { + // No boot patchlevel is available. Return a value that won't match anything + // and so will trigger test failures. + return kInvalidPatchlevel; + } +} + +uint32_t KeyMintAidlTestBase::boot_patch_level() { + return boot_patch_level(key_characteristics_); +} + ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) { if (result.isOk()) return ErrorCode::OK; @@ -998,16 +1022,7 @@ vector KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) { } break; case Algorithm::EC: - switch (SecLevel()) { - case SecurityLevel::SOFTWARE: - case SecurityLevel::TRUSTED_ENVIRONMENT: - return {224, 256, 384, 521}; - case SecurityLevel::STRONGBOX: - return {256}; - default: - ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel()); - break; - } + ADD_FAILURE() << "EC keys must be specified by curve not size"; break; case Algorithm::AES: return {128, 256}; @@ -1123,9 +1138,11 @@ vector KeyMintAidlTestBase::ValidCurves() { } vector KeyMintAidlTestBase::InvalidCurves() { - if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {}; - CHECK(SecLevel() == SecurityLevel::STRONGBOX); - return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521}; + if (SecLevel() == SecurityLevel::STRONGBOX) { + return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521}; + } else { + return {}; + } } vector KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) { @@ -1293,9 +1310,9 @@ bool verify_attestation_record(const string& challenge, // AuthorizationSet att_sw_enforced; AuthorizationSet att_hw_enforced; uint32_t att_attestation_version; - uint32_t att_keymaster_version; + uint32_t att_keymint_version; SecurityLevel att_attestation_security_level; - SecurityLevel att_keymaster_security_level; + SecurityLevel att_keymint_security_level; vector att_challenge; vector att_unique_id; vector att_app_id; @@ -1304,8 +1321,8 @@ bool verify_attestation_record(const string& challenge, // attest_rec->length, // &att_attestation_version, // &att_attestation_security_level, // - &att_keymaster_version, // - &att_keymaster_security_level, // + &att_keymint_version, // + &att_keymint_security_level, // &att_challenge, // &att_sw_enforced, // &att_hw_enforced, // @@ -1324,14 +1341,14 @@ bool verify_attestation_record(const string& challenge, // expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId); } - EXPECT_EQ(att_keymaster_version, 100U); - EXPECT_EQ(security_level, att_keymaster_security_level); + EXPECT_EQ(att_keymint_version, 100U); + EXPECT_EQ(security_level, att_keymint_security_level); EXPECT_EQ(security_level, att_attestation_security_level); char property_value[PROPERTY_VALUE_MAX] = {}; // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed - // keymaster implementation will report YYYYMM dates instead of YYYYMMDD + // keymint implementation will report YYYYMM dates instead of YYYYMMDD // for the BOOT_PATCH_LEVEL. if (avb_verification_enabled()) { for (int i = 0; i < att_hw_enforced.size(); i++) { @@ -1370,13 +1387,6 @@ bool verify_attestation_record(const string& challenge, // EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED)); } - // Alternatively this checks the opposite - a false boolean tag (one that isn't provided in - // the authorization list during key generation) isn't being attested to in the certificate. - EXPECT_FALSE(expected_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(att_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - if (att_hw_enforced.Contains(TAG_ALGORITHM, Algorithm::EC)) { // For ECDSA keys, either an EC_CURVE or a KEY_SIZE can be specified, but one must be. EXPECT_TRUE(att_hw_enforced.Contains(TAG_EC_CURVE) || @@ -1442,9 +1452,7 @@ bool verify_attestation_record(const string& challenge, // att_sw_enforced.Sort(); expected_sw_enforced.Sort(); - auto a = filtered_tags(expected_sw_enforced); - auto b = filtered_tags(att_sw_enforced); - EXPECT_EQ(a, b); + EXPECT_EQ(filtered_tags(expected_sw_enforced), filtered_tags(att_sw_enforced)); att_hw_enforced.Sort(); expected_hw_enforced.Sort(); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 82f192aa49..d592d3686b 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -76,6 +76,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { uint32_t os_version() { return os_version_; } uint32_t os_patch_level() { return os_patch_level_; } uint32_t vendor_patch_level() { return vendor_patch_level_; } + uint32_t boot_patch_level(const vector& key_characteristics); + uint32_t boot_patch_level(); ErrorCode GetReturnErrorCode(const Status& result); @@ -253,7 +255,7 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { /* ECDSA */ KeyData ecdsaKeyData; AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder() - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Authorization(tagToTest) .Digest(Digest::SHA_2_256) .Authorization(TAG_NO_AUTH_REQUIRED) diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 295be1a48d..d41d270764 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -18,6 +18,8 @@ #include #include + +#include #include #include @@ -1362,11 +1364,11 @@ TEST_P(NewKeyGenerationTest, RsaMissingParams) { * have correct characteristics. */ TEST_P(NewKeyGenerationTest, Ecdsa) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .SetDefaultValidity(), &key_blob, &key_characteristics)); @@ -1377,8 +1379,7 @@ TEST_P(NewKeyGenerationTest, Ecdsa) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; CheckedDeleteKey(&key_blob); } @@ -1400,13 +1401,13 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { uint64_t serial_int = 0xFFFFFFFFFFFFFFFF; vector serial_blob(build_serial_blob(serial_int)); - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1421,8 +1422,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_GT(cert_chain_.size(), 0); @@ -1438,6 +1438,170 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { } } +/* + * NewKeyGenerationTest.EcdsaAttestationTags + * + * Verifies that creation of an attested ECDSA key includes various tags in the + * attestation extension. + */ +TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { + auto challenge = "hello"; + auto app_id = "foo"; + auto subject = "cert subj 2"; + vector subject_der(make_name_from_str(subject)); + uint64_t serial_int = 0x1010; + vector serial_blob(build_serial_blob(serial_int)); + const AuthorizationSetBuilder base_builder = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(); + + // Various tags that map to fields in the attestation extension ASN.1 schema. + auto extra_tags = AuthorizationSetBuilder() + .Authorization(TAG_ROLLBACK_RESISTANCE) + .Authorization(TAG_EARLY_BOOT_ONLY) + .Authorization(TAG_ACTIVE_DATETIME, 1619621648000) + .Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, 1619621648000) + .Authorization(TAG_USAGE_EXPIRE_DATETIME, 1619621999000) + .Authorization(TAG_USAGE_COUNT_LIMIT, 42) + .Authorization(TAG_AUTH_TIMEOUT, 100000) + .Authorization(TAG_ALLOW_WHILE_ON_BODY) + .Authorization(TAG_TRUSTED_USER_PRESENCE_REQUIRED) + .Authorization(TAG_TRUSTED_CONFIRMATION_REQUIRED) + .Authorization(TAG_UNLOCKED_DEVICE_REQUIRED) + .Authorization(TAG_CREATION_DATETIME, 1619621648000); + for (const KeyParameter& tag : extra_tags) { + SCOPED_TRACE(testing::Message() << "tag-" << tag); + vector key_blob; + vector key_characteristics; + AuthorizationSetBuilder builder = base_builder; + builder.push_back(tag); + auto result = GenerateKey(builder, &key_blob, &key_characteristics); + if (result == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE && + tag.tag == TAG_ROLLBACK_RESISTANCE) { + continue; + } + if (result == ErrorCode::UNSUPPORTED_TAG && + (tag.tag == TAG_ALLOW_WHILE_ON_BODY || tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED)) { + // Optional tag not supported by this KeyMint implementation. + continue; + } + ASSERT_EQ(result, ErrorCode::OK); + ASSERT_GT(key_blob.size(), 0U); + + EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); + ASSERT_GT(cert_chain_.size(), 0); + verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); + if (tag.tag != TAG_ATTESTATION_APPLICATION_ID) { + // Expect to find most of the extra tags in the key characteristics + // of the generated key (but not for ATTESTATION_APPLICATION_ID). + EXPECT_TRUE(hw_enforced.Contains(tag.tag) || sw_enforced.Contains(tag.tag)) + << tag << " not in hw:" << hw_enforced << " nor sw:" << sw_enforced; + } + + // Verifying the attestation record will check for the specific tag because + // it's included in the authorizations. + EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced, + SecLevel(), cert_chain_[0].encodedCertificate)); + + CheckedDeleteKey(&key_blob); + } + + // Device attestation IDs should be rejected for normal attestation requests; these fields + // are only used for device unique attestation. + auto invalid_tags = AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_ID_BRAND, "brand") + .Authorization(TAG_ATTESTATION_ID_DEVICE, "device") + .Authorization(TAG_ATTESTATION_ID_PRODUCT, "product") + .Authorization(TAG_ATTESTATION_ID_SERIAL, "serial") + .Authorization(TAG_ATTESTATION_ID_IMEI, "imei") + .Authorization(TAG_ATTESTATION_ID_MEID, "meid") + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer") + .Authorization(TAG_ATTESTATION_ID_MODEL, "model"); + for (const KeyParameter& tag : invalid_tags) { + SCOPED_TRACE(testing::Message() << "tag-" << tag); + vector key_blob; + vector key_characteristics; + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(); + builder.push_back(tag); + ASSERT_EQ(ErrorCode::CANNOT_ATTEST_IDS, + GenerateKey(builder, &key_blob, &key_characteristics)); + } +} + +/* + * NewKeyGenerationTest.EcdsaAttestationTagNoApplicationId + * + * Verifies that creation of an attested ECDSA key does not include APPLICATION_ID. + */ +TEST_P(NewKeyGenerationTest, EcdsaAttestationTagNoApplicationId) { + auto challenge = "hello"; + auto attest_app_id = "foo"; + auto subject = "cert subj 2"; + vector subject_der(make_name_from_str(subject)); + uint64_t serial_int = 0x1010; + vector serial_blob(build_serial_blob(serial_int)); + + // Earlier versions of the attestation extension schema included a slot: + // applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, + // This should never have been included, and should never be filled in. + // Generate an attested key that include APPLICATION_ID and APPLICATION_DATA, + // to confirm that this field never makes it into the attestation extension. + vector key_blob; + vector key_characteristics; + auto result = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(attest_app_id) + .Authorization(TAG_APPLICATION_ID, "client_id") + .Authorization(TAG_APPLICATION_DATA, "appdata") + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(), + &key_blob, &key_characteristics); + ASSERT_EQ(result, ErrorCode::OK); + ASSERT_GT(key_blob.size(), 0U); + + EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); + ASSERT_GT(cert_chain_.size(), 0); + verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); + EXPECT_TRUE(verify_attestation_record(challenge, attest_app_id, sw_enforced, hw_enforced, + SecLevel(), cert_chain_[0].encodedCertificate)); + + // Check that the app id is not in the cert. + string app_id = "clientid"; + std::vector needle(reinterpret_cast(app_id.data()), + reinterpret_cast(app_id.data()) + app_id.size()); + ASSERT_EQ(std::search(cert_chain_[0].encodedCertificate.begin(), + cert_chain_[0].encodedCertificate.end(), needle.begin(), needle.end()), + cert_chain_[0].encodedCertificate.end()); + + CheckedDeleteKey(&key_blob); +} + /* * NewKeyGenerationTest.EcdsaSelfSignAttestation * @@ -1451,12 +1615,12 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) { uint64_t serial_int = 0x123456FFF1234; vector serial_blob(build_serial_blob(serial_int)); - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) @@ -1469,8 +1633,7 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); verify_subject_and_serial(cert_chain_[0], serial_int, subject, false); @@ -1512,11 +1675,11 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationRequireAppId) { TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { auto app_id = "foo"; - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .AttestationApplicationId(app_id) .SetDefaultValidity(), @@ -1529,8 +1692,7 @@ TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_EQ(cert_chain_.size(), 1); @@ -1552,7 +1714,6 @@ TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { */ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { auto challenge = "hello"; - auto key_size = 256; std::vector app_id_lengths{143, 258}; for (uint32_t length : app_id_lengths) { @@ -1561,7 +1722,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1574,8 +1735,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, EcCurve::P_256)) << "Curve P256 missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_GT(cert_chain_.size(), 0); @@ -1597,11 +1757,11 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { * resulting keys have correct characteristics. */ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .Authorization(TAG_USAGE_COUNT_LIMIT, 1) .SetDefaultValidity(), @@ -1614,8 +1774,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; // Check the usage count limit tag appears in the authorizations. AuthorizationSet auths; @@ -1632,7 +1791,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { /* * NewKeyGenerationTest.EcdsaDefaultSize * - * Verifies that failing to specify a key size for EC key generation returns + * Verifies that failing to specify a curve for EC key generation returns * UNSUPPORTED_KEY_SIZE. */ TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) { @@ -1651,20 +1810,23 @@ TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) { * UNSUPPORTED_KEY_SIZE. */ TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) { - for (auto key_size : InvalidKeySizes(Algorithm::EC)) { + for (auto curve : InvalidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .SetDefaultValidity(), &key_blob, &key_characteristics)); } - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(190) - .Digest(Digest::NONE) - .SetDefaultValidity())); + ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_ALGORITHM, Algorithm::EC) + .Authorization(TAG_KEY_SIZE, 190) + .SigningKey() + .Digest(Digest::NONE) + .SetDefaultValidity())); } /* @@ -1676,29 +1838,13 @@ TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) { TEST_P(NewKeyGenerationTest, EcdsaMismatchKeySize) { if (SecLevel() == SecurityLevel::STRONGBOX) return; - ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, - GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224) - .Authorization(TAG_EC_CURVE, EcCurve::P_256) - .Digest(Digest::NONE) - .SetDefaultValidity())); -} - -/* - * NewKeyGenerationTest.EcdsaAllValidSizes - * - * Verifies that keymint supports all required EC key sizes. - */ -TEST_P(NewKeyGenerationTest, EcdsaAllValidSizes) { - auto valid_sizes = ValidKeySizes(Algorithm::EC); - for (size_t size : valid_sizes) { - EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(size) - .Digest(Digest::NONE) - .SetDefaultValidity())) - << "Failed to generate size: " << size; - CheckedDeleteKey(); - } + auto result = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_KEY_SIZE, 224) + .Authorization(TAG_EC_CURVE, EcCurve::P_256) + .Digest(Digest::NONE) + .SetDefaultValidity()); + ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || + result == ErrorCode::UNSUPPORTED_ALGORITHM); } /* @@ -2470,31 +2616,6 @@ TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) { ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &signature)); } -/* - * SigningOperationsTest.EcdsaAllSizesAndHashes - * - * Verifies that ECDSA operations succeed with all possible key sizes and hashes. - */ -TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { - for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) - .Digest(digest) - .SetDefaultValidity()); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with size " << key_size - << " and digest " << digest; - if (error != ErrorCode::OK) continue; - - string message(1024, 'a'); - if (digest == Digest::NONE) message.resize(key_size / 8); - SignMessage(message, AuthorizationSetBuilder().Digest(digest)); - CheckedDeleteKey(); - } - } -} - /* * SigningOperationsTest.EcdsaAllDigestsAndCurves * @@ -2560,7 +2681,7 @@ TEST_P(SigningOperationsTest, EcdsaAllCurves) { TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .SetDefaultValidity())); string message(1 * 1024, 'a'); @@ -2575,7 +2696,7 @@ TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) { TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .Authorization(TAG_APPLICATION_ID, "clientid") .Authorization(TAG_APPLICATION_DATA, "appdata") @@ -2612,7 +2733,7 @@ TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { TEST_P(SigningOperationsTest, EcdsaIncompatibleDigest) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .Digest(Digest::SHA1) .SetDefaultValidity())); @@ -3000,13 +3121,12 @@ TEST_P(ImportKeyTest, RsaPublicExponentMismatch) { TEST_P(ImportKeyTest, EcdsaSuccess) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3027,13 +3147,12 @@ TEST_P(ImportKeyTest, EcdsaSuccess) { TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key_rfc5915)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3053,13 +3172,12 @@ TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) { TEST_P(ImportKeyTest, EcdsaP256SEC1Success) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key_sec1)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3080,13 +3198,12 @@ TEST_P(ImportKeyTest, Ecdsa521Success) { if (SecLevel() == SecurityLevel::STRONGBOX) return; ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(521) + .EcdsaSigningKey(EcCurve::P_521) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_521_key)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 521U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_521); CheckOrigin(); @@ -3097,21 +3214,6 @@ TEST_P(ImportKeyTest, Ecdsa521Success) { LocalVerifyMessage(message, signature, params); } -/* - * ImportKeyTest.EcdsaSizeMismatch - * - * Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the - * correct way. - */ -TEST_P(ImportKeyTest, EcdsaSizeMismatch) { - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224 /* Doesn't match key */) - .Digest(Digest::NONE) - .SetDefaultValidity(), - KeyFormat::PKCS8, ec_256_key)); -} - /* * ImportKeyTest.EcdsaCurveMismatch * @@ -3975,7 +4077,7 @@ TEST_P(EncryptionOperationsTest, RsaPkcs1Success) { TEST_P(EncryptionOperationsTest, EcdsaEncrypt) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .SetDefaultValidity())); auto params = AuthorizationSetBuilder().Digest(Digest::NONE); @@ -6418,7 +6520,7 @@ TEST_P(EarlyBootKeyTest, ImportEarlyBootKeyFailure) { ASSERT_EQ(ErrorCode::EARLY_BOOT_ENDED, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .Authorization(TAG_EARLY_BOOT_ONLY) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key));