Re: [PATCH] pre-shared passcode: secure pairing for "no keyboard, no display" devices

From: Emil Lenngren
Date: Fri Feb 15 2019 - 07:22:00 EST


Hi,
Den fre 15 feb. 2019 kl 12:46 skrev Pavel Machek <pavel@xxxxxx>:
>
> Hi!
>
> > > Currently, "no keyboard, no display" devices can be paired, but
> > > pairing is not secure against active attacker.
> > >
> > > Can we do better? Not for the first pairing; but for the next ones --
> > > yes, I believe we can.
> > >
> > > BLE device in this case has internal storage, and Linux running
> > > there. From factory, random 6-digit number is stored in the
> > > flash. Legitimate user knows the number, and system is manipulated so
> > > that pairing passkey will be this pre-shared passkey. After pairing,
> > > user is allowed to change it.
> > >
> > > [Or maybe passkey is 000000 from the factory; this is still win for
> > > the user, as long as he can change the key to something random in a
> > > secure cave.]
> > >
> > > Fortunately, kernel support for this is rather easy; patch is attached
> > > below.
> > >
> > > Does someone see a security issue with proposal above?
> >
> > Assuming "LE Secure Connections" is used, the protocol is only secure
> > if the passkey is not reused. A 6 digit passkey means 20 bits. The
> > protocol is performed in 20 steps, where one bit is compared and
> > revealed in every step. This means the attacker will know for every
> > attempt the first bit that is incorrect in the attempted passkey. If
> > the passkey is reused, the attacker can just try the same passkey with
> > the incorrect bit flipped. In average it takes 10 attempts to crack
> > the key and maximum 20 attempts. Hence, a static key doesn't really
> > add much security compared to Just Works and might give a false sense
> > of security.
>
> Thanks a lot for quick reply. And no, that is not good.
>
> Just Works basically means that there's no security at all, anyone
> within range can connect when owner is not around, and do whatever
> they want.
>
> Is there some common way this is solved?
>
> We do have pre-shared passkey, if only 20 bits. If we set
> passkey = sha( pre-shared passkey + pairing_attempt++ ), would we get
> some kind of meaningful security? Perhaps with limiting pairing
> attempt to say 10 a day?

I see two issues with that approach. First, the user needs to know the
correct counter of pairing_attempt (how?) and perform the sha
calculation and map that to a passkey. Second, if you eavesdrop a
pairing attempt that succeeds, you can just bruteforce sha over all
possible pre-shared passkeys (1 million if you have 6 digits) times
the number of different pairing_attempt counters you want to test, and
match that with the recorded pairing messages. That shouldn't take
more than a few seconds on a normal PC.

What people really do that wants proper security over BLE when they
need to use static passkeys, is using a PAKE algorithm in the
application layer to establish a session key, and then use some AEAD
cipher with that session key also in the application layer (or
potentially start BLE encryption using that session key as LTK, but I
haven't seen that). Unencrypted BLE is just used then as a transport
layer.

/Emil