mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Committer:
Brian Daniels
Date:
Thu Apr 07 11:11:18 2016 +0100
Revision:
4:bef26f687287
Parent:
1:24750b9ad5ef
Adding ported selftest test case

Who changed what in which revision?

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