mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 11:cada08fc8a70 1 /*
mbedAustin 11:cada08fc8a70 2 * Diffie-Hellman-Merkle key exchange
mbedAustin 11:cada08fc8a70 3 *
mbedAustin 11:cada08fc8a70 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
mbedAustin 11:cada08fc8a70 5 * SPDX-License-Identifier: Apache-2.0
mbedAustin 11:cada08fc8a70 6 *
mbedAustin 11:cada08fc8a70 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
mbedAustin 11:cada08fc8a70 8 * not use this file except in compliance with the License.
mbedAustin 11:cada08fc8a70 9 * You may obtain a copy of the License at
mbedAustin 11:cada08fc8a70 10 *
mbedAustin 11:cada08fc8a70 11 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 11:cada08fc8a70 12 *
mbedAustin 11:cada08fc8a70 13 * Unless required by applicable law or agreed to in writing, software
mbedAustin 11:cada08fc8a70 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
mbedAustin 11:cada08fc8a70 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 11:cada08fc8a70 16 * See the License for the specific language governing permissions and
mbedAustin 11:cada08fc8a70 17 * limitations under the License.
mbedAustin 11:cada08fc8a70 18 *
mbedAustin 11:cada08fc8a70 19 * This file is part of mbed TLS (https://tls.mbed.org)
mbedAustin 11:cada08fc8a70 20 */
mbedAustin 11:cada08fc8a70 21 /*
mbedAustin 11:cada08fc8a70 22 * Reference:
mbedAustin 11:cada08fc8a70 23 *
mbedAustin 11:cada08fc8a70 24 * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
mbedAustin 11:cada08fc8a70 25 */
mbedAustin 11:cada08fc8a70 26
mbedAustin 11:cada08fc8a70 27 #if !defined(MBEDTLS_CONFIG_FILE)
mbedAustin 11:cada08fc8a70 28 #include "mbedtls/config.h"
mbedAustin 11:cada08fc8a70 29 #else
mbedAustin 11:cada08fc8a70 30 #include MBEDTLS_CONFIG_FILE
mbedAustin 11:cada08fc8a70 31 #endif
mbedAustin 11:cada08fc8a70 32
mbedAustin 11:cada08fc8a70 33 #if defined(MBEDTLS_DHM_C)
mbedAustin 11:cada08fc8a70 34
mbedAustin 11:cada08fc8a70 35 #include "mbedtls/dhm.h"
mbedAustin 11:cada08fc8a70 36
mbedAustin 11:cada08fc8a70 37 #include <string.h>
mbedAustin 11:cada08fc8a70 38
mbedAustin 11:cada08fc8a70 39 #if defined(MBEDTLS_PEM_PARSE_C)
mbedAustin 11:cada08fc8a70 40 #include "mbedtls/pem.h"
mbedAustin 11:cada08fc8a70 41 #endif
mbedAustin 11:cada08fc8a70 42
mbedAustin 11:cada08fc8a70 43 #if defined(MBEDTLS_ASN1_PARSE_C)
mbedAustin 11:cada08fc8a70 44 #include "mbedtls/asn1.h"
mbedAustin 11:cada08fc8a70 45 #endif
mbedAustin 11:cada08fc8a70 46
mbedAustin 11:cada08fc8a70 47 #if defined(MBEDTLS_PLATFORM_C)
mbedAustin 11:cada08fc8a70 48 #include "mbedtls/platform.h"
mbedAustin 11:cada08fc8a70 49 #else
mbedAustin 11:cada08fc8a70 50 #include <stdlib.h>
mbedAustin 11:cada08fc8a70 51 #include <stdio.h>
mbedAustin 11:cada08fc8a70 52 #define mbedtls_printf printf
mbedAustin 11:cada08fc8a70 53 #define mbedtls_calloc calloc
mbedAustin 11:cada08fc8a70 54 #define mbedtls_free free
mbedAustin 11:cada08fc8a70 55 #endif
mbedAustin 11:cada08fc8a70 56
mbedAustin 11:cada08fc8a70 57 /* Implementation that should never be optimized out by the compiler */
mbedAustin 11:cada08fc8a70 58 static void mbedtls_zeroize( void *v, size_t n ) {
mbedAustin 11:cada08fc8a70 59 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
mbedAustin 11:cada08fc8a70 60 }
mbedAustin 11:cada08fc8a70 61
mbedAustin 11:cada08fc8a70 62 /*
mbedAustin 11:cada08fc8a70 63 * helper to validate the mbedtls_mpi size and import it
mbedAustin 11:cada08fc8a70 64 */
mbedAustin 11:cada08fc8a70 65 static int dhm_read_bignum( mbedtls_mpi *X,
mbedAustin 11:cada08fc8a70 66 unsigned char **p,
mbedAustin 11:cada08fc8a70 67 const unsigned char *end )
mbedAustin 11:cada08fc8a70 68 {
mbedAustin 11:cada08fc8a70 69 int ret, n;
mbedAustin 11:cada08fc8a70 70
mbedAustin 11:cada08fc8a70 71 if( end - *p < 2 )
mbedAustin 11:cada08fc8a70 72 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 73
mbedAustin 11:cada08fc8a70 74 n = ( (*p)[0] << 8 ) | (*p)[1];
mbedAustin 11:cada08fc8a70 75 (*p) += 2;
mbedAustin 11:cada08fc8a70 76
mbedAustin 11:cada08fc8a70 77 if( (int)( end - *p ) < n )
mbedAustin 11:cada08fc8a70 78 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 79
mbedAustin 11:cada08fc8a70 80 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
mbedAustin 11:cada08fc8a70 81 return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
mbedAustin 11:cada08fc8a70 82
mbedAustin 11:cada08fc8a70 83 (*p) += n;
mbedAustin 11:cada08fc8a70 84
mbedAustin 11:cada08fc8a70 85 return( 0 );
mbedAustin 11:cada08fc8a70 86 }
mbedAustin 11:cada08fc8a70 87
mbedAustin 11:cada08fc8a70 88 /*
mbedAustin 11:cada08fc8a70 89 * Verify sanity of parameter with regards to P
mbedAustin 11:cada08fc8a70 90 *
mbedAustin 11:cada08fc8a70 91 * Parameter should be: 2 <= public_param <= P - 2
mbedAustin 11:cada08fc8a70 92 *
mbedAustin 11:cada08fc8a70 93 * For more information on the attack, see:
mbedAustin 11:cada08fc8a70 94 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
mbedAustin 11:cada08fc8a70 95 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
mbedAustin 11:cada08fc8a70 96 */
mbedAustin 11:cada08fc8a70 97 static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
mbedAustin 11:cada08fc8a70 98 {
mbedAustin 11:cada08fc8a70 99 mbedtls_mpi L, U;
mbedAustin 11:cada08fc8a70 100 int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
mbedAustin 11:cada08fc8a70 101
mbedAustin 11:cada08fc8a70 102 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
mbedAustin 11:cada08fc8a70 103
mbedAustin 11:cada08fc8a70 104 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
mbedAustin 11:cada08fc8a70 105 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
mbedAustin 11:cada08fc8a70 106
mbedAustin 11:cada08fc8a70 107 if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 &&
mbedAustin 11:cada08fc8a70 108 mbedtls_mpi_cmp_mpi( param, &U ) <= 0 )
mbedAustin 11:cada08fc8a70 109 {
mbedAustin 11:cada08fc8a70 110 ret = 0;
mbedAustin 11:cada08fc8a70 111 }
mbedAustin 11:cada08fc8a70 112
mbedAustin 11:cada08fc8a70 113 cleanup:
mbedAustin 11:cada08fc8a70 114 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
mbedAustin 11:cada08fc8a70 115 return( ret );
mbedAustin 11:cada08fc8a70 116 }
mbedAustin 11:cada08fc8a70 117
mbedAustin 11:cada08fc8a70 118 void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
mbedAustin 11:cada08fc8a70 119 {
mbedAustin 11:cada08fc8a70 120 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
mbedAustin 11:cada08fc8a70 121 }
mbedAustin 11:cada08fc8a70 122
mbedAustin 11:cada08fc8a70 123 /*
mbedAustin 11:cada08fc8a70 124 * Parse the ServerKeyExchange parameters
mbedAustin 11:cada08fc8a70 125 */
mbedAustin 11:cada08fc8a70 126 int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
mbedAustin 11:cada08fc8a70 127 unsigned char **p,
mbedAustin 11:cada08fc8a70 128 const unsigned char *end )
mbedAustin 11:cada08fc8a70 129 {
mbedAustin 11:cada08fc8a70 130 int ret;
mbedAustin 11:cada08fc8a70 131
mbedAustin 11:cada08fc8a70 132 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
mbedAustin 11:cada08fc8a70 133 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
mbedAustin 11:cada08fc8a70 134 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
mbedAustin 11:cada08fc8a70 135 return( ret );
mbedAustin 11:cada08fc8a70 136
mbedAustin 11:cada08fc8a70 137 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
mbedAustin 11:cada08fc8a70 138 return( ret );
mbedAustin 11:cada08fc8a70 139
mbedAustin 11:cada08fc8a70 140 ctx->len = mbedtls_mpi_size( &ctx->P );
mbedAustin 11:cada08fc8a70 141
mbedAustin 11:cada08fc8a70 142 return( 0 );
mbedAustin 11:cada08fc8a70 143 }
mbedAustin 11:cada08fc8a70 144
mbedAustin 11:cada08fc8a70 145 /*
mbedAustin 11:cada08fc8a70 146 * Setup and write the ServerKeyExchange parameters
mbedAustin 11:cada08fc8a70 147 */
mbedAustin 11:cada08fc8a70 148 int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
mbedAustin 11:cada08fc8a70 149 unsigned char *output, size_t *olen,
mbedAustin 11:cada08fc8a70 150 int (*f_rng)(void *, unsigned char *, size_t),
mbedAustin 11:cada08fc8a70 151 void *p_rng )
mbedAustin 11:cada08fc8a70 152 {
mbedAustin 11:cada08fc8a70 153 int ret, count = 0;
mbedAustin 11:cada08fc8a70 154 size_t n1, n2, n3;
mbedAustin 11:cada08fc8a70 155 unsigned char *p;
mbedAustin 11:cada08fc8a70 156
mbedAustin 11:cada08fc8a70 157 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
mbedAustin 11:cada08fc8a70 158 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 159
mbedAustin 11:cada08fc8a70 160 /*
mbedAustin 11:cada08fc8a70 161 * Generate X as large as possible ( < P )
mbedAustin 11:cada08fc8a70 162 */
mbedAustin 11:cada08fc8a70 163 do
mbedAustin 11:cada08fc8a70 164 {
mbedAustin 11:cada08fc8a70 165 mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
mbedAustin 11:cada08fc8a70 166
mbedAustin 11:cada08fc8a70 167 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mbedAustin 11:cada08fc8a70 168 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
mbedAustin 11:cada08fc8a70 169
mbedAustin 11:cada08fc8a70 170 if( count++ > 10 )
mbedAustin 11:cada08fc8a70 171 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
mbedAustin 11:cada08fc8a70 172 }
mbedAustin 11:cada08fc8a70 173 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
mbedAustin 11:cada08fc8a70 174
mbedAustin 11:cada08fc8a70 175 /*
mbedAustin 11:cada08fc8a70 176 * Calculate GX = G^X mod P
mbedAustin 11:cada08fc8a70 177 */
mbedAustin 11:cada08fc8a70 178 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
mbedAustin 11:cada08fc8a70 179 &ctx->P , &ctx->RP ) );
mbedAustin 11:cada08fc8a70 180
mbedAustin 11:cada08fc8a70 181 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
mbedAustin 11:cada08fc8a70 182 return( ret );
mbedAustin 11:cada08fc8a70 183
mbedAustin 11:cada08fc8a70 184 /*
mbedAustin 11:cada08fc8a70 185 * export P, G, GX
mbedAustin 11:cada08fc8a70 186 */
mbedAustin 11:cada08fc8a70 187 #define DHM_MPI_EXPORT(X,n) \
mbedAustin 11:cada08fc8a70 188 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \
mbedAustin 11:cada08fc8a70 189 *p++ = (unsigned char)( n >> 8 ); \
mbedAustin 11:cada08fc8a70 190 *p++ = (unsigned char)( n ); p += n;
mbedAustin 11:cada08fc8a70 191
mbedAustin 11:cada08fc8a70 192 n1 = mbedtls_mpi_size( &ctx->P );
mbedAustin 11:cada08fc8a70 193 n2 = mbedtls_mpi_size( &ctx->G );
mbedAustin 11:cada08fc8a70 194 n3 = mbedtls_mpi_size( &ctx->GX );
mbedAustin 11:cada08fc8a70 195
mbedAustin 11:cada08fc8a70 196 p = output;
mbedAustin 11:cada08fc8a70 197 DHM_MPI_EXPORT( &ctx->P , n1 );
mbedAustin 11:cada08fc8a70 198 DHM_MPI_EXPORT( &ctx->G , n2 );
mbedAustin 11:cada08fc8a70 199 DHM_MPI_EXPORT( &ctx->GX, n3 );
mbedAustin 11:cada08fc8a70 200
mbedAustin 11:cada08fc8a70 201 *olen = p - output;
mbedAustin 11:cada08fc8a70 202
mbedAustin 11:cada08fc8a70 203 ctx->len = n1;
mbedAustin 11:cada08fc8a70 204
mbedAustin 11:cada08fc8a70 205 cleanup:
mbedAustin 11:cada08fc8a70 206
mbedAustin 11:cada08fc8a70 207 if( ret != 0 )
mbedAustin 11:cada08fc8a70 208 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
mbedAustin 11:cada08fc8a70 209
mbedAustin 11:cada08fc8a70 210 return( 0 );
mbedAustin 11:cada08fc8a70 211 }
mbedAustin 11:cada08fc8a70 212
mbedAustin 11:cada08fc8a70 213 /*
mbedAustin 11:cada08fc8a70 214 * Import the peer's public value G^Y
mbedAustin 11:cada08fc8a70 215 */
mbedAustin 11:cada08fc8a70 216 int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
mbedAustin 11:cada08fc8a70 217 const unsigned char *input, size_t ilen )
mbedAustin 11:cada08fc8a70 218 {
mbedAustin 11:cada08fc8a70 219 int ret;
mbedAustin 11:cada08fc8a70 220
mbedAustin 11:cada08fc8a70 221 if( ctx == NULL || ilen < 1 || ilen > ctx->len )
mbedAustin 11:cada08fc8a70 222 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 223
mbedAustin 11:cada08fc8a70 224 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
mbedAustin 11:cada08fc8a70 225 return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
mbedAustin 11:cada08fc8a70 226
mbedAustin 11:cada08fc8a70 227 return( 0 );
mbedAustin 11:cada08fc8a70 228 }
mbedAustin 11:cada08fc8a70 229
mbedAustin 11:cada08fc8a70 230 /*
mbedAustin 11:cada08fc8a70 231 * Create own private value X and export G^X
mbedAustin 11:cada08fc8a70 232 */
mbedAustin 11:cada08fc8a70 233 int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
mbedAustin 11:cada08fc8a70 234 unsigned char *output, size_t olen,
mbedAustin 11:cada08fc8a70 235 int (*f_rng)(void *, unsigned char *, size_t),
mbedAustin 11:cada08fc8a70 236 void *p_rng )
mbedAustin 11:cada08fc8a70 237 {
mbedAustin 11:cada08fc8a70 238 int ret, count = 0;
mbedAustin 11:cada08fc8a70 239
mbedAustin 11:cada08fc8a70 240 if( ctx == NULL || olen < 1 || olen > ctx->len )
mbedAustin 11:cada08fc8a70 241 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 242
mbedAustin 11:cada08fc8a70 243 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
mbedAustin 11:cada08fc8a70 244 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 245
mbedAustin 11:cada08fc8a70 246 /*
mbedAustin 11:cada08fc8a70 247 * generate X and calculate GX = G^X mod P
mbedAustin 11:cada08fc8a70 248 */
mbedAustin 11:cada08fc8a70 249 do
mbedAustin 11:cada08fc8a70 250 {
mbedAustin 11:cada08fc8a70 251 mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
mbedAustin 11:cada08fc8a70 252
mbedAustin 11:cada08fc8a70 253 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mbedAustin 11:cada08fc8a70 254 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
mbedAustin 11:cada08fc8a70 255
mbedAustin 11:cada08fc8a70 256 if( count++ > 10 )
mbedAustin 11:cada08fc8a70 257 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
mbedAustin 11:cada08fc8a70 258 }
mbedAustin 11:cada08fc8a70 259 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
mbedAustin 11:cada08fc8a70 260
mbedAustin 11:cada08fc8a70 261 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
mbedAustin 11:cada08fc8a70 262 &ctx->P , &ctx->RP ) );
mbedAustin 11:cada08fc8a70 263
mbedAustin 11:cada08fc8a70 264 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
mbedAustin 11:cada08fc8a70 265 return( ret );
mbedAustin 11:cada08fc8a70 266
mbedAustin 11:cada08fc8a70 267 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
mbedAustin 11:cada08fc8a70 268
mbedAustin 11:cada08fc8a70 269 cleanup:
mbedAustin 11:cada08fc8a70 270
mbedAustin 11:cada08fc8a70 271 if( ret != 0 )
mbedAustin 11:cada08fc8a70 272 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
mbedAustin 11:cada08fc8a70 273
mbedAustin 11:cada08fc8a70 274 return( 0 );
mbedAustin 11:cada08fc8a70 275 }
mbedAustin 11:cada08fc8a70 276
mbedAustin 11:cada08fc8a70 277 /*
mbedAustin 11:cada08fc8a70 278 * Use the blinding method and optimisation suggested in section 10 of:
mbedAustin 11:cada08fc8a70 279 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
mbedAustin 11:cada08fc8a70 280 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
mbedAustin 11:cada08fc8a70 281 * Berlin Heidelberg, 1996. p. 104-113.
mbedAustin 11:cada08fc8a70 282 */
mbedAustin 11:cada08fc8a70 283 static int dhm_update_blinding( mbedtls_dhm_context *ctx,
mbedAustin 11:cada08fc8a70 284 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
mbedAustin 11:cada08fc8a70 285 {
mbedAustin 11:cada08fc8a70 286 int ret, count;
mbedAustin 11:cada08fc8a70 287
mbedAustin 11:cada08fc8a70 288 /*
mbedAustin 11:cada08fc8a70 289 * Don't use any blinding the first time a particular X is used,
mbedAustin 11:cada08fc8a70 290 * but remember it to use blinding next time.
mbedAustin 11:cada08fc8a70 291 */
mbedAustin 11:cada08fc8a70 292 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
mbedAustin 11:cada08fc8a70 293 {
mbedAustin 11:cada08fc8a70 294 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
mbedAustin 11:cada08fc8a70 295 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
mbedAustin 11:cada08fc8a70 296 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
mbedAustin 11:cada08fc8a70 297
mbedAustin 11:cada08fc8a70 298 return( 0 );
mbedAustin 11:cada08fc8a70 299 }
mbedAustin 11:cada08fc8a70 300
mbedAustin 11:cada08fc8a70 301 /*
mbedAustin 11:cada08fc8a70 302 * Ok, we need blinding. Can we re-use existing values?
mbedAustin 11:cada08fc8a70 303 * If yes, just update them by squaring them.
mbedAustin 11:cada08fc8a70 304 */
mbedAustin 11:cada08fc8a70 305 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
mbedAustin 11:cada08fc8a70 306 {
mbedAustin 11:cada08fc8a70 307 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
mbedAustin 11:cada08fc8a70 308 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
mbedAustin 11:cada08fc8a70 309
mbedAustin 11:cada08fc8a70 310 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
mbedAustin 11:cada08fc8a70 311 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
mbedAustin 11:cada08fc8a70 312
mbedAustin 11:cada08fc8a70 313 return( 0 );
mbedAustin 11:cada08fc8a70 314 }
mbedAustin 11:cada08fc8a70 315
mbedAustin 11:cada08fc8a70 316 /*
mbedAustin 11:cada08fc8a70 317 * We need to generate blinding values from scratch
mbedAustin 11:cada08fc8a70 318 */
mbedAustin 11:cada08fc8a70 319
mbedAustin 11:cada08fc8a70 320 /* Vi = random( 2, P-1 ) */
mbedAustin 11:cada08fc8a70 321 count = 0;
mbedAustin 11:cada08fc8a70 322 do
mbedAustin 11:cada08fc8a70 323 {
mbedAustin 11:cada08fc8a70 324 mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng );
mbedAustin 11:cada08fc8a70 325
mbedAustin 11:cada08fc8a70 326 while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
mbedAustin 11:cada08fc8a70 327 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
mbedAustin 11:cada08fc8a70 328
mbedAustin 11:cada08fc8a70 329 if( count++ > 10 )
mbedAustin 11:cada08fc8a70 330 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
mbedAustin 11:cada08fc8a70 331 }
mbedAustin 11:cada08fc8a70 332 while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
mbedAustin 11:cada08fc8a70 333
mbedAustin 11:cada08fc8a70 334 /* Vf = Vi^-X mod P */
mbedAustin 11:cada08fc8a70 335 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
mbedAustin 11:cada08fc8a70 336 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
mbedAustin 11:cada08fc8a70 337
mbedAustin 11:cada08fc8a70 338 cleanup:
mbedAustin 11:cada08fc8a70 339 return( ret );
mbedAustin 11:cada08fc8a70 340 }
mbedAustin 11:cada08fc8a70 341
mbedAustin 11:cada08fc8a70 342 /*
mbedAustin 11:cada08fc8a70 343 * Derive and export the shared secret (G^Y)^X mod P
mbedAustin 11:cada08fc8a70 344 */
mbedAustin 11:cada08fc8a70 345 int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
mbedAustin 11:cada08fc8a70 346 unsigned char *output, size_t output_size, size_t *olen,
mbedAustin 11:cada08fc8a70 347 int (*f_rng)(void *, unsigned char *, size_t),
mbedAustin 11:cada08fc8a70 348 void *p_rng )
mbedAustin 11:cada08fc8a70 349 {
mbedAustin 11:cada08fc8a70 350 int ret;
mbedAustin 11:cada08fc8a70 351 mbedtls_mpi GYb;
mbedAustin 11:cada08fc8a70 352
mbedAustin 11:cada08fc8a70 353 if( ctx == NULL || output_size < ctx->len )
mbedAustin 11:cada08fc8a70 354 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
mbedAustin 11:cada08fc8a70 355
mbedAustin 11:cada08fc8a70 356 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
mbedAustin 11:cada08fc8a70 357 return( ret );
mbedAustin 11:cada08fc8a70 358
mbedAustin 11:cada08fc8a70 359 mbedtls_mpi_init( &GYb );
mbedAustin 11:cada08fc8a70 360
mbedAustin 11:cada08fc8a70 361 /* Blind peer's value */
mbedAustin 11:cada08fc8a70 362 if( f_rng != NULL )
mbedAustin 11:cada08fc8a70 363 {
mbedAustin 11:cada08fc8a70 364 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
mbedAustin 11:cada08fc8a70 365 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
mbedAustin 11:cada08fc8a70 366 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
mbedAustin 11:cada08fc8a70 367 }
mbedAustin 11:cada08fc8a70 368 else
mbedAustin 11:cada08fc8a70 369 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
mbedAustin 11:cada08fc8a70 370
mbedAustin 11:cada08fc8a70 371 /* Do modular exponentiation */
mbedAustin 11:cada08fc8a70 372 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
mbedAustin 11:cada08fc8a70 373 &ctx->P, &ctx->RP ) );
mbedAustin 11:cada08fc8a70 374
mbedAustin 11:cada08fc8a70 375 /* Unblind secret value */
mbedAustin 11:cada08fc8a70 376 if( f_rng != NULL )
mbedAustin 11:cada08fc8a70 377 {
mbedAustin 11:cada08fc8a70 378 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
mbedAustin 11:cada08fc8a70 379 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
mbedAustin 11:cada08fc8a70 380 }
mbedAustin 11:cada08fc8a70 381
mbedAustin 11:cada08fc8a70 382 *olen = mbedtls_mpi_size( &ctx->K );
mbedAustin 11:cada08fc8a70 383
mbedAustin 11:cada08fc8a70 384 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
mbedAustin 11:cada08fc8a70 385
mbedAustin 11:cada08fc8a70 386 cleanup:
mbedAustin 11:cada08fc8a70 387 mbedtls_mpi_free( &GYb );
mbedAustin 11:cada08fc8a70 388
mbedAustin 11:cada08fc8a70 389 if( ret != 0 )
mbedAustin 11:cada08fc8a70 390 return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
mbedAustin 11:cada08fc8a70 391
mbedAustin 11:cada08fc8a70 392 return( 0 );
mbedAustin 11:cada08fc8a70 393 }
mbedAustin 11:cada08fc8a70 394
mbedAustin 11:cada08fc8a70 395 /*
mbedAustin 11:cada08fc8a70 396 * Free the components of a DHM key
mbedAustin 11:cada08fc8a70 397 */
mbedAustin 11:cada08fc8a70 398 void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
mbedAustin 11:cada08fc8a70 399 {
mbedAustin 11:cada08fc8a70 400 mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi );
mbedAustin 11:cada08fc8a70 401 mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
mbedAustin 11:cada08fc8a70 402 mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G );
mbedAustin 11:cada08fc8a70 403 mbedtls_mpi_free( &ctx->P );
mbedAustin 11:cada08fc8a70 404
mbedAustin 11:cada08fc8a70 405 mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
mbedAustin 11:cada08fc8a70 406 }
mbedAustin 11:cada08fc8a70 407
mbedAustin 11:cada08fc8a70 408 #if defined(MBEDTLS_ASN1_PARSE_C)
mbedAustin 11:cada08fc8a70 409 /*
mbedAustin 11:cada08fc8a70 410 * Parse DHM parameters
mbedAustin 11:cada08fc8a70 411 */
mbedAustin 11:cada08fc8a70 412 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
mbedAustin 11:cada08fc8a70 413 size_t dhminlen )
mbedAustin 11:cada08fc8a70 414 {
mbedAustin 11:cada08fc8a70 415 int ret;
mbedAustin 11:cada08fc8a70 416 size_t len;
mbedAustin 11:cada08fc8a70 417 unsigned char *p, *end;
mbedAustin 11:cada08fc8a70 418 #if defined(MBEDTLS_PEM_PARSE_C)
mbedAustin 11:cada08fc8a70 419 mbedtls_pem_context pem;
mbedAustin 11:cada08fc8a70 420
mbedAustin 11:cada08fc8a70 421 mbedtls_pem_init( &pem );
mbedAustin 11:cada08fc8a70 422
mbedAustin 11:cada08fc8a70 423 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
mbedAustin 11:cada08fc8a70 424 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
mbedAustin 11:cada08fc8a70 425 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
mbedAustin 11:cada08fc8a70 426 else
mbedAustin 11:cada08fc8a70 427 ret = mbedtls_pem_read_buffer( &pem,
mbedAustin 11:cada08fc8a70 428 "-----BEGIN DH PARAMETERS-----",
mbedAustin 11:cada08fc8a70 429 "-----END DH PARAMETERS-----",
mbedAustin 11:cada08fc8a70 430 dhmin, NULL, 0, &dhminlen );
mbedAustin 11:cada08fc8a70 431
mbedAustin 11:cada08fc8a70 432 if( ret == 0 )
mbedAustin 11:cada08fc8a70 433 {
mbedAustin 11:cada08fc8a70 434 /*
mbedAustin 11:cada08fc8a70 435 * Was PEM encoded
mbedAustin 11:cada08fc8a70 436 */
mbedAustin 11:cada08fc8a70 437 dhminlen = pem.buflen;
mbedAustin 11:cada08fc8a70 438 }
mbedAustin 11:cada08fc8a70 439 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
mbedAustin 11:cada08fc8a70 440 goto exit;
mbedAustin 11:cada08fc8a70 441
mbedAustin 11:cada08fc8a70 442 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
mbedAustin 11:cada08fc8a70 443 #else
mbedAustin 11:cada08fc8a70 444 p = (unsigned char *) dhmin;
mbedAustin 11:cada08fc8a70 445 #endif /* MBEDTLS_PEM_PARSE_C */
mbedAustin 11:cada08fc8a70 446 end = p + dhminlen;
mbedAustin 11:cada08fc8a70 447
mbedAustin 11:cada08fc8a70 448 /*
mbedAustin 11:cada08fc8a70 449 * DHParams ::= SEQUENCE {
mbedAustin 11:cada08fc8a70 450 * prime INTEGER, -- P
mbedAustin 11:cada08fc8a70 451 * generator INTEGER, -- g
mbedAustin 11:cada08fc8a70 452 * privateValueLength INTEGER OPTIONAL
mbedAustin 11:cada08fc8a70 453 * }
mbedAustin 11:cada08fc8a70 454 */
mbedAustin 11:cada08fc8a70 455 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
mbedAustin 11:cada08fc8a70 456 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
mbedAustin 11:cada08fc8a70 457 {
mbedAustin 11:cada08fc8a70 458 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
mbedAustin 11:cada08fc8a70 459 goto exit;
mbedAustin 11:cada08fc8a70 460 }
mbedAustin 11:cada08fc8a70 461
mbedAustin 11:cada08fc8a70 462 end = p + len;
mbedAustin 11:cada08fc8a70 463
mbedAustin 11:cada08fc8a70 464 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
mbedAustin 11:cada08fc8a70 465 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
mbedAustin 11:cada08fc8a70 466 {
mbedAustin 11:cada08fc8a70 467 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
mbedAustin 11:cada08fc8a70 468 goto exit;
mbedAustin 11:cada08fc8a70 469 }
mbedAustin 11:cada08fc8a70 470
mbedAustin 11:cada08fc8a70 471 if( p != end )
mbedAustin 11:cada08fc8a70 472 {
mbedAustin 11:cada08fc8a70 473 /* This might be the optional privateValueLength.
mbedAustin 11:cada08fc8a70 474 * If so, we can cleanly discard it */
mbedAustin 11:cada08fc8a70 475 mbedtls_mpi rec;
mbedAustin 11:cada08fc8a70 476 mbedtls_mpi_init( &rec );
mbedAustin 11:cada08fc8a70 477 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
mbedAustin 11:cada08fc8a70 478 mbedtls_mpi_free( &rec );
mbedAustin 11:cada08fc8a70 479 if ( ret != 0 )
mbedAustin 11:cada08fc8a70 480 {
mbedAustin 11:cada08fc8a70 481 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
mbedAustin 11:cada08fc8a70 482 goto exit;
mbedAustin 11:cada08fc8a70 483 }
mbedAustin 11:cada08fc8a70 484 if ( p != end )
mbedAustin 11:cada08fc8a70 485 {
mbedAustin 11:cada08fc8a70 486 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
mbedAustin 11:cada08fc8a70 487 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
mbedAustin 11:cada08fc8a70 488 goto exit;
mbedAustin 11:cada08fc8a70 489 }
mbedAustin 11:cada08fc8a70 490 }
mbedAustin 11:cada08fc8a70 491
mbedAustin 11:cada08fc8a70 492 ret = 0;
mbedAustin 11:cada08fc8a70 493
mbedAustin 11:cada08fc8a70 494 dhm->len = mbedtls_mpi_size( &dhm->P );
mbedAustin 11:cada08fc8a70 495
mbedAustin 11:cada08fc8a70 496 exit:
mbedAustin 11:cada08fc8a70 497 #if defined(MBEDTLS_PEM_PARSE_C)
mbedAustin 11:cada08fc8a70 498 mbedtls_pem_free( &pem );
mbedAustin 11:cada08fc8a70 499 #endif
mbedAustin 11:cada08fc8a70 500 if( ret != 0 )
mbedAustin 11:cada08fc8a70 501 mbedtls_dhm_free( dhm );
mbedAustin 11:cada08fc8a70 502
mbedAustin 11:cada08fc8a70 503 return( ret );
mbedAustin 11:cada08fc8a70 504 }
mbedAustin 11:cada08fc8a70 505
mbedAustin 11:cada08fc8a70 506 #if defined(MBEDTLS_FS_IO)
mbedAustin 11:cada08fc8a70 507 /*
mbedAustin 11:cada08fc8a70 508 * Load all data from a file into a given buffer.
mbedAustin 11:cada08fc8a70 509 *
mbedAustin 11:cada08fc8a70 510 * The file is expected to contain either PEM or DER encoded data.
mbedAustin 11:cada08fc8a70 511 * A terminating null byte is always appended. It is included in the announced
mbedAustin 11:cada08fc8a70 512 * length only if the data looks like it is PEM encoded.
mbedAustin 11:cada08fc8a70 513 */
mbedAustin 11:cada08fc8a70 514 static int load_file( const char *path, unsigned char **buf, size_t *n )
mbedAustin 11:cada08fc8a70 515 {
mbedAustin 11:cada08fc8a70 516 FILE *f;
mbedAustin 11:cada08fc8a70 517 long size;
mbedAustin 11:cada08fc8a70 518
mbedAustin 11:cada08fc8a70 519 if( ( f = fopen( path, "rb" ) ) == NULL )
mbedAustin 11:cada08fc8a70 520 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
mbedAustin 11:cada08fc8a70 521
mbedAustin 11:cada08fc8a70 522 fseek( f, 0, SEEK_END );
mbedAustin 11:cada08fc8a70 523 if( ( size = ftell( f ) ) == -1 )
mbedAustin 11:cada08fc8a70 524 {
mbedAustin 11:cada08fc8a70 525 fclose( f );
mbedAustin 11:cada08fc8a70 526 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
mbedAustin 11:cada08fc8a70 527 }
mbedAustin 11:cada08fc8a70 528 fseek( f, 0, SEEK_SET );
mbedAustin 11:cada08fc8a70 529
mbedAustin 11:cada08fc8a70 530 *n = (size_t) size;
mbedAustin 11:cada08fc8a70 531
mbedAustin 11:cada08fc8a70 532 if( *n + 1 == 0 ||
mbedAustin 11:cada08fc8a70 533 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
mbedAustin 11:cada08fc8a70 534 {
mbedAustin 11:cada08fc8a70 535 fclose( f );
mbedAustin 11:cada08fc8a70 536 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
mbedAustin 11:cada08fc8a70 537 }
mbedAustin 11:cada08fc8a70 538
mbedAustin 11:cada08fc8a70 539 if( fread( *buf, 1, *n, f ) != *n )
mbedAustin 11:cada08fc8a70 540 {
mbedAustin 11:cada08fc8a70 541 fclose( f );
mbedAustin 11:cada08fc8a70 542 mbedtls_free( *buf );
mbedAustin 11:cada08fc8a70 543 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
mbedAustin 11:cada08fc8a70 544 }
mbedAustin 11:cada08fc8a70 545
mbedAustin 11:cada08fc8a70 546 fclose( f );
mbedAustin 11:cada08fc8a70 547
mbedAustin 11:cada08fc8a70 548 (*buf)[*n] = '\0';
mbedAustin 11:cada08fc8a70 549
mbedAustin 11:cada08fc8a70 550 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
mbedAustin 11:cada08fc8a70 551 ++*n;
mbedAustin 11:cada08fc8a70 552
mbedAustin 11:cada08fc8a70 553 return( 0 );
mbedAustin 11:cada08fc8a70 554 }
mbedAustin 11:cada08fc8a70 555
mbedAustin 11:cada08fc8a70 556 /*
mbedAustin 11:cada08fc8a70 557 * Load and parse DHM parameters
mbedAustin 11:cada08fc8a70 558 */
mbedAustin 11:cada08fc8a70 559 int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
mbedAustin 11:cada08fc8a70 560 {
mbedAustin 11:cada08fc8a70 561 int ret;
mbedAustin 11:cada08fc8a70 562 size_t n;
mbedAustin 11:cada08fc8a70 563 unsigned char *buf;
mbedAustin 11:cada08fc8a70 564
mbedAustin 11:cada08fc8a70 565 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
mbedAustin 11:cada08fc8a70 566 return( ret );
mbedAustin 11:cada08fc8a70 567
mbedAustin 11:cada08fc8a70 568 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
mbedAustin 11:cada08fc8a70 569
mbedAustin 11:cada08fc8a70 570 mbedtls_zeroize( buf, n );
mbedAustin 11:cada08fc8a70 571 mbedtls_free( buf );
mbedAustin 11:cada08fc8a70 572
mbedAustin 11:cada08fc8a70 573 return( ret );
mbedAustin 11:cada08fc8a70 574 }
mbedAustin 11:cada08fc8a70 575 #endif /* MBEDTLS_FS_IO */
mbedAustin 11:cada08fc8a70 576 #endif /* MBEDTLS_ASN1_PARSE_C */
mbedAustin 11:cada08fc8a70 577
mbedAustin 11:cada08fc8a70 578 #if defined(MBEDTLS_SELF_TEST)
mbedAustin 11:cada08fc8a70 579
mbedAustin 11:cada08fc8a70 580 static const char mbedtls_test_dhm_params[] =
mbedAustin 11:cada08fc8a70 581 "-----BEGIN DH PARAMETERS-----\r\n"
mbedAustin 11:cada08fc8a70 582 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
mbedAustin 11:cada08fc8a70 583 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
mbedAustin 11:cada08fc8a70 584 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
mbedAustin 11:cada08fc8a70 585 "-----END DH PARAMETERS-----\r\n";
mbedAustin 11:cada08fc8a70 586
mbedAustin 11:cada08fc8a70 587 static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
mbedAustin 11:cada08fc8a70 588
mbedAustin 11:cada08fc8a70 589 /*
mbedAustin 11:cada08fc8a70 590 * Checkup routine
mbedAustin 11:cada08fc8a70 591 */
mbedAustin 11:cada08fc8a70 592 int mbedtls_dhm_self_test( int verbose )
mbedAustin 11:cada08fc8a70 593 {
mbedAustin 11:cada08fc8a70 594 int ret;
mbedAustin 11:cada08fc8a70 595 mbedtls_dhm_context dhm;
mbedAustin 11:cada08fc8a70 596
mbedAustin 11:cada08fc8a70 597 mbedtls_dhm_init( &dhm );
mbedAustin 11:cada08fc8a70 598
mbedAustin 11:cada08fc8a70 599 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 600 mbedtls_printf( " DHM parameter load: " );
mbedAustin 11:cada08fc8a70 601
mbedAustin 11:cada08fc8a70 602 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
mbedAustin 11:cada08fc8a70 603 (const unsigned char *) mbedtls_test_dhm_params,
mbedAustin 11:cada08fc8a70 604 mbedtls_test_dhm_params_len ) ) != 0 )
mbedAustin 11:cada08fc8a70 605 {
mbedAustin 11:cada08fc8a70 606 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 607 mbedtls_printf( "failed\n" );
mbedAustin 11:cada08fc8a70 608
mbedAustin 11:cada08fc8a70 609 ret = 1;
mbedAustin 11:cada08fc8a70 610 goto exit;
mbedAustin 11:cada08fc8a70 611 }
mbedAustin 11:cada08fc8a70 612
mbedAustin 11:cada08fc8a70 613 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 614 mbedtls_printf( "passed\n\n" );
mbedAustin 11:cada08fc8a70 615
mbedAustin 11:cada08fc8a70 616 exit:
mbedAustin 11:cada08fc8a70 617 mbedtls_dhm_free( &dhm );
mbedAustin 11:cada08fc8a70 618
mbedAustin 11:cada08fc8a70 619 return( ret );
mbedAustin 11:cada08fc8a70 620 }
mbedAustin 11:cada08fc8a70 621
mbedAustin 11:cada08fc8a70 622 #endif /* MBEDTLS_SELF_TEST */
mbedAustin 11:cada08fc8a70 623
mbedAustin 11:cada08fc8a70 624 #endif /* MBEDTLS_DHM_C */