Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ecdh.c
00001 /* 00002 * Elliptic curve Diffie-Hellman 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 /* 00023 * References: 00024 * 00025 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg 00026 * RFC 4492 00027 */ 00028 00029 #if !defined(MBEDTLS_CONFIG_FILE) 00030 #include "mbedtls/config.h" 00031 #else 00032 #include MBEDTLS_CONFIG_FILE 00033 #endif 00034 00035 #if defined(MBEDTLS_ECDH_C) 00036 00037 #include "mbedtls/ecdh.h" 00038 00039 #include <string.h> 00040 00041 #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) 00042 /* 00043 * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair 00044 */ 00045 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, 00046 int (*f_rng)(void *, unsigned char *, size_t), 00047 void *p_rng ) 00048 { 00049 return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); 00050 } 00051 #endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */ 00052 00053 #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) 00054 /* 00055 * Compute shared secret (SEC1 3.3.1) 00056 */ 00057 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, 00058 const mbedtls_ecp_point *Q, const mbedtls_mpi *d, 00059 int (*f_rng)(void *, unsigned char *, size_t), 00060 void *p_rng ) 00061 { 00062 int ret; 00063 mbedtls_ecp_point P; 00064 00065 mbedtls_ecp_point_init( &P ); 00066 00067 /* 00068 * Make sure Q is a valid pubkey before using it 00069 */ 00070 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); 00071 00072 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); 00073 00074 if( mbedtls_ecp_is_zero( &P ) ) 00075 { 00076 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00077 goto cleanup; 00078 } 00079 00080 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); 00081 00082 cleanup: 00083 mbedtls_ecp_point_free( &P ); 00084 00085 return( ret ); 00086 } 00087 #endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ 00088 00089 /* 00090 * Initialize context 00091 */ 00092 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) 00093 { 00094 memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); 00095 } 00096 00097 /* 00098 * Free context 00099 */ 00100 void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) 00101 { 00102 if( ctx == NULL ) 00103 return; 00104 00105 mbedtls_ecp_group_free( &ctx->grp ); 00106 mbedtls_ecp_point_free( &ctx->Q ); 00107 mbedtls_ecp_point_free( &ctx->Qp ); 00108 mbedtls_ecp_point_free( &ctx->Vi ); 00109 mbedtls_ecp_point_free( &ctx->Vf ); 00110 mbedtls_mpi_free( &ctx->d ); 00111 mbedtls_mpi_free( &ctx->z ); 00112 mbedtls_mpi_free( &ctx->_d ); 00113 } 00114 00115 /* 00116 * Setup and write the ServerKeyExhange parameters (RFC 4492) 00117 * struct { 00118 * ECParameters curve_params; 00119 * ECPoint public; 00120 * } ServerECDHParams; 00121 */ 00122 int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, 00123 unsigned char *buf, size_t blen, 00124 int (*f_rng)(void *, unsigned char *, size_t), 00125 void *p_rng ) 00126 { 00127 int ret; 00128 size_t grp_len, pt_len; 00129 00130 if( ctx == NULL || ctx->grp .pbits == 0 ) 00131 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00132 00133 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00134 != 0 ) 00135 return( ret ); 00136 00137 if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp , &grp_len, buf, blen ) ) 00138 != 0 ) 00139 return( ret ); 00140 00141 buf += grp_len; 00142 blen -= grp_len; 00143 00144 if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00145 &pt_len, buf, blen ) ) != 0 ) 00146 return( ret ); 00147 00148 *olen = grp_len + pt_len; 00149 return( 0 ); 00150 } 00151 00152 /* 00153 * Read the ServerKeyExhange parameters (RFC 4492) 00154 * struct { 00155 * ECParameters curve_params; 00156 * ECPoint public; 00157 * } ServerECDHParams; 00158 */ 00159 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, 00160 const unsigned char **buf, const unsigned char *end ) 00161 { 00162 int ret; 00163 00164 if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp , buf, end - *buf ) ) != 0 ) 00165 return( ret ); 00166 00167 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp , &ctx->Qp , buf, end - *buf ) ) 00168 != 0 ) 00169 return( ret ); 00170 00171 return( 0 ); 00172 } 00173 00174 /* 00175 * Get parameters from a keypair 00176 */ 00177 int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, 00178 mbedtls_ecdh_side side ) 00179 { 00180 int ret; 00181 00182 if( ( ret = mbedtls_ecp_group_copy( &ctx->grp , &key->grp ) ) != 0 ) 00183 return( ret ); 00184 00185 /* If it's not our key, just import the public part as Qp */ 00186 if( side == MBEDTLS_ECDH_THEIRS ) 00187 return( mbedtls_ecp_copy( &ctx->Qp , &key->Q ) ); 00188 00189 /* Our key: import public (as Q) and private parts */ 00190 if( side != MBEDTLS_ECDH_OURS ) 00191 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00192 00193 if( ( ret = mbedtls_ecp_copy( &ctx->Q , &key->Q ) ) != 0 || 00194 ( ret = mbedtls_mpi_copy( &ctx->d , &key->d ) ) != 0 ) 00195 return( ret ); 00196 00197 return( 0 ); 00198 } 00199 00200 /* 00201 * Setup and export the client public value 00202 */ 00203 int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, 00204 unsigned char *buf, size_t blen, 00205 int (*f_rng)(void *, unsigned char *, size_t), 00206 void *p_rng ) 00207 { 00208 int ret; 00209 00210 if( ctx == NULL || ctx->grp .pbits == 0 ) 00211 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00212 00213 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00214 != 0 ) 00215 return( ret ); 00216 00217 return mbedtls_ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00218 olen, buf, blen ); 00219 } 00220 00221 /* 00222 * Parse and import the client's public value 00223 */ 00224 int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, 00225 const unsigned char *buf, size_t blen ) 00226 { 00227 int ret; 00228 const unsigned char *p = buf; 00229 00230 if( ctx == NULL ) 00231 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00232 00233 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp , &ctx->Qp , &p, blen ) ) != 0 ) 00234 return( ret ); 00235 00236 if( (size_t)( p - buf ) != blen ) 00237 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00238 00239 return( 0 ); 00240 } 00241 00242 /* 00243 * Derive and export the shared secret 00244 */ 00245 int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, 00246 unsigned char *buf, size_t blen, 00247 int (*f_rng)(void *, unsigned char *, size_t), 00248 void *p_rng ) 00249 { 00250 int ret; 00251 00252 if( ctx == NULL ) 00253 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00254 00255 if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp , &ctx->z , &ctx->Qp , &ctx->d , 00256 f_rng, p_rng ) ) != 0 ) 00257 { 00258 return( ret ); 00259 } 00260 00261 if( mbedtls_mpi_size( &ctx->z ) > blen ) 00262 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00263 00264 *olen = ctx->grp .pbits / 8 + ( ( ctx->grp .pbits % 8 ) != 0 ); 00265 return mbedtls_mpi_write_binary( &ctx->z , buf, *olen ); 00266 } 00267 00268 #endif /* MBEDTLS_ECDH_C */
Generated on Tue Jul 12 2022 12:43:50 by
