MCPcopy Create free account
hub / github.com/TheThingsNetwork/lorawan-stack / UnwrapKey

Function UnwrapKey

pkg/crypto/keywrap.go:93–141  ·  view source on GitHub ↗

UnwrapKey implements the RFC 3394 Unwrap algorithm

(ciphertext, kek []byte)

Source from the content-addressed store, hash-verified

91
92// UnwrapKey implements the RFC 3394 Unwrap algorithm
93func UnwrapKey(ciphertext, kek []byte) ([]byte, error) {
94 length := len(ciphertext)
95 if length%8 != 0 {
96 return nil, errInvalidKeyLength.WithAttributes("size", length)
97 }
98
99 n := (length / 8) - 1
100 if n < 2 {
101 return nil, errInvalidKeyLength.WithAttributes("size", length)
102 }
103
104 cipher, err := aes.NewCipher(kek)
105 if err != nil {
106 return nil, err
107 }
108
109 // Set A to C[0]
110 var a [8]byte
111 copy(a[:], ciphertext[:8])
112
113 // Fill R blocks
114 r := make([][8]byte, n)
115 for i := range n {
116 copy(r[i][:], ciphertext[(i+1)*8:(i+2)*8])
117 }
118
119 // Run the algorithm
120 for j := 5; j >= 0; j-- {
121 for i := n; i >= 1; i-- {
122 var b [aes.BlockSize]byte
123 cipher.Decrypt(b[:], concat(xor(a, uint64(n*j+i)), r[i-1]))
124 a = msb(b)
125 r[i-1] = lsb(b)
126 }
127 }
128
129 // Check for corruption
130 if a != iv {
131 return nil, errCorruptKey.New()
132 }
133
134 // Build the result
135 plaintext := make([]byte, 0, 8*n)
136 for i := range n {
137 plaintext = append(plaintext, r[i][:]...)
138 }
139
140 return plaintext, nil
141}

Callers 2

TestKEKFunction · 0.85
UnwrapMethod · 0.85

Calls 7

concatFunction · 0.85
xorFunction · 0.85
msbFunction · 0.85
lsbFunction · 0.85
DecryptMethod · 0.65
NewMethod · 0.65
WithAttributesMethod · 0.45

Tested by 1

TestKEKFunction · 0.68