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