1010#include "argparse.h"
1111#include <bs_pc_backchannel.h>
1212
13+ #include <tinycrypt/constants.h>
14+ #include <tinycrypt/ecc.h>
15+ #include <tinycrypt/ecc_dh.h>
16+
1317#include <sys/byteorder.h>
1418
1519#define LOG_MODULE_NAME mesh_prov
@@ -24,7 +28,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
2428
2529#define PROV_MULTI_COUNT 3
2630#define PROV_REPROV_COUNT 10
27- #define WAIT_TIME 60 /*seconds*/
31+ #define WAIT_TIME 80 /*seconds*/
2832
2933enum test_flags {
3034 IS_PROVISIONER ,
@@ -36,14 +40,18 @@ static uint8_t static_key1[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F,
3640 0x65 , 0x78 , 0x61 , 0x6D , 0x70 , 0x6C , 0x65 , 0x5F , 0x31 };
3741static uint8_t static_key2 [] = {0x6E , 0x6F , 0x72 , 0x64 , 0x69 , 0x63 , 0x5F };
3842
39- static struct {
43+ static uint8_t private_key_be [64 ];
44+ static uint8_t public_key_be [64 ];
45+
46+ static struct oob_auth_test_vector_s {
4047 const uint8_t * static_val ;
4148 uint8_t static_val_len ;
4249 uint8_t output_size ;
4350 uint16_t output_actions ;
4451 uint8_t input_size ;
4552 uint16_t input_actions ;
4653} oob_auth_test_vector [] = {
54+ {NULL , 0 , 0 , 0 , 0 , 0 },
4755 {static_key1 , sizeof (static_key1 ), 0 , 0 , 0 , 0 },
4856 {static_key2 , sizeof (static_key2 ), 0 , 0 , 0 , 0 },
4957 {NULL , 0 , 3 , BT_MESH_BLINK , 0 , 0 },
@@ -75,6 +83,7 @@ static struct k_work_delayable oob_timer;
7583static void delayed_input (struct k_work * work );
7684
7785static uint * oob_channel_id ;
86+ static bool is_oob_auth ;
7887
7988static void test_device_init (void )
8089{
@@ -222,7 +231,7 @@ static void capabilities(const struct bt_mesh_dev_capabilities *cap)
222231 } else if (cap -> input_actions ) {
223232 LOG_INF ("Input OOB authentication" );
224233 ASSERT_OK (bt_mesh_auth_method_set_input (prov .input_actions , prov .input_size ));
225- } else if (!oob_channel_id ) {
234+ } else if (!is_oob_auth ) {
226235 bt_mesh_auth_method_set_none ();
227236 } else {
228237 FAIL ("No OOB in capability frame" );
@@ -231,15 +240,113 @@ static void capabilities(const struct bt_mesh_dev_capabilities *cap)
231240
232241static void oob_auth_set (int test_step )
233242{
243+ struct oob_auth_test_vector_s dummy = {0 };
244+
234245 ASSERT_TRUE (test_step < ARRAY_SIZE (oob_auth_test_vector ));
235246
247+ if (memcmp (& oob_auth_test_vector [test_step ], & dummy ,
248+ sizeof (struct oob_auth_test_vector_s ))) {
249+ is_oob_auth = true;
250+ } else {
251+ is_oob_auth = false;
252+ }
253+
236254 prov .static_val = oob_auth_test_vector [test_step ].static_val ;
237255 prov .static_val_len = oob_auth_test_vector [test_step ].static_val_len ;
238256 prov .output_size = oob_auth_test_vector [test_step ].output_size ;
239257 prov .output_actions = oob_auth_test_vector [test_step ].output_actions ;
240258 prov .input_size = oob_auth_test_vector [test_step ].input_size ;
241259 prov .input_actions = oob_auth_test_vector [test_step ].input_actions ;
242260}
261+ static void oob_device (bool use_oob_pk )
262+ {
263+ int err = 0 ;
264+
265+ k_sem_init (& prov_sem , 0 , 1 );
266+
267+ oob_channel_id = bs_open_back_channel (get_device_nbr (),
268+ (uint []){(get_device_nbr () + 1 ) % 2 }, (uint []){0 }, 1 );
269+ if (!oob_channel_id ) {
270+ FAIL ("Can't open OOB interface (err %d)\n" , err );
271+ }
272+
273+ bt_mesh_device_setup (& prov , & comp );
274+
275+ if (use_oob_pk ) {
276+ ASSERT_TRUE (uECC_make_key (public_key_be , private_key_be , uECC_secp256r1 ()));
277+ prov .public_key_be = public_key_be ;
278+ prov .private_key_be = private_key_be ;
279+ bs_bc_send_msg (* oob_channel_id , public_key_be , 64 );
280+ LOG_HEXDUMP_INF (public_key_be , 64 , "OOB Public Key:" );
281+ }
282+
283+ for (int i = 0 ; i < ARRAY_SIZE (oob_auth_test_vector ); i ++ ) {
284+ oob_auth_set (i );
285+
286+ ASSERT_OK (bt_mesh_prov_enable (BT_MESH_PROV_ADV ));
287+
288+ /* Keep a long timeout so the prov multi case has time to finish: */
289+ ASSERT_OK (k_sem_take (& prov_sem , K_SECONDS (40 )));
290+
291+ /* Delay to complete procedure with Provisioning Complete PDU frame.
292+ * Device shall start later provisioner was able to set OOB public key.
293+ */
294+ k_sleep (K_SECONDS (2 ));
295+
296+ bt_mesh_reset ();
297+ }
298+ }
299+
300+ static void oob_provisioner (bool read_oob_pk , bool use_oob_pk )
301+ {
302+ int err = 0 ;
303+
304+ k_sem_init (& prov_sem , 0 , 1 );
305+
306+ oob_channel_id = bs_open_back_channel (get_device_nbr (),
307+ (uint []){(get_device_nbr () + 1 ) % 2 }, (uint []){0 }, 1 );
308+ if (!oob_channel_id ) {
309+ FAIL ("Can't open OOB interface (err %d)\n" , err );
310+ }
311+
312+ bt_mesh_device_setup (& prov , & comp );
313+
314+ if (read_oob_pk ) {
315+ /* Delay to complete procedure public key generation on provisioning device. */
316+ k_sleep (K_SECONDS (1 ));
317+
318+ int size = bs_bc_is_msg_received (* oob_channel_id );
319+
320+ if (size <= 0 ) {
321+ FAIL ("OOB public key is not gotten" );
322+ }
323+
324+ bs_bc_receive_msg (* oob_channel_id , public_key_be , 64 );
325+ LOG_HEXDUMP_INF (public_key_be , 64 , "OOB Public Key:" );
326+ }
327+
328+ ASSERT_OK (bt_mesh_cdb_create (test_net_key ));
329+
330+ ASSERT_OK (bt_mesh_provision (test_net_key , 0 , 0 , 0 , 0x0001 , dev_key ));
331+
332+ for (int i = 0 ; i < ARRAY_SIZE (oob_auth_test_vector ); i ++ ) {
333+ oob_auth_set (i );
334+
335+ if (use_oob_pk ) {
336+ ASSERT_OK (bt_mesh_prov_remote_pub_key_set (public_key_be ));
337+ }
338+
339+ ASSERT_OK (k_sem_take (& prov_sem , K_SECONDS (40 )));
340+
341+ bt_mesh_cdb_node_del (bt_mesh_cdb_node_get (prov_addr - 1 ), true);
342+
343+ /* Delay to complete procedure with cleaning of the public key.
344+ * This is important that the provisioner started the new cycle loop
345+ * earlier than device to get OOB public key before capabilities frame.
346+ */
347+ k_sleep (K_SECONDS (1 ));
348+ }
349+ }
243350
244351/** @brief Verify that this device pb-adv provision.
245352 */
@@ -299,65 +406,35 @@ static void test_provisioner_pb_adv_no_oob(void)
299406
300407static void test_device_pb_adv_oob_auth (void )
301408{
302- int err = 0 ;
303-
304- k_sem_init (& prov_sem , 0 , 1 );
305-
306- oob_channel_id = bs_open_back_channel (get_device_nbr (),
307- (uint []){(get_device_nbr () + 1 ) % 2 }, (uint []){0 }, 1 );
308- if (!oob_channel_id ) {
309- FAIL ("Can't open OOB interface (err %d)\n" , err );
310- }
311-
312- bt_mesh_device_setup (& prov , & comp );
313-
314- for (int i = 0 ; i < ARRAY_SIZE (oob_auth_test_vector ); i ++ ) {
315- oob_auth_set (i );
316-
317- err = bt_mesh_prov_enable (BT_MESH_PROV_ADV );
318- ASSERT_OK (err , "Device PB-ADV Enable failed (err %d)" , err );
319-
320- /* Keep a long timeout so the prov multi case has time to finish: */
321- ASSERT_OK (k_sem_take (& prov_sem , K_SECONDS (40 )),
322- "Device provision fail" );
323-
324- /* Delay to complete procedure with Provisioning Complete PDU frame. */
325- k_sleep (K_SECONDS (1 ));
326-
327- bt_mesh_reset ();
328- }
409+ oob_device (false);
329410
330411 PASS ();
331412}
332413
333414static void test_provisioner_pb_adv_oob_auth (void )
334415{
335- int err = 0 ;
336-
337- k_sem_init (& prov_sem , 0 , 1 );
416+ oob_provisioner (false, false);
338417
339- oob_channel_id = bs_open_back_channel (get_device_nbr (),
340- (uint []){(get_device_nbr () + 1 ) % 2 }, (uint []){0 }, 1 );
341- if (!oob_channel_id ) {
342- FAIL ("Can't open OOB interface (err %d)\n" , err );
343- }
344-
345- bt_mesh_device_setup (& prov , & comp );
418+ PASS ();
419+ }
346420
347- err = bt_mesh_cdb_create (test_net_key );
348- ASSERT_OK (err , "Failed to create CDB (err %d)\n" , err );
421+ static void test_device_pb_adv_oob_public_key (void )
422+ {
423+ oob_device (true);
349424
350- err = bt_mesh_provision ( test_net_key , 0 , 0 , 0 , 0x0001 , dev_key );
351- ASSERT_OK ( err , "Provisioning failed (err %d)" , err );
425+ PASS ( );
426+ }
352427
353- for (int i = 0 ; i < ARRAY_SIZE (oob_auth_test_vector ); i ++ ) {
354- oob_auth_set (i );
428+ static void test_provisioner_pb_adv_oob_public_key (void )
429+ {
430+ oob_provisioner (true, true);
355431
356- ASSERT_OK ( k_sem_take ( & prov_sem , K_SECONDS ( 40 )),
357- "Provisioner provision fail" );
432+ PASS ();
433+ }
358434
359- bt_mesh_cdb_node_del (bt_mesh_cdb_node_get (prov_addr - 1 ), true);
360- }
435+ static void test_provisioner_pb_adv_oob_auth_no_oob_public_key (void )
436+ {
437+ oob_provisioner (true, false);
361438
362439 PASS ();
363440}
@@ -507,6 +584,8 @@ static const struct bst_test_instance test_connect[] = {
507584 "Device: pb-adv provisioning use no-oob method" ),
508585 TEST_CASE (device , pb_adv_oob_auth ,
509586 "Device: pb-adv provisioning use oob authentication" ),
587+ TEST_CASE (device , pb_adv_oob_public_key ,
588+ "Device: pb-adv provisioning use oob public key" ),
510589 TEST_CASE (device , pb_adv_reprovision ,
511590 "Device: pb-adv provisioning, reprovision" ),
512591
@@ -520,6 +599,10 @@ static const struct bst_test_instance test_connect[] = {
520599 "Provisioner: effect on ivu_duration when IV Update flag is set to one" ),
521600 TEST_CASE (provisioner , pb_adv_oob_auth ,
522601 "Provisioner: pb-adv provisioning use oob authentication" ),
602+ TEST_CASE (provisioner , pb_adv_oob_public_key ,
603+ "Provisioner: pb-adv provisioning use oob public key" ),
604+ TEST_CASE (provisioner , pb_adv_oob_auth_no_oob_public_key ,
605+ "Provisioner: pb-adv provisioning use oob authentication, ignore oob public key" ),
523606 TEST_CASE (provisioner , pb_adv_reprovision ,
524607 "Provisioner: pb-adv provisioning, resetting and reprovisioning multiple times." ),
525608
0 commit comments