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