mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
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
![doxygen](doxygen.png)