Skip to content

Commit

Permalink
[spmutil] add KDF seed loading subcommands
Browse files Browse the repository at this point in the history
This adds KDF seed loading subcommands to support the KDF operations
that will be used to generate OpenTitan Earlgrey LC tokens and Wafer
Auth Secrets during provisioning.

This partially addresses lowRISC#4.

Signed-off-by: Tim Trippel <[email protected]>
  • Loading branch information
timothytrippel committed Oct 1, 2024
1 parent 0536d38 commit 6eb099f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
16 changes: 14 additions & 2 deletions docs/spm.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@ $ bazelisk run //src/spm:spmutil -- \
--hsm_so=${OPENTITAN_VAR_DIR}/softhsm2/libsofthsm2.so \
--hsm_type=0 \
--hsm_slot=0 \
--force_keygen --gen_kg --gen_kca \
--force_keygen \
--gen_kg \
--gen_kca \
--load_low_sec_ks \
--low_sec_ks="0x23df79a8052010ef6e3d49255b606f871cff06170247c1145ebb71ad23834061" \
--load_high_sec_ks \
--high_sec_ks="0xaba9d5616e5a7c18b9a41d8a22f42d4dc3bafa9ca1fad01e404e708b1eab21fd" \
--ca_outfile=${OPENTITAN_VAR_DIR}/spm/config/certs/NuvotonTPMRootCA0200.cer
```

Expand All @@ -114,7 +120,13 @@ $ bazelisk run //src/spm:spmutil -- \
--hsm_so=/usr/safenet/lunaclient/lib/libCryptoki2_64.so \
--hsm_type=1 \
--hsm_slot=0 \
--force_keygen --gen_kg --gen_kca \
--force_keygen \
--gen_kg \
--gen_kca \
--load_low_sec_ks \
--low_sec_ks="0x23df79a8052010ef6e3d49255b606f871cff06170247c1145ebb71ad23834061" \
--load_high_sec_ks \
--high_sec_ks="0xaba9d5616e5a7c18b9a41d8a22f42d4dc3bafa9ca1fad01e404e708b1eab21fd" \
--ca_outfile=${OPENTITAN_VAR_DIR}/spm/config/certs/NuvotonTPMRootCA0200.cer
```

Expand Down
8 changes: 7 additions & 1 deletion run_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ bazelisk run //src/spm:spmutil -- \
--hsm_so=${OPENTITAN_VAR_DIR}/softhsm2/libsofthsm2.so \
--hsm_type=0 \
--hsm_slot=0 \
--force_keygen --gen_kg --gen_kca \
--force_keygen \
--gen_kg \
--gen_kca \
--load_low_sec_ks \
--low_sec_ks="0x23df79a8052010ef6e3d49255b606f871cff06170247c1145ebb71ad23834061" \
--load_high_sec_ks \
--high_sec_ks="0xaba9d5616e5a7c18b9a41d8a22f42d4dc3bafa9ca1fad01e404e708b1eab21fd" \
--ca_outfile=${OPENTITAN_VAR_DIR}/spm/config/certs/NuvotonTPMRootCA0200.cer

bazelisk run //src/pa:loadtest -- \
Expand Down
1 change: 1 addition & 0 deletions src/pk11/kdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ func (s *Session) ImportKeyMaterial(key []byte, opts *KeyOptions) (SecretKey, er
pkcs11.NewAttribute(pkcs11.CKA_DERIVE, true),
pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, !opts.Extractable),
pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, opts.Extractable),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, opts.Token),
}
s.tok.m.appendAttrKeyID(&tpl)

Expand Down
69 changes: 68 additions & 1 deletion src/spm/spmutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"crypto/elliptic"
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
"errors"
"flag"
"fmt"
Expand All @@ -31,13 +32,19 @@ var (
hsmSlot = flag.Int("hsm_slot", 0, "The HSM slot number; required")
genKG = flag.Bool("gen_kg", false, "Generate KG; optional")
genKCA = flag.Bool("gen_kca", false, "Generate KCA; optional")
forceKeygen = flag.Bool("force_keygen", false, "Destroy existing keys before keygen; optional")
loadHighSecKS = flag.Bool("load_high_sec_ks", false, "Load high security KDF seed; optional")
loadLowSecKS = flag.Bool("load_low_sec_ks", false, "Load low security KDF seed; optional")
forceKeygen = flag.Bool("force_keygen", false, "Destroy existing keys and seeds before keygen; optional")
caCertOutputPath = flag.String("ca_outfile", "", "CA output path; required when --gen_kca is set to true")
highSecKS = flag.String("high_sec_ks", "", "High security key seed; required when --load_high_sec_ks is set to true")
lowSecKS = flag.String("low_sec_ks", "", "Low security key seed; required when --load_low_sec_ks is set to true")
version = flag.Bool("version", false, "Print version information and exit")
)

const (
kgName = "KG"
hsksName = "HighSecKdfSeed"
lsksName = "LowSecKdfSeed"
kcaPrivName = "KCAPriv"
kcaPubName = "KCAPub"
)
Expand All @@ -60,6 +67,8 @@ func DestroyKeys(session *pk11.Session) error {
label string
}{
{pk11.ClassSecretKey, kgName},
{pk11.ClassSecretKey, hsksName},
{pk11.ClassSecretKey, lsksName},
{pk11.ClassPrivateKey, kcaPrivName},
{pk11.ClassPublicKey, kcaPubName},
}
Expand Down Expand Up @@ -101,6 +110,62 @@ func GenerateKG(session *pk11.Session) error {
return nil
}

// loadKdfSeed loads a secret seed that may be used to derive symmetric keys
// from during the provisioning flow.
func loadKdfSeed(session *pk11.Session, seedName string, seed []byte) error {
// Skip seed load if there is a seed with the same name already available.
if _, err := session.FindKeyByLabel(pk11.ClassSecretKey, seedName); err == nil {
log.Printf("KDF seed with label %q already exists.", seedName)
return nil
}

// Load the seed into the HSM.
kdfSeed, err := session.ImportKeyMaterial(seed, &pk11.KeyOptions{
Extractable: false,
Token: true,
})
if err != nil {
return fmt.Errorf("failed to load KDF seed, error: %v", err)
}

// Set a label name on the seed.
if err := kdfSeed.SetLabel(seedName); err != nil {
return fmt.Errorf("failed to set KDF seed label %q, error: %v", seedName, err)
}

return nil
}

// LoadHighSecKdfSeed loads a high security secret seed that may be used to
// derive symmetric keys from during the provisioning flow. This seed is
// expected to be rotated frequently.
func LoadHighSecKdfSeed(session *pk11.Session) error {
if *highSecKS == "" {
return errors.New("--high_sec_ks flag not set")
}
seed, _ := hex.DecodeString(*highSecKS)
err := loadKdfSeed(session, hsksName, seed)
if err != nil {
return fmt.Errorf("failed to load high security KDF seed: %q", seed)
}
return nil
}

// LoadLowSecKdfSeed loads a low security secret seed that may be used to derive
// symmetric keys from during the provisioning flow. This seed is NOT expected
// to be rotated frequently.
func LoadLowSecKdfSeed(session *pk11.Session) error {
if *lowSecKS == "" {
return errors.New("--low_sec_ks flag not set")
}
seed, _ := hex.DecodeString(*lowSecKS)
err := loadKdfSeed(session, lsksName, seed)
if err != nil {
return fmt.Errorf("failed to load low security KDF seed: %q", seed)
}
return nil
}

// buildCACert returns a root CA certificate template.
func buildCACert(session *pk11.Session) (*x509.Certificate, error) {
serialNumber, err := session.GenerateRandom(10)
Expand Down Expand Up @@ -221,6 +286,8 @@ func main() {
{"Removing previous keys", *forceKeygen, DestroyKeys},
{"Generating KG", *genKG, GenerateKG},
{"Generating KCA", *genKCA, GenerateKCA},
{"Loading high security KDF seed", *loadHighSecKS, LoadHighSecKdfSeed},
{"Loading low security KDF seed", *loadLowSecKS, LoadLowSecKdfSeed},
} {
if !task.run {
continue
Expand Down

0 comments on commit 6eb099f

Please sign in to comment.