Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MemorySecurityDb.h Source File

MemorySecurityDb.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef PAL_MEMORY_SECURITY_DB_H_
00018 #define PAL_MEMORY_SECURITY_DB_H_
00019 
00020 #include "SecurityDb.h"
00021 
00022 namespace ble {
00023 namespace pal {
00024 
00025 /** Naive memory implementation for verification. */
00026 class MemorySecurityDb : public SecurityDb {
00027 private:
00028     enum state_t {
00029         ENTRY_FREE,
00030         ENTRY_RESERVED,
00031         ENTRY_WRITTEN
00032     };
00033 
00034     struct entry_t {
00035         entry_t() : state(ENTRY_FREE) { };
00036         SecurityDistributionFlags_t flags;
00037         SecurityEntryKeys_t peer_keys;
00038         SecurityEntryKeys_t local_keys;
00039         SecurityEntryIdentity_t peer_identity;
00040         csrk_t csrk;
00041         state_t state;
00042     };
00043     static const size_t MAX_ENTRIES = 5;
00044 
00045     static entry_t* as_entry(entry_handle_t entry_handle)
00046     {
00047         return reinterpret_cast<entry_t*>(entry_handle);
00048     }
00049 
00050 public:
00051     MemorySecurityDb() { };
00052     virtual ~MemorySecurityDb() { };
00053 
00054     virtual const SecurityDistributionFlags_t* get_distribution_flags(
00055         entry_handle_t entry_handle
00056     ) {
00057         entry_t* entry = as_entry(entry_handle);
00058         if (!entry) {
00059             return NULL;
00060         }
00061 
00062         return &entry->flags;
00063     }
00064 
00065     /**
00066      * Set the distribution flags of the DB entry
00067      */
00068     virtual void set_distribution_flags(
00069         entry_handle_t entry_handle,
00070         const SecurityDistributionFlags_t& flags
00071     ) {
00072         entry_t* entry = as_entry(entry_handle);
00073         if (!entry) {
00074             return;
00075         }
00076 
00077         entry->state = ENTRY_WRITTEN;
00078         entry->flags = flags;
00079     }
00080 
00081     /* local keys */
00082 
00083     /* get */
00084     virtual void get_entry_local_keys(
00085         SecurityEntryKeysDbCb_t cb,
00086         entry_handle_t entry_handle,
00087         const ediv_t &ediv,
00088         const rand_t &rand
00089     ) {
00090         entry_t* entry = as_entry(entry_handle);
00091         if (!entry) {
00092             return;
00093         }
00094 
00095         /* validate we have the correct key */
00096         if (ediv == entry->local_keys.ediv && rand == entry->local_keys.rand) {
00097             cb(entry_handle, &entry->local_keys);
00098         } else {
00099             cb(entry_handle, NULL);
00100         }
00101     }
00102 
00103     virtual void get_entry_local_keys(
00104         SecurityEntryKeysDbCb_t cb,
00105         entry_handle_t entry_handle
00106     ) {
00107         entry_t* entry = as_entry(entry_handle);
00108         if (!entry) {
00109             return;
00110         }
00111 
00112         /* validate we have the correct key */
00113         if (entry->flags.secure_connections_paired) {
00114             cb(entry_handle, &entry->local_keys);
00115         } else {
00116             cb(entry_handle, NULL);
00117         }
00118     }
00119 
00120 
00121     /* set */
00122     virtual void set_entry_local_ltk(
00123         entry_handle_t entry_handle,
00124         const ltk_t &ltk
00125     ) {
00126         entry_t *entry = as_entry(entry_handle);
00127         if (entry) {
00128             entry->state = ENTRY_WRITTEN;
00129             entry->local_keys.ltk = ltk;
00130         }
00131     }
00132 
00133     virtual void set_entry_local_ediv_rand(
00134         entry_handle_t entry_handle,
00135         const ediv_t &ediv,
00136         const rand_t &rand
00137     ) {
00138         entry_t *entry = as_entry(entry_handle);
00139         if (entry) {
00140             entry->state = ENTRY_WRITTEN;
00141             entry->local_keys.ediv = ediv;
00142             entry->local_keys.rand = rand;
00143         }
00144     }
00145 
00146     /* peer's keys */
00147 
00148     /* get */
00149     virtual void get_entry_peer_csrk(
00150         SecurityEntryCsrkDbCb_t cb,
00151         entry_handle_t entry_handle
00152     ) {
00153         csrk_t csrk;
00154         entry_t *entry = as_entry(entry_handle);
00155         if (entry) {
00156             csrk = entry->csrk;
00157         }
00158         cb(entry_handle, &csrk);
00159     }
00160 
00161     virtual void get_entry_peer_keys(
00162         SecurityEntryKeysDbCb_t cb,
00163         entry_handle_t entry_handle
00164     ) {
00165         SecurityEntryKeys_t *key = NULL;
00166         entry_t *entry = as_entry(entry_handle);
00167         if (entry) {
00168             key = &entry->peer_keys;
00169         }
00170         cb(entry_handle, key);
00171     }
00172 
00173     /* set */
00174 
00175     virtual void set_entry_peer_ltk(
00176         entry_handle_t entry_handle,
00177         const ltk_t &ltk
00178     ) {
00179         entry_t *entry = as_entry(entry_handle);
00180         if (entry) {
00181             entry->state = ENTRY_WRITTEN;
00182             entry->peer_keys.ltk = ltk;
00183         }
00184     }
00185 
00186     virtual void set_entry_peer_ediv_rand(
00187         entry_handle_t entry_handle,
00188         const ediv_t &ediv,
00189         const rand_t &rand
00190     ) {
00191         entry_t *entry = as_entry(entry_handle);
00192         if (entry) {
00193             entry->state = ENTRY_WRITTEN;
00194             entry->peer_keys.ediv = ediv;
00195             entry->peer_keys.rand = rand;
00196         }
00197     }
00198 
00199     virtual void set_entry_peer_irk(
00200         entry_handle_t entry_handle,
00201         const irk_t &irk
00202     ) {
00203         entry_t *entry = as_entry(entry_handle);
00204         if (entry) {
00205             entry->state = ENTRY_WRITTEN;
00206             entry->peer_identity.irk = irk;
00207         }
00208     }
00209 
00210     virtual void set_entry_peer_bdaddr(
00211         entry_handle_t entry_handle,
00212         bool address_is_public,
00213         const address_t &peer_address
00214     ) {
00215         entry_t *entry = as_entry(entry_handle);
00216         if (entry) {
00217             entry->state = ENTRY_WRITTEN;
00218             entry->peer_identity.identity_address = peer_address;
00219         }
00220     }
00221 
00222     virtual void set_entry_peer_csrk(
00223         entry_handle_t entry_handle,
00224         const csrk_t &csrk
00225     ) {
00226         entry_t *entry = as_entry(entry_handle);
00227         if (entry) {
00228             entry->state = ENTRY_WRITTEN;
00229             entry->csrk = csrk;
00230         }
00231     }
00232 
00233     /* local csrk */
00234 
00235     virtual const csrk_t* get_local_csrk() {
00236         return &_local_csrk;
00237     }
00238 
00239     virtual void set_local_csrk(const csrk_t &csrk) {
00240         _local_csrk = csrk;
00241     }
00242 
00243     /* public key */
00244 
00245     virtual const public_key_coord_t& get_public_key_x() {
00246         return _public_key_x;
00247     }
00248 
00249     virtual const public_key_coord_t& get_public_key_y() {
00250         return _public_key_y;
00251     }
00252 
00253     virtual void set_public_key(
00254         const public_key_coord_t &public_key_x,
00255         const public_key_coord_t &public_key_y
00256     ) {
00257         _public_key_x = public_key_x;
00258         _public_key_y = public_key_y;
00259     }
00260 
00261     /* list management */
00262 
00263     virtual entry_handle_t open_entry(
00264         BLEProtocol::AddressType_t peer_address_type,
00265         const address_t &peer_address
00266     ) {
00267         const bool peer_address_public =
00268             (peer_address_type == BLEProtocol::AddressType::PUBLIC);
00269 
00270         for (size_t i = 0; i < MAX_ENTRIES; i++) {
00271             if (_entries[i].state == ENTRY_FREE) {
00272                 continue;
00273             } else if (peer_address == _entries[i].peer_identity.identity_address
00274                 && _entries[i].flags.peer_address_is_public == peer_address_public) {
00275                 return &_entries[i];
00276             }
00277         }
00278 
00279         /* if we din't find one grab the first disconnected slot*/
00280         for (size_t i = 0; i < MAX_ENTRIES; i++) {
00281             if (_entries[i].state == ENTRY_FREE) {
00282                 _entries[i] = entry_t();
00283                 _entries[i].flags.peer_address = peer_address;
00284                 _entries[i].flags.peer_address_is_public = peer_address_public;
00285                 _entries[i].state = ENTRY_RESERVED;
00286                 return &_entries[i];
00287             }
00288         }
00289 
00290         return NULL;
00291     }
00292 
00293     virtual void close_entry(entry_handle_t entry_handle)
00294     {
00295         entry_t *entry = as_entry(entry_handle);
00296         if (entry && entry->state == ENTRY_RESERVED) {
00297             entry->state = ENTRY_FREE;
00298         }
00299     }
00300 
00301     virtual void remove_entry(const address_t peer_identity_address)
00302     {
00303         for (size_t i = 0; i < MAX_ENTRIES; i++) {
00304             if (_entries[i].state == ENTRY_FREE) {
00305                 continue;
00306             } else if (peer_identity_address == _entries[i].peer_identity.identity_address) {
00307                 _entries[i] = entry_t();
00308                 _entries[i].state = ENTRY_FREE;
00309                 return;
00310             }
00311         }
00312     }
00313 
00314     virtual void clear_entries() {
00315         for (size_t i = 0; i < MAX_ENTRIES; i++) {
00316             _entries[i] = entry_t();
00317         }
00318         _local_identity = SecurityEntryIdentity_t();
00319         _local_csrk = csrk_t();
00320     }
00321 
00322     virtual void get_whitelist(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist) {
00323         /*TODO: fill whitelist*/
00324         cb(whitelist);
00325     }
00326 
00327     virtual void generate_whitelist_from_bond_table(WhitelistDbCb_t cb, ::Gap::Whitelist_t *whitelist) {
00328         for (size_t i = 0; i < MAX_ENTRIES && i < whitelist->capacity; i++) {
00329             if (_entries[i].flags.peer_address_is_public) {
00330                 whitelist->addresses[i].type = BLEProtocol::AddressType::PUBLIC;
00331             } else {
00332                 whitelist->addresses[i].type = BLEProtocol::AddressType::RANDOM_STATIC;
00333             }
00334 
00335             memcpy(
00336                 whitelist->addresses[i].address,
00337                 _entries[i].peer_identity.identity_address.data(),
00338                 sizeof(BLEProtocol::AddressBytes_t)
00339             );
00340         }
00341 
00342         cb(whitelist);
00343     }
00344 
00345     virtual void set_whitelist(const ::Gap::Whitelist_t &whitelist) { };
00346 
00347     virtual void add_whitelist_entry(const address_t &address) { }
00348 
00349     virtual void remove_whitelist_entry(const address_t &address) { }
00350 
00351     virtual void clear_whitelist() { }
00352 
00353     /* saving and loading from nvm */
00354 
00355     virtual void restore() { }
00356 
00357     virtual void sync() { }
00358 
00359     virtual void set_restore(bool reload) { }
00360 
00361 private:
00362     entry_t _entries[MAX_ENTRIES];
00363     SecurityEntryIdentity_t _local_identity;
00364     csrk_t _local_csrk;
00365     public_key_coord_t _public_key_x;
00366     public_key_coord_t _public_key_y;
00367 };
00368 
00369 } /* namespace pal */
00370 } /* namespace ble */
00371 
00372 #endif /*PAL_MEMORY_SECURITY_DB_H_*/