Merge changes I33036387,I63ca8d29 am: aedb92d5af am: 5455f2dc13

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1740893

Change-Id: I64708a3f57a27daa694722d6019419371be22101
This commit is contained in:
David Drysdale 2021-06-21 05:53:21 +00:00 committed by Automerger Merge Worker
commit dfff9c74f1
3 changed files with 254 additions and 142 deletions

View file

@ -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<KeyCharacteristics>& 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<uint32_t> 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<EcCurve> KeyMintAidlTestBase::ValidCurves() {
}
vector<EcCurve> 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<Digest> 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<uint8_t> att_challenge;
vector<uint8_t> att_unique_id;
vector<uint8_t> 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();

View file

@ -76,6 +76,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
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<KeyCharacteristics>& key_characteristics);
uint32_t boot_patch_level();
ErrorCode GetReturnErrorCode(const Status& result);
@ -253,7 +255,7 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
/* ECDSA */
KeyData ecdsaKeyData;
AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder()
.EcdsaSigningKey(256)
.EcdsaSigningKey(EcCurve::P_256)
.Authorization(tagToTest)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_NO_AUTH_REQUIRED)

View file

@ -18,6 +18,8 @@
#include <cutils/log.h>
#include <signal.h>
#include <algorithm>
#include <iostream>
#include <openssl/ec.h>
@ -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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> serial_blob(build_serial_blob(serial_int));
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
for (auto curve : ValidCurves()) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> subject_der(make_name_from_str(subject));
uint64_t serial_int = 0x1010;
vector<uint8_t> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> subject_der(make_name_from_str(subject));
uint64_t serial_int = 0x1010;
vector<uint8_t> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> needle(reinterpret_cast<const uint8_t*>(app_id.data()),
reinterpret_cast<const uint8_t*>(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<uint8_t> serial_blob(build_serial_blob(serial_int));
for (auto key_size : ValidKeySizes(Algorithm::EC)) {
for (auto curve : ValidCurves()) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint32_t> app_id_lengths{143, 258};
for (uint32_t length : app_id_lengths) {
@ -1561,7 +1722,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) {
vector<KeyCharacteristics> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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<uint8_t> key_blob;
vector<KeyCharacteristics> 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));