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