Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecdh.c Source File

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 */