Skip to content

Commit

Permalink
[pa] add protos / stub for GenLcToken RPC
Browse files Browse the repository at this point in the history
This adds protos and a function stub for the `GenLcToken` RPC call
which the PA must implement to support OpenTitan A1 provisioning flows.

This RPC function will generate test unlock/exit LC tokens and RMA
tokens to inject into an OpenTitan device during provisioning.

This partially addresses lowRISC#4.

Signed-off-by: Tim Trippel <[email protected]>
  • Loading branch information
timothytrippel committed Sep 23, 2024
1 parent 968f25c commit 39a7fd9
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/pa/proto/pa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ service ProvisioningApplianceService {
returns (CreateKeyAndCertResponse) {}
rpc EndorseCerts(EndorseCertsRequest)
returns (EndorseCertsResponse) {}
rpc GenLcToken(GenLcTokenRequest)
returns (GenLcTokenResponse) {}
rpc SendDeviceRegistrationPayload(RegistrationRequest)
returns (RegistrationResponse) {}
}
Expand All @@ -46,6 +48,60 @@ message EndorseCertsResponse {
repeated crypto.cert.Certificate certs = 1;
}

// OpenTitan Lifecycle Token Types.
enum LcTokenType {
// Unspecified.
LC_TOKEN_TYPE_UNSPECIFIED = 0;
// Test Unlock Token.
LC_TOKEN_TYPE_TEST_UNLOCK = 1;
// Test Exit Token.
LC_TOKEN_TYPE_TEST_EXIT = 2;
// RMA Token.
LC_TOKEN_TYPE_RMA = 3;
}

// OpenTitan Lifecycle Token Formats.
enum LcTokenFormat {
// Unspecified.
LC_TOKEN_FORMAT_UNSPECIFIED = 0;
// Raw.
//
// This format is used when the raw token must be generated in order to move
// the device from one LC state to another.
LC_TOKEN_FORMAT_RAW = 1;
// Hashed.
//
// This format is used when the cSHAKE128 hashed form of the token needs to
// be generated to program into the device's OTP memory.
//
// 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 on how OpenTitan LC tokens are stored in OTP.
LC_TOKEN_FORMAT_HASHED = 2;
}

// Generate lifecycle token request.
message GenLcTokenRequest {
// SKU identifier. Required.
string sku = 1;
// Device identifier. Optional.
//
// The DeviceId is only required when the token type is `LC_TOKEN_TYPE_RMA`,
// since these are required to be different per device.
device_id.DeviceId device_id = 2;
// Lifecycle token type. Required.
LcTokenType token_type = 3;
// Lifecycle token format. Required.
LcTokenFormat token_format = 4;
}

// Generate lifecycle token response.
message GenLcTokenResponse {
// A 128 bit LC token in either raw or hashed form (based on request sent).
// Size is enforced at a higher level.
bytes token = 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
Expand Down
8 changes: 8 additions & 0 deletions src/pa/services/pa.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ func (s *server) EndorseCerts(ctx context.Context, request *pbp.EndorseCertsRequ
return nil, nil
}

// GenLcToken generates a specific OpenTitan Lifecycle Token and returns it.
func (s *server) GenLcToken(ctx context.Context, request *pbp.GenLcTokenRequest) (*pbp.GenLcTokenResponse, error) {
log.Printf("In PA - Recieved GenLcToken request for DeviceID: %v", request.DeviceId)

// 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)
Expand Down

0 comments on commit 39a7fd9

Please sign in to comment.