diff --git a/common/ta_errors.c b/common/ta_errors.c index 3e0468eb..9112d386 100644 --- a/common/ta_errors.c +++ b/common/ta_errors.c @@ -204,6 +204,19 @@ const char* ta_error_to_string(status_t err) { return "Error occurred when reading message from CAN BUS socket"; case SC_ENDPOINT_CAN_CLOSE_ERROR: return "Error occurred when closing CAN BUS socket"; + + // Crypto + case SC_CRYPTO_RAND_INIT: + return "Failed to generate random number generator"; + case SC_CRYPTO_GEN_KEY: + return "Failed to generate ECDH public key"; + case SC_CRYPTO_COMPUTE_SECRET: + return "Failed to compute ECDH shared secret"; + case SC_CRYPTO_HASH: + return "Failed to hash"; + case SC_CRYPTO_ECDSA_SIGN: + return "Failed to sign with ECDSA"; + default: return "Unknown error."; } diff --git a/common/ta_errors.h b/common/ta_errors.h index f32a2994..8530bdaf 100644 --- a/common/ta_errors.h +++ b/common/ta_errors.h @@ -57,6 +57,7 @@ extern "C" { #define SC_MODULE_STORAGE (0x0A << SC_MODULE_SHIFT) #define SC_MODULE_CORE (0x0B << SC_MODULE_SHIFT) #define SC_MODULE_ENDPOINT (0x0C << SC_MODULE_SHIFT) +#define SC_MODULE_CRYPTO (0x0D << SC_MODULE_SHIFT) /** @} */ /** @name serverity code */ @@ -269,6 +270,18 @@ typedef enum { SC_ENDPOINT_CAN_CLOSE_ERROR = 0x0F | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL, /**< Failed to close CAN BUS socket */ + // Crypto module + SC_CRYPTO_RAND_INIT = 0x01 | SC_MODULE_CRYPTO | SC_SEVERITY_FATAL, + /**< Failed to generate random number generator */ + SC_CRYPTO_GEN_KEY = 0x02 | SC_MODULE_CRYPTO | SC_SEVERITY_FATAL, + /**< Failed to generate ECDH public key, or ECDSA key pair */ + SC_CRYPTO_COMPUTE_SECRET = 0x03 | SC_MODULE_CRYPTO | SC_SEVERITY_FATAL, + /**< Failed to compute ECDH shared secret */ + SC_CRYPTO_HASH = 0x04 | SC_MODULE_CRYPTO | SC_SEVERITY_FATAL, + /**< Failed to hash */ + SC_CRYPTO_ECDSA_SIGN = 0x05 | SC_MODULE_CRYPTO | SC_SEVERITY_FATAL, + /**< Failed to sign with ECDSA */ + } status_t; typedef enum { diff --git a/crypto/BUILD b/crypto/BUILD new file mode 100644 index 00000000..2adfd6c8 --- /dev/null +++ b/crypto/BUILD @@ -0,0 +1,34 @@ +cc_library( + name = "ecdh", + srcs = ["ecdh.c"], + hdrs = ["ecdh.h"], + visibility = ["//visibility:public"], + deps = [ + ":randomness", + "//common", + "@mbedtls", + ], +) + +cc_library( + name = "ecdsa", + srcs = ["ecdsa.c"], + hdrs = ["ecdsa.h"], + visibility = ["//visibility:public"], + deps = [ + ":randomness", + "//common", + "@mbedtls", + ], +) + +cc_library( + name = "randomness", + srcs = ["randomness.c"], + hdrs = ["randomness.h"], + visibility = ["//visibility:public"], + deps = [ + "//common", + "@mbedtls", + ], +) diff --git a/crypto/ecdh.c b/crypto/ecdh.c new file mode 100644 index 00000000..1ccdb79d --- /dev/null +++ b/crypto/ecdh.c @@ -0,0 +1,60 @@ +#include "ecdh.h" + +#define logger_id crypto_logger_id + +status_t ecdh_gen_public_key(mbedtls_ecdh_context *ctx, mbedtls_ctr_drbg_context *ctr_drbg, unsigned char *pkey) { + int ret = 1; + status_t sc = SC_OK; + + ret = mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_CURVE25519); + if (ret != 0) { + ta_log_error("mbedtls_ecp_group_load returned %d\n", ret); + sc = SC_CRYPTO_GEN_KEY; + goto exit; + } + + ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, mbedtls_ctr_drbg_random, ctr_drbg); + if (ret != 0) { + ta_log_error("mbedtls_ecdh_gen_public returned %d\n", ret); + sc = SC_CRYPTO_GEN_KEY; + goto exit; + } + + ret = mbedtls_mpi_write_binary(&ctx->Q.X, pkey, SHARE_DATA_LEN); + if (ret != 0) { + ta_log_error("mbedtls_mpi_write_binary returned %d\n", ret); + sc = SC_CRYPTO_GEN_KEY; + } + +exit: + return sc; +} + +status_t ecdh_compute_shared_secret(mbedtls_ecdh_context *ctx, mbedtls_ctr_drbg_context *ctr_drbg, + unsigned char *input_shared_data) { + int ret = 1; + status_t sc = SC_OK; + + ret = mbedtls_mpi_lset(&ctx->Qp.Z, 1); + if (ret != 0) { + ta_log_error("mbedtls_mpi_lset returned %d\n", ret); + sc = SC_CRYPTO_COMPUTE_SECRET; + goto exit; + } + + ret = mbedtls_mpi_read_binary(&ctx->Qp.X, input_shared_data, SHARE_DATA_LEN); + if (ret != 0) { + ta_log_error("mbedtls_mpi_read_binary returned %d\n", ret); + sc = SC_CRYPTO_COMPUTE_SECRET; + goto exit; + } + + ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, mbedtls_ctr_drbg_random, ctr_drbg); + if (ret != 0) { + ta_log_error("mbedtls_ecdh_compute_shared returned %d\n", ret); + sc = SC_CRYPTO_COMPUTE_SECRET; + } + +exit: + return sc; +} diff --git a/crypto/ecdh.h b/crypto/ecdh.h new file mode 100644 index 00000000..47fffb5f --- /dev/null +++ b/crypto/ecdh.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 BiiLabs Co., Ltd. and Contributors + * All Rights Reserved. + * This is free software; you can redistribute it and/or modify it under the + * terms of the MIT license. A copy of the license can be found in the file + * "LICENSE" at the root of this distribution. + */ + +#ifndef ECDH_ECDH_H +#define ECDH_ECDH_H + +#include "common/logger.h" +#include "common/ta_errors.h" +#include "mbedtls/config.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/entropy.h" +#include "mbedtls/platform.h" +#include "randomness.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SHARE_DATA_LEN 32 + +/** + * @brief Initialize ECDH context and generate ECDH keypair + * + * @param[in] ctx ECDH context + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * @param[out] pkey Output public key which would be sent to counterpart + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ecdh_gen_public_key(mbedtls_ecdh_context *ctx, mbedtls_ctr_drbg_context *ctr_drbg, unsigned char *pkey); + +/** + * @brief Compute the shared secret by Diffie–Hellman key exchange protocol + * + * @param[in] ctx ECDH context + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * @param[in] input_shared_data The public key sent by counterpart + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ecdh_compute_shared_secret(mbedtls_ecdh_context *ctx, mbedtls_ctr_drbg_context *ctr_drbg, + unsigned char *input_shared_data); + +#ifdef __cplusplus +} +#endif + +#endif // ECDH_ECDH_H diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c new file mode 100644 index 00000000..ea18634f --- /dev/null +++ b/crypto/ecdsa.c @@ -0,0 +1,48 @@ +#include "ecdsa.h" + +#define logger_id crypto_logger_id + +static void dump_buf(char *title, unsigned char *buf, const int len) { + char dump[len + 1]; + for (int i = 0; i < len; i++) { + dump[i * 2] = "0123456789ABCDEF"[buf[i] / 16]; + dump[i * 2 + 1] = "0123456789ABCDEF"[buf[i] % 16]; + } + ta_log_debug("%s%s\n", title, dump); +} + +status_t ecdsa_gen_key_pair(mbedtls_ecdsa_context *ctx_sign, mbedtls_ctr_drbg_context *ctr_drbg) { + int ret = 1; + status_t sc = SC_OK; + + if ((ret = mbedtls_ecdsa_genkey(ctx_sign, MBEDTLS_ECP_DP_SECP192R1, mbedtls_ctr_drbg_random, ctr_drbg)) != 0) { + ta_log_error("mbedtls_ecdsa_genkey returned %d\n", ret); + sc = SC_CRYPTO_GEN_KEY; + } + + return sc; +} + +status_t compute_sha256(unsigned char *msg, const int msg_len, unsigned char *hash) { + int ret = 1; + status_t sc = SC_OK; + if ((ret = mbedtls_sha256_ret(msg, msg_len, hash, 0)) != 0) { + ta_log_error("mbedtls_sha256_ret returned %d\n", ret); + sc = SC_CRYPTO_HASH; + } + + return sc; +} + +status_t ecdsa_sign_msg(mbedtls_ecdsa_context *ctx_sign, mbedtls_ctr_drbg_context *ctr_drbg, unsigned char *hash, + const uint16_t hash_len, unsigned char *sig, size_t *sig_len) { + int ret = 1; + status_t sc = SC_OK; + if ((ret = mbedtls_ecdsa_write_signature(ctx_sign, MBEDTLS_MD_SHA256, hash, hash_len, sig, sig_len, + mbedtls_ctr_drbg_random, ctr_drbg)) != 0) { + ta_log_error("mbedtls_ecdsa_write_signature returned %d\n", ret); + sc = SC_CRYPTO_ECDSA_SIGN; + } + + return sc; +} diff --git a/crypto/ecdsa.h b/crypto/ecdsa.h new file mode 100644 index 00000000..b7779df9 --- /dev/null +++ b/crypto/ecdsa.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 BiiLabs Co., Ltd. and Contributors + * All Rights Reserved. + * This is free software; you can redistribute it and/or modify it under the + * terms of the MIT license. A copy of the license can be found in the file + * "LICENSE" at the root of this distribution. + */ + +#include "mbedtls/config.h" +#include "mbedtls/platform.h" + +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/ecdsa.h" +#include "mbedtls/entropy.h" +#include "mbedtls/sha256.h" + +#include + +#include "common/logger.h" +#include "common/ta_errors.h" +#include "randomness.h" + +#define SHA256_LEN 32 + +/** + * @brief Generate ECDSA key pair + * + * @param[in] ctx_sign ECDSA context for signing + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ecdsa_gen_key_pair(mbedtls_ecdsa_context *ctx_sign, mbedtls_ctr_drbg_context *ctr_drbg); + +/** + * @brief Compute SHA256 + * + * @param[in] msg Message is going to be hashed + * @param[in] msg_len The length of message + * @param[out] hash The output hash result + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t compute_sha256(unsigned char *msg, const int msg_len, unsigned char *hash); + +/** + * @brief Sign messega with ECDSA + * + * @param[in] ctx_sign ECDSA context for signing + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * @param[in] input The input string + * @param[in] input_len The length of input string + * @param[out] sig Output signed message + * @param[out] sig_len The length of signed message + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ecdsa_sign_msg(mbedtls_ecdsa_context *ctx_sign, mbedtls_ctr_drbg_context *ctr_drbg, unsigned char *input, + const uint16_t input_len, unsigned char *sig, size_t *sig_len); \ No newline at end of file diff --git a/crypto/randomness.c b/crypto/randomness.c new file mode 100644 index 00000000..32da3cad --- /dev/null +++ b/crypto/randomness.c @@ -0,0 +1,33 @@ +#include "randomness.h" + +#define CRYPTO_LOGGER "crypto" +#define logger_id crypto_logger_id + +void crypto_logger_init() { logger_id = logger_helper_enable(CRYPTO_LOGGER, LOGGER_DEBUG, true); } + +int crypto_logger_release() { + logger_helper_release(logger_id); + return 0; +} + +status_t rand_num_gen_init(mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg, char *rand_seed, + uint16_t seed_len) { + int ret = 1; + status_t sc = SC_OK; + + mbedtls_ctr_drbg_init(ctr_drbg); + mbedtls_entropy_init(entropy); + + if ((ret = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy, (const unsigned char *)rand_seed, + seed_len)) != 0) { + ta_log_error("mbedtls_ctr_drbg_seed returned %d\n", ret); + sc = SC_CRYPTO_RAND_INIT; + } + + return sc; +} + +void rand_num_gen_release(mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg) { + mbedtls_ctr_drbg_free(ctr_drbg); + mbedtls_entropy_free(entropy); +} diff --git a/crypto/randomness.h b/crypto/randomness.h new file mode 100644 index 00000000..65d875cf --- /dev/null +++ b/crypto/randomness.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 BiiLabs Co., Ltd. and Contributors + * All Rights Reserved. + * This is free software; you can redistribute it and/or modify it under the + * terms of the MIT license. A copy of the license can be found in the file + * "LICENSE" at the root of this distribution. + */ + +#ifndef ECDH_COMMON_H +#define ECDH_COMMON_H + +#include "common/logger.h" +#include "common/ta_errors.h" +#include "mbedtls/config.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/entropy.h" +#include "mbedtls/platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +logger_id_t crypto_logger_id; + +/** + * Initialize logger for ECDH + */ +void crypto_logger_init(); + +/** + * Release logger + * + * @return + * - zero on success + * - EXIT_FAILURE on error + */ +int crypto_logger_release(); + +typedef struct rand_gen_s { + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; +} rand_gen_t; + +/** + * @brief Initialize mbedtls random number generator + * + * @param[in] entropy Entropy contrext for randomess + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * @param[in] rand_seed Random seed for random number generator + * @param[in] seed_len The length of random seed + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t rand_num_gen_init(mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg, char *rand_seed, + uint16_t seed_len); + +/** + * @brief Release random number generator + * + * @param[in] entropy Entropy contrext for randomess + * @param[in] ctr_drbg Counter-mode block-cipher-based Deterministic Random Bit Generator object + * + * @return + * - SC_OK on success + * - non-zero on error + */ +void rand_num_gen_release(mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg); + +#ifdef __cplusplus +} +#endif + +#endif // ECDH_COMMON_H diff --git a/tests/unit-test/BUILD b/tests/unit-test/BUILD index 6fbbdeb7..12c23776 100644 --- a/tests/unit-test/BUILD +++ b/tests/unit-test/BUILD @@ -73,3 +73,14 @@ cc_test( "//utils:tryte_byte_conv", ], ) + +cc_test( + name = "test_ec_crypto", + srcs = ["test_ec_crypto.c"], + deps = [ + "//crypto:ecdh", + "//crypto:ecdsa", + "//tests:test_define", + "@mbedtls", + ], +) diff --git a/tests/unit-test/test_ec_crypto.c b/tests/unit-test/test_ec_crypto.c new file mode 100644 index 00000000..868d3ecc --- /dev/null +++ b/tests/unit-test/test_ec_crypto.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2020 BiiLabs Co., Ltd. and Contributors + * All Rights Reserved. + * This is free software; you can redistribute it and/or modify it under the + * terms of the MIT license. A copy of the license can be found in the file + * "LICENSE" at the root of this distribution. + */ + +#include "crypto/ecdh.h" +#include "crypto/ecdsa.h" +#include "tests/test_define.h" + +#define MSG_LEN 100 + +void test_srv_cli_communication(void) { + rand_gen_t rand_gen; + mbedtls_ecdh_context ecdh_srv, ecdh_cli; + unsigned char cli_to_srv[SHARE_DATA_LEN], srv_to_cli[SHARE_DATA_LEN]; + + // initialize ECDH object for server side and client side + mbedtls_ecdh_init(&ecdh_srv); + mbedtls_ecdh_init(&ecdh_cli); + + TEST_ASSERT_EQUAL_INT32(SC_OK, + rand_num_gen_init(&rand_gen.entropy, &rand_gen.ctr_drbg, TEST_UUID, strlen(TEST_UUID) + 1)); + + // [client] initialize ECDH context and generate public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_cli, &rand_gen.ctr_drbg, cli_to_srv)); + + // [server] initialize ECDH context and generate public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_srv, &rand_gen.ctr_drbg, srv_to_cli)); + + // [server] compute shared secret with peer's public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_srv, &rand_gen.ctr_drbg, cli_to_srv)); + + // [client] compute shared secret with peer's public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_cli, &rand_gen.ctr_drbg, srv_to_cli)); + + // Check if the two shared secret are the same + TEST_ASSERT_EQUAL_INT32(0, mbedtls_mpi_cmp_mpi(&ecdh_cli.z, &ecdh_srv.z)); + + rand_num_gen_release(&rand_gen.entropy, &rand_gen.ctr_drbg); + mbedtls_ecdh_free(&ecdh_srv); + mbedtls_ecdh_free(&ecdh_cli); +} + +void test_ecdsa(void) { + rand_gen_t rand_gen; + mbedtls_ecdsa_context ctx_sign, ctx_verify; + unsigned char message[MSG_LEN]; + unsigned char hash[SHA256_LEN] = {}; + unsigned char signature[MBEDTLS_ECDSA_MAX_LEN] = {}; + size_t signature_len = 0; + memset(message, 0x25, sizeof(message)); + mbedtls_ecdsa_init(&ctx_sign); + mbedtls_ecdsa_init(&ctx_verify); + + TEST_ASSERT_EQUAL_INT32(SC_OK, + rand_num_gen_init(&rand_gen.entropy, &rand_gen.ctr_drbg, TEST_UUID, strlen(TEST_UUID) + 1)); + + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdsa_gen_key_pair(&ctx_sign, &rand_gen.ctr_drbg)); + TEST_ASSERT_EQUAL_INT32(SC_OK, compute_sha256(message, MSG_LEN, hash)); + TEST_ASSERT_EQUAL_INT32(SC_OK, + ecdsa_sign_msg(&ctx_sign, &rand_gen.ctr_drbg, hash, SHA256_LEN, signature, &signature_len)); + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_group_copy(&ctx_verify.grp, &ctx_sign.grp)); + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_copy(&ctx_verify.Q, &ctx_sign.Q)); + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecdsa_read_signature(&ctx_verify, hash, sizeof(hash), signature, signature_len)); + + rand_num_gen_release(&rand_gen.entropy, &rand_gen.ctr_drbg); + mbedtls_ecdsa_free(&ctx_verify); + mbedtls_ecdsa_free(&ctx_sign); +} + +void test_sign_ecdh_pkey(void) { + rand_gen_t rand_gen; + mbedtls_ecdh_context ecdh_srv, ecdh_cli; + mbedtls_ecdsa_context cli_ecdsa_sign, cli_ecdsa_verify; + mbedtls_ecdsa_context srv_ecdsa_sign, srv_ecdsa_verify; + unsigned char cli_to_srv[SHARE_DATA_LEN], srv_to_cli[SHARE_DATA_LEN]; + unsigned char cli_signature[MBEDTLS_ECDSA_MAX_LEN] = {}, srv_signature[MBEDTLS_ECDSA_MAX_LEN] = {}; + size_t cli_signature_len = 0, srv_signature_len = 0; + + // initialize ECDH object for server side and client side + mbedtls_ecdh_init(&ecdh_srv); + mbedtls_ecdh_init(&ecdh_cli); + + // Initialize ECDSA + mbedtls_ecdsa_init(&cli_ecdsa_sign); + mbedtls_ecdsa_init(&cli_ecdsa_verify); + mbedtls_ecdsa_init(&srv_ecdsa_sign); + mbedtls_ecdsa_init(&srv_ecdsa_verify); + + TEST_ASSERT_EQUAL_INT32(SC_OK, + rand_num_gen_init(&rand_gen.entropy, &rand_gen.ctr_drbg, TEST_UUID, strlen(TEST_UUID) + 1)); + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdsa_gen_key_pair(&cli_ecdsa_sign, &rand_gen.ctr_drbg)); + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdsa_gen_key_pair(&srv_ecdsa_sign, &rand_gen.ctr_drbg)); + + // [client] initialize ECDH context and generate public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_cli, &rand_gen.ctr_drbg, cli_to_srv)); + + // Sign client's pkey + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdsa_sign_msg(&cli_ecdsa_sign, &rand_gen.ctr_drbg, cli_to_srv, SHARE_DATA_LEN, + cli_signature, &cli_signature_len)); + + // [server] initialize ECDH context and generate public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_srv, &rand_gen.ctr_drbg, srv_to_cli)); + + // Sign service's pkey + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdsa_sign_msg(&srv_ecdsa_sign, &rand_gen.ctr_drbg, srv_to_cli, SHARE_DATA_LEN, + srv_signature, &srv_signature_len)); + + // [server] examine if the signature is correct + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_group_copy(&cli_ecdsa_verify.grp, &cli_ecdsa_sign.grp)); + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_copy(&cli_ecdsa_verify.Q, &cli_ecdsa_sign.Q)); + TEST_ASSERT_EQUAL_INT32( + 0, mbedtls_ecdsa_read_signature(&cli_ecdsa_verify, cli_to_srv, SHARE_DATA_LEN, cli_signature, cli_signature_len)); + + // [server] compute shared secret with peer's public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_srv, &rand_gen.ctr_drbg, cli_to_srv)); + + // [client] examine if the signature is correct + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_group_copy(&cli_ecdsa_verify.grp, &cli_ecdsa_sign.grp)); + TEST_ASSERT_EQUAL_INT32(0, mbedtls_ecp_copy(&cli_ecdsa_verify.Q, &cli_ecdsa_sign.Q)); + TEST_ASSERT_EQUAL_INT32( + 0, mbedtls_ecdsa_read_signature(&cli_ecdsa_verify, cli_to_srv, SHARE_DATA_LEN, cli_signature, cli_signature_len)); + + // [client] compute shared secret with peer's public key + TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_cli, &rand_gen.ctr_drbg, srv_to_cli)); + + // Check if the two shared secret are the same + TEST_ASSERT_EQUAL_INT32(0, mbedtls_mpi_cmp_mpi(&ecdh_cli.z, &ecdh_srv.z)); + + rand_num_gen_release(&rand_gen.entropy, &rand_gen.ctr_drbg); + mbedtls_ecdh_free(&ecdh_srv); + mbedtls_ecdh_free(&ecdh_cli); +} + +int main(void) { + UNITY_BEGIN(); + + // Initialize logger + if (ta_logger_init() != SC_OK) { + return EXIT_FAILURE; + } + + crypto_logger_init(); + RUN_TEST(test_srv_cli_communication); + RUN_TEST(test_ecdsa); + RUN_TEST(test_sign_ecdh_pkey); + crypto_logger_release(); + + return UNITY_END(); +}