mbed-os/features/FEATURE_BLE/ble/pal/PalSecurityManager.h

978 lines
31 KiB
C
Raw Normal View History

2018-01-11 13:17:47 +00:00
/* mbed Microcontroller Library
* Copyright (c) 2017-2018 ARM Limited
2017-12-22 15:53:54 +00:00
*
2018-01-11 13:17:47 +00:00
* 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.
2017-12-22 15:53:54 +00:00
*/
#ifndef MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_
#define MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_
#include "platform/Callback.h"
#include "platform/NonCopyable.h"
#include "ble/BLETypes.h"
#include "ble/BLEProtocol.h"
#include "ble/SecurityManager.h"
#include "ble/pal/GapTypes.h"
2017-12-22 15:53:54 +00:00
namespace ble {
namespace pal {
typedef SecurityManager::SecurityCompletionStatus_t SecurityCompletionStatus_t;
typedef SecurityManager::SecurityMode_t SecurityMode_t;
typedef SecurityManager::LinkSecurityStatus_t LinkSecurityStatus_t;
typedef SecurityManager::Keypress_t Keypress_t;
2017-12-22 15:53:54 +00:00
typedef uint32_t passkey_num_t;
2017-12-22 15:53:54 +00:00
class PasskeyAsci {
public:
static const uint8_t NUMBER_OFFSET = '0';
2018-01-18 20:13:49 +00:00
PasskeyAsci() {
memset(asci, NUMBER_OFFSET, SecurityManager::PASSKEY_LEN);
}
PasskeyAsci(const uint8_t* passkey) {
if (passkey) {
memcpy(asci, passkey, SecurityManager::PASSKEY_LEN);
} else {
memset(asci, NUMBER_OFFSET, SecurityManager::PASSKEY_LEN);
}
}
2018-01-19 11:30:27 +00:00
PasskeyAsci(passkey_num_t passkey) {
for (int i = 5, m = 100000; i >= 0; --i, m /= 10) {
2018-01-18 20:13:49 +00:00
uint32_t result = passkey / m;
asci[i] = NUMBER_OFFSET + result;
2018-01-18 20:13:49 +00:00
passkey -= result;
}
}
2018-01-18 20:13:49 +00:00
operator passkey_num_t() {
return to_num(asci);
}
2018-01-18 20:13:49 +00:00
static uint32_t to_num(const uint8_t *asci) {
uint32_t passkey = 0;
for (size_t i = 0, m = 1; i < SecurityManager::PASSKEY_LEN; ++i, m *= 10) {
passkey += (asci[i] - NUMBER_OFFSET) * m;
}
return passkey;
}
uint8_t asci[SecurityManager::PASSKEY_LEN];
};
2018-01-30 17:27:12 +00:00
/**
* Key distribution as required by the SMP with convenient setters and getters,
* use value() to get the octet you can use directly in the PDU.
*/
2018-01-18 12:08:33 +00:00
class KeyDistribution {
public:
enum KeyDistributionFlags_t {
KEY_DISTRIBUTION_NONE = 0x00,
KEY_DISTRIBUTION_ENCRYPTION = 0x01,
KEY_DISTRIBUTION_IDENTITY = 0x02,
KEY_DISTRIBUTION_SIGNING = 0x04,
KEY_DISTRIBUTION_LINK = 0x08,
KEY_DISTRIBUTION_ALL = 0x0F
};
KeyDistribution() : _value(0) { }
KeyDistribution(uint8_t value) : _value(value) { }
KeyDistribution(bool encryption,
bool identity,
bool signing,
bool link) : _value(0) {
2018-01-18 12:08:33 +00:00
set_encryption(encryption);
set_identity(identity);
set_signing(signing);
set_link(link);
}
bool get_encryption() {
return _value & KEY_DISTRIBUTION_ENCRYPTION;
}
bool get_identity() {
return _value & KEY_DISTRIBUTION_IDENTITY;
}
bool get_signing() {
return _value & KEY_DISTRIBUTION_SIGNING;
}
bool get_link() {
return _value & KEY_DISTRIBUTION_LINK;
}
void set_encryption(bool enabled = true) {
if (enabled) {
_value |= KEY_DISTRIBUTION_ENCRYPTION;
} else {
_value &= ~KEY_DISTRIBUTION_ENCRYPTION;
}
}
void set_identity(bool enabled = true) {
if (enabled) {
_value |= KEY_DISTRIBUTION_IDENTITY;
} else {
_value &= ~KEY_DISTRIBUTION_IDENTITY;
}
}
void set_signing(bool enabled = true) {
if (enabled) {
_value |= KEY_DISTRIBUTION_SIGNING;
} else {
_value &= ~KEY_DISTRIBUTION_SIGNING;
}
}
void set_link(bool enabled = true) {
if (enabled) {
_value |= KEY_DISTRIBUTION_LINK;
} else {
_value &= ~KEY_DISTRIBUTION_LINK;
}
}
operator uint8_t() {
return _value;
}
uint8_t value() {
return _value;
}
2018-01-18 12:08:33 +00:00
private:
uint8_t _value;
2018-01-12 12:41:43 +00:00
};
2018-01-30 17:27:12 +00:00
/**
* Authentication mask as required by the SMP with convenient setters and getters,
* use value() to get the octet you can use directly in the PDU.
*/
class AuthenticationMask {
public:
enum AuthenticationFlags_t {
AUTHENTICATION_BONDABLE = 0x01,
AUTHENTICATION_MITM = 0x04, /* 0x02 missing because bonding uses two bits */
AUTHENTICATION_SECURE_CONNECTIONS = 0x08,
AUTHENTICATION_KEYPRESS_NOTIFICATION = 0x10
};
2018-01-12 12:41:43 +00:00
2018-01-18 12:08:33 +00:00
AuthenticationMask() : _value(0) { }
AuthenticationMask(uint8_t value) : _value(value) { }
AuthenticationMask(bool bondable,
bool mitm,
bool secure_connections,
bool keypress) : _value(0) {
set_bondable(bondable);
set_mitm(mitm);
set_secure_connections(secure_connections);
set_keypress_notification(keypress);
}
bool get_bondable() {
2018-01-18 12:08:33 +00:00
return _value & AUTHENTICATION_BONDABLE;
}
bool get_mitm() {
2018-01-18 12:08:33 +00:00
return _value & AUTHENTICATION_MITM;
}
bool get_secure_connections() {
2018-01-18 12:08:33 +00:00
return _value & AUTHENTICATION_SECURE_CONNECTIONS;
}
bool get_keypress_notification() {
2018-01-18 12:08:33 +00:00
return _value & AUTHENTICATION_KEYPRESS_NOTIFICATION;
}
void set_bondable(bool enabled = true) {
if (enabled) {
2018-01-18 12:08:33 +00:00
_value |= AUTHENTICATION_BONDABLE;
} else {
2018-01-18 12:08:33 +00:00
_value &= ~AUTHENTICATION_BONDABLE;
}
}
void set_mitm(bool enabled = true) {
if (enabled) {
2018-01-18 12:08:33 +00:00
_value |= AUTHENTICATION_MITM;
} else {
2018-01-18 12:08:33 +00:00
_value &= ~AUTHENTICATION_MITM;
}
}
void set_secure_connections(bool enabled = true) {
if (enabled) {
2018-01-18 12:08:33 +00:00
_value |= AUTHENTICATION_SECURE_CONNECTIONS;
} else {
2018-01-18 12:08:33 +00:00
_value &= ~AUTHENTICATION_SECURE_CONNECTIONS;
}
}
void set_keypress_notification(bool enabled = true) {
if (enabled) {
2018-01-18 12:08:33 +00:00
_value |= AUTHENTICATION_KEYPRESS_NOTIFICATION;
} else {
2018-01-18 12:08:33 +00:00
_value &= ~AUTHENTICATION_KEYPRESS_NOTIFICATION;
}
}
operator uint8_t() {
2018-01-18 12:08:33 +00:00
return _value;
}
uint8_t value() {
return _value;
}
2018-01-18 12:08:33 +00:00
private:
uint8_t _value;
2018-01-12 12:41:43 +00:00
};
/**
* Handle events generated by ble::pal::SecurityManager
*/
2018-01-11 18:45:27 +00:00
class SecurityManagerEventHandler {
public:
////////////////////////////////////////////////////////////////////////////
// Pairing
//
/**
2018-01-30 17:27:12 +00:00
* Request pairing. This is called on the slave in response to a request from the master.
* Upper layer shall either send a pairing response (send_pairing_response)
* or cancel the pairing procedure (cancel_pairing).
2018-01-30 17:27:12 +00:00
*
* @param[in] connection connection handle
* @param[in] oob_data_flag is oob data present
* @param[in] authentication_requirements authentication requirements
* @param[in] initiator_dist key distribution
* @param[in] responder_dist key distribution
*/
virtual void on_pairing_request(
connection_handle_t connection,
bool oob_data_flag,
AuthenticationMask authentication_requirements,
2018-01-18 12:08:33 +00:00
KeyDistribution initiator_dist,
KeyDistribution responder_dist
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Indicate that the pairing has failed.
*
* @note Any subsequent pairing procedure shall restart from the Pairing
* Feature Exchange phase.
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] error reason for the failed pairing
*/
virtual void on_pairing_error(
connection_handle_t connection,
pairing_failure_t error
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Indicate that the pairing has timed out.
*
* @param[in] connection connection handle
*/
2018-01-30 17:27:12 +00:00
virtual void on_pairing_timed_out(
connection_handle_t connection
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Indicate that the pairing for the link has completed.
*
* @param[in] connection connection handle
*/
2018-01-30 17:27:12 +00:00
virtual void on_pairing_completed(
connection_handle_t connection
) = 0;
////////////////////////////////////////////////////////////////////////////
// Security
//
/**
2018-01-30 17:27:12 +00:00
* Indicate that the authentication timeout time has elapsed
* and we received no packets with a valid MIC in that time.
*
* @param[in] connection connection handle
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 6, Part B, 5.4
*/
2018-01-30 17:27:12 +00:00
virtual void on_valid_mic_timeout(
connection_handle_t connection
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Ask the stack to evaluate the security request received from the slave.
* This might result in the stack enabling encryption, or pairing/re-pairing.
*
* @param[in] connection connection handle
* @param[in] authentication authentication requirements from the slave
*/
2018-01-22 11:49:42 +00:00
virtual void on_slave_security_request(
connection_handle_t connection,
AuthenticationMask authentication
) = 0;
////////////////////////////////////////////////////////////////////////////
// Encryption
//
/**
2018-01-30 17:27:12 +00:00
* Inform the application of the result of an encryption request.
* @note Do no call if request timed out, call on_link_encryption_request_timed_out
* instead.
2018-01-30 17:27:12 +00:00
*
* @param[in] connection connection handle
* @param[in] result encryption state of the link
*/
virtual void on_link_encryption_result(
connection_handle_t connection,
link_encryption_t result
) = 0;
2018-01-11 18:45:27 +00:00
/**
2018-01-30 20:00:21 +00:00
* Indicate that the encryption request failed due to timeout.
*
* @param[in] connection connection handle
*/
2018-01-30 20:00:21 +00:00
virtual void on_link_encryption_request_timed_out(
connection_handle_t connection
) = 0;
2018-01-11 18:45:27 +00:00
////////////////////////////////////////////////////////////////////////////
// MITM
//
/**
2018-01-30 17:27:12 +00:00
* Inform the application that should display a passkey.
*
* @param[in] connection connection handle
* @param[in] passkey passkey to be displayed
*/
virtual void on_passkey_display(
connection_handle_t connection,
const passkey_num_t passkey
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Indicate that user confirmation is required to confirm matching
* passkeys displayed on devices.
*
* @param[in] connection connection handle
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E, 7.7.42
*/
2018-01-30 17:27:12 +00:00
virtual void on_confirmation_request(
connection_handle_t connection
) = 0;
/**
* Request the passkey entered during pairing.
*
* @note shall be followed by: pal::SecurityManager::passkey_request_reply
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* or a cancellation of the procedure.
*/
2018-01-30 17:27:12 +00:00
virtual void on_passkey_request(
connection_handle_t connection
) = 0;
2018-01-11 18:45:27 +00:00
/**
2018-01-30 17:27:12 +00:00
* Indicate that a key has been pressed by the peer.
*
* @param[in] connection connection handle
* @param[in] keypress type of keypress event
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H, 3.5.8
*/
2018-01-30 17:27:12 +00:00
virtual void on_keypress_notification(
connection_handle_t connection,
SecurityManager::Keypress_t keypress
) = 0;
2018-01-11 18:45:27 +00:00
/**
2018-01-30 17:27:12 +00:00
* Request OOB data from the user application.
*
* @param[in] connection connection handle
*/
2018-01-30 17:27:12 +00:00
virtual void on_legacy_pairing_oob_request(
connection_handle_t connection
) = 0;
2018-01-11 18:45:27 +00:00
/**
2018-01-30 17:27:12 +00:00
* Request oob data entered during pairing.
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @note shall be followed by: pal::SecurityManager::oob_data_request_reply
* or a cancellation of the procedure.
*/
2018-01-30 17:27:12 +00:00
virtual void on_oob_request(
connection_handle_t connection
) = 0;
////////////////////////////////////////////////////////////////////////////
// Keys
//
2018-01-11 18:45:27 +00:00
2018-01-30 17:27:12 +00:00
/**
* Store the results of key distribution after all the keys have been received.
*
* @param[in] connection connection handle
* @param[in] peer_address_type public or private address indication from the SMP
* @param[in] peer_address identity address from the peer
* @param[in] ediv encryption diversifier from the peer
* @param[in] rand random value from the peer
* @param[in] ltk long term key from the peer
* @param[in] irk identity resolution key
* @param[in] csrk signing key
*/
virtual void on_keys_distributed(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
advertising_peer_address_type_t peer_address_type,
2018-01-19 10:38:27 +00:00
const address_t &peer_address,
2018-01-24 10:22:53 +00:00
const ediv_t *ediv,
const rand_t *rand,
const ltk_t *ltk,
const irk_t *irk,
const csrk_t *csrk
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Store the results of key distribution after LTK has been received.
*
* @param[in] connection connection handle
* @param[in] ltk long term key from the peer
*/
virtual void on_keys_distributed_ltk(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ltk_t *ltk
) = 0;
2018-01-11 18:45:27 +00:00
2018-01-30 17:27:12 +00:00
/**
* Store the results of key distribution after EDIV and RAND has been received.
*
* @param[in] connection connection handle
* @param[in] ltk long term key from the peer
*/
virtual void on_keys_distributed_ediv_rand(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ediv_t *ediv,
const rand_t *rand
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Store the local key, if we are slave now or in the future
* this will be used to encrypt.
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] ltk key sent to the peer
*/
virtual void on_keys_distributed_local_ltk(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ltk_t *ltk
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Store the EDIV and RAND that will be used to identify
* the stored local LTK. if we are slave that LTK will be
* used to encrypt, otherwise this will be stored to
2018-01-30 17:27:12 +00:00
* be used in case of role reversal.
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] ediv idenitfies LTK
* @param[in] rand idenitfies LTK
*/
virtual void on_keys_distributed_local_ediv_rand(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ediv_t *ediv,
const rand_t *rand
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Store the results of key distribution after IRK has been received.
*
* @param[in] connection connection handle
* @param[in] irk identity resolution key
*/
virtual void on_keys_distributed_irk(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const irk_t *irk
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Store the identity address of the peer after it has been distributed.
*
* @param[in] connection connection handle
* @param[in] peer_identity_address_type public or private address indication
* @param[in] peer_identity_address peer address
*/
virtual void on_keys_distributed_bdaddr(
connection_handle_t connection,
advertising_peer_address_type_t peer_identity_address_type,
2018-01-19 10:38:27 +00:00
const address_t &peer_identity_address
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Store the peer's CSRK after it has been distributed.
*
* @param[in] connection connection handle
* @param[in] csrk signing key
*/
virtual void on_keys_distributed_csrk(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const csrk_t *csrk
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Request the LTK since the peer is asking us to encrypt the link. We need to
* provide the LTK based on the EDIV and RAND provided by the other side.
*
* @param[in] connection connection handle
2018-01-30 20:00:21 +00:00
* @param[in] ediv identifies LTK
* @param[in] rand identifies LTK
*/
virtual void on_ltk_request(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ediv_t *ediv,
const rand_t *rand
) = 0;
};
/**
* Adaptation layer of the Security Manager.
*/
2018-01-03 18:04:22 +00:00
class SecurityManager : private mbed::NonCopyable<SecurityManager> {
2017-12-22 15:53:54 +00:00
public:
SecurityManager() : _pal_event_handler(NULL) { };
virtual ~SecurityManager() { };
2017-12-22 15:53:54 +00:00
////////////////////////////////////////////////////////////////////////////
// SM lifecycle management
//
2018-01-30 17:27:12 +00:00
/**
* Initialise stack. Called before first use.
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t initialize() = 0;
2018-01-30 17:27:12 +00:00
/**
* Finalise all actions. Called before shutdown.
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t terminate() = 0;
2018-01-30 17:27:12 +00:00
/**
* Reset to same state as after initialize.
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t reset() = 0;
2017-12-22 15:53:54 +00:00
////////////////////////////////////////////////////////////////////////////
// Resolving list management
//
/**
* Return the number of address translation entries that can be stored by the
* subsystem.
*
* @warning: The number of entries is considered fixed.
*
2018-01-30 17:27:12 +00:00
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.41
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual uint8_t read_resolving_list_capacity() = 0;
/**
* Add a device definition into the resolving list of the LE subsystem.
*
2018-01-30 17:27:12 +00:00
* @param[in] peer_identity_address_type public/private indicator
* @param[in] peer_identity_address address of the device whose entry is to be added
2018-01-30 20:00:21 +00:00
* @param[in] peer_irk peer identity resolving key
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.38
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t add_device_to_resolving_list(
advertising_peer_address_type_t peer_identity_address_type,
address_t peer_identity_address,
2018-01-30 17:27:12 +00:00
const irk_t peer_irk
) = 0;
/**
* Add a device definition from the resolving list of the LE subsystem.
*
2018-01-30 17:27:12 +00:00
* @param[in] peer_identity_address_type public/private indicator
* @param[in] peer_identity_address address of the device whose entry is to be removed
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.39
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t remove_device_from_resolving_list(
advertising_peer_address_type_t peer_identity_address_type,
2018-01-19 10:38:27 +00:00
const address_t &peer_identity_address
) = 0;
/**
* Remove all devices from the resolving list.
*
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.40
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t clear_resolving_list() = 0;
////////////////////////////////////////////////////////////////////////////
// Feature support
//
2017-12-22 15:53:54 +00:00
2018-01-30 20:00:21 +00:00
/**
* Check if the Secure Connections feature is supported by the stack and controller.
*
* @param[out] enabled true if SC are supported
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t get_secure_connections_support(
bool &enabled
) = 0;
2017-12-22 15:53:54 +00:00
/**
2018-01-30 17:27:12 +00:00
* Set the IO capability that will be used during pairing feature exchange.
2018-01-30 20:00:21 +00:00
*
2018-01-30 17:27:12 +00:00
* @param[in] io_capability type of IO capabilities available on the local device
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-30 17:27:12 +00:00
virtual ble_error_t set_io_capability(
io_capability_t io_capability
) = 0;
////////////////////////////////////////////////////////////////////////////
// Security settings
//
2018-01-30 17:27:12 +00:00
/**
* Set the time after which an event will be generated unless we received a packet with
* a valid MIC.
* @param[in] connection connection handle
* @param[in] timeout_in_10ms time measured in units of 10 milliseconds
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t set_authentication_timeout(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
2018-01-19 10:38:27 +00:00
uint16_t timeout_in_10ms
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Set the time after which an event will be generated unless we received a packet with
* a valid MIC.
* @param[in] connection connection handle
* @param[out] timeout_in_10ms time measured in units of 10 milliseconds
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t get_authentication_timeout(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
2018-01-19 10:38:27 +00:00
uint16_t &timeout_in_10ms
) = 0;
/**
* Set the key size boundaries that will be used during pairing feature
* exchange.
*
* @param[in] min_encryption_key_size The minimum encryption key size in bytes
* required for pairing. This value shall be in the range [7 : 16].
*
* @param[in] max_encryption_key_size The maximum encryption key size in bytes
* required for pairing. This value shall be in the range
* [min_encryption_key_size : 16].
2018-01-30 17:27:12 +00:00
*
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t set_encryption_key_requirements(
uint8_t min_encryption_key_size,
uint8_t max_encryption_key_size
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Request change of security level from the master. This is called by the slave when
* it needs to elevate the security level as it can't change it itself. This will be
* received by the master who will take the decision about what action to take
* (encryption, pairing, re-paring).
*
* @param[in] connection connection handle
* @param[in] authentication authentication requirements
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-22 11:49:42 +00:00
virtual ble_error_t slave_security_request(
connection_handle_t connection,
AuthenticationMask authentication
) = 0;
////////////////////////////////////////////////////////////////////////////
// Encryption
//
2018-01-12 15:32:11 +00:00
2018-01-30 17:27:12 +00:00
/**
* Enabled encryption using the LTK given. The EDIV and RAND will be sent to the peer and
* used to identify the LTK. This is called by the master.
* @param[in] connection connection handle
* @param[in] ltk long term key from the peer
* @param[in] ediv encryption diversifier from the peer
* @param[in] rand random value from the peer
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-21 22:57:05 +00:00
virtual ble_error_t enable_encryption(
connection_handle_t connection,
2018-01-24 10:22:53 +00:00
const ltk_t *ltk,
const rand_t *rand = NULL,
const ediv_t *ediv = NULL
2018-01-21 22:57:05 +00:00
) = 0;
2018-01-12 15:32:11 +00:00
virtual ble_error_t disable_encryption(connection_handle_t connection) = 0;
2018-01-12 15:32:11 +00:00
2018-01-30 17:27:12 +00:00
/**
* Get the link's key size.
*
* @param[in] connection connection handle
2018-01-30 20:00:21 +00:00
* @param[out] bytesize size of the encryption key in bytes
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t get_encryption_key_size(
2018-01-19 10:38:27 +00:00
connection_handle_t connection,
2018-01-30 17:27:12 +00:00
uint8_t &bytesize
) = 0;
2018-01-12 15:32:11 +00:00
2018-01-30 17:27:12 +00:00
/**
* Encrypt data with a given key. This uses the facility on the controller to
* perform the encryption.
*
* @param[in] key encryption key
* @param[in,out] data data to be encrypted
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t encrypt_data(
const key_t *key,
uint8_t *data
) = 0;
////////////////////////////////////////////////////////////////////////////
// Privacy
//
2017-12-22 15:53:54 +00:00
virtual ble_error_t set_private_address_timeout(uint16_t timeout_in_seconds) = 0;
////////////////////////////////////////////////////////////////////////////
// Keys
//
2018-01-30 17:27:12 +00:00
/**
* Set the LTK that is to be used for encryption.
2018-01-30 20:00:21 +00:00
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] ltk long term key
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t set_ltk(
connection_handle_t connection,
const ltk_t *ltk
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Set the local IRK.
2018-01-30 20:00:21 +00:00
*
2018-01-30 17:27:12 +00:00
* @param[in] irk identity resolutino key
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-30 17:27:12 +00:00
virtual ble_error_t set_irk(
const irk_t *irk
) = 0;
/**
2018-01-30 17:27:12 +00:00
* Set the local CSRK.
2018-01-30 20:00:21 +00:00
*
2018-01-30 17:27:12 +00:00
* @param[in] csrk signing key
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-30 17:27:12 +00:00
virtual ble_error_t set_csrk(
const csrk_t *csrk
) = 0;
////////////////////////////////////////////////////////////////////////////
// Authentication
//
2018-01-11 18:27:45 +00:00
/**
* Send a pairing request to a slave.
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] oob_data_flag is oob data present
* @param[in] authentication_requirements authentication requirements
* @param[in] initiator_dist key distribution
* @param[in] responder_dist key distribution
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.1
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t send_pairing_request(
connection_handle_t connection,
bool oob_data_flag,
AuthenticationMask authentication_requirements,
2018-01-18 12:08:33 +00:00
KeyDistribution initiator_dist,
KeyDistribution responder_dist
);
2018-01-12 12:41:43 +00:00
/**
* Send a pairing response to a master.
*
2018-01-30 17:27:12 +00:00
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.2*
* @param[in] connection connection handle
* @param[in] oob_data_flag is oob data present
* @param[in] authentication_requirements authentication requirements
* @param[in] initiator_dist key distribution
* @param[in] responder_dist key distribution
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t send_pairing_response(
connection_handle_t connection,
bool oob_data_flag,
AuthenticationMask authentication_requirements,
2018-01-18 12:08:33 +00:00
KeyDistribution initiator_dist,
KeyDistribution responder_dist
) = 0;
2018-01-07 22:22:55 +00:00
/**
2018-01-30 17:27:12 +00:00
* Cancel an ongoing pairing.
*
2018-01-30 17:27:12 +00:00
* @param[in] connection connection handle
* @param[in] reason pairing failure error
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.5
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t cancel_pairing(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
pairing_failure_t reason
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Request authentication of the connection. This will trigger an appropriate reaction,
* which might include encryption or pairing/re-pairing.
*
* @param[in] connection connection handle
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t request_authentication(
connection_handle_t connection
) = 0;
2018-01-07 22:22:55 +00:00
2018-01-16 11:50:49 +00:00
/**
* Generate and return 8 octets of random data compliant with [FIPS PUB 140-2]
*
* @param[out] random_data returns 8 octets of random data
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part H 2
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
2018-01-16 11:50:49 +00:00
*/
2018-01-30 17:27:12 +00:00
virtual ble_error_t get_random_data(
random_data_t &random_data
) = 0;
2018-01-16 11:50:49 +00:00
////////////////////////////////////////////////////////////////////////////
// MITM
//
2017-12-22 15:53:54 +00:00
/**
* Set the default passkey that will be used when the SM needs a passkey to
* be displayed.
*
* By default, the pal security manager generates a random passkey when a
* passkey has to be displayed by the application. A call to this function
* with a valid passkey alter this behaviour and the SecurityManager shall
* pass the passkey set into SecurityManagerEvent::on_passkey_display .
*
* A call to this function with a null pointer will reset the behaviour and
* indicates to the security manager that passkeys passed to
* SecurityManagerEvent::on_passkey_display shall be randomly generated.
*
* @param[in] passkey Set the passkey that shall be used by the security
* manager when SecurityManagerEvent::on_passkey_display is called. If
* passkey is a null pointer then the security manager generates a random
* passkey everytime it calls SecurityManagerEvent::on_passkey_display.
*
2018-01-30 17:27:12 +00:00
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
2018-01-30 17:27:12 +00:00
virtual ble_error_t set_display_passkey(
const passkey_num_t passkey
) = 0;
/**
* Reply to a passkey request received from the SecurityManagerEventHandler.
2018-01-30 17:27:12 +00:00
*
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t passkey_request_reply(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
const passkey_num_t passkey
) = 0;
/**
* Reply to an oob data request received from the SecurityManagerEventHandler.
2018-01-30 17:27:12 +00:00
*
* @param[in] connection connection handle
* @param[in] oob_data pointer to out of band data
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t oob_data_request_reply(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
const oob_data_t *oob_data
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Notify the stack that the user has confirmed the values during numerical
* comparison stage of pairing.
*
* @param[in] connection connection handle
* @param[in] confirmation true if the user indicated the numbers match
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t confirmation_entered(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
bool confirmation
) = 0;
2018-01-30 17:27:12 +00:00
/**
* Notify the stack that the user pressed a key. This will be sent to the peer and create
* an appropriate event there if the keypress protocol is enabled.
* @param[in] connection connection handle
* @param[in] keypress type of keypress event
* @return
*/
virtual ble_error_t send_keypress_notification(
2018-01-30 17:27:12 +00:00
connection_handle_t connection,
Keypress_t keypress
) = 0;
2017-12-22 15:53:54 +00:00
/* Entry points for the underlying stack to report events back to the user. */
public:
2018-01-30 17:27:12 +00:00
/**
* Sets the event handler that us called by the PAL porters to notify the stack of events
* which will in turn be passed onto the user application when appropriate.
*
* @param[in] event_handler the new event handler interface implementation
*/
void set_event_handler(
SecurityManagerEventHandler *event_handler
) {
2018-01-12 12:41:43 +00:00
_pal_event_handler = event_handler;
2017-12-22 15:53:54 +00:00
}
protected:
SecurityManagerEventHandler* get_event_handler() {
return _pal_event_handler;
}
2017-12-22 15:53:54 +00:00
private:
SecurityManagerEventHandler *_pal_event_handler;
2017-12-22 15:53:54 +00:00
};
} /* namespace pal */
} /* namespace ble */
2017-12-22 15:53:54 +00:00
#endif /* MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_ */