Bluetooth: Host: SMP: Verify public key before usage
Add a separate test for public key validity. This needs to be done synchronously so that we can respond with an early failure message to the peer device. Fixes #80218 Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
This commit is contained in:
parent
81ad6ecc13
commit
880384a20e
3 changed files with 45 additions and 0 deletions
|
@ -7,9 +7,12 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/sys/check.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#include "ecc.h"
|
||||
#include "hci_core.h"
|
||||
|
||||
|
@ -39,6 +42,35 @@ bool bt_pub_key_is_debug(uint8_t *cmp_pub_key)
|
|||
return memcmp(cmp_pub_key, debug_public_key, BT_PUB_KEY_LEN) == 0;
|
||||
}
|
||||
|
||||
bool bt_pub_key_is_valid(const uint8_t key[BT_PUB_KEY_LEN])
|
||||
{
|
||||
uint8_t key_be[BT_PUB_KEY_LEN + 1];
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t ret;
|
||||
psa_key_id_t handle;
|
||||
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(&attr, 256);
|
||||
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_ECDH);
|
||||
|
||||
/* PSA expects secp256r1 public key to start with a predefined 0x04 byte */
|
||||
key_be[0] = 0x04;
|
||||
sys_memcpy_swap(&key_be[1], key, BT_PUB_KEY_COORD_LEN);
|
||||
sys_memcpy_swap(&key_be[1 + BT_PUB_KEY_COORD_LEN], &key[BT_PUB_KEY_COORD_LEN],
|
||||
BT_PUB_KEY_COORD_LEN);
|
||||
|
||||
ret = psa_import_key(&attr, key_be, sizeof(key_be), &handle);
|
||||
psa_reset_key_attributes(&attr);
|
||||
|
||||
if (ret == PSA_SUCCESS) {
|
||||
psa_destroy_key(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int bt_pub_key_gen(struct bt_pub_key_cb *new_cb)
|
||||
{
|
||||
struct bt_pub_key_cb *cb;
|
||||
|
|
|
@ -44,6 +44,16 @@ struct bt_pub_key_cb {
|
|||
*/
|
||||
bool bt_pub_key_is_debug(uint8_t *cmp_pub_key);
|
||||
|
||||
/* @brief Check if public key is valid.
|
||||
*
|
||||
* Verify that the public key is valid, e.g. that its coordinates lie on the eliptic curve.
|
||||
*
|
||||
* @param key The public key to validate.
|
||||
*
|
||||
* @return True if the public key is valid.
|
||||
*/
|
||||
bool bt_pub_key_is_valid(const uint8_t key[BT_PUB_KEY_LEN]);
|
||||
|
||||
/* @brief Generate a new Public Key.
|
||||
*
|
||||
* Generate a new ECC Public Key. Provided cb must persists until callback
|
||||
|
|
|
@ -4311,6 +4311,9 @@ static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf)
|
|||
if (!update_debug_keys_check(smp)) {
|
||||
return BT_SMP_ERR_AUTH_REQUIREMENTS;
|
||||
}
|
||||
} else if (!bt_pub_key_is_valid(smp->pkey)) {
|
||||
LOG_WRN("Received invalid public key");
|
||||
return BT_SMP_ERR_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue