static bool verify_random(const uint8_t rnd[16]) { struct test_data *data = tester_get_data(); uint8_t confirm[16]; if (!bt_crypto_c1(data->crypto, data->tk, data->rrnd, data->prsp, data->preq, data->ia_type, data->ia, data->ra_type, data->ra, confirm)) return false; if (memcmp(data->pcnf, confirm, sizeof(data->pcnf) != 0)) { tester_warn("Confirmation values don't match"); return false; } if (data->out) { struct bthost *bthost = hciemu_client_get_host(data->hciemu); bt_crypto_s1(data->crypto, data->tk, data->rrnd, data->prnd, data->ltk); bthost_le_start_encrypt(bthost, data->handle, data->ltk); } else { bt_crypto_s1(data->crypto, data->tk, data->prnd, data->rrnd, data->ltk); } return true; }
static const void *get_pdu(const uint8_t *pdu) { struct test_data *data = tester_get_data(); uint8_t opcode = pdu[0]; static uint8_t buf[17]; switch (opcode) { case 0x01: /* Pairing Request */ memcpy(data->preq, pdu, sizeof(data->preq)); break; case 0x02: /* Pairing Response */ memcpy(data->prsp, pdu, sizeof(data->prsp)); break; case 0x03: /* Pairing Confirm */ buf[0] = pdu[0]; bt_crypto_c1(data->crypto, data->tk, data->prnd, data->prsp, data->preq, data->ia_type, data->ia, data->ra_type, data->ra, &buf[1]); return buf; case 0x04: /* Pairing Random */ buf[0] = pdu[0]; memcpy(&buf[1], data->prnd, 16); return buf; default: break; } return pdu; }
static bool verify_random(struct smp_conn *conn, const uint8_t rnd[16]) { uint8_t confirm[16]; if (!bt_crypto_c1(conn->smp->crypto, conn->tk, conn->rrnd, conn->prsp, conn->preq, conn->ia_type, conn->ia, conn->ra_type, conn->ra, confirm)) return false; if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf) != 0)) { printf("Confirmation values don't match\n"); return false; } if (conn->out) { bt_crypto_s1(conn->smp->crypto, conn->tk, conn->rrnd, conn->prnd, conn->ltk); bthost_le_start_encrypt(conn->smp->bthost, conn->handle, conn->ltk); } else { bt_crypto_s1(conn->smp->crypto, conn->tk, conn->prnd, conn->rrnd, conn->ltk); } return true; }
static void pairing_rsp(struct smp_conn *conn, const void *data, uint16_t len) { struct smp *smp = conn->smp; uint8_t cfm[17]; memcpy(conn->prsp, data, sizeof(conn->prsp)); conn->local_key_dist = conn->prsp[5]; conn->remote_key_dist = conn->prsp[6]; cfm[0] = BT_L2CAP_SMP_PAIRING_CONFIRM; bt_crypto_c1(smp->crypto, conn->tk, conn->prnd, conn->prsp, conn->preq, conn->ia_type, conn->ia, conn->ra_type, conn->ra, &cfm[1]); bthost_send_cid(smp->bthost, conn->handle, SMP_CID, cfm, sizeof(cfm)); }
static void pairing_cfm(struct smp_conn *conn, const void *data, uint16_t len) { struct bthost *bthost = conn->smp->bthost; uint8_t rsp[17]; memcpy(conn->pcnf, data + 1, 16); if (conn->out) { rsp[0] = BT_L2CAP_SMP_PAIRING_RANDOM; memset(&rsp[1], 0, 16); } else { rsp[0] = BT_L2CAP_SMP_PAIRING_CONFIRM; bt_crypto_c1(conn->smp->crypto, conn->tk, conn->prnd, conn->prsp, conn->preq, conn->ia_type, conn->ia, conn->ra_type, conn->ra, &rsp[1]); } bthost_send_cid(bthost, conn->handle, SMP_CID, rsp, sizeof(rsp)); }
static const void *get_pdu(const uint8_t *pdu) { struct test_data *data = tester_get_data(); const struct smp_data *smp = data->test_data; uint8_t opcode = pdu[0]; static uint8_t buf[65]; switch (opcode) { case 0x01: /* Pairing Request */ memcpy(data->preq, pdu, sizeof(data->preq)); break; case 0x02: /* Pairing Response */ memcpy(data->prsp, pdu, sizeof(data->prsp)); break; case 0x03: /* Pairing Confirm */ buf[0] = pdu[0]; if (smp->sc) bt_crypto_f4(data->crypto, data->local_pk, data->remote_pk, data->prnd, 0, &buf[1]); else bt_crypto_c1(data->crypto, data->tk, data->prnd, data->prsp, data->preq, data->ia_type, data->ia, data->ra_type, data->ra, &buf[1]); return buf; case 0x04: /* Pairing Random */ buf[0] = pdu[0]; memcpy(&buf[1], data->prnd, 16); return buf; case 0x0c: /* Public Key */ buf[0] = pdu[0]; memcpy(&buf[1], data->local_pk, 64); return buf; default: break; } return pdu; }