This repository has been archived by the owner on Dec 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mam): Implement ECDH for MAM key exchange
- Loading branch information
Showing
6 changed files
with
260 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
cc_library( | ||
name = "ecdh", | ||
srcs = ["ecdh.c"], | ||
hdrs = ["ecdh.h"], | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
"//common", | ||
"@mbedtls", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include "ecdh.h" | ||
|
||
#define ECDH_LOGGER "ecdh" | ||
static logger_id_t logger_id; | ||
|
||
void ecdh_logger_init() { logger_id = logger_helper_enable(ECDH_LOGGER, LOGGER_DEBUG, true); } | ||
|
||
int ecdh_logger_release() { | ||
logger_helper_release(logger_id); | ||
return 0; | ||
} | ||
|
||
status_t ecdh_ctx_init(ecdh_ctx_t *ecdh_ctx, 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_ecdh_init(&ecdh_ctx->ctx); | ||
|
||
if (entropy && ctr_drbg) { | ||
mbedtls_ctr_drbg_init(ctr_drbg); | ||
|
||
/* | ||
* Initialize random number generation | ||
*/ | ||
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); | ||
goto exit; | ||
} | ||
} | ||
|
||
exit: | ||
return sc; | ||
} | ||
|
||
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); | ||
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); | ||
goto exit; | ||
} | ||
|
||
ret = mbedtls_mpi_write_binary(&ctx->Q.X, pkey, 32); | ||
if (ret != 0) { | ||
ta_log_error("mbedtls_mpi_write_binary returned %d\n", ret); | ||
goto exit; | ||
} | ||
|
||
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); | ||
goto exit; | ||
} | ||
|
||
ret = mbedtls_mpi_read_binary(&ctx->Qp.X, input_shared_data, 32); | ||
if (ret != 0) { | ||
ta_log_error("mbedtls_mpi_read_binary returned %d\n", ret); | ||
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); | ||
goto exit; | ||
} | ||
|
||
exit: | ||
return sc; | ||
} | ||
|
||
void ecdh_ctx_release(ecdh_ctx_t *ecdh_ctx, mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg) { | ||
mbedtls_ecdh_free(&ecdh_ctx->ctx); | ||
mbedtls_ctr_drbg_free(ctr_drbg); | ||
mbedtls_entropy_free(entropy); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* 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 | ||
|
||
typedef struct ecdh_ctx_s { | ||
mbedtls_ecdh_context ctx; | ||
mbedtls_entropy_context entropy; | ||
mbedtls_ctr_drbg_context ctr_drbg; | ||
} ecdh_ctx_t; | ||
|
||
void ecdh_logger_init(); | ||
|
||
int ecdh_logger_release(); | ||
|
||
/** | ||
* @brief Initialize tangle-accelerator ECDH object and random number generator | ||
* | ||
* @param[in] ecdh_ctx tangle-accelerator ECDH object | ||
* @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 ecdh_ctx_init(ecdh_ctx_t *ecdh_ctx, mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg, | ||
char *rand_seed, uint16_t seed_len); | ||
|
||
/** | ||
* @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); | ||
|
||
/** | ||
* @brief Release tangle-accelerator ECDH object and random number generator | ||
* | ||
* @param[in] ecdh_ctx tangle-accelerator ECDH object | ||
* @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 ecdh_ctx_release(ecdh_ctx_t *ecdh_ctx, mbedtls_entropy_context *entropy, mbedtls_ctr_drbg_context *ctr_drbg); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // ECDH_COMMON_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include "crypto/ecdh.h" | ||
#include "tests/test_define.h" | ||
|
||
void test_srv_cli_communication(void) { | ||
ecdh_ctx_t ecdh_cli, ecdh_srv; | ||
unsigned char cli_to_srv[32], srv_to_cli[32]; | ||
|
||
TEST_ASSERT_EQUAL_INT32( | ||
SC_OK, ecdh_ctx_init(&ecdh_srv, &ecdh_srv.entropy, &ecdh_srv.ctr_drbg, TEST_UUID, strlen(TEST_UUID) + 1)); | ||
TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_ctx_init(&ecdh_cli, NULL, NULL, NULL, 0)); | ||
|
||
TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_cli.ctx, &ecdh_srv.ctr_drbg, cli_to_srv)); | ||
|
||
/* | ||
* Server: initialize context and generate keypair | ||
*/ | ||
TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_gen_public_key(&ecdh_srv.ctx, &ecdh_srv.ctr_drbg, srv_to_cli)); | ||
|
||
/* | ||
* Server: read peer's key and generate shared secret | ||
*/ | ||
TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_srv.ctx, &ecdh_srv.ctr_drbg, cli_to_srv)); | ||
|
||
/* | ||
* Client: read peer's key and generate shared secret | ||
*/ | ||
TEST_ASSERT_EQUAL_INT32(SC_OK, ecdh_compute_shared_secret(&ecdh_cli.ctx, &ecdh_srv.ctr_drbg, srv_to_cli)); | ||
|
||
/* | ||
* Verification: are the computed secrets equal? | ||
*/ | ||
TEST_ASSERT_EQUAL_INT32(0, mbedtls_mpi_cmp_mpi(&ecdh_cli.ctx.z, &ecdh_srv.ctx.z)); | ||
|
||
ecdh_ctx_release(&ecdh_srv, &ecdh_srv.entropy, &ecdh_srv.ctr_drbg); | ||
mbedtls_ecdh_free(&ecdh_cli.ctx); | ||
} | ||
|
||
int main(void) { | ||
UNITY_BEGIN(); | ||
|
||
// Initialize logger | ||
if (ta_logger_init() != SC_OK) { | ||
return EXIT_FAILURE; | ||
} | ||
|
||
ecdh_logger_init(); | ||
RUN_TEST(test_srv_cli_communication); | ||
ecdh_logger_release(); | ||
|
||
return UNITY_END(); | ||
} |