github.com/transparency-dev/armored-witness-os@v0.1.3-0.20240514084412-27eef7325168/trusted_os/main.go (about) 1 // Copyright 2022 The Armored Witness OS authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "bytes" 19 "crypto/sha256" 20 _ "embed" 21 "encoding/gob" 22 "fmt" 23 "log" 24 "os" 25 "runtime" 26 "strings" 27 "time" 28 29 "github.com/coreos/go-semver/semver" 30 usbarmory "github.com/usbarmory/tamago/board/usbarmory/mk2" 31 "github.com/usbarmory/tamago/soc/nxp/enet" 32 "github.com/usbarmory/tamago/soc/nxp/imx6ul" 33 "github.com/usbarmory/tamago/soc/nxp/usb" 34 "golang.org/x/mod/sumdb/note" 35 36 // for now just test compilation of these 37 "github.com/transparency-dev/armored-witness-common/release/firmware" 38 _ "github.com/transparency-dev/armored-witness-os/internal/hab" 39 _ "github.com/transparency-dev/armored-witness-os/rpmb" 40 ) 41 42 const ( 43 Build = "" 44 ) 45 46 // initialized at compile time (see Makefile) 47 var ( 48 Revision string 49 Version string 50 SRKHash string 51 LogVerifier string 52 LogOrigin string 53 AppletManifestVerifier string 54 OSManifestVerifier1 string 55 OSManifestVerifier2 string 56 ) 57 58 var ( 59 Control *usb.USB 60 61 // USB armory Mk II (rev. β) - UA-MKII-β 62 // USB armory Mk II (rev. γ) - UA-MKII-γ 63 USB *usb.USB 64 65 // USB armory Mk II LAN - UA-MKII-LAN 66 LAN *enet.ENET 67 68 // osVersion is the semver parsed representation of the Version string above. 69 osVersion semver.Version 70 // loadedAppletVersion is taken from the manifest used to verify the 71 // applet. 72 loadedAppletVersion semver.Version 73 74 AppletBundleVerifier firmware.BundleVerifier 75 OSBundleVerifier firmware.BundleVerifier 76 ) 77 78 // A Trusted Applet can be embedded for testing purposes with QEMU. 79 var ( 80 //go:embed assets/trusted_applet.elf 81 taELF []byte 82 83 //go:embed assets/trusted_applet.proofbundle 84 taProofBundle []byte 85 ) 86 87 func init() { 88 log.SetFlags(log.Ltime) 89 log.SetOutput(os.Stdout) 90 91 if imx6ul.Native { 92 imx6ul.SetARMFreq(imx6ul.Freq528) 93 94 if imx6ul.DCP != nil { 95 imx6ul.DCP.Init() 96 } 97 98 model, _ := usbarmory.Model() 99 100 switch model { 101 case usbarmory.BETA, usbarmory.GAMMA: 102 USB = usbarmory.USB1 103 USB.Init() 104 105 Control = usbarmory.USB2 106 Control.Init() 107 108 if debug { 109 debugConsole, _ := usbarmory.DetectDebugAccessory(250 * time.Millisecond) 110 <-debugConsole 111 } 112 case usbarmory.LAN: 113 LAN = usbarmory.ENET2 114 LAN.RingSize = 512 115 LAN.Init() 116 117 Control = usbarmory.USB1 118 Control.Init() 119 } 120 } else { 121 LAN = imx6ul.ENET1 122 LAN.RingSize = 512 123 LAN.Init() 124 } 125 126 imx6ul.GIC.Init(true, false) 127 128 log.Printf("%s/%s (%s) • TEE security monitor (Secure World system/monitor) • %s %s", 129 runtime.GOOS, runtime.GOARCH, runtime.Version(), 130 Revision, Build) 131 } 132 133 func main() { 134 // Increase default fuse-blowing timeout 135 if imx6ul.Native && imx6ul.OCOTP != nil { 136 imx6ul.OCOTP.Timeout = 100 * time.Millisecond 137 } 138 // Strip off v from GitTag so we can semver parse it. 139 Version = strings.TrimPrefix(Version, "v") 140 141 var err error 142 143 usbarmory.LED("blue", false) 144 usbarmory.LED("white", false) 145 146 Storage := storage() 147 if Storage != nil { 148 if err = Storage.Detect(); err != nil { 149 log.Fatalf("SM failed to detect storage, %v", err) 150 } 151 } 152 153 rpmb, err := newRPMB(Storage) 154 if err != nil { 155 log.Fatalf("SM could not initialize rollback protection, %v", err) 156 } 157 158 rpc := &RPC{ 159 RPMB: rpmb, 160 Storage: Storage, 161 Diversifier: sha256.Sum256([]byte(AppletManifestVerifier)), 162 } 163 164 ctl := &controlInterface{ 165 RPC: rpc, 166 SRKHash: SRKHash, 167 } 168 169 if imx6ul.Native && imx6ul.SNVS.Available() { 170 log.Printf("SM version verification (%s)", Version) 171 172 if err = rpmb.init(); err != nil { 173 log.Fatalf("SM could not initialize rollback protection, %v", err) 174 } 175 176 if err = rpmb.checkVersion(osVersionSector, Version); err != nil { 177 log.Fatalf("SM firmware rollback check failure, %v", err) 178 } 179 } 180 181 if err := determineLoadedOSBlock(Storage); err != nil { 182 log.Printf("Failed to determine OS MMC block (no OS installed?): %v", err) 183 } 184 185 log.Printf("SM log verification pub: %s", LogVerifier) 186 logVerifier, err := note.NewVerifier(LogVerifier) 187 if err != nil { 188 log.Fatalf("SM invalid AppletLogVerifier: %v", err) 189 } 190 log.Printf("SM applet verification pub: %s", AppletManifestVerifier) 191 AppletBundleVerifier, err = createBundleVerifier(LogOrigin, logVerifier, []string{AppletManifestVerifier}) 192 if err != nil { 193 log.Fatalf("SM failed to create applet bundle verifier: %v", err) 194 } 195 OSBundleVerifier, err = createBundleVerifier(LogOrigin, logVerifier, []string{OSManifestVerifier1, OSManifestVerifier2}) 196 if err != nil { 197 log.Fatalf("SM failed to create OS bundle verifier: %v", err) 198 } 199 200 if v, err := semver.NewVersion(Version); err != nil { 201 log.Printf("Failed to parse OS version %q: %v", Version, err) 202 } else { 203 osVersion = *v 204 } 205 206 var ta *firmware.Bundle 207 if len(taELF) > 0 && len(taProofBundle) > 0 { 208 // Handle embedded applet & proof. 209 dec := gob.NewDecoder(bytes.NewBuffer(taProofBundle)) 210 ta = &firmware.Bundle{} 211 if err := dec.Decode(ta); err != nil { 212 log.Printf("SM invalid embedded proof bundle: %v", err) 213 } 214 ta.Firmware = taELF 215 } else { 216 if ta, err = read(Storage); err != nil { 217 log.Printf("SM could not load applet, %v", err) 218 } 219 } 220 221 if ta != nil { 222 go func() { 223 for { 224 log.Print("SM Verifying applet bundle") 225 manifest, err := AppletBundleVerifier.Verify(*ta) 226 if err != nil { 227 log.Printf("SM applet verification error, %v", err) 228 } 229 loadedAppletVersion = manifest.Git.TagName 230 log.Printf("SM Loaded applet version %s", loadedAppletVersion.String()) 231 232 usbarmory.LED("white", true) 233 234 appletCtx, err := loadApplet(ta.Firmware, ctl) 235 if err != nil { 236 log.Printf("SM applet execution error, %v", err) 237 } 238 239 <-appletCtx.Done() 240 if err := storeAppletCrashLog(Storage, getConsoleLogs()); err != nil { 241 log.Printf("Failed to store ringbuffer logs: %v", err) 242 } 243 } 244 }() 245 } 246 247 go func() { 248 l := true 249 for { 250 usbarmory.LED("white", l) 251 l = !l 252 time.Sleep(500 * time.Millisecond) 253 } 254 }() 255 256 if imx6ul.Native { 257 // start USB control interface 258 ctl.Start() 259 } 260 261 // never returns 262 handleInterrupts() 263 } 264 265 func createBundleVerifier(logOrigin string, logVerifier note.Verifier, manifestVerifiers []string) (firmware.BundleVerifier, error) { 266 vs := []note.Verifier{} 267 for _, v := range manifestVerifiers { 268 nv, err := note.NewVerifier(v) 269 if err != nil { 270 return firmware.BundleVerifier{}, fmt.Errorf("invalid manifest verifier %q: %v", v, err) 271 } 272 vs = append(vs, nv) 273 } 274 bv := firmware.BundleVerifier{ 275 LogOrigin: logOrigin, 276 LogVerifer: logVerifier, 277 ManifestVerifiers: vs, 278 } 279 return bv, nil 280 }