From 3cb64a68227e04f802551f5fef0a0721225756ff Mon Sep 17 00:00:00 2001 From: Shawn Willden Date: Mon, 5 Apr 2021 14:39:05 -0600 Subject: [PATCH] Add attestation format documentation Somehow the attestation format docs got dropped from KeyMint in the transition from Keymaster. This replaces them, and also clarifies that KeyMint StrongBox should not support device attestation. Test: VtsAidlKeyMintTargetTest Change-Id: I2334e99b4797c7a0e2e59727ffa730cf7504df31 --- .../security/keymint/IKeyMintDevice.aidl | 8 ++ .../security/keymint/KeyCreationResult.aidl | 107 +++++++++++++++++- .../hardware/security/keymint/Tag.aidl | 27 ++--- .../vts/functional/KeyMintAidlTestBase.cpp | 4 +- 4 files changed, 130 insertions(+), 16 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index 1c503c2913..ddbeafcd44 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -325,6 +325,10 @@ interface IKeyMintDevice { * return ErrorCode::INCOMPATIBLE_PURPOSE. If the provided AttestationKey has an empty * issuer subject name, the IKeyMintDevice must return ErrorCode::INVALID_ARGUMENT. * + * If `attestationKey` is null and `keyParams` contains Tag::ATTESTATION_CHALLENGE but + * the KeyMint implementation does not have factory-provisioned attestation keys, it must + * return ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED. + * * @return The result of key creation. See KeyCreationResult.aidl. */ KeyCreationResult generateKey( @@ -364,6 +368,10 @@ interface IKeyMintDevice { * return ErrorCode::INCOMPATIBLE_PURPOSE. If the provided AttestationKey has an empty * issuer subject name, the IKeyMintDevice must return ErrorCode::INVALID_ARGUMENT. * + * If `attestationKey` is null and `keyParams` contains Tag::ATTESTATION_CHALLENGE but + * the KeyMint implementation does not have factory-provisioned attestation keys, it must + * return ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED. + * * @return The result of key creation. See KeyCreationResult.aidl. */ KeyCreationResult importKey(in KeyParameter[] keyParams, in KeyFormat keyFormat, diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl index c2e21b6d37..972a6a52e5 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl @@ -66,7 +66,8 @@ parcelable KeyCreationResult { * provisioned attestation key, and the full certificate chain for that factory-provisioned * attestation key. Tag::ATTESTATION_APPLICATION_ID must also be provided when the * ATTESTATION_CHALLENGE is provided, otherwise ATTESTATION_APPLICATION_ID_MISSING will be - * returned. + * returned. KeyMint implementations are not required to support factory-provisioned + * attestation keys. * * 2. Asymmetric key attestation with caller-provided key. If Tag::ATTESTATION_CHALLENGE is * provided and the `attestationKey` parameter on the generat/import call is non-null and @@ -90,6 +91,110 @@ parcelable KeyCreationResult { * 5. Symmetric key. If the generated/imported key is symmetric, the certificate chain must * return empty, any Tag::ATTESTATION_CHALLENGE or Tag::ATTESTATION_APPLICATION_ID inputs, * if provided, are ignored. + * + * In all cases except the symmetric key, the contents of certificate chain must be DER-encoded + * X.509 certificates ordered such that each certificate is signed by the subsequent one, up to + * the root which must be self-signed (or contain a fake signature in the case of case 4 above). + * The first certificate in the chain signs the public key info of the newly-generated or + * newly-imported key pair. In the attestation cases (1 and 2 above), the first certificate + * must also satisfy some other requirements: + * + * o It must have the serial number provided in Tag::CERTIFICATE_SERIAL, or default to 1 if the + * tag is not provided. + * + * o It must have the subject provided in Tag::CERTIFICATE_SUBJECT, or default to CN="Android + * Keystore Key", if the tag is not provided. + * + * o It must contain the notBefore and notAfter date-times specified in + * Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER, respectively. + * + * o It must contain a Key Usage extension with: + * + * - the digitalSignature bit set iff the attested key has KeyPurpose::SIGN, + * - the dataEncipherment bit set iff the attested key has KeyPurpose::DECRYPT, + * - the keyEncipherment bit set iff the attested key has KeyPurpose::WRAP_KEY, + * - the keyAgreement bit set iff the attested key has KeyPurpose::AGREE_KEY, and + * - the keyCertSignBit set iff the attested key has KeyPurpose::ATTEST_KEY. + * + * o it must contain a KeyDescription attestation extension with OID 1.3.6.1.4.1.11129.2.1.17. + * + * The KeyDescription content is defined by the following ASN.1 schema, which is mostly a + * straightforward translation of the KeyMint tag/value parameter lists to ASN.1. + * + * KeyDescription ::= SEQUENCE { + * attestationVersion INTEGER, # Value 100 + * attestationSecurityLevel SecurityLevel, # See below + * keyMintVersion INTEGER, # Value 100 + * keymintSecurityLevel SecurityLevel, # See below + * attestationChallenge OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams + * uniqueId OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID + * softwareEnforced AuthorizationList, # See below + * hardwareEnforced AuthorizationList, # See below + * } + * + * SecurityLevel ::= ENUMERATED { + * Software (0), + * TrustedEnvironment (1), + * StrongBox (2), + * } + * + * RootOfTrust ::= SEQUENCE { + * verifiedBootKey OCTET_STRING, + * deviceLocked BOOLEAN, + * verifiedBootState VerifiedBootState, + * # verifiedBootHash must contain 32-byte value that represents the state of all binaries + * # or other components validated by verified boot. Updating any verified binary or + * # component must cause this value to change. + * verifiedBootHash OCTET_STRING, + * } + * + * VerifiedBootState ::= ENUMERATED { + * Verified (0), + * SelfSigned (1), + * Unverified (2), + * Failed (3), + * } + * + * AuthorizationList ::= SEQUENCE { + * purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, + * algorithm [2] EXPLICIT INTEGER OPTIONAL, + * keySize [3] EXPLICIT INTEGER OPTIONAL, + * blockMode [4] EXPLICIT SET OF INTEGER OPTIONAL, + * digest [5] EXPLICIT SET OF INTEGER OPTIONAL, + * padding [6] EXPLICIT SET OF INTEGER OPTIONAL, + * callerNonce [7] EXPLICIT NULL OPTIONAL, + * minMacLength [8] EXPLICIT INTEGER OPTIONAL, + * ecCurve [10] EXPLICIT INTEGER OPTIONAL, + * rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, + * rollbackResistance [303] EXPLICIT NULL OPTIONAL, + * activeDateTime [400] EXPLICIT INTEGER OPTIONAL, + * originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, + * usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, + * userSecureId [502] EXPLICIT INTEGER OPTIONAL, + * noAuthRequired [503] EXPLICIT NULL OPTIONAL, + * userAuthType [504] EXPLICIT INTEGER OPTIONAL, + * authTimeout [505] EXPLICIT INTEGER OPTIONAL, + * allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, + * trustedUserPresenceReq [507] EXPLICIT NULL OPTIONAL, + * trustedConfirmationReq [508] EXPLICIT NULL OPTIONAL, + * unlockedDeviceReq [509] EXPLICIT NULL OPTIONAL, + * creationDateTime [701] EXPLICIT INTEGER OPTIONAL, + * origin [702] EXPLICIT INTEGER OPTIONAL, + * rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, + * osVersion [705] EXPLICIT INTEGER OPTIONAL, + * osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, + * attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, + * attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, + * vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, + * bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, + * } */ Certificate[] certificateChain; } diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index cde1fc0f60..2a1ec5c633 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -935,33 +935,34 @@ enum Tag { CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005, /** - * Tag::CERTIFICATE_SERIAL specifies the serial number to be assigned to the - * attestation certificate to be generated for the given key. This parameter should only - * be passed to keyMint in the attestation parameters during generateKey() and importKey(). + * Tag::CERTIFICATE_SERIAL specifies the serial number to be assigned to the attestation + * certificate to be generated for the given key. This parameter should only be passed to + * keyMint in the attestation parameters during generateKey() and importKey(). If not provided, + * the serial shall default to 1. */ CERTIFICATE_SERIAL = (8 << 28) /* TagType:BIGNUM */ | 1006, /** - * Tag::CERTIFICATE_SUBJECT the certificate subject. The value is a DER encoded X509 NAME. - * This value is used when generating a self signed certificates. This tag may be specified + * Tag::CERTIFICATE_SUBJECT the certificate subject. The value is a DER encoded X509 NAME. + * This value is used when generating a self signed certificates. This tag may be specified * during generateKey and importKey. If not provided the subject name shall default to - * . + * CN="Android Keystore Key". */ CERTIFICATE_SUBJECT = (9 << 28) /* TagType:BYTES */ | 1007, /** * Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch - * time in seconds. This value is used when generating attestation or self signed certificates. - * ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if this tag is - * not provided to generateKey or importKey. + * time in seconds. This value is used when generating attestation or self signed certificates. + * ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if this tag is not + * provided to generateKey or importKey. */ CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008, /** - * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch - * time in seconds. This value is used when generating attestation or self signed certificates. - * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey - * or importKey. + * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in + * seconds. This value is used when generating attestation or self signed certificates. + * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or + * importKey. */ CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009, diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 6202a8ba97..ce23f7088d 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -942,7 +942,7 @@ bool verify_attestation_record(const string& challenge, // EXPECT_EQ(ErrorCode::OK, error); if (error != ErrorCode::OK) return false; - EXPECT_GE(att_attestation_version, 3U); + EXPECT_EQ(att_attestation_version, 100U); vector appId(app_id.begin(), app_id.end()); // check challenge and app id only if we expects a non-fake certificate @@ -953,7 +953,7 @@ bool verify_attestation_record(const string& challenge, // expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId); } - EXPECT_GE(att_keymaster_version, 4U); + EXPECT_EQ(att_keymaster_version, 100U); EXPECT_EQ(security_level, att_keymaster_security_level); EXPECT_EQ(security_level, att_attestation_security_level);