Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[spmutil] add KDF seed loading subcommands #23

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading