tillitis-key/hw/application_fpga/tools/tkeyimage/sigfile.go
Michael Cardell Widerkrantz 445c16feae tool: Support app1 in tkeyimage
Add support for an app in slot 1 and a signature for the same app.

- App digest and app signature is stored in the partition table
- The app is stored in app slot 1
- Two new flags are introduced: -app1 and -app1sig.
  - app1: The app binary
  - app1sig: A .sig file on a format similar the the files produced by
    tkey-sign. Signing algorithm is not checked, it is left to the app
    that will validate the signature to specify what algorithm to use.
- sigfile.go is imported from tkey-boot-verifier

Co-authored-by: Mikael Ågren <mikael@tillitis.se>
2025-12-03 15:41:00 +01:00

98 lines
2.1 KiB
Go

// SPDX-FileCopyrightText: 2023 Tillitis AB <tillitis.se>
// SPDX-License-Identifier: BSD-2-Clause
package main
import (
"bytes"
"encoding/base64"
"encoding/binary"
"fmt"
"os"
"strings"
)
type Signature struct {
Alg [2]byte
KeyNum [8]byte
Sig [64]byte
}
// ReadBase64 reads the file in filename with base64, decodes it and
// returns a binary representation
func ReadBase64(filename string) ([]byte, error) {
input, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
lines := strings.Split(string(input), "\n")
if len(lines) < 2 {
return nil, fmt.Errorf("too few lines in file %s", filename)
}
data, err := base64.StdEncoding.DecodeString(lines[1])
if err != nil {
return nil, fmt.Errorf("could not decode: %w", err)
}
return data, nil
}
func ReadSig(filename string) (*Signature, error) {
var sig Signature
buf, err := ReadBase64(filename)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
r := bytes.NewReader(buf)
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
return &sig, nil
}
// WriteBase64 encodes data in base64 and writes it the file given in
// filename. If overwrite is true it overwrites any existing file,
// otherwise it returns an error.
func WriteBase64(filename string, data any, comment string, overwrite bool) error {
var buf bytes.Buffer
err := binary.Write(&buf, binary.BigEndian, data)
if err != nil {
return fmt.Errorf("%w", err)
}
b64 := base64.StdEncoding.EncodeToString(buf.Bytes())
b64 += "\n"
var f *os.File
f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o666)
if err != nil {
if os.IsExist(err) && overwrite {
f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0o666)
if err != nil {
return fmt.Errorf("%w", err)
}
} else {
return fmt.Errorf("%w", err)
}
}
defer func() { _ = f.Close() }()
_, err = fmt.Fprintf(f, "untrusted comment: %s\n", comment)
if err != nil {
return fmt.Errorf("%w", err)
}
_, err = f.Write([]byte(b64))
if err != nil {
return fmt.Errorf("%w", err)
}
return nil
}