<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SECURITY_MANAGER_H_
#define SECURITY_MANAGER_H_

#include <stdint.h>

#include "ble/common/StaticInterface.h"
#include "ble/blecommon.h"
#include "ble/BLETypes.h"
#include "ble/Gap.h"
#include "CallChainOfFunctionPointersWithContext.h"
#include "BleImplementationForward.h"

#if !defined(DOXYGEN_ONLY)
namespace ble {
namespace interface {
#endif

/**
 * Overview
 *
 * Security Manager is used to provide link security through encryption, signing and authentication
 * which are made possible by pairing and optionally bonding. Pairing is the process of establishing
 * and/or exchanging keys used for the current connection. Bonding means saving this information so that
 * it can later be used after reconnecting without having to pair again. This saves time and power.
 *
 * @par Paring
 *
 * There are several ways to provide different levels of security during pairing depending on your requirements
 * and the facilities provided by the application. The process starts with initialising the SecurityManager
 * with default options for new connections. Some settings can later be changed per link or globally.
 *
 * The important settings in the init() function are the MITM requirement and IO capabilities. Man in the
 * Middle (MITM) protection prevents an attack where one device can impersonate another device by
 * pairing with both devices at the same time. This protection is achieved by sharing some information
 * between the devices through some independent channel. The IO capabilities of both devices dictate
 * what algorithm is used. For details @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 2.3.5.1.
 * You can change the IO capabilities after initialisation with setIoCapability(). This will take effect
 * for all subsequent pairings.
 *
 * @par Out of Band data used in pairing
 *
 * Sharing this information through IO capabilities means user interaction which limits the degree of
 * protection due to the limit of the amount of data that we can expect the user to transfer. Another
 * solution is using OOB (out of band) communication to transfer this data instead which can send much
 * more data making MITM attack even less likely to succeed. OOB data has to be exchanged by the application
 * and provided to the Security Manager. Use setOOBDataUsage() to indicate you want to use it. The same call also
 * allows you to set whether or not the communication channel you are using to transmit the OOB data is
 * itself secure against MITM protection - this will set the level of the link security achieved using pairing
 * that uses this data.
 *
 * The most secure pairing is provided by Secure Connections which relies on Elliptical Curve Cryptography.
 * Support for Secure Connections is dependent on both the stack and controller on both sides supporting
 * it. If either side doesn't support it Legacy Pairing will be used. This is an older standard of pairing.
 * If higher security is required legacy pairing can be disabled by calling allowLegacyPairing(false);
 *
 * @par Signing
 *
 * Applications may require a level of security providing confidence that data transfers are coming
 * from a trusted source. This can be achieved by encrypting the link which also provides added confidentiality.
 * Encryption is a good choice when a device stays connected but introduces latency due to the need of encrypting the
 * link if the device only connects periodically to transfer data. If confidentiality is not required data GATT
 * server may allow writes to happen over an unencrypted link but authenticated by a signature present in each packet.
 * This signature relies on having sent a signing key to the peer during pairing prior to sending any signed packets.
 *
 * @par Persistence of Security information
 *
 * Security Manager stores all the data required for its operation on active links. Depending on resources
 * available on the device it will also attempt to store data for disconnected devices which have bonded to be
 * reused when reconnected.
 *
 * If the application has initialised a filesystem and the Security Manager has been provided with a
 * filepath during the init() call it may also provide data persistence across resets. This must be enabled by
 * calling preserveBondingStateOnReset(). Persistence is not guaranteed and may fail if abnormally terminated.
 * The Security Manager may also fall back to a non-persistent implementation if the resources are too limited.
 *
 * @par How to use
 *
 * First thing you need to do is to initialise the manager by calling init() with your chosen settings.
 *
 * The SecurityManager communicates with your application through events. These will trigger calls in
 * the EventHandler which you must provide by calling the setSecurityManagerEventHandler() function.
 *
 * The most important process is pairing. This may be triggered manually by calling requestPairing() or
 * may be called as a result of the application requiring encryption by calling setLinkEncryption() or
 * as a result of the application requiring MITM protection through requestAuthentication().
 *
 * All these can be implicitly called by using setLinkSecurity() to conveniently set the required
 * security for the link. The SecurityManager will trigger all the process required to achieve the set
 * security level. Security level can only be escalated. Asking the Security Manager for a lower
 * security level than the existing one will not fail but will result in a event informing the
 * application through linkEncryptionResult() of the current level (which remains unchanged).
 *
 * Depending on the IO capabilities and OOB usage settings different pairing algorithms will be chosen.
 * They will produce appropriate events which must be handled by your EventHandler. If your event handler
 * doesn't support all the calls you must not set IO capabilities or set OOB usage in such a way that would
 * trigger them or else the pairing will fail (usually by timing out).
 *
 * The simplest example is a pairing of a device with no IO capabilities and no OOB data available.
 * With such limited pairing capabilities the "just works" method will be employed. This does not provide
 * any MITM protection. The pairing (triggered implicitly or called explicitly) will result in an event
 * being generated on the peer calling pairingRequest(). The event handler must make a decision (either in
 * the application itself or based on user interaction) whether to accept the pairing and call
 * accetPairing() or cancelPairing(). The result will be communicated on both peers through an event calling
 * pairingResult() in the EventHandler.
 *
 * @par Sequence diagrams
 *
 * Sequence diagram "Just Works" pairing
 *
 * \verbatim
 *  /----------- Device 1 --------------\  *------ BLE link ------*  /-------------- Device 2 -------------\
 *
 * App  EventHandler              SecurityManager              SecurityManager           EventHandler     App
 *  |        |                          |                            |                        |            |
 *  |---------------------------> requestPairing()                   |                        |            |
 *  |        |                          |------[pairing start]------>|                        |            |
 *  |        |                          |                            |----------------> pairingRequest() ->|
 *  |        |                          |                        acceptPairing() <------------------------ |
 *  |        |                          |<---[pairing complete]----->|                        |            |
 *  |<- pairingResult() <---------------|                            |----------------> pairingResult() -->|
 *  |        |                          |                            |                        |            |
 * @endverbatim
 * 
 *  @note the requestPairing() call isn't required to trigger pairing. Pairing will also be triggered
 *  if you request encryption and authentication and no bonding information is available. The sequence will
 *  be the same save for the lack of explicit requestPairing() call.
 *
 *
 *  Sequence diagram Encryption request when bonding information is available
 *
 * \verbatim
 *  /----------- Device 1 --------------\  *------ BLE link ------*  /-------------- Device 2 -------------\
 *
 * App  EventHandler              SecurityManager              SecurityManager           EventHandler     App
 *  |       |                           |                            |                        |            |
 *  |---------------------------> setLinkEncryption()                |                        |            |
 *  |       |                           |<-[encryption established]->|                        |            |
 *  |<- linkEncryptionResult() <--------|                            |---------> linkEncryptionResult() -->|
 *  |       |                           |                            |                        |            |
 * @endverbatim
 * 
 * @note if bonding information is not available, pairing will be triggered
 *
 *
 * Sequence diagram for Secure Connections passkey entry pairing with one device having a display only
 * and other a keyboard
 *
 * \verbatim
 *  /----------- Device 1 (keyboard) ---\  *------ BLE link ------*  /-------------- Device 2 (display) ---\
 *
 * App  EventHandler              SecurityManager              SecurityManager           EventHandler     App
 *  |        |                          |                            |                        |            |
 *  |---------------------------> requestPairing()                   |                        |            |
 *  |        |                          |------[pairing start]------>|                        |            |
 *  |        |                          |                            |----------------> pairingRequest() ->|
 *  |        |                          |                        acceptPairing() <------------------------ |
 *  |        |                          |<---[secure con. pairing]-->|                        |            |
 *  |<- passkeyRequest() <--------------|                            |----------------> passkeyDisplay() ->|
 *  |        |                          |                            |                        |            |
 *
 *                       user reads the passkey on Device 2 and inputs it on Device 1
 *
 *  |        |                          |                            |                        |            |
 *  |-------------------------->passkeyEntered()                     |                        |            |
 *  |        |                          |<---[pairing complete]----->|                        |            |
 *  |<- pairingResult() <---------------|                            |----------------> pairingResult() -->|
 *  |        |                          |                            |                        |            |
 * @endverbatim
 * 
 */
#if !defined(DOXYGEN_ONLY)
template <class Impl>
class SecurityManager : public StaticInterface<Impl, SecurityManager> {
#else
class SecurityManager {
#endif

    using StaticInterface<Impl, ::ble::interface::SecurityManager>::impl;

public:
    /** events sent and received when passkey is being entered */
    enum Keypress_t {
        KEYPRESS_STARTED,   /**< Passkey entry started */
        KEYPRESS_ENTERED,   /**< Passkey digit entered */
        KEYPRESS_ERASED,    /**< Passkey digit erased */
        KEYPRESS_CLEARED,   /**< Passkey cleared */
        KEYPRESS_COMPLETED, /**< Passkey entry completed */
    };
<commit_msg>Adjusted SecurityManager Doxygen ASCII art to make it display correctly on mbed.com<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SECURITY_MANAGER_H_
#define SECURITY_MANAGER_H_

#include <stdint.h>

#include "ble/common/StaticInterface.h"
#include "ble/blecommon.h"
#include "ble/BLETypes.h"
#include "ble/Gap.h"
#include "CallChainOfFunctionPointersWithContext.h"
#include "BleImplementationForward.h"

#if !defined(DOXYGEN_ONLY)
namespace ble {
namespace interface {
#endif

/**
 * Overview
 *
 * Security Manager is used to provide link security through encryption, signing and authentication
 * which are made possible by pairing and optionally bonding. Pairing is the process of establishing
 * and/or exchanging keys used for the current connection. Bonding means saving this information so that
 * it can later be used after reconnecting without having to pair again. This saves time and power.
 *
 * @par Paring
 *
 * There are several ways to provide different levels of security during pairing depending on your requirements
 * and the facilities provided by the application. The process starts with initialising the SecurityManager
 * with default options for new connections. Some settings can later be changed per link or globally.
 *
 * The important settings in the init() function are the MITM requirement and IO capabilities. Man in the
 * Middle (MITM) protection prevents an attack where one device can impersonate another device by
 * pairing with both devices at the same time. This protection is achieved by sharing some information
 * between the devices through some independent channel. The IO capabilities of both devices dictate
 * what algorithm is used. For details @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 2.3.5.1.
 * You can change the IO capabilities after initialisation with setIoCapability(). This will take effect
 * for all subsequent pairings.
 *
 * @par Out of Band data used in pairing
 *
 * Sharing this information through IO capabilities means user interaction which limits the degree of
 * protection due to the limit of the amount of data that we can expect the user to transfer. Another
 * solution is using OOB (out of band) communication to transfer this data instead which can send much
 * more data making MITM attack even less likely to succeed. OOB data has to be exchanged by the application
 * and provided to the Security Manager. Use setOOBDataUsage() to indicate you want to use it. The same call also
 * allows you to set whether or not the communication channel you are using to transmit the OOB data is
 * itself secure against MITM protection - this will set the level of the link security achieved using pairing
 * that uses this data.
 *
 * The most secure pairing is provided by Secure Connections which relies on Elliptical Curve Cryptography.
 * Support for Secure Connections is dependent on both the stack and controller on both sides supporting
 * it. If either side doesn't support it Legacy Pairing will be used. This is an older standard of pairing.
 * If higher security is required legacy pairing can be disabled by calling allowLegacyPairing(false);
 *
 * @par Signing
 *
 * Applications may require a level of security providing confidence that data transfers are coming
 * from a trusted source. This can be achieved by encrypting the link which also provides added confidentiality.
 * Encryption is a good choice when a device stays connected but introduces latency due to the need of encrypting the
 * link if the device only connects periodically to transfer data. If confidentiality is not required data GATT
 * server may allow writes to happen over an unencrypted link but authenticated by a signature present in each packet.
 * This signature relies on having sent a signing key to the peer during pairing prior to sending any signed packets.
 *
 * @par Persistence of Security information
 *
 * Security Manager stores all the data required for its operation on active links. Depending on resources
 * available on the device it will also attempt to store data for disconnected devices which have bonded to be
 * reused when reconnected.
 *
 * If the application has initialised a filesystem and the Security Manager has been provided with a
 * filepath during the init() call it may also provide data persistence across resets. This must be enabled by
 * calling preserveBondingStateOnReset(). Persistence is not guaranteed and may fail if abnormally terminated.
 * The Security Manager may also fall back to a non-persistent implementation if the resources are too limited.
 *
 * @par How to use
 *
 * First thing you need to do is to initialise the manager by calling init() with your chosen settings.
 *
 * The SecurityManager communicates with your application through events. These will trigger calls in
 * the EventHandler which you must provide by calling the setSecurityManagerEventHandler() function.
 *
 * The most important process is pairing. This may be triggered manually by calling requestPairing() or
 * may be called as a result of the application requiring encryption by calling setLinkEncryption() or
 * as a result of the application requiring MITM protection through requestAuthentication().
 *
 * All these can be implicitly called by using setLinkSecurity() to conveniently set the required
 * security for the link. The SecurityManager will trigger all the process required to achieve the set
 * security level. Security level can only be escalated. Asking the Security Manager for a lower
 * security level than the existing one will not fail but will result in a event informing the
 * application through linkEncryptionResult() of the current level (which remains unchanged).
 *
 * Depending on the IO capabilities and OOB usage settings different pairing algorithms will be chosen.
 * They will produce appropriate events which must be handled by your EventHandler. If your event handler
 * doesn't support all the calls you must not set IO capabilities or set OOB usage in such a way that would
 * trigger them or else the pairing will fail (usually by timing out).
 *
 * The simplest example is a pairing of a device with no IO capabilities and no OOB data available.
 * With such limited pairing capabilities the "just works" method will be employed. This does not provide
 * any MITM protection. The pairing (triggered implicitly or called explicitly) will result in an event
 * being generated on the peer calling pairingRequest(). The event handler must make a decision (either in
 * the application itself or based on user interaction) whether to accept the pairing and call
 * accetPairing() or cancelPairing(). The result will be communicated on both peers through an event calling
 * pairingResult() in the EventHandler.
 *
 * @par Sequence diagrams
 *
 * Sequence diagram "Just Works" pairing
 *
 * \verbatim
 *  /-------- Device 1 ---------\  *----- BLE link -----*  /----------- Device 2-----------\
 *
 * App  EventHandler      SecurityManager            SecurityManager    EventHandler      App
 *  |        |                  |                          |                 |             |
 *  |-------------------> requestPairing()                 |                 |             |
 *  |        |                  |-----[pairing start]----->|                 |             |
 *  |        |                  |                          |---------> pairingRequest() -->|
 *  |        |                  |                   acceptPairing() <--------------------- |
 *  |        |                  |<--[pairing complete]---->|                 |             |
 *  |<- pairingResult() <-------|                          |---------> pairingResult() --->|
 *  |        |                  |                          |                 |             |
 * @endverbatim
 *
 *  @note the requestPairing() call isn't required to trigger pairing. Pairing will also be triggered
 *  if you request encryption and authentication and no bonding information is available. The sequence will
 *  be the same save for the lack of explicit requestPairing() call.
 *
 *
 *  Sequence diagram Encryption request when bonding information is available
 *
 * \verbatim
 *  /--------- Device 1 ---------\  *------ BLE link ------*  /--------- Device 2 ---------\
 *
 * App  EventHandler       SecurityManager              SecurityManager   EventHandler    App
 *  |       |                    |                            |                |           |
 *  |--------------------> setLinkEncryption()                |                |           |
 *  |       |                    |<-[encryption established]->|                |           |
 *  |<- linkEncryptionResult() <-|                            |-> linkEncryptionResult() ->|
 *  |       |                    |                            |                |           |
 * @endverbatim
 *
 * @note if bonding information is not available, pairing will be triggered
 *
 *
 * Sequence diagram for Secure Connections passkey entry pairing with one device having a display only
 * and other a keyboard
 *
 * \verbatim
 *  /---- Device 1 (keyboard) ---\  *------ BLE link ------*  /----- Device 2 (display) ---\
 *
 * App  EventHandler       SecurityManager              SecurityManager  EventHandler     App
 *  |       |                    |                            |               |            |
 *  |--------------------> requestPairing()                   |               |            |
 *  |        |                   |------[pairing start]------>|               |            |
 *  |        |                   |                            |-------> pairingRequest() ->|
 *  |        |                   |                        acceptPairing() <--------------- |
 *  |        |                   |<---[secure con. pairing]-->|               |            |
 *  |<- passkeyRequest() <-------|                            |-------> passkeyDisplay() ->|
 *  |        |                   |                            |               |            |
 *
 *                  user reads the passkey on Device 2 and inputs it on Device 1
 *
 *  |        |                   |                            |               |            |
 *  |------------------->passkeyEntered()                     |               |            |
 *  |        |                   |<---[pairing complete]----->|               |            |
 *  |<- pairingResult() <--------|                            |-------> pairingResult() -->|
 *  |        |                   |                            |               |            |
 * @endverbatim
 *
 */
#if !defined(DOXYGEN_ONLY)
template <class Impl>
class SecurityManager : public StaticInterface<Impl, SecurityManager> {
#else
class SecurityManager {
#endif

    using StaticInterface<Impl, ::ble::interface::SecurityManager>::impl;

public:
    /** events sent and received when passkey is being entered */
    enum Keypress_t {
        KEYPRESS_STARTED,   /**< Passkey entry started */
        KEYPRESS_ENTERED,   /**< Passkey digit entered */
        KEYPRESS_ERASED,    /**< Passkey digit erased */
        KEYPRESS_CLEARED,   /**< Passkey cleared */
        KEYPRESS_COMPLETED, /**< Passkey entry completed */
    };

{'fraction_non_alphanumeric': 0.09419868868785791, 'fraction_numerical': 0.002240849863059175, 'mean_word_length': 1.932822197882439, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 108, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '357882', 'n_tokens_mistral': 5535, 'n_tokens_neox': 5203, 'n_words': 2557}