tests: bluetooth: replace TinyCrypt with PSA in unit tests

Replace all references to TinyCrypt with PSA Crypto API in BT unit
tests.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This commit is contained in:
Valerio Setti 2024-10-29 06:13:45 +01:00 committed by Anas Nashif
commit 7c1b5059ca
26 changed files with 160 additions and 525 deletions

View file

@ -8,11 +8,10 @@ add_library(mocks STATIC
mocks/hci_core_expects.c
mocks/aes.c
mocks/aes_expects.c
mocks/hmac_prng.c
mocks/hmac_prng_expects.c
mocks/crypto_help_utils.c
mocks/prng.c
mocks/prng_expects.c
${ZEPHYR_BASE}/subsys/bluetooth/host/crypto_tc.c
${ZEPHYR_BASE}/subsys/bluetooth/host/crypto_psa.c
${ZEPHYR_BASE}/subsys/logging/log_minimal.c
${ZEPHYR_BASE}/subsys/bluetooth/common/bt_str.c
${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c
@ -24,7 +23,7 @@ target_include_directories(mocks PUBLIC
${ZEPHYR_BASE}/subsys/bluetooth/host
${ZEPHYR_BASE}/tests/bluetooth/host
${ZEPHYR_BASE}/tests/bluetooth/host/crypto/mocks
${ZEPHYR_BASE}/../modules/crypto/tinycrypt/lib/include
${ZEPHYR_MBEDTLS_MODULE_DIR}/include
)
target_link_libraries(mocks PRIVATE test_interface)

View file

@ -28,8 +28,8 @@ ZTEST_SUITE(bt_encrypt_be, NULL, NULL, NULL, NULL, NULL);
* Test bt_encrypt_be() succeeds
*
* Constraints:
* - tc_aes128_set_encrypt_key() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - tc_aes_encrypt() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - psa_import_key() succeeds and returns 'PSA_SUCCESS'.
* - psa_cipher_encrypt() succeeds and returns 'PSA_SUCCESS'.
*
* Expected behaviour:
* - bt_encrypt_be() returns 0 (success)
@ -41,12 +41,12 @@ ZTEST(bt_encrypt_be, test_bt_encrypt_be_succeeds)
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_SUCCESS;
tc_aes_encrypt_fake.return_val = TC_CRYPTO_SUCCESS;
psa_import_key_fake.return_val = PSA_SUCCESS;
psa_cipher_encrypt_fake.return_val = PSA_SUCCESS;
err = bt_encrypt_be(key, plaintext, enc_data);
expect_single_call_tc_aes_encrypt(enc_data);
expect_single_call_psa_cipher_encrypt(enc_data);
zassert_ok(err, "Unexpected error code '%d' was returned", err);
}

View file

@ -12,7 +12,7 @@
#include <host/crypto.h>
ZTEST_SUITE(bt_encrypt_le_invalid_cases, NULL, NULL, NULL, NULL, NULL);
ZTEST_SUITE(bt_encrypt_be_invalid_cases, NULL, NULL, NULL, NULL, NULL);
/*
* Test passing NULL reference for the key argument
@ -24,7 +24,7 @@ ZTEST_SUITE(bt_encrypt_le_invalid_cases, NULL, NULL, NULL, NULL, NULL);
* Expected behaviour:
* - An assertion is raised and execution stops
*/
ZTEST(bt_encrypt_le_invalid_cases, test_null_key_reference)
ZTEST(bt_encrypt_be_invalid_cases, test_null_key_reference)
{
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
@ -43,7 +43,7 @@ ZTEST(bt_encrypt_le_invalid_cases, test_null_key_reference)
* Expected behaviour:
* - An assertion is raised and execution stops
*/
ZTEST(bt_encrypt_le_invalid_cases, test_null_plaintext_reference)
ZTEST(bt_encrypt_be_invalid_cases, test_null_plaintext_reference)
{
const uint8_t key[16] = {0};
uint8_t enc_data[16] = {0};
@ -62,7 +62,7 @@ ZTEST(bt_encrypt_le_invalid_cases, test_null_plaintext_reference)
* Expected behaviour:
* - An assertion is raised and execution stops
*/
ZTEST(bt_encrypt_le_invalid_cases, test_null_enc_data_reference)
ZTEST(bt_encrypt_be_invalid_cases, test_null_enc_data_reference)
{
const uint8_t key[16] = {0};
const uint8_t plaintext[16] = {0};
@ -75,19 +75,19 @@ ZTEST(bt_encrypt_le_invalid_cases, test_null_enc_data_reference)
* Test bt_encrypt_le() fails when tc_aes128_set_encrypt_key() fails
*
* Constraints:
* - tc_aes128_set_encrypt_key() fails and returns 'TC_CRYPTO_FAIL'.
* - psa_import_key() fails and returns 'PSA_ERROR_GENERIC_ERROR'.
*
* Expected behaviour:
* - bt_encrypt_le() returns a negative error code '-EINVAL' (failure)
*/
ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes128_set_encrypt_key_fails)
ZTEST(bt_encrypt_be_invalid_cases, test_psa_import_key_fails)
{
int err;
const uint8_t key[16] = {0};
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_FAIL;
psa_import_key_fake.return_val = PSA_ERROR_GENERIC_ERROR;
err = bt_encrypt_le(key, plaintext, enc_data);
@ -98,23 +98,23 @@ ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes128_set_encrypt_key_fails)
* Test bt_encrypt_le() fails when tc_aes_encrypt() fails
*
* Constraints:
* - tc_aes128_set_encrypt_key() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - tc_aes_encrypt() fails and returns 'TC_CRYPTO_FAIL'.
* - psa_import_key() succeeds and returns 'PSA_SUCCESS'.
* - psa_cipher_encrypt() fails and returns 'PSA_ERROR_GENERIC_ERROR'.
*
* Expected behaviour:
* - bt_encrypt_le() returns a negative error code '-EINVAL' (failure)
*/
ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes_encrypt_fails)
ZTEST(bt_encrypt_be_invalid_cases, test_psa_cipher_encrypt_fails)
{
int err;
const uint8_t key[16] = {0};
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_SUCCESS;
tc_aes_encrypt_fake.return_val = TC_CRYPTO_FAIL;
psa_import_key_fake.return_val = PSA_SUCCESS;
psa_cipher_encrypt_fake.return_val = -EINVAL;
err = bt_encrypt_le(key, plaintext, enc_data);
zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}

View file

@ -41,12 +41,12 @@ ZTEST(bt_encrypt_le, test_bt_encrypt_le_succeeds)
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_SUCCESS;
tc_aes_encrypt_fake.return_val = TC_CRYPTO_SUCCESS;
psa_import_key_fake.return_val = PSA_SUCCESS;
psa_cipher_encrypt_fake.return_val = PSA_SUCCESS;
err = bt_encrypt_le(key, plaintext, enc_data);
expect_single_call_tc_aes_encrypt(enc_data);
expect_single_call_psa_cipher_encrypt(enc_data);
zassert_ok(err, "Unexpected error code '%d' was returned", err);
}

View file

@ -87,7 +87,7 @@ ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes128_set_encrypt_key_fails)
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_FAIL;
psa_import_key_fake.return_val = PSA_ERROR_GENERIC_ERROR;
err = bt_encrypt_le(key, plaintext, enc_data);
@ -98,8 +98,8 @@ ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes128_set_encrypt_key_fails)
* Test bt_encrypt_le() fails when tc_aes_encrypt() fails
*
* Constraints:
* - tc_aes128_set_encrypt_key() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - tc_aes_encrypt() fails and returns 'TC_CRYPTO_FAIL'.
* - psa_import_key() succeeds and returns 'PSA_SUCCESS'.
* - psa_cipher_encrypt() fails and returns '-EINVAL'.
*
* Expected behaviour:
* - bt_encrypt_le() returns a negative error code '-EINVAL' (failure)
@ -111,10 +111,10 @@ ZTEST(bt_encrypt_le_invalid_cases, test_tc_aes_encrypt_fails)
const uint8_t plaintext[16] = {0};
uint8_t enc_data[16] = {0};
tc_aes128_set_encrypt_key_fake.return_val = TC_CRYPTO_SUCCESS;
tc_aes_encrypt_fake.return_val = TC_CRYPTO_FAIL;
psa_import_key_fake.return_val = PSA_SUCCESS;
psa_cipher_encrypt_fake.return_val = -EINVAL;
err = bt_encrypt_le(key, plaintext, enc_data);
zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}

View file

@ -4,11 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "mocks/crypto_help_utils.h"
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
#include "mocks/prng.h"
#include "mocks/prng_expects.h"
#include <zephyr/bluetooth/crypto.h>
#include <zephyr/fff.h>
@ -21,7 +20,7 @@ DEFINE_FFF_GLOBALS;
static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
{
HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
HMAC_PRNG_FFF_FAKES_LIST(RESET_FAKE);
PRNG_FFF_FAKES_LIST(RESET_FAKE);
}
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
@ -57,74 +56,29 @@ ZTEST(bt_rand, test_bt_rand_succeeds_host_crypto_prng_disabled)
}
/*
* Test bt_rand() succeeds when tc_hmac_prng_generate() succeeds on the first call while
* Test bt_rand() succeeds when psa_generate_random() succeeds on the first call while
* 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled.
*
* Constraints:
* - 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled
* - tc_hmac_prng_generate() succeeds and returns 'TC_CRYPTO_SUCCESS' on the first call.
* - psa_generate_random() succeeds and returns 'PSA_SUCCESS' on the first call.
*
* Expected behaviour:
* - bt_rand() returns 0 (success)
*/
ZTEST(bt_rand, test_tc_hmac_prng_generate_succeeds_on_first_call)
ZTEST(bt_rand, test_psa_generate_random_succeeds_on_first_call)
{
int err;
uint8_t buf[16];
size_t buf_len = 16;
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
Z_TEST_SKIP_IFNDEF(CONFIG_BT_HOST_CRYPTO_PRNG);
tc_hmac_prng_generate_fake.return_val = TC_CRYPTO_SUCCESS;
psa_generate_random_fake.return_val = PSA_SUCCESS;
err = bt_rand(buf, buf_len);
expect_call_count_tc_hmac_prng_generate(1, buf, buf_len, hmac_prng);
zassert_ok(err, "Unexpected error code '%d' was returned", err);
}
static int tc_hmac_prng_generate_custom_fake(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
{
if (tc_hmac_prng_generate_fake.call_count == 1) {
return TC_HMAC_PRNG_RESEED_REQ;
}
return TC_CRYPTO_SUCCESS;
}
/*
* Test bt_rand() succeeds when tc_hmac_prng_generate() succeeds on the second call after a seeding
* request by tc_hmac_prng_generate() while 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled.
*
* Constraints:
* - 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled
* - tc_hmac_prng_generate() fails and returns 'TC_HMAC_PRNG_RESEED_REQ' on the first call.
* - tc_hmac_prng_generate() succeeds and returns 'TC_CRYPTO_SUCCESS' on the second call.
*
* Expected behaviour:
* - bt_rand() returns 0 (success)
*/
ZTEST(bt_rand, test_tc_hmac_prng_generate_succeeds_on_second_call)
{
int err;
uint8_t buf[16];
size_t buf_len = 16;
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
Z_TEST_SKIP_IFNDEF(CONFIG_BT_HOST_CRYPTO_PRNG);
tc_hmac_prng_generate_fake.custom_fake = tc_hmac_prng_generate_custom_fake;
/* This is to make prng_reseed() succeeds and return 0 */
bt_hci_le_rand_fake.return_val = 0;
tc_hmac_prng_reseed_fake.return_val = TC_CRYPTO_SUCCESS;
err = bt_rand(buf, buf_len);
expect_call_count_tc_hmac_prng_generate(2, buf, buf_len, hmac_prng);
expect_single_call_tc_hmac_prng_reseed(hmac_prng, 32, sizeof(int64_t));
expect_single_call_psa_generate_random(buf, buf_len);
zassert_ok(err, "Unexpected error code '%d' was returned", err);
}

View file

@ -5,11 +5,10 @@
*/
#include "host_mocks/assert.h"
#include "mocks/crypto_help_utils.h"
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
#include "mocks/prng.h"
#include "mocks/prng_expects.h"
#include <zephyr/bluetooth/crypto.h>
#include <zephyr/kernel.h>
@ -81,12 +80,12 @@ ZTEST(bt_rand_invalid_cases, test_bt_hci_le_rand_fails)
}
/*
* Test bt_rand() fails when tc_hmac_prng_generate() fails on the first call while
* Test bt_rand() fails when psa_generate_random() fails on the first call while
* 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled.
*
* Constraints:
* - 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled
* - tc_hmac_prng_generate() fails and returns 'TC_CRYPTO_FAIL' on the first call.
* - psa_generate_random() fails and returns '-EIO' on the first call.
*
* Expected behaviour:
* - bt_rand() returns a negative error code '-EIO' (failure)
@ -96,92 +95,14 @@ ZTEST(bt_rand_invalid_cases, test_tc_hmac_prng_generate_fails_on_first_call)
int err;
uint8_t buf[16];
size_t buf_len = 16;
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
Z_TEST_SKIP_IFNDEF(CONFIG_BT_HOST_CRYPTO_PRNG);
tc_hmac_prng_generate_fake.return_val = TC_CRYPTO_FAIL;
psa_generate_random_fake.return_val = -EIO;
err = bt_rand(buf, buf_len);
expect_call_count_tc_hmac_prng_generate(1, buf, buf_len, hmac_prng);
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}
/*
* Test bt_rand() fails when prng_reseed() fails on seeding request by tc_hmac_prng_generate()
* while 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled.
*
* Constraints:
* - 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled
* - tc_hmac_prng_generate() fails and returns 'TC_HMAC_PRNG_RESEED_REQ' on the first call.
* - prng_reseed() fails and returns a negative error code
*
* Expected behaviour:
* - bt_rand() returns a negative error code (failure)
*/
ZTEST(bt_rand_invalid_cases, test_prng_reseed_fails_on_seeding_request)
{
int err;
uint8_t buf[16];
size_t buf_len = 16;
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
Z_TEST_SKIP_IFNDEF(CONFIG_BT_HOST_CRYPTO_PRNG);
tc_hmac_prng_generate_fake.return_val = TC_HMAC_PRNG_RESEED_REQ;
/* This is to make prng_reseed() fails */
bt_hci_le_rand_fake.return_val = -1;
err = bt_rand(buf, buf_len);
expect_call_count_tc_hmac_prng_generate(1, buf, buf_len, hmac_prng);
zassert_true(err < 0, "Unexpected error code '%d' was returned", err);
}
static int tc_hmac_prng_generate_custom_fake(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
{
if (tc_hmac_prng_generate_fake.call_count == 1) {
return TC_HMAC_PRNG_RESEED_REQ;
}
return TC_CRYPTO_FAIL;
}
/*
* Test bt_rand() fails when tc_hmac_prng_generate() fails on the second call after a seeding
* request by tc_hmac_prng_generate() while 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled.
*
* Constraints:
* - 'CONFIG_BT_HOST_CRYPTO_PRNG' is enabled
* - tc_hmac_prng_generate() fails and returns 'TC_HMAC_PRNG_RESEED_REQ' on the first call.
* - tc_hmac_prng_generate() fails and returns 'TC_CRYPTO_FAIL' on the second call.
*
* Expected behaviour:
* - bt_rand() returns a negative error code '-EIO' (failure)
*/
ZTEST(bt_rand_invalid_cases, test_tc_hmac_prng_generate_fails_on_second_call)
{
int err;
uint8_t buf[16];
size_t buf_len = 16;
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
Z_TEST_SKIP_IFNDEF(CONFIG_BT_HOST_CRYPTO_PRNG);
tc_hmac_prng_generate_fake.custom_fake = tc_hmac_prng_generate_custom_fake;
/* This is to make prng_reseed() succeeds and return 0 */
bt_hci_le_rand_fake.return_val = 0;
tc_hmac_prng_reseed_fake.return_val = TC_CRYPTO_SUCCESS;
err = bt_rand(buf, buf_len);
expect_call_count_tc_hmac_prng_generate(2, buf, buf_len, hmac_prng);
expect_single_call_tc_hmac_prng_reseed(hmac_prng, 32, sizeof(int64_t));
expect_single_call_psa_generate_random(buf, buf_len);
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}

View file

@ -7,5 +7,10 @@
#include <zephyr/kernel.h>
#include "mocks/aes.h"
DEFINE_FAKE_VALUE_FUNC(int, tc_aes_encrypt, uint8_t *, const uint8_t *, const TCAesKeySched_t);
DEFINE_FAKE_VALUE_FUNC(int, tc_aes128_set_encrypt_key, TCAesKeySched_t, const uint8_t *);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_crypto_init);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_generate_random, uint8_t *, size_t);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_import_key, const psa_key_attributes_t *, const uint8_t *,
size_t, mbedtls_svc_key_id_t *);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_cipher_encrypt, mbedtls_svc_key_id_t, psa_algorithm_t,
const uint8_t *, size_t, uint8_t *, size_t, size_t *);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_destroy_key, mbedtls_svc_key_id_t);

View file

@ -6,13 +6,20 @@
#include <zephyr/kernel.h>
#include <zephyr/fff.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/constants.h>
#include <psa/crypto.h>
/* List of fakes used by this unit tester */
#define AES_FFF_FAKES_LIST(FAKE) \
FAKE(tc_aes_encrypt) \
FAKE(tc_aes128_set_encrypt_key)
FAKE(psa_crypto_init) \
FAKE(psa_generate_random) \
FAKE(psa_import_key) \
FAKE(psa_cipher_encrypt) \
FAKE(psa_destroy_key)
DECLARE_FAKE_VALUE_FUNC(int, tc_aes_encrypt, uint8_t *, const uint8_t *, const TCAesKeySched_t);
DECLARE_FAKE_VALUE_FUNC(int, tc_aes128_set_encrypt_key, TCAesKeySched_t, const uint8_t *);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_crypto_init);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_generate_random, uint8_t *, size_t);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_import_key, const psa_key_attributes_t *, const uint8_t *,
size_t, mbedtls_svc_key_id_t *);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_cipher_encrypt, mbedtls_svc_key_id_t, psa_algorithm_t,
const uint8_t *, size_t, uint8_t *, size_t, size_t *);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_destroy_key, mbedtls_svc_key_id_t);

View file

@ -8,17 +8,19 @@
#include "mocks/aes.h"
#include "mocks/aes_expects.h"
void expect_single_call_tc_aes_encrypt(uint8_t *out)
void expect_single_call_psa_cipher_encrypt(uint8_t *out)
{
const char *func_name = "tc_aes_encrypt";
const char *func_name = "psa_cipher_encrypt";
zassert_equal(tc_aes_encrypt_fake.call_count, 1, "'%s()' was called more than once",
zassert_equal(psa_cipher_encrypt_fake.call_count, 1, "'%s()' was called more than once",
func_name);
zassert_equal_ptr(tc_aes_encrypt_fake.arg0_val, out,
"'%s()' was called with incorrect '%s' value", func_name, "out");
zassert_not_null(tc_aes_encrypt_fake.arg1_val,
"'%s()' was called with incorrect '%s' value", func_name, "in");
zassert_not_null(tc_aes_encrypt_fake.arg2_val,
"'%s()' was called with incorrect '%s' value", func_name, "s");
zassert_not_equal(psa_cipher_encrypt_fake.arg1_val, 0,
"'%s()' was called with incorrect '%s' value", func_name, "arg1");
zassert_not_equal(psa_cipher_encrypt_fake.arg3_val, 0,
"'%s()' was called with incorrect '%s' value", func_name, "arg3");
zassert_equal_ptr(psa_cipher_encrypt_fake.arg4_val, out,
"'%s()' was called with incorrect '%s' value", func_name, "arg4");
zassert_not_equal(psa_cipher_encrypt_fake.arg5_val, 0,
"'%s()' was called with incorrect '%s' value", func_name, "arg5");
}

View file

@ -7,9 +7,9 @@
#include <zephyr/kernel.h>
/*
* Validate expected behaviour when tc_aes_encrypt() is called
* Validate expected behaviour when psa_cipher_encrypt() is called
*
* Expected behaviour:
* - tc_aes_encrypt() to be called once with correct parameters
* - psa_cipher_encrypt() to be called once with correct parameters
*/
void expect_single_call_tc_aes_encrypt(uint8_t *out);
void expect_single_call_psa_cipher_encrypt(uint8_t *out);

View file

@ -1,9 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <host/crypto.h>
#include "crypto_help_utils.h"

View file

@ -1,10 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <tinycrypt/hmac_prng.h>
/* crypto.c declarations */
struct tc_hmac_prng_struct *bt_crypto_get_hmac_prng_instance(void);

View file

@ -1,13 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include "mocks/hmac_prng.h"
DEFINE_FAKE_VALUE_FUNC(int, tc_hmac_prng_init, TCHmacPrng_t, const uint8_t *, unsigned int);
DEFINE_FAKE_VALUE_FUNC(int, tc_hmac_prng_reseed, TCHmacPrng_t, const uint8_t *, unsigned int,
const uint8_t *, unsigned int);
DEFINE_FAKE_VALUE_FUNC(int, tc_hmac_prng_generate, uint8_t *, unsigned int, TCHmacPrng_t);

View file

@ -1,21 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/fff.h>
#include <tinycrypt/hmac_prng.h>
#include <tinycrypt/constants.h>
/* List of fakes used by this unit tester */
#define HMAC_PRNG_FFF_FAKES_LIST(FAKE) \
FAKE(tc_hmac_prng_init) \
FAKE(tc_hmac_prng_reseed) \
FAKE(tc_hmac_prng_generate)
DECLARE_FAKE_VALUE_FUNC(int, tc_hmac_prng_init, TCHmacPrng_t, const uint8_t *, unsigned int);
DECLARE_FAKE_VALUE_FUNC(int, tc_hmac_prng_reseed, TCHmacPrng_t, const uint8_t *, unsigned int,
const uint8_t *, unsigned int);
DECLARE_FAKE_VALUE_FUNC(int, tc_hmac_prng_generate, uint8_t *, unsigned int, TCHmacPrng_t);

View file

@ -1,61 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
void expect_single_call_tc_hmac_prng_init(TCHmacPrng_t prng, unsigned int plen)
{
const char *func_name = "tc_hmac_prng_init";
zassert_equal(tc_hmac_prng_init_fake.call_count, 1, "'%s()' was called more than once",
func_name);
zassert_equal_ptr(tc_hmac_prng_init_fake.arg0_val, prng,
"'%s()' was called with incorrect '%s' value", func_name, "prng");
zassert_not_null(tc_hmac_prng_init_fake.arg1_val,
"'%s()' was called with incorrect '%s' value", func_name, "buffer");
zassert_equal(tc_hmac_prng_init_fake.arg2_val, plen,
"'%s()' was called with incorrect '%s' value", func_name, "plen");
}
void expect_single_call_tc_hmac_prng_reseed(TCHmacPrng_t prng, unsigned int seedlen,
unsigned int additionallen)
{
const char *func_name = "tc_hmac_prng_reseed";
zassert_equal(tc_hmac_prng_reseed_fake.call_count, 1, "'%s()' was called more than once",
func_name);
zassert_equal_ptr(tc_hmac_prng_reseed_fake.arg0_val, prng,
"'%s()' was called with incorrect '%s' value", func_name, "prng");
zassert_not_null(tc_hmac_prng_reseed_fake.arg1_val,
"'%s()' was called with incorrect '%s' value", func_name, "seed");
zassert_equal(tc_hmac_prng_reseed_fake.arg2_val, seedlen,
"'%s()' was called with incorrect '%s' value", func_name, "seedlen");
zassert_not_null(tc_hmac_prng_reseed_fake.arg3_val,
"'%s()' was called with incorrect '%s' value", func_name,
"additional_input");
zassert_equal(tc_hmac_prng_reseed_fake.arg4_val, additionallen,
"'%s()' was called with incorrect '%s' value", func_name, "additionallen");
}
void expect_call_count_tc_hmac_prng_generate(int call_count, uint8_t *out, unsigned int outlen,
TCHmacPrng_t prng)
{
const char *func_name = "tc_hmac_prng_generate";
zassert_equal(tc_hmac_prng_generate_fake.call_count, call_count,
"'%s()' was called more than once", func_name);
zassert_equal_ptr(tc_hmac_prng_generate_fake.arg0_val, out,
"'%s()' was called with incorrect '%s' value", func_name, "out");
zassert_equal(tc_hmac_prng_generate_fake.arg1_val, outlen,
"'%s()' was called with incorrect '%s' value", func_name, "outlen");
zassert_equal_ptr(tc_hmac_prng_generate_fake.arg2_val, prng,
"'%s()' was called with incorrect '%s' value", func_name, "prng");
}

View file

@ -1,33 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
/*
* Validate expected behaviour when tc_hmac_prng_init() is called
*
* Expected behaviour:
* - tc_hmac_prng_init() to be called once with correct parameters
*/
void expect_single_call_tc_hmac_prng_init(TCHmacPrng_t prng, unsigned int plen);
/*
* Validate expected behaviour when tc_hmac_prng_reseed() is called
*
* Expected behaviour:
* - tc_hmac_prng_reseed() to be called once with correct parameters
*/
void expect_single_call_tc_hmac_prng_reseed(TCHmacPrng_t prng, unsigned int seedlen,
unsigned int additionallen);
/*
* Validate expected behaviour when tc_hmac_prng_generate() is called
*
* Expected behaviour:
* - tc_hmac_prng_generate() to be called once with correct parameters
*/
void expect_call_count_tc_hmac_prng_generate(int call_count, uint8_t *out, unsigned int outlen,
TCHmacPrng_t prng);

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include "mocks/prng.h"
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_crypto_init);
DEFINE_FAKE_VALUE_FUNC(psa_status_t, psa_generate_random, uint8_t *, size_t);

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/fff.h>
#include <psa/crypto.h>
/* List of fakes used by this unit tester */
#define PRNG_FFF_FAKES_LIST(FAKE) \
FAKE(psa_crypto_init) \
FAKE(psa_generate_random)
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_crypto_init);
DECLARE_FAKE_VALUE_FUNC(psa_status_t, psa_generate_random, uint8_t *, size_t);

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include "mocks/prng.h"
#include "mocks/prng_expects.h"
void expect_single_call_tc_psa_crypto_init(void)
{
const char *func_name = "psa_crypto_init";
zassert_equal(psa_crypto_init_fake.call_count, 1, "'%s()' was called more than once",
func_name);
}
void expect_single_call_psa_generate_random(uint8_t *out, size_t outlen)
{
const char *func_name = "psa_generate_random";
zassert_equal(psa_generate_random_fake.call_count, 1,
"'%s()' was called more than once", func_name);
zassert_equal_ptr(psa_generate_random_fake.arg0_val, out,
"'%s()' was called with incorrect '%s' value", func_name, "out");
zassert_equal(psa_generate_random_fake.arg1_val, outlen,
"'%s()' was called with incorrect '%s' value", func_name, "outlen");
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
/*
* Validate expected behaviour when psa_crypto_init() is called
*
* Expected behaviour:
* - psa_crypto_init() to be called once with correct parameters
*/
void expect_single_call_tc_psa_crypto_init(void);
/*
* Validate expected behaviour when psa_generate_random() is called
*
* Expected behaviour:
* - psa_generate_random() to be called once with correct parameters
*/
void expect_single_call_psa_generate_random(uint8_t *out, unsigned int outlen);

View file

@ -1,16 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(prng_init)
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host host_mocks)
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host/crypto mocks)
target_sources(testbinary PRIVATE
src/main.c
src/test_suite_invalid_inputs.c
)
target_link_libraries(testbinary PRIVATE mocks host_mocks)

View file

@ -1,8 +0,0 @@
CONFIG_ZTEST=y
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_MAX_PAIRED=7
CONFIG_ASSERT=y
CONFIG_ASSERT_LEVEL=2
CONFIG_ASSERT_VERBOSE=y
CONFIG_ASSERT_ON_ERRORS=y

View file

@ -1,58 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mocks/crypto_help_utils.h"
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
#include <zephyr/fff.h>
#include <zephyr/kernel.h>
#include <host/crypto.h>
DEFINE_FFF_GLOBALS;
static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
{
HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
HMAC_PRNG_FFF_FAKES_LIST(RESET_FAKE);
}
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
ZTEST_SUITE(prng_init, NULL, NULL, NULL, NULL, NULL);
/*
* Test prng_init() succeeds
*
* Constraints:
* - bt_hci_le_rand() succeeds and returns 0 (success)
* - tc_hmac_prng_init() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - tc_hmac_prng_reseed() succeeds and returns 'TC_CRYPTO_SUCCESS'.
*
* Expected behaviour:
* - prng_init() returns 0 (success)
*/
ZTEST(prng_init, test_prng_init_succeeds)
{
int err;
uint8_t expected_args_history[] = {8, 32};
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
bt_hci_le_rand_fake.return_val = 0;
tc_hmac_prng_init_fake.return_val = TC_CRYPTO_SUCCESS;
tc_hmac_prng_reseed_fake.return_val = TC_CRYPTO_SUCCESS;
err = prng_init();
expect_call_count_bt_hci_le_rand(2, expected_args_history);
expect_single_call_tc_hmac_prng_init(hmac_prng, 8);
expect_single_call_tc_hmac_prng_reseed(hmac_prng, 32, sizeof(int64_t));
zassert_ok(err, "Unexpected error code '%d' was returned", err);
}

View file

@ -1,98 +0,0 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "host_mocks/assert.h"
#include "mocks/crypto_help_utils.h"
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
#include <zephyr/kernel.h>
#include <host/crypto.h>
ZTEST_SUITE(prng_init_invalid_cases, NULL, NULL, NULL, NULL, NULL);
/*
* Test prng_init() fails when bt_hci_le_rand() fails
*
* Constraints:
* - bt_hci_le_rand() fails and returns a negative error code.
*
* Expected behaviour:
* - prng_init() returns a negative error code (failure)
*/
ZTEST(prng_init_invalid_cases, test_bt_hci_le_rand_fails)
{
int err;
uint8_t expected_args_history[] = {8};
bt_hci_le_rand_fake.return_val = -1;
err = prng_init();
expect_call_count_bt_hci_le_rand(1, expected_args_history);
zassert_true(err < 0, "Unexpected error code '%d' was returned", err);
}
/*
* Test prng_init() fails when tc_hmac_prng_init() fails
*
* Constraints:
* - bt_hci_le_rand() succeeds and returns 0 (success)
* - tc_hmac_prng_init() fails and returns 'TC_CRYPTO_FAIL'.
*
* Expected behaviour:
* - prng_init() returns a negative error code '-EIO' (failure)
*/
ZTEST(prng_init_invalid_cases, test_tc_hmac_prng_init_fails)
{
int err;
uint8_t expected_args_history[] = {8};
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
bt_hci_le_rand_fake.return_val = 0;
tc_hmac_prng_init_fake.return_val = TC_CRYPTO_FAIL;
err = prng_init();
expect_call_count_bt_hci_le_rand(1, expected_args_history);
expect_single_call_tc_hmac_prng_init(hmac_prng, 8);
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}
/*
* Test prng_init() fails when prng_reseed() fails
*
* Constraints:
* - bt_hci_le_rand() succeeds and returns 0 (success)
* - tc_hmac_prng_init() succeeds and returns 'TC_CRYPTO_SUCCESS'.
* - tc_hmac_prng_reseed() fails and returns 'TC_CRYPTO_FAIL'.
*
* Expected behaviour:
* - prng_init() returns a negative error code '-EIO' (failure)
*/
ZTEST(prng_init_invalid_cases, test_prng_reseed_fails)
{
int err;
uint8_t expected_args_history[] = {8, 32};
struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();
bt_hci_le_rand_fake.return_val = 0;
tc_hmac_prng_init_fake.return_val = TC_CRYPTO_SUCCESS;
tc_hmac_prng_reseed_fake.return_val = TC_CRYPTO_FAIL;
err = prng_init();
expect_call_count_bt_hci_le_rand(2, expected_args_history);
expect_single_call_tc_hmac_prng_init(hmac_prng, 8);
expect_single_call_tc_hmac_prng_reseed(hmac_prng, 32, sizeof(int64_t));
zassert_true(err == -EIO, "Unexpected error code '%d' was returned", err);
}

View file

@ -1,7 +0,0 @@
common:
tags:
- bluetooth
- host
tests:
bluetooth.host.prng_init.default:
type: unit