ecdh_curve25519.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Example ECDHE with Curve25519 program
  3. *
  4. * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * This file is part of mbed TLS (https://tls.mbed.org)
  20. */
  21. #if !defined(MBEDTLS_CONFIG_FILE)
  22. #include "mbedtls/config.h"
  23. #else
  24. #include MBEDTLS_CONFIG_FILE
  25. #endif
  26. #if defined(MBEDTLS_PLATFORM_C)
  27. #include "mbedtls/platform.h"
  28. #else
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #define mbedtls_printf printf
  32. #define mbedtls_exit exit
  33. #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
  34. #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
  35. #endif /* MBEDTLS_PLATFORM_C */
  36. #if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
  37. !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
  38. !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
  39. int main( void )
  40. {
  41. mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
  42. "MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
  43. "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
  44. "not defined\n" );
  45. return( 0 );
  46. }
  47. #else
  48. #include "mbedtls/entropy.h"
  49. #include "mbedtls/ctr_drbg.h"
  50. #include "mbedtls/ecdh.h"
  51. int main( int argc, char *argv[] )
  52. {
  53. int ret = 1;
  54. int exit_code = MBEDTLS_EXIT_FAILURE;
  55. mbedtls_ecdh_context ctx_cli, ctx_srv;
  56. mbedtls_entropy_context entropy;
  57. mbedtls_ctr_drbg_context ctr_drbg;
  58. unsigned char cli_to_srv[32], srv_to_cli[32];
  59. const char pers[] = "ecdh";
  60. ((void) argc);
  61. ((void) argv);
  62. mbedtls_ecdh_init( &ctx_cli );
  63. mbedtls_ecdh_init( &ctx_srv );
  64. mbedtls_ctr_drbg_init( &ctr_drbg );
  65. /*
  66. * Initialize random number generation
  67. */
  68. mbedtls_printf( " . Seeding the random number generator..." );
  69. fflush( stdout );
  70. mbedtls_entropy_init( &entropy );
  71. if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
  72. (const unsigned char *) pers,
  73. sizeof pers ) ) != 0 )
  74. {
  75. mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
  76. goto exit;
  77. }
  78. mbedtls_printf( " ok\n" );
  79. /*
  80. * Client: inialize context and generate keypair
  81. */
  82. mbedtls_printf( " . Setting up client context..." );
  83. fflush( stdout );
  84. ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
  85. if( ret != 0 )
  86. {
  87. mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret );
  88. goto exit;
  89. }
  90. ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
  91. mbedtls_ctr_drbg_random, &ctr_drbg );
  92. if( ret != 0 )
  93. {
  94. mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret );
  95. goto exit;
  96. }
  97. ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
  98. if( ret != 0 )
  99. {
  100. mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret );
  101. goto exit;
  102. }
  103. mbedtls_printf( " ok\n" );
  104. /*
  105. * Server: initialize context and generate keypair
  106. */
  107. mbedtls_printf( " . Setting up server context..." );
  108. fflush( stdout );
  109. ret = mbedtls_ecp_group_load( &ctx_srv.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_srv.grp, &ctx_srv.d, &ctx_srv.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_srv.Q.X, srv_to_cli, 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: read peer's key and generate shared secret
  131. */
  132. mbedtls_printf( " . Server reading client key and computing secret..." );
  133. fflush( stdout );
  134. ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
  135. if( ret != 0 )
  136. {
  137. mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
  138. goto exit;
  139. }
  140. ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
  141. if( ret != 0 )
  142. {
  143. mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
  144. goto exit;
  145. }
  146. ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
  147. &ctx_srv.Qp, &ctx_srv.d,
  148. mbedtls_ctr_drbg_random, &ctr_drbg );
  149. if( ret != 0 )
  150. {
  151. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  152. goto exit;
  153. }
  154. mbedtls_printf( " ok\n" );
  155. /*
  156. * Client: read peer's key and generate shared secret
  157. */
  158. mbedtls_printf( " . Client reading server key and computing secret..." );
  159. fflush( stdout );
  160. ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
  161. if( ret != 0 )
  162. {
  163. mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret );
  164. goto exit;
  165. }
  166. ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
  167. if( ret != 0 )
  168. {
  169. mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret );
  170. goto exit;
  171. }
  172. ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
  173. &ctx_cli.Qp, &ctx_cli.d,
  174. mbedtls_ctr_drbg_random, &ctr_drbg );
  175. if( ret != 0 )
  176. {
  177. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  178. goto exit;
  179. }
  180. mbedtls_printf( " ok\n" );
  181. /*
  182. * Verification: are the computed secrets equal?
  183. */
  184. mbedtls_printf( " . Checking if both computed secrets are equal..." );
  185. fflush( stdout );
  186. ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
  187. if( ret != 0 )
  188. {
  189. mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret );
  190. goto exit;
  191. }
  192. mbedtls_printf( " ok\n" );
  193. exit_code = MBEDTLS_EXIT_SUCCESS;
  194. exit:
  195. #if defined(_WIN32)
  196. mbedtls_printf( " + Press Enter to exit this program.\n" );
  197. fflush( stdout ); getchar();
  198. #endif
  199. mbedtls_ecdh_free( &ctx_srv );
  200. mbedtls_ecdh_free( &ctx_cli );
  201. mbedtls_ctr_drbg_free( &ctr_drbg );
  202. mbedtls_entropy_free( &entropy );
  203. return( exit_code );
  204. }
  205. #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECP_DP_CURVE25519_ENABLED &&
  206. MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */