From 18a799cd5f7e7cc1dc2be1e980dc3c50cdb0aa22 Mon Sep 17 00:00:00 2001 From: Tim Trippel Date: Fri, 20 Sep 2024 13:30:57 -0700 Subject: [PATCH] [pa] add protos / stub for `DeriveSymmetricKey` RPC This adds protos and a function stub for the `DeriveSymmetricKey` RPC call which the PA must implement to support OpenTitan A1 provisioning flows. This RPC will support: - OpenTitan lifecycle token generation (in raw and hashed form) - OpenTitan wafer authentication secret generation. This partially addresses #4. Signed-off-by: Tim Trippel --- src/pa/proto/pa.proto | 61 +++++++++++++++++++++++++++++++++++++++++++ src/pa/services/pa.go | 9 +++++++ 2 files changed, 70 insertions(+) diff --git a/src/pa/proto/pa.proto b/src/pa/proto/pa.proto index f8ff5f8..133709a 100644 --- a/src/pa/proto/pa.proto +++ b/src/pa/proto/pa.proto @@ -23,6 +23,8 @@ service ProvisioningApplianceService { returns (CreateKeyAndCertResponse) {} rpc EndorseCerts(EndorseCertsRequest) returns (EndorseCertsResponse) {} + rpc DeriveSymmetricKey(DeriveSymmetricKeyRequest) + returns (DeriveSymmetricKeyResponse) {} rpc SendDeviceRegistrationPayload(RegistrationRequest) returns (RegistrationResponse) {} } @@ -44,6 +46,65 @@ message EndorseCertsResponse { repeated crypto.cert.Certificate certs = 1; } +// Symmetric key seed type (seed is provisioned into HSM). +enum SymmetricKeySeed { + // Unspecified. + SYMMETRIC_KEY_SEED_UNSPECIFIED = 0; + // Low Security: seed is rotated infrequently. + SYMMETRIC_KEY_SEED_LOW_SECURITY = 1; + // High Security: seed is rotated frequently. + SYMMETRIC_KEY_SEED_HIGH_SECURITY = 2; +} + +// Symmetric key type. +enum SymmetricKeyType { + // Unspecified. + SYMMETRIC_KEY_TYPE_UNSPECIFIED = 0; + // Raw. + // + // This format is used when the raw plaintext key must be generated. + SYMMETRIC_KEY_TYPE_RAW = 1; + // Hashed. + // + // This format is used when the cSHAKE128 hashed (with "LC_CTRL" customization + // string) form of the key needs to be generated. This type supports + // provisioning of OpenTitan lifecycle tokens, which are programmed into a + // device's OTP memory in this form. + // + // protolint:disable:next MAX_LINE_LENGTH + // See https://opentitan.org/book/hw/ip/lc_ctrl/doc/theory_of_operation.html#token-hashing-mechanism + // for more details. + SYMMETRIC_KEY_TYPE_HASHED_OT_LC_TOKEN = 2; +} + +// Symmetric key size. +enum SymmetricKeySize { + // Unspecified. + SYMMETRIC_KEY_SIZE_UNSPECIFIED = 0; + // 128 bits. + SYMMETRIC_KEY_SIZE_128_BITS = 1; + // 256 bits. + SYMMETRIC_KEY_SIZE_256_BITS = 2; +} + +// Derive symmetric key request. +message DeriveSymmetricKeyRequest{ + // Symmetric key seed to use. Required. + SymmetricKeySeed seed = 1; + // Symmetric key type to generate. Required. + SymmetricKeyType type = 2; + // Symmetric key size. Required. + SymmetricKeySize size = 3; + // Diversifier string to use in KDF operation. Required. + string diversifier = 4; +} + +// Derive symmetric key response. +message DeriveSymmetricKeyResponse{ + // Key bytes. Size is provided in the request. + bytes key = 1; +} + // Create key and endorsement certificates request. // The `sku` fields is used as an unique key to // implement the specific key gen and endorsement certificate flow for a diff --git a/src/pa/services/pa.go b/src/pa/services/pa.go index 84a9fa1..bb3d5e6 100644 --- a/src/pa/services/pa.go +++ b/src/pa/services/pa.go @@ -108,6 +108,15 @@ func (s *server) EndorseCerts(ctx context.Context, request *pbp.EndorseCertsRequ return nil, nil } +// DeriveSymmetricKey generates a symmetric key from a seed (pre-provisioned in +// the SPM/HSM) and diversifier string. +func (s *server) DeriveSymmetricKey(ctx context.Context, request *pbp.DeriveSymmetricKeyRequest) (*pbp.DeriveSymmetricKeyResponse, error) { + log.Printf("In PA - Recieved DeriveSymmetricKey request with diversifier string: %s", request.Diversifier) + + // TODO(#4) implement backend operations. + return nil, nil +} + // SendDeviceRegistrationPayload registers a new device record to the local MySql DB. func (s *server) SendDeviceRegistrationPayload(ctx context.Context, request *pbp.RegistrationRequest) (*pbp.RegistrationResponse, error) { log.Printf("In PA - Received SendDeviceRegistrationPayload request with DeviceID: %v", request.DeviceRecord.Id)