Skip to content

Commit ed17033

Browse files
authored
Merge pull request #6188 from paul-szczepanek-arm/master
BLE: Security Manager
2 parents 2532196 + a3383c1 commit ed17033

File tree

86 files changed

+6137
-263
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+6137
-263
lines changed

features/FEATURE_BLE/.mbedignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tests/*

features/FEATURE_BLE/ble/BLE.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#ifdef YOTTA_CFG_MBED_OS
2929
#include "mbed-drivers/mbed_error.h"
3030
#else
31-
#include "mbed_error.h"
31+
#include "platform/mbed_error.h"
3232
#endif
3333

3434
#include "platform/mbed_toolchain.h"

features/FEATURE_BLE/ble/BLETypes.h

Lines changed: 265 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <stddef.h>
2121
#include <stdint.h>
22+
#include <string.h>
23+
#include "ble/SafeEnum.h"
2224

2325
/**
2426
* @addtogroup ble
@@ -54,7 +56,7 @@ typedef uint16_t attribute_handle_t;
5456
*/
5557
struct attribute_handle_range_t {
5658
/**
57-
* Begining of the range.
59+
* Beginning of the range.
5860
*/
5961
attribute_handle_t begin;
6062

@@ -96,8 +98,8 @@ struct attribute_handle_range_t {
9698
/**
9799
* Construct an attribute_handle_range_t from its first and last attribute handle.
98100
*
99-
* @param begin Handle at the begining of the range.
100-
* @param end Handle at the end of the range.
101+
* @param[in] begin Handle at the beginning of the range.
102+
* @param[in] end Handle at the end of the range.
101103
*
102104
* @return An instance of attribute_handle_range_t where
103105
* attribute_handle_range_t::begin is equal to begin and
@@ -117,6 +119,266 @@ static inline attribute_handle_range_t attribute_handle_range(
117119
return result;
118120
}
119121

122+
/**
123+
* Type that describes link's encryption state.
124+
*/
125+
struct link_encryption_t : SafeEnum<link_encryption_t, uint8_t> {
126+
/** struct scoped enum wrapped by the class */
127+
enum type {
128+
NOT_ENCRYPTED, /**< The link is not secured. */
129+
ENCRYPTION_IN_PROGRESS, /**< Link security is being established. */
130+
ENCRYPTED, /**< The link is secure. */
131+
ENCRYPTED_WITH_MITM /**< The link is secure and authenticated. */
132+
};
133+
134+
/**
135+
* Construct a new instance of link_encryption_t.
136+
*/
137+
link_encryption_t(type value) : SafeEnum<link_encryption_t, uint8_t>(value) { }
138+
};
139+
140+
/**
141+
* Type that describe a pairing failure.
142+
*/
143+
struct pairing_failure_t : SafeEnum<pairing_failure_t, uint8_t> {
144+
/** struct scoped enum wrapped by the class */
145+
enum type {
146+
PASSKEY_ENTRY_FAILED = 0x01,
147+
OOB_NOT_AVAILABLE = 0x02,
148+
AUTHENTICATION_REQUIREMENTS = 0x03,
149+
CONFIRM_VALUE_FAILED = 0x04,
150+
PAIRING_NOT_SUPPORTED = 0x05,
151+
ENCRYPTION_KEY_SIZE = 0x06,
152+
COMMAND_NOT_SUPPORTED = 0x07,
153+
UNSPECIFIED_REASON = 0x08,
154+
REPEATED_ATTEMPTS = 0x09,
155+
INVALID_PARAMETERS = 0x0A,
156+
DHKEY_CHECK_FAILED = 0x0B,
157+
NUMERIC_COMPARISON_FAILED = 0x0c,
158+
BR_EDR_PAIRING_IN_PROGRESS = 0x0D,
159+
CROSS_TRANSPORT_KEY_DERIVATION_OR_GENERATION_NOT_ALLOWED = 0x0E
160+
};
161+
162+
/**
163+
* Construct a new instance of pairing_failure_t.
164+
*/
165+
pairing_failure_t(type value) : SafeEnum<pairing_failure_t, uint8_t>(value) { }
166+
};
167+
168+
169+
/**
170+
* Type that describe the IO capability of a device; it is used during Pairing
171+
* Feature exchange.
172+
*/
173+
struct io_capability_t : SafeEnum<io_capability_t, uint8_t> {
174+
enum type {
175+
DISPLAY_ONLY = 0x00,
176+
DISPLAY_YES_NO = 0x01,
177+
KEYBOARD_ONLY = 0x02,
178+
NO_INPUT_NO_OUTPUT = 0x03,
179+
KEYBOARD_DISPLAY = 0x04
180+
};
181+
182+
/**
183+
* Construct a new instance of io_capability_t.
184+
*/
185+
io_capability_t(type value) : SafeEnum<io_capability_t, uint8_t>(value) { }
186+
};
187+
188+
/**
189+
* Passkey stored as a number.
190+
*/
191+
typedef uint32_t passkey_num_t;
192+
193+
/**
194+
* Passkey stored as a string of digits.
195+
*/
196+
class PasskeyAscii {
197+
public:
198+
static const uint8_t PASSKEY_LEN = 6;
199+
static const uint8_t NUMBER_OFFSET = '0';
200+
201+
/**
202+
* Default to all zeroes
203+
*/
204+
PasskeyAscii() {
205+
memset(ascii, NUMBER_OFFSET, PASSKEY_LEN);
206+
}
207+
208+
/**
209+
* Initialize a data from a string.
210+
*
211+
* @param[in] passkey value of the data.
212+
*/
213+
PasskeyAscii(const uint8_t* passkey) {
214+
if (passkey) {
215+
memcpy(ascii, passkey, PASSKEY_LEN);
216+
} else {
217+
memset(ascii, NUMBER_OFFSET, PASSKEY_LEN);
218+
}
219+
}
220+
221+
/**
222+
* Initialize a data from a number.
223+
*
224+
* @param[in] passkey value of the data.
225+
*/
226+
PasskeyAscii(passkey_num_t passkey) {
227+
for (int i = 5, m = 100000; i >= 0; --i, m /= 10) {
228+
uint32_t result = passkey / m;
229+
ascii[i] = NUMBER_OFFSET + result;
230+
passkey -= result * m;
231+
}
232+
}
233+
234+
/**
235+
* Cast to number.
236+
*/
237+
operator passkey_num_t() {
238+
return to_num(ascii);
239+
}
240+
241+
/**
242+
* Convert ASCII string of digits into a number.
243+
* @param[in] ascii ASCII string of 6 digits stored as ASCII characters
244+
* @return Passkey as a number.
245+
*/
246+
static uint32_t to_num(const uint8_t *ascii) {
247+
uint32_t passkey = 0;
248+
for (size_t i = 0, m = 1; i < PASSKEY_LEN; ++i, m *= 10) {
249+
passkey += (ascii[i] - NUMBER_OFFSET) * m;
250+
}
251+
return passkey;
252+
}
253+
254+
/**
255+
* Return the pointer to the buffer holding the string.
256+
*/
257+
uint8_t* value() {
258+
return ascii;
259+
}
260+
private:
261+
uint8_t ascii[PASSKEY_LEN];
262+
};
263+
264+
template <size_t array_size>
265+
struct byte_array_t {
266+
/**
267+
* Default to all zeroes
268+
*/
269+
byte_array_t() {
270+
memset(_value, 0x00, sizeof(_value));
271+
}
272+
273+
/**
274+
* Initialize a data from an array of bytes.
275+
*
276+
* @param[in] input_value value of the data.
277+
*/
278+
byte_array_t(const uint8_t *input_value) {
279+
memcpy(_value, input_value, sizeof(_value));
280+
}
281+
282+
/**
283+
* Initialize a data from an buffer of bytes.
284+
*
285+
* @param[in] input_value pointer to buffer.
286+
* @param[in] size buffer size
287+
*/
288+
byte_array_t(const uint8_t* input_value, size_t size) {
289+
memcpy(_value, input_value, size);
290+
}
291+
292+
/**
293+
* Equal operator between two octet types.
294+
*/
295+
friend bool operator==(const byte_array_t& lhs, const byte_array_t& rhs) {
296+
return memcmp(lhs._value, rhs._value, sizeof(lhs._value)) == 0;
297+
}
298+
299+
/**
300+
* Non equal operator between two octet types.
301+
*/
302+
friend bool operator!=(const byte_array_t& lhs, const byte_array_t& rhs) {
303+
return !(lhs == rhs);
304+
}
305+
306+
/**
307+
* Subscript operator to access data content
308+
*/
309+
uint8_t& operator[](uint8_t i) {
310+
return _value[i];
311+
}
312+
313+
/**
314+
* Return the pointer to the buffer holding data.
315+
*/
316+
const uint8_t* data() const {
317+
return _value;
318+
}
319+
320+
/**
321+
* Return the pointer to the buffer holding data.
322+
*/
323+
uint8_t* buffer() {
324+
return _value;
325+
}
326+
327+
/**
328+
* Size in byte of a data.
329+
*/
330+
static size_t size() {
331+
return array_size;
332+
}
333+
334+
protected:
335+
uint8_t _value[array_size];
336+
};
337+
338+
/** 128 bit keys used by paired devices */
339+
typedef byte_array_t<16> irk_t;
340+
typedef byte_array_t<16> csrk_t;
341+
typedef byte_array_t<16> ltk_t;
342+
343+
/** Used to identify LTK for legacy pairing connections */
344+
typedef byte_array_t<2> ediv_t;
345+
typedef byte_array_t<8> rand_t;
346+
347+
/** Out of band data exchanged during pairing */
348+
typedef byte_array_t<16> oob_tk_t; /**< legacy pairing TK */
349+
typedef byte_array_t<16> oob_lesc_value_t; /**< secure connections oob random 128 value */
350+
typedef byte_array_t<16> oob_confirm_t; /**< secure connections oob confirmation value */
351+
352+
/** data to be encrypted */
353+
typedef byte_array_t<16> encryption_block_t;
354+
355+
/** public key coordinate, two of which define the public key */
356+
typedef byte_array_t<32> public_key_coord_t;
357+
358+
/** Diffie-Hellman key */
359+
typedef byte_array_t<32> dhkey_t;
360+
361+
/**
362+
* MAC address data type.
363+
*/
364+
struct address_t : public byte_array_t<6> {
365+
/**
366+
* Create an invalid mac address, equal to FF:FF:FF:FF:FF:FF
367+
*/
368+
address_t() {
369+
memset(_value, 0xFF, sizeof(_value));
370+
}
371+
372+
/**
373+
* Initialize a data from an array of bytes.
374+
*
375+
* @param[in] input_value value of the data.
376+
*/
377+
address_t(const uint8_t *input_value) {
378+
memcpy(_value, input_value, sizeof(_value));
379+
}
380+
};
381+
120382
} // namespace ble
121383

122384
/**

features/FEATURE_BLE/ble/Gap.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class GapAdvertisingData;
237237
* // Initiate the connection procedure
238238
* gap.connect(
239239
* packet->peerAddr,
240-
* BLEProtocol::RANDOM_STATIC,
240+
* packet->addressType,
241241
* &connection_parameters,
242242
* &scanning_params
243243
* );
@@ -608,6 +608,11 @@ class Gap {
608608
* Pointer to the advertisement packet's data.
609609
*/
610610
const uint8_t *advertisingData;
611+
612+
/**
613+
* Type of the address received
614+
*/
615+
AddressType_t addressType;
611616
};
612617

613618
/**
@@ -2304,6 +2309,7 @@ class Gap {
23042309
ownAddr,
23052310
connectionParams
23062311
);
2312+
23072313
connectionCallChain.call(&callbackParams);
23082314
}
23092315

@@ -2342,22 +2348,29 @@ class Gap {
23422348
* @param[in] type Advertising type of the packet.
23432349
* @param[in] advertisingDataLen Length of the advertisement data received.
23442350
* @param[in] advertisingData Pointer to the advertisement packet's data.
2351+
* @param[in] addressType Type of the address of the peer that has emitted the packet.
23452352
*/
23462353
void processAdvertisementReport(
23472354
const BLEProtocol::AddressBytes_t peerAddr,
23482355
int8_t rssi,
23492356
bool isScanResponse,
23502357
GapAdvertisingParams::AdvertisingType_t type,
23512358
uint8_t advertisingDataLen,
2352-
const uint8_t *advertisingData
2359+
const uint8_t *advertisingData,
2360+
BLEProtocol::AddressType_t addressType = BLEProtocol::AddressType::RANDOM_STATIC
23532361
) {
2362+
// FIXME: remove default parameter for addressType when ST shield is merged;
2363+
// this has been added to mitigate the lack of dependency management in
2364+
// testing jobs ....
2365+
23542366
AdvertisementCallbackParams_t params;
23552367
memcpy(params.peerAddr, peerAddr, ADDR_LEN);
23562368
params.rssi = rssi;
23572369
params.isScanResponse = isScanResponse;
23582370
params.type = type;
23592371
params.advertisingDataLen = advertisingDataLen;
23602372
params.advertisingData = advertisingData;
2373+
params.addressType = addressType;
23612374
onAdvertisementReport.call(&params);
23622375
}
23632376

0 commit comments

Comments
 (0)