x25519.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * ECDH with curve-optimized implementation multiplexing
  3. *
  4. * Copyright 2016-2018 INRIA and Microsoft Corporation
  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. #include "common.h"
  22. #if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  23. #include <mbedtls/ecdh.h>
  24. #if !(defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16))
  25. #define KRML_VERIFIED_UINT128
  26. #endif
  27. #include <Hacl_Curve25519.h>
  28. #include <mbedtls/platform_util.h>
  29. #include "x25519.h"
  30. #include <string.h>
  31. /*
  32. * Initialize context
  33. */
  34. void mbedtls_x25519_init( mbedtls_x25519_context *ctx )
  35. {
  36. mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x25519_context ) );
  37. }
  38. /*
  39. * Free context
  40. */
  41. void mbedtls_x25519_free( mbedtls_x25519_context *ctx )
  42. {
  43. if( ctx == NULL )
  44. return;
  45. mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
  46. mbedtls_platform_zeroize( ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
  47. }
  48. int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
  49. unsigned char *buf, size_t blen,
  50. int( *f_rng )(void *, unsigned char *, size_t),
  51. void *p_rng )
  52. {
  53. int ret = 0;
  54. uint8_t base[MBEDTLS_X25519_KEY_SIZE_BYTES] = {0};
  55. if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
  56. return ret;
  57. *olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 4;
  58. if( blen < *olen )
  59. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  60. *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
  61. *buf++ = MBEDTLS_ECP_TLS_CURVE25519 >> 8;
  62. *buf++ = MBEDTLS_ECP_TLS_CURVE25519 & 0xFF;
  63. *buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
  64. base[0] = 9;
  65. Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
  66. base[0] = 0;
  67. if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
  68. return MBEDTLS_ERR_ECP_RANDOM_FAILED;
  69. return( 0 );
  70. }
  71. int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
  72. const unsigned char **buf, const unsigned char *end )
  73. {
  74. if( end - *buf < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
  75. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  76. if( ( *(*buf)++ != MBEDTLS_X25519_KEY_SIZE_BYTES ) )
  77. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  78. memcpy( ctx->peer_point, *buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
  79. *buf += MBEDTLS_X25519_KEY_SIZE_BYTES;
  80. return( 0 );
  81. }
  82. int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
  83. mbedtls_x25519_ecdh_side side )
  84. {
  85. size_t olen = 0;
  86. switch( side ) {
  87. case MBEDTLS_X25519_ECDH_THEIRS:
  88. return mbedtls_ecp_point_write_binary( &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
  89. case MBEDTLS_X25519_ECDH_OURS:
  90. return mbedtls_mpi_write_binary_le( &key->d, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
  91. default:
  92. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  93. }
  94. }
  95. int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
  96. unsigned char *buf, size_t blen,
  97. int( *f_rng )(void *, unsigned char *, size_t),
  98. void *p_rng )
  99. {
  100. /* f_rng and p_rng are not used here because this implementation does not
  101. need blinding since it has constant trace. */
  102. (( void )f_rng);
  103. (( void )p_rng);
  104. *olen = MBEDTLS_X25519_KEY_SIZE_BYTES;
  105. if( blen < *olen )
  106. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  107. Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, ctx->peer_point);
  108. /* Wipe the DH secret and don't let the peer chose a small subgroup point */
  109. mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
  110. if( memcmp( buf, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
  111. return MBEDTLS_ERR_ECP_RANDOM_FAILED;
  112. return( 0 );
  113. }
  114. int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
  115. unsigned char *buf, size_t blen,
  116. int( *f_rng )(void *, unsigned char *, size_t),
  117. void *p_rng )
  118. {
  119. int ret = 0;
  120. unsigned char base[MBEDTLS_X25519_KEY_SIZE_BYTES] = { 0 };
  121. if( ctx == NULL )
  122. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  123. if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
  124. return ret;
  125. *olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 1;
  126. if( blen < *olen )
  127. return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
  128. *buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
  129. base[0] = 9;
  130. Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
  131. base[0] = 0;
  132. if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES ) == 0 )
  133. return MBEDTLS_ERR_ECP_RANDOM_FAILED;
  134. return( ret );
  135. }
  136. int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
  137. const unsigned char *buf, size_t blen )
  138. {
  139. if( blen < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
  140. return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
  141. if( (*buf++ != MBEDTLS_X25519_KEY_SIZE_BYTES) )
  142. return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
  143. memcpy( ctx->peer_point, buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
  144. return( 0 );
  145. }
  146. #endif /* MBEDTLS_ECDH_C && MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */