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, &ltk);
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