From 5bdc9f92bb7a004d01a7a60e84995edb95122948 Mon Sep 17 00:00:00 2001 From: Andrew Scull Date: Thu, 19 Jan 2023 09:55:29 +0000 Subject: [PATCH] Allow P-384 and SHA-384 in RKP v3 Following requests from partners, document P-384 and SHA-384 as officially supported signing algorithms and hash functions in the DICE chain. Bug: 265455904 Test: n/a -- documentation-only change Change-Id: Id7b5eaf81be17fda9278dc7ad5f2b441931c6b83 --- security/rkp/CHANGELOG.md | 1 + security/rkp/README.md | 27 +++++++--------- .../IRemotelyProvisionedComponent.aidl | 32 ++++++++++++------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md index 715cf28e4e..9409a6db0c 100644 --- a/security/rkp/CHANGELOG.md +++ b/security/rkp/CHANGELOG.md @@ -41,6 +41,7 @@ This document provides an exact description of which changes have occurred in th payload and the implementation-defined payload itself. This is done by creating a typed `AuthenticatedRequest` object representing the top level data required to authenticate the data provided in the payload, `T`. + * The new CSR format supports P-384 signing keys and SHA-384 hashes in the DICE chain. * RpcHardwareInfo * `supportedNumKeysInCsr` added to report the maximum number of keys supported in a CSR. * `supportedEekCurve` is no longer used, due to the removal of the EEK from the scheme. diff --git a/security/rkp/README.md b/security/rkp/README.md index 5fb49486ce..9090ac5c05 100644 --- a/security/rkp/README.md +++ b/security/rkp/README.md @@ -172,31 +172,28 @@ This document uses: * ECDSA P-256 for attestation signing keys; * Remote provisioning protocol signing keys: - * Ed25519 / P-256 + * Ed25519 / P-256 / P-384 * ECDH keys: * X25519 / P-256 * AES-GCM for all encryption; -* SHA-256 for all message digesting; -* HMAC-SHA-256 for all MACing; and -* HKDF-SHA-256 for all key derivation. +* SHA-256 / SHA-384 / SHA-512 for message digesting; +* HMAC with a supported message digest for all MACing; and +* HKDF with a supported message digest for all key derivation. We believe that Curve25519 offers the best tradeoff in terms of security, efficiency and global trustworthiness, and that it is now sufficiently widely-used and widely-implemented to make it a practical choice. -However, since Secure Elements (SE) do not currently offer support for curve -25519, we are allowing implementations to instead make use of EC P-256 for -signing and ECDH. To put it simply, the device unique key pair will be a P-256 -key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt -message will have its payload encrypted with P-256 ECDH key exchange instead of -X25519. +However, since hardware such as Secure Elements (SE) do not currently offer +support for curve 25519, we are allowing implementations to instead make use of +ECDSA and ECDH. The CDDL in the rest of the document will use the '/' operator to show areas -where either curve 25519 or P-256 may be used. Since there is no easy way to -bind choices across different CDDL groups, it is important that the implementor -stays consistent in which type is chosen. E.g. taking ES256 as the choice for -algorithm implies the implementor should also choose the P256 public key group -further down in the COSE structure. +where either curve 25519, P-256 or P-384 may be used. Since there is no easy way +to bind choices across different CDDL groups, it is important that the +implementor stays consistent in which type is chosen. E.g. taking ES256 as the +choice for algorithm implies the implementor should also choose the P256 public +key group further down in the COSE structure. ### Testability diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl index 5485db3e9b..9067dba751 100644 --- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl +++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl @@ -344,7 +344,7 @@ interface IRemotelyProvisionedComponent { * * ; COSE_Sign1 (untagged) * SignedData = [ - * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 }, + * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 }, * unprotected: {}, * payload: bstr .cbor Data / nil, * signature: bstr ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct) / @@ -354,7 +354,7 @@ interface IRemotelyProvisionedComponent { * ; Sig_structure for SignedData * SignedDataSigStruct = [ * context: "Signature1", - * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 }, + * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 }, * external_aad: bstr .size 0, * payload: bstr .cbor Data / nil, * ] @@ -386,7 +386,7 @@ interface IRemotelyProvisionedComponent { * ; after the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN) * ; Note that there is no DiceChainEntry for UDS_pub, only a "bare" COSE_key. * DiceCertChain = [ - * PubKeyEd25519 / PubKeyECDSA256, ; UDS_Pub + * PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384, ; UDS_Pub * + DiceChainEntry, ; First CDI_Certificate -> Last CDI_Certificate * ; Last certificate corresponds to KeyMint's DICE key. * ] @@ -394,16 +394,17 @@ interface IRemotelyProvisionedComponent { * ; This is the signed payload for each entry in the DICE chain. Note that the "Configuration * ; Input Values" described by the Open Profile are not used here. Instead, the DICE chain * ; defines its own configuration values for the Configuration Descriptor field. See - * ; the Open Profile for DICE for more details on the fields. SHA256 and SHA512 are acceptable - * ; hash algorithms. The digest bstr values in the payload are the digest values without any - * ; padding. Note that for SHA256, this implies the digest bstr is 32 bytes. This is an - * ; intentional, minor deviation from Open Profile for DICE, which specifies all digests are - * ; 64 bytes. + * ; the Open Profile for DICE for more details on the fields. SHA256, SHA384 and SHA512 are + * ; acceptable hash algorithms. The digest bstr values in the payload are the digest values + * ; without any padding. Note that this implies that the digest is a 32-byte bstr for SHA256 + * ; and a 48-byte bstr for SHA384. This is an intentional, minor deviation from Open Profile + * ; for DICE, which specifies all digests are 64 bytes. * DiceChainEntryPayload = { ; CWT [RFC8392] * 1 : tstr, ; Issuer * 2 : tstr, ; Subject * -4670552 : bstr .cbor PubKeyEd25519 / - * bstr .cbor PubKeyECDSA256, ; Subject Public Key + * bstr .cbor PubKeyECDSA256, + * bstr .cbor PubKeyECDSA384, ; Subject Public Key * -4670553 : bstr ; Key Usage * * ; NOTE: All of the following fields may be omitted for a "Degenerate DICE Chain", as @@ -424,7 +425,7 @@ interface IRemotelyProvisionedComponent { * ; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous * ; entry in the DICE chain array. * DiceChainEntry = [ ; COSE_Sign1 (untagged) - * protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 }, + * protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 }, * unprotected: {}, * payload: bstr .cbor DiceChainEntryPayload, * signature: bstr ; PureEd25519(SigningKey, bstr .cbor DiceChainEntryInput) / @@ -435,7 +436,7 @@ interface IRemotelyProvisionedComponent { * * DiceChainEntryInput = [ * context: "Signature1", - * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 }, + * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 }, * external_aad: bstr .size 0, * payload: bstr .cbor DiceChainEntryPayload * ] @@ -470,7 +471,16 @@ interface IRemotelyProvisionedComponent { * -3 : bstr ; Y coordinate * } * + * PubKeyECDSA384 = { ; COSE_Key + * 1 : 2, ; Key type : EC2 + * 3 : AlgorithmES384, ; Algorithm : ECDSA w/ SHA-384 + * -1 : 2, ; Curve: P384 + * -2 : bstr, ; X coordinate + * -3 : bstr ; Y coordinate + * } + * * AlgorithmES256 = -7 + * AlgorithmES384 = -35 * AlgorithmEdDSA = -8 */ byte[] generateCertificateRequestV2(in MacedPublicKey[] keysToSign, in byte[] challenge);