Files
story/cmd/firmware-sign/main.go
T

54 lines
1.5 KiB
Go
Raw Normal View History

2026-08-26 06:41:07 +08:00
package main
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"os"
)
type signedFirmware struct {
PublicKeyBase64 string `json:"public_key_base64"`
SignatureBase64 string `json:"signature_base64"`
SHA256 string `json:"sha256"`
Size int `json:"size"`
Manifest string `json:"manifest"`
}
func main() {
if len(os.Args) != 5 {
fmt.Fprintln(os.Stderr, "usage: firmware-sign <model> <hardware-revision> <version> <file>")
os.Exit(2)
}
content, err := os.ReadFile(os.Args[4])
if err != nil {
panic(err)
}
result, err := signFirmware(os.Args[1], os.Args[2], os.Args[3], content)
if err != nil {
panic(err)
}
if err := json.NewEncoder(os.Stdout).Encode(result); err != nil {
panic(err)
}
}
func signFirmware(model, hardwareRevision, version string, content []byte) (signedFirmware, error) {
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return signedFirmware{}, err
}
digest := sha256.Sum256(content)
digestText := hex.EncodeToString(digest[:])
manifest := fmt.Sprintf("firmware-manifest-v1\nmodel=%s\nhardware_revision=%s\nversion=%s\nsha256=%s\nsize=%d\n", model, hardwareRevision, version, digestText, len(content))
return signedFirmware{
PublicKeyBase64: base64.StdEncoding.EncodeToString(publicKey),
SignatureBase64: base64.StdEncoding.EncodeToString(ed25519.Sign(privateKey, []byte(manifest))),
SHA256: digestText, Size: len(content), Manifest: manifest,
}, nil
}