github.com/google/trillian-examples@v0.0.0-20240520080811-0d40d35cef0e/binary_transparency/firmware/devices/usbarmory/bootloader/conf.go (about) 1 // https://github.com/usbarmory/armory-boot 2 // 3 // Copyright (c) F-Secure Corporation 4 // https://foundry.f-secure.com 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 //go:build armory 10 // +build armory 11 12 package main 13 14 import ( 15 "encoding/json" 16 "errors" 17 "fmt" 18 "log" 19 ) 20 21 const defaultConfigPath = "/boot/armory-boot.conf" 22 const signatureSuffix = ".sig" 23 24 var conf Config 25 26 type Config struct { 27 // Kernel is the path to a Linux kernel image. 28 Kernel []string `json:"kernel"` 29 30 // DeviceTreeBlob is the path to a Linux DTB file. 31 DeviceTreeBlob []string `json:"dtb"` 32 33 // CmdLine is the Linux kernel command-line parameters. 34 CmdLine string `json:"cmdline"` 35 36 // Unikernel is the path to an ELF unikernel image. 37 Unikernel []string `json:"unikernel"` 38 39 partition *Partition 40 conf []byte 41 42 kernel []byte 43 kernelHash string 44 45 params []byte 46 paramsHash string 47 48 elf bool 49 } 50 51 func (c *Config) Init(p *Partition, configPath string) (err error) { 52 log.Printf("armory-boot: reading configuration at %s\n", configPath) 53 54 c.partition = p 55 c.conf, err = p.ReadAll(configPath) 56 57 return 58 } 59 60 func (c *Config) Verify(sigPath string, pubKey string) (err error) { 61 sig, err := c.partition.ReadAll(sigPath) 62 63 if err != nil { 64 return fmt.Errorf("invalid signature path, %v", err) 65 } 66 67 return verifySignature(c.conf, sig, pubKey) 68 } 69 70 func (c *Config) Load() (err error) { 71 err = json.Unmarshal(c.conf, &c) 72 73 if err != nil { 74 return 75 } 76 77 ul, kl := len(conf.Unikernel), len(conf.Kernel) 78 isUnikernel, isKernel := ul > 0, kl > 0 79 80 if isUnikernel == isKernel { 81 return errors.New("must specify either unikernel or kernel") 82 } 83 84 var kernelPath string 85 86 switch { 87 case isKernel: 88 if kl != 2 { 89 return errors.New("invalid kernel parameter size") 90 } 91 92 if len(conf.DeviceTreeBlob) != 2 { 93 return errors.New("invalid dtb parameter size") 94 } 95 96 kernelPath = conf.Kernel[0] 97 c.kernelHash = conf.Kernel[1] 98 case isUnikernel: 99 if ul != 2 { 100 return errors.New("invalid unikernel parameter size") 101 } 102 103 kernelPath = conf.Unikernel[0] 104 c.kernelHash = conf.Unikernel[1] 105 } 106 107 c.Print() 108 109 c.kernel, err = c.partition.ReadAll(kernelPath) 110 111 if err != nil { 112 return fmt.Errorf("invalid path %s, %v\n", kernelPath, err) 113 } 114 115 if isUnikernel { 116 c.elf = true 117 return 118 } 119 120 c.paramsHash = conf.DeviceTreeBlob[1] 121 c.params, err = c.partition.ReadAll(conf.DeviceTreeBlob[0]) 122 123 if err != nil { 124 return fmt.Errorf("invalid path %s, %v\n", conf.DeviceTreeBlob[0], err) 125 } 126 127 return 128 } 129 130 func (c *Config) Print() { 131 j, _ := json.MarshalIndent(c, "", "\t") 132 log.Printf("\n%s", string(j)) 133 }