github.com/transparency-dev/armored-witness-os@v0.1.3-0.20240514084412-27eef7325168/trusted_os/usb_hid.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 "encoding/binary" 19 "unicode/utf16" 20 21 "github.com/gsora/fidati" 22 "github.com/gsora/fidati/u2fhid" 23 24 "github.com/usbarmory/tamago/soc/nxp/usb" 25 26 "github.com/transparency-dev/armored-witness-os/api" 27 ) 28 29 func configureDevice(device *usb.Device, serial string) (err error) { 30 // Supported Language Code Zero: English 31 device.SetLanguageCodes([]uint16{0x0409}) 32 33 // device descriptor 34 device.Descriptor = &usb.DeviceDescriptor{} 35 device.Descriptor.SetDefaults() 36 37 // p5, Table 1-1. Device Descriptor Using Class Codes for IAD, 38 // USB Interface Association Descriptor Device Class Code and Use Model. 39 device.Descriptor.DeviceClass = 0xef 40 device.Descriptor.DeviceSubClass = 0x02 41 device.Descriptor.DeviceProtocol = 0x01 42 43 device.Descriptor.VendorId = api.VendorID 44 device.Descriptor.ProductId = api.ProductID 45 46 device.Descriptor.Device = 0x0001 47 48 iManufacturer, _ := device.AddString(`WithSecure Foundry`) 49 device.Descriptor.Manufacturer = iManufacturer 50 51 iProduct, _ := device.AddString(`Armory Witness`) 52 device.Descriptor.Product = iProduct 53 54 iSerial, _ := device.AddString(serial) 55 device.Descriptor.SerialNumber = iSerial 56 57 conf := &usb.ConfigurationDescriptor{} 58 conf.SetDefaults() 59 60 if err = device.AddConfiguration(conf); err != nil { 61 return 62 } 63 64 // device qualifier 65 device.Qualifier = &usb.DeviceQualifierDescriptor{} 66 device.Qualifier.SetDefaults() 67 device.Qualifier.NumConfigurations = uint8(len(device.Configurations)) 68 69 return 70 } 71 72 func configureHID(device *usb.Device, ctl *controlInterface) (err error) { 73 // Windows blocks non-administrative access to FIDO devices, for this 74 // reason we override its standard usage page identifier with a custom 75 // one, which grants access. 76 binary.LittleEndian.PutUint16(u2fhid.DefaultReport[1:], api.HIDUsagePage) 77 78 hid, err := u2fhid.NewHandler(ctl) 79 80 if err != nil { 81 return 82 } 83 84 if err = fidati.ConfigureUSB(device.Configurations[0], device, hid); err != nil { 85 return 86 } 87 88 numInterfaces := len(device.Configurations[0].Interfaces) 89 90 // override interface name 91 var buf []byte 92 93 r := []rune("U2FHID interface descriptor") 94 u := utf16.Encode([]rune(r)) 95 96 for i := 0; i < len(u); i++ { 97 buf = append(buf, byte(u[i]&0xff)) 98 buf = append(buf, byte(u[i]>>8)) 99 } 100 101 interfaceName := device.Configurations[0].Interfaces[numInterfaces-1].Interface 102 copy(device.Strings[interfaceName][2:], buf) 103 104 // avoid conflict with Serial over USB 105 device.Configurations[0].Interfaces[numInterfaces-1].Endpoints[usb.OUT].EndpointAddress = 0x03 106 device.Configurations[0].Interfaces[numInterfaces-1].Endpoints[usb.IN].EndpointAddress = 0x83 107 108 if err = hid.AddMapping(api.U2FHID_ARMORY_INF, ctl.Status); err != nil { 109 return 110 } 111 112 if err = hid.AddMapping(api.U2FHID_ARMORY_CFG, ctl.Config); err != nil { 113 return 114 } 115 116 if err = hid.AddMapping(api.U2FHID_ARMORY_HAB, ctl.HAB); err != nil { 117 return 118 } 119 120 if err = hid.AddMapping(api.U2FHID_ARMORY_CONSOLE_LOGS, ctl.ConsoleLogs); err != nil { 121 return 122 } 123 if err = hid.AddMapping(api.U2FHID_ARMORY_CRASH_LOGS, ctl.CrashLogs); err != nil { 124 return 125 } 126 127 return 128 }