diff --git a/linux/hci/smp/context.go b/linux/hci/smp/context.go index 0dbdcde..1149f0c 100644 --- a/linux/hci/smp/context.go +++ b/linux/hci/smp/context.go @@ -89,7 +89,7 @@ func (p *pairingContext) checkPasskeyConfirm() error { kax := MarshalPublicKeyX(p.scECDHKeys.public) nb := p.remoteRandom i := p.passKeyIteration - key := p.authData.Passkey + key := p.authData.GetPasskey() //this gets the bit of the passkey for the current iteration z := 0x80 | (byte)((key&(1<>uint(i)) @@ -114,7 +114,7 @@ func (p *pairingContext) checkPasskeyConfirm() error { return nil } -//todo: key should be set at the beginning +// todo: key should be set at the beginning func (p *pairingContext) generatePassKeyConfirm() ([]byte, []byte) { kbx := MarshalPublicKeyX(p.scRemotePubKey) kax := MarshalPublicKeyX(p.scECDHKeys.public) @@ -125,7 +125,7 @@ func (p *pairingContext) generatePassKeyConfirm() ([]byte, []byte) { } i := p.passKeyIteration - z := 0x80 | (byte)((p.authData.Passkey&(1<>uint(i)) + z := 0x80 | (byte)((p.authData.GetPasskey()&(1<>uint(i)) calcConf, err := smpF4(kax, kbx, nai, z) if err != nil { @@ -176,7 +176,7 @@ func (p *pairingContext) checkDHKeyCheck() error { ra := make([]byte, 16) if p.pairingType == Passkey { keyBytes := make([]byte, 4) - binary.BigEndian.PutUint32(keyBytes, uint32(p.authData.Passkey)) + binary.BigEndian.PutUint32(keyBytes, uint32(p.authData.GetPasskey())) ra[12] = keyBytes[0] ra[13] = keyBytes[1] ra[14] = keyBytes[2] @@ -230,7 +230,7 @@ func (p *pairingContext) checkLegacyConfirm() error { k := make([]byte, 16) if p.pairingType == Passkey { - k = getLegacyParingTK(p.authData.Passkey) + k = getLegacyParingTK(p.authData.GetPasskey()) } c1, err := smpC1(k, sRand, preq, pres, p.localAddrType, diff --git a/linux/hci/smp/handler.go b/linux/hci/smp/handler.go index 97d2007..f94c67c 100644 --- a/linux/hci/smp/handler.go +++ b/linux/hci/smp/handler.go @@ -151,7 +151,7 @@ func onLegacyRandom(t *transport) ([]byte, error) { //calculate STK var k []byte if t.pairing.pairingType == Passkey { - k = getLegacyParingTK(t.pairing.authData.Passkey) + k = getLegacyParingTK(t.pairing.authData.GetPasskey()) } else { k = getLegacyParingTK(0) } @@ -314,8 +314,8 @@ func continuePassKeyPairing(t *transport) { t.send(out) } -//Core spec v5.0 Vol 3, Part H, 2.3.5.1 -//Tables 2.6, 2.7, and 2.8 +// Core spec v5.0 Vol 3, Part H, 2.3.5.1 +// Tables 2.6, 2.7, and 2.8 var ioCapsTableSC = [][]int{ {JustWorks, JustWorks, Passkey, JustWorks, Passkey}, {JustWorks, NumericComp, Passkey, JustWorks, NumericComp}, diff --git a/linux/hci/smp/transport.go b/linux/hci/smp/transport.go index 0499c77..4b6e0d1 100644 --- a/linux/hci/smp/transport.go +++ b/linux/hci/smp/transport.go @@ -153,7 +153,7 @@ func (t *transport) sendDHKeyCheck() error { rb := make([]byte, 16) if t.pairing.pairingType == Passkey { keyBytes := make([]byte, 4) - binary.BigEndian.PutUint32(keyBytes, uint32(t.pairing.authData.Passkey)) + binary.BigEndian.PutUint32(keyBytes, uint32(t.pairing.authData.GetPasskey())) rb[12] = keyBytes[0] rb[13] = keyBytes[1] rb[14] = keyBytes[2] @@ -198,7 +198,7 @@ func (t *transport) sendMConfirm() error { k := make([]byte, 16) if t.pairing.pairingType == Passkey { - k = getLegacyParingTK(t.pairing.authData.Passkey) + k = getLegacyParingTK(t.pairing.authData.GetPasskey()) } c1, err := smpC1(k, r, preq, pres, diff --git a/smp.go b/smp.go index 980a199..02d8958 100644 --- a/smp.go +++ b/smp.go @@ -1,6 +1,26 @@ package ble type AuthData struct { + // Passkey is the numeric passkey for pairing. Passkey int + + // PasskeyFn is a function that returns the passkey for pairing. + // If Passkey is not set, this function will be called to + // retrieve the passkey. + PasskeyFn func() int + + // OOBData is the out-of-band data for pairing. OOBData []byte -} \ No newline at end of file +} + +// GetPasskey returns the passkey for pairing. If Passkey is not set, +// it calls PasskeyFn to populate it. +func (a *AuthData) GetPasskey() int { + if a.Passkey != 0 { + return a.Passkey + } + if a.PasskeyFn != nil { + a.Passkey = a.PasskeyFn() + } + return a.Passkey +}