-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy patharmoryctl.go
274 lines (226 loc) · 6.76 KB
/
armoryctl.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
// armoryctl | https://github.com/usbarmory/armoryctl
//
// USB armory Mk II - hardware control tool
// Copyright (c) WithSecure Corporation
//
// Use of this source code is governed by the license
// that can be found in the LICENSE file.
//
// +build linux
package main
import (
"errors"
"flag"
"fmt"
"log"
"os"
"os/user"
"path/filepath"
"regexp"
"github.com/usbarmory/armoryctl/anna_b112"
"github.com/usbarmory/armoryctl/atecc608"
"github.com/usbarmory/armoryctl/fusb303"
"github.com/usbarmory/armoryctl/internal"
"github.com/usbarmory/armoryctl/led"
"github.com/usbarmory/armoryctl/pf1510"
"github.com/usbarmory/armoryctl/tusb320"
)
type Config struct {
debug bool
force bool
logger *log.Logger
}
var conf *Config
const warning = `
████████████████████████████████████████████████████████████████████████████████
** WARNING **
This tool is only meant to be used on USB armory Mk II hardware, execution on
any other hardware is unsupported and can lead to irreversible damage.
The use of this tool is therefore **at your own risk**.
████████████████████████████████████████████████████████████████████████████████
`
const commandUsage = `
LED control
led (white|blue) (on|off)
Type-C plug port controller (TUSB320)
tusb id # read controller identifier
tusb current_mode # read advertised current
Type-C receptacle port controller (FUSB303)
fusb id # read controller identifier
fusb current_mode # read advertised current
fusb enable # enable the controller
fusb disable # disable the controller
Bluetooth module (ANNA-B112)
ble info # read device information
ble enable # set visible peripheral BLE role
ble disable # disable BLE communication
ble reset # reset the module
ble bootloader_mode # switch to bootloader mode
ble normal_mode # switch to normal operation
ble rc_lfck (flash|at) # set LF clock source to internal RC oscillator
ble update <firmware path> # module firmware update
ble name <device name> # set device name
Secure Element (ATECC608A/ATECC608B)
atecc info # read device information
atecc self_test # execute self test procedure
Power Management Integrated Circuit (PF1510)
pmic info # read device information
`
func init() {
log.SetOutput(os.Stdout)
log.SetFlags(0)
conf = &Config{
logger: log.New(os.Stdout, log.Prefix(), log.Flags()),
}
cachePath := ""
usr, err := user.Current()
if err == nil {
cachePath = filepath.Join(usr.HomeDir, ".armoryctl")
}
flag.Usage = func() {
tags := ""
if armoryctl.Revision != "" && armoryctl.Build != "" {
tags = fmt.Sprintf("%s (%s)", armoryctl.Revision, armoryctl.Build)
}
log.Printf("USB armory Mk II hardware control tool\n%s\n", tags)
log.Print(warning)
log.Printf("Usage: armoryctl [options] [command]\n")
flag.PrintDefaults()
log.Print(commandUsage)
}
flag.BoolVar(&conf.debug, "d", false, "debug")
flag.BoolVar(&conf.force, "f", false, "skip hardware check and force execution")
flag.StringVar(&anna_b112.CachePath, "c", cachePath, "ANNA-B112 firmware cache path")
flag.StringVar(&anna_b112.OpenOCDPath, "x", anna_b112.OpenOCDPath, "OpenOCD lookpath")
flag.StringVar(&anna_b112.UARTPath, "u", anna_b112.UARTPath, "ANNA-B112 UART path")
flag.IntVar(&anna_b112.UARTSpeed, "s", anna_b112.UARTSpeed, "ANNA-B112 UART speed")
flag.IntVar(&atecc608.I2CBus, "i", atecc608.I2CBus, "ATECC608 I2C bus number")
flag.IntVar(&atecc608.I2CAddress, "l", atecc608.I2CAddress, "ATECC608 I2C address")
flag.IntVar(&fusb303.I2CBus, "m", fusb303.I2CBus, "FUSB303 I2C bus number")
flag.IntVar(&fusb303.I2CAddress, "n", fusb303.I2CAddress, "FUSB303 I2C address")
flag.IntVar(&tusb320.I2CBus, "o", tusb320.I2CBus, "TUSB320 I2C bus number")
flag.IntVar(&tusb320.I2CAddress, "p", tusb320.I2CAddress, "TUSB320 I2C address")
flag.IntVar(&pf1510.I2CBus, "q", pf1510.I2CBus, "PF1510 I2C bus number")
flag.IntVar(&pf1510.I2CAddress, "r", pf1510.I2CAddress, "PF1510 I2C address")
}
func checkModel() (match bool) {
model, _ := os.ReadFile("/proc/device-tree/model")
match, _ = regexp.Match("F-Secure USB armory Mk II", model)
return
}
func invalid() {
flag.Usage()
log.Fatalf("error: invalid command given")
}
func main() {
var err error
var res string
defer func() {
if err != nil {
log.Fatalf("error: %v", err)
}
if len(res) != 0 {
log.Printf("%s", res)
}
}()
flag.Parse()
if len(flag.Args()) < 2 {
flag.Usage()
err = errors.New("no valid command given")
return
}
if !conf.force && !checkModel() {
err = errors.New("this tool is only meant to be used on USB armory Mk II hardware")
return
}
if conf.debug {
armoryctl.Logger = conf.logger
}
device := flag.Arg(0)
command := flag.Arg(1)
op := fmt.Sprintf("%s %s", device, command)
switch op {
case "led white", "led blue":
if len(flag.Args()) < 3 {
invalid()
}
switch flag.Arg(2) {
case "on":
err = led.Set(command, true)
case "off":
err = led.Set(command, false)
default:
invalid()
}
case "tusb id":
var id []byte
id, err = tusb320.GetDeviceID()
if err == nil {
res = string(id)
}
case "fusb id":
var id []byte
id, err = fusb303.GetDeviceID()
if err == nil {
res = fmt.Sprintf("0x%x", id)
}
case "tusb current_mode":
var mode byte
mode, err = tusb320.GetCurrentMode()
if err == nil {
res = tusb320.CurrentMode[mode]
}
case "fusb current_mode":
var mode byte
mode, err = fusb303.GetCurrentMode()
if err == nil {
res = fusb303.CurrentMode[mode]
}
case "fusb enable":
err = fusb303.Enable()
case "fusb disable":
err = fusb303.Disable()
case "ble info":
res, err = anna_b112.Info()
case "ble enable":
err = anna_b112.Enable()
case "ble disable":
err = anna_b112.Disable()
case "ble reset":
err = anna_b112.Reset()
case "ble bootloader_mode":
err = anna_b112.EnterBootloaderMode()
case "ble normal_mode":
err = anna_b112.EnterNormalMode()
case "ble rc_lfck":
if len(flag.Args()) < 3 {
invalid()
}
switch flag.Arg(2) {
case "at":
err = anna_b112.ATSetInternalRCLFCK()
case "flash":
err = anna_b112.FlashSetInternalRCLFCK()
default:
invalid()
}
case "ble update":
if len(flag.Args()) < 3 {
invalid()
}
err = anna_b112.Update(flag.Arg(2))
case "ble name":
if len(flag.Args()) < 3 {
invalid()
}
err = anna_b112.SetDeviceName(flag.Arg(2))
case "atecc info":
res, err = atecc608.Info()
case "atecc self_test":
res, err = atecc608.SelfTest()
case "pmic info":
res, err = pf1510.Info()
default:
invalid()
}
}