Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b44de714 authored by Martin Brabham's avatar Martin Brabham
Browse files

OOB: Store keys and data generated for local OOB use.

Bug: 190395922
Test: Manual, test app
Tag: #feature
Change-Id: Ib88abb866ce08b99c7fbf17ac9cfb85ee0f3441e
parent 1514e057
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -1457,7 +1457,13 @@ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
      return;
    }

    if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
    // If we are doing SMP_MODEL_SEC_CONN_OOB we don't need to request OOB data
    // locally if loc_oob_flag == 0x00 b/c there is no OOB data to give.  In the
    // event the loc_oob_flag is another value, we should request the OOB data
    // locally.  Which seems to cause it to make a TK REQUEST which is used for
    // the legacy flow which requires both sides to have OOB data.
    if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB &&
        p_cb->loc_oob_flag != 0x00) {
      if (smp_request_oob_data(p_cb)) return;
    }

@@ -1948,10 +1954,21 @@ void smp_set_local_oob_random_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
                         p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
                         p_cb->sc_oob_data.loc_oob_data.randomizer, 0);

  p_cb->sc_oob_data.loc_oob_data.present = true;

  /* pass created OOB data up */
  p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT;
  smp_send_app_cback(p_cb, NULL);

  // Store the data for later use when we are paired with
  // Event though the doc above says to pass up for safe keeping it never gets
  // kept safe. Additionally, when we need the data to make a decision we
  // wouldn't have it.  This will save the sc_oob_data in the smp_keys.cc such
  // that when we receive a request to create new keys we check to see if the
  // sc_oob_data exists and utilize the keys that are stored there otherwise the
  // connector will fail commitment check and dhkey exchange.
  smp_save_local_oob_data(p_cb);

  smp_cb_cleanup(p_cb);
}

+0 −3
Original line number Diff line number Diff line
@@ -567,9 +567,6 @@ void SMP_CrLocScOobData(
                            const std::array<unsigned char, 16>&,
                            const std::array<unsigned char, 16>&)>
        callback) {
  smp_cb.local_random = bluetooth::os::GenerateRandom<16>();
  smp_cb.selected_association_model = SMP_MODEL_SEC_CONN_OOB;

  tSMP_INT_DATA smp_int_data;
  smp_sm_event(&smp_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, &smp_int_data);
}
+4 −0
Original line number Diff line number Diff line
@@ -461,4 +461,8 @@ extern bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb);
extern void print128(const Octet16& x, const uint8_t* key_name);
extern void smp_xor_128(Octet16* a, const Octet16& b);

/* Save the p_cb->sc_oob_data.loc_oob_data for later, since the p_cb gets
 * cleaned up */
extern void smp_save_local_oob_data(tSMP_CB* p_cb);

#endif /* SMP_INT_H */
+36 −0
Original line number Diff line number Diff line
@@ -55,6 +55,19 @@ static void smp_process_private_key(tSMP_CB* p_cb);

#define SMP_PASSKEY_MASK 0xfff00000

// If there is data saved here, then use its info instead
// This needs to be cleared on a successfult pairing using the oob data
static tSMP_LOC_OOB_DATA saved_local_oob_data = {};

void smp_save_local_oob_data(tSMP_CB* p_cb) {
  saved_local_oob_data = p_cb->sc_oob_data.loc_oob_data;
}

static bool is_empty(tSMP_LOC_OOB_DATA* data) {
  tSMP_LOC_OOB_DATA empty_data = {};
  return memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0;
}

void smp_debug_print_nbyte_little_endian(uint8_t* p, const char* key_name,
                                         uint8_t len) {
}
@@ -574,6 +587,29 @@ Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb) {
void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);

  // Only use the stored OOB data if we are in an oob association model
  if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
    LOG_WARN("OOB Association Model");
    // Make sure our data isn't empty, otherwise we generate new and eventually
    // pairing will fail Not much we can do about it at this point, just have to
    // generate new data The data will be cleared after the advertiser times
    // out, so if the advertiser times out we want the pairing to fail anyway.
    if (!is_empty(&saved_local_oob_data)) {
      LOG_WARN("Found OOB data, loading keys");
      memcpy(p_cb->private_key, saved_local_oob_data.private_key_used,
             BT_OCTET32_LEN);
      memcpy(p_cb->loc_publ_key.x, saved_local_oob_data.publ_key_used.x,
             BT_OCTET32_LEN);
      memcpy(p_cb->loc_publ_key.y, saved_local_oob_data.publ_key_used.y,
             BT_OCTET32_LEN);
      p_cb->sc_oob_data.loc_oob_data = saved_local_oob_data;
      p_cb->local_random = saved_local_oob_data.randomizer;
      smp_process_private_key(p_cb);
      return;
    }
    LOG_WARN("OOB Association Model with no saved data present");
  }

  btsnd_hcic_ble_rand(Bind(
      [](tSMP_CB* p_cb, BT_OCTET8 rand) {
        memcpy((void*)p_cb->private_key, rand, BT_OCTET8_LEN);