xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/sm/util_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
16 
17 #include <array>
18 #include <cstdint>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
22 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
23 #include "pw_bluetooth_sapphire/internal/host/common/uint256.h"
24 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
25 #include "pw_bluetooth_sapphire/internal/host/sm/error.h"
26 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
27 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
28 #include "pw_unit_test/framework.h"
29 
30 // inclusive-language: disable
31 
32 namespace bt::sm::util {
33 namespace {
34 
TEST(UtilTest,ConvertSmIoCapabilityToHci)35 TEST(UtilTest, ConvertSmIoCapabilityToHci) {
36   EXPECT_EQ(pw::bluetooth::emboss::IoCapability::DISPLAY_ONLY,
37             IOCapabilityForHci(IOCapability::kDisplayOnly));
38   EXPECT_EQ(pw::bluetooth::emboss::IoCapability::DISPLAY_YES_NO,
39             IOCapabilityForHci(IOCapability::kDisplayYesNo));
40   EXPECT_EQ(pw::bluetooth::emboss::IoCapability::KEYBOARD_ONLY,
41             IOCapabilityForHci(IOCapability::kKeyboardOnly));
42   EXPECT_EQ(pw::bluetooth::emboss::IoCapability::NO_INPUT_NO_OUTPUT,
43             IOCapabilityForHci(IOCapability::kNoInputNoOutput));
44   EXPECT_EQ(pw::bluetooth::emboss::IoCapability::DISPLAY_YES_NO,
45             IOCapabilityForHci(IOCapability::kKeyboardDisplay));
46 
47   // Test remaining invalid values for sm::IOCapability.
48   for (int i = 0x05; i < 0xff; i++) {
49     EXPECT_EQ(pw::bluetooth::emboss::IoCapability::NO_INPUT_NO_OUTPUT,
50               IOCapabilityForHci(static_cast<IOCapability>(i)));
51   }
52 }
53 
TEST(UtilTest,MapToRolesCorrectly)54 TEST(UtilTest, MapToRolesCorrectly) {
55   UInt128 local_val = {1}, peer_val = {2};
56   auto [initiator_val, responder_val] =
57       MapToRoles(local_val, peer_val, Role::kInitiator);
58   EXPECT_EQ(local_val, initiator_val);
59   EXPECT_EQ(peer_val, responder_val);
60 
61   std::tie(initiator_val, responder_val) =
62       MapToRoles(local_val, peer_val, Role::kResponder);
63   EXPECT_EQ(local_val, responder_val);
64   EXPECT_EQ(peer_val, initiator_val);
65 }
66 
TEST(UtilTest,SelectPairingMethodOOB)67 TEST(UtilTest, SelectPairingMethodOOB) {
68   // In SC OOB is selected if either device has OOB data.
69   EXPECT_EQ(PairingMethod::kOutOfBand,
70             SelectPairingMethod(/*secure_connections=*/true,
71                                 /*local_oob=*/true,
72                                 /*peer_oob=*/false,
73                                 /*mitm_required=*/true,
74                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
75                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
76                                 /*local_initiator=*/true));
77   EXPECT_EQ(PairingMethod::kOutOfBand,
78             SelectPairingMethod(/*secure_connections=*/true,
79                                 /*local_oob=*/false,
80                                 /*peer_oob=*/true,
81                                 /*mitm_required=*/true,
82                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
83                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
84                                 /*local_initiator=*/true));
85   EXPECT_NE(PairingMethod::kOutOfBand,
86             SelectPairingMethod(/*secure_connections=*/true,
87                                 /*local_oob=*/false,
88                                 /*peer_oob=*/false,
89                                 /*mitm_required=*/true,
90                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
91                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
92                                 /*local_initiator=*/true));
93 
94   // In legacy OOB is selected if both devices have OOB data.
95   EXPECT_EQ(PairingMethod::kOutOfBand,
96             SelectPairingMethod(/*secure_connections=*/false,
97                                 /*local_oob=*/true,
98                                 /*peer_oob=*/true,
99                                 /*mitm_required=*/true,
100                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
101                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
102                                 /*local_initiator=*/true));
103   EXPECT_NE(PairingMethod::kOutOfBand,
104             SelectPairingMethod(/*secure_connections=*/false,
105                                 /*local_oob=*/false,
106                                 /*peer_oob=*/true,
107                                 /*mitm_required=*/true,
108                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
109                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
110                                 /*local_initiator=*/true));
111   EXPECT_NE(PairingMethod::kOutOfBand,
112             SelectPairingMethod(/*secure_connections=*/false,
113                                 /*local_oob=*/true,
114                                 /*peer_oob=*/false,
115                                 /*mitm_required=*/true,
116                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
117                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
118                                 /*local_initiator=*/true));
119   EXPECT_NE(PairingMethod::kOutOfBand,
120             SelectPairingMethod(/*secure_connections=*/false,
121                                 /*local_oob=*/false,
122                                 /*peer_oob=*/false,
123                                 /*mitm_required=*/true,
124                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
125                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
126                                 /*local_initiator=*/true));
127 }
128 
TEST(UtilTest,SelectPairingMethodNoMITM)129 TEST(UtilTest, SelectPairingMethodNoMITM) {
130   // The pairing method should be "Just Works" if neither device requires MITM
131   // protection, regardless of other parameters.
132   EXPECT_EQ(PairingMethod::kJustWorks,
133             SelectPairingMethod(/*secure_connections=*/true,
134                                 /*local_oob=*/false,
135                                 /*peer_oob=*/false,
136                                 /*mitm_required=*/false,
137                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
138                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
139                                 /*local_initiator=*/true));
140 
141   // Shouldn't default to "Just Works" if at least one device requires MITM
142   // protection.
143   EXPECT_NE(PairingMethod::kJustWorks,
144             SelectPairingMethod(/*secure_connections=*/false,
145                                 /*local_oob=*/false,
146                                 /*peer_oob=*/false,
147                                 /*mitm_required=*/true,
148                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
149                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
150                                 /*local_initiator=*/true));
151 }
152 
153 // Tests all combinations that result in the "Just Works" pairing method.
TEST(UtilTest,SelectPairingMethodJustWorks)154 TEST(UtilTest, SelectPairingMethodJustWorks) {
155   // Local: DisplayOnly
156   EXPECT_EQ(PairingMethod::kJustWorks,
157             SelectPairingMethod(/*secure_connections=*/true,
158                                 /*local_oob=*/false,
159                                 /*peer_oob=*/false,
160                                 /*mitm_required=*/true,
161                                 /*local_ioc=*/IOCapability::kDisplayOnly,
162                                 /*peer_ioc=*/IOCapability::kDisplayOnly,
163                                 /*local_initiator=*/true));
164   EXPECT_EQ(PairingMethod::kJustWorks,
165             SelectPairingMethod(/*secure_connections=*/true,
166                                 /*local_oob=*/false,
167                                 /*peer_oob=*/false,
168                                 /*mitm_required=*/true,
169                                 /*local_ioc=*/IOCapability::kDisplayOnly,
170                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
171                                 /*local_initiator=*/true));
172   EXPECT_EQ(PairingMethod::kJustWorks,
173             SelectPairingMethod(/*secure_connections=*/true,
174                                 /*local_oob=*/false,
175                                 /*peer_oob=*/false,
176                                 /*mitm_required=*/true,
177                                 /*local_ioc=*/IOCapability::kDisplayOnly,
178                                 /*peer_ioc=*/IOCapability::kNoInputNoOutput,
179                                 /*local_initiator=*/true));
180 
181   // Local: DisplayYesNo
182   EXPECT_EQ(PairingMethod::kJustWorks,
183             SelectPairingMethod(/*secure_connections=*/true,
184                                 /*local_oob=*/false,
185                                 /*peer_oob=*/false,
186                                 /*mitm_required=*/true,
187                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
188                                 /*peer_ioc=*/IOCapability::kDisplayOnly,
189                                 /*local_initiator=*/true));
190   // If both devices are DisplayYesNo, then "Just Works" is selected for LE
191   // legacy pairing (i.e. at least one device doesn't support Secure
192   // Connections).
193   EXPECT_EQ(PairingMethod::kJustWorks,
194             SelectPairingMethod(/*secure_connections=*/false,
195                                 /*local_oob=*/false,
196                                 /*peer_oob=*/false,
197                                 /*mitm_required=*/true,
198                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
199                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
200                                 /*local_initiator=*/true));
201   EXPECT_EQ(PairingMethod::kJustWorks,
202             SelectPairingMethod(/*secure_connections=*/true,
203                                 /*local_oob=*/false,
204                                 /*peer_oob=*/false,
205                                 /*mitm_required=*/true,
206                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
207                                 /*peer_ioc=*/IOCapability::kNoInputNoOutput,
208                                 /*local_initiator=*/true));
209 
210   // Local: KeyboardOnly
211   EXPECT_EQ(PairingMethod::kJustWorks,
212             SelectPairingMethod(/*secure_connections=*/true,
213                                 /*local_oob=*/false,
214                                 /*peer_oob=*/false,
215                                 /*mitm_required=*/true,
216                                 /*local_ioc=*/IOCapability::kKeyboardOnly,
217                                 /*peer_ioc=*/IOCapability::kNoInputNoOutput,
218                                 /*local_initiator=*/true));
219 
220   // Local: NoInputNoOutput. Always "Just Works".
221   EXPECT_EQ(PairingMethod::kJustWorks,
222             SelectPairingMethod(/*secure_connections=*/true,
223                                 /*local_oob=*/false,
224                                 /*peer_oob=*/false,
225                                 /*mitm_required=*/true,
226                                 /*local_ioc=*/IOCapability::kNoInputNoOutput,
227                                 /*peer_ioc=*/IOCapability::kDisplayOnly,
228                                 /*local_initiator=*/true));
229   EXPECT_EQ(PairingMethod::kJustWorks,
230             SelectPairingMethod(/*secure_connections=*/true,
231                                 /*local_oob=*/false,
232                                 /*peer_oob=*/false,
233                                 /*mitm_required=*/true,
234                                 /*local_ioc=*/IOCapability::kNoInputNoOutput,
235                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
236                                 /*local_initiator=*/true));
237   EXPECT_EQ(PairingMethod::kJustWorks,
238             SelectPairingMethod(/*secure_connections=*/true,
239                                 /*local_oob=*/false,
240                                 /*peer_oob=*/false,
241                                 /*mitm_required=*/true,
242                                 /*local_ioc=*/IOCapability::kNoInputNoOutput,
243                                 /*peer_ioc=*/IOCapability::kKeyboardOnly,
244                                 /*local_initiator=*/true));
245   EXPECT_EQ(PairingMethod::kJustWorks,
246             SelectPairingMethod(/*secure_connections=*/true,
247                                 /*local_oob=*/false,
248                                 /*peer_oob=*/false,
249                                 /*mitm_required=*/true,
250                                 /*local_ioc=*/IOCapability::kNoInputNoOutput,
251                                 /*peer_ioc=*/IOCapability::kNoInputNoOutput,
252                                 /*local_initiator=*/true));
253   EXPECT_EQ(PairingMethod::kJustWorks,
254             SelectPairingMethod(/*secure_connections=*/true,
255                                 /*local_oob=*/false,
256                                 /*peer_oob=*/false,
257                                 /*mitm_required=*/true,
258                                 /*local_ioc=*/IOCapability::kNoInputNoOutput,
259                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
260                                 /*local_initiator=*/true));
261 
262   // Local: KeyboardDisplay
263   EXPECT_EQ(PairingMethod::kJustWorks,
264             SelectPairingMethod(/*secure_connections=*/true,
265                                 /*local_oob=*/false,
266                                 /*peer_oob=*/false,
267                                 /*mitm_required=*/true,
268                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
269                                 /*peer_ioc=*/IOCapability::kNoInputNoOutput,
270                                 /*local_initiator=*/true));
271 }
272 
273 // Tests all combinations that result in the "Passkey Entry (input)" pairing
274 // method.
TEST(UtilTest,SelectPairingMethodPasskeyEntryInput)275 TEST(UtilTest, SelectPairingMethodPasskeyEntryInput) {
276   // Local: KeyboardOnly
277   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
278             SelectPairingMethod(/*secure_connections=*/true,
279                                 /*local_oob=*/false,
280                                 /*peer_oob=*/false,
281                                 /*mitm_required=*/true,
282                                 /*local_ioc=*/IOCapability::kKeyboardOnly,
283                                 /*peer_ioc=*/IOCapability::kDisplayOnly,
284                                 /*local_initiator=*/true));
285   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
286             SelectPairingMethod(/*secure_connections=*/true,
287                                 /*local_oob=*/false,
288                                 /*peer_oob=*/false,
289                                 /*mitm_required=*/true,
290                                 /*local_ioc=*/IOCapability::kKeyboardOnly,
291                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
292                                 /*local_initiator=*/true));
293   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
294             SelectPairingMethod(/*secure_connections=*/true,
295                                 /*local_oob=*/false,
296                                 /*peer_oob=*/false,
297                                 /*mitm_required=*/true,
298                                 /*local_ioc=*/IOCapability::kKeyboardOnly,
299                                 /*peer_ioc=*/IOCapability::kKeyboardOnly,
300                                 /*local_initiator=*/true));
301   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
302             SelectPairingMethod(/*secure_connections=*/true,
303                                 /*local_oob=*/false,
304                                 /*peer_oob=*/false,
305                                 /*mitm_required=*/true,
306                                 /*local_ioc=*/IOCapability::kKeyboardOnly,
307                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
308                                 /*local_initiator=*/true));
309 
310   // Local: KeyboardDisplay
311   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
312             SelectPairingMethod(/*secure_connections=*/true,
313                                 /*local_oob=*/false,
314                                 /*peer_oob=*/false,
315                                 /*mitm_required=*/true,
316                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
317                                 /*peer_ioc=*/IOCapability::kDisplayOnly,
318                                 /*local_initiator=*/true));
319   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
320             SelectPairingMethod(/*secure_connections=*/false,
321                                 /*local_oob=*/false,
322                                 /*peer_oob=*/false,
323                                 /*mitm_required=*/true,
324                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
325                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
326                                 /*local_initiator=*/true));
327 
328   // If both devices have the KeyboardDisplay capability then the responder
329   // inputs.
330   EXPECT_EQ(PairingMethod::kPasskeyEntryInput,
331             SelectPairingMethod(/*secure_connections=*/false,
332                                 /*local_oob=*/false,
333                                 /*peer_oob=*/false,
334                                 /*mitm_required=*/true,
335                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
336                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
337                                 /*local_initiator=*/false));
338 }
339 
340 // Tests all combinations that result in the "Passkey Entry (display)" pairing
341 // method.
TEST(UtilTest,SelectPairingMethodPasskeyEntryDisplay)342 TEST(UtilTest, SelectPairingMethodPasskeyEntryDisplay) {
343   // Local: DisplayOnly
344   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
345             SelectPairingMethod(/*secure_connections=*/true,
346                                 /*local_oob=*/false,
347                                 /*peer_oob=*/false,
348                                 /*mitm_required=*/true,
349                                 /*local_ioc=*/IOCapability::kDisplayOnly,
350                                 /*peer_ioc=*/IOCapability::kKeyboardOnly,
351                                 /*local_initiator=*/true));
352   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
353             SelectPairingMethod(/*secure_connections=*/true,
354                                 /*local_oob=*/false,
355                                 /*peer_oob=*/false,
356                                 /*mitm_required=*/true,
357                                 /*local_ioc=*/IOCapability::kDisplayOnly,
358                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
359                                 /*local_initiator=*/true));
360 
361   // Local: DisplayYesNo
362   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
363             SelectPairingMethod(/*secure_connections=*/true,
364                                 /*local_oob=*/false,
365                                 /*peer_oob=*/false,
366                                 /*mitm_required=*/true,
367                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
368                                 /*peer_ioc=*/IOCapability::kKeyboardOnly,
369                                 /*local_initiator=*/true));
370   // If the peer has a display then use "Passkey Entry" only for LE Legacy
371   // pairing.
372   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
373             SelectPairingMethod(/*secure_connections=*/false,
374                                 /*local_oob=*/false,
375                                 /*peer_oob=*/false,
376                                 /*mitm_required=*/true,
377                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
378                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
379                                 /*local_initiator=*/true));
380 
381   // Local: KeyboardDisplay
382   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
383             SelectPairingMethod(/*secure_connections=*/true,
384                                 /*local_oob=*/false,
385                                 /*peer_oob=*/false,
386                                 /*mitm_required=*/true,
387                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
388                                 /*peer_ioc=*/IOCapability::kKeyboardOnly,
389                                 /*local_initiator=*/true));
390 
391   // If both devices have the KeyboardDisplay capability then the initiator
392   // displays.
393   EXPECT_EQ(PairingMethod::kPasskeyEntryDisplay,
394             SelectPairingMethod(/*secure_connections=*/false,
395                                 /*local_oob=*/false,
396                                 /*peer_oob=*/false,
397                                 /*mitm_required=*/true,
398                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
399                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
400                                 /*local_initiator=*/true));
401 }
402 
403 // Tests all combinations that result in the "Numeric Comparison" pairing
404 // method. This will be selected in certain I/O capability combinations only if
405 // both devices support Secure Connections.
TEST(UtilTest,SelectPairingMethodNumericComparison)406 TEST(UtilTest, SelectPairingMethodNumericComparison) {
407   // Local: DisplayYesNo
408   EXPECT_EQ(PairingMethod::kNumericComparison,
409             SelectPairingMethod(/*secure_connections=*/true,
410                                 /*local_oob=*/false,
411                                 /*peer_oob=*/false,
412                                 /*mitm_required=*/true,
413                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
414                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
415                                 /*local_initiator=*/true));
416   EXPECT_EQ(PairingMethod::kNumericComparison,
417             SelectPairingMethod(/*secure_connections=*/true,
418                                 /*local_oob=*/false,
419                                 /*peer_oob=*/false,
420                                 /*mitm_required=*/true,
421                                 /*local_ioc=*/IOCapability::kDisplayYesNo,
422                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
423                                 /*local_initiator=*/true));
424 
425   // Local: KeyboardDisplay
426   EXPECT_EQ(PairingMethod::kNumericComparison,
427             SelectPairingMethod(/*secure_connections=*/true,
428                                 /*local_oob=*/false,
429                                 /*peer_oob=*/false,
430                                 /*mitm_required=*/true,
431                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
432                                 /*peer_ioc=*/IOCapability::kDisplayYesNo,
433                                 /*local_initiator=*/true));
434   EXPECT_EQ(PairingMethod::kNumericComparison,
435             SelectPairingMethod(/*secure_connections=*/true,
436                                 /*local_oob=*/false,
437                                 /*peer_oob=*/false,
438                                 /*mitm_required=*/true,
439                                 /*local_ioc=*/IOCapability::kKeyboardDisplay,
440                                 /*peer_ioc=*/IOCapability::kKeyboardDisplay,
441                                 /*local_initiator=*/true));
442 }
443 
444 // Tests "c1" using the sample data from Vol 3, Part H, 2.2.3.
TEST(UtilTest,C1)445 TEST(UtilTest, C1) {
446   const UInt128 tk{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
447   const UInt128 r{{0xE0,
448                    0x2E,
449                    0x70,
450                    0xC6,
451                    0x4E,
452                    0x27,
453                    0x88,
454                    0x63,
455                    0x0E,
456                    0x6F,
457                    0xAD,
458                    0x56,
459                    0x21,
460                    0xD5,
461                    0x83,
462                    0x57}};
463   const StaticByteBuffer preq(0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07);
464   const StaticByteBuffer pres(0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05);
465   const DeviceAddress initiator_addr(DeviceAddress::Type::kLERandom,
466                                      {0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1});
467   const DeviceAddress responder_addr(DeviceAddress::Type::kLEPublic,
468                                      {0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1});
469 
470   const UInt128 kExpected{{0x86,
471                            0x3B,
472                            0xF1,
473                            0xBE,
474                            0xC5,
475                            0x4D,
476                            0xA7,
477                            0xD2,
478                            0xEA,
479                            0x88,
480                            0x89,
481                            0x87,
482                            0xEF,
483                            0x3F,
484                            0x1E,
485                            0x1E}};
486 
487   UInt128 result;
488   C1(tk, r, preq, pres, initiator_addr, responder_addr, &result);
489   EXPECT_TRUE(ContainersEqual(kExpected, result));
490 }
491 
492 // Tests "s1" using the sample data from Vol 3, Part H, 2.2.4.
TEST(UtilTest,S1)493 TEST(UtilTest, S1) {
494   const UInt128 tk{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
495   const UInt128 r1{{0x88,
496                     0x77,
497                     0x66,
498                     0x55,
499                     0x44,
500                     0x33,
501                     0x22,
502                     0x11,
503                     0x09,
504                     0xA0,
505                     0xB0,
506                     0xC0,
507                     0xD0,
508                     0xE0,
509                     0xF0,
510                     0x00}};
511   const UInt128 r2{{0x00,
512                     0xFF,
513                     0xEE,
514                     0xDD,
515                     0xCC,
516                     0xBB,
517                     0xAA,
518                     0x99,
519                     0x08,
520                     0x07,
521                     0x06,
522                     0x05,
523                     0x04,
524                     0x03,
525                     0x02,
526                     0x01}};
527 
528   const UInt128 kExpected{{0x62,
529                            0xA0,
530                            0x6D,
531                            0x79,
532                            0xAE,
533                            0x16,
534                            0x42,
535                            0x5B,
536                            0x9B,
537                            0xF4,
538                            0xB0,
539                            0xE8,
540                            0xF0,
541                            0xE1,
542                            0x1F,
543                            0x9A}};
544 
545   UInt128 result;
546   S1(tk, r1, r2, &result);
547   EXPECT_TRUE(ContainersEqual(kExpected, result));
548 }
549 
550 // Test "ah" using the sample data from Vol 3, Part H, Appendix D.7.
TEST(UtilTest,Ah)551 TEST(UtilTest, Ah) {
552   const UInt128 irk{{0x9B,
553                      0x7D,
554                      0x39,
555                      0x0A,
556                      0xA6,
557                      0x10,
558                      0x10,
559                      0x34,
560                      0x05,
561                      0xAD,
562                      0xC8,
563                      0x57,
564                      0xA3,
565                      0x34,
566                      0x02,
567                      0xEC}};
568   const uint32_t prand = 0x708194;
569   const uint32_t kExpected = 0x0DFBAA;
570 
571   EXPECT_EQ(kExpected, Ah(irk, prand));
572 }
573 
TEST(UtilTest,IrkCanResolveRpa)574 TEST(UtilTest, IrkCanResolveRpa) {
575   // Using the sample data from Vol 3, Part H, Appendix D.7.
576   const UInt128 kIRK{{0x9B,
577                       0x7D,
578                       0x39,
579                       0x0A,
580                       0xA6,
581                       0x10,
582                       0x10,
583                       0x34,
584                       0x05,
585                       0xAD,
586                       0xC8,
587                       0x57,
588                       0xA3,
589                       0x34,
590                       0x02,
591                       0xEC}};
592   const DeviceAddress kStaticRandom(DeviceAddress::Type::kLERandom,
593                                     {0xA9, 0xFB, 0x0D, 0x94, 0x81, 0xF0});
594   const DeviceAddress kNonResolvable(DeviceAddress::Type::kLERandom,
595                                      {0xA9, 0xFB, 0x0D, 0x94, 0x81, 0x00});
596   const DeviceAddress kNonMatchingResolvable(
597       DeviceAddress::Type::kLERandom, {0xA9, 0xFB, 0x0D, 0x94, 0x81, 0x70});
598   const DeviceAddress kMatchingResolvable(DeviceAddress::Type::kLERandom,
599                                           {0xAA, 0xFB, 0x0D, 0x94, 0x81, 0x70});
600 
601   ASSERT_FALSE(kStaticRandom.IsResolvablePrivate());
602   ASSERT_FALSE(kNonResolvable.IsResolvablePrivate());
603   ASSERT_TRUE(kNonMatchingResolvable.IsResolvablePrivate());
604   ASSERT_TRUE(kMatchingResolvable.IsResolvablePrivate());
605 
606   EXPECT_FALSE(IrkCanResolveRpa(kIRK, kStaticRandom));
607   EXPECT_FALSE(IrkCanResolveRpa(kIRK, kNonResolvable));
608   EXPECT_FALSE(IrkCanResolveRpa(kIRK, kNonMatchingResolvable));
609   EXPECT_TRUE(IrkCanResolveRpa(kIRK, kMatchingResolvable));
610 }
611 
TEST(UtilTest,GenerateRpa)612 TEST(UtilTest, GenerateRpa) {
613   const UInt128 irk{{'s',
614                      'o',
615                      'm',
616                      'e',
617                      ' ',
618                      'r',
619                      'a',
620                      'n',
621                      'd',
622                      'o',
623                      'm',
624                      ' ',
625                      'd',
626                      'a',
627                      't',
628                      'a'}};
629 
630   DeviceAddress rpa = GenerateRpa(irk);
631 
632   EXPECT_EQ(DeviceAddress::Type::kLERandom, rpa.type());
633   EXPECT_TRUE(rpa.IsResolvablePrivate());
634 
635   // It should be possible to resolve the RPA with the IRK used to generate it.
636   EXPECT_TRUE(IrkCanResolveRpa(irk, rpa));
637 }
638 
TEST(UtilTest,GenerateRandomAddress)639 TEST(UtilTest, GenerateRandomAddress) {
640   DeviceAddress addr = GenerateRandomAddress(false);
641   EXPECT_EQ(DeviceAddress::Type::kLERandom, addr.type());
642   EXPECT_TRUE(addr.IsNonResolvablePrivate());
643 
644   addr = GenerateRandomAddress(true);
645   EXPECT_EQ(DeviceAddress::Type::kLERandom, addr.type());
646   EXPECT_TRUE(addr.IsStaticRandom());
647 }
648 
649 // Using the sample data from Vol 3, Part H, Appendix D.1.
TEST(UtilTest,AesCmac)650 TEST(UtilTest, AesCmac) {
651   const UInt128 key{0x3C,
652                     0x4F,
653                     0xCF,
654                     0x09,
655                     0x88,
656                     0x15,
657                     0xF7,
658                     0xAB,
659                     0xA6,
660                     0xD2,
661                     0xAE,
662                     0x28,
663                     0x16,
664                     0x15,
665                     0x7E,
666                     0x2B};
667 
668   // D.1.1 Example 1: Len = 0
669   const BufferView kMsg0;
670   const UInt128 kMsg0ExpectedCmac = {0x46,
671                                      0x67,
672                                      0x75,
673                                      0x9B,
674                                      0x12,
675                                      0x7D,
676                                      0xA3,
677                                      0x7F,
678                                      0x28,
679                                      0x37,
680                                      0x59,
681                                      0xE9,
682                                      0x29,
683                                      0x69,
684                                      0x1D,
685                                      0xBB};
686 
687   // D.1.2 Example 2: Len = 16
688   const StaticByteBuffer<16> kMsg16{0x2A,
689                                     0x17,
690                                     0x93,
691                                     0x73,
692                                     0x11,
693                                     0x7E,
694                                     0x3D,
695                                     0xE9,
696                                     0x96,
697                                     0x9F,
698                                     0x40,
699                                     0x2E,
700                                     0xE2,
701                                     0xBE,
702                                     0xC1,
703                                     0x6B};
704   const UInt128 kMsg16ExpectedCmac{0x7C,
705                                    0x28,
706                                    0x4A,
707                                    0xD0,
708                                    0x9D,
709                                    0xDD,
710                                    0x9B,
711                                    0xF7,
712                                    0x44,
713                                    0x41,
714                                    0x4D,
715                                    0x6B,
716                                    0xB4,
717                                    0x16,
718                                    0x0A,
719                                    0x07};
720 
721   // D.1.3 Example 3: Len = 40
722   const StaticByteBuffer<40> kMsg40{
723       0x11, 0xE4, 0x5C, 0xA3, 0x46, 0x1C, 0xC8, 0x30, 0x51, 0x8E,
724       0xAF, 0x45, 0xAC, 0x6F, 0xB7, 0x9E, 0x9C, 0xAC, 0x03, 0x1E,
725       0x57, 0x8A, 0x2D, 0xAE, 0x2A, 0x17, 0x93, 0x73, 0x11, 0x7E,
726       0x3D, 0xE9, 0x96, 0x9F, 0x40, 0x2E, 0xE2, 0xBE, 0xC1, 0x6B};
727   const UInt128 kMsg40ExpectedCmac{0x27,
728                                    0xC8,
729                                    0x97,
730                                    0x14,
731                                    0x61,
732                                    0x32,
733                                    0xCA,
734                                    0x30,
735                                    0x30,
736                                    0xE6,
737                                    0x9A,
738                                    0xDE,
739                                    0x47,
740                                    0x67,
741                                    0xA6,
742                                    0xDF};
743 
744   // D.1.4 Example 4: Len = 64
745   const StaticByteBuffer<64> kMsg64{
746       0x10, 0x37, 0x6C, 0xE6, 0x7B, 0x41, 0x2B, 0xAD, 0x17, 0x9B, 0x4F,
747       0xDF, 0x45, 0x24, 0x9F, 0xF6, 0xEF, 0x52, 0x0A, 0x1A, 0x19, 0xC1,
748       0xFB, 0xE5, 0x11, 0xE4, 0x5C, 0xA3, 0x46, 0x1C, 0xC8, 0x30, 0x51,
749       0x8E, 0xAF, 0x45, 0xAC, 0x6F, 0xB7, 0x9E, 0x9C, 0xAC, 0x03, 0x1E,
750       0x57, 0x8A, 0x2D, 0xAE, 0x2A, 0x17, 0x93, 0x73, 0x11, 0x7E, 0x3D,
751       0xE9, 0x96, 0x9F, 0x40, 0x2E, 0xE2, 0xBE, 0xC1, 0x6B};
752   const UInt128 kMsg64ExpectedCmac{0xFE,
753                                    0x3C,
754                                    0x36,
755                                    0x79,
756                                    0x17,
757                                    0x74,
758                                    0x49,
759                                    0xFC,
760                                    0x92,
761                                    0x9D,
762                                    0x3B,
763                                    0x7E,
764                                    0xBF,
765                                    0xBE,
766                                    0xF0,
767                                    0x51};
768 
769   std::optional<UInt128> cmac_output{};
770 
771   cmac_output = AesCmac(key, kMsg0);
772   ASSERT_TRUE(cmac_output.has_value());
773   EXPECT_EQ(kMsg0ExpectedCmac, *cmac_output);
774 
775   cmac_output = AesCmac(key, kMsg16);
776   ASSERT_TRUE(cmac_output.has_value());
777   EXPECT_EQ(kMsg16ExpectedCmac, *cmac_output);
778 
779   cmac_output = AesCmac(key, kMsg40);
780   ASSERT_TRUE(cmac_output.has_value());
781   EXPECT_EQ(kMsg40ExpectedCmac, *cmac_output);
782 
783   cmac_output = AesCmac(key, kMsg64);
784   ASSERT_TRUE(cmac_output.has_value());
785   EXPECT_EQ(kMsg64ExpectedCmac, *cmac_output);
786 }
787 
788 // Using the sample data from Vol 3, Part H, Appendix D.2.
TEST(UtilTest,F4)789 TEST(UtilTest, F4) {
790   const UInt256 kU{0xE6, 0x9D, 0x35, 0x0E, 0x48, 0x01, 0x03, 0xCC,
791                    0xDB, 0xFD, 0xF4, 0xAC, 0x11, 0x91, 0xF4, 0xEF,
792                    0xB9, 0xA5, 0xF9, 0xE9, 0xA7, 0x83, 0x2C, 0x5E,
793                    0x2C, 0xBE, 0x97, 0xF2, 0xD2, 0x03, 0xB0, 0x20};
794   const UInt256 kV{0xFD, 0xC5, 0x7F, 0xF4, 0x49, 0xDD, 0x4F, 0x6B,
795                    0xFB, 0x7C, 0x9D, 0xF1, 0xC2, 0x9A, 0xCB, 0x59,
796                    0x2A, 0xE7, 0xD4, 0xEE, 0xFB, 0xFC, 0x0A, 0x90,
797                    0x9A, 0xBB, 0xF6, 0x32, 0x3D, 0x8B, 0x18, 0x55};
798   const UInt128 kX{0xAB,
799                    0xAE,
800                    0x2B,
801                    0x71,
802                    0xEC,
803                    0xB2,
804                    0xFF,
805                    0xFF,
806                    0x3E,
807                    0x73,
808                    0x77,
809                    0xD1,
810                    0x54,
811                    0x84,
812                    0xCB,
813                    0xD5};
814   const uint8_t kZ = 0x00;
815   const UInt128 kExpectedF4{0x2D,
816                             0x87,
817                             0x74,
818                             0xA9,
819                             0xBE,
820                             0xA1,
821                             0xED,
822                             0xF1,
823                             0x1C,
824                             0xBD,
825                             0xA9,
826                             0x07,
827                             0xF1,
828                             0x16,
829                             0xC9,
830                             0xF2};
831 
832   std::optional<UInt128> f4_out = F4(kU, kV, kX, kZ);
833   ASSERT_TRUE(f4_out.has_value());
834   EXPECT_EQ(kExpectedF4, *f4_out);
835 }
836 
837 // Using the sample data from Vol 3, Part H, Appendix D.3.
TEST(UtilTest,F5)838 TEST(UtilTest, F5) {
839   const UInt256 kDhKey{0x98, 0xA6, 0xBF, 0x73, 0xF3, 0x34, 0x8D, 0x86,
840                        0xF1, 0x66, 0xF8, 0xB4, 0x13, 0x6B, 0x79, 0x99,
841                        0x9B, 0x7D, 0x39, 0x0A, 0xA6, 0x10, 0x10, 0x34,
842                        0x05, 0xAD, 0xC8, 0x57, 0xA3, 0x34, 0x02, 0xEC};
843   const UInt128 kInitiatorNonce{0xAB,
844                                 0xAE,
845                                 0x2B,
846                                 0x71,
847                                 0xEC,
848                                 0xB2,
849                                 0xFF,
850                                 0xFF,
851                                 0x3E,
852                                 0x73,
853                                 0x77,
854                                 0xD1,
855                                 0x54,
856                                 0x84,
857                                 0xCB,
858                                 0xD5};
859   const UInt128 kResponderNonce{0xCF,
860                                 0xC4,
861                                 0x3D,
862                                 0xFF,
863                                 0xF7,
864                                 0x83,
865                                 0x65,
866                                 0x21,
867                                 0x6E,
868                                 0x5F,
869                                 0xA7,
870                                 0x25,
871                                 0xCC,
872                                 0xE7,
873                                 0xE8,
874                                 0xA6};
875   const DeviceAddress kInitiatorAddr(DeviceAddress::Type::kLEPublic,
876                                      {0xCE, 0xBF, 0x37, 0x37, 0x12, 0x56});
877   const DeviceAddress kResponderAddr(DeviceAddress::Type::kLEPublic,
878                                      {0xC1, 0xCF, 0x2D, 0x70, 0x13, 0xA7});
879   const UInt128 kExpectedMacKey{0x20,
880                                 0x6E,
881                                 0x63,
882                                 0xCE,
883                                 0x20,
884                                 0x6A,
885                                 0x3F,
886                                 0xFD,
887                                 0x02,
888                                 0x4A,
889                                 0x08,
890                                 0xA1,
891                                 0x76,
892                                 0xF1,
893                                 0x65,
894                                 0x29};
895   const UInt128 kExpectedLtk{0x38,
896                              0x0A,
897                              0x75,
898                              0x94,
899                              0xB5,
900                              0x22,
901                              0x05,
902                              0x98,
903                              0x23,
904                              0xCD,
905                              0xD7,
906                              0x69,
907                              0x11,
908                              0x79,
909                              0x86,
910                              0x69};
911 
912   std::optional<F5Results> results = F5(
913       kDhKey, kInitiatorNonce, kResponderNonce, kInitiatorAddr, kResponderAddr);
914 
915   ASSERT_TRUE(results.has_value());
916   EXPECT_EQ(kExpectedMacKey, results->mac_key);
917   EXPECT_EQ(kExpectedLtk, results->ltk);
918 }
919 
920 // Using the sample data from Vol 3, Part H, Appendix D.4
TEST(UtilTest,F6)921 TEST(UtilTest, F6) {
922   const UInt128 kMacKey{0x20,
923                         0x6E,
924                         0x63,
925                         0xCE,
926                         0x20,
927                         0x6A,
928                         0x3F,
929                         0xFD,
930                         0x02,
931                         0x4A,
932                         0x08,
933                         0xA1,
934                         0x76,
935                         0xF1,
936                         0x65,
937                         0x29};
938   const UInt128 kN1{0xAB,
939                     0xAE,
940                     0x2B,
941                     0x71,
942                     0xEC,
943                     0xB2,
944                     0xFF,
945                     0xFF,
946                     0x3E,
947                     0x73,
948                     0x77,
949                     0xD1,
950                     0x54,
951                     0x84,
952                     0xCB,
953                     0xD5};
954   const UInt128 kN2{0xCF,
955                     0xC4,
956                     0x3D,
957                     0xFF,
958                     0xF7,
959                     0x83,
960                     0x65,
961                     0x21,
962                     0x6E,
963                     0x5F,
964                     0xA7,
965                     0x25,
966                     0xCC,
967                     0xE7,
968                     0xE8,
969                     0xA6};
970   const UInt128 kR{0xC8,
971                    0x0F,
972                    0x2D,
973                    0x0C,
974                    0xD2,
975                    0x42,
976                    0xDA,
977                    0x08,
978                    0x54,
979                    0xBB,
980                    0x53,
981                    0xB4,
982                    0x3B,
983                    0x34,
984                    0xA3,
985                    0x12};
986   const AuthReqField auth_req = 0x01;
987   const auto oob = static_cast<OOBDataFlag>(0x01);
988   const auto io_cap = static_cast<IOCapability>(0x02);
989   const DeviceAddress a1(DeviceAddress::Type::kLEPublic,
990                          {0xCE, 0xBF, 0x37, 0x37, 0x12, 0x56});
991   const DeviceAddress a2(DeviceAddress::Type::kLEPublic,
992                          {0xC1, 0xCF, 0x2D, 0x70, 0x13, 0xA7});
993   const UInt128 kExpectedF6Out{0x61,
994                                0x8F,
995                                0x95,
996                                0xDA,
997                                0x09,
998                                0x0B,
999                                0x6C,
1000                                0xD2,
1001                                0xC5,
1002                                0xE8,
1003                                0xD0,
1004                                0x9C,
1005                                0x98,
1006                                0x73,
1007                                0xC4,
1008                                0xE3};
1009 
1010   std::optional<UInt128> f6_out =
1011       F6(kMacKey, kN1, kN2, kR, auth_req, oob, io_cap, a1, a2);
1012 
1013   ASSERT_TRUE(f6_out.has_value());
1014   EXPECT_EQ(kExpectedF6Out, *f6_out);
1015 }
1016 
1017 // Using the sample data from Vol 3, Part H, Appendix D.5
TEST(UtilTest,G2)1018 TEST(UtilTest, G2) {
1019   const UInt256 kInitiatorPubKeyX{
1020       0xE6, 0x9D, 0x35, 0x0E, 0x48, 0x01, 0x03, 0xCC, 0xDB, 0xFD, 0xF4,
1021       0xAC, 0x11, 0x91, 0xF4, 0xEF, 0xB9, 0xA5, 0xF9, 0xE9, 0xA7, 0x83,
1022       0x2C, 0x5E, 0x2C, 0xBE, 0x97, 0xF2, 0xD2, 0x03, 0xB0, 0x20};
1023   const UInt256 kResponderPubKeyX{
1024       0xFD, 0xC5, 0x7F, 0xF4, 0x49, 0xDD, 0x4F, 0x6B, 0xFB, 0x7C, 0x9D,
1025       0xF1, 0xC2, 0x9A, 0xCB, 0x59, 0x2A, 0xE7, 0xD4, 0xEE, 0xFB, 0xFC,
1026       0x0A, 0x90, 0x9A, 0xBB, 0xF6, 0x32, 0x3D, 0x8B, 0x18, 0x55};
1027   const UInt128 kInitiatorNonce{0xAB,
1028                                 0xAE,
1029                                 0x2B,
1030                                 0x71,
1031                                 0xEC,
1032                                 0xB2,
1033                                 0xFF,
1034                                 0xFF,
1035                                 0x3E,
1036                                 0x73,
1037                                 0x77,
1038                                 0xD1,
1039                                 0x54,
1040                                 0x84,
1041                                 0xCB,
1042                                 0xD5};
1043   const UInt128 kResponderNonce{0xCF,
1044                                 0xC4,
1045                                 0x3D,
1046                                 0xFF,
1047                                 0xF7,
1048                                 0x83,
1049                                 0x65,
1050                                 0x21,
1051                                 0x6E,
1052                                 0x5F,
1053                                 0xA7,
1054                                 0x25,
1055                                 0xCC,
1056                                 0xE7,
1057                                 0xE8,
1058                                 0xA6};
1059   const uint32_t kExpectedG2Out = 0x2f9ed5ba;
1060 
1061   std::optional<uint32_t> g2_out = G2(
1062       kInitiatorPubKeyX, kResponderPubKeyX, kInitiatorNonce, kResponderNonce);
1063 
1064   ASSERT_TRUE(g2_out.has_value());
1065   EXPECT_EQ(kExpectedG2Out, *g2_out);
1066 }
1067 
1068 // Using the sample data from v5.2 Vol. 3, Part H, Appendix D.6
TEST(UtilTest,H6)1069 TEST(UtilTest, H6) {
1070   const UInt128 kKeyBytes = {0x9B,
1071                              0x7D,
1072                              0x39,
1073                              0x0A,
1074                              0xA6,
1075                              0x10,
1076                              0x10,
1077                              0x34,
1078                              0x05,
1079                              0xAD,
1080                              0xC8,
1081                              0x57,
1082                              0xA3,
1083                              0x34,
1084                              0x02,
1085                              0xEC};
1086   const uint32_t kKeyId = 0x6c656272;
1087   const UInt128 kExpectedH6Out = {0x99,
1088                                   0x63,
1089                                   0xB1,
1090                                   0x80,
1091                                   0xE2,
1092                                   0xA9,
1093                                   0xD3,
1094                                   0xE8,
1095                                   0x1C,
1096                                   0xC9,
1097                                   0x6D,
1098                                   0xE7,
1099                                   0x02,
1100                                   0xE1,
1101                                   0x9A,
1102                                   0x2D};
1103 
1104   std::optional<UInt128> h6_out = H6(kKeyBytes, kKeyId);
1105   ASSERT_TRUE(h6_out.has_value());
1106   ASSERT_EQ(kExpectedH6Out, *h6_out);
1107 }
1108 
1109 // Using the sample data from v5.2 Vol. 3, Part H, Appendix D.8
TEST(UtilTest,H7)1110 TEST(UtilTest, H7) {
1111   const UInt128 kKeyBytes = {0x9B,
1112                              0x7D,
1113                              0x39,
1114                              0x0A,
1115                              0xA6,
1116                              0x10,
1117                              0x10,
1118                              0x34,
1119                              0x05,
1120                              0xAD,
1121                              0xC8,
1122                              0x57,
1123                              0xA3,
1124                              0x34,
1125                              0x02,
1126                              0xEC};
1127   const UInt128 kSalt = {0x31,
1128                          0x70,
1129                          0x6D,
1130                          0x74,
1131                          0x00,
1132                          0x00,
1133                          0x00,
1134                          0x00,
1135                          0x00,
1136                          0x00,
1137                          0x00,
1138                          0x00,
1139                          0x00,
1140                          0x00,
1141                          0x00,
1142                          0x00};
1143   const UInt128 kExpectedH7Out = {0x11,
1144                                   0x70,
1145                                   0xA5,
1146                                   0x75,
1147                                   0x2A,
1148                                   0x8C,
1149                                   0x99,
1150                                   0xD2,
1151                                   0xEC,
1152                                   0xC0,
1153                                   0xA3,
1154                                   0xC6,
1155                                   0x97,
1156                                   0x35,
1157                                   0x17,
1158                                   0xFB};
1159 
1160   std::optional<UInt128> h7_out = H7(kSalt, kKeyBytes);
1161   ASSERT_TRUE(h7_out.has_value());
1162   ASSERT_EQ(kExpectedH7Out, *h7_out);
1163 }
1164 
1165 // Using the sample data from v5.2 Vol. 3, Part H, Appendix D.9
TEST(UtilTest,LtkToLinkKeyUsingH7)1166 TEST(UtilTest, LtkToLinkKeyUsingH7) {
1167   const UInt128 kLtkBytes = {0x64,
1168                              0xBF,
1169                              0x4F,
1170                              0x33,
1171                              0x33,
1172                              0x6C,
1173                              0x06,
1174                              0xBD,
1175                              0x58,
1176                              0x4B,
1177                              0x26,
1178                              0xE3,
1179                              0xBC,
1180                              0xF9,
1181                              0x8D,
1182                              0x36};
1183   const UInt128 kExpectedLinkKeyBytes = {0x35,
1184                                          0xB8,
1185                                          0x47,
1186                                          0x30,
1187                                          0xF4,
1188                                          0xF1,
1189                                          0x39,
1190                                          0x0A,
1191                                          0x53,
1192                                          0x02,
1193                                          0xA4,
1194                                          0xDC,
1195                                          0x79,
1196                                          0xD3,
1197                                          0x7A,
1198                                          0x28};
1199   std::optional<UInt128> out_link_key =
1200       LeLtkToBrEdrLinkKey(kLtkBytes, CrossTransportKeyAlgo::kUseH7);
1201 
1202   ASSERT_TRUE(out_link_key.has_value());
1203   EXPECT_EQ(kExpectedLinkKeyBytes, *out_link_key);
1204 }
1205 
1206 // Using the sample data from v5.2 Vol. 3, Part H, Appendix D.10
TEST(UtilTest,LtkToLinkKeyUsingH6)1207 TEST(UtilTest, LtkToLinkKeyUsingH6) {
1208   const UInt128 kLtkBytes = {0x64,
1209                              0xBF,
1210                              0x4F,
1211                              0x33,
1212                              0x33,
1213                              0x6C,
1214                              0x06,
1215                              0xBD,
1216                              0x58,
1217                              0x4B,
1218                              0x26,
1219                              0xE3,
1220                              0xBC,
1221                              0xF9,
1222                              0x8D,
1223                              0x36};
1224   const UInt128 kExpectedLinkKeyBytes = {0xB0,
1225                                          0x8F,
1226                                          0x38,
1227                                          0xEE,
1228                                          0xAF,
1229                                          0x30,
1230                                          0x82,
1231                                          0x0D,
1232                                          0xBD,
1233                                          0xC1,
1234                                          0x3F,
1235                                          0x63,
1236                                          0xEF,
1237                                          0xA4,
1238                                          0x1C,
1239                                          0xBC};
1240   std::optional<UInt128> out_link_key =
1241       LeLtkToBrEdrLinkKey(kLtkBytes, CrossTransportKeyAlgo::kUseH6);
1242 
1243   ASSERT_TRUE(out_link_key.has_value());
1244   EXPECT_EQ(kExpectedLinkKeyBytes, *out_link_key);
1245 }
1246 }  // namespace
1247 }  // namespace bt::sm::util
1248