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

Commit 1fb7de76 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Support for H7 function for key derivation

am: fc2060e6

Change-Id: I7c8739d5956be9b2c430e8b5c952469c54bb98df
parents 1c4428bc fc2060e6
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -1638,12 +1638,13 @@ typedef uint8_t tBTM_LE_KEY_TYPE;
typedef uint8_t tBTM_LE_AUTH_REQ;
#define BTM_LE_SC_SUPPORT_BIT SMP_SC_SUPPORT_BIT /* (1 << 3) */
#define BTM_LE_KP_SUPPORT_BIT SMP_KP_SUPPORT_BIT /* (1 << 4) */
#define BTM_LE_H7_SUPPORT_BIT SMP_H7_SUPPORT_BIT /* (1 << 5) */

#define BTM_LE_AUTH_REQ_SC_ONLY SMP_AUTH_SC_ENC_ONLY     /* 1 << 3 */
#define BTM_LE_AUTH_REQ_SC_BOND SMP_AUTH_SC_GB           /* 1001 */
#define BTM_LE_AUTH_REQ_SC_MITM SMP_AUTH_SC_MITM_NB      /* 1100 */
#define BTM_LE_AUTH_REQ_SC_MITM_BOND SMP_AUTH_SC_MITM_GB /* 1101 */
#define BTM_LE_AUTH_REQ_MASK SMP_AUTH_MASK               /* 0x1D */
#define BTM_LE_AUTH_REQ_SC_ONLY SMP_AUTH_SC_ENC_ONLY     /* 00101000 */
#define BTM_LE_AUTH_REQ_SC_BOND SMP_AUTH_SC_GB           /* 00101001 */
#define BTM_LE_AUTH_REQ_SC_MITM SMP_AUTH_SC_MITM_NB      /* 00101100 */
#define BTM_LE_AUTH_REQ_SC_MITM_BOND SMP_AUTH_SC_MITM_GB /* 00101101 */
#define BTM_LE_AUTH_REQ_MASK SMP_AUTH_MASK               /* 0x3D */

/* LE security level */
#define BTM_LE_SEC_NONE SMP_SEC_NONE
+9 −6
Original line number Diff line number Diff line
@@ -128,10 +128,11 @@ typedef uint8_t tSMP_OOB_DATA_TYPE;
#define SMP_AUTH_YN_BIT (1 << 2)
#define SMP_SC_SUPPORT_BIT (1 << 3)
#define SMP_KP_SUPPORT_BIT (1 << 4)
#define SMP_H7_SUPPORT_BIT (1 << 5)

#define SMP_AUTH_MASK                                         \
  (SMP_AUTH_GEN_BOND | SMP_AUTH_YN_BIT | SMP_SC_SUPPORT_BIT | \
   SMP_KP_SUPPORT_BIT)
   SMP_KP_SUPPORT_BIT | SMP_H7_SUPPORT_BIT)

#define SMP_AUTH_BOND SMP_AUTH_GEN_BOND

@@ -149,18 +150,20 @@ typedef uint8_t tSMP_OOB_DATA_TYPE;
#define SMP_AUTH_GB_IOCAP (SMP_AUTH_GEN_BOND | SMP_AUTH_YN_BIT)

/* Secure Connections, no MITM, no Bonding */
#define SMP_AUTH_SC_ENC_ONLY (SMP_SC_SUPPORT_BIT)
#define SMP_AUTH_SC_ENC_ONLY (SMP_H7_SUPPORT_BIT | SMP_SC_SUPPORT_BIT)

/* Secure Connections, no MITM, Bonding */
#define SMP_AUTH_SC_GB (SMP_SC_SUPPORT_BIT | SMP_AUTH_GEN_BOND)
#define SMP_AUTH_SC_GB \
  (SMP_H7_SUPPORT_BIT | SMP_SC_SUPPORT_BIT | SMP_AUTH_GEN_BOND)

/* Secure Connections, MITM, no Bonding */
#define SMP_AUTH_SC_MITM_NB \
  (SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | SMP_AUTH_NO_BOND)
  (SMP_H7_SUPPORT_BIT | SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | SMP_AUTH_NO_BOND)

/* Secure Connections, MITM, Bonding */
#define SMP_AUTH_SC_MITM_GB                                    \
  (SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | SMP_AUTH_GEN_BOND)
  (SMP_H7_SUPPORT_BIT | SMP_SC_SUPPORT_BIT | SMP_AUTH_YN_BIT | \
   SMP_AUTH_GEN_BOND)

/* All AuthReq RFU bits are set to 1 - NOTE: reserved bit in Bonding_Flags is
 * not set */
+11 −2
Original line number Diff line number Diff line
@@ -209,14 +209,16 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
          p_cb->loc_enc_size = cb_data.io_req.max_key_size;
          p_cb->local_i_key = cb_data.io_req.init_keys;
          p_cb->local_r_key = cb_data.io_req.resp_keys;
          p_cb->loc_auth_req |= SMP_H7_SUPPORT_BIT;

          p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
          p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;

          SMP_TRACE_WARNING(
              "for SMP over BR max_key_size: 0x%02x,\
                        local_i_key: 0x%02x, local_r_key: 0x%02x",
              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
                        local_i_key: 0x%02x, local_r_key: 0x%02x, p_cb->loc_auth_req: 0x%02x",
              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key,
              p_cb->loc_auth_req);

          smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
          break;
@@ -845,6 +847,13 @@ void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
    p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
  }

  /* Check if H7 function needs to be used for key derivation*/
  if ((p_cb->loc_auth_req & SMP_H7_SUPPORT_BIT) &&
      (p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT)) {
    p_cb->key_derivation_h7_used = TRUE;
  }
  SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used);

  SMP_TRACE_DEBUG(
      "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
      "(i-initiator r-responder)",
+2 −0
Original line number Diff line number Diff line
@@ -299,6 +299,7 @@ typedef struct {
  /* either in Secure Connections mode or not at all */
  tSMP_ASSO_MODEL selected_association_model;
  bool le_secure_connections_mode_is_used;
  bool key_derivation_h7_used;
  bool le_sc_kp_notif_is_used;
  tSMP_SC_KEY_TYPE local_keypress_notification;
  tSMP_SC_KEY_TYPE peer_keypress_notification;
@@ -528,6 +529,7 @@ extern bool smp_calculate_f6(uint8_t* w, uint8_t* n1, uint8_t* n2, uint8_t* r,
                             uint8_t* iocap, uint8_t* a1, uint8_t* a2,
                             uint8_t* f3);
extern bool smp_calculate_h6(uint8_t* w, uint8_t* keyid, uint8_t* h2);
extern bool smp_calculate_h7(uint8_t* salt, uint8_t* w, uint8_t* h2);
#if (SMP_DEBUG == TRUE)
extern void smp_debug_print_nbyte_little_endian(uint8_t* p,
                                                const char* key_name,
+59 −5
Original line number Diff line number Diff line
@@ -1634,6 +1634,8 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) {
  tBTM_SEC_DEV_REC* p_dev_rec;
  BD_ADDR bda_for_lk;
  tBLE_ADDR_TYPE conn_addr_type;
  BT_OCTET16 salt = {0x31, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  SMP_TRACE_DEBUG("%s", __func__);

@@ -1659,6 +1661,9 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) {
  BT_OCTET16 intermediate_link_key;
  bool ret = true;

  if (p_cb->key_derivation_h7_used)
    ret = smp_calculate_h7((uint8_t*)salt, p_cb->ltk, intermediate_link_key);
  else
    ret = smp_calculate_h6(p_cb->ltk, (uint8_t*)"1pmt" /* reversed "tmp1" */,
                           intermediate_link_key);
  if (!ret) {
@@ -1724,6 +1729,8 @@ bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb) {
  bool ret = true;
  tBTM_SEC_DEV_REC* p_dev_rec;
  uint8_t rev_link_key[16];
  BT_OCTET16 salt = {0x32, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  SMP_TRACE_DEBUG("%s", __func__);

@@ -1754,9 +1761,14 @@ bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb) {
  REVERSE_ARRAY_TO_STREAM(p1, p2, 16);

  BT_OCTET16 intermediate_long_term_key;
  if (p_cb->key_derivation_h7_used) {
    ret = smp_calculate_h7((uint8_t*)salt, rev_link_key,
                           intermediate_long_term_key);
  } else {
    /* "tmp2" obtained from the spec */
    ret = smp_calculate_h6(rev_link_key, (uint8_t*)"2pmt" /* reversed "tmp2" */,
                           intermediate_long_term_key);
  }

  if (!ret) {
    SMP_TRACE_ERROR("%s failed to derive intermediate_long_term_key", __func__);
@@ -1849,6 +1861,48 @@ bool smp_calculate_h6(uint8_t* w, uint8_t* keyid, uint8_t* c) {
  return ret;
}

/*******************************************************************************
**
** Function         smp_calculate_h7
**
** Description      The function calculates
**                  C = h7(SALT, W) = AES-CMAC   (W)
**                                            SALT
**                  where
**                  input:  W is 128 bit,
**                          SALT is 128 bit,
**                  output: C is 128 bit.
**
** Returns          FALSE if out of resources, TRUE in other cases.
**
** Note             The LSB is the first octet, the MSB is the last octet of
**                  the AES-CMAC input/output stream.
**
*******************************************************************************/
bool smp_calculate_h7(uint8_t* salt, uint8_t* w, uint8_t* c) {
  SMP_TRACE_DEBUG("%s", __FUNCTION__);

  uint8_t key[BT_OCTET16_LEN];
  uint8_t* p = key;
  ARRAY_TO_STREAM(p, salt, BT_OCTET16_LEN);

  uint8_t msg_len = BT_OCTET16_LEN /* msg size */;
  uint8_t msg[BT_OCTET16_LEN];
  p = msg;
  ARRAY_TO_STREAM(p, w, BT_OCTET16_LEN);

  bool ret = true;
  uint8_t cmac[BT_OCTET16_LEN];
  if (!aes_cipher_msg_auth_code(key, msg, msg_len, BT_OCTET16_LEN, cmac)) {
    SMP_TRACE_ERROR("%s failed", __FUNCTION__);
    ret = false;
  }

  p = c;
  ARRAY_TO_STREAM(p, cmac, BT_OCTET16_LEN);
  return ret;
}

/**
 * This function generates nonce.
 */
Loading