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.
Fork of mbedtls by
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 /* 00042 * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair 00043 */ 00044 int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, 00045 int (*f_rng)(void *, unsigned char *, size_t), 00046 void *p_rng ) 00047 { 00048 return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); 00049 } 00050 00051 /* 00052 * Compute shared secret (SEC1 3.3.1) 00053 */ 00054 int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, 00055 const mbedtls_ecp_point *Q, const mbedtls_mpi *d, 00056 int (*f_rng)(void *, unsigned char *, size_t), 00057 void *p_rng ) 00058 { 00059 int ret; 00060 mbedtls_ecp_point P; 00061 00062 mbedtls_ecp_point_init( &P ); 00063 00064 /* 00065 * Make sure Q is a valid pubkey before using it 00066 */ 00067 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); 00068 00069 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); 00070 00071 if( mbedtls_ecp_is_zero( &P ) ) 00072 { 00073 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00074 goto cleanup; 00075 } 00076 00077 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); 00078 00079 cleanup: 00080 mbedtls_ecp_point_free( &P ); 00081 00082 return( ret ); 00083 } 00084 00085 /* 00086 * Initialize context 00087 */ 00088 void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) 00089 { 00090 memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); 00091 } 00092 00093 /* 00094 * Free context 00095 */ 00096 void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) 00097 { 00098 if( ctx == NULL ) 00099 return; 00100 00101 mbedtls_ecp_group_free( &ctx->grp ); 00102 mbedtls_ecp_point_free( &ctx->Q ); 00103 mbedtls_ecp_point_free( &ctx->Qp ); 00104 mbedtls_ecp_point_free( &ctx->Vi ); 00105 mbedtls_ecp_point_free( &ctx->Vf ); 00106 mbedtls_mpi_free( &ctx->d ); 00107 mbedtls_mpi_free( &ctx->z ); 00108 mbedtls_mpi_free( &ctx->_d ); 00109 } 00110 00111 /* 00112 * Setup and write the ServerKeyExhange parameters (RFC 4492) 00113 * struct { 00114 * ECParameters curve_params; 00115 * ECPoint public; 00116 * } ServerECDHParams; 00117 */ 00118 int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, 00119 unsigned char *buf, size_t blen, 00120 int (*f_rng)(void *, unsigned char *, size_t), 00121 void *p_rng ) 00122 { 00123 int ret; 00124 size_t grp_len, pt_len; 00125 00126 if( ctx == NULL || ctx->grp .pbits == 0 ) 00127 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00128 00129 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00130 != 0 ) 00131 return( ret ); 00132 00133 if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp , &grp_len, buf, blen ) ) 00134 != 0 ) 00135 return( ret ); 00136 00137 buf += grp_len; 00138 blen -= grp_len; 00139 00140 if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00141 &pt_len, buf, blen ) ) != 0 ) 00142 return( ret ); 00143 00144 *olen = grp_len + pt_len; 00145 return( 0 ); 00146 } 00147 00148 /* 00149 * Read the ServerKeyExhange parameters (RFC 4492) 00150 * struct { 00151 * ECParameters curve_params; 00152 * ECPoint public; 00153 * } ServerECDHParams; 00154 */ 00155 int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, 00156 const unsigned char **buf, const unsigned char *end ) 00157 { 00158 int ret; 00159 00160 if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp , buf, end - *buf ) ) != 0 ) 00161 return( ret ); 00162 00163 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp , &ctx->Qp , buf, end - *buf ) ) 00164 != 0 ) 00165 return( ret ); 00166 00167 return( 0 ); 00168 } 00169 00170 /* 00171 * Get parameters from a keypair 00172 */ 00173 int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, 00174 mbedtls_ecdh_side side ) 00175 { 00176 int ret; 00177 00178 if( ( ret = mbedtls_ecp_group_copy( &ctx->grp , &key->grp ) ) != 0 ) 00179 return( ret ); 00180 00181 /* If it's not our key, just import the public part as Qp */ 00182 if( side == MBEDTLS_ECDH_THEIRS ) 00183 return( mbedtls_ecp_copy( &ctx->Qp , &key->Q ) ); 00184 00185 /* Our key: import public (as Q) and private parts */ 00186 if( side != MBEDTLS_ECDH_OURS ) 00187 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00188 00189 if( ( ret = mbedtls_ecp_copy( &ctx->Q , &key->Q ) ) != 0 || 00190 ( ret = mbedtls_mpi_copy( &ctx->d , &key->d ) ) != 0 ) 00191 return( ret ); 00192 00193 return( 0 ); 00194 } 00195 00196 /* 00197 * Setup and export the client public value 00198 */ 00199 int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, 00200 unsigned char *buf, size_t blen, 00201 int (*f_rng)(void *, unsigned char *, size_t), 00202 void *p_rng ) 00203 { 00204 int ret; 00205 00206 if( ctx == NULL || ctx->grp .pbits == 0 ) 00207 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00208 00209 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00210 != 0 ) 00211 return( ret ); 00212 00213 return mbedtls_ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00214 olen, buf, blen ); 00215 } 00216 00217 /* 00218 * Parse and import the client's public value 00219 */ 00220 int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, 00221 const unsigned char *buf, size_t blen ) 00222 { 00223 int ret; 00224 const unsigned char *p = buf; 00225 00226 if( ctx == NULL ) 00227 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00228 00229 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp , &ctx->Qp , &p, blen ) ) != 0 ) 00230 return( ret ); 00231 00232 if( (size_t)( p - buf ) != blen ) 00233 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00234 00235 return( 0 ); 00236 } 00237 00238 /* 00239 * Derive and export the shared secret 00240 */ 00241 int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, 00242 unsigned char *buf, size_t blen, 00243 int (*f_rng)(void *, unsigned char *, size_t), 00244 void *p_rng ) 00245 { 00246 int ret; 00247 00248 if( ctx == NULL ) 00249 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00250 00251 if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp , &ctx->z , &ctx->Qp , &ctx->d , 00252 f_rng, p_rng ) ) != 0 ) 00253 { 00254 return( ret ); 00255 } 00256 00257 if( mbedtls_mpi_size( &ctx->z ) > blen ) 00258 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00259 00260 *olen = ctx->grp .pbits / 8 + ( ( ctx->grp .pbits % 8 ) != 0 ); 00261 return mbedtls_mpi_write_binary( &ctx->z , buf, *olen ); 00262 } 00263 00264 #endif /* MBEDTLS_ECDH_C */
Generated on Tue Jul 12 2022 12:52:43 by
