This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
maclobdell
Date:
Wed May 18 19:06:32 2016 +0000
Revision:
0:f7c60d3e7b8a
clean version

Who changed what in which revision?

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