| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | *  Elliptic curve Diffie-Hellman | 
|  | 3 | * | 
| Manuel Pégourié-Gonnard | 6fb8187 | 2015-07-27 11:11:48 +0200 | [diff] [blame] | 4 | *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved | 
| Manuel Pégourié-Gonnard | 37ff140 | 2015-09-04 14:21:07 +0200 | [diff] [blame] | 5 | *  SPDX-License-Identifier: Apache-2.0 | 
|  | 6 | * | 
|  | 7 | *  Licensed under the Apache License, Version 2.0 (the "License"); you may | 
|  | 8 | *  not use this file except in compliance with the License. | 
|  | 9 | *  You may obtain a copy of the License at | 
|  | 10 | * | 
|  | 11 | *  http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 12 | * | 
|  | 13 | *  Unless required by applicable law or agreed to in writing, software | 
|  | 14 | *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
|  | 15 | *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 16 | *  See the License for the specific language governing permissions and | 
|  | 17 | *  limitations under the License. | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 18 | * | 
| Manuel Pégourié-Gonnard | fe44643 | 2015-03-06 13:17:10 +0000 | [diff] [blame] | 19 | *  This file is part of mbed TLS (https://tls.mbed.org) | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 20 | */ | 
|  | 21 |  | 
|  | 22 | /* | 
|  | 23 | * References: | 
|  | 24 | * | 
|  | 25 | * SEC1 http://www.secg.org/index.php?action=secg,docs_secg | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 26 | * RFC 4492 | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 27 | */ | 
|  | 28 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 29 | #if !defined(MBEDTLS_CONFIG_FILE) | 
| Manuel Pégourié-Gonnard | 7f80997 | 2015-03-09 17:05:11 +0000 | [diff] [blame] | 30 | #include "mbedtls/config.h" | 
| Manuel Pégourié-Gonnard | cef4ad2 | 2014-04-29 12:39:06 +0200 | [diff] [blame] | 31 | #else | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 32 | #include MBEDTLS_CONFIG_FILE | 
| Manuel Pégourié-Gonnard | cef4ad2 | 2014-04-29 12:39:06 +0200 | [diff] [blame] | 33 | #endif | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 34 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 35 | #if defined(MBEDTLS_ECDH_C) | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 36 |  | 
| Manuel Pégourié-Gonnard | 7f80997 | 2015-03-09 17:05:11 +0000 | [diff] [blame] | 37 | #include "mbedtls/ecdh.h" | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 38 |  | 
| Rich Evans | 00ab470 | 2015-02-06 13:43:58 +0000 | [diff] [blame] | 39 | #include <string.h> | 
|  | 40 |  | 
| Ron Eldor | a84c1cb | 2017-10-10 19:04:27 +0300 | [diff] [blame] | 41 | #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 42 | /* | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 43 | * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 44 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 45 | int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 46 | int (*f_rng)(void *, unsigned char *, size_t), | 
|  | 47 | void *p_rng ) | 
|  | 48 | { | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 49 | return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 50 | } | 
| Ron Eldor | a84c1cb | 2017-10-10 19:04:27 +0300 | [diff] [blame] | 51 | #endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */ | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 52 |  | 
| Ron Eldor | a84c1cb | 2017-10-10 19:04:27 +0300 | [diff] [blame] | 53 | #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 54 | /* | 
|  | 55 | * Compute shared secret (SEC1 3.3.1) | 
|  | 56 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 57 | int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, | 
|  | 58 | const mbedtls_ecp_point *Q, const mbedtls_mpi *d, | 
| Manuel Pégourié-Gonnard | e09d2f8 | 2013-09-02 14:29:09 +0200 | [diff] [blame] | 59 | int (*f_rng)(void *, unsigned char *, size_t), | 
|  | 60 | void *p_rng ) | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 61 | { | 
|  | 62 | int ret; | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 63 | mbedtls_ecp_point P; | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 64 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 65 | mbedtls_ecp_point_init( &P ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 66 |  | 
|  | 67 | /* | 
|  | 68 | * Make sure Q is a valid pubkey before using it | 
|  | 69 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 70 | MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 71 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 72 | MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 73 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 74 | if( mbedtls_ecp_is_zero( &P ) ) | 
| Paul Bakker | b548d77 | 2013-07-26 14:21:34 +0200 | [diff] [blame] | 75 | { | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 76 | ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; | 
| Paul Bakker | b548d77 | 2013-07-26 14:21:34 +0200 | [diff] [blame] | 77 | goto cleanup; | 
|  | 78 | } | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 79 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 80 | MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 81 |  | 
|  | 82 | cleanup: | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 83 | mbedtls_ecp_point_free( &P ); | 
| Manuel Pégourié-Gonnard | 6545ca7 | 2013-01-26 16:05:22 +0100 | [diff] [blame] | 84 |  | 
|  | 85 | return( ret ); | 
|  | 86 | } | 
| Ron Eldor | a84c1cb | 2017-10-10 19:04:27 +0300 | [diff] [blame] | 87 | #endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ | 
|  | 88 |  | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 89 | /* | 
|  | 90 | * Initialize context | 
|  | 91 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 92 | void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 93 | { | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 94 | memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 95 | } | 
|  | 96 |  | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 97 | /* | 
|  | 98 | * Free context | 
|  | 99 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 100 | void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 101 | { | 
|  | 102 | if( ctx == NULL ) | 
|  | 103 | return; | 
|  | 104 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 105 | mbedtls_ecp_group_free( &ctx->grp ); | 
|  | 106 | mbedtls_ecp_point_free( &ctx->Q   ); | 
|  | 107 | mbedtls_ecp_point_free( &ctx->Qp  ); | 
|  | 108 | mbedtls_ecp_point_free( &ctx->Vi  ); | 
|  | 109 | mbedtls_ecp_point_free( &ctx->Vf  ); | 
|  | 110 | mbedtls_mpi_free( &ctx->d  ); | 
|  | 111 | mbedtls_mpi_free( &ctx->z  ); | 
|  | 112 | mbedtls_mpi_free( &ctx->_d ); | 
| Manuel Pégourié-Gonnard | 63533e4 | 2013-02-10 14:21:04 +0100 | [diff] [blame] | 113 | } | 
|  | 114 |  | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 115 | /* | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 116 | * Setup and write the ServerKeyExhange parameters (RFC 4492) | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 117 | *      struct { | 
|  | 118 | *          ECParameters    curve_params; | 
|  | 119 | *          ECPoint         public; | 
|  | 120 | *      } ServerECDHParams; | 
|  | 121 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 122 | int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 123 | unsigned char *buf, size_t blen, | 
|  | 124 | int (*f_rng)(void *, unsigned char *, size_t), | 
|  | 125 | void *p_rng ) | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 126 | { | 
|  | 127 | int ret; | 
|  | 128 | size_t grp_len, pt_len; | 
|  | 129 |  | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 130 | if( ctx == NULL || ctx->grp.pbits == 0 ) | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 131 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 132 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 133 | if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 134 | != 0 ) | 
|  | 135 | return( ret ); | 
|  | 136 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 137 | if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) ) | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 138 | != 0 ) | 
|  | 139 | return( ret ); | 
|  | 140 |  | 
|  | 141 | buf += grp_len; | 
|  | 142 | blen -= grp_len; | 
|  | 143 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 144 | if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 145 | &pt_len, buf, blen ) ) != 0 ) | 
|  | 146 | return( ret ); | 
|  | 147 |  | 
|  | 148 | *olen = grp_len + pt_len; | 
| Paul Bakker | d8bb826 | 2014-06-17 14:06:49 +0200 | [diff] [blame] | 149 | return( 0 ); | 
| Manuel Pégourié-Gonnard | 1372476 | 2013-02-10 15:01:54 +0100 | [diff] [blame] | 150 | } | 
|  | 151 |  | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 152 | /* | 
|  | 153 | * Read the ServerKeyExhange parameters (RFC 4492) | 
|  | 154 | *      struct { | 
|  | 155 | *          ECParameters    curve_params; | 
|  | 156 | *          ECPoint         public; | 
|  | 157 | *      } ServerECDHParams; | 
|  | 158 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 159 | int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 160 | const unsigned char **buf, const unsigned char *end ) | 
|  | 161 | { | 
|  | 162 | int ret; | 
|  | 163 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 164 | if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 165 | return( ret ); | 
|  | 166 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 167 | if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 168 | != 0 ) | 
|  | 169 | return( ret ); | 
|  | 170 |  | 
| Paul Bakker | d8bb826 | 2014-06-17 14:06:49 +0200 | [diff] [blame] | 171 | return( 0 ); | 
| Manuel Pégourié-Gonnard | 854fbd7 | 2013-02-11 20:28:55 +0100 | [diff] [blame] | 172 | } | 
| Manuel Pégourié-Gonnard | 0bad5c2 | 2013-01-26 15:30:46 +0100 | [diff] [blame] | 173 |  | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 174 | /* | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 175 | * Get parameters from a keypair | 
|  | 176 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 177 | int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, | 
|  | 178 | mbedtls_ecdh_side side ) | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 179 | { | 
|  | 180 | int ret; | 
|  | 181 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 182 | if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 183 | return( ret ); | 
|  | 184 |  | 
|  | 185 | /* If it's not our key, just import the public part as Qp */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 186 | if( side == MBEDTLS_ECDH_THEIRS ) | 
|  | 187 | return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 188 |  | 
|  | 189 | /* Our key: import public (as Q) and private parts */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 190 | if( side != MBEDTLS_ECDH_OURS ) | 
|  | 191 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 192 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 193 | if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || | 
|  | 194 | ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) | 
| Manuel Pégourié-Gonnard | cdff3cf | 2013-12-12 09:55:52 +0100 | [diff] [blame] | 195 | return( ret ); | 
|  | 196 |  | 
|  | 197 | return( 0 ); | 
|  | 198 | } | 
|  | 199 |  | 
|  | 200 | /* | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 201 | * Setup and export the client public value | 
|  | 202 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 203 | int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 204 | unsigned char *buf, size_t blen, | 
|  | 205 | int (*f_rng)(void *, unsigned char *, size_t), | 
|  | 206 | void *p_rng ) | 
|  | 207 | { | 
|  | 208 | int ret; | 
|  | 209 |  | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 210 | if( ctx == NULL || ctx->grp.pbits == 0 ) | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 211 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 212 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 213 | if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 214 | != 0 ) | 
|  | 215 | return( ret ); | 
|  | 216 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 217 | return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 218 | olen, buf, blen ); | 
|  | 219 | } | 
|  | 220 |  | 
|  | 221 | /* | 
|  | 222 | * Parse and import the client's public value | 
|  | 223 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 224 | int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 225 | const unsigned char *buf, size_t blen ) | 
|  | 226 | { | 
| Manuel Pégourié-Gonnard | 969ccc6 | 2014-03-26 19:53:25 +0100 | [diff] [blame] | 227 | int ret; | 
|  | 228 | const unsigned char *p = buf; | 
|  | 229 |  | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 230 | if( ctx == NULL ) | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 231 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 232 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 233 | if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) | 
| Manuel Pégourié-Gonnard | 969ccc6 | 2014-03-26 19:53:25 +0100 | [diff] [blame] | 234 | return( ret ); | 
|  | 235 |  | 
|  | 236 | if( (size_t)( p - buf ) != blen ) | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 237 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | 969ccc6 | 2014-03-26 19:53:25 +0100 | [diff] [blame] | 238 |  | 
|  | 239 | return( 0 ); | 
| Manuel Pégourié-Gonnard | 5cceb41 | 2013-02-11 21:51:45 +0100 | [diff] [blame] | 240 | } | 
|  | 241 |  | 
| Manuel Pégourié-Gonnard | 424fda5 | 2013-02-11 22:05:42 +0100 | [diff] [blame] | 242 | /* | 
|  | 243 | * Derive and export the shared secret | 
|  | 244 | */ | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 245 | int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, | 
| Manuel Pégourié-Gonnard | e09d2f8 | 2013-09-02 14:29:09 +0200 | [diff] [blame] | 246 | unsigned char *buf, size_t blen, | 
|  | 247 | int (*f_rng)(void *, unsigned char *, size_t), | 
|  | 248 | void *p_rng ) | 
| Manuel Pégourié-Gonnard | 424fda5 | 2013-02-11 22:05:42 +0100 | [diff] [blame] | 249 | { | 
|  | 250 | int ret; | 
|  | 251 |  | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 252 | if( ctx == NULL ) | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 253 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Manuel Pégourié-Gonnard | f35b739 | 2013-02-11 22:12:39 +0100 | [diff] [blame] | 254 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 255 | if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, | 
| Manuel Pégourié-Gonnard | e09d2f8 | 2013-09-02 14:29:09 +0200 | [diff] [blame] | 256 | f_rng, p_rng ) ) != 0 ) | 
|  | 257 | { | 
| Manuel Pégourié-Gonnard | 424fda5 | 2013-02-11 22:05:42 +0100 | [diff] [blame] | 258 | return( ret ); | 
| Manuel Pégourié-Gonnard | e09d2f8 | 2013-09-02 14:29:09 +0200 | [diff] [blame] | 259 | } | 
| Manuel Pégourié-Gonnard | 424fda5 | 2013-02-11 22:05:42 +0100 | [diff] [blame] | 260 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 261 | if( mbedtls_mpi_size( &ctx->z ) > blen ) | 
|  | 262 | return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | 
| Paul Bakker | 41c83d3 | 2013-03-20 14:39:14 +0100 | [diff] [blame] | 263 |  | 
| Manuel Pégourié-Gonnard | 0a56c2c | 2014-01-17 21:24:04 +0100 | [diff] [blame] | 264 | *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 265 | return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); | 
| Manuel Pégourié-Gonnard | 424fda5 | 2013-02-11 22:05:42 +0100 | [diff] [blame] | 266 | } | 
|  | 267 |  | 
| Manuel Pégourié-Gonnard | 2cf5a7c | 2015-04-08 12:49:31 +0200 | [diff] [blame] | 268 | #endif /* MBEDTLS_ECDH_C */ |