Skip to content

Commit

Permalink
Modify hss-file param in hss gathering to also accept directory paths
Browse files Browse the repository at this point in the history
This makes argument passing easier for platform abstracted content. Non uniform HSS gathering can be dumped into a standard directory, eg. /hss

Signed-off-by: Colin Mitchell <[email protected]>
  • Loading branch information
colinmitchell-ggl committed Jul 30, 2024
1 parent 18acf51 commit dfaeea7
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 12 deletions.
2 changes: 1 addition & 1 deletion cmds/exp/disk_unlock/disk_unlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (
retries = flag.Int("num_retries", 1, "Number of times to retry password if unlocking fails for any reason other than the password being wrong.")
salt = flag.String("salt", hsskey.DefaultPasswordSalt, "Salt for password generation")
eepromPattern = flag.String("eeprom-pattern", "", "The pattern used to match EEPROM sysfs paths where the Host Secret Seeds are located")
hssFiles = flag.String("hss-files", "", "Comma deliminated paths to files containing a Host Secret Seed (HSS) to use")
hssFiles = flag.String("hss-files", "", "Comma deliminated list of files or directories containing additional Host Secret Seed (HSS)")
)

func verboseLog(msg string) {
Expand Down
2 changes: 1 addition & 1 deletion cmds/exp/nvme_unlock/nvme_unlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (
lock = flag.Bool("lock", false, "Lock instead of unlocking")
salt = flag.String("salt", hsskey.DefaultPasswordSalt, "Salt for password generation")
eepromPattern = flag.String("eeprom-pattern", "", "The pattern used to match EEPROM sysfs paths where the Host Secret Seeds are located")
hssFiles = flag.String("hss-files", "", "Comma deliminated paths to files containing a Host Secret Seed (HSS) to use")
hssFiles = flag.String("hss-files", "", "Comma deliminated list of files or directories containing additional Host Secret Seed (HSS)")
)

func verboseLog(msg string) {
Expand Down
64 changes: 54 additions & 10 deletions pkg/hsskey/hsskey.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"

"github.com/u-root/u-root/pkg/ipmi"
Expand Down Expand Up @@ -78,7 +80,7 @@ func getHssFromIpmi(warnings io.Writer, verboseDangerous bool) ([][]uint8, error

blobCount, err := h.BlobGetCount()
if err != nil {
return nil, fmt.Errorf("failed to get blob count: %v", err)
return nil, fmt.Errorf("failed to get blob count: %w", err)
}

hssLists := [][][]uint8{}
Expand Down Expand Up @@ -117,7 +119,7 @@ func getHssFromIpmi(warnings io.Writer, verboseDangerous bool) ([][]uint8, error
}

if warnings != nil && verboseDangerous {
io.WriteString(warnings, fmt.Sprintf("HSS Entry: Id=%s, Seed=%x\n", id, hss))
fmt.Fprintf(warnings, "HSS Entry: Id=%s, Seed=%x\n", id, hss)
}

hssLists[prefixIdx] = append(hssLists[prefixIdx], hss)
Expand Down Expand Up @@ -148,30 +150,40 @@ func GetAllHss(warnings io.Writer, verboseDangerous bool, eepromPattern string,
// Attempt to get HSS from IPMI.
hssList, err := getHssFromIpmi(warnings, verboseDangerous)
if err != nil || len(hssList) == 0 {
io.WriteString(warnings, fmt.Sprintf("Failed to get HSS key from IPMI: %v\n", err))
fmt.Fprintf(warnings, "Failed to get HSS key from IPMI: %v\n", err)
}

// Attempt to get HSS from EEPROM.
if eepromPattern != "" {
filePaths, err := getHssEepromPaths(baseSysfsPattern, eepromPattern)
if err != nil {
io.WriteString(warnings, fmt.Sprintf("Failed to find HSS EEPROM paths: %v\n", err))
fmt.Fprintf(warnings, "Failed to find HSS EEPROM paths: %v\n", err)
}
hssEeprom, err := GetHssFromFile(warnings, verboseDangerous, filePaths, hostSecretSeedCount)
if err == nil && len(hssEeprom) > 0 {
hssList = append(hssList, hssEeprom...)
} else {
io.WriteString(warnings, fmt.Sprintf("Failed to get HSS key from file: %v\n", err))
fmt.Fprintf(warnings, "Failed to get HSS key from file: %v\n", err)
}
}

// Attempt to get HSS from files.
if hssFiles != "" {
hssFileArr := strings.Split(hssFiles, ",")
hss, err := GetHssFromFile(warnings, verboseDangerous, hssFileArr, 0)
if err != nil {
io.WriteString(warnings, fmt.Sprintf("Error parsing file %s for HSS: %v\n", hss, err))
hssFileArr := []string{}
// Parse if list of paths were given.
for _, hssFile := range strings.Split(strings.TrimSpace(hssFiles), ",") {
hssFile, err := evaluateHssPath(hssFile)
if err != nil {
fmt.Fprintf(warnings, "Error parsing path %s for file: %v\n", hssFile, err)
}
hssFileArr = append(hssFileArr, hssFile...)
}
if len(hss) > 0 {

if len(hssFileArr) > 0 {
hss, err := GetHssFromFile(warnings, verboseDangerous, hssFileArr, 0)
if err != nil {
fmt.Fprintf(warnings, "Error parsing files %s for HSS: %v\n", hss, err)
}
hssList = append(hssList, hss...)
}
}
Expand All @@ -182,6 +194,38 @@ func GetAllHss(warnings io.Writer, verboseDangerous bool, eepromPattern string,
return nil, fmt.Errorf("failed all HSS retrieval attempts")
}

// evaluateHssPath evaluates a filepath to return the file or contents if a directory.
// This function evaluates the base pointer for symlinks.
func evaluateHssPath(hssFiles string) ([]string, error) {
// Follow symlink if needed.
hssFiles, err := filepath.EvalSymlinks(hssFiles)
if err != nil {
return nil, fmt.Errorf("failed evaluating HSS path: %w", err)
}

hssFileArr := []string{}

fi, err := os.Stat(hssFiles)
if err != nil {
return nil, fmt.Errorf("failed to stat HSS files: %w", err)
}

// Check if hssFiles is a directory or a file. Add all regular files in the base directory.
switch mode := fi.Mode(); {
case mode.IsDir():
filepath.Walk(hssFiles, func(fpath string, info os.FileInfo, _ error) error {
if info.Mode().IsRegular() {
hssFileArr = append(hssFileArr, fpath)
}
return nil
})
case mode.IsRegular():
hssFileArr = append(hssFileArr, hssFiles)
}

return hssFileArr, nil
}

// GenPassword computes the password deterministically as the 32-byte HDKF-SHA256 of the
// HSS plus the device identity.
func GenPassword(hss []byte, salt string, identifiers ...string) ([]byte, error) {
Expand Down

0 comments on commit dfaeea7

Please sign in to comment.