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

Commit 8f4672cf authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

smp_keys simplification am: 7660d1ec

am: 50c42a52

Change-Id: I3239ecc555586da8f31a8e00b51aaf76cd2e7bee
parents d4b9ccc4 50c42a52
Loading
Loading
Loading
Loading
+0 −20
Original line number Diff line number Diff line
@@ -205,25 +205,6 @@ enum {
};
typedef uint8_t tSMP_BR_STATE;

/* random and encrption activity state */
enum {
  SMP_GEN_COMPARE = 1,
  SMP_GEN_CONFIRM,

  SMP_GEN_DIV_LTK,
  SMP_GEN_DIV_CSRK,
  SMP_GEN_RAND_V,
  SMP_GEN_TK,
  SMP_GEN_SRAND_MRAND,
  SMP_GEN_SRAND_MRAND_CONT,
  SMP_GENERATE_PRIVATE_KEY_0_7,
  SMP_GENERATE_PRIVATE_KEY_8_15,
  SMP_GENERATE_PRIVATE_KEY_16_23,
  SMP_GENERATE_PRIVATE_KEY_24_31,
  SMP_GEN_NONCE_0_7,
  SMP_GEN_NONCE_8_15
};

enum {
  SMP_KEY_TYPE_TK,
  SMP_KEY_TYPE_CFM,
@@ -338,7 +319,6 @@ typedef struct {
  BT_OCTET16 csrk; /* storage for local CSRK */
  uint16_t ediv;
  BT_OCTET8 enc_rand;
  uint8_t rand_enc_proc_state;
  uint8_t addr_type;
  BD_ADDR local_bda;
  bool is_pair_cancel;
+187 −357
Original line number Diff line number Diff line
@@ -45,19 +45,10 @@ using base::Bind;
#define SMP_MAX_ENC_REPEAT 3
#endif

static void smp_rand_back(BT_OCTET8 rand);
static void smp_generate_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
static void smp_generate_ltk_cont(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
static void smp_generate_y(tSMP_CB* p_cb, tSMP_INT_DATA* p);
static void smp_generate_rand_vector(tSMP_CB* p_cb, tSMP_INT_DATA* p);
static void smp_process_stk(tSMP_CB* p_cb, tSMP_ENC* p);
static void smp_process_ediv(tSMP_CB* p_cb, tSMP_ENC* p);
static bool smp_calculate_legacy_short_term_key(tSMP_CB* p_cb,
                                                tSMP_ENC* output);
static void smp_continue_private_key_creation(tSMP_CB* p_cb, BT_OCTET8 rand);
static void smp_process_private_key(tSMP_CB* p_cb);
static void smp_finish_nonce_generation(tSMP_CB* p_cb);
static void smp_process_new_nonce(tSMP_CB* p_cb);

#define SMP_PASSKEY_MASK 0xfff00000

@@ -170,23 +161,6 @@ bool smp_encrypt_data(uint8_t* key, uint8_t key_len, uint8_t* plain_text,
  return true;
}

/*******************************************************************************
 *
 * Function         smp_generate_passkey
 *
 * Description      This function is called to generate passkey.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_passkey(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_TK;

  /* generate MRand or SRand */
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}

/*******************************************************************************
 *
 * Function         smp_proc_passkey
@@ -228,6 +202,21 @@ void smp_proc_passkey(tSMP_CB* p_cb, BT_OCTET8 rand) {
  }
}

/*******************************************************************************
 *
 * Function         smp_generate_passkey
 *
 * Description      This function is called to generate passkey.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_passkey(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  /* generate MRand or SRand */
  btsnd_hcic_ble_rand(Bind(&smp_proc_passkey, p_cb));
}

/*******************************************************************************
 *
 * Function         smp_generate_stk
@@ -260,91 +249,10 @@ void smp_generate_stk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  smp_process_stk(p_cb, &output);
}

/*******************************************************************************
 *
 * Function         smp_generate_srand_mrand_confirm
 *
 * Description      This function is called to start the second pairing phase by
 *                  start generating random number.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_srand_mrand_confirm(tSMP_CB* p_cb,
                                      UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_SRAND_MRAND;
  /* generate MRand or SRand */
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}

/*******************************************************************************
 *
 * Function         smp_generate_rand_cont
 *
 * Description      This function is called to generate another 64 bits random
 *                  for MRand or Srand.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_rand_cont(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_SRAND_MRAND_CONT;
  /* generate 64 MSB of MRand or SRand */
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}

/*******************************************************************************
 *
 * Function         smp_generate_ltk
 *
 * Description      This function is called:
 *                  - in legacy pairing - to calculate LTK, starting with DIV
 *                    generation;
 *                  - in LE Secure Connections pairing over LE transport - to
 *                    process LTK already generated to encrypt LE link;
 *                  - in LE Secure Connections pairing over BR/EDR transport -
 *                    to start BR/EDR Link Key processing.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  bool div_status;
  SMP_TRACE_DEBUG("%s", __func__);
  if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) {
    smp_br_process_link_key(p_cb, NULL);
    return;
  } else if (p_cb->le_secure_connections_mode_is_used) {
    smp_process_secure_connection_long_term_key();
    return;
  }

  div_status = btm_get_local_div(p_cb->pairing_bda, &p_cb->div);

  if (div_status) {
    smp_generate_ltk_cont(p_cb, NULL);
  } else {
    SMP_TRACE_DEBUG("Generate DIV for LTK");
    p_cb->rand_enc_proc_state = SMP_GEN_DIV_LTK;
    /* generate MRand or SRand */
    btsnd_hcic_ble_rand(Bind(&smp_rand_back));
  }
}

/*******************************************************************************
 *
 * Function         smp_compute_csrk
 *
 * Description      This function is called to calculate CSRK
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_compute_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
/**
 * This function is called to calculate CSRK
 */
void smp_compute_csrk(uint16_t div, tSMP_CB* p_cb) {
  BT_OCTET16 er;
  uint8_t buffer[4]; /* for (r || DIV)  r=1*/
  uint16_t r = 1;
@@ -352,7 +260,9 @@ void smp_compute_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  tSMP_ENC output;
  tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;

  SMP_TRACE_DEBUG("smp_compute_csrk div=%x", p_cb->div);
  p_cb->div = div;

  SMP_TRACE_DEBUG("%s: div=%x", __func__, p_cb->div);
  BTM_GetDeviceEncRoot(er);
  /* CSRK = d1(ER, DIV, 1) */
  UINT16_TO_STREAM(p, p_cb->div);
@@ -371,17 +281,9 @@ void smp_compute_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  }
}

/*******************************************************************************
 *
 * Function         smp_generate_csrk
 *
 * Description      This function is called to calculate CSRK, starting with DIV
 *                  generation.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
/**
 * This function is called to calculate CSRK, starting with DIV generation.
 */
void smp_generate_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  bool div_status;

@@ -389,11 +291,16 @@ void smp_generate_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {

  div_status = btm_get_local_div(p_cb->pairing_bda, &p_cb->div);
  if (div_status) {
    smp_compute_csrk(p_cb, NULL);
    smp_compute_csrk(p_cb->div, p_cb);
  } else {
    SMP_TRACE_DEBUG("Generate DIV for CSRK");
    p_cb->rand_enc_proc_state = SMP_GEN_DIV_CSRK;
    btsnd_hcic_ble_rand(Bind(&smp_rand_back));
    btsnd_hcic_ble_rand(Bind(
        [](tSMP_CB* p_cb, BT_OCTET8 rand) {
          uint16_t div;
          STREAM_TO_UINT16(div, rand);
          smp_compute_csrk(div, p_cb);
        },
        p_cb));
  }
}

@@ -567,10 +474,8 @@ tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, BT_OCTET16 rand,
 * Returns          void
 *
 ******************************************************************************/
static void smp_generate_confirm(tSMP_CB* p_cb,
                                 UNUSED_ATTR tSMP_INT_DATA* p_data) {
static void smp_generate_confirm(tSMP_CB* p_cb) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_CONFIRM;
  smp_debug_print_nbyte_little_endian((uint8_t*)p_cb->rand, "local_rand", 16);
  tSMP_ENC output;
  tSMP_STATUS status = smp_calculate_comfirm(p_cb, p_cb->rand, &output);
@@ -587,6 +492,36 @@ static void smp_generate_confirm(tSMP_CB* p_cb,
  smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
}

/*******************************************************************************
 *
 * Function         smp_generate_srand_mrand_confirm
 *
 * Description      This function is called to start the second pairing phase by
 *                  start generating random number.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_generate_srand_mrand_confirm(tSMP_CB* p_cb,
                                      UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  /* generate MRand or SRand */
  btsnd_hcic_ble_rand(Bind(
      [](tSMP_CB* p_cb, BT_OCTET8 rand) {
        memcpy((void*)p_cb->rand, rand, 8);

        /* generate 64 MSB of MRand or SRand */
        btsnd_hcic_ble_rand(Bind(
            [](tSMP_CB* p_cb, BT_OCTET8 rand) {
              memcpy((void*)&p_cb->rand[8], rand, BT_OCTET8_LEN);
              smp_generate_confirm(p_cb);
            },
            p_cb));
      },
      p_cb));
}

/*******************************************************************************
 *
 * Function         smp_generate_compare
@@ -601,7 +536,6 @@ static void smp_generate_confirm(tSMP_CB* p_cb,
 ******************************************************************************/
void smp_generate_compare(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("smp_generate_compare ");
  p_cb->rand_enc_proc_state = SMP_GEN_COMPARE;
  smp_debug_print_nbyte_little_endian((uint8_t*)p_cb->rrand, "peer rand", 16);
  tSMP_ENC output;
  tSMP_STATUS status = smp_calculate_comfirm(p_cb, p_cb->rrand, &output);
@@ -642,107 +576,116 @@ static void smp_process_stk(tSMP_CB* p_cb, tSMP_ENC* p) {
  smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
}

/*******************************************************************************
 *
 * Function         smp_generate_ltk_cont
 *
 * Description      Calculate LTK = d1(ER, DIV, 0)= e(ER, DIV)
 *
 * Returns          void
 *
 ******************************************************************************/
static void smp_generate_ltk_cont(tSMP_CB* p_cb,
                                  UNUSED_ATTR tSMP_INT_DATA* p_data) {
  BT_OCTET16 er;
/**
 * This function is to calculate EDIV = Y xor DIV
 */
static void smp_process_ediv(tSMP_CB* p_cb, tSMP_ENC* p) {
  tSMP_KEY key;
  uint8_t* pp = p->param_buf;
  uint16_t y;

  SMP_TRACE_DEBUG("smp_process_ediv ");
  STREAM_TO_UINT16(y, pp);

  /* EDIV = Y xor DIV */
  p_cb->ediv = p_cb->div ^ y;
  /* send LTK ready */
  SMP_TRACE_ERROR("LTK ready");
  key.key_type = SMP_KEY_TYPE_LTK;
  key.p_data = p->param_buf;

  smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
}

/**
 * This function is to proceed generate Y = E(DHK, Rand)
 */
static void smp_generate_y(tSMP_CB* p_cb, BT_OCTET8 rand) {
  SMP_TRACE_DEBUG("%s ", __func__);

  BT_OCTET16 dhk;
  BTM_GetDeviceDHK(dhk);

  memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
  tSMP_ENC output;
  if (!SMP_Encrypt(dhk, BT_OCTET16_LEN, rand, BT_OCTET8_LEN, &output)) {
    SMP_TRACE_ERROR("%s failed", __func__);
    tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
  } else {
    smp_process_ediv(p_cb, &output);
  }
}

/**
 * Calculate LTK = d1(ER, DIV, 0)= e(ER, DIV)
 */
static void smp_generate_ltk_cont(uint16_t div, tSMP_CB* p_cb) {
  p_cb->div = div;

  SMP_TRACE_DEBUG("%s", __func__);
  BT_OCTET16 er;
  BTM_GetDeviceEncRoot(er);

  tSMP_ENC output;
  /* LTK = d1(ER, DIV, 0)= e(ER, DIV)*/
  if (!SMP_Encrypt(er, BT_OCTET16_LEN, (uint8_t*)&p_cb->div, sizeof(uint16_t),
                   &output)) {
    SMP_TRACE_ERROR("%s failed", __func__);
    tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
  } else {
    /* mask the LTK */
    smp_mask_enc_key(p_cb->loc_enc_size, output.param_buf);
    memcpy((void*)p_cb->ltk, output.param_buf, BT_OCTET16_LEN);
    smp_generate_rand_vector(p_cb, NULL);
  }
}

/*******************************************************************************
 *
 * Function         smp_generate_y
 *
 * Description      This function is to proceed generate Y = E(DHK, Rand)
 *
 * Returns          void
 *
 ******************************************************************************/
static void smp_generate_y(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p) {
  BT_OCTET16 dhk;
  tSMP_ENC output;
  tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;

  SMP_TRACE_DEBUG("smp_generate_y ");
  BTM_GetDeviceDHK(dhk);

  if (!SMP_Encrypt(dhk, BT_OCTET16_LEN, p_cb->enc_rand, BT_OCTET8_LEN,
                   &output)) {
    SMP_TRACE_ERROR("smp_generate_y failed");
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
  } else {
    smp_process_ediv(p_cb, &output);
    /* generate EDIV and rand now */
    btsnd_hcic_ble_rand(Bind(&smp_generate_y, p_cb));
  }
}

/*******************************************************************************
 *
 * Function         smp_generate_rand_vector
 * Function         smp_generate_ltk
 *
 * Description      This function is called when an LTK is generated, send state
 *                  machine event to SMP.
 * Description      This function is called:
 *                  - in legacy pairing - to calculate LTK, starting with DIV
 *                    generation;
 *                  - in LE Secure Connections pairing over LE transport - to
 *                    process LTK already generated to encrypt LE link;
 *                  - in LE Secure Connections pairing over BR/EDR transport -
 *                    to start BR/EDR Link Key processing.
 *
 * Returns          void
 *
 ******************************************************************************/
static void smp_generate_rand_vector(tSMP_CB* p_cb,
                                     UNUSED_ATTR tSMP_INT_DATA* p) {
  /* generate EDIV and rand now */
  /* generate random vector */
  SMP_TRACE_DEBUG("smp_generate_rand_vector ");
  p_cb->rand_enc_proc_state = SMP_GEN_RAND_V;
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}
void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);

/*******************************************************************************
 *
 * Function         smp_process_ediv
 *
 * Description      This function is to calculate EDIV = Y xor DIV
 *
 * Returns          void
 *
 ******************************************************************************/
static void smp_process_ediv(tSMP_CB* p_cb, tSMP_ENC* p) {
  tSMP_KEY key;
  uint8_t* pp = p->param_buf;
  uint16_t y;
  if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) {
    smp_br_process_link_key(p_cb, NULL);
    return;
  } else if (p_cb->le_secure_connections_mode_is_used) {
    smp_process_secure_connection_long_term_key();
    return;
  }

  SMP_TRACE_DEBUG("smp_process_ediv ");
  STREAM_TO_UINT16(y, pp);
  bool div_status = btm_get_local_div(p_cb->pairing_bda, &p_cb->div);

  /* EDIV = Y xor DIV */
  p_cb->ediv = p_cb->div ^ y;
  /* send LTK ready */
  SMP_TRACE_ERROR("LTK ready");
  key.key_type = SMP_KEY_TYPE_LTK;
  key.p_data = p->param_buf;
  if (div_status) {
    smp_generate_ltk_cont(p_cb->div, p_cb);
  } else {
    SMP_TRACE_DEBUG("%s: Generate DIV for LTK", __func__);

  smp_sm_event(p_cb, SMP_KEY_READY_EVT, &key);
    /* generate MRand or SRand */
    btsnd_hcic_ble_rand(Bind(
        [](tSMP_CB* p_cb, BT_OCTET8 rand) {
          uint16_t div;
          STREAM_TO_UINT16(div, rand);
          smp_generate_ltk_cont(div, p_cb);
        },
        p_cb));
  }
}

/*******************************************************************************
@@ -755,10 +698,10 @@ static void smp_process_ediv(tSMP_CB* p_cb, tSMP_ENC* p) {
 *
 ******************************************************************************/
bool smp_calculate_legacy_short_term_key(tSMP_CB* p_cb, tSMP_ENC* output) {
  SMP_TRACE_DEBUG("%s", __func__);

  BT_OCTET16 ptext;
  uint8_t* p = ptext;

  SMP_TRACE_DEBUG("%s", __func__);
  memset(p, 0, BT_OCTET16_LEN);
  if (p_cb->role == HCI_ROLE_MASTER) {
    memcpy(p, p_cb->rand, BT_OCTET8_LEN);
@@ -768,9 +711,8 @@ bool smp_calculate_legacy_short_term_key(tSMP_CB* p_cb, tSMP_ENC* output) {
    memcpy(&p[BT_OCTET8_LEN], p_cb->rand, BT_OCTET8_LEN);
  }

  bool encrypted;
  /* generate STK = Etk(rand|rrand)*/
  encrypted =
  bool encrypted =
      SMP_Encrypt(p_cb->tk, BT_OCTET16_LEN, ptext, BT_OCTET16_LEN, output);
  if (!encrypted) {
    SMP_TRACE_ERROR("%s failed", __func__);
@@ -792,8 +734,29 @@ bool smp_calculate_legacy_short_term_key(tSMP_CB* p_cb, tSMP_ENC* output) {
 ******************************************************************************/
void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_0_7;
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));

  btsnd_hcic_ble_rand(Bind(
      [](tSMP_CB* p_cb, BT_OCTET8 rand) {
        memcpy((void*)p_cb->private_key, rand, BT_OCTET8_LEN);
        btsnd_hcic_ble_rand(Bind(
            [](tSMP_CB* p_cb, BT_OCTET8 rand) {
              memcpy((void*)&p_cb->private_key[8], rand, BT_OCTET8_LEN);
              btsnd_hcic_ble_rand(Bind(
                  [](tSMP_CB* p_cb, BT_OCTET8 rand) {
                    memcpy((void*)&p_cb->private_key[16], rand, BT_OCTET8_LEN);
                    btsnd_hcic_ble_rand(Bind(
                        [](tSMP_CB* p_cb, BT_OCTET8 rand) {
                          memcpy((void*)&p_cb->private_key[24], rand,
                                 BT_OCTET8_LEN);
                          smp_process_private_key(p_cb);
                        },
                        p_cb));
                  },
                  p_cb));
            },
            p_cb));
      },
      p_cb));
}

/*******************************************************************************
@@ -832,50 +795,6 @@ void smp_use_oob_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  }
}

/*******************************************************************************
 *
 * Function         smp_continue_private_key_creation
 *
 * Description      This function is used to continue private key creation.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_continue_private_key_creation(tSMP_CB* p_cb, BT_OCTET8 rand) {
  uint8_t state = p_cb->rand_enc_proc_state & ~0x80;
  SMP_TRACE_DEBUG("%s state=0x%x", __func__, state);

  switch (state) {
    case SMP_GENERATE_PRIVATE_KEY_0_7:
      memcpy((void*)p_cb->private_key, rand, 8);
      p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_8_15;
      btsnd_hcic_ble_rand(Bind(&smp_rand_back));
      break;

    case SMP_GENERATE_PRIVATE_KEY_8_15:
      memcpy((void*)&p_cb->private_key[8], rand, 8);
      p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_16_23;
      btsnd_hcic_ble_rand(Bind(&smp_rand_back));
      break;

    case SMP_GENERATE_PRIVATE_KEY_16_23:
      memcpy((void*)&p_cb->private_key[16], rand, 8);
      p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_24_31;
      btsnd_hcic_ble_rand(Bind(&smp_rand_back));
      break;

    case SMP_GENERATE_PRIVATE_KEY_24_31:
      memcpy((void*)&p_cb->private_key[24], rand, 8);
      smp_process_private_key(p_cb);
      break;

    default:
      break;
  }

  return;
}

/*******************************************************************************
 *
 * Function         smp_process_private_key
@@ -1930,111 +1849,22 @@ bool smp_calculate_h6(uint8_t* w, uint8_t* keyid, uint8_t* c) {
  return ret;
}

/*******************************************************************************
 *
 * Function         smp_start_nonce_generation
 *
 * Description      This function starts nonce generation.
 *
 * Returns          void
 *
 ******************************************************************************/
/**
 * This function generates nonce.
 */
void smp_start_nonce_generation(tSMP_CB* p_cb) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_NONCE_0_7;
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}

/*******************************************************************************
 *
 * Function         smp_finish_nonce_generation
 *
 * Description      This function finishes nonce generation.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_finish_nonce_generation(tSMP_CB* p_cb) {
  SMP_TRACE_DEBUG("%s", __func__);
  p_cb->rand_enc_proc_state = SMP_GEN_NONCE_8_15;
  btsnd_hcic_ble_rand(Bind(&smp_rand_back));
}

/*******************************************************************************
 *
 * Function         smp_process_new_nonce
 *
 * Description      This function notifies SM that it has new nonce.
 *
 * Returns          void
 *
 ******************************************************************************/
void smp_process_new_nonce(tSMP_CB* p_cb) {
  btsnd_hcic_ble_rand(Bind(
      [](tSMP_CB* p_cb, BT_OCTET8 rand) {
        memcpy((void*)p_cb->rand, rand, BT_OCTET8_LEN);
        btsnd_hcic_ble_rand(Bind(
            [](tSMP_CB* p_cb, BT_OCTET8 rand) {
              memcpy((void*)&p_cb->rand[8], rand, BT_OCTET8_LEN);
              SMP_TRACE_DEBUG("%s round %d", __func__, p_cb->round);
              /* notifies SM that it has new nonce. */
              smp_sm_event(p_cb, SMP_HAVE_LOC_NONCE_EVT, NULL);
}

/*******************************************************************************
 *
 * Function         smp_rand_back
 *
 * Description      This function is to process the rand command finished,
 *                  process the random/encrypted number for further action.
 *
 * Returns          void
 *
 ******************************************************************************/
static void smp_rand_back(BT_OCTET8 rand) {
  tSMP_CB* p_cb = &smp_cb;
  uint8_t* pp = rand;
  uint8_t state = p_cb->rand_enc_proc_state & ~0x80;

  SMP_TRACE_DEBUG("%s state=0x%x", __func__, state);
  switch (state) {
    case SMP_GEN_SRAND_MRAND:
      memcpy((void*)p_cb->rand, rand, 8);
      smp_generate_rand_cont(p_cb, NULL);
      break;

    case SMP_GEN_SRAND_MRAND_CONT:
      memcpy((void*)&p_cb->rand[8], rand, 8);
      smp_generate_confirm(p_cb, NULL);
      break;

    case SMP_GEN_DIV_LTK:
      STREAM_TO_UINT16(p_cb->div, pp);
      smp_generate_ltk_cont(p_cb, NULL);
      break;

    case SMP_GEN_DIV_CSRK:
      STREAM_TO_UINT16(p_cb->div, pp);
      smp_compute_csrk(p_cb, NULL);
      break;

    case SMP_GEN_TK:
      smp_proc_passkey(p_cb, rand);
      break;

    case SMP_GEN_RAND_V:
      memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
      smp_generate_y(p_cb, NULL);
      break;

    case SMP_GENERATE_PRIVATE_KEY_0_7:
    case SMP_GENERATE_PRIVATE_KEY_8_15:
    case SMP_GENERATE_PRIVATE_KEY_16_23:
    case SMP_GENERATE_PRIVATE_KEY_24_31:
      smp_continue_private_key_creation(p_cb, rand);
      break;

    case SMP_GEN_NONCE_0_7:
      memcpy((void*)p_cb->rand, rand, 8);
      smp_finish_nonce_generation(p_cb);
      break;

    case SMP_GEN_NONCE_8_15:
      memcpy((void*)&p_cb->rand[8], rand, 8);
      smp_process_new_nonce(p_cb);
      break;
  }
            },
            p_cb));
      },
      p_cb));
}