Keyring Management

Introduction

Public keyring:

The extended public keyring enables the generic data blob to be signed/verified with user’s auxiliary key other than the root key (i.e. SMPK/BMPK).

Symmetric keyring:

The extended symmetric keyring also enables the generic data blob to be encrypted/decrypted with user’s auxiliary key other than the root key (i.e. SMEK/BMEK).

Background on Use-cases

The following describes the use-cases which substantiate the need for keyring within SMS and drive the design decisions described later in this document.

Public keyring:

  • Import auxiliary public keys’ hash presented in the form of a signed x509 certificate after validation.
  • The imported keys’ hash can be used to authenticate the signed firmware or data blobs presented to System Firmware.
  • The imported keys’ hash can be used for debug certificate authentication.

Symmetric keyring:

  • Import symmetric keys presented in the form of a signed and encrypted x509 certificate after validation and decryption.
  • The imported symmetric keys can be used to decrypt the signed and encrypted firmware or data blobs presented to System Firmware.

Functional Goals

Keyring provides the following functionality:

  1. APIs to import the entire keyring in to TIFS internal memory.
  2. System Firmware can use the keys imported from the extended public keyring, during the signed firmware, debug certificate authentication or data blob authentication.
  3. System Firmware can use the keys imported from the extended symmetric keyring, during the signed and encrypted firmware or data blob decryption.

Design

Keyring design is described in the following sections

Key Data Storage

The keyring exists in a carved out section of SMS internal memory with a build-time configurable size. The keyring memory contains following information:

  • Internal state of the keyring. This is only initialized and transitioned inside System Firmware. It is meaningless from the host perspective and should be treated as reserved.
  • Array of metadata descriptors for the keys in the keyring. The descriptors for the key slots specify:

The following table gives the Parameters of Public keys

Public Keyring parameters Description
key_type
Flag to indicate if key is asymmetric or symmetric
Value 0 denotes asymmetric key
keyid
keyid of the key
keyid can take values between and including 1 to 254
imageauth
Flag to indicate if key can be used for firmware image authentication
Value 1 indicates the key can be used
debugauth
Flag to indicate if key can be used for debug certificate authentication
Value 1 indicates the key can be used
reserved
reserved[0] is used to denote the sha algorithm used to generate the auxiliary public key’s hash
• reserved[0] = 0 denotes sha512
• reserved[0] = 1 denotes sha384
• reserved[0] = 2 denotes sha256

reserved[1] is used to denote the auxiliary public key’s length
• reserved[1] = 0 denotes RSA4096
• reserved[1] = 1 denotes RSA3072

reserved[3] and reserved[4] remains 0 and is reserved for internal/future use
esmpkh
esmpk hash for authentication

The following table gives the Parameters of symmetric keys

Symmetric Keyring parameters Description
key_type
Flag to indicate if key is asymmetric or symmetric
Value 1 denotes symmetric key
keyid
keyid of the key
keyid can take values between and including 1 to 254
key_length
Value to indicate the size of the symmetric key
Value 2 denotes AES256 key
Currently, only AES256 keys are supported
rsvd
Reserved for internal/future use
key_rights
Key rights to indicate if the key can be used for different operations
<    MSB                                    LSB    >
<---1byte---><---1byte---><---1byte---><---1byte--->
<  Reserved       HKDF    CSP_decrypt Image_enc_dec>
image_enc_dec flag to indicate if key can be used for firmware image encryption & decryption
CSP_decrypt flag to indicate if key can be used for CSP decryption
HKDF flag to indicate if key can be used for HKDF
Value 0x5A in the respective byte denotes the key can be used for the respective operation
Value 0xA5 in the respective byte denotes the key can’t be used for the respective operation
reserved_0
Reserved for internal/future use
reserved_1
Reserved for internal/future use
reserved_2
Reserved for internal/future use
esmek
esmek key for encryption/decryption

The above information is placed at the base of the keyring memory. This can be more concisely represented by the C-code definition of the keyring structure.

Public keyring structure

struct aux_pkh {
      uint8_t key_type;
      uint8_t keyid;
      uint8_t imageauth;
      uint8_t debugauth;
      uint8_t reserved[4];
} __attribute__((packed));

struct keyring_asymm {
      struct aux_pkh  aux;
      uint8_t         smpkh[64];
} __attribute__((packed));

Symmetric keyring structure

struct aux_symm {
      uint8_t key_type;
      uint8_t key_id;
      uint8_t key_length;
      uint8_t rsvd;
      uint32_t key_rights;
      uint32_t reserved_0;
      uint32_t reserved_1;
      uint32_t reserved_2;
} __attribute__((packed));

struct keyring_symm {
      struct aux_symm aux;
      uint8_t         esmek[32];
} __attribute__((packed));

Combined Asymmetric-Symmetric keyring structure

struct keyring_asymm_symm {
      struct keyring_asymm asymm_keys[6];
      u8 reserved[32];
      struct keyring_symm symm_keys[6];
} __attribute__((packed));

Keyring Import

Early in the lifecycle of the HS device, the customer will use the keywriter to blow the eFuse with Secondary MPKH and MEK (among other contents) and transition the device from HS-FS state to HS-SE. At this point, the keyring contents have not yet been populated and it is up to the system software owner to provision an initial set of keys. This is achieved through a bulk import of the keyring contents which have been appended to an x509 certificate signed with the active customer MPK, similar to how one signs an encrypted binary for secure boot. The keyring blob can be optionally encrypted with the active customer MEK. Validation of the certificate ensures that the keyring contents are trustworthy and can hence be stored into the reserved memory. If the certificate check fails then provisioning will not be successful and the keyring will remain uninitialized.

The host is responsible for ensuring that the keyring data is properly formatted when creating the payload for the keyring import API. If not, the data will be interpreted differently between the host and System Firmware which can cause unpredictable values for the various fields in the structure. The data corruption may cause following failures in subsequent key operations:

  • Key type is not correct, so operations checking for the key type will fail.
  • The key id of each key must be between and including values 1-254, else the keyring import will fail.
  • Usage flags are not correct, so usage permissions checks will fail.
  • Key length value is not correct, so key length checks will fail.

Keyring import operation requires following constraints:

  • The number of keys in the certificate extension must match the number of keys present in the keyring.
  • Without a keyring info certificate extension, keyring import will fail.
  • The number of asymmetric keys should be between and including values 1-6.
  • The number of symmetric keys should be between and including values 1-6.
  • Public/Symmetric/Combined Keyring can only be imported once, and any further attempts will fail. Symmetric keyring can be imported after importing public keyring and vice versa, but any attempts to import already successfully imported scenario will fail. Trying to import public/symmetric keyring after a successful combined keyring import will as well fail.
  • If symmetric keys are imported using either symmetric keyring/combined keyring, it is mandatory to encrypt the keyring blob, else keyring import will fail.
  • While importing a combined keyring, the number of asymmetric keys should always be 6 and the number of symmetric keys can be 1-6.

Keyring import scenarios

Case 1 (Valid)

../_images/keyring_import_case_1.png

Case 2 (Valid)

../_images/keyring_import_case_2.png

Case 3 (Valid)

../_images/keyring_import_case_3.png

Case 4 (Invalid)

../_images/keyring_import_case_4.png

Case 5 (Multiple import scenarios in one runtime)

../_images/keyring_import_case_5_part_1.png
../_images/keyring_import_case_5_part_2.png
../_images/keyring_import_case_5_part_3.png

Proc auth boot operation requires following constraints:

  • Without a key info certificate extension for the certificate signed/encrypted by one of the keys from the keyring, the corresponding processor auth boot will fail.
  • In a certificate signed or blob encrypted by one of the keys from the keyring, the auth_key_id/enc_key_id in the key info certificate extension must match the key id of the key from the keyring that was used to sign the certificate / encrypt the blob.

User flow

../_images/user_guide_flow.png

Key generation

Public key generation:

  • In public keyring, currently only RSA4096 and RSA3072 keys are supported.
  • The RSA key pair can be generated using openssl.
  • For example, Generate a 4096 bit RSA Key: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out rsa_privkey.pem -outform pem
  • Extract the public key: openssl rsa -inform pem -in rsa_privkey.pem -pubout -outform der > rsa_pubkey.der
  • Private key format -> .pem
  • Public key format -> .der

Symmetric key generation:

  • In symmetric keyring, currently only AES256 keys are supported.
  • The AES256 key can be generated using openssl.
  • For example, Generate a 256 bit AES Key: openssl rand -hex 32 > key.txt

Keyring blob generation

Public keyring:

  • Create an array of keyring_asymm structure instances.
  • Fill in the key metadata and the public key hash for all the keys in the keyring.

Symmetric keyring:

  • Create an array of keyring_symm structure instances.
  • Fill in the key metadata and the symmetric key for all the keys in the keyring.

Combined keyring:

  • Create the combined keyring_asymm_symm structure instance such that it has a six membered array of keyring asymm structure instances and an array of keyring_symm structure instances.
  • Fill in the key metadata and the public key hash for all the keys in the keyring.
  • Fill in the key metadata and the symmetric key for all the keys in the keyring.

Sign and optionally encrypt the generated keyring blob:

  • Compile the c file created in the previous step.
  • Take the data section of the compiled object file and put it in a bin file.
  • Sign and optionally encrypt this binary with the appropriate X509 extensions required.
  • Create a keyring header file and hex dump the certificate and the bin file in it.
  • Place the header files data in an array and send it to System Firmware using the TISCI_MSG_KEYRING_IMPORT API.

Sign and optionally encrypt a firmware image using the keys from the imported keyring:

  • Sign and optionally encrypt the binary with the appropriate X509 extensions required.
  • Create a binary header file and hex dump the certificate and the binary file in it.
  • Place the header files data in an array and send it to System Firmware using the TISCI_MSG_PROC_AUTH_BOOT API.

References

  1. https://en.wikipedia.org/wiki/Public_key_infrastructure
  2. Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile https://tools.ietf.org/html/rfc5280