1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Example ECDHE with Curve25519 program 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 6a8e1175bSopenharmony_ci * 7a8e1175bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); you may 8a8e1175bSopenharmony_ci * not use this file except in compliance with the License. 9a8e1175bSopenharmony_ci * You may obtain a copy of the License at 10a8e1175bSopenharmony_ci * 11a8e1175bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12a8e1175bSopenharmony_ci * 13a8e1175bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14a8e1175bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15a8e1175bSopenharmony_ci * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16a8e1175bSopenharmony_ci * See the License for the specific language governing permissions and 17a8e1175bSopenharmony_ci * limitations under the License. 18a8e1175bSopenharmony_ci */ 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 23a8e1175bSopenharmony_ci 24a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECDH_C) || \ 25a8e1175bSopenharmony_ci !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ 26a8e1175bSopenharmony_ci !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) 27a8e1175bSopenharmony_ciint main(void) 28a8e1175bSopenharmony_ci{ 29a8e1175bSopenharmony_ci mbedtls_printf("MBEDTLS_ECDH_C and/or " 30a8e1175bSopenharmony_ci "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or " 31a8e1175bSopenharmony_ci "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C " 32a8e1175bSopenharmony_ci "not defined\n"); 33a8e1175bSopenharmony_ci mbedtls_exit(0); 34a8e1175bSopenharmony_ci} 35a8e1175bSopenharmony_ci#else 36a8e1175bSopenharmony_ci 37a8e1175bSopenharmony_ci#include "mbedtls/entropy.h" 38a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h" 39a8e1175bSopenharmony_ci#include "mbedtls/ecdh.h" 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci#include <string.h> 42a8e1175bSopenharmony_ci 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ciint main(int argc, char *argv[]) 45a8e1175bSopenharmony_ci{ 46a8e1175bSopenharmony_ci int ret = 1; 47a8e1175bSopenharmony_ci int exit_code = MBEDTLS_EXIT_FAILURE; 48a8e1175bSopenharmony_ci mbedtls_ecdh_context ctx_cli, ctx_srv; 49a8e1175bSopenharmony_ci mbedtls_entropy_context entropy; 50a8e1175bSopenharmony_ci mbedtls_ctr_drbg_context ctr_drbg; 51a8e1175bSopenharmony_ci unsigned char cli_to_srv[36], srv_to_cli[33]; 52a8e1175bSopenharmony_ci const char pers[] = "ecdh"; 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci size_t srv_olen; 55a8e1175bSopenharmony_ci size_t cli_olen; 56a8e1175bSopenharmony_ci unsigned char secret_cli[32] = { 0 }; 57a8e1175bSopenharmony_ci unsigned char secret_srv[32] = { 0 }; 58a8e1175bSopenharmony_ci const unsigned char *p_cli_to_srv = cli_to_srv; 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_ci ((void) argc); 61a8e1175bSopenharmony_ci ((void) argv); 62a8e1175bSopenharmony_ci 63a8e1175bSopenharmony_ci mbedtls_ecdh_init(&ctx_cli); 64a8e1175bSopenharmony_ci mbedtls_ecdh_init(&ctx_srv); 65a8e1175bSopenharmony_ci mbedtls_ctr_drbg_init(&ctr_drbg); 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci /* 68a8e1175bSopenharmony_ci * Initialize random number generation 69a8e1175bSopenharmony_ci */ 70a8e1175bSopenharmony_ci mbedtls_printf(" . Seed the random number generator..."); 71a8e1175bSopenharmony_ci fflush(stdout); 72a8e1175bSopenharmony_ci 73a8e1175bSopenharmony_ci mbedtls_entropy_init(&entropy); 74a8e1175bSopenharmony_ci if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, 75a8e1175bSopenharmony_ci &entropy, 76a8e1175bSopenharmony_ci (const unsigned char *) pers, 77a8e1175bSopenharmony_ci sizeof(pers))) != 0) { 78a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", 79a8e1175bSopenharmony_ci ret); 80a8e1175bSopenharmony_ci goto exit; 81a8e1175bSopenharmony_ci } 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci /* 86a8e1175bSopenharmony_ci * Client: initialize context and generate keypair 87a8e1175bSopenharmony_ci */ 88a8e1175bSopenharmony_ci mbedtls_printf(" . Set up client context, generate EC key pair..."); 89a8e1175bSopenharmony_ci fflush(stdout); 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci ret = mbedtls_ecdh_setup(&ctx_cli, MBEDTLS_ECP_DP_CURVE25519); 92a8e1175bSopenharmony_ci if (ret != 0) { 93a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_setup returned %d\n", ret); 94a8e1175bSopenharmony_ci goto exit; 95a8e1175bSopenharmony_ci } 96a8e1175bSopenharmony_ci 97a8e1175bSopenharmony_ci ret = mbedtls_ecdh_make_params(&ctx_cli, &cli_olen, cli_to_srv, 98a8e1175bSopenharmony_ci sizeof(cli_to_srv), 99a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 100a8e1175bSopenharmony_ci if (ret != 0) { 101a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_make_params returned %d\n", 102a8e1175bSopenharmony_ci ret); 103a8e1175bSopenharmony_ci goto exit; 104a8e1175bSopenharmony_ci } 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci /* 109a8e1175bSopenharmony_ci * Server: initialize context and generate keypair 110a8e1175bSopenharmony_ci */ 111a8e1175bSopenharmony_ci mbedtls_printf(" . Server: read params, generate public key..."); 112a8e1175bSopenharmony_ci fflush(stdout); 113a8e1175bSopenharmony_ci 114a8e1175bSopenharmony_ci ret = mbedtls_ecdh_read_params(&ctx_srv, &p_cli_to_srv, 115a8e1175bSopenharmony_ci p_cli_to_srv + sizeof(cli_to_srv)); 116a8e1175bSopenharmony_ci if (ret != 0) { 117a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_read_params returned %d\n", 118a8e1175bSopenharmony_ci ret); 119a8e1175bSopenharmony_ci goto exit; 120a8e1175bSopenharmony_ci } 121a8e1175bSopenharmony_ci 122a8e1175bSopenharmony_ci ret = mbedtls_ecdh_make_public(&ctx_srv, &srv_olen, srv_to_cli, 123a8e1175bSopenharmony_ci sizeof(srv_to_cli), 124a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 125a8e1175bSopenharmony_ci if (ret != 0) { 126a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_make_public returned %d\n", 127a8e1175bSopenharmony_ci ret); 128a8e1175bSopenharmony_ci goto exit; 129a8e1175bSopenharmony_ci } 130a8e1175bSopenharmony_ci 131a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 132a8e1175bSopenharmony_ci 133a8e1175bSopenharmony_ci /* 134a8e1175bSopenharmony_ci * Client: read public key 135a8e1175bSopenharmony_ci */ 136a8e1175bSopenharmony_ci mbedtls_printf(" . Client: read public key..."); 137a8e1175bSopenharmony_ci fflush(stdout); 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci ret = mbedtls_ecdh_read_public(&ctx_cli, srv_to_cli, 140a8e1175bSopenharmony_ci sizeof(srv_to_cli)); 141a8e1175bSopenharmony_ci if (ret != 0) { 142a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_read_public returned %d\n", 143a8e1175bSopenharmony_ci ret); 144a8e1175bSopenharmony_ci goto exit; 145a8e1175bSopenharmony_ci } 146a8e1175bSopenharmony_ci 147a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 148a8e1175bSopenharmony_ci 149a8e1175bSopenharmony_ci /* 150a8e1175bSopenharmony_ci * Calculate secrets 151a8e1175bSopenharmony_ci */ 152a8e1175bSopenharmony_ci mbedtls_printf(" . Calculate secrets..."); 153a8e1175bSopenharmony_ci fflush(stdout); 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci ret = mbedtls_ecdh_calc_secret(&ctx_cli, &cli_olen, secret_cli, 156a8e1175bSopenharmony_ci sizeof(secret_cli), 157a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 158a8e1175bSopenharmony_ci if (ret != 0) { 159a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_calc_secret returned %d\n", 160a8e1175bSopenharmony_ci ret); 161a8e1175bSopenharmony_ci goto exit; 162a8e1175bSopenharmony_ci } 163a8e1175bSopenharmony_ci 164a8e1175bSopenharmony_ci ret = mbedtls_ecdh_calc_secret(&ctx_srv, &srv_olen, secret_srv, 165a8e1175bSopenharmony_ci sizeof(secret_srv), 166a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 167a8e1175bSopenharmony_ci if (ret != 0) { 168a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ecdh_calc_secret returned %d\n", 169a8e1175bSopenharmony_ci ret); 170a8e1175bSopenharmony_ci goto exit; 171a8e1175bSopenharmony_ci } 172a8e1175bSopenharmony_ci 173a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 174a8e1175bSopenharmony_ci 175a8e1175bSopenharmony_ci /* 176a8e1175bSopenharmony_ci * Verification: are the computed secrets equal? 177a8e1175bSopenharmony_ci */ 178a8e1175bSopenharmony_ci mbedtls_printf(" . Check if both calculated secrets are equal..."); 179a8e1175bSopenharmony_ci fflush(stdout); 180a8e1175bSopenharmony_ci 181a8e1175bSopenharmony_ci ret = memcmp(secret_srv, secret_cli, srv_olen); 182a8e1175bSopenharmony_ci if (ret != 0 || (cli_olen != srv_olen)) { 183a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! Shared secrets not equal.\n"); 184a8e1175bSopenharmony_ci goto exit; 185a8e1175bSopenharmony_ci } 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 188a8e1175bSopenharmony_ci 189a8e1175bSopenharmony_ci exit_code = MBEDTLS_EXIT_SUCCESS; 190a8e1175bSopenharmony_ci 191a8e1175bSopenharmony_ciexit: 192a8e1175bSopenharmony_ci 193a8e1175bSopenharmony_ci mbedtls_ecdh_free(&ctx_srv); 194a8e1175bSopenharmony_ci mbedtls_ecdh_free(&ctx_cli); 195a8e1175bSopenharmony_ci mbedtls_ctr_drbg_free(&ctr_drbg); 196a8e1175bSopenharmony_ci mbedtls_entropy_free(&entropy); 197a8e1175bSopenharmony_ci 198a8e1175bSopenharmony_ci mbedtls_exit(exit_code); 199a8e1175bSopenharmony_ci} 200a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED && 201a8e1175bSopenharmony_ci MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ 202