/
rfid_password_provider.go
147 lines (122 loc) · 3.02 KB
/
rfid_password_provider.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
package pass
import (
"fmt"
"time"
"periph.io/x/periph/conn/gpio/gpioreg"
"periph.io/x/periph/conn/spi/spireg"
"periph.io/x/periph/experimental/devices/mfrc522"
"periph.io/x/periph/experimental/devices/mfrc522/commands"
)
type RFID struct {
rfid *mfrc522.Dev
currentPass string
cardKey [6]byte
pwdSector, pwdBlock int
currentPassOk bool
}
var ZeroKey = [...]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
var defaultKey = [...]byte{0xca, 0xfe, 0xba, 0xbe, 0, 0}
const (
//resetPinStr = "13"
//irqPinStr = "12"
resetPinStr = "27"
irqPinStr = "17"
)
type config struct {
resetPin, irqPin string
}
var defaultConfig = config{
resetPin: "27",
irqPin: "17",
}
type PinConfF func(*config) *config
func WithResetPin(pin string) PinConfF {
return func(c *config) *config {
c.resetPin = pin
return c
}
}
func WithIRQPin(pin string) PinConfF {
return func(c *config) *config {
c.irqPin = pin
return c
}
}
func NewRFIDPass(cardKey [6]byte, pwdSector, pwdBlock int, confs ...PinConfF) (*RFID, error) {
dev, err := spireg.Open("")
if err != nil {
return nil, err
}
c := defaultConfig
{
cc := &c
for _, f := range confs {
cc = f(cc)
}
c = *cc
}
resetPin := gpioreg.ByName(c.resetPin)
if resetPin == nil {
return nil, fmt.Errorf("can't open reset pin")
}
irqPin := gpioreg.ByName(c.irqPin)
if irqPin == nil {
return nil, fmt.Errorf("can't open irq pin")
}
nr, err := mfrc522.NewSPI(dev, resetPin, irqPin)
if err != nil {
return nil, err
}
return &RFID{
rfid: nr,
cardKey: cardKey,
pwdBlock: pwdBlock,
pwdSector: pwdSector,
}, nil
}
var (
edgeTimeout = 2 * time.Second
readTimeout = 5 * time.Second
)
func (r *RFID) GetCurrentPassword() ([]byte, error) {
if err := r.rfid.LowLevel.WaitForEdge(edgeTimeout); err != nil {
return nil, err
}
pwd, err := r.rfid.ReadCard(readTimeout, commands.PICC_AUTHENT1A, r.pwdSector, r.pwdBlock, r.cardKey)
if err != nil {
return nil, err
}
return pwd, nil
}
func (r *RFID) ResetAccessKey(newKeyArr [6]byte, sector int) error {
if err := r.rfid.LowLevel.WaitForEdge(edgeTimeout); err != nil {
return err
}
fmt.Printf("Card key %v => %v\n", r.cardKey, newKeyArr)
return r.rfid.WriteSectorTrail(readTimeout, commands.PICC_AUTHENT1A, sector, newKeyArr, newKeyArr,
&mfrc522.BlocksAccess{
B0: mfrc522.AnyKeyRWID,
B1: mfrc522.AnyKeyRWID,
B2: mfrc522.AnyKeyRWID,
B3: mfrc522.KeyA_RN_WA_BITS_RA_WA_KeyB_RA_WA,
}, r.cardKey)
}
func (r *RFID) ResetPassword(newPassword []byte, sector, block int) error {
if len(newPassword) != 16 {
return fmt.Errorf("Password length must be of size 16 - found %d", len(newPassword))
}
var pwdArr [16]byte
for i, v := range newPassword {
pwdArr[i] = v
}
if err := r.rfid.LowLevel.WaitForEdge(edgeTimeout); err != nil {
return err
}
return r.rfid.WriteCard(readTimeout, commands.PICC_AUTHENT1A, sector, block, pwdArr, r.cardKey)
}
func (r *RFID) GetCardKey() [6]byte {
return r.cardKey
}
func (r *RFID) Close() error {
return r.rfid.LowLevel.StopCrypto()
}