mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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?

UserRevisionLine numberNew 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 &ltk
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 &ltk
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__*/