mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Elliptic curve Diffie-Hellman
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kenjiArai 0:5b88d5760320 5 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 6 *
kenjiArai 0:5b88d5760320 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kenjiArai 0:5b88d5760320 8 * not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 9 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 10 *
kenjiArai 0:5b88d5760320 11 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 12 *
kenjiArai 0:5b88d5760320 13 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kenjiArai 0:5b88d5760320 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 16 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 17 * limitations under the License.
kenjiArai 0:5b88d5760320 18 *
kenjiArai 0:5b88d5760320 19 * This file is part of mbed TLS (https://tls.mbed.org)
kenjiArai 0:5b88d5760320 20 */
kenjiArai 0:5b88d5760320 21
kenjiArai 0:5b88d5760320 22 /*
kenjiArai 0:5b88d5760320 23 * References:
kenjiArai 0:5b88d5760320 24 *
kenjiArai 0:5b88d5760320 25 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
kenjiArai 0:5b88d5760320 26 * RFC 4492
kenjiArai 0:5b88d5760320 27 */
kenjiArai 0:5b88d5760320 28
kenjiArai 0:5b88d5760320 29 #if !defined(MBEDTLS_CONFIG_FILE)
kenjiArai 0:5b88d5760320 30 #include "mbedtls/config.h"
kenjiArai 0:5b88d5760320 31 #else
kenjiArai 0:5b88d5760320 32 #include MBEDTLS_CONFIG_FILE
kenjiArai 0:5b88d5760320 33 #endif
kenjiArai 0:5b88d5760320 34
kenjiArai 0:5b88d5760320 35 #if defined(MBEDTLS_ECDH_C)
kenjiArai 0:5b88d5760320 36
kenjiArai 0:5b88d5760320 37 #include "mbedtls/ecdh.h"
kenjiArai 0:5b88d5760320 38 #include "mbedtls/platform_util.h"
kenjiArai 0:5b88d5760320 39
kenjiArai 0:5b88d5760320 40 #include <string.h>
kenjiArai 0:5b88d5760320 41
kenjiArai 0:5b88d5760320 42 /* Parameter validation macros based on platform_util.h */
kenjiArai 0:5b88d5760320 43 #define ECDH_VALIDATE_RET( cond ) \
kenjiArai 0:5b88d5760320 44 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
kenjiArai 0:5b88d5760320 45 #define ECDH_VALIDATE( cond ) \
kenjiArai 0:5b88d5760320 46 MBEDTLS_INTERNAL_VALIDATE( cond )
kenjiArai 0:5b88d5760320 47
kenjiArai 0:5b88d5760320 48 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 49 typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
kenjiArai 0:5b88d5760320 50 #endif
kenjiArai 0:5b88d5760320 51
kenjiArai 0:5b88d5760320 52 static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
kenjiArai 0:5b88d5760320 53 const mbedtls_ecdh_context *ctx )
kenjiArai 0:5b88d5760320 54 {
kenjiArai 0:5b88d5760320 55 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 56 return( ctx->grp.id );
kenjiArai 0:5b88d5760320 57 #else
kenjiArai 0:5b88d5760320 58 return( ctx->grp_id );
kenjiArai 0:5b88d5760320 59 #endif
kenjiArai 0:5b88d5760320 60 }
kenjiArai 0:5b88d5760320 61
kenjiArai 1:9db0e321a9f4 62 int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
kenjiArai 1:9db0e321a9f4 63 {
kenjiArai 1:9db0e321a9f4 64 /* At this time, all groups support ECDH. */
kenjiArai 1:9db0e321a9f4 65 (void) gid;
kenjiArai 1:9db0e321a9f4 66 return( 1 );
kenjiArai 1:9db0e321a9f4 67 }
kenjiArai 1:9db0e321a9f4 68
kenjiArai 0:5b88d5760320 69 #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
kenjiArai 0:5b88d5760320 70 /*
kenjiArai 0:5b88d5760320 71 * Generate public key (restartable version)
kenjiArai 0:5b88d5760320 72 *
kenjiArai 0:5b88d5760320 73 * Note: this internal function relies on its caller preserving the value of
kenjiArai 0:5b88d5760320 74 * the output parameter 'd' across continuation calls. This would not be
kenjiArai 0:5b88d5760320 75 * acceptable for a public function but is OK here as we control call sites.
kenjiArai 0:5b88d5760320 76 */
kenjiArai 0:5b88d5760320 77 static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
kenjiArai 0:5b88d5760320 78 mbedtls_mpi *d, mbedtls_ecp_point *Q,
kenjiArai 0:5b88d5760320 79 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 80 void *p_rng,
kenjiArai 0:5b88d5760320 81 mbedtls_ecp_restart_ctx *rs_ctx )
kenjiArai 0:5b88d5760320 82 {
kenjiArai 0:5b88d5760320 83 int ret;
kenjiArai 0:5b88d5760320 84
kenjiArai 0:5b88d5760320 85 /* If multiplication is in progress, we already generated a privkey */
kenjiArai 0:5b88d5760320 86 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 87 if( rs_ctx == NULL || rs_ctx->rsm == NULL )
kenjiArai 0:5b88d5760320 88 #endif
kenjiArai 0:5b88d5760320 89 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
kenjiArai 0:5b88d5760320 90
kenjiArai 0:5b88d5760320 91 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
kenjiArai 0:5b88d5760320 92 f_rng, p_rng, rs_ctx ) );
kenjiArai 0:5b88d5760320 93
kenjiArai 0:5b88d5760320 94 cleanup:
kenjiArai 0:5b88d5760320 95 return( ret );
kenjiArai 0:5b88d5760320 96 }
kenjiArai 0:5b88d5760320 97
kenjiArai 0:5b88d5760320 98 /*
kenjiArai 0:5b88d5760320 99 * Generate public key
kenjiArai 0:5b88d5760320 100 */
kenjiArai 0:5b88d5760320 101 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
kenjiArai 0:5b88d5760320 102 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 103 void *p_rng )
kenjiArai 0:5b88d5760320 104 {
kenjiArai 0:5b88d5760320 105 ECDH_VALIDATE_RET( grp != NULL );
kenjiArai 0:5b88d5760320 106 ECDH_VALIDATE_RET( d != NULL );
kenjiArai 0:5b88d5760320 107 ECDH_VALIDATE_RET( Q != NULL );
kenjiArai 0:5b88d5760320 108 ECDH_VALIDATE_RET( f_rng != NULL );
kenjiArai 0:5b88d5760320 109 return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
kenjiArai 0:5b88d5760320 110 }
kenjiArai 0:5b88d5760320 111 #endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
kenjiArai 0:5b88d5760320 112
kenjiArai 0:5b88d5760320 113 #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
kenjiArai 0:5b88d5760320 114 /*
kenjiArai 0:5b88d5760320 115 * Compute shared secret (SEC1 3.3.1)
kenjiArai 0:5b88d5760320 116 */
kenjiArai 0:5b88d5760320 117 static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
kenjiArai 0:5b88d5760320 118 mbedtls_mpi *z,
kenjiArai 0:5b88d5760320 119 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
kenjiArai 0:5b88d5760320 120 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 121 void *p_rng,
kenjiArai 0:5b88d5760320 122 mbedtls_ecp_restart_ctx *rs_ctx )
kenjiArai 0:5b88d5760320 123 {
kenjiArai 0:5b88d5760320 124 int ret;
kenjiArai 0:5b88d5760320 125 mbedtls_ecp_point P;
kenjiArai 0:5b88d5760320 126
kenjiArai 0:5b88d5760320 127 mbedtls_ecp_point_init( &P );
kenjiArai 0:5b88d5760320 128
kenjiArai 0:5b88d5760320 129 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q,
kenjiArai 0:5b88d5760320 130 f_rng, p_rng, rs_ctx ) );
kenjiArai 0:5b88d5760320 131
kenjiArai 0:5b88d5760320 132 if( mbedtls_ecp_is_zero( &P ) )
kenjiArai 0:5b88d5760320 133 {
kenjiArai 0:5b88d5760320 134 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 135 goto cleanup;
kenjiArai 0:5b88d5760320 136 }
kenjiArai 0:5b88d5760320 137
kenjiArai 0:5b88d5760320 138 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
kenjiArai 0:5b88d5760320 139
kenjiArai 0:5b88d5760320 140 cleanup:
kenjiArai 0:5b88d5760320 141 mbedtls_ecp_point_free( &P );
kenjiArai 0:5b88d5760320 142
kenjiArai 0:5b88d5760320 143 return( ret );
kenjiArai 0:5b88d5760320 144 }
kenjiArai 0:5b88d5760320 145
kenjiArai 0:5b88d5760320 146 /*
kenjiArai 0:5b88d5760320 147 * Compute shared secret (SEC1 3.3.1)
kenjiArai 0:5b88d5760320 148 */
kenjiArai 0:5b88d5760320 149 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
kenjiArai 0:5b88d5760320 150 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
kenjiArai 0:5b88d5760320 151 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 152 void *p_rng )
kenjiArai 0:5b88d5760320 153 {
kenjiArai 0:5b88d5760320 154 ECDH_VALIDATE_RET( grp != NULL );
kenjiArai 0:5b88d5760320 155 ECDH_VALIDATE_RET( Q != NULL );
kenjiArai 0:5b88d5760320 156 ECDH_VALIDATE_RET( d != NULL );
kenjiArai 0:5b88d5760320 157 ECDH_VALIDATE_RET( z != NULL );
kenjiArai 0:5b88d5760320 158 return( ecdh_compute_shared_restartable( grp, z, Q, d,
kenjiArai 0:5b88d5760320 159 f_rng, p_rng, NULL ) );
kenjiArai 0:5b88d5760320 160 }
kenjiArai 0:5b88d5760320 161 #endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
kenjiArai 0:5b88d5760320 162
kenjiArai 0:5b88d5760320 163 static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx )
kenjiArai 0:5b88d5760320 164 {
kenjiArai 0:5b88d5760320 165 mbedtls_ecp_group_init( &ctx->grp );
kenjiArai 0:5b88d5760320 166 mbedtls_mpi_init( &ctx->d );
kenjiArai 0:5b88d5760320 167 mbedtls_ecp_point_init( &ctx->Q );
kenjiArai 0:5b88d5760320 168 mbedtls_ecp_point_init( &ctx->Qp );
kenjiArai 0:5b88d5760320 169 mbedtls_mpi_init( &ctx->z );
kenjiArai 0:5b88d5760320 170
kenjiArai 0:5b88d5760320 171 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 172 mbedtls_ecp_restart_init( &ctx->rs );
kenjiArai 0:5b88d5760320 173 #endif
kenjiArai 0:5b88d5760320 174 }
kenjiArai 0:5b88d5760320 175
kenjiArai 0:5b88d5760320 176 /*
kenjiArai 0:5b88d5760320 177 * Initialize context
kenjiArai 0:5b88d5760320 178 */
kenjiArai 0:5b88d5760320 179 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
kenjiArai 0:5b88d5760320 180 {
kenjiArai 0:5b88d5760320 181 ECDH_VALIDATE( ctx != NULL );
kenjiArai 0:5b88d5760320 182
kenjiArai 0:5b88d5760320 183 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 184 ecdh_init_internal( ctx );
kenjiArai 0:5b88d5760320 185 mbedtls_ecp_point_init( &ctx->Vi );
kenjiArai 0:5b88d5760320 186 mbedtls_ecp_point_init( &ctx->Vf );
kenjiArai 0:5b88d5760320 187 mbedtls_mpi_init( &ctx->_d );
kenjiArai 0:5b88d5760320 188 #else
kenjiArai 0:5b88d5760320 189 memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
kenjiArai 0:5b88d5760320 190
kenjiArai 0:5b88d5760320 191 ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
kenjiArai 0:5b88d5760320 192 #endif
kenjiArai 0:5b88d5760320 193 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
kenjiArai 0:5b88d5760320 194 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 195 ctx->restart_enabled = 0;
kenjiArai 0:5b88d5760320 196 #endif
kenjiArai 0:5b88d5760320 197 }
kenjiArai 0:5b88d5760320 198
kenjiArai 0:5b88d5760320 199 static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 200 mbedtls_ecp_group_id grp_id )
kenjiArai 0:5b88d5760320 201 {
kenjiArai 0:5b88d5760320 202 int ret;
kenjiArai 0:5b88d5760320 203
kenjiArai 0:5b88d5760320 204 ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
kenjiArai 0:5b88d5760320 205 if( ret != 0 )
kenjiArai 0:5b88d5760320 206 {
kenjiArai 0:5b88d5760320 207 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
kenjiArai 0:5b88d5760320 208 }
kenjiArai 0:5b88d5760320 209
kenjiArai 0:5b88d5760320 210 return( 0 );
kenjiArai 0:5b88d5760320 211 }
kenjiArai 0:5b88d5760320 212
kenjiArai 0:5b88d5760320 213 /*
kenjiArai 0:5b88d5760320 214 * Setup context
kenjiArai 0:5b88d5760320 215 */
kenjiArai 0:5b88d5760320 216 int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
kenjiArai 0:5b88d5760320 217 {
kenjiArai 0:5b88d5760320 218 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 219
kenjiArai 0:5b88d5760320 220 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 221 return( ecdh_setup_internal( ctx, grp_id ) );
kenjiArai 0:5b88d5760320 222 #else
kenjiArai 0:5b88d5760320 223 switch( grp_id )
kenjiArai 0:5b88d5760320 224 {
kenjiArai 1:9db0e321a9f4 225 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 226 case MBEDTLS_ECP_DP_CURVE25519:
kenjiArai 1:9db0e321a9f4 227 ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
kenjiArai 1:9db0e321a9f4 228 ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
kenjiArai 1:9db0e321a9f4 229 ctx->grp_id = grp_id;
kenjiArai 1:9db0e321a9f4 230 return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
kenjiArai 1:9db0e321a9f4 231 #endif
kenjiArai 0:5b88d5760320 232 default:
kenjiArai 0:5b88d5760320 233 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
kenjiArai 0:5b88d5760320 234 ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
kenjiArai 0:5b88d5760320 235 ctx->grp_id = grp_id;
kenjiArai 0:5b88d5760320 236 ecdh_init_internal( &ctx->ctx.mbed_ecdh );
kenjiArai 0:5b88d5760320 237 return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
kenjiArai 0:5b88d5760320 238 }
kenjiArai 0:5b88d5760320 239 #endif
kenjiArai 0:5b88d5760320 240 }
kenjiArai 0:5b88d5760320 241
kenjiArai 0:5b88d5760320 242 static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx )
kenjiArai 0:5b88d5760320 243 {
kenjiArai 0:5b88d5760320 244 mbedtls_ecp_group_free( &ctx->grp );
kenjiArai 0:5b88d5760320 245 mbedtls_mpi_free( &ctx->d );
kenjiArai 0:5b88d5760320 246 mbedtls_ecp_point_free( &ctx->Q );
kenjiArai 0:5b88d5760320 247 mbedtls_ecp_point_free( &ctx->Qp );
kenjiArai 0:5b88d5760320 248 mbedtls_mpi_free( &ctx->z );
kenjiArai 0:5b88d5760320 249
kenjiArai 0:5b88d5760320 250 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 251 mbedtls_ecp_restart_free( &ctx->rs );
kenjiArai 0:5b88d5760320 252 #endif
kenjiArai 0:5b88d5760320 253 }
kenjiArai 0:5b88d5760320 254
kenjiArai 0:5b88d5760320 255 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 256 /*
kenjiArai 0:5b88d5760320 257 * Enable restartable operations for context
kenjiArai 0:5b88d5760320 258 */
kenjiArai 0:5b88d5760320 259 void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
kenjiArai 0:5b88d5760320 260 {
kenjiArai 0:5b88d5760320 261 ECDH_VALIDATE( ctx != NULL );
kenjiArai 0:5b88d5760320 262
kenjiArai 0:5b88d5760320 263 ctx->restart_enabled = 1;
kenjiArai 0:5b88d5760320 264 }
kenjiArai 0:5b88d5760320 265 #endif
kenjiArai 0:5b88d5760320 266
kenjiArai 0:5b88d5760320 267 /*
kenjiArai 0:5b88d5760320 268 * Free context
kenjiArai 0:5b88d5760320 269 */
kenjiArai 0:5b88d5760320 270 void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
kenjiArai 0:5b88d5760320 271 {
kenjiArai 0:5b88d5760320 272 if( ctx == NULL )
kenjiArai 0:5b88d5760320 273 return;
kenjiArai 0:5b88d5760320 274
kenjiArai 0:5b88d5760320 275 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 276 mbedtls_ecp_point_free( &ctx->Vi );
kenjiArai 0:5b88d5760320 277 mbedtls_ecp_point_free( &ctx->Vf );
kenjiArai 0:5b88d5760320 278 mbedtls_mpi_free( &ctx->_d );
kenjiArai 0:5b88d5760320 279 ecdh_free_internal( ctx );
kenjiArai 0:5b88d5760320 280 #else
kenjiArai 0:5b88d5760320 281 switch( ctx->var )
kenjiArai 0:5b88d5760320 282 {
kenjiArai 1:9db0e321a9f4 283 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 284 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 285 mbedtls_everest_free( &ctx->ctx.everest_ecdh );
kenjiArai 1:9db0e321a9f4 286 break;
kenjiArai 1:9db0e321a9f4 287 #endif
kenjiArai 0:5b88d5760320 288 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 289 ecdh_free_internal( &ctx->ctx.mbed_ecdh );
kenjiArai 0:5b88d5760320 290 break;
kenjiArai 0:5b88d5760320 291 default:
kenjiArai 0:5b88d5760320 292 break;
kenjiArai 0:5b88d5760320 293 }
kenjiArai 0:5b88d5760320 294
kenjiArai 0:5b88d5760320 295 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
kenjiArai 0:5b88d5760320 296 ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
kenjiArai 0:5b88d5760320 297 ctx->grp_id = MBEDTLS_ECP_DP_NONE;
kenjiArai 0:5b88d5760320 298 #endif
kenjiArai 0:5b88d5760320 299 }
kenjiArai 0:5b88d5760320 300
kenjiArai 0:5b88d5760320 301 static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 302 size_t *olen, int point_format,
kenjiArai 0:5b88d5760320 303 unsigned char *buf, size_t blen,
kenjiArai 0:5b88d5760320 304 int (*f_rng)(void *,
kenjiArai 0:5b88d5760320 305 unsigned char *,
kenjiArai 0:5b88d5760320 306 size_t),
kenjiArai 0:5b88d5760320 307 void *p_rng,
kenjiArai 0:5b88d5760320 308 int restart_enabled )
kenjiArai 0:5b88d5760320 309 {
kenjiArai 0:5b88d5760320 310 int ret;
kenjiArai 0:5b88d5760320 311 size_t grp_len, pt_len;
kenjiArai 0:5b88d5760320 312 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 313 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
kenjiArai 0:5b88d5760320 314 #endif
kenjiArai 0:5b88d5760320 315
kenjiArai 0:5b88d5760320 316 if( ctx->grp.pbits == 0 )
kenjiArai 0:5b88d5760320 317 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 318
kenjiArai 0:5b88d5760320 319 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 320 if( restart_enabled )
kenjiArai 0:5b88d5760320 321 rs_ctx = &ctx->rs;
kenjiArai 0:5b88d5760320 322 #else
kenjiArai 0:5b88d5760320 323 (void) restart_enabled;
kenjiArai 0:5b88d5760320 324 #endif
kenjiArai 0:5b88d5760320 325
kenjiArai 0:5b88d5760320 326
kenjiArai 0:5b88d5760320 327 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 328 if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
kenjiArai 0:5b88d5760320 329 f_rng, p_rng, rs_ctx ) ) != 0 )
kenjiArai 0:5b88d5760320 330 return( ret );
kenjiArai 0:5b88d5760320 331 #else
kenjiArai 0:5b88d5760320 332 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
kenjiArai 0:5b88d5760320 333 f_rng, p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 334 return( ret );
kenjiArai 0:5b88d5760320 335 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 336
kenjiArai 0:5b88d5760320 337 if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf,
kenjiArai 0:5b88d5760320 338 blen ) ) != 0 )
kenjiArai 0:5b88d5760320 339 return( ret );
kenjiArai 0:5b88d5760320 340
kenjiArai 0:5b88d5760320 341 buf += grp_len;
kenjiArai 0:5b88d5760320 342 blen -= grp_len;
kenjiArai 0:5b88d5760320 343
kenjiArai 0:5b88d5760320 344 if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format,
kenjiArai 0:5b88d5760320 345 &pt_len, buf, blen ) ) != 0 )
kenjiArai 0:5b88d5760320 346 return( ret );
kenjiArai 0:5b88d5760320 347
kenjiArai 0:5b88d5760320 348 *olen = grp_len + pt_len;
kenjiArai 0:5b88d5760320 349 return( 0 );
kenjiArai 0:5b88d5760320 350 }
kenjiArai 0:5b88d5760320 351
kenjiArai 0:5b88d5760320 352 /*
kenjiArai 1:9db0e321a9f4 353 * Setup and write the ServerKeyExchange parameters (RFC 4492)
kenjiArai 0:5b88d5760320 354 * struct {
kenjiArai 0:5b88d5760320 355 * ECParameters curve_params;
kenjiArai 0:5b88d5760320 356 * ECPoint public;
kenjiArai 0:5b88d5760320 357 * } ServerECDHParams;
kenjiArai 0:5b88d5760320 358 */
kenjiArai 0:5b88d5760320 359 int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
kenjiArai 0:5b88d5760320 360 unsigned char *buf, size_t blen,
kenjiArai 0:5b88d5760320 361 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 362 void *p_rng )
kenjiArai 0:5b88d5760320 363 {
kenjiArai 0:5b88d5760320 364 int restart_enabled = 0;
kenjiArai 0:5b88d5760320 365 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 366 ECDH_VALIDATE_RET( olen != NULL );
kenjiArai 0:5b88d5760320 367 ECDH_VALIDATE_RET( buf != NULL );
kenjiArai 0:5b88d5760320 368 ECDH_VALIDATE_RET( f_rng != NULL );
kenjiArai 0:5b88d5760320 369
kenjiArai 0:5b88d5760320 370 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 371 restart_enabled = ctx->restart_enabled;
kenjiArai 0:5b88d5760320 372 #else
kenjiArai 0:5b88d5760320 373 (void) restart_enabled;
kenjiArai 0:5b88d5760320 374 #endif
kenjiArai 0:5b88d5760320 375
kenjiArai 0:5b88d5760320 376 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 377 return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen,
kenjiArai 0:5b88d5760320 378 f_rng, p_rng, restart_enabled ) );
kenjiArai 0:5b88d5760320 379 #else
kenjiArai 0:5b88d5760320 380 switch( ctx->var )
kenjiArai 0:5b88d5760320 381 {
kenjiArai 1:9db0e321a9f4 382 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 383 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 384 return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
kenjiArai 1:9db0e321a9f4 385 buf, blen, f_rng, p_rng ) );
kenjiArai 1:9db0e321a9f4 386 #endif
kenjiArai 0:5b88d5760320 387 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 388 return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
kenjiArai 0:5b88d5760320 389 ctx->point_format, buf, blen,
kenjiArai 0:5b88d5760320 390 f_rng, p_rng,
kenjiArai 0:5b88d5760320 391 restart_enabled ) );
kenjiArai 0:5b88d5760320 392 default:
kenjiArai 0:5b88d5760320 393 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 394 }
kenjiArai 0:5b88d5760320 395 #endif
kenjiArai 0:5b88d5760320 396 }
kenjiArai 0:5b88d5760320 397
kenjiArai 0:5b88d5760320 398 static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 399 const unsigned char **buf,
kenjiArai 0:5b88d5760320 400 const unsigned char *end )
kenjiArai 0:5b88d5760320 401 {
kenjiArai 0:5b88d5760320 402 return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
kenjiArai 0:5b88d5760320 403 end - *buf ) );
kenjiArai 0:5b88d5760320 404 }
kenjiArai 0:5b88d5760320 405
kenjiArai 0:5b88d5760320 406 /*
kenjiArai 0:5b88d5760320 407 * Read the ServerKeyExhange parameters (RFC 4492)
kenjiArai 0:5b88d5760320 408 * struct {
kenjiArai 0:5b88d5760320 409 * ECParameters curve_params;
kenjiArai 0:5b88d5760320 410 * ECPoint public;
kenjiArai 0:5b88d5760320 411 * } ServerECDHParams;
kenjiArai 0:5b88d5760320 412 */
kenjiArai 0:5b88d5760320 413 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
kenjiArai 0:5b88d5760320 414 const unsigned char **buf,
kenjiArai 0:5b88d5760320 415 const unsigned char *end )
kenjiArai 0:5b88d5760320 416 {
kenjiArai 0:5b88d5760320 417 int ret;
kenjiArai 0:5b88d5760320 418 mbedtls_ecp_group_id grp_id;
kenjiArai 0:5b88d5760320 419 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 420 ECDH_VALIDATE_RET( buf != NULL );
kenjiArai 0:5b88d5760320 421 ECDH_VALIDATE_RET( *buf != NULL );
kenjiArai 0:5b88d5760320 422 ECDH_VALIDATE_RET( end != NULL );
kenjiArai 0:5b88d5760320 423
kenjiArai 0:5b88d5760320 424 if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
kenjiArai 0:5b88d5760320 425 != 0 )
kenjiArai 0:5b88d5760320 426 return( ret );
kenjiArai 0:5b88d5760320 427
kenjiArai 0:5b88d5760320 428 if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
kenjiArai 0:5b88d5760320 429 return( ret );
kenjiArai 0:5b88d5760320 430
kenjiArai 0:5b88d5760320 431 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 432 return( ecdh_read_params_internal( ctx, buf, end ) );
kenjiArai 0:5b88d5760320 433 #else
kenjiArai 0:5b88d5760320 434 switch( ctx->var )
kenjiArai 0:5b88d5760320 435 {
kenjiArai 1:9db0e321a9f4 436 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 437 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 438 return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
kenjiArai 1:9db0e321a9f4 439 buf, end) );
kenjiArai 1:9db0e321a9f4 440 #endif
kenjiArai 0:5b88d5760320 441 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 442 return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
kenjiArai 0:5b88d5760320 443 buf, end ) );
kenjiArai 0:5b88d5760320 444 default:
kenjiArai 0:5b88d5760320 445 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 446 }
kenjiArai 0:5b88d5760320 447 #endif
kenjiArai 0:5b88d5760320 448 }
kenjiArai 0:5b88d5760320 449
kenjiArai 0:5b88d5760320 450 static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 451 const mbedtls_ecp_keypair *key,
kenjiArai 0:5b88d5760320 452 mbedtls_ecdh_side side )
kenjiArai 0:5b88d5760320 453 {
kenjiArai 0:5b88d5760320 454 int ret;
kenjiArai 0:5b88d5760320 455
kenjiArai 0:5b88d5760320 456 /* If it's not our key, just import the public part as Qp */
kenjiArai 0:5b88d5760320 457 if( side == MBEDTLS_ECDH_THEIRS )
kenjiArai 0:5b88d5760320 458 return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
kenjiArai 0:5b88d5760320 459
kenjiArai 0:5b88d5760320 460 /* Our key: import public (as Q) and private parts */
kenjiArai 0:5b88d5760320 461 if( side != MBEDTLS_ECDH_OURS )
kenjiArai 0:5b88d5760320 462 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 463
kenjiArai 0:5b88d5760320 464 if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
kenjiArai 0:5b88d5760320 465 ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 )
kenjiArai 0:5b88d5760320 466 return( ret );
kenjiArai 0:5b88d5760320 467
kenjiArai 0:5b88d5760320 468 return( 0 );
kenjiArai 0:5b88d5760320 469 }
kenjiArai 0:5b88d5760320 470
kenjiArai 0:5b88d5760320 471 /*
kenjiArai 0:5b88d5760320 472 * Get parameters from a keypair
kenjiArai 0:5b88d5760320 473 */
kenjiArai 0:5b88d5760320 474 int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
kenjiArai 0:5b88d5760320 475 const mbedtls_ecp_keypair *key,
kenjiArai 0:5b88d5760320 476 mbedtls_ecdh_side side )
kenjiArai 0:5b88d5760320 477 {
kenjiArai 0:5b88d5760320 478 int ret;
kenjiArai 0:5b88d5760320 479 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 480 ECDH_VALIDATE_RET( key != NULL );
kenjiArai 0:5b88d5760320 481 ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
kenjiArai 0:5b88d5760320 482 side == MBEDTLS_ECDH_THEIRS );
kenjiArai 0:5b88d5760320 483
kenjiArai 0:5b88d5760320 484 if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE )
kenjiArai 0:5b88d5760320 485 {
kenjiArai 0:5b88d5760320 486 /* This is the first call to get_params(). Set up the context
kenjiArai 0:5b88d5760320 487 * for use with the group. */
kenjiArai 0:5b88d5760320 488 if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
kenjiArai 0:5b88d5760320 489 return( ret );
kenjiArai 0:5b88d5760320 490 }
kenjiArai 0:5b88d5760320 491 else
kenjiArai 0:5b88d5760320 492 {
kenjiArai 0:5b88d5760320 493 /* This is not the first call to get_params(). Check that the
kenjiArai 0:5b88d5760320 494 * current key's group is the same as the context's, which was set
kenjiArai 0:5b88d5760320 495 * from the first key's group. */
kenjiArai 0:5b88d5760320 496 if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id )
kenjiArai 0:5b88d5760320 497 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 498 }
kenjiArai 0:5b88d5760320 499
kenjiArai 0:5b88d5760320 500 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 501 return( ecdh_get_params_internal( ctx, key, side ) );
kenjiArai 0:5b88d5760320 502 #else
kenjiArai 0:5b88d5760320 503 switch( ctx->var )
kenjiArai 0:5b88d5760320 504 {
kenjiArai 1:9db0e321a9f4 505 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 506 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 507 {
kenjiArai 1:9db0e321a9f4 508 mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
kenjiArai 1:9db0e321a9f4 509 MBEDTLS_EVEREST_ECDH_OURS :
kenjiArai 1:9db0e321a9f4 510 MBEDTLS_EVEREST_ECDH_THEIRS;
kenjiArai 1:9db0e321a9f4 511 return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
kenjiArai 1:9db0e321a9f4 512 key, s) );
kenjiArai 1:9db0e321a9f4 513 }
kenjiArai 1:9db0e321a9f4 514 #endif
kenjiArai 0:5b88d5760320 515 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 516 return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
kenjiArai 0:5b88d5760320 517 key, side ) );
kenjiArai 0:5b88d5760320 518 default:
kenjiArai 0:5b88d5760320 519 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 520 }
kenjiArai 0:5b88d5760320 521 #endif
kenjiArai 0:5b88d5760320 522 }
kenjiArai 0:5b88d5760320 523
kenjiArai 0:5b88d5760320 524 static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 525 size_t *olen, int point_format,
kenjiArai 0:5b88d5760320 526 unsigned char *buf, size_t blen,
kenjiArai 0:5b88d5760320 527 int (*f_rng)(void *,
kenjiArai 0:5b88d5760320 528 unsigned char *,
kenjiArai 0:5b88d5760320 529 size_t),
kenjiArai 0:5b88d5760320 530 void *p_rng,
kenjiArai 0:5b88d5760320 531 int restart_enabled )
kenjiArai 0:5b88d5760320 532 {
kenjiArai 0:5b88d5760320 533 int ret;
kenjiArai 0:5b88d5760320 534 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 535 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
kenjiArai 0:5b88d5760320 536 #endif
kenjiArai 0:5b88d5760320 537
kenjiArai 0:5b88d5760320 538 if( ctx->grp.pbits == 0 )
kenjiArai 0:5b88d5760320 539 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 540
kenjiArai 0:5b88d5760320 541 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 542 if( restart_enabled )
kenjiArai 0:5b88d5760320 543 rs_ctx = &ctx->rs;
kenjiArai 0:5b88d5760320 544 #else
kenjiArai 0:5b88d5760320 545 (void) restart_enabled;
kenjiArai 0:5b88d5760320 546 #endif
kenjiArai 0:5b88d5760320 547
kenjiArai 0:5b88d5760320 548 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 549 if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
kenjiArai 0:5b88d5760320 550 f_rng, p_rng, rs_ctx ) ) != 0 )
kenjiArai 0:5b88d5760320 551 return( ret );
kenjiArai 0:5b88d5760320 552 #else
kenjiArai 0:5b88d5760320 553 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
kenjiArai 0:5b88d5760320 554 f_rng, p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 555 return( ret );
kenjiArai 0:5b88d5760320 556 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 557
kenjiArai 0:5b88d5760320 558 return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
kenjiArai 0:5b88d5760320 559 buf, blen );
kenjiArai 0:5b88d5760320 560 }
kenjiArai 0:5b88d5760320 561
kenjiArai 0:5b88d5760320 562 /*
kenjiArai 0:5b88d5760320 563 * Setup and export the client public value
kenjiArai 0:5b88d5760320 564 */
kenjiArai 0:5b88d5760320 565 int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
kenjiArai 0:5b88d5760320 566 unsigned char *buf, size_t blen,
kenjiArai 0:5b88d5760320 567 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 568 void *p_rng )
kenjiArai 0:5b88d5760320 569 {
kenjiArai 0:5b88d5760320 570 int restart_enabled = 0;
kenjiArai 0:5b88d5760320 571 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 572 ECDH_VALIDATE_RET( olen != NULL );
kenjiArai 0:5b88d5760320 573 ECDH_VALIDATE_RET( buf != NULL );
kenjiArai 0:5b88d5760320 574 ECDH_VALIDATE_RET( f_rng != NULL );
kenjiArai 0:5b88d5760320 575
kenjiArai 0:5b88d5760320 576 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 577 restart_enabled = ctx->restart_enabled;
kenjiArai 0:5b88d5760320 578 #endif
kenjiArai 0:5b88d5760320 579
kenjiArai 0:5b88d5760320 580 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 581 return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen,
kenjiArai 0:5b88d5760320 582 f_rng, p_rng, restart_enabled ) );
kenjiArai 0:5b88d5760320 583 #else
kenjiArai 0:5b88d5760320 584 switch( ctx->var )
kenjiArai 0:5b88d5760320 585 {
kenjiArai 1:9db0e321a9f4 586 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 587 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 588 return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
kenjiArai 1:9db0e321a9f4 589 buf, blen, f_rng, p_rng ) );
kenjiArai 1:9db0e321a9f4 590 #endif
kenjiArai 0:5b88d5760320 591 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 592 return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
kenjiArai 0:5b88d5760320 593 ctx->point_format, buf, blen,
kenjiArai 0:5b88d5760320 594 f_rng, p_rng,
kenjiArai 0:5b88d5760320 595 restart_enabled ) );
kenjiArai 0:5b88d5760320 596 default:
kenjiArai 0:5b88d5760320 597 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 598 }
kenjiArai 0:5b88d5760320 599 #endif
kenjiArai 0:5b88d5760320 600 }
kenjiArai 0:5b88d5760320 601
kenjiArai 0:5b88d5760320 602 static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 603 const unsigned char *buf, size_t blen )
kenjiArai 0:5b88d5760320 604 {
kenjiArai 0:5b88d5760320 605 int ret;
kenjiArai 0:5b88d5760320 606 const unsigned char *p = buf;
kenjiArai 0:5b88d5760320 607
kenjiArai 0:5b88d5760320 608 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
kenjiArai 0:5b88d5760320 609 blen ) ) != 0 )
kenjiArai 0:5b88d5760320 610 return( ret );
kenjiArai 0:5b88d5760320 611
kenjiArai 0:5b88d5760320 612 if( (size_t)( p - buf ) != blen )
kenjiArai 0:5b88d5760320 613 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 614
kenjiArai 0:5b88d5760320 615 return( 0 );
kenjiArai 0:5b88d5760320 616 }
kenjiArai 0:5b88d5760320 617
kenjiArai 0:5b88d5760320 618 /*
kenjiArai 0:5b88d5760320 619 * Parse and import the client's public value
kenjiArai 0:5b88d5760320 620 */
kenjiArai 0:5b88d5760320 621 int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
kenjiArai 0:5b88d5760320 622 const unsigned char *buf, size_t blen )
kenjiArai 0:5b88d5760320 623 {
kenjiArai 0:5b88d5760320 624 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 625 ECDH_VALIDATE_RET( buf != NULL );
kenjiArai 0:5b88d5760320 626
kenjiArai 0:5b88d5760320 627 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 628 return( ecdh_read_public_internal( ctx, buf, blen ) );
kenjiArai 0:5b88d5760320 629 #else
kenjiArai 0:5b88d5760320 630 switch( ctx->var )
kenjiArai 0:5b88d5760320 631 {
kenjiArai 1:9db0e321a9f4 632 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 633 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 634 return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
kenjiArai 1:9db0e321a9f4 635 buf, blen ) );
kenjiArai 1:9db0e321a9f4 636 #endif
kenjiArai 0:5b88d5760320 637 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 638 return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
kenjiArai 0:5b88d5760320 639 buf, blen ) );
kenjiArai 0:5b88d5760320 640 default:
kenjiArai 0:5b88d5760320 641 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 642 }
kenjiArai 0:5b88d5760320 643 #endif
kenjiArai 0:5b88d5760320 644 }
kenjiArai 0:5b88d5760320 645
kenjiArai 0:5b88d5760320 646 static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
kenjiArai 0:5b88d5760320 647 size_t *olen, unsigned char *buf,
kenjiArai 0:5b88d5760320 648 size_t blen,
kenjiArai 0:5b88d5760320 649 int (*f_rng)(void *,
kenjiArai 0:5b88d5760320 650 unsigned char *,
kenjiArai 0:5b88d5760320 651 size_t),
kenjiArai 0:5b88d5760320 652 void *p_rng,
kenjiArai 0:5b88d5760320 653 int restart_enabled )
kenjiArai 0:5b88d5760320 654 {
kenjiArai 0:5b88d5760320 655 int ret;
kenjiArai 0:5b88d5760320 656 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 657 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
kenjiArai 0:5b88d5760320 658 #endif
kenjiArai 0:5b88d5760320 659
kenjiArai 0:5b88d5760320 660 if( ctx == NULL || ctx->grp.pbits == 0 )
kenjiArai 0:5b88d5760320 661 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 662
kenjiArai 0:5b88d5760320 663 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 664 if( restart_enabled )
kenjiArai 0:5b88d5760320 665 rs_ctx = &ctx->rs;
kenjiArai 0:5b88d5760320 666 #else
kenjiArai 0:5b88d5760320 667 (void) restart_enabled;
kenjiArai 0:5b88d5760320 668 #endif
kenjiArai 0:5b88d5760320 669
kenjiArai 0:5b88d5760320 670 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 671 if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
kenjiArai 0:5b88d5760320 672 &ctx->d, f_rng, p_rng,
kenjiArai 0:5b88d5760320 673 rs_ctx ) ) != 0 )
kenjiArai 0:5b88d5760320 674 {
kenjiArai 0:5b88d5760320 675 return( ret );
kenjiArai 0:5b88d5760320 676 }
kenjiArai 0:5b88d5760320 677 #else
kenjiArai 0:5b88d5760320 678 if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp,
kenjiArai 0:5b88d5760320 679 &ctx->d, f_rng, p_rng ) ) != 0 )
kenjiArai 0:5b88d5760320 680 {
kenjiArai 0:5b88d5760320 681 return( ret );
kenjiArai 0:5b88d5760320 682 }
kenjiArai 0:5b88d5760320 683 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 684
kenjiArai 0:5b88d5760320 685 if( mbedtls_mpi_size( &ctx->z ) > blen )
kenjiArai 0:5b88d5760320 686 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 687
kenjiArai 0:5b88d5760320 688 *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
kenjiArai 0:5b88d5760320 689
kenjiArai 0:5b88d5760320 690 if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
kenjiArai 0:5b88d5760320 691 return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
kenjiArai 0:5b88d5760320 692
kenjiArai 0:5b88d5760320 693 return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
kenjiArai 0:5b88d5760320 694 }
kenjiArai 0:5b88d5760320 695
kenjiArai 0:5b88d5760320 696 /*
kenjiArai 0:5b88d5760320 697 * Derive and export the shared secret
kenjiArai 0:5b88d5760320 698 */
kenjiArai 0:5b88d5760320 699 int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
kenjiArai 0:5b88d5760320 700 unsigned char *buf, size_t blen,
kenjiArai 0:5b88d5760320 701 int (*f_rng)(void *, unsigned char *, size_t),
kenjiArai 0:5b88d5760320 702 void *p_rng )
kenjiArai 0:5b88d5760320 703 {
kenjiArai 0:5b88d5760320 704 int restart_enabled = 0;
kenjiArai 0:5b88d5760320 705 ECDH_VALIDATE_RET( ctx != NULL );
kenjiArai 0:5b88d5760320 706 ECDH_VALIDATE_RET( olen != NULL );
kenjiArai 0:5b88d5760320 707 ECDH_VALIDATE_RET( buf != NULL );
kenjiArai 0:5b88d5760320 708
kenjiArai 0:5b88d5760320 709 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 710 restart_enabled = ctx->restart_enabled;
kenjiArai 0:5b88d5760320 711 #endif
kenjiArai 0:5b88d5760320 712
kenjiArai 0:5b88d5760320 713 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
kenjiArai 0:5b88d5760320 714 return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng,
kenjiArai 0:5b88d5760320 715 restart_enabled ) );
kenjiArai 0:5b88d5760320 716 #else
kenjiArai 0:5b88d5760320 717 switch( ctx->var )
kenjiArai 0:5b88d5760320 718 {
kenjiArai 1:9db0e321a9f4 719 #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
kenjiArai 1:9db0e321a9f4 720 case MBEDTLS_ECDH_VARIANT_EVEREST:
kenjiArai 1:9db0e321a9f4 721 return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
kenjiArai 1:9db0e321a9f4 722 buf, blen, f_rng, p_rng ) );
kenjiArai 1:9db0e321a9f4 723 #endif
kenjiArai 0:5b88d5760320 724 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
kenjiArai 0:5b88d5760320 725 return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
kenjiArai 0:5b88d5760320 726 blen, f_rng, p_rng,
kenjiArai 0:5b88d5760320 727 restart_enabled ) );
kenjiArai 0:5b88d5760320 728 default:
kenjiArai 0:5b88d5760320 729 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 730 }
kenjiArai 0:5b88d5760320 731 #endif
kenjiArai 0:5b88d5760320 732 }
kenjiArai 0:5b88d5760320 733
kenjiArai 0:5b88d5760320 734 #endif /* MBEDTLS_ECDH_C */