Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | /** * @file rpa.c * Resolvable Private Address Generation and Resolution */ /* * Copyright (c) 2017 Nordic Semiconductor ASA * Copyright (c) 2015-2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <stddef.h> #include <errno.h> #include <string.h> #include "common/bt_str.h" #include <zephyr/bluetooth/crypto.h> #define LOG_LEVEL CONFIG_BT_RPA_LOG_LEVEL #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(bt_rpa); #if defined(CONFIG_BT_CTLR) && defined(CONFIG_BT_HOST_CRYPTO) #include "../controller/util/util.h" #include "../controller/hal/ecb.h" #endif /* defined(CONFIG_BT_CTLR) && defined(CONFIG_BT_HOST_CRYPTO) */ #if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_CTLR_PRIVACY) static int internal_rand(void *buf, size_t len) { /* Force using controller rand function. */ #if defined(CONFIG_BT_CTLR) && defined(CONFIG_BT_HOST_CRYPTO) return lll_csrand_get(buf, len); #else return bt_rand(buf, len); #endif } #endif /* defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_CTLR_PRIVACY) */ static int internal_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16], uint8_t enc_data[16]) { /* Force using controller encrypt function if supported. */ #if defined(CONFIG_BT_CTLR) && defined(CONFIG_BT_HOST_CRYPTO) && \ defined(CONFIG_BT_CTLR_LE_ENC) ecb_encrypt(key, plaintext, enc_data, NULL); return 0; #else return bt_encrypt_le(key, plaintext, enc_data); #endif } static int ah(const uint8_t irk[16], const uint8_t r[3], uint8_t out[3]) { uint8_t res[16]; int err; LOG_DBG("irk %s", bt_hex(irk, 16)); LOG_DBG("r %s", bt_hex(r, 3)); /* r' = padding || r */ memcpy(res, r, 3); (void)memset(res + 3, 0, 13); err = internal_encrypt_le(irk, res, res); if (err) { return err; } /* The output of the random address function ah is: * ah(h, r) = e(k, r') mod 2^24 * The output of the security function e is then truncated to 24 bits * by taking the least significant 24 bits of the output of e as the * result of ah. */ memcpy(out, res, 3); return 0; } #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CTLR_PRIVACY) bool bt_rpa_irk_matches(const uint8_t irk[16], const bt_addr_t *addr) { uint8_t hash[3]; int err; LOG_DBG("IRK %s bdaddr %s", bt_hex(irk, 16), bt_addr_str(addr)); err = ah(irk, addr->val + 3, hash); if (err) { return false; } return !memcmp(addr->val, hash, 3); } #endif #if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_CTLR_PRIVACY) int bt_rpa_create(const uint8_t irk[16], bt_addr_t *rpa) { int err; err = internal_rand(rpa->val + 3, 3); if (err) { return err; } BT_ADDR_SET_RPA(rpa); err = ah(irk, rpa->val + 3, rpa->val); if (err) { return err; } LOG_DBG("Created RPA %s", bt_addr_str((bt_addr_t *)rpa->val)); return 0; } #else int bt_rpa_create(const uint8_t irk[16], bt_addr_t *rpa) { return -ENOTSUP; } #endif /* CONFIG_BT_PRIVACY */ |