• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &ltk);
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