ecdh_curve25519.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. * This file is provided under the Apache License 2.0, or the
  8. * GNU General Public License v2.0 or later.
  9. *
  10. * **********
  11. * Apache License 2.0:
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  14. * not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  21. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *
  25. * **********
  26. *
  27. * **********
  28. * GNU General Public License v2.0 or later:
  29. *
  30. * This program is free software; you can redistribute it and/or modify
  31. * it under the terms of the GNU General Public License as published by
  32. * the Free Software Foundation; either version 2 of the License, or
  33. * (at your option) any later version.
  34. *
  35. * This program is distributed in the hope that it will be useful,
  36. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  38. * GNU General Public License for more details.
  39. *
  40. * You should have received a copy of the GNU General Public License along
  41. * with this program; if not, write to the Free Software Foundation, Inc.,
  42. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  43. *
  44. * **********
  45. */
  46. #if !defined(MBEDTLS_CONFIG_FILE)
  47. #include "mbedtls/config.h"
  48. #else
  49. #include MBEDTLS_CONFIG_FILE
  50. #endif
  51. #if defined(MBEDTLS_PLATFORM_C)
  52. #include "mbedtls/platform.h"
  53. #else
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #define mbedtls_printf printf
  57. #define mbedtls_exit exit
  58. #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
  59. #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
  60. #endif /* MBEDTLS_PLATFORM_C */
  61. #if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
  62. !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
  63. !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
  64. int main( void )
  65. {
  66. mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
  67. "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
  68. "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
  69. "not defined\n" );
  70. mbedtls_exit( 0 );
  71. }
  72. #else
  73. #include "mbedtls/entropy.h"
  74. #include "mbedtls/ctr_drbg.h"
  75. #include "mbedtls/ecdh.h"
  76. int main( int argc, char *argv[] )
  77. {
  78. int ret = 1;
  79. int exit_code = MBEDTLS_EXIT_FAILURE;
  80. mbedtls_ecdh_context ctx_cli, ctx_srv;
  81. mbedtls_entropy_context entropy;
  82. mbedtls_ctr_drbg_context ctr_drbg;
  83. unsigned char cli_to_srv[32], srv_to_cli[32];
  84. const char pers[] = "ecdh";
  85. ((void) argc);
  86. ((void) argv);
  87. mbedtls_ecdh_init( &ctx_cli );
  88. mbedtls_ecdh_init( &ctx_srv );
  89. mbedtls_ctr_drbg_init( &ctr_drbg );
  90. /*
  91. * Initialize random number generation
  92. */
  93. mbedtls_printf( " . Seeding the random number generator..." );
  94. fflush( stdout );
  95. mbedtls_entropy_init( &entropy );
  96. if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
  97. (const unsigned char *) pers,
  98. sizeof pers ) ) != 0 )
  99. {
  100. mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
  101. goto exit;
  102. }
  103. mbedtls_printf( " ok\n" );
  104. /*
  105. * Client: inialize context and generate keypair
  106. */
  107. mbedtls_printf( " . Setting up client context..." );
  108. fflush( stdout );
  109. ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
  110. if( ret != 0 )
  111. {
  112. mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
  113. goto exit;
  114. }
  115. ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
  116. mbedtls_ctr_drbg_random, &ctr_drbg );
  117. if( ret != 0 )
  118. {
  119. mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
  120. goto exit;
  121. }
  122. ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
  123. if( ret != 0 )
  124. {
  125. mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
  126. goto exit;
  127. }
  128. mbedtls_printf( " ok\n" );
  129. /*
  130. * Server: initialize context and generate keypair
  131. */
  132. mbedtls_printf( " . Setting up server context..." );
  133. fflush( stdout );
  134. ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 );
  135. if( ret != 0 )
  136. {
  137. mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
  138. goto exit;
  139. }
  140. ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q,
  141. mbedtls_ctr_drbg_random, &ctr_drbg );
  142. if( ret != 0 )
  143. {
  144. mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
  145. goto exit;
  146. }
  147. ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 );
  148. if( ret != 0 )
  149. {
  150. mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
  151. goto exit;
  152. }
  153. mbedtls_printf( " ok\n" );
  154. /*
  155. * Server: read peer's key and generate shared secret
  156. */
  157. mbedtls_printf( " . Server reading client key and computing secret..." );
  158. fflush( stdout );
  159. ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
  160. if( ret != 0 )
  161. {
  162. mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
  163. goto exit;
  164. }
  165. ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
  166. if( ret != 0 )
  167. {
  168. mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
  169. goto exit;
  170. }
  171. ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
  172. &ctx_srv.Qp, &ctx_srv.d,
  173. mbedtls_ctr_drbg_random, &ctr_drbg );
  174. if( ret != 0 )
  175. {
  176. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  177. goto exit;
  178. }
  179. mbedtls_printf( " ok\n" );
  180. /*
  181. * Client: read peer's key and generate shared secret
  182. */
  183. mbedtls_printf( " . Client reading server key and computing secret..." );
  184. fflush( stdout );
  185. ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
  186. if( ret != 0 )
  187. {
  188. mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
  189. goto exit;
  190. }
  191. ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
  192. if( ret != 0 )
  193. {
  194. mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
  195. goto exit;
  196. }
  197. ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
  198. &ctx_cli.Qp, &ctx_cli.d,
  199. mbedtls_ctr_drbg_random, &ctr_drbg );
  200. if( ret != 0 )
  201. {
  202. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  203. goto exit;
  204. }
  205. mbedtls_printf( " ok\n" );
  206. /*
  207. * Verification: are the computed secrets equal?
  208. */
  209. mbedtls_printf( " . Checking if both computed secrets are equal..." );
  210. fflush( stdout );
  211. ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
  212. if( ret != 0 )
  213. {
  214. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  215. goto exit;
  216. }
  217. mbedtls_printf( " ok\n" );
  218. exit_code = MBEDTLS_EXIT_SUCCESS;
  219. exit:
  220. #if defined(_WIN32)
  221. mbedtls_printf( " + Press Enter to exit this program.\n" );
  222. fflush( stdout ); getchar();
  223. #endif
  224. mbedtls_ecdh_free( &ctx_srv );
  225. mbedtls_ecdh_free( &ctx_cli );
  226. mbedtls_ctr_drbg_free( &ctr_drbg );
  227. mbedtls_entropy_free( &entropy );
  228. mbedtls_exit( exit_code );
  229. }
  230. #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
  231. MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */