mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
features/FEATURE_BLE/ble/generic/SecurityDb.h@1:9db0e321a9f4, 2019-12-31 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 31 06:02:27 2019 +0000
- Revision:
- 1:9db0e321a9f4
- Parent:
- 0:5b88d5760320
updated based on mbed-os5.15.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:5b88d5760320 | 1 | /* mbed Microcontroller Library |
kenjiArai | 0:5b88d5760320 | 2 | * Copyright (c) 2018 ARM Limited |
kenjiArai | 0:5b88d5760320 | 3 | * |
kenjiArai | 0:5b88d5760320 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kenjiArai | 0:5b88d5760320 | 5 | * you may not use this file except in compliance with the License. |
kenjiArai | 0:5b88d5760320 | 6 | * You may obtain a copy of the License at |
kenjiArai | 0:5b88d5760320 | 7 | * |
kenjiArai | 0:5b88d5760320 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
kenjiArai | 0:5b88d5760320 | 9 | * |
kenjiArai | 0:5b88d5760320 | 10 | * Unless required by applicable law or agreed to in writing, software |
kenjiArai | 0:5b88d5760320 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
kenjiArai | 0:5b88d5760320 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kenjiArai | 0:5b88d5760320 | 13 | * See the License for the specific language governing permissions and |
kenjiArai | 0:5b88d5760320 | 14 | * limitations under the License. |
kenjiArai | 0:5b88d5760320 | 15 | */ |
kenjiArai | 0:5b88d5760320 | 16 | |
kenjiArai | 0:5b88d5760320 | 17 | #ifndef GENERIC_SECURITY_MANAGER_DB_H__ |
kenjiArai | 0:5b88d5760320 | 18 | #define GENERIC_SECURITY_MANAGER_DB_H__ |
kenjiArai | 0:5b88d5760320 | 19 | |
kenjiArai | 0:5b88d5760320 | 20 | #include "platform/Callback.h" |
kenjiArai | 0:5b88d5760320 | 21 | #include "ble/pal/GapTypes.h" |
kenjiArai | 0:5b88d5760320 | 22 | #include "ble/BLETypes.h" |
kenjiArai | 0:5b88d5760320 | 23 | #include "ble/Gap.h" |
kenjiArai | 0:5b88d5760320 | 24 | #include <stdlib.h> |
kenjiArai | 0:5b88d5760320 | 25 | |
kenjiArai | 0:5b88d5760320 | 26 | namespace ble { |
kenjiArai | 0:5b88d5760320 | 27 | namespace generic { |
kenjiArai | 0:5b88d5760320 | 28 | |
kenjiArai | 0:5b88d5760320 | 29 | |
kenjiArai | 0:5b88d5760320 | 30 | /** |
kenjiArai | 0:5b88d5760320 | 31 | * Security flags associated with a bond. |
kenjiArai | 0:5b88d5760320 | 32 | */ |
kenjiArai | 0:5b88d5760320 | 33 | struct SecurityDistributionFlags_t { |
kenjiArai | 0:5b88d5760320 | 34 | SecurityDistributionFlags_t() : |
kenjiArai | 0:5b88d5760320 | 35 | peer_address(), |
kenjiArai | 0:5b88d5760320 | 36 | encryption_key_size(0), |
kenjiArai | 0:5b88d5760320 | 37 | peer_address_is_public(false), |
kenjiArai | 0:5b88d5760320 | 38 | csrk_stored(false), |
kenjiArai | 0:5b88d5760320 | 39 | ltk_stored(false), |
kenjiArai | 0:5b88d5760320 | 40 | ltk_sent(false), |
kenjiArai | 0:5b88d5760320 | 41 | irk_stored(false), |
kenjiArai | 0:5b88d5760320 | 42 | csrk_mitm_protected(false), |
kenjiArai | 0:5b88d5760320 | 43 | ltk_mitm_protected(false), |
kenjiArai | 0:5b88d5760320 | 44 | secure_connections_paired(false), |
kenjiArai | 0:5b88d5760320 | 45 | connected(false) { |
kenjiArai | 0:5b88d5760320 | 46 | } |
kenjiArai | 0:5b88d5760320 | 47 | |
kenjiArai | 0:5b88d5760320 | 48 | /** peer address */ |
kenjiArai | 0:5b88d5760320 | 49 | address_t peer_address; |
kenjiArai | 0:5b88d5760320 | 50 | |
kenjiArai | 0:5b88d5760320 | 51 | /** encryption key size */ |
kenjiArai | 0:5b88d5760320 | 52 | uint8_t encryption_key_size; |
kenjiArai | 0:5b88d5760320 | 53 | /** true if peer address is public, false if it's static random */ |
kenjiArai | 0:5b88d5760320 | 54 | uint8_t peer_address_is_public:1; |
kenjiArai | 0:5b88d5760320 | 55 | |
kenjiArai | 0:5b88d5760320 | 56 | /** CSRK (Connection Signature Resolving Key) has been distributed and stored */ |
kenjiArai | 0:5b88d5760320 | 57 | uint8_t csrk_stored:1; |
kenjiArai | 0:5b88d5760320 | 58 | /** LTK (Long Term Key) has been distributed and stored */ |
kenjiArai | 0:5b88d5760320 | 59 | uint8_t ltk_stored:1; |
kenjiArai | 0:5b88d5760320 | 60 | uint8_t ltk_sent:1; |
kenjiArai | 0:5b88d5760320 | 61 | /** the security entry has been distributed and stored */ |
kenjiArai | 0:5b88d5760320 | 62 | uint8_t irk_stored:1; |
kenjiArai | 0:5b88d5760320 | 63 | |
kenjiArai | 0:5b88d5760320 | 64 | /** CSRK that is stored has MITM protection */ |
kenjiArai | 0:5b88d5760320 | 65 | uint8_t csrk_mitm_protected:1; |
kenjiArai | 0:5b88d5760320 | 66 | /** LTK that is stored has MITM protection */ |
kenjiArai | 0:5b88d5760320 | 67 | uint8_t ltk_mitm_protected:1; |
kenjiArai | 0:5b88d5760320 | 68 | /** the current pairing was done using Secure Connections */ |
kenjiArai | 0:5b88d5760320 | 69 | uint8_t secure_connections_paired:1; |
kenjiArai | 0:5b88d5760320 | 70 | uint8_t connected:1; |
kenjiArai | 0:5b88d5760320 | 71 | }; |
kenjiArai | 0:5b88d5760320 | 72 | |
kenjiArai | 0:5b88d5760320 | 73 | /** Long Term Key and data used to identify it */ |
kenjiArai | 0:5b88d5760320 | 74 | struct SecurityEntryKeys_t { |
kenjiArai | 0:5b88d5760320 | 75 | /** Long Term Key */ |
kenjiArai | 0:5b88d5760320 | 76 | ltk_t ltk; |
kenjiArai | 0:5b88d5760320 | 77 | /** EDIV (Encryption diversifier) used to identify LTK during legacy pairing */ |
kenjiArai | 0:5b88d5760320 | 78 | ediv_t ediv; |
kenjiArai | 0:5b88d5760320 | 79 | /** Rand (random number) used to identify LTK during legacy pairing */ |
kenjiArai | 0:5b88d5760320 | 80 | rand_t rand; |
kenjiArai | 0:5b88d5760320 | 81 | }; |
kenjiArai | 0:5b88d5760320 | 82 | |
kenjiArai | 0:5b88d5760320 | 83 | /** CSRK and sign counter used to verify messages */ |
kenjiArai | 0:5b88d5760320 | 84 | struct SecurityEntrySigning_t { |
kenjiArai | 0:5b88d5760320 | 85 | SecurityEntrySigning_t() : counter(0) { }; |
kenjiArai | 0:5b88d5760320 | 86 | /** Signing key */ |
kenjiArai | 0:5b88d5760320 | 87 | csrk_t csrk; |
kenjiArai | 0:5b88d5760320 | 88 | /** counter used to verify message to guard from replay attacks */ |
kenjiArai | 0:5b88d5760320 | 89 | sign_count_t counter; |
kenjiArai | 0:5b88d5760320 | 90 | }; |
kenjiArai | 0:5b88d5760320 | 91 | |
kenjiArai | 0:5b88d5760320 | 92 | /** Data for resolving random resolvable addresses */ |
kenjiArai | 0:5b88d5760320 | 93 | struct SecurityEntryIdentity_t { |
kenjiArai | 0:5b88d5760320 | 94 | /** identity address */ |
kenjiArai | 0:5b88d5760320 | 95 | address_t identity_address; |
kenjiArai | 0:5b88d5760320 | 96 | /** Identity Resolving Key */ |
kenjiArai | 0:5b88d5760320 | 97 | irk_t irk; |
kenjiArai | 0:5b88d5760320 | 98 | /** true if peer identity address is public, false if it's static random */ |
kenjiArai | 0:5b88d5760320 | 99 | uint8_t identity_address_is_public:1; |
kenjiArai | 0:5b88d5760320 | 100 | }; |
kenjiArai | 0:5b88d5760320 | 101 | |
kenjiArai | 0:5b88d5760320 | 102 | /** |
kenjiArai | 0:5b88d5760320 | 103 | * SecurityDb holds the state for active connections and bonded devices. |
kenjiArai | 0:5b88d5760320 | 104 | * Keys can be stored in NVM and are returned via callbacks. |
kenjiArai | 0:5b88d5760320 | 105 | * SecurityDb is responsible for serialising any requests and keeping |
kenjiArai | 0:5b88d5760320 | 106 | * the store in a consistent state. |
kenjiArai | 0:5b88d5760320 | 107 | * Active connections state must be returned immediately. |
kenjiArai | 0:5b88d5760320 | 108 | */ |
kenjiArai | 0:5b88d5760320 | 109 | class SecurityDb { |
kenjiArai | 0:5b88d5760320 | 110 | public: |
kenjiArai | 0:5b88d5760320 | 111 | /** |
kenjiArai | 0:5b88d5760320 | 112 | * Opaque type representing a handle to a database entry. |
kenjiArai | 0:5b88d5760320 | 113 | */ |
kenjiArai | 0:5b88d5760320 | 114 | typedef void* entry_handle_t; |
kenjiArai | 0:5b88d5760320 | 115 | |
kenjiArai | 0:5b88d5760320 | 116 | /* callbacks for asynchronous data retrieval from the security db */ |
kenjiArai | 0:5b88d5760320 | 117 | |
kenjiArai | 0:5b88d5760320 | 118 | typedef mbed::Callback<void(entry_handle_t, const SecurityEntryKeys_t*)> |
kenjiArai | 0:5b88d5760320 | 119 | SecurityEntryKeysDbCb_t; |
kenjiArai | 0:5b88d5760320 | 120 | typedef mbed::Callback<void(entry_handle_t, const SecurityEntrySigning_t*)> |
kenjiArai | 0:5b88d5760320 | 121 | SecurityEntrySigningDbCb_t; |
kenjiArai | 0:5b88d5760320 | 122 | typedef mbed::Callback<void(entry_handle_t, const SecurityEntryIdentity_t*)> |
kenjiArai | 0:5b88d5760320 | 123 | SecurityEntryIdentityDbCb_t; |
kenjiArai | 0:5b88d5760320 | 124 | typedef mbed::Callback<void(Span<SecurityEntryIdentity_t>&, size_t count)> |
kenjiArai | 0:5b88d5760320 | 125 | IdentitylistDbCb_t; |
kenjiArai | 0:5b88d5760320 | 126 | typedef mbed::Callback<void(::Gap::Whitelist_t*)> |
kenjiArai | 0:5b88d5760320 | 127 | WhitelistDbCb_t; |
kenjiArai | 0:5b88d5760320 | 128 | |
kenjiArai | 0:5b88d5760320 | 129 | SecurityDb() : _local_sign_counter(0) { }; |
kenjiArai | 0:5b88d5760320 | 130 | virtual ~SecurityDb() { }; |
kenjiArai | 0:5b88d5760320 | 131 | |
kenjiArai | 0:5b88d5760320 | 132 | /** |
kenjiArai | 0:5b88d5760320 | 133 | * Return immediately security flags associated to a db entry. |
kenjiArai | 0:5b88d5760320 | 134 | * |
kenjiArai | 0:5b88d5760320 | 135 | * @param[in] db_handle Entry of the database queried. |
kenjiArai | 0:5b88d5760320 | 136 | * @return pointer to the flags or NULL if the entry do not have any |
kenjiArai | 0:5b88d5760320 | 137 | * associated flags. |
kenjiArai | 0:5b88d5760320 | 138 | */ |
kenjiArai | 0:5b88d5760320 | 139 | virtual SecurityDistributionFlags_t* get_distribution_flags( |
kenjiArai | 0:5b88d5760320 | 140 | entry_handle_t db_handle |
kenjiArai | 0:5b88d5760320 | 141 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 142 | |
kenjiArai | 0:5b88d5760320 | 143 | /** |
kenjiArai | 0:5b88d5760320 | 144 | * Set the distribution flags of a DB entry. |
kenjiArai | 0:5b88d5760320 | 145 | * |
kenjiArai | 0:5b88d5760320 | 146 | * @param[in] db_handle Entry of the database that will store the flags. |
kenjiArai | 0:5b88d5760320 | 147 | * @param[in] flags Distribution flags to store in @p db_handle. |
kenjiArai | 0:5b88d5760320 | 148 | */ |
kenjiArai | 0:5b88d5760320 | 149 | virtual void set_distribution_flags( |
kenjiArai | 0:5b88d5760320 | 150 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 151 | const SecurityDistributionFlags_t& new_flags |
kenjiArai | 0:5b88d5760320 | 152 | ) { |
kenjiArai | 0:5b88d5760320 | 153 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 154 | if (flags) { |
kenjiArai | 0:5b88d5760320 | 155 | *flags = new_flags; |
kenjiArai | 0:5b88d5760320 | 156 | } |
kenjiArai | 0:5b88d5760320 | 157 | } |
kenjiArai | 0:5b88d5760320 | 158 | |
kenjiArai | 0:5b88d5760320 | 159 | /* local keys */ |
kenjiArai | 0:5b88d5760320 | 160 | |
kenjiArai | 0:5b88d5760320 | 161 | /** |
kenjiArai | 0:5b88d5760320 | 162 | * Retrieve stored LTK based on passed in EDIV and RAND values. |
kenjiArai | 0:5b88d5760320 | 163 | * |
kenjiArai | 0:5b88d5760320 | 164 | * @param[in] cb callback that will receive the LTK struct |
kenjiArai | 0:5b88d5760320 | 165 | * @param[in] db_handle handle of the entry being queried. |
kenjiArai | 0:5b88d5760320 | 166 | * @param[in] ediv one of the values used to identify the LTK |
kenjiArai | 0:5b88d5760320 | 167 | * @param[in] rand one of the values used to identify the LTK |
kenjiArai | 0:5b88d5760320 | 168 | */ |
kenjiArai | 0:5b88d5760320 | 169 | virtual void get_entry_local_keys( |
kenjiArai | 0:5b88d5760320 | 170 | SecurityEntryKeysDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 171 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 172 | const ediv_t &ediv, |
kenjiArai | 0:5b88d5760320 | 173 | const rand_t &rand |
kenjiArai | 0:5b88d5760320 | 174 | ) { |
kenjiArai | 0:5b88d5760320 | 175 | SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle); |
kenjiArai | 0:5b88d5760320 | 176 | /* validate we have the correct key */ |
kenjiArai | 0:5b88d5760320 | 177 | if (keys && ediv == keys->ediv && rand == keys->rand) { |
kenjiArai | 0:5b88d5760320 | 178 | cb(db_handle, keys); |
kenjiArai | 0:5b88d5760320 | 179 | } else { |
kenjiArai | 0:5b88d5760320 | 180 | cb(db_handle, NULL); |
kenjiArai | 0:5b88d5760320 | 181 | } |
kenjiArai | 0:5b88d5760320 | 182 | } |
kenjiArai | 0:5b88d5760320 | 183 | |
kenjiArai | 0:5b88d5760320 | 184 | /** |
kenjiArai | 0:5b88d5760320 | 185 | * Retrieve stored LTK generated during secure connections pairing. |
kenjiArai | 0:5b88d5760320 | 186 | * |
kenjiArai | 0:5b88d5760320 | 187 | * @param[in] cb callback that will receive the LTK struct |
kenjiArai | 0:5b88d5760320 | 188 | * @param[in] db_handle handle of the entry being queried. |
kenjiArai | 0:5b88d5760320 | 189 | */ |
kenjiArai | 0:5b88d5760320 | 190 | virtual void get_entry_local_keys( |
kenjiArai | 0:5b88d5760320 | 191 | SecurityEntryKeysDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 192 | entry_handle_t db_handle |
kenjiArai | 0:5b88d5760320 | 193 | ) { |
kenjiArai | 0:5b88d5760320 | 194 | SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle); |
kenjiArai | 0:5b88d5760320 | 195 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 196 | /* validate we have the correct key */ |
kenjiArai | 0:5b88d5760320 | 197 | if (flags && keys && flags->secure_connections_paired) { |
kenjiArai | 0:5b88d5760320 | 198 | cb(db_handle, keys); |
kenjiArai | 0:5b88d5760320 | 199 | } else { |
kenjiArai | 0:5b88d5760320 | 200 | cb(db_handle, NULL); |
kenjiArai | 0:5b88d5760320 | 201 | } |
kenjiArai | 0:5b88d5760320 | 202 | } |
kenjiArai | 0:5b88d5760320 | 203 | |
kenjiArai | 0:5b88d5760320 | 204 | /** |
kenjiArai | 0:5b88d5760320 | 205 | * Save new local LTK for a connection. |
kenjiArai | 0:5b88d5760320 | 206 | * |
kenjiArai | 0:5b88d5760320 | 207 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 208 | * @param[in] ltk the new LTK, if the device is slave, this is the LTK that |
kenjiArai | 0:5b88d5760320 | 209 | * will be used when link is encrypted |
kenjiArai | 0:5b88d5760320 | 210 | */ |
kenjiArai | 0:5b88d5760320 | 211 | virtual void set_entry_local_ltk( |
kenjiArai | 0:5b88d5760320 | 212 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 213 | const ltk_t <k |
kenjiArai | 0:5b88d5760320 | 214 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 215 | |
kenjiArai | 0:5b88d5760320 | 216 | /** |
kenjiArai | 0:5b88d5760320 | 217 | * Update EDIV and RAND used to identify the LTK. |
kenjiArai | 0:5b88d5760320 | 218 | * |
kenjiArai | 0:5b88d5760320 | 219 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 220 | * @param[in] ediv new EDIV value |
kenjiArai | 0:5b88d5760320 | 221 | * @param[in] rand new RAND value |
kenjiArai | 0:5b88d5760320 | 222 | */ |
kenjiArai | 0:5b88d5760320 | 223 | virtual void set_entry_local_ediv_rand( |
kenjiArai | 0:5b88d5760320 | 224 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 225 | const ediv_t &ediv, |
kenjiArai | 0:5b88d5760320 | 226 | const rand_t &rand |
kenjiArai | 0:5b88d5760320 | 227 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 228 | |
kenjiArai | 0:5b88d5760320 | 229 | /* peer's keys */ |
kenjiArai | 0:5b88d5760320 | 230 | |
kenjiArai | 0:5b88d5760320 | 231 | /** |
kenjiArai | 0:5b88d5760320 | 232 | * Return asynchronously the peer signing key through a callback |
kenjiArai | 0:5b88d5760320 | 233 | * so that signed packets can be verified. |
kenjiArai | 0:5b88d5760320 | 234 | * |
kenjiArai | 0:5b88d5760320 | 235 | * @param[in] cb callback which will receive the key |
kenjiArai | 0:5b88d5760320 | 236 | * @param[in] db_handle handle of the entry being queried. |
kenjiArai | 0:5b88d5760320 | 237 | */ |
kenjiArai | 0:5b88d5760320 | 238 | virtual void get_entry_peer_csrk( |
kenjiArai | 0:5b88d5760320 | 239 | SecurityEntrySigningDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 240 | entry_handle_t db_handle |
kenjiArai | 0:5b88d5760320 | 241 | ) { |
kenjiArai | 0:5b88d5760320 | 242 | SecurityEntrySigning_t* signing = read_in_entry_peer_signing(db_handle); |
kenjiArai | 0:5b88d5760320 | 243 | cb(db_handle, signing); |
kenjiArai | 0:5b88d5760320 | 244 | } |
kenjiArai | 0:5b88d5760320 | 245 | |
kenjiArai | 0:5b88d5760320 | 246 | /** |
kenjiArai | 0:5b88d5760320 | 247 | * Return asynchronously the peer encryption key through a callback |
kenjiArai | 0:5b88d5760320 | 248 | * so that encryption can be enabled. |
kenjiArai | 0:5b88d5760320 | 249 | * |
kenjiArai | 0:5b88d5760320 | 250 | * @param[in] cb callback which will receive the key |
kenjiArai | 0:5b88d5760320 | 251 | * @param[in] db_handle handle of the entry being queried. |
kenjiArai | 0:5b88d5760320 | 252 | */ |
kenjiArai | 0:5b88d5760320 | 253 | virtual void get_entry_peer_keys( |
kenjiArai | 0:5b88d5760320 | 254 | SecurityEntryKeysDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 255 | entry_handle_t db_handle |
kenjiArai | 0:5b88d5760320 | 256 | ) { |
kenjiArai | 0:5b88d5760320 | 257 | SecurityEntryKeys_t* keys = read_in_entry_peer_keys(db_handle); |
kenjiArai | 0:5b88d5760320 | 258 | cb(db_handle, keys); |
kenjiArai | 0:5b88d5760320 | 259 | } |
kenjiArai | 0:5b88d5760320 | 260 | |
kenjiArai | 0:5b88d5760320 | 261 | /** |
kenjiArai | 0:5b88d5760320 | 262 | * Save new LTK received from the peer. |
kenjiArai | 0:5b88d5760320 | 263 | * |
kenjiArai | 0:5b88d5760320 | 264 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 265 | * @param[in] ltk the new LTK, if the peer device is slave, this is the LTK |
kenjiArai | 0:5b88d5760320 | 266 | * that will be used when link is encrypted |
kenjiArai | 0:5b88d5760320 | 267 | */ |
kenjiArai | 0:5b88d5760320 | 268 | virtual void set_entry_peer_ltk( |
kenjiArai | 0:5b88d5760320 | 269 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 270 | const ltk_t <k |
kenjiArai | 0:5b88d5760320 | 271 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 272 | |
kenjiArai | 0:5b88d5760320 | 273 | /** |
kenjiArai | 0:5b88d5760320 | 274 | * Update EDIV and RAND used to identify the LTK sent by the peer. |
kenjiArai | 0:5b88d5760320 | 275 | * |
kenjiArai | 0:5b88d5760320 | 276 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 277 | * @param[in] ediv new EDIV value |
kenjiArai | 0:5b88d5760320 | 278 | * @param[in] rand new RAND value |
kenjiArai | 0:5b88d5760320 | 279 | */ |
kenjiArai | 0:5b88d5760320 | 280 | virtual void set_entry_peer_ediv_rand( |
kenjiArai | 0:5b88d5760320 | 281 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 282 | const ediv_t &ediv, |
kenjiArai | 0:5b88d5760320 | 283 | const rand_t &rand |
kenjiArai | 0:5b88d5760320 | 284 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 285 | |
kenjiArai | 0:5b88d5760320 | 286 | /** |
kenjiArai | 0:5b88d5760320 | 287 | * Update IRK for this connection. |
kenjiArai | 0:5b88d5760320 | 288 | * |
kenjiArai | 0:5b88d5760320 | 289 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 290 | * @param[in] irk new IRK value |
kenjiArai | 0:5b88d5760320 | 291 | */ |
kenjiArai | 0:5b88d5760320 | 292 | virtual void set_entry_peer_irk( |
kenjiArai | 0:5b88d5760320 | 293 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 294 | const irk_t &irk |
kenjiArai | 0:5b88d5760320 | 295 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 296 | |
kenjiArai | 0:5b88d5760320 | 297 | /** |
kenjiArai | 0:5b88d5760320 | 298 | * Update the identity address of the peer. |
kenjiArai | 0:5b88d5760320 | 299 | * |
kenjiArai | 0:5b88d5760320 | 300 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 301 | * @param[in] address_is_public is the identity address public or private |
kenjiArai | 0:5b88d5760320 | 302 | * @param[in] peer_address the new address |
kenjiArai | 0:5b88d5760320 | 303 | */ |
kenjiArai | 0:5b88d5760320 | 304 | virtual void set_entry_peer_bdaddr( |
kenjiArai | 0:5b88d5760320 | 305 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 306 | bool address_is_public, |
kenjiArai | 0:5b88d5760320 | 307 | const address_t &peer_address |
kenjiArai | 0:5b88d5760320 | 308 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 309 | |
kenjiArai | 0:5b88d5760320 | 310 | /** |
kenjiArai | 0:5b88d5760320 | 311 | * Retrieve stored identity address and IRK. |
kenjiArai | 0:5b88d5760320 | 312 | * |
kenjiArai | 0:5b88d5760320 | 313 | * @param[in] cb callback that will receive the SecurityEntryIdentity_t struct |
kenjiArai | 0:5b88d5760320 | 314 | * @param[in] db_handle handle of the entry being queried. |
kenjiArai | 0:5b88d5760320 | 315 | */ |
kenjiArai | 0:5b88d5760320 | 316 | virtual void get_entry_identity( |
kenjiArai | 0:5b88d5760320 | 317 | SecurityEntryIdentityDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 318 | entry_handle_t db_handle |
kenjiArai | 0:5b88d5760320 | 319 | ) { |
kenjiArai | 0:5b88d5760320 | 320 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 321 | if (flags && flags->irk_stored) { |
kenjiArai | 0:5b88d5760320 | 322 | SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle); |
kenjiArai | 0:5b88d5760320 | 323 | if (peer_identity) { |
kenjiArai | 0:5b88d5760320 | 324 | cb(db_handle, peer_identity); |
kenjiArai | 0:5b88d5760320 | 325 | return; |
kenjiArai | 0:5b88d5760320 | 326 | } |
kenjiArai | 0:5b88d5760320 | 327 | } |
kenjiArai | 0:5b88d5760320 | 328 | /* avoid duplicate else */ |
kenjiArai | 0:5b88d5760320 | 329 | cb(db_handle, NULL); |
kenjiArai | 0:5b88d5760320 | 330 | } |
kenjiArai | 0:5b88d5760320 | 331 | |
kenjiArai | 0:5b88d5760320 | 332 | /** |
kenjiArai | 0:5b88d5760320 | 333 | * Asynchronously return the identity list stored in NVM through a callback. |
kenjiArai | 0:5b88d5760320 | 334 | * Function takes ownership of the memory. The identity list and the |
kenjiArai | 0:5b88d5760320 | 335 | * ownership will be returned in the callback. |
kenjiArai | 0:5b88d5760320 | 336 | * |
kenjiArai | 0:5b88d5760320 | 337 | * @param[in] cb callback that will receive the whitelist |
kenjiArai | 0:5b88d5760320 | 338 | * @param[in] identity_list preallocated identity_list that will be filled |
kenjiArai | 0:5b88d5760320 | 339 | * in. |
kenjiArai | 0:5b88d5760320 | 340 | */ |
kenjiArai | 0:5b88d5760320 | 341 | virtual void get_identity_list( |
kenjiArai | 0:5b88d5760320 | 342 | IdentitylistDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 343 | Span<SecurityEntryIdentity_t>& identity_list |
kenjiArai | 0:5b88d5760320 | 344 | ) { |
kenjiArai | 0:5b88d5760320 | 345 | size_t count = 0; |
kenjiArai | 0:5b88d5760320 | 346 | for (size_t i = 0; i < get_entry_count() && count < identity_list.size(); ++i) { |
kenjiArai | 0:5b88d5760320 | 347 | |
kenjiArai | 0:5b88d5760320 | 348 | entry_handle_t db_handle = get_entry_handle_by_index(i); |
kenjiArai | 0:5b88d5760320 | 349 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 350 | |
kenjiArai | 0:5b88d5760320 | 351 | |
kenjiArai | 0:5b88d5760320 | 352 | if (flags && flags->irk_stored) { |
kenjiArai | 0:5b88d5760320 | 353 | SecurityEntryIdentity_t* peer_identity = read_in_entry_peer_identity(db_handle); |
kenjiArai | 0:5b88d5760320 | 354 | if (peer_identity) { |
kenjiArai | 0:5b88d5760320 | 355 | identity_list[count] = *peer_identity; |
kenjiArai | 0:5b88d5760320 | 356 | count++; |
kenjiArai | 0:5b88d5760320 | 357 | } |
kenjiArai | 0:5b88d5760320 | 358 | } |
kenjiArai | 0:5b88d5760320 | 359 | } |
kenjiArai | 0:5b88d5760320 | 360 | |
kenjiArai | 0:5b88d5760320 | 361 | cb(identity_list, count); |
kenjiArai | 0:5b88d5760320 | 362 | } |
kenjiArai | 0:5b88d5760320 | 363 | |
kenjiArai | 0:5b88d5760320 | 364 | /** |
kenjiArai | 0:5b88d5760320 | 365 | * Update peer signing key. |
kenjiArai | 0:5b88d5760320 | 366 | * |
kenjiArai | 0:5b88d5760320 | 367 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 368 | * @param[in] csrk new CSRK value |
kenjiArai | 0:5b88d5760320 | 369 | */ |
kenjiArai | 0:5b88d5760320 | 370 | virtual void set_entry_peer_csrk( |
kenjiArai | 0:5b88d5760320 | 371 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 372 | const csrk_t &csrk |
kenjiArai | 0:5b88d5760320 | 373 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 374 | |
kenjiArai | 0:5b88d5760320 | 375 | /** |
kenjiArai | 0:5b88d5760320 | 376 | * Update peer signing counter. |
kenjiArai | 0:5b88d5760320 | 377 | * |
kenjiArai | 0:5b88d5760320 | 378 | * @param[in] db_handle handle of the entry being updated. |
kenjiArai | 0:5b88d5760320 | 379 | * @param[in] sign_counter new signing counter value |
kenjiArai | 0:5b88d5760320 | 380 | */ |
kenjiArai | 0:5b88d5760320 | 381 | virtual void set_entry_peer_sign_counter( |
kenjiArai | 0:5b88d5760320 | 382 | entry_handle_t db_handle, |
kenjiArai | 0:5b88d5760320 | 383 | sign_count_t sign_counter |
kenjiArai | 0:5b88d5760320 | 384 | ) = 0; |
kenjiArai | 0:5b88d5760320 | 385 | |
kenjiArai | 0:5b88d5760320 | 386 | /* local csrk */ |
kenjiArai | 0:5b88d5760320 | 387 | |
kenjiArai | 0:5b88d5760320 | 388 | /** |
kenjiArai | 0:5b88d5760320 | 389 | * Return local signing key used for signing packets. |
kenjiArai | 0:5b88d5760320 | 390 | * |
kenjiArai | 0:5b88d5760320 | 391 | * @return pointer to local CSRK |
kenjiArai | 0:5b88d5760320 | 392 | */ |
kenjiArai | 0:5b88d5760320 | 393 | virtual const csrk_t* get_local_csrk() { |
kenjiArai | 0:5b88d5760320 | 394 | return &_local_csrk; |
kenjiArai | 0:5b88d5760320 | 395 | } |
kenjiArai | 0:5b88d5760320 | 396 | |
kenjiArai | 0:5b88d5760320 | 397 | /** |
kenjiArai | 0:5b88d5760320 | 398 | * Return local signing counter. |
kenjiArai | 0:5b88d5760320 | 399 | * |
kenjiArai | 0:5b88d5760320 | 400 | * @return signing counter |
kenjiArai | 0:5b88d5760320 | 401 | */ |
kenjiArai | 0:5b88d5760320 | 402 | virtual sign_count_t get_local_sign_counter() { |
kenjiArai | 0:5b88d5760320 | 403 | return _local_sign_counter; |
kenjiArai | 0:5b88d5760320 | 404 | } |
kenjiArai | 0:5b88d5760320 | 405 | |
kenjiArai | 0:5b88d5760320 | 406 | /** |
kenjiArai | 0:5b88d5760320 | 407 | * Update local signing key. |
kenjiArai | 0:5b88d5760320 | 408 | * |
kenjiArai | 0:5b88d5760320 | 409 | * @param[in] csrk new CSRK value |
kenjiArai | 0:5b88d5760320 | 410 | */ |
kenjiArai | 0:5b88d5760320 | 411 | virtual void set_local_csrk( |
kenjiArai | 0:5b88d5760320 | 412 | const csrk_t &csrk |
kenjiArai | 0:5b88d5760320 | 413 | ) { |
kenjiArai | 0:5b88d5760320 | 414 | _local_csrk = csrk; |
kenjiArai | 0:5b88d5760320 | 415 | } |
kenjiArai | 0:5b88d5760320 | 416 | |
kenjiArai | 0:5b88d5760320 | 417 | /** |
kenjiArai | 0:5b88d5760320 | 418 | * Update local signing counter. |
kenjiArai | 0:5b88d5760320 | 419 | * |
kenjiArai | 0:5b88d5760320 | 420 | * @param[in] sign_counter new signing counter value |
kenjiArai | 0:5b88d5760320 | 421 | */ |
kenjiArai | 0:5b88d5760320 | 422 | virtual void set_local_sign_counter( |
kenjiArai | 0:5b88d5760320 | 423 | sign_count_t sign_counter |
kenjiArai | 0:5b88d5760320 | 424 | ) { |
kenjiArai | 0:5b88d5760320 | 425 | _local_sign_counter = sign_counter; |
kenjiArai | 0:5b88d5760320 | 426 | } |
kenjiArai | 0:5b88d5760320 | 427 | |
kenjiArai | 0:5b88d5760320 | 428 | /* list management */ |
kenjiArai | 0:5b88d5760320 | 429 | |
kenjiArai | 0:5b88d5760320 | 430 | /** |
kenjiArai | 0:5b88d5760320 | 431 | * Open a database entry. |
kenjiArai | 0:5b88d5760320 | 432 | * |
kenjiArai | 0:5b88d5760320 | 433 | * While this entry is opened; it can be queried and updated with the help |
kenjiArai | 0:5b88d5760320 | 434 | * of the database setter and getter functions. |
kenjiArai | 0:5b88d5760320 | 435 | * |
kenjiArai | 0:5b88d5760320 | 436 | * @param[in] peer_address_type type of address |
kenjiArai | 0:5b88d5760320 | 437 | * @param[in] peer_address this address will be used to locate an existing |
kenjiArai | 0:5b88d5760320 | 438 | * entry. |
kenjiArai | 0:5b88d5760320 | 439 | * |
kenjiArai | 0:5b88d5760320 | 440 | * @return A handle to the entry. |
kenjiArai | 0:5b88d5760320 | 441 | */ |
kenjiArai | 0:5b88d5760320 | 442 | virtual entry_handle_t open_entry( |
kenjiArai | 0:5b88d5760320 | 443 | peer_address_type_t peer_address_type, |
kenjiArai | 0:5b88d5760320 | 444 | const address_t &peer_address |
kenjiArai | 0:5b88d5760320 | 445 | ) { |
kenjiArai | 0:5b88d5760320 | 446 | entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address); |
kenjiArai | 0:5b88d5760320 | 447 | if (db_handle) { |
kenjiArai | 0:5b88d5760320 | 448 | return db_handle; |
kenjiArai | 0:5b88d5760320 | 449 | } |
kenjiArai | 0:5b88d5760320 | 450 | |
kenjiArai | 0:5b88d5760320 | 451 | SecurityDistributionFlags_t* flags = get_free_entry_flags(); |
kenjiArai | 0:5b88d5760320 | 452 | if (flags) { |
kenjiArai | 0:5b88d5760320 | 453 | const bool peer_address_public = |
kenjiArai | 0:5b88d5760320 | 454 | (peer_address_type == peer_address_type_t::PUBLIC) || |
kenjiArai | 0:5b88d5760320 | 455 | (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY); |
kenjiArai | 0:5b88d5760320 | 456 | /* we need some address to store, so we store even random ones |
kenjiArai | 0:5b88d5760320 | 457 | * this address will be used as an id, possibly replaced later |
kenjiArai | 0:5b88d5760320 | 458 | * by identity address */ |
kenjiArai | 0:5b88d5760320 | 459 | flags->peer_address = peer_address; |
kenjiArai | 0:5b88d5760320 | 460 | flags->peer_address_is_public = peer_address_public; |
kenjiArai | 0:5b88d5760320 | 461 | return flags; |
kenjiArai | 0:5b88d5760320 | 462 | } |
kenjiArai | 0:5b88d5760320 | 463 | |
kenjiArai | 0:5b88d5760320 | 464 | return NULL; |
kenjiArai | 0:5b88d5760320 | 465 | } |
kenjiArai | 0:5b88d5760320 | 466 | |
kenjiArai | 0:5b88d5760320 | 467 | /** |
kenjiArai | 0:5b88d5760320 | 468 | * Find a database entry based on peer address. |
kenjiArai | 0:5b88d5760320 | 469 | * |
kenjiArai | 0:5b88d5760320 | 470 | * @param[in] peer_address_type type of address |
kenjiArai | 0:5b88d5760320 | 471 | * @param[in] peer_address this address will be used to locate an existing entry. |
kenjiArai | 0:5b88d5760320 | 472 | * |
kenjiArai | 0:5b88d5760320 | 473 | * @return A handle to the entry. |
kenjiArai | 0:5b88d5760320 | 474 | */ |
kenjiArai | 0:5b88d5760320 | 475 | virtual entry_handle_t find_entry_by_peer_address( |
kenjiArai | 0:5b88d5760320 | 476 | peer_address_type_t peer_address_type, |
kenjiArai | 0:5b88d5760320 | 477 | const address_t &peer_address |
kenjiArai | 0:5b88d5760320 | 478 | ) { |
kenjiArai | 0:5b88d5760320 | 479 | const bool peer_address_public = |
kenjiArai | 0:5b88d5760320 | 480 | (peer_address_type == peer_address_type_t::PUBLIC) || |
kenjiArai | 0:5b88d5760320 | 481 | (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY); |
kenjiArai | 0:5b88d5760320 | 482 | |
kenjiArai | 0:5b88d5760320 | 483 | for (size_t i = 0; i < get_entry_count(); i++) { |
kenjiArai | 0:5b88d5760320 | 484 | entry_handle_t db_handle = get_entry_handle_by_index(i); |
kenjiArai | 0:5b88d5760320 | 485 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 486 | |
kenjiArai | 0:5b88d5760320 | 487 | /* only look among disconnected entries */ |
kenjiArai | 0:5b88d5760320 | 488 | if (flags && !flags->connected) { |
kenjiArai | 0:5b88d5760320 | 489 | if (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY && |
kenjiArai | 0:5b88d5760320 | 490 | flags->irk_stored == false) { |
kenjiArai | 0:5b88d5760320 | 491 | continue; |
kenjiArai | 0:5b88d5760320 | 492 | } |
kenjiArai | 0:5b88d5760320 | 493 | |
kenjiArai | 0:5b88d5760320 | 494 | /* lookup for connection address used during bonding */ |
kenjiArai | 0:5b88d5760320 | 495 | if (flags->peer_address == peer_address && |
kenjiArai | 0:5b88d5760320 | 496 | flags->peer_address_is_public == peer_address_public) { |
kenjiArai | 0:5b88d5760320 | 497 | return flags; |
kenjiArai | 0:5b88d5760320 | 498 | } |
kenjiArai | 0:5b88d5760320 | 499 | |
kenjiArai | 0:5b88d5760320 | 500 | /* look for the identity address if stored */ |
kenjiArai | 0:5b88d5760320 | 501 | if (flags->irk_stored) { |
kenjiArai | 0:5b88d5760320 | 502 | SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle); |
kenjiArai | 0:5b88d5760320 | 503 | |
kenjiArai | 0:5b88d5760320 | 504 | if (identity && |
kenjiArai | 0:5b88d5760320 | 505 | identity->identity_address == peer_address && |
kenjiArai | 0:5b88d5760320 | 506 | identity->identity_address_is_public == peer_address_public) { |
kenjiArai | 0:5b88d5760320 | 507 | return flags; |
kenjiArai | 0:5b88d5760320 | 508 | } |
kenjiArai | 0:5b88d5760320 | 509 | } |
kenjiArai | 0:5b88d5760320 | 510 | } |
kenjiArai | 0:5b88d5760320 | 511 | } |
kenjiArai | 0:5b88d5760320 | 512 | |
kenjiArai | 0:5b88d5760320 | 513 | return NULL; |
kenjiArai | 0:5b88d5760320 | 514 | } |
kenjiArai | 0:5b88d5760320 | 515 | |
kenjiArai | 0:5b88d5760320 | 516 | /** |
kenjiArai | 0:5b88d5760320 | 517 | * Close a connection entry. |
kenjiArai | 0:5b88d5760320 | 518 | * |
kenjiArai | 0:5b88d5760320 | 519 | * @param[in] db_handle this handle will be freed up from the security db. |
kenjiArai | 0:5b88d5760320 | 520 | */ |
kenjiArai | 0:5b88d5760320 | 521 | virtual void close_entry(entry_handle_t db_handle) { |
kenjiArai | 0:5b88d5760320 | 522 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 523 | if (flags) { |
kenjiArai | 0:5b88d5760320 | 524 | flags->connected = false; |
kenjiArai | 0:5b88d5760320 | 525 | } |
kenjiArai | 0:5b88d5760320 | 526 | sync(db_handle); |
kenjiArai | 0:5b88d5760320 | 527 | } |
kenjiArai | 0:5b88d5760320 | 528 | |
kenjiArai | 0:5b88d5760320 | 529 | /** |
kenjiArai | 0:5b88d5760320 | 530 | * Remove entry for this peer from NVM. |
kenjiArai | 0:5b88d5760320 | 531 | * |
kenjiArai | 0:5b88d5760320 | 532 | * @param[in] peer_address_type type of address |
kenjiArai | 0:5b88d5760320 | 533 | * @param[in] peer_address this address will be used to locate an existing |
kenjiArai | 0:5b88d5760320 | 534 | * entry. |
kenjiArai | 0:5b88d5760320 | 535 | * |
kenjiArai | 0:5b88d5760320 | 536 | * @return A handle to the entry. |
kenjiArai | 0:5b88d5760320 | 537 | */ |
kenjiArai | 0:5b88d5760320 | 538 | virtual void remove_entry( |
kenjiArai | 0:5b88d5760320 | 539 | peer_address_type_t peer_address_type, |
kenjiArai | 0:5b88d5760320 | 540 | const address_t &peer_address |
kenjiArai | 0:5b88d5760320 | 541 | ) { |
kenjiArai | 0:5b88d5760320 | 542 | entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address); |
kenjiArai | 0:5b88d5760320 | 543 | if (db_handle) { |
kenjiArai | 0:5b88d5760320 | 544 | reset_entry(db_handle); |
kenjiArai | 0:5b88d5760320 | 545 | } |
kenjiArai | 0:5b88d5760320 | 546 | } |
kenjiArai | 0:5b88d5760320 | 547 | |
kenjiArai | 0:5b88d5760320 | 548 | /** |
kenjiArai | 0:5b88d5760320 | 549 | * Remove all entries from the security DB. |
kenjiArai | 0:5b88d5760320 | 550 | */ |
kenjiArai | 0:5b88d5760320 | 551 | virtual void clear_entries() { |
kenjiArai | 0:5b88d5760320 | 552 | for (size_t i = 0; i < get_entry_count(); i++) { |
kenjiArai | 0:5b88d5760320 | 553 | entry_handle_t db_handle = get_entry_handle_by_index(i); |
kenjiArai | 0:5b88d5760320 | 554 | reset_entry(db_handle); |
kenjiArai | 0:5b88d5760320 | 555 | } |
kenjiArai | 0:5b88d5760320 | 556 | _local_identity = SecurityEntryIdentity_t(); |
kenjiArai | 0:5b88d5760320 | 557 | _local_csrk = csrk_t(); |
kenjiArai | 0:5b88d5760320 | 558 | } |
kenjiArai | 0:5b88d5760320 | 559 | |
kenjiArai | 0:5b88d5760320 | 560 | /** |
kenjiArai | 0:5b88d5760320 | 561 | * Asynchronously return the whitelist stored in NVM through a callback. |
kenjiArai | 0:5b88d5760320 | 562 | * Function takes ownership of the memory. The whitelist and the ownership |
kenjiArai | 0:5b88d5760320 | 563 | * will be returned in the callback. |
kenjiArai | 0:5b88d5760320 | 564 | * |
kenjiArai | 0:5b88d5760320 | 565 | * @param[in] cb callback that will receive the whitelist |
kenjiArai | 0:5b88d5760320 | 566 | * @param[in] whitelist preallocated whitelist that will be filled in |
kenjiArai | 0:5b88d5760320 | 567 | */ |
kenjiArai | 0:5b88d5760320 | 568 | virtual void get_whitelist( |
kenjiArai | 0:5b88d5760320 | 569 | WhitelistDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 570 | ::Gap::Whitelist_t *whitelist |
kenjiArai | 0:5b88d5760320 | 571 | ) { |
kenjiArai | 0:5b88d5760320 | 572 | /*TODO: fill whitelist*/ |
kenjiArai | 0:5b88d5760320 | 573 | cb(whitelist); |
kenjiArai | 0:5b88d5760320 | 574 | } |
kenjiArai | 0:5b88d5760320 | 575 | |
kenjiArai | 0:5b88d5760320 | 576 | /** |
kenjiArai | 0:5b88d5760320 | 577 | * Asynchronously return a whitelist through a callback, generated from the |
kenjiArai | 0:5b88d5760320 | 578 | * bond table. |
kenjiArai | 0:5b88d5760320 | 579 | * |
kenjiArai | 0:5b88d5760320 | 580 | * @param[in] cb callback that will receive the whitelist |
kenjiArai | 0:5b88d5760320 | 581 | * @param[in] whitelist preallocated whitelist that will be filled in |
kenjiArai | 0:5b88d5760320 | 582 | */ |
kenjiArai | 0:5b88d5760320 | 583 | virtual void generate_whitelist_from_bond_table( |
kenjiArai | 0:5b88d5760320 | 584 | WhitelistDbCb_t cb, |
kenjiArai | 0:5b88d5760320 | 585 | ::Gap::Whitelist_t *whitelist |
kenjiArai | 0:5b88d5760320 | 586 | ) { |
kenjiArai | 0:5b88d5760320 | 587 | for (size_t i = 0; i < get_entry_count() && whitelist->size < whitelist->capacity; i++) { |
kenjiArai | 0:5b88d5760320 | 588 | entry_handle_t db_handle = get_entry_handle_by_index(i); |
kenjiArai | 0:5b88d5760320 | 589 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 590 | |
kenjiArai | 0:5b88d5760320 | 591 | if (!flags || !flags->irk_stored) { |
kenjiArai | 0:5b88d5760320 | 592 | continue; |
kenjiArai | 0:5b88d5760320 | 593 | } |
kenjiArai | 0:5b88d5760320 | 594 | |
kenjiArai | 0:5b88d5760320 | 595 | SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle); |
kenjiArai | 0:5b88d5760320 | 596 | if (!identity) { |
kenjiArai | 0:5b88d5760320 | 597 | continue; |
kenjiArai | 0:5b88d5760320 | 598 | } |
kenjiArai | 0:5b88d5760320 | 599 | |
kenjiArai | 0:5b88d5760320 | 600 | memcpy( |
kenjiArai | 0:5b88d5760320 | 601 | whitelist->addresses[whitelist->size].address, |
kenjiArai | 0:5b88d5760320 | 602 | identity->identity_address.data(), |
kenjiArai | 0:5b88d5760320 | 603 | sizeof(BLEProtocol::AddressBytes_t) |
kenjiArai | 0:5b88d5760320 | 604 | ); |
kenjiArai | 0:5b88d5760320 | 605 | |
kenjiArai | 0:5b88d5760320 | 606 | if (identity->identity_address_is_public) { |
kenjiArai | 0:5b88d5760320 | 607 | whitelist->addresses[whitelist->size].type = BLEProtocol::AddressType::PUBLIC; |
kenjiArai | 0:5b88d5760320 | 608 | } else { |
kenjiArai | 0:5b88d5760320 | 609 | whitelist->addresses[whitelist->size].type = BLEProtocol::AddressType::RANDOM_STATIC; |
kenjiArai | 0:5b88d5760320 | 610 | } |
kenjiArai | 0:5b88d5760320 | 611 | |
kenjiArai | 0:5b88d5760320 | 612 | whitelist->size++; |
kenjiArai | 0:5b88d5760320 | 613 | } |
kenjiArai | 0:5b88d5760320 | 614 | |
kenjiArai | 0:5b88d5760320 | 615 | cb(whitelist); |
kenjiArai | 0:5b88d5760320 | 616 | } |
kenjiArai | 0:5b88d5760320 | 617 | |
kenjiArai | 0:5b88d5760320 | 618 | /** |
kenjiArai | 0:5b88d5760320 | 619 | * Update the whitelist stored in NVM by replacing it with new one. |
kenjiArai | 0:5b88d5760320 | 620 | * |
kenjiArai | 0:5b88d5760320 | 621 | * @param[in] whitelist |
kenjiArai | 0:5b88d5760320 | 622 | */ |
kenjiArai | 0:5b88d5760320 | 623 | virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) { }; |
kenjiArai | 0:5b88d5760320 | 624 | |
kenjiArai | 0:5b88d5760320 | 625 | /** |
kenjiArai | 0:5b88d5760320 | 626 | * Add a new entry to the whitelist in the NVM. |
kenjiArai | 0:5b88d5760320 | 627 | * |
kenjiArai | 0:5b88d5760320 | 628 | * @param[in] address new whitelist entry |
kenjiArai | 0:5b88d5760320 | 629 | */ |
kenjiArai | 0:5b88d5760320 | 630 | virtual void add_whitelist_entry(const address_t &address) { }; |
kenjiArai | 0:5b88d5760320 | 631 | |
kenjiArai | 0:5b88d5760320 | 632 | /** |
kenjiArai | 0:5b88d5760320 | 633 | * Remove whitelist entry from NVM. |
kenjiArai | 0:5b88d5760320 | 634 | * |
kenjiArai | 0:5b88d5760320 | 635 | * @param[in] address entry to be removed |
kenjiArai | 0:5b88d5760320 | 636 | */ |
kenjiArai | 0:5b88d5760320 | 637 | virtual void remove_whitelist_entry(const address_t &address) { }; |
kenjiArai | 0:5b88d5760320 | 638 | |
kenjiArai | 0:5b88d5760320 | 639 | /** |
kenjiArai | 0:5b88d5760320 | 640 | *Remove all whitelist entries stored in the NVM. |
kenjiArai | 0:5b88d5760320 | 641 | */ |
kenjiArai | 0:5b88d5760320 | 642 | virtual void clear_whitelist() { }; |
kenjiArai | 0:5b88d5760320 | 643 | |
kenjiArai | 0:5b88d5760320 | 644 | /* saving and loading from nvm */ |
kenjiArai | 0:5b88d5760320 | 645 | |
kenjiArai | 0:5b88d5760320 | 646 | /** |
kenjiArai | 0:5b88d5760320 | 647 | * Read values from storage. |
kenjiArai | 0:5b88d5760320 | 648 | */ |
kenjiArai | 0:5b88d5760320 | 649 | virtual void restore() { }; |
kenjiArai | 0:5b88d5760320 | 650 | |
kenjiArai | 0:5b88d5760320 | 651 | /** |
kenjiArai | 0:5b88d5760320 | 652 | * Flush all values which might be stored in memory into NVM. |
kenjiArai | 0:5b88d5760320 | 653 | */ |
kenjiArai | 0:5b88d5760320 | 654 | virtual void sync(entry_handle_t db_handle) { }; |
kenjiArai | 0:5b88d5760320 | 655 | |
kenjiArai | 0:5b88d5760320 | 656 | /** |
kenjiArai | 0:5b88d5760320 | 657 | * Toggle whether values should be preserved across resets. |
kenjiArai | 0:5b88d5760320 | 658 | * |
kenjiArai | 0:5b88d5760320 | 659 | * @param[in] reload if true values will be preserved across resets. |
kenjiArai | 0:5b88d5760320 | 660 | */ |
kenjiArai | 0:5b88d5760320 | 661 | virtual void set_restore(bool reload) { }; |
kenjiArai | 0:5b88d5760320 | 662 | |
kenjiArai | 0:5b88d5760320 | 663 | private: |
kenjiArai | 0:5b88d5760320 | 664 | /** |
kenjiArai | 0:5b88d5760320 | 665 | * Get an entry for a new connection not present in the db yet. This will find a free entry |
kenjiArai | 0:5b88d5760320 | 666 | * or use a disconnected entry by reseting all the stored information. |
kenjiArai | 0:5b88d5760320 | 667 | * @return empty entry for the new connection |
kenjiArai | 0:5b88d5760320 | 668 | */ |
kenjiArai | 0:5b88d5760320 | 669 | virtual SecurityDistributionFlags_t* get_free_entry_flags() { |
kenjiArai | 0:5b88d5760320 | 670 | /* get a free one if available */ |
kenjiArai | 0:5b88d5760320 | 671 | SecurityDistributionFlags_t* match = NULL; |
kenjiArai | 0:5b88d5760320 | 672 | for (size_t i = 0; i < get_entry_count(); i++) { |
kenjiArai | 0:5b88d5760320 | 673 | entry_handle_t db_handle = get_entry_handle_by_index(i); |
kenjiArai | 0:5b88d5760320 | 674 | SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle); |
kenjiArai | 0:5b88d5760320 | 675 | |
kenjiArai | 0:5b88d5760320 | 676 | if (flags && !flags->connected) { |
kenjiArai | 0:5b88d5760320 | 677 | /* we settle for any disconnected if we don't find an empty one */ |
kenjiArai | 0:5b88d5760320 | 678 | match = flags; |
kenjiArai | 0:5b88d5760320 | 679 | if (!flags->csrk_stored |
kenjiArai | 0:5b88d5760320 | 680 | && !flags->ltk_stored |
kenjiArai | 0:5b88d5760320 | 681 | && !flags->ltk_sent |
kenjiArai | 0:5b88d5760320 | 682 | && !flags->irk_stored) { |
kenjiArai | 0:5b88d5760320 | 683 | /* empty one found, stop looking*/ |
kenjiArai | 0:5b88d5760320 | 684 | break; |
kenjiArai | 0:5b88d5760320 | 685 | } |
kenjiArai | 0:5b88d5760320 | 686 | } |
kenjiArai | 0:5b88d5760320 | 687 | } |
kenjiArai | 0:5b88d5760320 | 688 | |
kenjiArai | 0:5b88d5760320 | 689 | if (match) { |
kenjiArai | 0:5b88d5760320 | 690 | reset_entry(match); |
kenjiArai | 0:5b88d5760320 | 691 | } |
kenjiArai | 0:5b88d5760320 | 692 | |
kenjiArai | 0:5b88d5760320 | 693 | return match; |
kenjiArai | 0:5b88d5760320 | 694 | } |
kenjiArai | 0:5b88d5760320 | 695 | |
kenjiArai | 0:5b88d5760320 | 696 | /** |
kenjiArai | 0:5b88d5760320 | 697 | * How many entries can be stored in the databes. |
kenjiArai | 0:5b88d5760320 | 698 | * @return max number of entries |
kenjiArai | 0:5b88d5760320 | 699 | */ |
kenjiArai | 0:5b88d5760320 | 700 | virtual uint8_t get_entry_count() = 0; |
kenjiArai | 0:5b88d5760320 | 701 | |
kenjiArai | 0:5b88d5760320 | 702 | /** |
kenjiArai | 0:5b88d5760320 | 703 | * Return database entry based on its index. |
kenjiArai | 0:5b88d5760320 | 704 | * @param index index from 0 to get_entry_count() |
kenjiArai | 0:5b88d5760320 | 705 | * @return databse entry stored at index |
kenjiArai | 0:5b88d5760320 | 706 | */ |
kenjiArai | 0:5b88d5760320 | 707 | virtual SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) = 0; |
kenjiArai | 0:5b88d5760320 | 708 | |
kenjiArai | 0:5b88d5760320 | 709 | /** |
kenjiArai | 0:5b88d5760320 | 710 | * Delete all the information. |
kenjiArai | 0:5b88d5760320 | 711 | * @param db_handle handle for the entry to be reset |
kenjiArai | 0:5b88d5760320 | 712 | */ |
kenjiArai | 0:5b88d5760320 | 713 | virtual void reset_entry(entry_handle_t db_handle) = 0; |
kenjiArai | 0:5b88d5760320 | 714 | |
kenjiArai | 0:5b88d5760320 | 715 | /** |
kenjiArai | 0:5b88d5760320 | 716 | * This will read in the requested information into a buffer that will remain valid |
kenjiArai | 0:5b88d5760320 | 717 | * until another read_in call is made. |
kenjiArai | 0:5b88d5760320 | 718 | * @param db_handle handle of the entry to be read |
kenjiArai | 0:5b88d5760320 | 719 | * @return pointer to buffer holding the query result, NULL when not found |
kenjiArai | 0:5b88d5760320 | 720 | */ |
kenjiArai | 0:5b88d5760320 | 721 | virtual SecurityEntryIdentity_t* read_in_entry_peer_identity(entry_handle_t db_handle) = 0; |
kenjiArai | 0:5b88d5760320 | 722 | |
kenjiArai | 0:5b88d5760320 | 723 | /** |
kenjiArai | 0:5b88d5760320 | 724 | * This will read in the requested information into a buffer that will remain valid |
kenjiArai | 0:5b88d5760320 | 725 | * until another read_in call is made. |
kenjiArai | 0:5b88d5760320 | 726 | * @param db_handle handle of the entry to be read |
kenjiArai | 0:5b88d5760320 | 727 | * @return pointer to buffer holding the query result, NULL when not found |
kenjiArai | 0:5b88d5760320 | 728 | */ |
kenjiArai | 0:5b88d5760320 | 729 | virtual SecurityEntryKeys_t* read_in_entry_peer_keys(entry_handle_t db_handle) = 0; |
kenjiArai | 0:5b88d5760320 | 730 | |
kenjiArai | 0:5b88d5760320 | 731 | /** |
kenjiArai | 0:5b88d5760320 | 732 | * This will read in the requested information into a buffer that will remain valid |
kenjiArai | 0:5b88d5760320 | 733 | * until another read_in call is made. |
kenjiArai | 0:5b88d5760320 | 734 | * @param db_handle handle of the entry to be read |
kenjiArai | 0:5b88d5760320 | 735 | * @return pointer to buffer holding the query result, NULL when not found |
kenjiArai | 0:5b88d5760320 | 736 | */ |
kenjiArai | 0:5b88d5760320 | 737 | virtual SecurityEntryKeys_t* read_in_entry_local_keys(entry_handle_t db_handle) = 0; |
kenjiArai | 0:5b88d5760320 | 738 | |
kenjiArai | 0:5b88d5760320 | 739 | /** |
kenjiArai | 0:5b88d5760320 | 740 | * This will read in the requested information into a buffer that will remain valid |
kenjiArai | 0:5b88d5760320 | 741 | * until another read_in call is made. |
kenjiArai | 0:5b88d5760320 | 742 | * @param db_handle handle of the entry to be read |
kenjiArai | 0:5b88d5760320 | 743 | * @return pointer to buffer holding the query result, NULL when not found |
kenjiArai | 0:5b88d5760320 | 744 | */ |
kenjiArai | 0:5b88d5760320 | 745 | virtual SecurityEntrySigning_t* read_in_entry_peer_signing(entry_handle_t db_handle) = 0; |
kenjiArai | 0:5b88d5760320 | 746 | |
kenjiArai | 0:5b88d5760320 | 747 | protected: |
kenjiArai | 0:5b88d5760320 | 748 | SecurityEntryIdentity_t _local_identity; |
kenjiArai | 0:5b88d5760320 | 749 | csrk_t _local_csrk; |
kenjiArai | 0:5b88d5760320 | 750 | sign_count_t _local_sign_counter; |
kenjiArai | 0:5b88d5760320 | 751 | }; |
kenjiArai | 0:5b88d5760320 | 752 | |
kenjiArai | 0:5b88d5760320 | 753 | } /* namespace pal */ |
kenjiArai | 0:5b88d5760320 | 754 | } /* namespace ble */ |
kenjiArai | 0:5b88d5760320 | 755 | |
kenjiArai | 0:5b88d5760320 | 756 | #endif /*GENERIC_SECURITY_MANAGER_DB_H__*/ |