File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -278,7 +278,28 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
278278 if (event->passkey .params .action == BLE_SM_IOACT_DISP) {
279279 struct ble_sm_io pkey = {0 };
280280 pkey.action = event->passkey .params .action ;
281- pkey.passkey = ble_ll_rand () % 1000000 ;
281+
282+ /*
283+ * Passkey is a 6 digits code (1'000'000 possibilities).
284+ * It is important every possible value has an equal probability
285+ * of getting generated. Simply applying a modulo creates a bias
286+ * since 2^32 is not a multiple of 1'000'000.
287+ * To prevent that, we can reject values greater than 999'999.
288+ *
289+ * Rejecting values would happen a lot since 2^32-1 is way greater
290+ * than 1'000'000. An optimisation is to use a multiple of 1'000'000.
291+ * The greatest multiple of 1'000'000 lesser than 2^32-1 is
292+ * 4'294'000'000.
293+ *
294+ * Great explanation at:
295+ * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
296+ */
297+ uint32_t passkey_rand;
298+ do {
299+ passkey_rand = ble_ll_rand ();
300+ } while (passkey_rand > 4293999999 );
301+ pkey.passkey = passkey_rand % 1000000 ;
302+
282303 bleController.SetPairingKey (pkey.passkey );
283304 systemTask.PushMessage (Pinetime::System::Messages::OnPairing);
284305 ble_sm_inject_io (event->passkey .conn_handle , &pkey);
You can’t perform that action at this time.
0 commit comments