gatt server pass

mostly phy and security issues
pull/9790/head
paul-szczepanek-arm 2019-02-25 14:37:25 +00:00 committed by Vincent Coubard
parent f8c28fcbe7
commit a034bf875e
11 changed files with 104 additions and 14 deletions

View File

@ -528,6 +528,7 @@ struct att_security_requirement_t : SafeEnum<att_security_requirement_t, uint8_t
*/
NONE,
#if BLE_FEATURE_SECURITY
/**
* The operation requires security and there's no requirement towards
* peer authentication.
@ -553,6 +554,7 @@ struct att_security_requirement_t : SafeEnum<att_security_requirement_t, uint8_t
*/
AUTHENTICATED,
#if BLE_FEATURE_SECURE_CONNECTIONS
/**
* The operation require encryption with an authenticated peer that
* paired using secure connection pairing.
@ -561,6 +563,8 @@ struct att_security_requirement_t : SafeEnum<att_security_requirement_t, uint8_t
* security is achieved with link encryption.
*/
SC_AUTHENTICATED
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
};
/**
@ -637,7 +641,7 @@ struct phy_t : SafeEnum<phy_t, uint8_t> {
* @note This physical transport was available since Bluetooth 4.0
*/
LE_1M = 1,
#if BLE_FEATURE_PHY_MANAGEMENT
/**
* 2Mbit/s LE.
*
@ -671,6 +675,7 @@ struct phy_t : SafeEnum<phy_t, uint8_t> {
* @note This transport has been introduced with the Bluetooth 5.
*/
LE_CODED
#endif // BLE_FEATURE_PHY_MANAGEMENT
};
/**
@ -717,8 +722,10 @@ public:
_value()
{
set_1m(phy_1m);
#if BLE_FEATURE_PHY_MANAGEMENT
set_2m(phy_2m);
set_coded(phy_coded);
#endif // BLE_FEATURE_PHY_MANAGEMENT
}
/**
@ -732,12 +739,14 @@ public:
case phy_t::LE_1M:
set_1m(true);
break;
#if BLE_FEATURE_PHY_MANAGEMENT
case phy_t::LE_2M:
set_2m(true);
break;
case phy_t::LE_CODED:
set_coded(true);
break;
#endif // BLE_FEATURE_PHY_MANAGEMENT
default:
break;
}
@ -752,6 +761,7 @@ public:
}
}
#if BLE_FEATURE_PHY_MANAGEMENT
/** Prefer 2M PHY. */
void set_2m(bool enabled = true) {
if (enabled) {
@ -769,6 +779,7 @@ public:
_value &= ~PHY_SET_CODED;
}
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
bool get_1m() const {
return (_value & PHY_SET_1M);

View File

@ -1414,6 +1414,7 @@ public:
_valueAttribute.allowWrite(isWritable(_properties));
_valueAttribute.allowRead(isReadable(_properties));
#if BLE_FEATURE_SECURITY
// signed writes requires at least an unauthenticated CSRK or an
// unauthenticated ltk if the link is encrypted.
if (_properties & BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES) {
@ -1421,6 +1422,7 @@ public:
SecurityRequirement_t::UNAUTHENTICATED
);
}
#endif // BLE_FEATURE_SECURITY
}
public:
@ -1500,11 +1502,13 @@ public:
*/
void setWriteSecurityRequirement(SecurityRequirement_t security)
{
#if BLE_FEATURE_SECURITY
MBED_ASSERT(
((_properties & BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES) &&
((security == SecurityRequirement_t::NONE) ||
(security == SecurityRequirement_t::SC_AUTHENTICATED))) == false
);
#endif // BLE_FEATURE_SECURITY
_valueAttribute.setWriteSecurityRequirement(security);
}
@ -1758,7 +1762,7 @@ public:
case SecurityRequirement_t::NONE:
MBED_ASSERT(needs_signing == false);
return SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
#if BLE_FEATURE_SECURITY
case SecurityRequirement_t::UNAUTHENTICATED:
return (needs_signing) ?
SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
@ -1768,11 +1772,13 @@ public:
return (needs_signing) ?
SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
#if BLE_FEATURE_SECURE_CONNECTIONS
case SecurityRequirement_t::SC_AUTHENTICATED:
MBED_ASSERT(needs_signing == false);
// fallback to encryption with MITM
return SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
default:
MBED_ASSERT(false);
return SecurityManager::SECURITY_MODE_NO_ACCESS;
@ -1851,15 +1857,19 @@ private:
// assuming access is managed by property and orthogonal to
// security mode ...
return SecurityRequirement_t::NONE;
#if BLE_FEATURE_SECURITY
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
#if BLE_FEATURE_SIGNING
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
#endif
return SecurityRequirement_t::UNAUTHENTICATED;
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
#if BLE_FEATURE_SIGNING
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
#endif
return SecurityRequirement_t::AUTHENTICATED;
#endif // BLE_FEATURE_SECURITY
default:
// should not happens; makes the compiler happy.
return SecurityRequirement_t::NONE;

View File

@ -121,9 +121,13 @@ namespace ble {
class ConnectionParameters {
enum {
LE_1M_INDEX = 0,
#if BLE_FEATURE_PHY_MANAGEMENT
LE_2M_INDEX = 1,
LE_CODED_INDEX = 2,
MAX_PARAM_PHYS = 3
#else
MAX_PARAM_PHYS = 1
#endif // BLE_FEATURE_PHY_MANAGEMENT
};
public:
@ -208,6 +212,7 @@ public:
return *this;
}
#if BLE_FEATURE_PHY_MANAGEMENT
/**
* Enable or disable PHYs.
*
@ -251,6 +256,7 @@ public:
return *this;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
/* getters */
/**
@ -270,9 +276,11 @@ public:
uint8_t getNumberOfEnabledPhys() const
{
return (
_enabledPhy[LE_1M_INDEX] * 1 +
_enabledPhy[LE_2M_INDEX] * 1 +
_enabledPhy[LE_CODED_INDEX] * 1
_enabledPhy[LE_1M_INDEX] * 1
#if BLE_FEATURE_PHY_MANAGEMENT
+ _enabledPhy[LE_2M_INDEX] * 1
+ _enabledPhy[LE_CODED_INDEX] * 1
#endif // BLE_FEATURE_PHY_MANAGEMENT
);
}
@ -309,14 +317,19 @@ public:
phy_set_t getPhySet() const
{
#if BLE_FEATURE_PHY_MANAGEMENT
phy_set_t set(
_enabledPhy[LE_1M_INDEX],
_enabledPhy[LE_2M_INDEX],
_enabledPhy[LE_CODED_INDEX]
);
return set;
#else
return phy_set_t::PHY_SET_1M;
#endif // BLE_FEATURE_PHY_MANAGEMENT
}
/* These return pointers to arrays of settings valid only across the number of active PHYs */
const uint16_t *getScanIntervalArray() const
@ -364,6 +377,7 @@ public:
private:
uint8_t getFirstEnabledIndex() const
{
#if BLE_FEATURE_PHY_MANAGEMENT
if (_enabledPhy[LE_1M_INDEX]) {
return LE_1M_INDEX;
} else if (_enabledPhy[LE_2M_INDEX]) {
@ -374,6 +388,7 @@ private:
/* This should never happen; it means you were trying to start a connection with a blank set
* of parameters - you need to enable at least one PHY */
MBED_ASSERT("Trying to use connection parameters without any PHY defined.");
#endif // BLE_FEATURE_PHY_MANAGEMENT
return 0;
}
@ -387,6 +402,7 @@ private:
{
uint8_t index = phyToIndex(phy);
#if BLE_FEATURE_PHY_MANAGEMENT
bool was_swapped = isSwapped();
_enabledPhy[index] = enable;
@ -401,6 +417,7 @@ private:
/* To keep the data contiguous, coded params are in place of the missing 2M params */
index = LE_2M_INDEX;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
return index;
}
@ -412,20 +429,23 @@ private:
case phy_t::LE_1M:
index = LE_1M_INDEX;
break;
#if BLE_FEATURE_PHY_MANAGEMENT
case phy_t::LE_2M:
index = LE_2M_INDEX;
break;
case phy_t::LE_CODED:
index = LE_CODED_INDEX;
break;
#endif // BLE_FEATURE_PHY_MANAGEMENT
default:
index = MAX_PARAM_PHYS;
index = LE_1M_INDEX;
MBED_ASSERT("Illegal PHY");
break;
}
return index;
}
#if BLE_FEATURE_PHY_MANAGEMENT
bool isSwapped() const
{
return (
@ -437,6 +457,7 @@ private:
/** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
void swapCodedAnd2M();
#endif // BLE_FEATURE_PHY_MANAGEMENT
private:
initiator_filter_policy_t _filterPolicy;

View File

@ -133,9 +133,12 @@ public:
phy_configuration_t conf(scan_interval, scan_window, active_scanning);
if (phy == phy_t::LE_1M) {
phy_1m_configuration = conf;
} else if (phy == phy_t::LE_CODED) {
}
#if BLE_FEATURE_PHY_MANAGEMENT
else if (phy == phy_t::LE_CODED) {
phy_coded_configuration = conf;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
}
/**
@ -182,6 +185,7 @@ public:
#endif // BLE_FEATURE_WHITELIST
}
#if BLE_FEATURE_PHY_MANAGEMENT
/**
* Enable or disable PHYs that should be used during scanning.
* @param enable_1m True to enable the 1M phy and false to disable it.
@ -194,6 +198,7 @@ public:
phys.set_coded(enable_coded);
return *this;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
/**
* Get the PHYs to use during scanning.
@ -231,6 +236,7 @@ public:
return phy_1m_configuration;
}
#if BLE_FEATURE_PHY_MANAGEMENT
/**
* Set the coded PHY scan configuration.
* @param interval The scan interval to use.
@ -250,6 +256,7 @@ public:
);
return *this;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
/**
* Get the coded PHY scan configuration.

View File

@ -23,6 +23,7 @@
namespace ble {
namespace pal {
#if BLE_FEATURE_SIGNING
/**
* Implemented by classes that are reacting to signing events.
*/
@ -92,6 +93,8 @@ public:
}
};
#endif // BLE_FEATURE_SIGNING
} // namespace pal
} // namespace ble

View File

@ -100,6 +100,7 @@ ConnectionParameters &ConnectionParameters::setConnectionParameters(
return *this;
}
#if BLE_FEATURE_PHY_MANAGEMENT
/** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
void ConnectionParameters::swapCodedAnd2M()
{
@ -130,5 +131,6 @@ void ConnectionParameters::swapCodedAnd2M()
_minEventLength[LE_CODED_INDEX] = minEventLength;
_maxEventLength[LE_CODED_INDEX] = maxEventLength;
}
#endif // BLE_FEATURE_PHY_MANAGEMENT
} // namespace ble

View File

@ -17,6 +17,7 @@
#include "BLERoles.h"
#if BLE_FEATURE_GATT_SERVER
#if BLE_ROLE_BROADCASTER
#ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */
@ -47,4 +48,5 @@ DFUService::ResetPrepare_t DFUService::handoverCallback = NULL;
#endif /* #ifdef TARGET_NRF51822 */
#endif // BLE_ROLE_BROADCASTER
#endif // BLE_FEATURE_GATT_SERVER

View File

@ -17,6 +17,7 @@
#include "BLERoles.h"
#if BLE_FEATURE_GATT_SERVER
#if BLE_ROLE_BROADCASTER
#include "ble/services/UARTService.h"
@ -44,4 +45,5 @@ const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] = {
0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
};
#endif // BLE_ROLE_BROADCASTER
#endif // BLE_FEATURE_GATT_SERVER

View File

@ -17,6 +17,7 @@
#include "BLERoles.h"
#if BLE_FEATURE_GATT_SERVER
#if BLE_ROLE_BROADCASTER
#include "ble/services/URIBeaconConfigService.h"
@ -38,4 +39,5 @@ const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_B
const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE};
#endif // BLE_ROLE_BROADCASTER
#endif // BLE_FEATURE_GATT_SERVER

View File

@ -229,7 +229,9 @@ private:
static void att_cb(const attEvt_t *pEvt);
static uint8_t atts_read_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, attsAttr_t *pAttr);
static uint8_t atts_write_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
#if BLE_FEATURE_SECURITY
static uint8_t atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle);
#endif // BLE_FEATURE_SECURITY
void add_generic_access_service();
void add_generic_attribute_service();
void* alloc_block(size_t block_size);

View File

@ -241,13 +241,19 @@ bool GattServer::is_characteristic_valid(GattCharacteristic *characteristic) {
return false;
}
#if BLE_FEATURE_SIGNING
// check for invalid permissions
if ((properties == SIGNED_WRITE_PROPERTY) &&
(characteristic->getWriteSecurityRequirement() == att_security_requirement_t::NONE ||
characteristic->getWriteSecurityRequirement() == att_security_requirement_t::SC_AUTHENTICATED)
(characteristic->getWriteSecurityRequirement() == att_security_requirement_t::NONE
#if BLE_FEATURE_SECURE_CONNECTIONS
|| characteristic->getWriteSecurityRequirement() == att_security_requirement_t::SC_AUTHENTICATED
#endif // BLE_FEATURE_SECURE_CONNECTIONS
)
) {
return false;
}
#endif // BLE_FEATURE_SIGNING
return true;
}
@ -324,6 +330,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
switch (characteristic->getReadSecurityRequirement().value()) {
case att_security_requirement_t::NONE:
break;
#if BLE_FEATURE_SECURITY
case att_security_requirement_t::UNAUTHENTICATED:
attribute_it->permissions |= ATTS_PERMIT_READ_ENC;
break;
@ -332,6 +339,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
ATTS_PERMIT_READ_ENC |
ATTS_PERMIT_READ_AUTH;
break;
#if BLE_FEATURE_SECURE_CONNECTIONS
case att_security_requirement_t::SC_AUTHENTICATED:
// Note: check done in the cordio stack doesn't cover LESC
// so this one is done in attsAuthorCback
@ -340,6 +348,8 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
ATTS_PERMIT_READ_AUTH |
ATTS_PERMIT_READ_AUTHORIZ;
break;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
}
}
@ -349,6 +359,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
switch (characteristic->getWriteSecurityRequirement().value()) {
case att_security_requirement_t::NONE:
break;
#if BLE_FEATURE_SECURITY
case att_security_requirement_t::UNAUTHENTICATED:
attribute_it->permissions |= ATTS_PERMIT_WRITE_ENC;
break;
@ -357,6 +368,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
ATTS_PERMIT_WRITE_ENC |
ATTS_PERMIT_WRITE_AUTH;
break;
#if BLE_FEATURE_SECURE_CONNECTIONS
case att_security_requirement_t::SC_AUTHENTICATED:
// Note: check done in the cordio stack doesn't cover LESC
// so this one is done in attsAuthorCback
@ -365,6 +377,8 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
ATTS_PERMIT_WRITE_AUTH |
ATTS_PERMIT_WRITE_AUTHORIZ;
break;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
}
}
@ -456,6 +470,7 @@ ble_error_t GattServer::insert_descriptor(
switch (descriptor->getReadSecurityRequirement().value()) {
case att_security_requirement_t::NONE:
break;
#if BLE_FEATURE_SECURITY
case att_security_requirement_t::UNAUTHENTICATED:
attribute_it->permissions |= ATTS_PERMIT_READ_ENC;
break;
@ -464,6 +479,7 @@ ble_error_t GattServer::insert_descriptor(
ATTS_PERMIT_READ_ENC |
ATTS_PERMIT_READ_AUTH;
break;
#if BLE_FEATURE_SECURE_CONNECTIONS
case att_security_requirement_t::SC_AUTHENTICATED:
// Note: check done in the cordio stack doesn't cover LESC
// so this one is done in attsAuthorCback
@ -472,6 +488,8 @@ ble_error_t GattServer::insert_descriptor(
ATTS_PERMIT_READ_AUTH |
ATTS_PERMIT_READ_AUTHORIZ;
break;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
}
}
@ -481,6 +499,7 @@ ble_error_t GattServer::insert_descriptor(
switch (descriptor->getWriteSecurityRequirement().value()) {
case att_security_requirement_t::NONE:
break;
#if BLE_FEATURE_SECURITY
case att_security_requirement_t::UNAUTHENTICATED:
attribute_it->permissions |= ATTS_PERMIT_WRITE_ENC;
break;
@ -489,6 +508,7 @@ ble_error_t GattServer::insert_descriptor(
ATTS_PERMIT_WRITE_ENC |
ATTS_PERMIT_WRITE_AUTH;
break;
#if BLE_FEATURE_SECURE_CONNECTIONS
case att_security_requirement_t::SC_AUTHENTICATED:
// Note: check done in the cordio stack doesn't cover LESC
// so this one is done in attsAuthorCback
@ -497,6 +517,8 @@ ble_error_t GattServer::insert_descriptor(
ATTS_PERMIT_WRITE_AUTH |
ATTS_PERMIT_WRITE_AUTHORIZ;
break;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
}
}
@ -988,6 +1010,7 @@ uint8_t GattServer::atts_write_cb(
return ATT_SUCCESS;
}
#if BLE_FEATURE_SECURITY
uint8_t GattServer::atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle)
{
// this CB is triggered when read or write of an attribute (either a value
@ -1006,6 +1029,7 @@ uint8_t GattServer::atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t han
return ATT_SUCCESS;
}
#endif // BLE_FEATURE_SECURITY
void GattServer::add_generic_access_service()
{
@ -1254,14 +1278,17 @@ bool GattServer::is_update_authorized(
return true;
}
#if BLE_FEATURE_SECURITY
SecurityManager& security_manager = BLE::deviceInstance().getSecurityManager();
link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED);
ble_error_t err = security_manager.getLinkEncryption(connection, &encryption);
if (err) {
return false;
}
#endif // BLE_FEATURE_SECURITY
switch (sec_req.value()) {
#if BLE_FEATURE_SECURITY
case att_security_requirement_t::UNAUTHENTICATED:
if (encryption < link_encryption_t::ENCRYPTED) {
return false;
@ -1273,13 +1300,14 @@ bool GattServer::is_update_authorized(
return false;
}
return true;
#if BLE_FEATURE_SECURE_CONNECTIONS
case att_security_requirement_t::SC_AUTHENTICATED:
if (encryption != link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM) {
return false;
}
return true;
#endif // BLE_FEATURE_SECURE_CONNECTIONS
#endif // BLE_FEATURE_SECURITY
default:
return false;
}