Skip to content

Commit 48000cd

Browse files
ahmedmoheb-nordiccarlescufi
authored andcommitted
tests: bluetooth: host: Add UT for bt_dh_key_gen()
Unit test project for bt_dh_key_gen(). This is part of subsys/bluetooth/host/ecc.c unit testing. Signed-off-by: Ahmed Moheb <[email protected]>
1 parent aebd5d8 commit 48000cd

File tree

5 files changed

+360
-0
lines changed

5 files changed

+360
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
set(SOURCES
6+
src/main.c
7+
src/test_suite_invalid_inputs.c
8+
)
9+
10+
project(bt_dh_key_gen)
11+
12+
find_package(Zephyr COMPONENTS unittest HINTS $ENV{ZEPHYR_BASE})
13+
14+
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host host_mocks)
15+
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host/ecc mocks)
16+
17+
target_link_libraries(testbinary PRIVATE mocks host_mocks)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_ZTEST_NEW_API=y
3+
CONFIG_BT=y
4+
CONFIG_BT_CENTRAL=y
5+
CONFIG_BT_MAX_PAIRED=7
6+
CONFIG_ASSERT=y
7+
CONFIG_ASSERT_LEVEL=2
8+
CONFIG_ASSERT_VERBOSE=y
9+
CONFIG_ASSERT_ON_ERRORS=y
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2022 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "mocks/ecc_help_utils.h"
8+
#include "mocks/hci_core.h"
9+
#include "mocks/hci_core_expects.h"
10+
#include "mocks/net_buf.h"
11+
#include "mocks/net_buf_expects.h"
12+
13+
#include <zephyr/bluetooth/hci.h>
14+
#include <zephyr/fff.h>
15+
#include <zephyr/kernel.h>
16+
17+
#include <host/ecc.h>
18+
#include <host/hci_core.h>
19+
20+
DEFINE_FFF_GLOBALS;
21+
22+
static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
23+
{
24+
bt_dh_key_cb_t *dh_key_cb = bt_ecc_get_dh_key_cb();
25+
26+
*dh_key_cb = NULL;
27+
memset(&bt_dev, 0x00, sizeof(struct bt_dev));
28+
29+
HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
30+
}
31+
32+
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
33+
34+
ZTEST_SUITE(bt_dh_key_gen, NULL, NULL, NULL, NULL, NULL);
35+
36+
static void bt_dh_key_unreachable_cb(const uint8_t key[BT_DH_KEY_LEN])
37+
{
38+
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
39+
}
40+
41+
/*
42+
* Test DH key generation succeeds
43+
*
44+
* Constraints:
45+
* - 'BT_DEV_HAS_PUB_KEY' flag is set
46+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
47+
* - 'CONFIG_BT_USE_DEBUG_KEYS' isn't enabled
48+
*
49+
* Expected behaviour:
50+
* - bt_dh_key_gen() returns 0 (success)
51+
*/
52+
ZTEST(bt_dh_key_gen, test_generate_dh_key_passes)
53+
{
54+
int result;
55+
struct net_buf net_buff = {0};
56+
struct bt_hci_cp_le_generate_dhkey cp = {0};
57+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
58+
59+
Z_TEST_SKIP_IFDEF(CONFIG_BT_USE_DEBUG_KEYS);
60+
61+
atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
62+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
63+
64+
/* This makes hci_generate_dhkey_v1() succeeds and returns 0 */
65+
net_buf_simple_add_fake.return_val = &cp;
66+
bt_hci_cmd_create_fake.return_val = &net_buff;
67+
bt_hci_cmd_send_sync_fake.return_val = 0;
68+
69+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
70+
71+
expect_single_call_net_buf_simple_add(&net_buff.b, sizeof(cp));
72+
expect_single_call_bt_hci_cmd_create(BT_HCI_OP_LE_GENERATE_DHKEY, sizeof(cp));
73+
expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_LE_GENERATE_DHKEY);
74+
75+
zassert_ok(result, "Unexpected error code '%d' was returned", result);
76+
}
77+
78+
/*
79+
* Test DH key generation succeeds with 'CONFIG_BT_USE_DEBUG_KEYS' enabled
80+
*
81+
* Constraints:
82+
* - 'BT_DEV_HAS_PUB_KEY' flag is set
83+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
84+
* - 'CONFIG_BT_USE_DEBUG_KEYS' is enabled
85+
*
86+
* Expected behaviour:
87+
* - bt_dh_key_gen() returns 0 (success)
88+
*/
89+
ZTEST(bt_dh_key_gen, test_generate_dh_key_passes_with_debug_keys_enabled)
90+
{
91+
int result;
92+
struct net_buf net_buff = {0};
93+
struct bt_hci_cp_le_generate_dhkey_v2 cp = {0};
94+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
95+
96+
Z_TEST_SKIP_IFNDEF(CONFIG_BT_USE_DEBUG_KEYS);
97+
98+
atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
99+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
100+
101+
/* Set "ECC Debug Keys" command support bit */
102+
bt_dev.supported_commands[41] |= BIT(2);
103+
104+
/* This makes hci_generate_dhkey_v2() succeeds and returns 0 */
105+
net_buf_simple_add_fake.return_val = &cp;
106+
bt_hci_cmd_create_fake.return_val = &net_buff;
107+
bt_hci_cmd_send_sync_fake.return_val = 0;
108+
109+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
110+
111+
expect_single_call_net_buf_simple_add(&net_buff.b, sizeof(cp));
112+
expect_single_call_bt_hci_cmd_create(BT_HCI_OP_LE_GENERATE_DHKEY_V2, sizeof(cp));
113+
expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_LE_GENERATE_DHKEY_V2);
114+
115+
zassert_ok(result, "Unexpected error code '%d' was returned", result);
116+
}
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/*
2+
* Copyright (c) 2022 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "host_mocks/assert.h"
8+
#include "mocks/ecc_help_utils.h"
9+
#include "mocks/hci_core.h"
10+
#include "mocks/hci_core_expects.h"
11+
#include "mocks/net_buf.h"
12+
#include "mocks/net_buf_expects.h"
13+
14+
#include <zephyr/bluetooth/hci.h>
15+
#include <zephyr/kernel.h>
16+
17+
#include <host/ecc.h>
18+
#include <host/hci_core.h>
19+
20+
ZTEST_SUITE(bt_dh_key_gen_invalid_cases, NULL, NULL, NULL, NULL, NULL);
21+
22+
static void bt_dh_key_unreachable_cb(const uint8_t key[BT_DH_KEY_LEN])
23+
{
24+
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
25+
}
26+
27+
/*
28+
* Test passing NULL reference for the 'remote_pk' argument
29+
*
30+
* Constraints:
31+
* - NULL reference is used for the 'remote_pk' argument
32+
*
33+
* Expected behaviour:
34+
* - An assertion is raised and execution stops
35+
*/
36+
ZTEST(bt_dh_key_gen_invalid_cases, test_null_remote_pk_reference)
37+
{
38+
expect_assert();
39+
bt_dh_key_gen(NULL, bt_dh_key_unreachable_cb);
40+
}
41+
42+
/*
43+
* Test passing NULL reference for the 'dh_key_cb' argument
44+
*
45+
* Constraints:
46+
* - NULL reference is used for the 'dh_key_cb' argument
47+
*
48+
* Expected behaviour:
49+
* - An assertion is raised and execution stops
50+
*/
51+
ZTEST(bt_dh_key_gen_invalid_cases, test_null_dh_key_cb_reference)
52+
{
53+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
54+
55+
expect_assert();
56+
bt_dh_key_gen(remote_pk, NULL);
57+
}
58+
59+
/*
60+
* Test DH key generation fails if the callback is already registered
61+
*
62+
* Constraints:
63+
* - 'BT_DEV_HAS_PUB_KEY' flag is set
64+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
65+
*
66+
* Expected behaviour:
67+
* - bt_dh_key_gen() returns a negative error code (-EALREADY)
68+
*/
69+
ZTEST(bt_dh_key_gen_invalid_cases, test_callback_already_registered)
70+
{
71+
int result;
72+
struct net_buf net_buff = {0};
73+
struct bt_hci_cp_le_generate_dhkey cp = {0};
74+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
75+
76+
atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
77+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
78+
79+
/* This makes hci_generate_dhkey_v1() succeeds and returns 0 */
80+
net_buf_simple_add_fake.return_val = &cp;
81+
bt_hci_cmd_create_fake.return_val = &net_buff;
82+
bt_hci_cmd_send_sync_fake.return_val = 0;
83+
84+
/* Pass first call that will set dh_key_cb = cb*/
85+
bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
86+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
87+
88+
zassert_true(result == -EALREADY, "Unexpected error code '%d' was returned", result);
89+
}
90+
91+
static void bt_dh_key_unreachable_2nd_trial_cb(const uint8_t key[BT_DH_KEY_LEN])
92+
{
93+
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
94+
}
95+
96+
/*
97+
* Test DH key generation fails if a current key generation cycle hasn't been finished yet and
98+
* 'dh_key_cb' isn't NULL.
99+
*
100+
* Constraints:
101+
* - 'BT_DEV_HAS_PUB_KEY' flag is set
102+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
103+
*
104+
* Expected behaviour:
105+
* - bt_dh_key_gen() returns a negative error code (-EBUSY)
106+
*/
107+
ZTEST(bt_dh_key_gen_invalid_cases, test_generate_key_parallel_with_running_one)
108+
{
109+
int result;
110+
struct net_buf net_buff = {0};
111+
struct bt_hci_cp_le_generate_dhkey cp = {0};
112+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
113+
114+
atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
115+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
116+
117+
/* This makes hci_generate_dhkey_v1() succeeds and returns 0 */
118+
net_buf_simple_add_fake.return_val = &cp;
119+
bt_hci_cmd_create_fake.return_val = &net_buff;
120+
bt_hci_cmd_send_sync_fake.return_val = 0;
121+
122+
/* Pass first call that will set dh_key_cb = cb*/
123+
bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
124+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_2nd_trial_cb);
125+
126+
zassert_true(result == -EBUSY, "Unexpected error code '%d' was returned", result);
127+
}
128+
129+
/*
130+
* Test DH key generation fails if a current key generation cycle hasn't been finished yet and
131+
* 'dh_key_cb' isn't NULL.
132+
*
133+
* Constraints:
134+
* - 'BT_DEV_PUB_KEY_BUSY' flag is set
135+
*
136+
* Expected behaviour:
137+
* - bt_dh_key_gen() returns a negative error code (-EBUSY)
138+
*/
139+
ZTEST(bt_dh_key_gen_invalid_cases, test_bt_dev_pub_key_busy_set)
140+
{
141+
int result;
142+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
143+
144+
atomic_set_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
145+
146+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
147+
148+
zassert_true(result == -EBUSY, "Unexpected error code '%d' was returned", result);
149+
}
150+
151+
/*
152+
* Test DH key generation fails if the 'BT_DEV_HAS_PUB_KEY' flag isn't set
153+
*
154+
* Constraints:
155+
* - 'BT_DEV_HAS_PUB_KEY' flag isn't set
156+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
157+
*
158+
* Expected behaviour:
159+
* - bt_dh_key_gen() returns a negative error code (-EADDRNOTAVAIL)
160+
*/
161+
ZTEST(bt_dh_key_gen_invalid_cases, test_device_has_no_pub_key)
162+
{
163+
int result;
164+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
165+
166+
atomic_clear_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
167+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
168+
169+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
170+
171+
zassert_true(result == -EADDRNOTAVAIL, "Unexpected error code '%d' was returned", result);
172+
}
173+
174+
/*
175+
* Test DH key generation fails when hci_generate_dhkey_v1/2() fails
176+
*
177+
* Constraints:
178+
* - 'BT_DEV_HAS_PUB_KEY' flag is set
179+
* - 'BT_DEV_PUB_KEY_BUSY' flag isn't set
180+
* - 'hci_generate_dhkey_v1/2()' fails and returns a negative error code (-ENOBUFS)
181+
*
182+
* Expected behaviour:
183+
* - bt_dh_key_gen() returns a negative error code (-ENOBUFS)
184+
*/
185+
ZTEST(bt_dh_key_gen_invalid_cases, test_hci_generate_dhkey_vx_fails)
186+
{
187+
int result;
188+
bt_dh_key_cb_t *dh_key_cb;
189+
const uint8_t remote_pk[BT_PUB_KEY_LEN] = {0};
190+
191+
atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY);
192+
atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY);
193+
194+
if (IS_ENABLED(CONFIG_BT_USE_DEBUG_KEYS)) {
195+
/* Set "ECC Debug Keys" command support bit */
196+
bt_dev.supported_commands[41] |= BIT(2);
197+
}
198+
199+
/* This makes hci_generate_dhkey_vx() fails and returns (-ENOBUFS) */
200+
bt_hci_cmd_create_fake.return_val = NULL;
201+
202+
result = bt_dh_key_gen(remote_pk, bt_dh_key_unreachable_cb);
203+
204+
zassert_true(result == -ENOBUFS, "Unexpected error code '%d' was returned", result);
205+
206+
dh_key_cb = bt_ecc_get_dh_key_cb();
207+
zassert_is_null(*dh_key_cb, "Unexpected callback reference was set");
208+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
common:
2+
tags: test_framework bluetooth host
3+
tests:
4+
bluetooth.host.bt_dh_key_gen.default:
5+
type: unit
6+
bluetooth.host.bt_dh_key_gen.bt_use_debug_keys_enabled:
7+
type: unit
8+
extra_configs:
9+
- CONFIG_BT_SMP=y
10+
- CONFIG_BT_USE_DEBUG_KEYS=y

0 commit comments

Comments
 (0)