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