1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * Simple test to show support for secp256r1 curve with either MbedTLS and
9  * TinyCrypt. Operations are pretty simple:
10  * - generate 2 keys
11  * - perform key agreement.
12  * The idea is to provide a way to compare memory footprint for the very
13  * same kind of implemented feature between the 2 crypto libraries.
14  */
15 
16 #include <zephyr/ztest.h>
17 
18 #if defined(CONFIG_MBEDTLS)
19 #if defined(CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW)
20 #include "p256-m.h"
21 #else /* CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW */
22 #include "psa/crypto.h"
23 #endif /* CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW */
24 #else /* CONFIG_MBEDTLS */
25 #include "zephyr/random/random.h"
26 #include "tinycrypt/constants.h"
27 #include "tinycrypt/ecc.h"
28 #include "tinycrypt/ecc_dh.h"
29 #endif /* CONFIG_MBEDTLS */
30 
31 #if defined(CONFIG_MBEDTLS)
32 #if defined(CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW)
ZTEST_USER(test_fn,test_mbedtls)33 ZTEST_USER(test_fn, test_mbedtls)
34 {
35 	int ret;
36 	uint8_t public_key_1[64], public_key_2[64];
37 	uint8_t private_key_1[32], private_key_2[32];
38 	uint8_t secret[32];
39 
40 	ret = p256_gen_keypair(private_key_1, public_key_1);
41 	zassert_equal(ret, P256_SUCCESS, "Unable to generate 1st EC key (%d)", ret);
42 
43 	ret = p256_gen_keypair(private_key_2, public_key_2);
44 	zassert_equal(ret, P256_SUCCESS, "Unable to generate 2nd EC key (%d)", ret);
45 
46 	ret = p256_ecdh_shared_secret(secret, private_key_1, public_key_2);
47 	zassert_equal(ret, P256_SUCCESS, "Unable to compute the shared secret (%d)", ret);
48 }
49 #else /* CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW */
ZTEST_USER(test_fn,test_mbedtls)50 ZTEST_USER(test_fn, test_mbedtls)
51 {
52 	psa_status_t status;
53 	psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
54 	mbedtls_svc_key_id_t key_id_1 = MBEDTLS_SVC_KEY_ID_INIT;
55 	mbedtls_svc_key_id_t key_id_2 = MBEDTLS_SVC_KEY_ID_INIT;
56 	uint8_t public_key_2[65];
57 	size_t public_key_2_len;
58 	uint8_t secret[32];
59 	size_t secret_len;
60 
61 	psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
62 	psa_set_key_bits(&key_attr, 256);
63 	psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
64 	psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);
65 
66 	status = psa_generate_key(&key_attr, &key_id_1);
67 	zassert_equal(status, PSA_SUCCESS, "Unable to generate 1st EC key (%d)", status);
68 
69 	status = psa_generate_key(&key_attr, &key_id_2);
70 	zassert_equal(status, PSA_SUCCESS, "Unable to generate 1st EC key (%d)", status);
71 
72 	status = psa_export_public_key(key_id_2, public_key_2, sizeof(public_key_2),
73 					&public_key_2_len);
74 	zassert_equal(status, PSA_SUCCESS, "Unable to export public key (%d)", status);
75 
76 	status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id_1, public_key_2, public_key_2_len,
77 					secret, sizeof(secret), &secret_len);
78 	zassert_equal(status, PSA_SUCCESS, "Unable to compute shared secret (%d)", status);
79 }
80 #endif /* CONFIG_MBEDTLS_PSA_P256M_DRIVER_RAW */
81 #else /* CONFIG_MBEDTLS */
ZTEST_USER(test_fn,test_tinycrypt)82 ZTEST_USER(test_fn, test_tinycrypt)
83 {
84 	uint8_t public_key_1[64], public_key_2[64];
85 	uint8_t private_key_1[32], private_key_2[32];
86 	uint8_t secret[32];
87 	int ret;
88 
89 	ret = uECC_make_key(public_key_1, private_key_1, &curve_secp256r1);
90 	zassert_equal(ret, TC_CRYPTO_SUCCESS, "Unable to generate 1st EC key (%d)", ret);
91 
92 	ret = uECC_make_key(public_key_2, private_key_2, &curve_secp256r1);
93 	zassert_equal(ret, TC_CRYPTO_SUCCESS, "Unable to generate 2nd EC key (%d)", ret);
94 
95 	ret = uECC_valid_public_key(public_key_2, &curve_secp256r1);
96 	zassert_equal(ret, 0, "Invalid public key (%d)", ret);
97 
98 	ret = uECC_shared_secret(public_key_2, private_key_1, secret, &curve_secp256r1);
99 	zassert_equal(ret, TC_CRYPTO_SUCCESS, "Unable to compute the shared secret (%d)", ret);
100 }
101 
default_CSPRNG(uint8_t * dst,unsigned int len)102 int default_CSPRNG(uint8_t *dst, unsigned int len)
103 {
104 	return (sys_csrand_get(dst, len) == 0);
105 }
106 #endif /* CONFIG_MBEDTLS */
107 
108 ZTEST_SUITE(test_fn, NULL, NULL, NULL, NULL, NULL);
109