/
ums.go
94 lines (72 loc) · 1.91 KB
/
ums.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
// Copyright (c) WithSecure Corporation
// https://foundry.withsecure.com
//
// use of this source code is governed by the license
// that can be found in the license file.
package ums
import (
"github.com/usbarmory/armory-drive/api"
"github.com/usbarmory/armory-drive/internal/crypto"
usbarmory "github.com/usbarmory/tamago/board/usbarmory/mk2"
"github.com/usbarmory/tamago/soc/nxp/usdhc"
)
const (
// exactly 8 bytes required
VendorID = "F-Secure"
// exactly 16 bytes required
ProductID = "USB armory Mk II"
// exactly 4 bytes required
ProductRevision = "1.00"
)
type Card interface {
Detect() error
Info() usdhc.CardInfo
ReadBlocks(int, []byte) error
WriteBlocks(int, []byte) error
}
// Drive represents an encrypted drive instance.
type Drive struct {
// Cipher controls whether FDE should be applied
Cipher bool
// Keyring instance
Keyring *crypto.Keyring
// Ready represents the logical device status
Ready bool
// PairingComplete signals pairing completion
PairingComplete chan bool
// Mult is the block multiplier
Mult int
// Card represents the underlying storage instance
card Card
// send is the queue for IN device responses
send chan []byte
// free is the queue for IN device DMA buffers for later release
free chan uint
// dataPending is the buffer for write commands which spawn across
// multiple USB transfers
dataPending *writeOp
}
func (d *Drive) Init(card Card) (err error) {
if err = card.Detect(); err != nil {
return
}
d.card = card
d.PairingComplete = make(chan bool)
d.send = make(chan []byte, 2)
d.free = make(chan uint, 1)
return
}
func (d *Drive) Capacity() uint64 {
info := d.card.Info()
return uint64(info.Blocks) * uint64(info.BlockSize)
}
func (d *Drive) Lock() (err error) {
// invalidate the drive
d.Ready = false
// clear FDE key
if err = d.Keyring.SetCipher(api.Cipher_NONE, nil); err != nil {
return
}
usbarmory.LED("white", false)
return
}