mbedtls ported to mbed-classic
Fork of mbedtls by
source/dhm.c@1:24750b9ad5ef, 2016-01-22 (annotated)
- Committer:
- Christopher Haster
- Date:
- Fri Jan 22 16:44:49 2016 -0600
- Revision:
- 1:24750b9ad5ef
Initial move of mbedtls to mercurial
Who changed what in which revision?
User | Revision | Line number | New 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 */ |