1# -*- coding: utf-8 -*-
2# Copyright 2019 Oticon A/S
3# SPDX-License-Identifier: Apache-2.0
4
5from components.utils import *;
6from components.basic_commands import *;
7from components.address import *;
8from components.smpdata import *;
9from components.events import *;
10
11"""
12    Pairing is used to establish an encrypted link between two parties.
13    - The two parties can be two entities running without Host layer.
14    - The two parties can also be one entity running without Host layer (initiator) and one entity running with Host layer (responder).
15    - All the necessary keys willl be generated and exchanged between the parties.
16    - After a successful exchange of random numbers - the link will be encrypted.
17    - After the link has been encrypted - encryption keys will be exchanged.
18"""
19class Pairing:
20    """
21        Constructor:
22            transport - PTTT_bsim object
23            trace     - Trace object
24            initiator - Initiator object representing the connection between the parties
25            IRKm      - Number: Identity Resolving Key for Initiator
26            IRKs      - Number: Identity Resolving Key for Responder (only needed if Responder is running without Host layer)
27    """
28    def __init__(self, transport, trace, initiator, IRKm, IRKs=None):
29        self.transport = transport;
30        self.initiator = initiator;
31        self.trace = trace;
32        self.IRKm = IRKm;
33        self.IRKs = IRKs;
34        self.rand = self.ediv = self.ltk = 0;
35
36    """
37        Send an SMP Protocol request from device with index <idx> to the other device
38
39        Arguments:
40            idx    - Number: holding the index of the device that sends the request
41            txData - List:   containing the SMP PDU to send
42    """
43    def __request(self, idx, txData):
44        status = le_data_write(self.transport, idx, self.initiator.handles[idx], 0, 0, txData, 100);
45        success = status == 0;
46        dataSent = False;
47
48        while success and not dataSent:
49            dataSent = has_event(self.transport, idx, 100)[0];
50            success = success and dataSent;
51            if dataSent:
52                event = get_event(self.transport, idx, 100);
53              # showEvent(event, eventData, self.trace);
54                dataSent = event.event == Events.BT_HCI_EVT_NUM_COMPLETED_PACKETS;
55
56        return dataSent;
57
58    """
59        Receive a SMP Protocol request/response in device with index <idx>
60
61        Arguments:
62            idx - Number: holding the index of the device that receives the request/response
63    """
64    def __response(self, idx):
65        success, rxData = True, [];
66
67        dataReady = le_data_ready(self.transport, idx, 100);
68        if dataReady:
69            rxPBFlags, rxBCFlags, rxData = le_data_read(self.transport, idx, 100)[2:];
70
71        return (len(rxData) > 0), rxData;
72
73    """
74        Generate an 8 octet random number...
75
76        Arguments:
77            idx - Number: holding the index of the device in which the random number is generated
78    """
79    def __random(self, idx):
80        status, rand = le_rand(self.transport, idx, 100);
81        success = status == 0;
82        event = get_event(self.transport, idx, 100);
83        success = success and event.isCommandComplete();
84        return success, toNumber(rand);
85
86    """
87        Generate a 16 octet random number...
88
89        Arguments:
90            idx - Number: holding the index of the device in which the random number is generated
91    """
92    def __random128(self, idx):
93        success, randL = self.__random(idx);
94        if success:
95            success, randU = self.__random(idx);
96            randL = (randU << 64) | randL;
97        return success, randL;
98
99    """
100        Encrypt <plaintext> with the key <key>...
101
102        Arguments:
103            idx       - Number: holding the index of the device in which the encryption takes place
104            key       - Number: containing the key to use
105            plaintext - Number: containing the message to be encrypted
106    """
107    def __encrypt(self, idx, key, plaintext):
108        status, encrypted = le_encrypt(self.transport, idx, toArray(key, 16), toArray(plaintext, 16), 2000);
109        success = status == 0;
110        event = get_event(self.transport, idx, 100);
111        success = success and event.isCommandComplete();
112        return success, toNumber(encrypted);
113
114    """
115        Calculate the Pairing Confirm value:
116
117        Arguments:
118            idx  - Number: holding the index of the device in which the calculation takes place
119            tk   - Number: containing a temporare key to use (0 for Just Works)
120            rand - Number: containing a 128 bit random number
121            preq - List: containing the full pairing request PDU
122            pres - List: containing the full pairing response PDU
123            ia   - Address object: containing the address of the initiator (address and address-type)
124            ra   - Address object: containing the address of the responder (address and address-type)
125
126        Calculations:
127            p1 = pres || preq || rat || iat
128            p2 = ia || ra
129            c1 = e(tk, e(tk, rand XOR p1) XOR p2)
130    """
131    def __calcConfirm(self, idx, tk, rand, preq, pres, ia, ra):
132        p1 = (((((pres << 56) | preq) << 8) | ra.type) << 8) | ia.type;
133        p2 = (toNumber(ia.address) << 48) | toNumber(ra.address);
134        p1 ^= rand;
135        success, p1 = self.__encrypt(idx, tk, p1);
136        p1 ^= p2;
137        success, p1 = self.__encrypt(idx, tk, p1);
138        return success, p1;
139
140    """
141        Calculate the Pairing Short Term Key (STK):
142
143        Arguments:
144            idx - Number: holding the index of the device in which the calculation takes place
145            tk  - Number: containing a temporare key to use (0 for Just Works)
146            r1  - Number: containing a 128 bit random number
147            r2  - Number: containing a 128 bit random number
148
149        Calculations:
150            r1 = <limit to 64 bits>
151            r2 = <limit to 64 bits>
152             r = r1 || r2
153            s1 = e(tk, r)
154    """
155    def __calcSTK(self, idx, tk, r1, r2):
156        r1 &= 0x00FFFFFFFFFFFFFFFF;
157        r2 &= 0x00FFFFFFFFFFFFFFFF;
158        r1 = (r1 << 64) | r2;
159        success, r1 = self.__encrypt(idx, tk, r1);
160        return success, r1;
161
162    """
163        Calculate the Pairing Long Term Key (LTK):
164
165        Arguments:
166            idx - Number: holding the index of the device in which the calculation takes place
167            er  - Number: containing the encryption root (128 bit)
168            div - Number: containing the diversifier (16 bits)
169
170        Calculations:
171            LTK = d1(ER, DIV, 0)
172
173            k = ER  is 128 bits
174            d = DIV is 16 bits
175            r = 0
176            d' = padding || r || d
177            d1 = e(k, d')
178    """
179    def __calcLTK(self, idx, er, div):
180        success, d1 = self.__encrypt(idx, er, div & 0xFFFF);
181        return success, d1;
182
183    """
184        Calculate DIV masking
185
186        Arguments:
187            idx - Number: holding the index of the device in which the calculation takes place
188            k   - Number: containing the Diversifier Hiding Key (128 bit)
189            r   - Number: containing a 64 bit random number
190
191        Calculations:
192            k is 128 bits
193            r is 64 bits (padded to 128 bits)
194            r' = padding || r
195
196            dm(k, r') = e(k, r') mod 2^16
197    """
198    def __calcDIVMask(self, idx, k, r):
199        success, dm = self.__encrypt(idx, k, r);
200        return success, (dm & 0x00FFFF);
201
202    """
203        Generate EDIV for distribution (Encrypted Diversifier)
204
205        Arguments:
206            idx  - Number: holding the index of the device in which the calculation takes place
207            dhk  - Number: containing the Diversifier Hiding Key (128 bit)
208            rand - Number: containing a 64 bit random number
209            div  - Number: containing the diversifier
210
211        Calculations:
212            k = DHK (Diversifier Hiding Key) is 128 bit
213            r = Rand is 64 bit
214
215            Y = dm(DHK, Rand)
216            EDIV = Y XOR DIV
217    """
218    def __generateEDIV(self, idx, dhk, rand, div):
219        success, y = self.__calcDIVMask(idx, dhk, rand);
220        return success, (div ^ y);
221
222    """
223        Recover DIV from distribution (from Encrypted Diversifier)
224
225        Arguments:
226            idx  - Number: holding the index of the device in which the calculation takes place
227            dhk  - Number: containing the Diversifier Hiding Key (128 bit)
228            rand - Number: containing a 64 bit random number
229            ediv - Number: containing the Encrypted Diversifier
230
231        Calculations:
232            k = DHK (Diversifier Hiding Key) is 128 bit
233            r = Rand is 64 bit
234
235            Y = dm(DHK, Rand)
236            DIV = Y XOR EDIV
237    """
238    def __recoverDIV(self, idx, dhk, rand, ediv):
239        success, y = self.__calcDIVMask(idx, dhk, rand);
240        return success, (ediv ^ y);
241
242    """
243        Calculate keys to be distributed
244
245        Arguments:
246            idx - Number: holding the index of the device in which the calculation takes place
247
248        Calculations:
249            ir   : Identity Root   (unique to each device)
250            er   : Encryption Root (unique to each device)
251            dhk  = e(ir, 2)
252            div  : random 128 bit number
253            ltk  = d1(er, div, 0)
254            rand : random 64 bit number
255            ediv = dm(dhk, rand) XOR div
256    """
257    def __calculateKeys(self, idx):
258        ir = er = 0x00112233445566778899AABBCCDDEEFF if idx == 0 else 0x112233445566778899AABBCCDDEEFF00;
259
260        success, dhk = self.__encrypt(idx, ir, 0x02);
261        success, div = self.__random128(idx);
262        success, ltk = self.__calcLTK(idx, er, div);
263        success, rand = self.__random(idx);
264        success, ediv = self.__generateEDIV(idx, dhk, rand, div);
265        ediv &= 0x00FFFF;
266
267        return success, ediv, rand, ltk;
268
269    def __publicKey(self):
270        status = 0;
271
272    """
273        Prepare for pairing by exchanging requirements and capabilities...
274
275                SMP_PAIRING_REQUEST -->
276            <-- SMP_PAIRING_RESPONSE
277    """
278    def __capabilities(self, authRequest):
279        smpData = SMPData();
280        reply = { };
281
282        distKeys = SMPDistribution.SMP_DST_ENCKEY | SMPDistribution.SMP_DST_IDKEY;
283
284        txiData = smpData.encode( SMPOpcode.SMP_PAIRING_REQUEST, SMPCapability.SMP_CAP_NO_INPUT_NO_OUTPUT, SMPOOBFlag.SMP_OOB_NO_AUTH_DATA, authRequest, 16, distKeys, distKeys );
285        success = self.__request( self.initiator.initiator, txiData );
286        while success:
287            if not self.initiator.peer is None:
288                success, rxrData = self.__response( self.initiator.peer );
289                if not success:
290                    break;
291                reply = smpData.decode( rxrData );
292                success = reply["opcode"] == SMPOpcode.SMP_PAIRING_REQUEST;
293                if not success:
294                    break;
295                txrData = smpData.encode( SMPOpcode.SMP_PAIRING_RESPONSE, SMPCapability.SMP_CAP_NO_INPUT_NO_OUTPUT, SMPOOBFlag.SMP_OOB_NO_AUTH_DATA, authRequest, 16, distKeys, distKeys );
296                success = self.__request( self.initiator.peer, txrData );
297                if not success:
298                    break;
299
300            success, rxiData = self.__response( self.initiator.initiator );
301            if not success:
302                break;
303            reply = smpData.decode( rxiData );
304            success = reply["opcode"] == SMPOpcode.SMP_PAIRING_RESPONSE;
305            if not success:
306                break;
307
308            self.pRequest  = toNumber(txiData[4:]);
309            self.pResponse = toNumber(rxiData[4:]);
310
311            break;
312
313        return success, reply;
314
315    """
316        Prepare for pairing by exchanging random numbers...
317
318                SMP_PAIRING_CONFIRM -->
319            <-- SMP_PAIRING_CONFIRM
320                SMP_PAIRING_RANDOM  -->
321            <-- SMP_PAIRING_RANDOM
322
323        Finally calculate the STK to use for encrypting the connection.
324    """
325    def __legacyPairing(self, ia, ra):
326        smpData = SMPData();
327        success = True;
328        stk = 0;
329
330        while success:
331            success, mRand = self.__random128( self.initiator.initiator );
332            if not success:
333                break;
334            success, mConfirm = self.__calcConfirm( self.initiator.initiator, 0, mRand, self.pRequest, self.pResponse, ia, ra );
335            if not success:
336                break;
337            txData = smpData.encode( SMPOpcode.SMP_PAIRING_CONFIRM, mConfirm );
338            success = self.__request( self.initiator.initiator, txData );
339            if not success:
340                break;
341            """
342                If peer device doesn't have a Host layer to process the SMP_PAIRING_CONFIRM message, we need to do it...
343            """
344            if not self.initiator.peer is None:
345                success, rxData = self.__response( self.initiator.peer );
346                if not success:
347                    break;
348                reply = smpData.decode( rxData );
349                success = reply["opcode"] == SMPOpcode.SMP_PAIRING_CONFIRM;
350                if not success:
351                    break;
352                success, sRand = self.__random128( self.initiator.peer );
353                if not success:
354                    break;
355                success, sConfirm = self.__calcConfirm( self.initiator.peer, 0, sRand, self.pRequest, self.pResponse, ia, ra );
356                if not success:
357                    break;
358                txData = smpData.encode( SMPOpcode.SMP_PAIRING_CONFIRM, sConfirm );
359                success = self.__request( self.initiator.peer, txData );
360
361            success, rxData = self.__response( self.initiator.initiator );
362            if not success:
363                break;
364            reply = smpData.decode( rxData );
365            success = reply["opcode"] == SMPOpcode.SMP_PAIRING_CONFIRM;
366            if not success:
367                break;
368
369            sConfirm = reply["value"];
370
371            txData = smpData.encode( SMPOpcode.SMP_PAIRING_RANDOM, mRand );
372            success = self.__request( self.initiator.initiator, txData );
373            if not success:
374                break;
375            """
376                If peer device doesn't have a Host layer to process the SMP_PAIRING_RANDOM message, we need to do it...
377            """
378            if not self.initiator.peer is None:
379                success, rxData = self.__response( self.initiator.peer );
380                if not success:
381                    break;
382                reply = smpData.decode( rxData );
383                success = reply["opcode"] == SMPOpcode.SMP_PAIRING_RANDOM;
384                if not success:
385                    break;
386
387                success, xConfirm = self.__calcConfirm( self.initiator.peer, 0, mRand, self.pRequest, self.pResponse, ia, ra );
388                if not success:
389                    break;
390                success = xConfirm == mConfirm;
391                if not success:
392                    txData = smpData.encode( SMPOpcode.SMP_PAIRING_FAILED, SMPError.SMP_ERROR_CONFIRM );
393                    success = self.__request( self.initiator.peer, txData );
394                else:
395                    txData = smpData.encode( SMPOpcode.SMP_PAIRING_RANDOM, sRand );
396                    success = self.__request( self.initiator.peer, txData );
397                if not success:
398                    break;
399
400            success, rxData = self.__response( self.initiator.initiator );
401            if not success:
402                break;
403            reply = smpData.decode( rxData );
404            success = reply["opcode"] == SMPOpcode.SMP_PAIRING_RANDOM;
405            if not success:
406                break;
407
408            sRand = reply["value"];
409
410            success, xConfirm = self.__calcConfirm( self.initiator.initiator, 0, sRand, self.pRequest, self.pResponse, ia, ra );
411            if not success:
412                break;
413            success = xConfirm == sConfirm;
414            if not success:
415                txData = smpData.encode( SMPOpcode.SMP_PAIRING_FAILED, SMPError.SMP_ERROR_CONFIRM );
416                self.__request( self.initiator.initiator, txData );
417                break;
418
419            success, stk = self.__calcSTK( self.initiator.initiator, 0, sRand, mRand );
420            break;
421
422        return success, stk;
423
424    """
425        Encrypt the link.
426
427
428    """
429    def __encryptLink(self, rand, ediv, ltk):
430        status = le_start_encryption(self.transport, self.initiator.initiator, self.initiator.handles[0], rand, ediv, toArray(ltk, 16), 200);
431        success = status == 0;
432        event = get_event(self.transport, self.initiator.initiator, 100);
433        self.trace.trace(7, str(event));
434        success = success and event.isCommandStatus();
435        while success:
436
437            if not self.initiator.peer is None:
438                success = has_event(self.transport, self.initiator.peer, 100)[0];
439                while success:
440                    event = get_event(self.transport, self.initiator.peer, 100);
441                    self.trace.trace(7, str(event));
442                    success = event.subEvent == MetaEvents.BT_HCI_EVT_LE_LTK_REQUEST;
443                    if not success:
444                        break;
445                    handle = event.decode()[0];
446                    status, handle = le_long_term_key_request_reply(self.transport, self.initiator.peer, handle, toArray(ltk, 16), 200);
447                    success = status == 0;
448                    if not success:
449                        break;
450                    event = get_event(self.transport, self.initiator.peer, 100);
451                    self.trace.trace(7, str(event));
452                    success = event.event == Events.BT_HCI_EVT_CMD_COMPLETE;
453                    if not success:
454                        break;
455                    success = has_event(self.transport, self.initiator.peer, 1000)[0];
456                    if not success:
457                        break;
458                    event = get_event(self.transport, self.initiator.peer, 100);
459                    self.trace.trace(7, str(event));
460                    success = (event.event == Events.BT_HCI_EVT_ENCRYPT_CHANGE_V1) or (event.event == Events.BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE);
461                    if not success:
462                        break;
463                    if event.event == Events.BT_HCI_EVT_ENCRYPT_CHANGE_V1:
464                        status, handle, enabled = event.decode();
465                        success = (status == 0) and (enabled == 1);
466                    else:
467                        status, handle = event.decode();
468                        success = status == 0;
469                    break;
470
471            if not success:
472                break;
473            success = has_event(self.transport, self.initiator.initiator, 1000)[0];
474            if not success:
475                break;
476            event = get_event(self.transport, self.initiator.initiator, 100)[1:];
477            self.trace.trace(7, str(event));
478            success = (event.event == Events.BT_HCI_EVT_ENCRYPT_CHANGE_V1) or (event.event == Events.BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE);
479            if not success:
480                break;
481            if event.event == Events.BT_HCI_EVT_ENCRYPT_CHANGE_V1:
482                status, handle, enabled = event.decode();
483                success = (status == 0) and (enabled == 1);
484            else:
485                status, handle = event.decode();
486                success = status == 0;
487            break;
488
489        return success;
490
491    """
492        Distribute Initiators keys...
493
494            LTK, EDIV, Rand, IRK, Address and Address Type are send to the peer.
495    """
496    def __sendInitiatorKeys(self, ltk, ediv, rand, irk):
497        smpData = SMPData();
498
499        txData = smpData.encode( SMPOpcode.SMP_ENCRYPTION_INFORMATION, ltk );
500        success = self.__request( self.initiator.initiator, txData );
501        while success:
502            txData = smpData.encode( SMPOpcode.SMP_CENTRAL_IDENTIFICATION, ediv, rand );
503            success = self.__request( self.initiator.initiator, txData );
504            if not success:
505                break;
506            txData = smpData.encode( SMPOpcode.SMP_IDENTITY_INFORMATION, irk );
507            success = self.__request( self.initiator.initiator, txData );
508            if not success:
509                break;
510            txData = smpData.encode( SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION, self.initiator.initiatorAddress.type, toNumber( self.initiator.initiatorAddress.address ) );
511            success = self.__request( self.initiator.initiator, txData );
512            break;
513        return success;
514
515    """
516        Distribute Responder keys...
517
518            LTK, EDIV, Rand, IRK, Address and Address Type are send to the initiator.
519    """
520    def __sendResponderKeys(self, ltk, ediv, rand, irk):
521        smpData = SMPData();
522
523        txData = smpData.encode( SMPOpcode.SMP_ENCRYPTION_INFORMATION, ltk );
524        success = self.__request( self.initiator.peer, txData );
525        while success:
526            txData = smpData.encode( SMPOpcode.SMP_CENTRAL_IDENTIFICATION, ediv, rand );
527            success = self.__request( self.initiator.peer, txData );
528            if not success:
529                break;
530            txData = smpData.encode( SMPOpcode.SMP_IDENTITY_INFORMATION, irk );
531            success = self.__request( self.initiator.peer, txData );
532            if not success:
533                break;
534            txData = smpData.encode( SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION, self.initiator.peerAddress.type, toNumber( self.initiator.peerAddress.address ) );
535            success = self.__request( self.initiator.peer, txData );
536            break;
537        return success;
538
539    """
540        Receive keys send by the Responder...
541
542            LTK, EDIV, Rand, IRK, Address and Address Type are received.
543    """
544    def __recvResponderKeys(self):
545        smpData = SMPData();
546
547        LTKs, EDIVs, RANDs, IRKs, address, addressType = 0, 0, 0, 0, 0, 0;
548
549        mask  = (1<<SMPOpcode.SMP_ENCRYPTION_INFORMATION) | (1<<SMPOpcode.SMP_CENTRAL_IDENTIFICATION);
550        mask |= (1<<SMPOpcode.SMP_IDENTITY_INFORMATION) | (1<<SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION);
551        recv = 0;
552        success = True;
553
554        while success and ((recv & mask) != mask):
555            success, rxData = self.__response( self.initiator.initiator );
556            if not success:
557                break;
558            reply = smpData.decode( rxData );
559
560            recv |= 1<<reply["opcode"];
561
562            if   reply["opcode"] == SMPOpcode.SMP_ENCRYPTION_INFORMATION:
563               success = True;
564               LTKs = reply["ltk"];
565            elif reply["opcode"] == SMPOpcode.SMP_CENTRAL_IDENTIFICATION:
566               success = True;
567               EDIVs = reply["ediv"];
568               RANDs = reply["rand"];
569            elif reply["opcode"] == SMPOpcode.SMP_IDENTITY_INFORMATION:
570               success = True;
571               IRKs = reply["irk"];
572            elif reply["opcode"] == SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION:
573               success = True;
574               address = reply["address"];
575               addressType = reply["type"];
576            else:
577               success = False;
578
579            if not success:
580                break;
581        return success, LTKs, EDIVs, RANDs, IRKs, address, addressType;
582
583    """
584        Receive keys send by the Initiator...
585
586            LTK, EDIV, Rand and IRK are received.
587    """
588    def __recvInitiatorKeys(self):
589        smpData = SMPData();
590
591        LTKm, EDIVm, RANDm, IRKm, address, addressType = 0, 0, 0, 0, 0, 0;
592
593        mask  = (1<<SMPOpcode.SMP_ENCRYPTION_INFORMATION) | (1<<SMPOpcode.SMP_CENTRAL_IDENTIFICATION);
594        mask |= (1<<SMPOpcode.SMP_IDENTITY_INFORMATION) | (1<<SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION);
595        recv = 0;
596        success = True;
597
598        while success and ((recv & mask) != mask):
599            success, rxData = self.__response( self.initiator.peer );
600            if not success:
601                break;
602            reply = smpData.decode( rxData );
603
604            recv |= 1<<reply["opcode"];
605
606            if   reply["opcode"] == SMPOpcode.SMP_ENCRYPTION_INFORMATION:
607               success = True;
608               LTKm = reply["ltk"];
609            elif reply["opcode"] == SMPOpcode.SMP_CENTRAL_IDENTIFICATION:
610               success = True;
611               EDIVm = reply["ediv"];
612               RANDm = reply["rand"];
613            elif reply["opcode"] == SMPOpcode.SMP_IDENTITY_INFORMATION:
614               success = True;
615               IRKm = reply["irk"];
616            elif reply["opcode"] == SMPOpcode.SMP_IDENTITY_ADDRESS_INFORMATION:
617               success = True;
618               address = reply["address"];
619               addressType = reply["type"];
620            else:
621               success = False;
622
623            if not success:
624                break;
625        return success, LTKm, EDIVm, RANDm, IRKm, address, addressType;
626
627    """
628        Establish an encrypted link between parties in a connection.
629
630        First exchange capabilities and requirements to the encryption.
631        Based on the outcome of this exchange of requirements and capabilities a decision is made whether to use LE Legacy Pairing or Secure Connections Pairing.
632        Currently only LE Legacy Pairing is supported...
633
634    """
635    def pair(self):
636
637        authRequest  = SMPBondingFlag.SMP_BOND_REQUESTED | SMPMITMFlag.SMP_MITM_NONE | SMPSecureConnections.SMP_SC_NOT_SUPPORTED;
638        authRequest |= SMPKeyPressNotifications.SMP_KPN_NONE | SMPSupportH7.SMP_CT2_NO_SUPPORT;
639
640        success, reply = self.__capabilities( authRequest );
641
642        while success:
643
644            SCFlagInitiator = (authRequest & SMPSecureConnections.SMP_SC_SUPPORTED) == SMPSecureConnections.SMP_SC_SUPPORTED;
645            SCFlagResponder = (reply["auth"] & SMPSecureConnections.SMP_SC_SUPPORTED) == SMPSecureConnections.SMP_SC_SUPPORTED;
646
647            CAPFlagINitiator = OOBFlagInitiator = MITMFlagInitiator = 0;
648
649            CAPFlagResponder = reply["capability"];
650            OOBFlagResponder = (reply["oob"] & SMPOOBFlag.SMP_OOB_AUTH_DATA_PRESENT) == SMPOOBFlag.SMP_OOB_AUTH_DATA_PRESENT;
651            MITMFlagResponder = (reply["auth"] & SMPMITMFlag.SMP_MITM_REQUESTED) == SMPMITMFlag.SMP_MITM_REQUESTED;
652
653            if SCFlagInitiator and SCFlagResponder:
654                self.trace.trace(6,"Both Initiator and Responder supports Secure Connections...");
655
656            success, self.stk = self.__legacyPairing( self.initiator.initiatorAddress, self.initiator.peerAddress );
657            if not success:
658                break;
659            success = self.__encryptLink( 0, 0, self.stk );
660            if not success:
661                break;
662
663            if not self.initiator.peer is None:
664                success, ediv, rand, ltk = self.__calculateKeys( self.initiator.peer );
665                if not success:
666                    break;
667                success = self.__sendResponderKeys( ltk, ediv, rand, self.IRKs );
668                if not success:
669                    break;
670
671            success, self.LTKs, self.EDIVs, self.RANDs, self.IRKs, address, addressType = self.__recvResponderKeys( );
672            if not success:
673                break;
674
675            self.trace.trace(6, "Responders  LTK = 0x%032X" % self.LTKs);
676            self.trace.trace(6, "Responders EDIV = 0x%04X" % self.EDIVs);
677            self.trace.trace(6, "Responders RAND = 0x%016X" % self.RANDs);
678            self.trace.trace(6, "Responders  IRK = 0x%032X" % self.IRKs);
679            self.trace.trace(6, "Responders ADDR = %s" % formatAddress(toArray(address, 6), addressType));
680
681            success, self.ediv, self.rand, self.ltk = self.__calculateKeys( self.initiator.initiator );
682            if not success:
683                break;
684            success = self.__sendInitiatorKeys( self.ltk, self.ediv, self.rand, self.IRKm );
685
686            self.trace.trace(6, "Initiators  LTK = 0x%032X" % self.ltk);
687            self.trace.trace(6, "Initiators EDIV = 0x%04X" % self.ediv);
688            self.trace.trace(6, "Initiators RAND = 0x%016X" % self.rand);
689
690            if not success:
691                break;
692
693            if not self.initiator.peer is None:
694                success, LTKm, EDIVm, RANDm, IRKm, address, addressType = self.__recvInitiatorKeys( );
695                if not success:
696                    break;
697            break;
698
699        return success;
700
701    """
702        Pause encryption on the link...
703
704                LL_PAUSE_ENC_REQ -->
705            <-- LL_PAUSE_ENC_RSP
706                LL_PAUSE_ENC_RSP -->
707    """
708    def pause(self):
709        success = self.__encryptLink( 0, 0, self.stk );
710        return success;
711
712    """
713        Resume encryption on the link...
714
715                LL_ENC_REQ -->
716            <-- LL_ENC_RSP
717            <-- LL_START_ENC_REQ
718                LL_START_ENC_RSP -->
719            <-- LL_START_ENC_RSP
720    """
721    def resume(self):
722        return True;
723