-
Notifications
You must be signed in to change notification settings - Fork 157
/
session_keys.go
111 lines (90 loc) · 3.3 KB
/
session_keys.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
package joinserver
import (
"crypto/aes"
"fmt"
"github.com/pkg/errors"
"github.com/brocaar/lorawan"
)
// getFNwkSIntKey returns the FNwkSIntKey.
// For LoRaWAN 1.0: SNwkSIntKey = NwkSEncKey = FNwkSIntKey = NwkSKey
func getFNwkSIntKey(optNeg bool, nwkKey lorawan.AES128Key, netID lorawan.NetID, joinEUI lorawan.EUI64, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) {
return getSKey(optNeg, 0x01, nwkKey, netID, joinEUI, joinNonce, devNonce)
}
// getAppSKey returns appSKey.
func getAppSKey(optNeg bool, nwkKey lorawan.AES128Key, netID lorawan.NetID, joinEUI lorawan.EUI64, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) {
return getSKey(optNeg, 0x02, nwkKey, netID, joinEUI, joinNonce, devNonce)
}
// getSNwkSIntKey returns the NwkSIntKey.
func getSNwkSIntKey(optNeg bool, nwkKey lorawan.AES128Key, netID lorawan.NetID, joinEUI lorawan.EUI64, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) {
return getSKey(optNeg, 0x03, nwkKey, netID, joinEUI, joinNonce, devNonce)
}
// getNwkSEncKey returns the NwkSEncKey.
func getNwkSEncKey(optNeg bool, nwkKey lorawan.AES128Key, netID lorawan.NetID, joinEUI lorawan.EUI64, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) {
return getSKey(optNeg, 0x04, nwkKey, netID, joinEUI, joinNonce, devNonce)
}
// getJSIntKey returns the JSIntKey.
func getJSIntKey(nwkKey lorawan.AES128Key, devEUI lorawan.EUI64) (lorawan.AES128Key, error) {
return getJSKey(0x06, devEUI, nwkKey)
}
// getJSEncKey returns the JSEncKey.
func getJSEncKey(nwkKey lorawan.AES128Key, devEUI lorawan.EUI64) (lorawan.AES128Key, error) {
return getJSKey(0x05, devEUI, nwkKey)
}
func getSKey(optNeg bool, typ byte, nwkKey lorawan.AES128Key, netID lorawan.NetID, joinEUI lorawan.EUI64, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) {
var key lorawan.AES128Key
b := make([]byte, 16)
b[0] = typ
netIDB, err := netID.MarshalBinary()
if err != nil {
return key, errors.Wrap(err, "marshal binary error")
}
joinEUIB, err := joinEUI.MarshalBinary()
if err != nil {
return key, errors.Wrap(err, "marshal binary error")
}
joinNonceB, err := joinNonce.MarshalBinary()
if err != nil {
return key, errors.Wrap(err, "marshal binary error")
}
devNonceB, err := devNonce.MarshalBinary()
if err != nil {
return key, errors.Wrap(err, "marshal binary error")
}
if optNeg {
copy(b[1:4], joinNonceB)
copy(b[4:12], joinEUIB)
copy(b[12:14], devNonceB)
} else {
copy(b[1:4], joinNonceB)
copy(b[4:7], netIDB)
copy(b[7:9], devNonceB)
}
block, err := aes.NewCipher(nwkKey[:])
if err != nil {
return key, err
}
if block.BlockSize() != len(b) {
return key, fmt.Errorf("block-size of %d bytes is expected", len(b))
}
block.Encrypt(key[:], b)
return key, nil
}
func getJSKey(typ byte, devEUI lorawan.EUI64, nwkKey lorawan.AES128Key) (lorawan.AES128Key, error) {
var key lorawan.AES128Key
b := make([]byte, 16)
b[0] = typ
devB, err := devEUI.MarshalBinary()
if err != nil {
return key, err
}
copy(b[1:9], devB[:])
block, err := aes.NewCipher(nwkKey[:])
if err != nil {
return key, err
}
if block.BlockSize() != len(b) {
return key, fmt.Errorf("block-size of %d bytes is expected", len(b))
}
block.Encrypt(key[:], b)
return key, nil
}