Skip to content

Commit

Permalink
[pa,spm] implement DeriveSymmetricKey RPC
Browse files Browse the repository at this point in the history
This updates the PA and SPM to implement the `DeriveSymmetricKey` key
RPC function. This partially addresses lowRISC#4.

Signed-off-by: Tim Trippel <[email protected]>
  • Loading branch information
timothytrippel committed Oct 8, 2024
1 parent 66d467e commit 9956b66
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/pa/proto/pa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ message DeriveSymmetricKeyResponse{
message CreateKeyAndCertRequest {
// SKU identifier. Required.
string sku = 1;
// Device identifier. Required.
// Device identifier. Optional.
device_id.DeviceId device_id = 2;
// Serial Number per sku. Optional.
// Serial Number per sku. Required.
bytes serial_number = 3;
}

Expand Down
8 changes: 5 additions & 3 deletions src/pa/services/pa.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ func (s *server) EndorseCerts(ctx context.Context, request *pbp.EndorseCertsRequ
// 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
r, err := s.spmClient.DeriveSymmetricKey(ctx, request)
if err != nil {
return nil, status.Errorf(codes.Internal, "SPM returned error: %v", err)
}
return r, nil
}

// SendDeviceRegistrationPayload registers a new device record to the local MySql DB.
Expand Down
8 changes: 8 additions & 0 deletions src/spm/proto/spm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ service SpmService {
// certificate.
rpc CreateKeyAndCert(pa.CreateKeyAndCertRequest)
returns (pa.CreateKeyAndCertResponse) {}

// DeriveSymmetricKey generates a symmetric key from the following inputs:
// - a seed type (that matches a seed pre-provisioned in the SPM),
// - a key type (raw or cSHAKE128 hashed OpenTitan LC token),
// - a size, and
// - a diversifier string.
rpc DeriveSymmetricKey(pa.DeriveSymmetricKeyRequest)
returns (pa.DeriveSymmetricKeyResponse) {}
}
97 changes: 80 additions & 17 deletions src/spm/services/spm.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,17 @@ type AuthConfig struct {
}

type Config struct {
Sku string `yaml:"sku"`
SlotID int `yaml:"slotId"`
NumSessions int `yaml:"numSessions"`
WrapKeyName string `yaml:"wrapKeyName"`
CaKeyName string `yaml:"caKeyName"`
CertTemplate []certloader.CertificateConfig `yaml:"certTemplate"`
CertTemplateSan certloader.CertificateSubjectAltName `yaml:"certTemplateSAN"`
Keys []certloader.Key `yaml:"keyWrapConfig"`
RootCaPath string `yaml:"rootCAPath"`
Sku string `yaml:"sku"`
SlotID int `yaml:"slotId"`
NumSessions int `yaml:"numSessions"`
WrapKeyName string `yaml:"wrapKeyName"`
HighSecSeedKeyName string `yaml:"highSecSeedKeyName"`
LowSecSeedKeyName string `yaml:"lowSecSeedKeyName"`
CaKeyName string `yaml:"caKeyName"`
CertTemplate []certloader.CertificateConfig `yaml:"certTemplate"`
CertTemplateSan certloader.CertificateSubjectAltName `yaml:"certTemplateSAN"`
Keys []certloader.Key `yaml:"keyWrapConfig"`
RootCaPath string `yaml:"rootCAPath"`
}

type skuState struct {
Expand Down Expand Up @@ -175,14 +177,10 @@ func (s *server) initSku(sku string) (string, error) {
log.Printf("failed to generate session token: %v", err)
return "", status.Errorf(codes.NotFound, "failed to generate session token: %v", err)
}

if strings.HasPrefix(sku, "tpm_") {
log.Printf("SPM.InitSession Response - TPM Token")
err = s.initializeSKU(sku)
if err != nil {
log.Printf("failed to initialize sku: %v", err)
return "", status.Errorf(codes.Internal, "failed to initialize sku")
}
err = s.initializeSKU(sku)
if err != nil {
log.Printf("failed to initialize sku: %v", err)
return "", status.Errorf(codes.Internal, "failed to initialize sku")
}
return token, nil
}
Expand Down Expand Up @@ -271,6 +269,69 @@ func (s *server) CreateKeyAndCert(ctx context.Context, request *pbp.CreateKeyAnd
}, nil
}

// DeriveSymmetricKey generates a symmetric key from a seed and diversification string.
func (s *server) DeriveSymmetricKey(ctx context.Context, request *pbp.DeriveSymmetricKeyRequest) (*pbp.DeriveSymmetricKeyResponse, error) {
// Acquire mutex before accessing SKU configuration.
s.muSKU.RLock()
defer s.muSKU.RUnlock()
sku, ok := s.skus[request.Sku]
if !ok {
return nil, status.Errorf(codes.NotFound,
"unable to find sku %q. Try calling InitSession first", request.Sku)
}

// Retrieve seed configuration.
var useHighSecSeed bool
if request.Seed == pbp.SymmetricKeySeed_SYMMETRIC_KEY_SEED_HIGH_SECURITY {
useHighSecSeed = true
} else if request.Seed == pbp.SymmetricKeySeed_SYMMETRIC_KEY_SEED_LOW_SECURITY {
useHighSecSeed = false
} else {
return nil, status.Errorf(codes.InvalidArgument,
"invalid key seed requested: %d", request.Seed)
}

// Retrieve key size.
var keySizeInBits uint
if request.Size == pbp.SymmetricKeySize_SYMMETRIC_KEY_SIZE_128_BITS {
keySizeInBits = 128
} else if request.Size == pbp.SymmetricKeySize_SYMMETRIC_KEY_SIZE_256_BITS {
keySizeInBits = 256
} else {
return nil, status.Errorf(codes.InvalidArgument,
"invalid key size requested: %d", request.Size)
}

// Retrieve key type.
var keyType uint
if request.Type == pbp.SymmetricKeyType_SYMMETRIC_KEY_TYPE_RAW {
keyType = se.SymmetricKeyTypeRaw
} else if request.Type == pbp.SymmetricKeyType_SYMMETRIC_KEY_TYPE_HASHED_OT_LC_TOKEN {
keyType = se.SymmetricKeyTypeHashedOtLcToken
} else {
return nil, status.Errorf(codes.InvalidArgument,
"invalid key type requested: %d", request.Type)
}

// Generate the symmetric key.
p := se.SymmetricKeygenParams{
UseHighSecuritySeed: useHighSecSeed,
KeyType: keyType,
SizeInBits: keySizeInBits,
Sku: request.Sku,
Diversifier: request.Diversifier,
}
keygenParams := []*se.SymmetricKeygenParams{&p}
keys, err := sku.seHandle.GenerateSymmetricKey(keygenParams)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not generate symmetric key: %s", err)
}

return &pbp.DeriveSymmetricKeyResponse{
Key: keys[0],
}, nil
}

func (s *server) initializeSKU(skuName string) error {
s.muSKU.Lock()
defer s.muSKU.Unlock()
Expand Down Expand Up @@ -318,6 +379,8 @@ func (s *server) initializeSKU(skuName string) error {
NumSessions: cfg.NumSessions,
KGName: cfg.WrapKeyName,
KcaName: cfg.CaKeyName,
KHsksName: cfg.HighSecSeedKeyName,
KLsksName: cfg.LowSecSeedKeyName,
HSMType: s.hsmType,
})
if err != nil {
Expand Down

0 comments on commit 9956b66

Please sign in to comment.