1#ifndef BLUETOE_SM_SECURITY_CONNECTION_DATA_HPP
2#define BLUETOE_SM_SECURITY_CONNECTION_DATA_HPP
8 using identity_resolving_key_t = std::array< std::uint8_t, 16 >;
9 using uint128_t = std::array< std::uint8_t, 16 >;
11 using ecdh_public_key_t = std::array< std::uint8_t, 64 >;
12 using ecdh_private_key_t = std::array< std::uint8_t, 32 >;
13 using ecdh_shared_secret_t = std::array< std::uint8_t, 32 >;
15 using io_capabilities_t = std::array< std::uint8_t, 3 >;
23 std::array< std::uint8_t, 16 > longterm_key;
27 bool operator==(
const longterm_key_t& rhs)
const
29 return longterm_key == rhs.longterm_key
34 bool operator!=(
const longterm_key_t& rhs)
const
36 return !(*
this == rhs);
40 struct security_manager_meta_type {};
41 struct authentication_requirements_flags_meta_type {};
42 struct bonding_data_base_meta_type {};
43 struct key_distribution_meta_type {};
45 enum class sm_pairing_state : std::uint8_t {
51 user_response_success,
53 legacy_pairing_requested,
54 legacy_pairing_confirmed,
56 lesc_pairing_requested,
57 lesc_public_keys_exchanged,
58 lesc_pairing_confirm_send,
59 lesc_pairing_random_exchanged,
62 enum class authentication_requirements_flags : std::uint8_t {
65 secure_connections = 0x08,
69 template <
class OtherConnectionData >
70 class security_connection_data_base :
public OtherConnectionData
73 template <
class ... Args >
74 security_connection_data_base( Args&&... args )
75 : OtherConnectionData( args... )
76 , state_( details::sm_pairing_state::idle )
79 details::sm_pairing_state state()
const
86 remote_addr_ = remote;
96 state( details::sm_pairing_state::idle );
100 void state( details::sm_pairing_state state )
106 link_layer::device_address remote_addr_;
107 details::sm_pairing_state state_;
110 template <
class OtherConnectionData >
111 class legacy_security_connection_data :
public security_connection_data_base< OtherConnectionData >
114 template <
class ... Args >
115 legacy_security_connection_data( Args&&... args )
116 : security_connection_data_base< OtherConnectionData >( args... )
119 void legacy_pairing_request(
const details::uint128_t& srand,
const details::uint128_t& p1,
const details::uint128_t& p2 )
121 assert( this->state() == details::sm_pairing_state::idle );
122 this->state( details::sm_pairing_state::legacy_pairing_requested );
123 state_data_.pairing_state.c1_p1 = p1;
124 state_data_.pairing_state.c1_p2 = p2;
125 state_data_.pairing_state.srand = srand;
128 void pairing_confirm(
const std::uint8_t* mconfirm_begin,
const std::uint8_t* mconfirm_end )
130 assert( this->state() == details::sm_pairing_state::legacy_pairing_requested );
131 this->state( details::sm_pairing_state::legacy_pairing_confirmed );
133 assert(
static_cast< std::size_t
>( mconfirm_end - mconfirm_begin ) == state_data_.pairing_state.mconfirm.max_size() );
134 std::copy( mconfirm_begin, mconfirm_end, state_data_.pairing_state.mconfirm.begin() );
137 void legacy_pairing_completed(
const details::uint128_t& short_term_key )
139 assert( this->state() == details::sm_pairing_state::legacy_pairing_confirmed );
140 this->state( details::sm_pairing_state::pairing_completed );
142 state_data_.completed_state.short_term_key = short_term_key;
145 template <
class Link >
146 bool outgoing_security_manager_data_available(
const Link& link )
const
148 return link.is_encrypted() && this->state() != details::sm_pairing_state::pairing_completed;
151 std::pair< bool, details::uint128_t > find_key( std::uint16_t ediv, std::uint64_t rand )
const
153 if ( ediv == 0 && rand == 0 && this->state() == details::sm_pairing_state::pairing_completed )
154 return {
true, state_data_.completed_state.short_term_key };
156 return std::pair< bool, details::uint128_t >{};
159 const details::uint128_t& c1_p1()
const
161 return state_data_.pairing_state.c1_p1;
164 const details::uint128_t& c1_p2()
const
166 return state_data_.pairing_state.c1_p2;
169 const details::uint128_t& srand()
const
171 return state_data_.pairing_state.srand;
174 const details::uint128_t& mconfirm()
const
176 return state_data_.pairing_state.mconfirm;
179 void pairing_algorithm( details::legacy_pairing_algorithm algo )
184 details::legacy_pairing_algorithm legacy_pairing_algorithm()
const
189 device_pairing_status local_device_pairing_status()
const
191 if ( this->state() != details::sm_pairing_state::pairing_completed )
192 return bluetoe::device_pairing_status::no_key;
194 return algorithm_ == details::legacy_pairing_algorithm::just_works
195 ? device_pairing_status::unauthenticated_key
196 : device_pairing_status::authenticated_key;
199 void passkey(
const details::uint128_t& key )
201 state_data_.pairing_state.passkey = key;
204 details::uint128_t passkey()
const
206 return state_data_.pairing_state.passkey;
209 details::legacy_pairing_algorithm algorithm_;
213 details::uint128_t c1_p1;
214 details::uint128_t c1_p2;
215 details::uint128_t srand;
216 details::uint128_t mconfirm;
217 details::uint128_t passkey;
221 details::uint128_t short_term_key;
226 template <
class OtherConnectionData >
227 class lesc_security_connection_data :
public security_connection_data_base< OtherConnectionData >,
public pairing_yes_no_response
230 template <
class ... Args >
231 lesc_security_connection_data( Args&&... args )
232 : security_connection_data_base< OtherConnectionData >( args... )
235 void wait_for_user_response()
237 this->state( details::sm_pairing_state::user_response_wait );
240 void yes_no_response(
bool response )
override
242 assert( this->state() == details::sm_pairing_state::user_response_wait );
244 this->state( response
245 ? details::sm_pairing_state::user_response_success
246 : details::sm_pairing_state::user_response_failed );
249 device_pairing_status local_device_pairing_status()
const
251 return this->state() == details::sm_pairing_state::pairing_completed
252 ? bluetoe::device_pairing_status::unauthenticated_key
253 : bluetoe::device_pairing_status::no_key;
256 std::pair< bool, details::uint128_t > find_key( std::uint16_t ediv, std::uint64_t rand )
const
258 if ( this->state() == details::sm_pairing_state::pairing_completed && ediv == 0 && rand == 0 )
259 return {
true, long_term_key_ };
261 return std::pair< bool, details::uint128_t >{};
264 void pairing_requested(
const io_capabilities_t& remote_io_caps )
266 assert( this->state() == details::sm_pairing_state::idle );
267 this->state( details::sm_pairing_state::lesc_pairing_requested );
268 remote_io_caps_ = remote_io_caps;
271 void public_key_exchanged(
272 const ecdh_private_key_t& local_private_key,
273 const ecdh_public_key_t& local_public_key,
274 const std::uint8_t* remote_public_key,
275 const details::uint128_t& nonce )
277 assert( this->state() == details::sm_pairing_state::lesc_pairing_requested );
278 this->state( details::sm_pairing_state::lesc_public_keys_exchanged );
280 local_private_key_ = local_private_key;
281 local_public_key_ = local_public_key;
282 local_nonce_ = nonce;
283 std::copy( remote_public_key, remote_public_key + remote_public_key_.size(), remote_public_key_.begin() );
286 void pairing_confirm_send()
288 assert( this->state() == details::sm_pairing_state::lesc_public_keys_exchanged );
289 this->state( details::sm_pairing_state::lesc_pairing_confirm_send );
292 void pairing_random_exchanged(
const std::uint8_t* remote_nonce )
294 assert( this->state() == details::sm_pairing_state::lesc_pairing_confirm_send );
295 this->state( details::sm_pairing_state::lesc_pairing_random_exchanged );
297 std::copy( remote_nonce, remote_nonce + 16, remote_nonce_.begin() );
300 void lesc_pairing_completed(
const details::uint128_t& long_term_key )
302 assert( this->state() == details::sm_pairing_state::lesc_pairing_random_exchanged
303 || this->state() == details::sm_pairing_state::user_response_success );
305 this->state( details::sm_pairing_state::pairing_completed );
307 long_term_key_ = long_term_key;
310 const uint128_t& local_nonce()
const
315 const uint128_t& remote_nonce()
const
317 return remote_nonce_;
320 const std::uint8_t* local_public_key_x()
const
322 return local_public_key_.data();
325 const std::uint8_t* remote_public_key_x()
const
327 return remote_public_key_.data();
330 const std::uint8_t* remote_public_key()
const
332 return remote_public_key_.data();
335 const std::uint8_t* local_private_key()
const
337 return local_private_key_.data();
340 const io_capabilities_t& remote_io_caps()
const
342 return remote_io_caps_;
345 void pairing_algorithm( details::lesc_pairing_algorithm algo )
350 details::lesc_pairing_algorithm lesc_pairing_algorithm()
const
355 enum lesc_pairing_algorithm algorithm_;
357 ecdh_private_key_t local_private_key_;
358 ecdh_public_key_t local_public_key_;
359 ecdh_public_key_t remote_public_key_;
360 uint128_t local_nonce_;
361 uint128_t remote_nonce_;
362 io_capabilities_t remote_io_caps_;
363 uint128_t long_term_key_;
366 template <
class OtherConnectionData >
367 class security_connection_data :
public security_connection_data_base< OtherConnectionData >,
public pairing_yes_no_response
370 template <
class ... Args >
371 security_connection_data( Args&&... args )
372 : security_connection_data_base< OtherConnectionData >( args... )
375 void wait_for_user_response()
377 this->state( details::sm_pairing_state::user_response_wait );
380 void yes_no_response(
bool response )
override
382 assert( this->state() == details::sm_pairing_state::user_response_wait );
384 this->state( response
385 ? details::sm_pairing_state::user_response_success
386 : details::sm_pairing_state::user_response_failed );
389 void pairing_algorithm( details::legacy_pairing_algorithm algo )
391 state_data_.legacy_state.algorithm = algo;
394 details::legacy_pairing_algorithm legacy_pairing_algorithm()
const
396 return state_data_.legacy_state.algorithm;
399 void pairing_algorithm( details::lesc_pairing_algorithm algo )
401 state_data_.lesc_state.algorithm = algo;
404 details::lesc_pairing_algorithm lesc_pairing_algorithm()
const
406 return state_data_.lesc_state.algorithm;
409 void legacy_pairing_request(
const details::uint128_t& srand,
const details::uint128_t& p1,
const details::uint128_t& p2 )
411 assert( this->state() == details::sm_pairing_state::idle );
412 this->state( details::sm_pairing_state::legacy_pairing_requested );
413 state_data_.legacy_state.states.pairing_state.c1_p1 = p1;
414 state_data_.legacy_state.states.pairing_state.c1_p2 = p2;
415 state_data_.legacy_state.states.pairing_state.srand = srand;
418 void pairing_confirm(
const std::uint8_t* mconfirm_begin,
const std::uint8_t* mconfirm_end )
420 assert( this->state() == details::sm_pairing_state::legacy_pairing_requested );
421 this->state( details::sm_pairing_state::legacy_pairing_confirmed );
423 assert(
static_cast< std::size_t
>( mconfirm_end - mconfirm_begin ) == state_data_.legacy_state.states.pairing_state.mconfirm.max_size() );
424 std::copy( mconfirm_begin, mconfirm_end, state_data_.legacy_state.states.pairing_state.mconfirm.begin() );
427 void legacy_pairing_completed(
const details::uint128_t& short_term_key )
429 assert( this->state() == details::sm_pairing_state::legacy_pairing_confirmed );
430 this->state( details::sm_pairing_state::pairing_completed );
432 long_term_key_ = short_term_key;
434 pairing_status_ = state_data_.legacy_state.algorithm == details::legacy_pairing_algorithm::just_works
435 ? device_pairing_status::unauthenticated_key
436 : device_pairing_status::authenticated_key;
439 void lesc_pairing_completed(
const details::uint128_t& long_term_key )
441 assert( this->state() == details::sm_pairing_state::lesc_pairing_random_exchanged
442 || this->state() == details::sm_pairing_state::user_response_success );
444 this->state( details::sm_pairing_state::pairing_completed );
446 long_term_key_ = long_term_key;
448 pairing_status_ = state_data_.lesc_state.algorithm == details::lesc_pairing_algorithm::just_works
449 ? device_pairing_status::unauthenticated_key
450 : device_pairing_status::authenticated_key;
453 const details::uint128_t& c1_p1()
const
455 return state_data_.legacy_state.states.pairing_state.c1_p1;
458 const details::uint128_t& c1_p2()
const
460 return state_data_.legacy_state.states.pairing_state.c1_p2;
463 const details::uint128_t& srand()
const
465 return state_data_.legacy_state.states.pairing_state.srand;
468 const details::uint128_t& mconfirm()
const
470 return state_data_.legacy_state.states.pairing_state.mconfirm;
473 void passkey(
const details::uint128_t& key )
475 state_data_.legacy_state.states.pairing_state.passkey = key;
478 details::uint128_t passkey()
const
480 return state_data_.legacy_state.states.pairing_state.passkey;
483 void public_key_exchanged(
484 const ecdh_private_key_t& local_private_key,
485 const ecdh_public_key_t& local_public_key,
486 const std::uint8_t* remote_public_key,
487 const details::uint128_t& nonce )
489 assert( this->state() == details::sm_pairing_state::lesc_pairing_requested );
490 this->state( details::sm_pairing_state::lesc_public_keys_exchanged );
492 state_data_.lesc_state.local_private_key_ = local_private_key;
493 state_data_.lesc_state.local_public_key_ = local_public_key;
494 state_data_.lesc_state.local_nonce_ = nonce;
495 std::copy( remote_public_key, remote_public_key + state_data_.lesc_state.remote_public_key_.size(), state_data_.lesc_state.remote_public_key_.begin() );
498 void pairing_confirm_send()
500 assert( this->state() == details::sm_pairing_state::lesc_public_keys_exchanged );
501 this->state( details::sm_pairing_state::lesc_pairing_confirm_send );
504 void pairing_random_exchanged(
const std::uint8_t* remote_nonce )
506 assert( this->state() == details::sm_pairing_state::lesc_pairing_confirm_send );
507 this->state( details::sm_pairing_state::lesc_pairing_random_exchanged );
509 std::copy( remote_nonce, remote_nonce + 16, state_data_.lesc_state.remote_nonce_.begin() );
512 void pairing_requested(
const io_capabilities_t& remote_io_caps )
514 assert( this->state() == details::sm_pairing_state::idle );
515 this->state( details::sm_pairing_state::lesc_pairing_requested );
516 state_data_.lesc_state.remote_io_caps_ = remote_io_caps;
519 const uint128_t& local_nonce()
const
521 return state_data_.lesc_state.local_nonce_;
524 const uint128_t& remote_nonce()
const
526 return state_data_.lesc_state.remote_nonce_;
529 const std::uint8_t* local_public_key_x()
const
531 return state_data_.lesc_state.local_public_key_.data();
534 const std::uint8_t* remote_public_key_x()
const
536 return state_data_.lesc_state.remote_public_key_.data();
539 const std::uint8_t* remote_public_key()
const
541 return state_data_.lesc_state.remote_public_key_.data();
544 const std::uint8_t* local_private_key()
const
546 return state_data_.lesc_state.local_private_key_.data();
549 const io_capabilities_t& remote_io_caps()
const
551 return state_data_.lesc_state.remote_io_caps_;
554 template <
class Link >
555 bool outgoing_security_manager_data_available(
const Link& link )
const
557 return link.is_encrypted() && this->state() != details::sm_pairing_state::pairing_completed;
560 std::pair< bool, details::uint128_t > find_key( std::uint16_t ediv, std::uint64_t rand )
const
562 if ( this->state() == details::sm_pairing_state::pairing_completed && ediv == 0 && rand == 0 )
563 return {
true, long_term_key_ };
565 return std::pair< bool, details::uint128_t >{};
568 device_pairing_status local_device_pairing_status()
const
570 if ( this->state() != details::sm_pairing_state::pairing_completed )
571 return bluetoe::device_pairing_status::no_key;
573 return pairing_status_;
577 details::uint128_t long_term_key_;
578 device_pairing_status pairing_status_;
584 details::uint128_t c1_p1;
585 details::uint128_t c1_p2;
586 details::uint128_t srand;
587 details::uint128_t mconfirm;
588 details::uint128_t passkey;
591 enum legacy_pairing_algorithm algorithm;
595 ecdh_private_key_t local_private_key_;
596 ecdh_public_key_t local_public_key_;
597 ecdh_public_key_t remote_public_key_;
598 uint128_t local_nonce_;
599 uint128_t remote_nonce_;
600 io_capabilities_t remote_io_caps_;
601 enum lesc_pairing_algorithm algorithm;
data type containing a device address and the address type (public or random).
Definition: address.hpp:107