1 /******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include "stack/crypto_toolbox/crypto_toolbox.h"
20
21 #include <base/logging.h>
22 #include <base/strings/string_number_conversions.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25
26 #include <vector>
27
28 #include "stack/crypto_toolbox/aes.h"
29 #include "stack/include/bt_octets.h"
30
31 using ::testing::ElementsAreArray;
32
33 namespace crypto_toolbox {
34
35 // BT Spec 5.0 | Vol 3, Part H D.1
TEST(CryptoToolboxTest,bt_spec_test_d_1_test)36 TEST(CryptoToolboxTest, bt_spec_test_d_1_test) {
37 uint8_t k[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
38 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
39
40 uint8_t m[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
42
43 uint8_t aes_cmac_k_m[] = {0x7d, 0xf7, 0x6b, 0x0c, 0x1a, 0xb8, 0x99, 0xb3,
44 0x3e, 0x42, 0xf0, 0x47, 0xb9, 0x1b, 0x54, 0x6f};
45
46 uint8_t output[16];
47 aes_context ctx;
48 aes_set_key(k, sizeof(k), &ctx);
49 aes_encrypt(m, output, &ctx); /* outputs in byte 48 to byte 63 */
50
51 EXPECT_THAT(output, ElementsAreArray(aes_cmac_k_m, OCTET16_LEN));
52
53 // useful for debugging
54 // LOG(INFO) << "k " << base::HexEncode(k, OCTET16_LEN);
55 // LOG(INFO) << "m " << base::HexEncode(m, sizeof(m));
56 // LOG(INFO) << "output " << base::HexEncode(output, OCTET16_LEN);
57 }
58
59 // BT Spec 5.0 | Vol 3, Part H D.1.1
TEST(CryptoToolboxTest,bt_spec_example_d_1_1_test)60 TEST(CryptoToolboxTest, bt_spec_example_d_1_1_test) {
61 Octet16 k{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
62 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
63
64 Octet16 aes_cmac_k_m{0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
65 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46};
66
67 // algorithm expect all input to be in little endian format, so reverse
68 std::reverse(std::begin(k), std::end(k));
69 std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
70
71 Octet16 output = aes_cmac(k, nullptr /* empty message */, 0);
72
73 EXPECT_EQ(output, aes_cmac_k_m);
74
75 // useful for debugging
76 // LOG(INFO) << "k " << base::HexEncode(k.data(), k.size());
77 // LOG(INFO) << "aes_cmac(k,nullptr) "
78 // << base::HexEncode(output.data(), output.size());
79 }
80
81 // BT Spec 5.0 | Vol 3, Part H D.1.2
TEST(CryptoToolboxTest,bt_spec_example_d_1_2_test)82 TEST(CryptoToolboxTest, bt_spec_example_d_1_2_test) {
83 Octet16 k{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
84 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
85
86 Octet16 m = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
87 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
88
89 Octet16 aes_cmac_k_m{0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
90 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c};
91
92 // algorithm expect all input to be in little endian format, so reverse
93 std::reverse(std::begin(k), std::end(k));
94 std::reverse(std::begin(m), std::end(m));
95 std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
96
97 Octet16 output = aes_cmac(k, m);
98
99 EXPECT_EQ(output, aes_cmac_k_m);
100
101 // useful for debugging
102 // LOG(INFO) << "k " << base::HexEncode(k.data(), k.size());
103 // LOG(INFO) << "m " << base::HexEncode(m, sizeof(m));
104 // LOG(INFO) << "aes_cmac(k,m) "
105 // << base::HexEncode(output.data(), output.size());
106 }
107
108 // BT Spec 5.0 | Vol 3, Part H D.1.3
TEST(CryptoToolboxTest,bt_spec_example_d_1_3_test)109 TEST(CryptoToolboxTest, bt_spec_example_d_1_3_test) {
110 Octet16 k{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
111 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
112
113 uint8_t m[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d,
114 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57,
115 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf,
116 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11};
117
118 Octet16 aes_cmac_k_m{0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
119 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27};
120
121 // algorithm expect all input to be in little endian format, so reverse
122 std::reverse(std::begin(k), std::end(k));
123 std::reverse(std::begin(m), std::end(m));
124 std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
125
126 Octet16 output = aes_cmac(k, m, sizeof(m));
127 EXPECT_EQ(output, aes_cmac_k_m);
128 }
129
130 // BT Spec 5.0 | Vol 3, Part H D.1.4
TEST(CryptoToolboxTest,bt_spec_example_d_1_4_test)131 TEST(CryptoToolboxTest, bt_spec_example_d_1_4_test) {
132 Octet16 k{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
133 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
134
135 uint8_t m[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d,
136 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57,
137 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf,
138 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
139 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f,
140 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b,
141 0xe6, 0x6c, 0x37, 0x10};
142
143 Octet16 aes_cmac_k_m{0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
144 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe};
145
146 // algorithm expect all input to be in little endian format, so reverse
147 std::reverse(std::begin(k), std::end(k));
148 std::reverse(std::begin(m), std::end(m));
149 std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
150
151 Octet16 output = aes_cmac(k, m, sizeof(m));
152
153 EXPECT_EQ(output, aes_cmac_k_m);
154 }
155
156 // BT Spec 5.0 | Vol 3, Part H D.2
TEST(CryptoToolboxTest,bt_spec_example_d_2_test)157 TEST(CryptoToolboxTest, bt_spec_example_d_2_test) {
158 std::vector<uint8_t> u{0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c,
159 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9,
160 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb,
161 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6};
162 std::vector<uint8_t> v{0x55, 0x18, 0x8b, 0x3d, 0x32, 0xf6, 0xbb, 0x9a,
163 0x90, 0x0a, 0xfc, 0xfb, 0xee, 0xd4, 0xe7, 0x2a,
164 0x59, 0xcb, 0x9a, 0xc2, 0xf1, 0x9d, 0x7c, 0xfb,
165 0x6b, 0x4f, 0xdd, 0x49, 0xf4, 0x7f, 0xc5, 0xfd};
166 Octet16 x{0xd5, 0xcb, 0x84, 0x54, 0xd1, 0x77, 0x73, 0x3e,
167 0xff, 0xff, 0xb2, 0xec, 0x71, 0x2b, 0xae, 0xab};
168 uint8_t z = 0x00;
169
170 Octet16 aes_cmac_k_m{0xf2, 0xc9, 0x16, 0xf1, 0x07, 0xa9, 0xbd, 0x1c,
171 0xf1, 0xed, 0xa1, 0xbe, 0xa9, 0x74, 0x87, 0x2d};
172
173 // algorithm expect all input to be in little endian format, so reverse
174 std::reverse(std::begin(u), std::end(u));
175 std::reverse(std::begin(v), std::end(v));
176 std::reverse(std::begin(x), std::end(x));
177 std::reverse(std::begin(aes_cmac_k_m), std::end(aes_cmac_k_m));
178
179 Octet16 output = f4(u.data(), v.data(), x, z);
180
181 EXPECT_EQ(output, aes_cmac_k_m);
182 }
183
184 // BT Spec 5.0 | Vol 3, Part H D.3
TEST(CryptoToolboxTest,bt_spec_example_d_3_test)185 TEST(CryptoToolboxTest, bt_spec_example_d_3_test) {
186 std::array<uint8_t, 32> dhkey_w{
187 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10,
188 0xa6, 0x0a, 0x39, 0x7d, 0x9b, 0x99, 0x79, 0x6b, 0x13, 0xb4, 0xf8,
189 0x66, 0xf1, 0x86, 0x8d, 0x34, 0xf3, 0x73, 0xbf, 0xa6, 0x98};
190 Octet16 n1{0xd5, 0xcb, 0x84, 0x54, 0xd1, 0x77, 0x73, 0x3e,
191 0xff, 0xff, 0xb2, 0xec, 0x71, 0x2b, 0xae, 0xab};
192 Octet16 n2{0xa6, 0xe8, 0xe7, 0xcc, 0x25, 0xa7, 0x5f, 0x6e,
193 0x21, 0x65, 0x83, 0xf7, 0xff, 0x3d, 0xc4, 0xcf};
194 std::array<uint8_t, 7> a1{0x00, 0x56, 0x12, 0x37, 0x37, 0xbf, 0xce};
195 std::array<uint8_t, 7> a2{0x00, 0xa7, 0x13, 0x70, 0x2d, 0xcf, 0xc1};
196
197 Octet16 expected_ltk{0x69, 0x86, 0x79, 0x11, 0x69, 0xd7, 0xcd, 0x23,
198 0x98, 0x05, 0x22, 0xb5, 0x94, 0x75, 0x0a, 0x38};
199 Octet16 expected_mac_key{0x29, 0x65, 0xf1, 0x76, 0xa1, 0x08, 0x4a, 0x02,
200 0xfd, 0x3f, 0x6a, 0x20, 0xce, 0x63, 0x6e, 0x20};
201
202 // algorithm expect all input to be in little endian format, so reverse
203 std::reverse(std::begin(dhkey_w), std::end(dhkey_w));
204 std::reverse(std::begin(n1), std::end(n1));
205 std::reverse(std::begin(n2), std::end(n2));
206 std::reverse(std::begin(a1), std::end(a1));
207 std::reverse(std::begin(a2), std::end(a2));
208 std::reverse(std::begin(expected_ltk), std::end(expected_ltk));
209 std::reverse(std::begin(expected_mac_key), std::end(expected_mac_key));
210
211 Octet16 mac_key, ltk;
212 f5(dhkey_w.data(), n1, n2, a1.data(), a2.data(), &mac_key, <k);
213
214 EXPECT_EQ(mac_key, expected_mac_key);
215 EXPECT_EQ(ltk, expected_ltk);
216 }
217
218 // BT Spec 5.0 | Vol 3, Part H D.4
TEST(CryptoToolboxTest,bt_spec_example_d_4_test)219 TEST(CryptoToolboxTest, bt_spec_example_d_4_test) {
220 Octet16 n1{0xd5, 0xcb, 0x84, 0x54, 0xd1, 0x77, 0x73, 0x3e,
221 0xff, 0xff, 0xb2, 0xec, 0x71, 0x2b, 0xae, 0xab};
222 Octet16 n2{0xa6, 0xe8, 0xe7, 0xcc, 0x25, 0xa7, 0x5f, 0x6e,
223 0x21, 0x65, 0x83, 0xf7, 0xff, 0x3d, 0xc4, 0xcf};
224 Octet16 r{0x12, 0xa3, 0x34, 0x3b, 0xb4, 0x53, 0xbb, 0x54,
225 0x08, 0xda, 0x42, 0xd2, 0x0c, 0x2d, 0x0f, 0xc8};
226 std::vector<uint8_t> IOcap{0x01, 0x01, 0x02};
227 std::vector<uint8_t> a1{0x00, 0x56, 0x12, 0x37, 0x37, 0xbf, 0xce};
228 std::vector<uint8_t> a2{0x00, 0xa7, 0x13, 0x70, 0x2d, 0xcf, 0xc1};
229
230 Octet16 MacKey{0x29, 0x65, 0xf1, 0x76, 0xa1, 0x08, 0x4a, 0x02,
231 0xfd, 0x3f, 0x6a, 0x20, 0xce, 0x63, 0x6e, 0x20};
232
233 Octet16 expected_aes_cmac{0xe3, 0xc4, 0x73, 0x98, 0x9c, 0xd0, 0xe8, 0xc5,
234 0xd2, 0x6c, 0x0b, 0x09, 0xda, 0x95, 0x8f, 0x61};
235
236 // algorithm expect all input to be in little endian format, so reverse
237 std::reverse(std::begin(n1), std::end(n1));
238 std::reverse(std::begin(n2), std::end(n2));
239 std::reverse(std::begin(r), std::end(r));
240 std::reverse(std::begin(IOcap), std::end(IOcap));
241 std::reverse(std::begin(a1), std::end(a1));
242 std::reverse(std::begin(a2), std::end(a2));
243 std::reverse(std::begin(MacKey), std::end(MacKey));
244 std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
245
246 Octet16 aes_cmac = f6(MacKey, n1, n2, r, IOcap.data(), a1.data(), a2.data());
247
248 EXPECT_EQ(aes_cmac, expected_aes_cmac);
249 }
250
251 // BT Spec 5.0 | Vol 3, Part H D.5
TEST(CryptoToolboxTest,bt_spec_example_d_5_test)252 TEST(CryptoToolboxTest, bt_spec_example_d_5_test) {
253 std::array<uint8_t, 32> u{0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c,
254 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9,
255 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb,
256 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6};
257 std::array<uint8_t, 32> v{0x55, 0x18, 0x8b, 0x3d, 0x32, 0xf6, 0xbb, 0x9a,
258 0x90, 0x0a, 0xfc, 0xfb, 0xee, 0xd4, 0xe7, 0x2a,
259 0x59, 0xcb, 0x9a, 0xc2, 0xf1, 0x9d, 0x7c, 0xfb,
260 0x6b, 0x4f, 0xdd, 0x49, 0xf4, 0x7f, 0xc5, 0xfd};
261
262 Octet16 x{0xd5, 0xcb, 0x84, 0x54, 0xd1, 0x77, 0x73, 0x3e,
263 0xff, 0xff, 0xb2, 0xec, 0x71, 0x2b, 0xae, 0xab};
264 Octet16 y{0xa6, 0xe8, 0xe7, 0xcc, 0x25, 0xa7, 0x5f, 0x6e,
265 0x21, 0x65, 0x83, 0xf7, 0xff, 0x3d, 0xc4, 0xcf};
266
267 // algorithm expect all input to be in little endian format, so reverse
268 std::reverse(std::begin(u), std::end(u));
269 std::reverse(std::begin(v), std::end(v));
270 std::reverse(std::begin(x), std::end(x));
271 std::reverse(std::begin(y), std::end(y));
272
273 uint32_t val = g2(u.data(), v.data(), x, y);
274
275 /* the returned value is already mod 1000000, so do mod on the test result
276 * value too */
277 EXPECT_EQ(val, 0x2f9ed5baU % 1000000);
278 }
279
280 // BT Spec 5.0 | Vol 3, Part H D.6
TEST(CryptoToolboxTest,bt_spec_example_d_6_test)281 TEST(CryptoToolboxTest, bt_spec_example_d_6_test) {
282 Octet16 key{0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05,
283 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
284 std::array<uint8_t, 4> keyID{0x6c, 0x65, 0x62, 0x72};
285 Octet16 expected_aes_cmac{0x2d, 0x9a, 0xe1, 0x02, 0xe7, 0x6d, 0xc9, 0x1c,
286 0xe8, 0xd3, 0xa9, 0xe2, 0x80, 0xb1, 0x63, 0x99};
287
288 // algorithm expect all input to be in little endian format, so reverse
289 std::reverse(std::begin(key), std::end(key));
290 std::reverse(std::begin(keyID), std::end(keyID));
291 std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
292
293 Octet16 aes_cmac = h6(key, keyID);
294 EXPECT_EQ(aes_cmac, expected_aes_cmac);
295 }
296
297 // BT Spec 5.0 | Vol 3, Part H D.7
TEST(CryptoToolboxTest,bt_spec_example_d_7_test)298 TEST(CryptoToolboxTest, bt_spec_example_d_7_test) {
299 Octet16 IRK{0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05,
300 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
301 Octet16 prand{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x81, 0x94};
303 Octet16 expected_aes_128{0x15, 0x9d, 0x5f, 0xb7, 0x2e, 0xbe, 0x23, 0x11,
304 0xa4, 0x8c, 0x1b, 0xdc, 0xc4, 0x0d, 0xfb, 0xaa};
305 std::array<uint8_t, 3> expected_ah{0x0d, 0xfb, 0xaa};
306
307 // algorithm expect all input to be in little endian format, so reverse
308 std::reverse(std::begin(IRK), std::end(IRK));
309 std::reverse(std::begin(prand), std::end(prand));
310 std::reverse(std::begin(expected_aes_128), std::end(expected_aes_128));
311 std::reverse(std::begin(expected_ah), std::end(expected_ah));
312
313 Octet16 result = aes_128(IRK, prand.data(), 3);
314 EXPECT_EQ(expected_aes_128, result);
315
316 // little/big endian 24 bits
317 EXPECT_EQ(result[0], expected_ah[0]);
318 EXPECT_EQ(result[1], expected_ah[1]);
319 EXPECT_EQ(result[2], expected_ah[2]);
320 }
321
322 // BT Spec 5.0 | Vol 3, Part H D.8
TEST(CryptoToolboxTest,bt_spec_example_d_8_test)323 TEST(CryptoToolboxTest, bt_spec_example_d_8_test) {
324 Octet16 Key{0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05,
325 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
326 Octet16 SALT{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31};
328 Octet16 expected_aes_cmac{0xfb, 0x17, 0x35, 0x97, 0xc6, 0xa3, 0xc0, 0xec,
329 0xd2, 0x99, 0x8c, 0x2a, 0x75, 0xa5, 0x70, 0x11};
330
331 // algorithm expect all input to be in little endian format, so reverse
332 std::reverse(std::begin(Key), std::end(Key));
333 std::reverse(std::begin(SALT), std::end(SALT));
334 std::reverse(std::begin(expected_aes_cmac), std::end(expected_aes_cmac));
335
336 Octet16 aes_cmac = h7(SALT, Key);
337 EXPECT_EQ(expected_aes_cmac, aes_cmac);
338 }
339
340 Octet16 smp_calculate_ltk_to_link_key(const Octet16& ltk, bool use_h7);
341
342 // BT Spec 5.0 | Vol 3, Part H D.9
TEST(CryptoToolboxTest,bt_spec_example_d_9_test)343 TEST(CryptoToolboxTest, bt_spec_example_d_9_test) {
344 Octet16 LTK{0x36, 0x8d, 0xf9, 0xbc, 0xe3, 0x26, 0x4b, 0x58,
345 0xbd, 0x06, 0x6c, 0x33, 0x33, 0x4f, 0xbf, 0x64};
346 Octet16 expected_link_key{0x28, 0x7a, 0xd3, 0x79, 0xdc, 0xa4, 0x02, 0x53,
347 0x0a, 0x39, 0xf1, 0xf4, 0x30, 0x47, 0xb8, 0x35};
348
349 // algorithm expect all input to be in little endian format, so reverse
350 std::reverse(std::begin(LTK), std::end(LTK));
351 std::reverse(std::begin(expected_link_key), std::end(expected_link_key));
352
353 Octet16 link_key = ltk_to_link_key(LTK, true);
354 EXPECT_EQ(expected_link_key, link_key);
355 }
356
357 // BT Spec 5.0 | Vol 3, Part H D.10
TEST(CryptoToolboxTest,bt_spec_example_d_10_test)358 TEST(CryptoToolboxTest, bt_spec_example_d_10_test) {
359 Octet16 LTK{0x36, 0x8d, 0xf9, 0xbc, 0xe3, 0x26, 0x4b, 0x58,
360 0xbd, 0x06, 0x6c, 0x33, 0x33, 0x4f, 0xbf, 0x64};
361 Octet16 expected_link_key{0xbc, 0x1c, 0xa4, 0xef, 0x63, 0x3f, 0xc1, 0xbd,
362 0x0d, 0x82, 0x30, 0xaf, 0xee, 0x38, 0x8f, 0xb0};
363
364 // algorithm expect all input to be in little endian format, so reverse
365 std::reverse(std::begin(LTK), std::end(LTK));
366 std::reverse(std::begin(expected_link_key), std::end(expected_link_key));
367
368 Octet16 link_key = ltk_to_link_key(LTK, false);
369 EXPECT_EQ(expected_link_key, link_key);
370 }
371
372 // // BT Spec 5.0 | Vol 3, Part H D.11
TEST(CryptoToolboxTest,bt_spec_example_d_11_test)373 TEST(CryptoToolboxTest, bt_spec_example_d_11_test) {
374 Octet16 link_key{0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x09, 0x08,
375 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
376 Octet16 expected_ltk{0xe8, 0x5e, 0x09, 0xeb, 0x5e, 0xcc, 0xb3, 0xe2,
377 0x69, 0x41, 0x8a, 0x13, 0x32, 0x11, 0xbc, 0x79};
378
379 // algorithm expect all input to be in little endian format, so reverse
380 std::reverse(std::begin(link_key), std::end(link_key));
381 std::reverse(std::begin(expected_ltk), std::end(expected_ltk));
382
383 Octet16 ltk = link_key_to_ltk(link_key, true);
384 EXPECT_EQ(expected_ltk, ltk);
385 }
386
387 // BT Spec 5.0 | Vol 3, Part H D.12
TEST(CryptoToolboxTest,bt_spec_example_d_12_test)388 TEST(CryptoToolboxTest, bt_spec_example_d_12_test) {
389 Octet16 link_key{0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x09, 0x08,
390 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
391 Octet16 expected_ltk{0xa8, 0x13, 0xfb, 0x72, 0xf1, 0xa3, 0xdf, 0xa1,
392 0x8a, 0x2c, 0x9a, 0x43, 0xf1, 0x0d, 0x0a, 0x30};
393
394 // algorithm expect all input to be in little endian format, so reverse
395 std::reverse(std::begin(link_key), std::end(link_key));
396 std::reverse(std::begin(expected_ltk), std::end(expected_ltk));
397
398 Octet16 ltk = link_key_to_ltk(link_key, false);
399 EXPECT_EQ(expected_ltk, ltk);
400 }
401
402 } // namespace crypto_toolbox
403