Hannes Tschofenig
/
aes-gcm-test-program
Example program to test AES-GCM functionality. Used for a workshop
Embed:
(wiki syntax)
Show/hide line numbers
ecdh.c
00001 /* 00002 * Elliptic curve Diffie-Hellman 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 /* 00027 * References: 00028 * 00029 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg 00030 * RFC 4492 00031 */ 00032 00033 #if !defined(POLARSSL_CONFIG_FILE) 00034 #include "polarssl/config.h" 00035 #else 00036 #include POLARSSL_CONFIG_FILE 00037 #endif 00038 00039 #if defined(POLARSSL_ECDH_C) 00040 00041 #include "polarssl/ecdh.h" 00042 00043 /* 00044 * Generate public key: simple wrapper around ecp_gen_keypair 00045 */ 00046 int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q, 00047 int (*f_rng)(void *, unsigned char *, size_t), 00048 void *p_rng ) 00049 { 00050 return ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); 00051 } 00052 00053 /* 00054 * Compute shared secret (SEC1 3.3.1) 00055 */ 00056 int ecdh_compute_shared( ecp_group *grp, mpi *z, 00057 const ecp_point *Q, const mpi *d, 00058 int (*f_rng)(void *, unsigned char *, size_t), 00059 void *p_rng ) 00060 { 00061 int ret; 00062 ecp_point P; 00063 00064 ecp_point_init( &P ); 00065 00066 /* 00067 * Make sure Q is a valid pubkey before using it 00068 */ 00069 MPI_CHK( ecp_check_pubkey( grp, Q ) ); 00070 00071 MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); 00072 00073 if( ecp_is_zero( &P ) ) 00074 { 00075 ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA; 00076 goto cleanup; 00077 } 00078 00079 MPI_CHK( mpi_copy( z, &P.X ) ); 00080 00081 cleanup: 00082 ecp_point_free( &P ); 00083 00084 return( ret ); 00085 } 00086 00087 /* 00088 * Initialize context 00089 */ 00090 void ecdh_init( ecdh_context *ctx ) 00091 { 00092 memset( ctx, 0, sizeof( ecdh_context ) ); 00093 } 00094 00095 /* 00096 * Free context 00097 */ 00098 void ecdh_free( ecdh_context *ctx ) 00099 { 00100 if( ctx == NULL ) 00101 return; 00102 00103 ecp_group_free( &ctx->grp ); 00104 mpi_free ( &ctx->d ); 00105 ecp_point_free( &ctx->Q ); 00106 ecp_point_free( &ctx->Qp ); 00107 mpi_free ( &ctx->z ); 00108 ecp_point_free( &ctx->Vi ); 00109 ecp_point_free( &ctx->Vf ); 00110 mpi_free ( &ctx->_d ); 00111 } 00112 00113 /* 00114 * Setup and write the ServerKeyExhange parameters (RFC 4492) 00115 * struct { 00116 * ECParameters curve_params; 00117 * ECPoint public; 00118 * } ServerECDHParams; 00119 */ 00120 int ecdh_make_params( ecdh_context *ctx, size_t *olen, 00121 unsigned char *buf, size_t blen, 00122 int (*f_rng)(void *, unsigned char *, size_t), 00123 void *p_rng ) 00124 { 00125 int ret; 00126 size_t grp_len, pt_len; 00127 00128 if( ctx == NULL || ctx->grp .pbits == 0 ) 00129 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00130 00131 if( ( ret = ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00132 != 0 ) 00133 return( ret ); 00134 00135 if( ( ret = ecp_tls_write_group( &ctx->grp , &grp_len, buf, blen ) ) 00136 != 0 ) 00137 return( ret ); 00138 00139 buf += grp_len; 00140 blen -= grp_len; 00141 00142 if( ( ret = ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00143 &pt_len, buf, blen ) ) != 0 ) 00144 return( ret ); 00145 00146 *olen = grp_len + pt_len; 00147 return 0; 00148 } 00149 00150 /* 00151 * Read the ServerKeyExhange parameters (RFC 4492) 00152 * struct { 00153 * ECParameters curve_params; 00154 * ECPoint public; 00155 * } ServerECDHParams; 00156 */ 00157 int ecdh_read_params( ecdh_context *ctx, 00158 const unsigned char **buf, const unsigned char *end ) 00159 { 00160 int ret; 00161 00162 if( ( ret = ecp_tls_read_group( &ctx->grp , buf, end - *buf ) ) != 0 ) 00163 return( ret ); 00164 00165 if( ( ret = ecp_tls_read_point( &ctx->grp , &ctx->Qp , buf, end - *buf ) ) 00166 != 0 ) 00167 return( ret ); 00168 00169 return 0; 00170 } 00171 00172 /* 00173 * Get parameters from a keypair 00174 */ 00175 int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, 00176 ecdh_side side ) 00177 { 00178 int ret; 00179 00180 if( ( ret = ecp_group_copy( &ctx->grp , &key->grp ) ) != 0 ) 00181 return( ret ); 00182 00183 /* If it's not our key, just import the public part as Qp */ 00184 if( side == POLARSSL_ECDH_THEIRS ) 00185 return( ecp_copy( &ctx->Qp , &key->Q ) ); 00186 00187 /* Our key: import public (as Q) and private parts */ 00188 if( side != POLARSSL_ECDH_OURS ) 00189 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00190 00191 if( ( ret = ecp_copy( &ctx->Q , &key->Q ) ) != 0 || 00192 ( ret = mpi_copy( &ctx->d , &key->d ) ) != 0 ) 00193 return( ret ); 00194 00195 return( 0 ); 00196 } 00197 00198 /* 00199 * Setup and export the client public value 00200 */ 00201 int ecdh_make_public( ecdh_context *ctx, size_t *olen, 00202 unsigned char *buf, size_t blen, 00203 int (*f_rng)(void *, unsigned char *, size_t), 00204 void *p_rng ) 00205 { 00206 int ret; 00207 00208 if( ctx == NULL || ctx->grp .pbits == 0 ) 00209 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00210 00211 if( ( ret = ecdh_gen_public( &ctx->grp , &ctx->d , &ctx->Q , f_rng, p_rng ) ) 00212 != 0 ) 00213 return( ret ); 00214 00215 return ecp_tls_write_point( &ctx->grp , &ctx->Q , ctx->point_format , 00216 olen, buf, blen ); 00217 } 00218 00219 /* 00220 * Parse and import the client's public value 00221 */ 00222 int ecdh_read_public( ecdh_context *ctx, 00223 const unsigned char *buf, size_t blen ) 00224 { 00225 int ret; 00226 const unsigned char *p = buf; 00227 00228 if( ctx == NULL ) 00229 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00230 00231 if( ( ret = ecp_tls_read_point( &ctx->grp , &ctx->Qp , &p, blen ) ) != 0 ) 00232 return( ret ); 00233 00234 if( (size_t)( p - buf ) != blen ) 00235 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00236 00237 return( 0 ); 00238 } 00239 00240 /* 00241 * Derive and export the shared secret 00242 */ 00243 int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, 00244 unsigned char *buf, size_t blen, 00245 int (*f_rng)(void *, unsigned char *, size_t), 00246 void *p_rng ) 00247 { 00248 int ret; 00249 00250 if( ctx == NULL ) 00251 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00252 00253 if( ( ret = ecdh_compute_shared( &ctx->grp , &ctx->z , &ctx->Qp , &ctx->d , 00254 f_rng, p_rng ) ) != 0 ) 00255 { 00256 return( ret ); 00257 } 00258 00259 if( mpi_size( &ctx->z ) > blen ) 00260 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); 00261 00262 *olen = ctx->grp .pbits / 8 + ( ( ctx->grp .pbits % 8 ) != 0 ); 00263 return mpi_write_binary( &ctx->z , buf, *olen ); 00264 } 00265 00266 00267 #if defined(POLARSSL_SELF_TEST) 00268 00269 /* 00270 * Checkup routine 00271 */ 00272 int ecdh_self_test( int verbose ) 00273 { 00274 ((void) verbose ); 00275 return( 0 ); 00276 } 00277 00278 #endif /* POLARSSL_SELF_TEST */ 00279 00280 #endif /* POLARSSL_ECDH_C */ 00281 00282
Generated on Tue Jul 12 2022 19:40:15 by 1.7.2