BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:fbdae7e6d805 1 /*
borlanic 0:fbdae7e6d805 2 * Elliptic curve J-PAKE
borlanic 0:fbdae7e6d805 3 *
borlanic 0:fbdae7e6d805 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
borlanic 0:fbdae7e6d805 5 * SPDX-License-Identifier: Apache-2.0
borlanic 0:fbdae7e6d805 6 *
borlanic 0:fbdae7e6d805 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
borlanic 0:fbdae7e6d805 8 * not use this file except in compliance with the License.
borlanic 0:fbdae7e6d805 9 * You may obtain a copy of the License at
borlanic 0:fbdae7e6d805 10 *
borlanic 0:fbdae7e6d805 11 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:fbdae7e6d805 12 *
borlanic 0:fbdae7e6d805 13 * Unless required by applicable law or agreed to in writing, software
borlanic 0:fbdae7e6d805 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
borlanic 0:fbdae7e6d805 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:fbdae7e6d805 16 * See the License for the specific language governing permissions and
borlanic 0:fbdae7e6d805 17 * limitations under the License.
borlanic 0:fbdae7e6d805 18 *
borlanic 0:fbdae7e6d805 19 * This file is part of mbed TLS (https://tls.mbed.org)
borlanic 0:fbdae7e6d805 20 */
borlanic 0:fbdae7e6d805 21
borlanic 0:fbdae7e6d805 22 /*
borlanic 0:fbdae7e6d805 23 * References in the code are to the Thread v1.0 Specification,
borlanic 0:fbdae7e6d805 24 * available to members of the Thread Group http://threadgroup.org/
borlanic 0:fbdae7e6d805 25 */
borlanic 0:fbdae7e6d805 26
borlanic 0:fbdae7e6d805 27 #if !defined(MBEDTLS_CONFIG_FILE)
borlanic 0:fbdae7e6d805 28 #include "mbedtls/config.h"
borlanic 0:fbdae7e6d805 29 #else
borlanic 0:fbdae7e6d805 30 #include MBEDTLS_CONFIG_FILE
borlanic 0:fbdae7e6d805 31 #endif
borlanic 0:fbdae7e6d805 32
borlanic 0:fbdae7e6d805 33 #if defined(MBEDTLS_ECJPAKE_C)
borlanic 0:fbdae7e6d805 34
borlanic 0:fbdae7e6d805 35 #include "mbedtls/ecjpake.h"
borlanic 0:fbdae7e6d805 36
borlanic 0:fbdae7e6d805 37 #include <string.h>
borlanic 0:fbdae7e6d805 38
borlanic 0:fbdae7e6d805 39 #if !defined(MBEDTLS_ECJPAKE_ALT)
borlanic 0:fbdae7e6d805 40
borlanic 0:fbdae7e6d805 41 /*
borlanic 0:fbdae7e6d805 42 * Convert a mbedtls_ecjpake_role to identifier string
borlanic 0:fbdae7e6d805 43 */
borlanic 0:fbdae7e6d805 44 static const char * const ecjpake_id[] = {
borlanic 0:fbdae7e6d805 45 "client",
borlanic 0:fbdae7e6d805 46 "server"
borlanic 0:fbdae7e6d805 47 };
borlanic 0:fbdae7e6d805 48
borlanic 0:fbdae7e6d805 49 #define ID_MINE ( ecjpake_id[ ctx->role ] )
borlanic 0:fbdae7e6d805 50 #define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
borlanic 0:fbdae7e6d805 51
borlanic 0:fbdae7e6d805 52 /*
borlanic 0:fbdae7e6d805 53 * Initialize context
borlanic 0:fbdae7e6d805 54 */
borlanic 0:fbdae7e6d805 55 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
borlanic 0:fbdae7e6d805 56 {
borlanic 0:fbdae7e6d805 57 if( ctx == NULL )
borlanic 0:fbdae7e6d805 58 return;
borlanic 0:fbdae7e6d805 59
borlanic 0:fbdae7e6d805 60 ctx->md_info = NULL;
borlanic 0:fbdae7e6d805 61 mbedtls_ecp_group_init( &ctx->grp );
borlanic 0:fbdae7e6d805 62 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
borlanic 0:fbdae7e6d805 63
borlanic 0:fbdae7e6d805 64 mbedtls_ecp_point_init( &ctx->Xm1 );
borlanic 0:fbdae7e6d805 65 mbedtls_ecp_point_init( &ctx->Xm2 );
borlanic 0:fbdae7e6d805 66 mbedtls_ecp_point_init( &ctx->Xp1 );
borlanic 0:fbdae7e6d805 67 mbedtls_ecp_point_init( &ctx->Xp2 );
borlanic 0:fbdae7e6d805 68 mbedtls_ecp_point_init( &ctx->Xp );
borlanic 0:fbdae7e6d805 69
borlanic 0:fbdae7e6d805 70 mbedtls_mpi_init( &ctx->xm1 );
borlanic 0:fbdae7e6d805 71 mbedtls_mpi_init( &ctx->xm2 );
borlanic 0:fbdae7e6d805 72 mbedtls_mpi_init( &ctx->s );
borlanic 0:fbdae7e6d805 73 }
borlanic 0:fbdae7e6d805 74
borlanic 0:fbdae7e6d805 75 /*
borlanic 0:fbdae7e6d805 76 * Free context
borlanic 0:fbdae7e6d805 77 */
borlanic 0:fbdae7e6d805 78 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
borlanic 0:fbdae7e6d805 79 {
borlanic 0:fbdae7e6d805 80 if( ctx == NULL )
borlanic 0:fbdae7e6d805 81 return;
borlanic 0:fbdae7e6d805 82
borlanic 0:fbdae7e6d805 83 ctx->md_info = NULL;
borlanic 0:fbdae7e6d805 84 mbedtls_ecp_group_free( &ctx->grp );
borlanic 0:fbdae7e6d805 85
borlanic 0:fbdae7e6d805 86 mbedtls_ecp_point_free( &ctx->Xm1 );
borlanic 0:fbdae7e6d805 87 mbedtls_ecp_point_free( &ctx->Xm2 );
borlanic 0:fbdae7e6d805 88 mbedtls_ecp_point_free( &ctx->Xp1 );
borlanic 0:fbdae7e6d805 89 mbedtls_ecp_point_free( &ctx->Xp2 );
borlanic 0:fbdae7e6d805 90 mbedtls_ecp_point_free( &ctx->Xp );
borlanic 0:fbdae7e6d805 91
borlanic 0:fbdae7e6d805 92 mbedtls_mpi_free( &ctx->xm1 );
borlanic 0:fbdae7e6d805 93 mbedtls_mpi_free( &ctx->xm2 );
borlanic 0:fbdae7e6d805 94 mbedtls_mpi_free( &ctx->s );
borlanic 0:fbdae7e6d805 95 }
borlanic 0:fbdae7e6d805 96
borlanic 0:fbdae7e6d805 97 /*
borlanic 0:fbdae7e6d805 98 * Setup context
borlanic 0:fbdae7e6d805 99 */
borlanic 0:fbdae7e6d805 100 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 101 mbedtls_ecjpake_role role,
borlanic 0:fbdae7e6d805 102 mbedtls_md_type_t hash,
borlanic 0:fbdae7e6d805 103 mbedtls_ecp_group_id curve,
borlanic 0:fbdae7e6d805 104 const unsigned char *secret,
borlanic 0:fbdae7e6d805 105 size_t len )
borlanic 0:fbdae7e6d805 106 {
borlanic 0:fbdae7e6d805 107 int ret;
borlanic 0:fbdae7e6d805 108
borlanic 0:fbdae7e6d805 109 ctx->role = role;
borlanic 0:fbdae7e6d805 110
borlanic 0:fbdae7e6d805 111 if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
borlanic 0:fbdae7e6d805 112 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
borlanic 0:fbdae7e6d805 113
borlanic 0:fbdae7e6d805 114 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
borlanic 0:fbdae7e6d805 115
borlanic 0:fbdae7e6d805 116 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
borlanic 0:fbdae7e6d805 117
borlanic 0:fbdae7e6d805 118 cleanup:
borlanic 0:fbdae7e6d805 119 if( ret != 0 )
borlanic 0:fbdae7e6d805 120 mbedtls_ecjpake_free( ctx );
borlanic 0:fbdae7e6d805 121
borlanic 0:fbdae7e6d805 122 return( ret );
borlanic 0:fbdae7e6d805 123 }
borlanic 0:fbdae7e6d805 124
borlanic 0:fbdae7e6d805 125 /*
borlanic 0:fbdae7e6d805 126 * Check if context is ready for use
borlanic 0:fbdae7e6d805 127 */
borlanic 0:fbdae7e6d805 128 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
borlanic 0:fbdae7e6d805 129 {
borlanic 0:fbdae7e6d805 130 if( ctx->md_info == NULL ||
borlanic 0:fbdae7e6d805 131 ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
borlanic 0:fbdae7e6d805 132 ctx->s.p == NULL )
borlanic 0:fbdae7e6d805 133 {
borlanic 0:fbdae7e6d805 134 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 135 }
borlanic 0:fbdae7e6d805 136
borlanic 0:fbdae7e6d805 137 return( 0 );
borlanic 0:fbdae7e6d805 138 }
borlanic 0:fbdae7e6d805 139
borlanic 0:fbdae7e6d805 140 /*
borlanic 0:fbdae7e6d805 141 * Write a point plus its length to a buffer
borlanic 0:fbdae7e6d805 142 */
borlanic 0:fbdae7e6d805 143 static int ecjpake_write_len_point( unsigned char **p,
borlanic 0:fbdae7e6d805 144 const unsigned char *end,
borlanic 0:fbdae7e6d805 145 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 146 const int pf,
borlanic 0:fbdae7e6d805 147 const mbedtls_ecp_point *P )
borlanic 0:fbdae7e6d805 148 {
borlanic 0:fbdae7e6d805 149 int ret;
borlanic 0:fbdae7e6d805 150 size_t len;
borlanic 0:fbdae7e6d805 151
borlanic 0:fbdae7e6d805 152 /* Need at least 4 for length plus 1 for point */
borlanic 0:fbdae7e6d805 153 if( end < *p || end - *p < 5 )
borlanic 0:fbdae7e6d805 154 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 155
borlanic 0:fbdae7e6d805 156 ret = mbedtls_ecp_point_write_binary( grp, P, pf,
borlanic 0:fbdae7e6d805 157 &len, *p + 4, end - ( *p + 4 ) );
borlanic 0:fbdae7e6d805 158 if( ret != 0 )
borlanic 0:fbdae7e6d805 159 return( ret );
borlanic 0:fbdae7e6d805 160
borlanic 0:fbdae7e6d805 161 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
borlanic 0:fbdae7e6d805 162 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
borlanic 0:fbdae7e6d805 163 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
borlanic 0:fbdae7e6d805 164 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
borlanic 0:fbdae7e6d805 165
borlanic 0:fbdae7e6d805 166 *p += 4 + len;
borlanic 0:fbdae7e6d805 167
borlanic 0:fbdae7e6d805 168 return( 0 );
borlanic 0:fbdae7e6d805 169 }
borlanic 0:fbdae7e6d805 170
borlanic 0:fbdae7e6d805 171 /*
borlanic 0:fbdae7e6d805 172 * Size of the temporary buffer for ecjpake_hash:
borlanic 0:fbdae7e6d805 173 * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
borlanic 0:fbdae7e6d805 174 */
borlanic 0:fbdae7e6d805 175 #define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
borlanic 0:fbdae7e6d805 176
borlanic 0:fbdae7e6d805 177 /*
borlanic 0:fbdae7e6d805 178 * Compute hash for ZKP (7.4.2.2.2.1)
borlanic 0:fbdae7e6d805 179 */
borlanic 0:fbdae7e6d805 180 static int ecjpake_hash( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 181 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 182 const int pf,
borlanic 0:fbdae7e6d805 183 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 184 const mbedtls_ecp_point *V,
borlanic 0:fbdae7e6d805 185 const mbedtls_ecp_point *X,
borlanic 0:fbdae7e6d805 186 const char *id,
borlanic 0:fbdae7e6d805 187 mbedtls_mpi *h )
borlanic 0:fbdae7e6d805 188 {
borlanic 0:fbdae7e6d805 189 int ret;
borlanic 0:fbdae7e6d805 190 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
borlanic 0:fbdae7e6d805 191 unsigned char *p = buf;
borlanic 0:fbdae7e6d805 192 const unsigned char *end = buf + sizeof( buf );
borlanic 0:fbdae7e6d805 193 const size_t id_len = strlen( id );
borlanic 0:fbdae7e6d805 194 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
borlanic 0:fbdae7e6d805 195
borlanic 0:fbdae7e6d805 196 /* Write things to temporary buffer */
borlanic 0:fbdae7e6d805 197 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
borlanic 0:fbdae7e6d805 198 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
borlanic 0:fbdae7e6d805 199 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
borlanic 0:fbdae7e6d805 200
borlanic 0:fbdae7e6d805 201 if( end - p < 4 )
borlanic 0:fbdae7e6d805 202 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 203
borlanic 0:fbdae7e6d805 204 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
borlanic 0:fbdae7e6d805 205 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
borlanic 0:fbdae7e6d805 206 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
borlanic 0:fbdae7e6d805 207 *p++ = (unsigned char)( ( id_len ) & 0xFF );
borlanic 0:fbdae7e6d805 208
borlanic 0:fbdae7e6d805 209 if( end < p || (size_t)( end - p ) < id_len )
borlanic 0:fbdae7e6d805 210 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 211
borlanic 0:fbdae7e6d805 212 memcpy( p, id, id_len );
borlanic 0:fbdae7e6d805 213 p += id_len;
borlanic 0:fbdae7e6d805 214
borlanic 0:fbdae7e6d805 215 /* Compute hash */
borlanic 0:fbdae7e6d805 216 mbedtls_md( md_info, buf, p - buf, hash );
borlanic 0:fbdae7e6d805 217
borlanic 0:fbdae7e6d805 218 /* Turn it into an integer mod n */
borlanic 0:fbdae7e6d805 219 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
borlanic 0:fbdae7e6d805 220 mbedtls_md_get_size( md_info ) ) );
borlanic 0:fbdae7e6d805 221 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
borlanic 0:fbdae7e6d805 222
borlanic 0:fbdae7e6d805 223 cleanup:
borlanic 0:fbdae7e6d805 224 return( ret );
borlanic 0:fbdae7e6d805 225 }
borlanic 0:fbdae7e6d805 226
borlanic 0:fbdae7e6d805 227 /*
borlanic 0:fbdae7e6d805 228 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
borlanic 0:fbdae7e6d805 229 */
borlanic 0:fbdae7e6d805 230 static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 231 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 232 const int pf,
borlanic 0:fbdae7e6d805 233 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 234 const mbedtls_ecp_point *X,
borlanic 0:fbdae7e6d805 235 const char *id,
borlanic 0:fbdae7e6d805 236 const unsigned char **p,
borlanic 0:fbdae7e6d805 237 const unsigned char *end )
borlanic 0:fbdae7e6d805 238 {
borlanic 0:fbdae7e6d805 239 int ret;
borlanic 0:fbdae7e6d805 240 mbedtls_ecp_point V, VV;
borlanic 0:fbdae7e6d805 241 mbedtls_mpi r, h;
borlanic 0:fbdae7e6d805 242 size_t r_len;
borlanic 0:fbdae7e6d805 243
borlanic 0:fbdae7e6d805 244 mbedtls_ecp_point_init( &V );
borlanic 0:fbdae7e6d805 245 mbedtls_ecp_point_init( &VV );
borlanic 0:fbdae7e6d805 246 mbedtls_mpi_init( &r );
borlanic 0:fbdae7e6d805 247 mbedtls_mpi_init( &h );
borlanic 0:fbdae7e6d805 248
borlanic 0:fbdae7e6d805 249 /*
borlanic 0:fbdae7e6d805 250 * struct {
borlanic 0:fbdae7e6d805 251 * ECPoint V;
borlanic 0:fbdae7e6d805 252 * opaque r<1..2^8-1>;
borlanic 0:fbdae7e6d805 253 * } ECSchnorrZKP;
borlanic 0:fbdae7e6d805 254 */
borlanic 0:fbdae7e6d805 255 if( end < *p )
borlanic 0:fbdae7e6d805 256 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 257
borlanic 0:fbdae7e6d805 258 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
borlanic 0:fbdae7e6d805 259
borlanic 0:fbdae7e6d805 260 if( end < *p || (size_t)( end - *p ) < 1 )
borlanic 0:fbdae7e6d805 261 {
borlanic 0:fbdae7e6d805 262 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 263 goto cleanup;
borlanic 0:fbdae7e6d805 264 }
borlanic 0:fbdae7e6d805 265
borlanic 0:fbdae7e6d805 266 r_len = *(*p)++;
borlanic 0:fbdae7e6d805 267
borlanic 0:fbdae7e6d805 268 if( end < *p || (size_t)( end - *p ) < r_len )
borlanic 0:fbdae7e6d805 269 {
borlanic 0:fbdae7e6d805 270 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 271 goto cleanup;
borlanic 0:fbdae7e6d805 272 }
borlanic 0:fbdae7e6d805 273
borlanic 0:fbdae7e6d805 274 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
borlanic 0:fbdae7e6d805 275 *p += r_len;
borlanic 0:fbdae7e6d805 276
borlanic 0:fbdae7e6d805 277 /*
borlanic 0:fbdae7e6d805 278 * Verification
borlanic 0:fbdae7e6d805 279 */
borlanic 0:fbdae7e6d805 280 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
borlanic 0:fbdae7e6d805 281 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
borlanic 0:fbdae7e6d805 282 &VV, &h, X, &r, G ) );
borlanic 0:fbdae7e6d805 283
borlanic 0:fbdae7e6d805 284 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
borlanic 0:fbdae7e6d805 285 {
borlanic 0:fbdae7e6d805 286 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
borlanic 0:fbdae7e6d805 287 goto cleanup;
borlanic 0:fbdae7e6d805 288 }
borlanic 0:fbdae7e6d805 289
borlanic 0:fbdae7e6d805 290 cleanup:
borlanic 0:fbdae7e6d805 291 mbedtls_ecp_point_free( &V );
borlanic 0:fbdae7e6d805 292 mbedtls_ecp_point_free( &VV );
borlanic 0:fbdae7e6d805 293 mbedtls_mpi_free( &r );
borlanic 0:fbdae7e6d805 294 mbedtls_mpi_free( &h );
borlanic 0:fbdae7e6d805 295
borlanic 0:fbdae7e6d805 296 return( ret );
borlanic 0:fbdae7e6d805 297 }
borlanic 0:fbdae7e6d805 298
borlanic 0:fbdae7e6d805 299 /*
borlanic 0:fbdae7e6d805 300 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
borlanic 0:fbdae7e6d805 301 */
borlanic 0:fbdae7e6d805 302 static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 303 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 304 const int pf,
borlanic 0:fbdae7e6d805 305 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 306 const mbedtls_mpi *x,
borlanic 0:fbdae7e6d805 307 const mbedtls_ecp_point *X,
borlanic 0:fbdae7e6d805 308 const char *id,
borlanic 0:fbdae7e6d805 309 unsigned char **p,
borlanic 0:fbdae7e6d805 310 const unsigned char *end,
borlanic 0:fbdae7e6d805 311 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 312 void *p_rng )
borlanic 0:fbdae7e6d805 313 {
borlanic 0:fbdae7e6d805 314 int ret;
borlanic 0:fbdae7e6d805 315 mbedtls_ecp_point V;
borlanic 0:fbdae7e6d805 316 mbedtls_mpi v;
borlanic 0:fbdae7e6d805 317 mbedtls_mpi h; /* later recycled to hold r */
borlanic 0:fbdae7e6d805 318 size_t len;
borlanic 0:fbdae7e6d805 319
borlanic 0:fbdae7e6d805 320 if( end < *p )
borlanic 0:fbdae7e6d805 321 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 322
borlanic 0:fbdae7e6d805 323 mbedtls_ecp_point_init( &V );
borlanic 0:fbdae7e6d805 324 mbedtls_mpi_init( &v );
borlanic 0:fbdae7e6d805 325 mbedtls_mpi_init( &h );
borlanic 0:fbdae7e6d805 326
borlanic 0:fbdae7e6d805 327 /* Compute signature */
borlanic 0:fbdae7e6d805 328 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
borlanic 0:fbdae7e6d805 329 G, &v, &V, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 330 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
borlanic 0:fbdae7e6d805 331 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
borlanic 0:fbdae7e6d805 332 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
borlanic 0:fbdae7e6d805 333 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
borlanic 0:fbdae7e6d805 334
borlanic 0:fbdae7e6d805 335 /* Write it out */
borlanic 0:fbdae7e6d805 336 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
borlanic 0:fbdae7e6d805 337 pf, &len, *p, end - *p ) );
borlanic 0:fbdae7e6d805 338 *p += len;
borlanic 0:fbdae7e6d805 339
borlanic 0:fbdae7e6d805 340 len = mbedtls_mpi_size( &h ); /* actually r */
borlanic 0:fbdae7e6d805 341 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
borlanic 0:fbdae7e6d805 342 {
borlanic 0:fbdae7e6d805 343 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
borlanic 0:fbdae7e6d805 344 goto cleanup;
borlanic 0:fbdae7e6d805 345 }
borlanic 0:fbdae7e6d805 346
borlanic 0:fbdae7e6d805 347 *(*p)++ = (unsigned char)( len & 0xFF );
borlanic 0:fbdae7e6d805 348 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
borlanic 0:fbdae7e6d805 349 *p += len;
borlanic 0:fbdae7e6d805 350
borlanic 0:fbdae7e6d805 351 cleanup:
borlanic 0:fbdae7e6d805 352 mbedtls_ecp_point_free( &V );
borlanic 0:fbdae7e6d805 353 mbedtls_mpi_free( &v );
borlanic 0:fbdae7e6d805 354 mbedtls_mpi_free( &h );
borlanic 0:fbdae7e6d805 355
borlanic 0:fbdae7e6d805 356 return( ret );
borlanic 0:fbdae7e6d805 357 }
borlanic 0:fbdae7e6d805 358
borlanic 0:fbdae7e6d805 359 /*
borlanic 0:fbdae7e6d805 360 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
borlanic 0:fbdae7e6d805 361 * Output: verified public key X
borlanic 0:fbdae7e6d805 362 */
borlanic 0:fbdae7e6d805 363 static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 364 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 365 const int pf,
borlanic 0:fbdae7e6d805 366 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 367 mbedtls_ecp_point *X,
borlanic 0:fbdae7e6d805 368 const char *id,
borlanic 0:fbdae7e6d805 369 const unsigned char **p,
borlanic 0:fbdae7e6d805 370 const unsigned char *end )
borlanic 0:fbdae7e6d805 371 {
borlanic 0:fbdae7e6d805 372 int ret;
borlanic 0:fbdae7e6d805 373
borlanic 0:fbdae7e6d805 374 if( end < *p )
borlanic 0:fbdae7e6d805 375 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 376
borlanic 0:fbdae7e6d805 377 /*
borlanic 0:fbdae7e6d805 378 * struct {
borlanic 0:fbdae7e6d805 379 * ECPoint X;
borlanic 0:fbdae7e6d805 380 * ECSchnorrZKP zkp;
borlanic 0:fbdae7e6d805 381 * } ECJPAKEKeyKP;
borlanic 0:fbdae7e6d805 382 */
borlanic 0:fbdae7e6d805 383 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
borlanic 0:fbdae7e6d805 384 if( mbedtls_ecp_is_zero( X ) )
borlanic 0:fbdae7e6d805 385 {
borlanic 0:fbdae7e6d805 386 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
borlanic 0:fbdae7e6d805 387 goto cleanup;
borlanic 0:fbdae7e6d805 388 }
borlanic 0:fbdae7e6d805 389
borlanic 0:fbdae7e6d805 390 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
borlanic 0:fbdae7e6d805 391
borlanic 0:fbdae7e6d805 392 cleanup:
borlanic 0:fbdae7e6d805 393 return( ret );
borlanic 0:fbdae7e6d805 394 }
borlanic 0:fbdae7e6d805 395
borlanic 0:fbdae7e6d805 396 /*
borlanic 0:fbdae7e6d805 397 * Generate an ECJPAKEKeyKP
borlanic 0:fbdae7e6d805 398 * Output: the serialized structure, plus private/public key pair
borlanic 0:fbdae7e6d805 399 */
borlanic 0:fbdae7e6d805 400 static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 401 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 402 const int pf,
borlanic 0:fbdae7e6d805 403 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 404 mbedtls_mpi *x,
borlanic 0:fbdae7e6d805 405 mbedtls_ecp_point *X,
borlanic 0:fbdae7e6d805 406 const char *id,
borlanic 0:fbdae7e6d805 407 unsigned char **p,
borlanic 0:fbdae7e6d805 408 const unsigned char *end,
borlanic 0:fbdae7e6d805 409 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 410 void *p_rng )
borlanic 0:fbdae7e6d805 411 {
borlanic 0:fbdae7e6d805 412 int ret;
borlanic 0:fbdae7e6d805 413 size_t len;
borlanic 0:fbdae7e6d805 414
borlanic 0:fbdae7e6d805 415 if( end < *p )
borlanic 0:fbdae7e6d805 416 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 417
borlanic 0:fbdae7e6d805 418 /* Generate key (7.4.2.3.1) and write it out */
borlanic 0:fbdae7e6d805 419 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
borlanic 0:fbdae7e6d805 420 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 421 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
borlanic 0:fbdae7e6d805 422 pf, &len, *p, end - *p ) );
borlanic 0:fbdae7e6d805 423 *p += len;
borlanic 0:fbdae7e6d805 424
borlanic 0:fbdae7e6d805 425 /* Generate and write proof */
borlanic 0:fbdae7e6d805 426 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
borlanic 0:fbdae7e6d805 427 p, end, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 428
borlanic 0:fbdae7e6d805 429 cleanup:
borlanic 0:fbdae7e6d805 430 return( ret );
borlanic 0:fbdae7e6d805 431 }
borlanic 0:fbdae7e6d805 432
borlanic 0:fbdae7e6d805 433 /*
borlanic 0:fbdae7e6d805 434 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
borlanic 0:fbdae7e6d805 435 * Ouputs: verified peer public keys Xa, Xb
borlanic 0:fbdae7e6d805 436 */
borlanic 0:fbdae7e6d805 437 static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 438 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 439 const int pf,
borlanic 0:fbdae7e6d805 440 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 441 mbedtls_ecp_point *Xa,
borlanic 0:fbdae7e6d805 442 mbedtls_ecp_point *Xb,
borlanic 0:fbdae7e6d805 443 const char *id,
borlanic 0:fbdae7e6d805 444 const unsigned char *buf,
borlanic 0:fbdae7e6d805 445 size_t len )
borlanic 0:fbdae7e6d805 446 {
borlanic 0:fbdae7e6d805 447 int ret;
borlanic 0:fbdae7e6d805 448 const unsigned char *p = buf;
borlanic 0:fbdae7e6d805 449 const unsigned char *end = buf + len;
borlanic 0:fbdae7e6d805 450
borlanic 0:fbdae7e6d805 451 /*
borlanic 0:fbdae7e6d805 452 * struct {
borlanic 0:fbdae7e6d805 453 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
borlanic 0:fbdae7e6d805 454 * } ECJPAKEKeyKPPairList;
borlanic 0:fbdae7e6d805 455 */
borlanic 0:fbdae7e6d805 456 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
borlanic 0:fbdae7e6d805 457 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
borlanic 0:fbdae7e6d805 458
borlanic 0:fbdae7e6d805 459 if( p != end )
borlanic 0:fbdae7e6d805 460 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 461
borlanic 0:fbdae7e6d805 462 cleanup:
borlanic 0:fbdae7e6d805 463 return( ret );
borlanic 0:fbdae7e6d805 464 }
borlanic 0:fbdae7e6d805 465
borlanic 0:fbdae7e6d805 466 /*
borlanic 0:fbdae7e6d805 467 * Generate a ECJPAKEKeyKPPairList
borlanic 0:fbdae7e6d805 468 * Outputs: the serialized structure, plus two private/public key pairs
borlanic 0:fbdae7e6d805 469 */
borlanic 0:fbdae7e6d805 470 static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
borlanic 0:fbdae7e6d805 471 const mbedtls_ecp_group *grp,
borlanic 0:fbdae7e6d805 472 const int pf,
borlanic 0:fbdae7e6d805 473 const mbedtls_ecp_point *G,
borlanic 0:fbdae7e6d805 474 mbedtls_mpi *xm1,
borlanic 0:fbdae7e6d805 475 mbedtls_ecp_point *Xa,
borlanic 0:fbdae7e6d805 476 mbedtls_mpi *xm2,
borlanic 0:fbdae7e6d805 477 mbedtls_ecp_point *Xb,
borlanic 0:fbdae7e6d805 478 const char *id,
borlanic 0:fbdae7e6d805 479 unsigned char *buf,
borlanic 0:fbdae7e6d805 480 size_t len,
borlanic 0:fbdae7e6d805 481 size_t *olen,
borlanic 0:fbdae7e6d805 482 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 483 void *p_rng )
borlanic 0:fbdae7e6d805 484 {
borlanic 0:fbdae7e6d805 485 int ret;
borlanic 0:fbdae7e6d805 486 unsigned char *p = buf;
borlanic 0:fbdae7e6d805 487 const unsigned char *end = buf + len;
borlanic 0:fbdae7e6d805 488
borlanic 0:fbdae7e6d805 489 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
borlanic 0:fbdae7e6d805 490 &p, end, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 491 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
borlanic 0:fbdae7e6d805 492 &p, end, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 493
borlanic 0:fbdae7e6d805 494 *olen = p - buf;
borlanic 0:fbdae7e6d805 495
borlanic 0:fbdae7e6d805 496 cleanup:
borlanic 0:fbdae7e6d805 497 return( ret );
borlanic 0:fbdae7e6d805 498 }
borlanic 0:fbdae7e6d805 499
borlanic 0:fbdae7e6d805 500 /*
borlanic 0:fbdae7e6d805 501 * Read and process the first round message
borlanic 0:fbdae7e6d805 502 */
borlanic 0:fbdae7e6d805 503 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 504 const unsigned char *buf,
borlanic 0:fbdae7e6d805 505 size_t len )
borlanic 0:fbdae7e6d805 506 {
borlanic 0:fbdae7e6d805 507 return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
borlanic 0:fbdae7e6d805 508 &ctx->grp.G,
borlanic 0:fbdae7e6d805 509 &ctx->Xp1, &ctx->Xp2, ID_PEER,
borlanic 0:fbdae7e6d805 510 buf, len ) );
borlanic 0:fbdae7e6d805 511 }
borlanic 0:fbdae7e6d805 512
borlanic 0:fbdae7e6d805 513 /*
borlanic 0:fbdae7e6d805 514 * Generate and write the first round message
borlanic 0:fbdae7e6d805 515 */
borlanic 0:fbdae7e6d805 516 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 517 unsigned char *buf, size_t len, size_t *olen,
borlanic 0:fbdae7e6d805 518 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 519 void *p_rng )
borlanic 0:fbdae7e6d805 520 {
borlanic 0:fbdae7e6d805 521 return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
borlanic 0:fbdae7e6d805 522 &ctx->grp.G,
borlanic 0:fbdae7e6d805 523 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
borlanic 0:fbdae7e6d805 524 ID_MINE, buf, len, olen, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 525 }
borlanic 0:fbdae7e6d805 526
borlanic 0:fbdae7e6d805 527 /*
borlanic 0:fbdae7e6d805 528 * Compute the sum of three points R = A + B + C
borlanic 0:fbdae7e6d805 529 */
borlanic 0:fbdae7e6d805 530 static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
borlanic 0:fbdae7e6d805 531 const mbedtls_ecp_point *A,
borlanic 0:fbdae7e6d805 532 const mbedtls_ecp_point *B,
borlanic 0:fbdae7e6d805 533 const mbedtls_ecp_point *C )
borlanic 0:fbdae7e6d805 534 {
borlanic 0:fbdae7e6d805 535 int ret;
borlanic 0:fbdae7e6d805 536 mbedtls_mpi one;
borlanic 0:fbdae7e6d805 537
borlanic 0:fbdae7e6d805 538 mbedtls_mpi_init( &one );
borlanic 0:fbdae7e6d805 539
borlanic 0:fbdae7e6d805 540 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
borlanic 0:fbdae7e6d805 541 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
borlanic 0:fbdae7e6d805 542 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
borlanic 0:fbdae7e6d805 543
borlanic 0:fbdae7e6d805 544 cleanup:
borlanic 0:fbdae7e6d805 545 mbedtls_mpi_free( &one );
borlanic 0:fbdae7e6d805 546
borlanic 0:fbdae7e6d805 547 return( ret );
borlanic 0:fbdae7e6d805 548 }
borlanic 0:fbdae7e6d805 549
borlanic 0:fbdae7e6d805 550 /*
borlanic 0:fbdae7e6d805 551 * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
borlanic 0:fbdae7e6d805 552 */
borlanic 0:fbdae7e6d805 553 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 554 const unsigned char *buf,
borlanic 0:fbdae7e6d805 555 size_t len )
borlanic 0:fbdae7e6d805 556 {
borlanic 0:fbdae7e6d805 557 int ret;
borlanic 0:fbdae7e6d805 558 const unsigned char *p = buf;
borlanic 0:fbdae7e6d805 559 const unsigned char *end = buf + len;
borlanic 0:fbdae7e6d805 560 mbedtls_ecp_group grp;
borlanic 0:fbdae7e6d805 561 mbedtls_ecp_point G; /* C: GB, S: GA */
borlanic 0:fbdae7e6d805 562
borlanic 0:fbdae7e6d805 563 mbedtls_ecp_group_init( &grp );
borlanic 0:fbdae7e6d805 564 mbedtls_ecp_point_init( &G );
borlanic 0:fbdae7e6d805 565
borlanic 0:fbdae7e6d805 566 /*
borlanic 0:fbdae7e6d805 567 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
borlanic 0:fbdae7e6d805 568 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
borlanic 0:fbdae7e6d805 569 * Unified: G = Xm1 + Xm2 + Xp1
borlanic 0:fbdae7e6d805 570 * We need that before parsing in order to check Xp as we read it
borlanic 0:fbdae7e6d805 571 */
borlanic 0:fbdae7e6d805 572 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
borlanic 0:fbdae7e6d805 573 &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
borlanic 0:fbdae7e6d805 574
borlanic 0:fbdae7e6d805 575 /*
borlanic 0:fbdae7e6d805 576 * struct {
borlanic 0:fbdae7e6d805 577 * ECParameters curve_params; // only client reading server msg
borlanic 0:fbdae7e6d805 578 * ECJPAKEKeyKP ecjpake_key_kp;
borlanic 0:fbdae7e6d805 579 * } Client/ServerECJPAKEParams;
borlanic 0:fbdae7e6d805 580 */
borlanic 0:fbdae7e6d805 581 if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
borlanic 0:fbdae7e6d805 582 {
borlanic 0:fbdae7e6d805 583 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
borlanic 0:fbdae7e6d805 584 if( grp.id != ctx->grp.id )
borlanic 0:fbdae7e6d805 585 {
borlanic 0:fbdae7e6d805 586 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
borlanic 0:fbdae7e6d805 587 goto cleanup;
borlanic 0:fbdae7e6d805 588 }
borlanic 0:fbdae7e6d805 589 }
borlanic 0:fbdae7e6d805 590
borlanic 0:fbdae7e6d805 591 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
borlanic 0:fbdae7e6d805 592 ctx->point_format,
borlanic 0:fbdae7e6d805 593 &G, &ctx->Xp, ID_PEER, &p, end ) );
borlanic 0:fbdae7e6d805 594
borlanic 0:fbdae7e6d805 595 if( p != end )
borlanic 0:fbdae7e6d805 596 {
borlanic 0:fbdae7e6d805 597 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 598 goto cleanup;
borlanic 0:fbdae7e6d805 599 }
borlanic 0:fbdae7e6d805 600
borlanic 0:fbdae7e6d805 601 cleanup:
borlanic 0:fbdae7e6d805 602 mbedtls_ecp_group_free( &grp );
borlanic 0:fbdae7e6d805 603 mbedtls_ecp_point_free( &G );
borlanic 0:fbdae7e6d805 604
borlanic 0:fbdae7e6d805 605 return( ret );
borlanic 0:fbdae7e6d805 606 }
borlanic 0:fbdae7e6d805 607
borlanic 0:fbdae7e6d805 608 /*
borlanic 0:fbdae7e6d805 609 * Compute R = +/- X * S mod N, taking care not to leak S
borlanic 0:fbdae7e6d805 610 */
borlanic 0:fbdae7e6d805 611 static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
borlanic 0:fbdae7e6d805 612 const mbedtls_mpi *X,
borlanic 0:fbdae7e6d805 613 const mbedtls_mpi *S,
borlanic 0:fbdae7e6d805 614 const mbedtls_mpi *N,
borlanic 0:fbdae7e6d805 615 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 616 void *p_rng )
borlanic 0:fbdae7e6d805 617 {
borlanic 0:fbdae7e6d805 618 int ret;
borlanic 0:fbdae7e6d805 619 mbedtls_mpi b; /* Blinding value, then s + N * blinding */
borlanic 0:fbdae7e6d805 620
borlanic 0:fbdae7e6d805 621 mbedtls_mpi_init( &b );
borlanic 0:fbdae7e6d805 622
borlanic 0:fbdae7e6d805 623 /* b = s + rnd-128-bit * N */
borlanic 0:fbdae7e6d805 624 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 625 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
borlanic 0:fbdae7e6d805 626 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
borlanic 0:fbdae7e6d805 627
borlanic 0:fbdae7e6d805 628 /* R = sign * X * b mod N */
borlanic 0:fbdae7e6d805 629 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
borlanic 0:fbdae7e6d805 630 R->s *= sign;
borlanic 0:fbdae7e6d805 631 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
borlanic 0:fbdae7e6d805 632
borlanic 0:fbdae7e6d805 633 cleanup:
borlanic 0:fbdae7e6d805 634 mbedtls_mpi_free( &b );
borlanic 0:fbdae7e6d805 635
borlanic 0:fbdae7e6d805 636 return( ret );
borlanic 0:fbdae7e6d805 637 }
borlanic 0:fbdae7e6d805 638
borlanic 0:fbdae7e6d805 639 /*
borlanic 0:fbdae7e6d805 640 * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
borlanic 0:fbdae7e6d805 641 */
borlanic 0:fbdae7e6d805 642 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 643 unsigned char *buf, size_t len, size_t *olen,
borlanic 0:fbdae7e6d805 644 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 645 void *p_rng )
borlanic 0:fbdae7e6d805 646 {
borlanic 0:fbdae7e6d805 647 int ret;
borlanic 0:fbdae7e6d805 648 mbedtls_ecp_point G; /* C: GA, S: GB */
borlanic 0:fbdae7e6d805 649 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
borlanic 0:fbdae7e6d805 650 mbedtls_mpi xm; /* C: xc, S: xs */
borlanic 0:fbdae7e6d805 651 unsigned char *p = buf;
borlanic 0:fbdae7e6d805 652 const unsigned char *end = buf + len;
borlanic 0:fbdae7e6d805 653 size_t ec_len;
borlanic 0:fbdae7e6d805 654
borlanic 0:fbdae7e6d805 655 mbedtls_ecp_point_init( &G );
borlanic 0:fbdae7e6d805 656 mbedtls_ecp_point_init( &Xm );
borlanic 0:fbdae7e6d805 657 mbedtls_mpi_init( &xm );
borlanic 0:fbdae7e6d805 658
borlanic 0:fbdae7e6d805 659 /*
borlanic 0:fbdae7e6d805 660 * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
borlanic 0:fbdae7e6d805 661 *
borlanic 0:fbdae7e6d805 662 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
borlanic 0:fbdae7e6d805 663 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
borlanic 0:fbdae7e6d805 664 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
borlanic 0:fbdae7e6d805 665 */
borlanic 0:fbdae7e6d805 666 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
borlanic 0:fbdae7e6d805 667 &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
borlanic 0:fbdae7e6d805 668 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
borlanic 0:fbdae7e6d805 669 &ctx->grp.N, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 670 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 671
borlanic 0:fbdae7e6d805 672 /*
borlanic 0:fbdae7e6d805 673 * Now write things out
borlanic 0:fbdae7e6d805 674 *
borlanic 0:fbdae7e6d805 675 * struct {
borlanic 0:fbdae7e6d805 676 * ECParameters curve_params; // only server writing its message
borlanic 0:fbdae7e6d805 677 * ECJPAKEKeyKP ecjpake_key_kp;
borlanic 0:fbdae7e6d805 678 * } Client/ServerECJPAKEParams;
borlanic 0:fbdae7e6d805 679 */
borlanic 0:fbdae7e6d805 680 if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
borlanic 0:fbdae7e6d805 681 {
borlanic 0:fbdae7e6d805 682 if( end < p )
borlanic 0:fbdae7e6d805 683 {
borlanic 0:fbdae7e6d805 684 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
borlanic 0:fbdae7e6d805 685 goto cleanup;
borlanic 0:fbdae7e6d805 686 }
borlanic 0:fbdae7e6d805 687 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
borlanic 0:fbdae7e6d805 688 p, end - p ) );
borlanic 0:fbdae7e6d805 689 p += ec_len;
borlanic 0:fbdae7e6d805 690 }
borlanic 0:fbdae7e6d805 691
borlanic 0:fbdae7e6d805 692 if( end < p )
borlanic 0:fbdae7e6d805 693 {
borlanic 0:fbdae7e6d805 694 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
borlanic 0:fbdae7e6d805 695 goto cleanup;
borlanic 0:fbdae7e6d805 696 }
borlanic 0:fbdae7e6d805 697 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
borlanic 0:fbdae7e6d805 698 ctx->point_format, &ec_len, p, end - p ) );
borlanic 0:fbdae7e6d805 699 p += ec_len;
borlanic 0:fbdae7e6d805 700
borlanic 0:fbdae7e6d805 701 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
borlanic 0:fbdae7e6d805 702 ctx->point_format,
borlanic 0:fbdae7e6d805 703 &G, &xm, &Xm, ID_MINE,
borlanic 0:fbdae7e6d805 704 &p, end, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 705
borlanic 0:fbdae7e6d805 706 *olen = p - buf;
borlanic 0:fbdae7e6d805 707
borlanic 0:fbdae7e6d805 708 cleanup:
borlanic 0:fbdae7e6d805 709 mbedtls_ecp_point_free( &G );
borlanic 0:fbdae7e6d805 710 mbedtls_ecp_point_free( &Xm );
borlanic 0:fbdae7e6d805 711 mbedtls_mpi_free( &xm );
borlanic 0:fbdae7e6d805 712
borlanic 0:fbdae7e6d805 713 return( ret );
borlanic 0:fbdae7e6d805 714 }
borlanic 0:fbdae7e6d805 715
borlanic 0:fbdae7e6d805 716 /*
borlanic 0:fbdae7e6d805 717 * Derive PMS (7.4.2.7 / 7.4.2.8)
borlanic 0:fbdae7e6d805 718 */
borlanic 0:fbdae7e6d805 719 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 720 unsigned char *buf, size_t len, size_t *olen,
borlanic 0:fbdae7e6d805 721 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 722 void *p_rng )
borlanic 0:fbdae7e6d805 723 {
borlanic 0:fbdae7e6d805 724 int ret;
borlanic 0:fbdae7e6d805 725 mbedtls_ecp_point K;
borlanic 0:fbdae7e6d805 726 mbedtls_mpi m_xm2_s, one;
borlanic 0:fbdae7e6d805 727 unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
borlanic 0:fbdae7e6d805 728 size_t x_bytes;
borlanic 0:fbdae7e6d805 729
borlanic 0:fbdae7e6d805 730 *olen = mbedtls_md_get_size( ctx->md_info );
borlanic 0:fbdae7e6d805 731 if( len < *olen )
borlanic 0:fbdae7e6d805 732 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
borlanic 0:fbdae7e6d805 733
borlanic 0:fbdae7e6d805 734 mbedtls_ecp_point_init( &K );
borlanic 0:fbdae7e6d805 735 mbedtls_mpi_init( &m_xm2_s );
borlanic 0:fbdae7e6d805 736 mbedtls_mpi_init( &one );
borlanic 0:fbdae7e6d805 737
borlanic 0:fbdae7e6d805 738 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
borlanic 0:fbdae7e6d805 739
borlanic 0:fbdae7e6d805 740 /*
borlanic 0:fbdae7e6d805 741 * Client: K = ( Xs - X4 * x2 * s ) * x2
borlanic 0:fbdae7e6d805 742 * Server: K = ( Xc - X2 * x4 * s ) * x4
borlanic 0:fbdae7e6d805 743 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
borlanic 0:fbdae7e6d805 744 */
borlanic 0:fbdae7e6d805 745 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
borlanic 0:fbdae7e6d805 746 &ctx->grp.N, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 747 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
borlanic 0:fbdae7e6d805 748 &one, &ctx->Xp,
borlanic 0:fbdae7e6d805 749 &m_xm2_s, &ctx->Xp2 ) );
borlanic 0:fbdae7e6d805 750 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
borlanic 0:fbdae7e6d805 751 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 752
borlanic 0:fbdae7e6d805 753 /* PMS = SHA-256( K.X ) */
borlanic 0:fbdae7e6d805 754 x_bytes = ( ctx->grp.pbits + 7 ) / 8;
borlanic 0:fbdae7e6d805 755 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
borlanic 0:fbdae7e6d805 756 MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
borlanic 0:fbdae7e6d805 757
borlanic 0:fbdae7e6d805 758 cleanup:
borlanic 0:fbdae7e6d805 759 mbedtls_ecp_point_free( &K );
borlanic 0:fbdae7e6d805 760 mbedtls_mpi_free( &m_xm2_s );
borlanic 0:fbdae7e6d805 761 mbedtls_mpi_free( &one );
borlanic 0:fbdae7e6d805 762
borlanic 0:fbdae7e6d805 763 return( ret );
borlanic 0:fbdae7e6d805 764 }
borlanic 0:fbdae7e6d805 765
borlanic 0:fbdae7e6d805 766 #undef ID_MINE
borlanic 0:fbdae7e6d805 767 #undef ID_PEER
borlanic 0:fbdae7e6d805 768
borlanic 0:fbdae7e6d805 769 #endif /* ! MBEDTLS_ECJPAKE_ALT */
borlanic 0:fbdae7e6d805 770
borlanic 0:fbdae7e6d805 771 #if defined(MBEDTLS_SELF_TEST)
borlanic 0:fbdae7e6d805 772
borlanic 0:fbdae7e6d805 773 #if defined(MBEDTLS_PLATFORM_C)
borlanic 0:fbdae7e6d805 774 #include "mbedtls/platform.h"
borlanic 0:fbdae7e6d805 775 #else
borlanic 0:fbdae7e6d805 776 #include <stdio.h>
borlanic 0:fbdae7e6d805 777 #define mbedtls_printf printf
borlanic 0:fbdae7e6d805 778 #endif
borlanic 0:fbdae7e6d805 779
borlanic 0:fbdae7e6d805 780 #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
borlanic 0:fbdae7e6d805 781 !defined(MBEDTLS_SHA256_C)
borlanic 0:fbdae7e6d805 782 int mbedtls_ecjpake_self_test( int verbose )
borlanic 0:fbdae7e6d805 783 {
borlanic 0:fbdae7e6d805 784 (void) verbose;
borlanic 0:fbdae7e6d805 785 return( 0 );
borlanic 0:fbdae7e6d805 786 }
borlanic 0:fbdae7e6d805 787 #else
borlanic 0:fbdae7e6d805 788
borlanic 0:fbdae7e6d805 789 static const unsigned char ecjpake_test_password[] = {
borlanic 0:fbdae7e6d805 790 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
borlanic 0:fbdae7e6d805 791 0x65, 0x73, 0x74
borlanic 0:fbdae7e6d805 792 };
borlanic 0:fbdae7e6d805 793
borlanic 0:fbdae7e6d805 794 static const unsigned char ecjpake_test_x1[] = {
borlanic 0:fbdae7e6d805 795 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
borlanic 0:fbdae7e6d805 796 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
borlanic 0:fbdae7e6d805 797 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
borlanic 0:fbdae7e6d805 798 };
borlanic 0:fbdae7e6d805 799
borlanic 0:fbdae7e6d805 800 static const unsigned char ecjpake_test_x2[] = {
borlanic 0:fbdae7e6d805 801 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
borlanic 0:fbdae7e6d805 802 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
borlanic 0:fbdae7e6d805 803 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
borlanic 0:fbdae7e6d805 804 };
borlanic 0:fbdae7e6d805 805
borlanic 0:fbdae7e6d805 806 static const unsigned char ecjpake_test_x3[] = {
borlanic 0:fbdae7e6d805 807 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
borlanic 0:fbdae7e6d805 808 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
borlanic 0:fbdae7e6d805 809 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
borlanic 0:fbdae7e6d805 810 };
borlanic 0:fbdae7e6d805 811
borlanic 0:fbdae7e6d805 812 static const unsigned char ecjpake_test_x4[] = {
borlanic 0:fbdae7e6d805 813 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
borlanic 0:fbdae7e6d805 814 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
borlanic 0:fbdae7e6d805 815 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
borlanic 0:fbdae7e6d805 816 };
borlanic 0:fbdae7e6d805 817
borlanic 0:fbdae7e6d805 818 static const unsigned char ecjpake_test_cli_one[] = {
borlanic 0:fbdae7e6d805 819 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
borlanic 0:fbdae7e6d805 820 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
borlanic 0:fbdae7e6d805 821 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
borlanic 0:fbdae7e6d805 822 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
borlanic 0:fbdae7e6d805 823 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
borlanic 0:fbdae7e6d805 824 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
borlanic 0:fbdae7e6d805 825 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
borlanic 0:fbdae7e6d805 826 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
borlanic 0:fbdae7e6d805 827 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
borlanic 0:fbdae7e6d805 828 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
borlanic 0:fbdae7e6d805 829 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
borlanic 0:fbdae7e6d805 830 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
borlanic 0:fbdae7e6d805 831 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
borlanic 0:fbdae7e6d805 832 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
borlanic 0:fbdae7e6d805 833 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
borlanic 0:fbdae7e6d805 834 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
borlanic 0:fbdae7e6d805 835 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
borlanic 0:fbdae7e6d805 836 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
borlanic 0:fbdae7e6d805 837 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
borlanic 0:fbdae7e6d805 838 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
borlanic 0:fbdae7e6d805 839 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
borlanic 0:fbdae7e6d805 840 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
borlanic 0:fbdae7e6d805 841 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
borlanic 0:fbdae7e6d805 842 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
borlanic 0:fbdae7e6d805 843 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
borlanic 0:fbdae7e6d805 844 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
borlanic 0:fbdae7e6d805 845 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
borlanic 0:fbdae7e6d805 846 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
borlanic 0:fbdae7e6d805 847 };
borlanic 0:fbdae7e6d805 848
borlanic 0:fbdae7e6d805 849 static const unsigned char ecjpake_test_srv_one[] = {
borlanic 0:fbdae7e6d805 850 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
borlanic 0:fbdae7e6d805 851 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
borlanic 0:fbdae7e6d805 852 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
borlanic 0:fbdae7e6d805 853 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
borlanic 0:fbdae7e6d805 854 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
borlanic 0:fbdae7e6d805 855 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
borlanic 0:fbdae7e6d805 856 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
borlanic 0:fbdae7e6d805 857 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
borlanic 0:fbdae7e6d805 858 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
borlanic 0:fbdae7e6d805 859 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
borlanic 0:fbdae7e6d805 860 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
borlanic 0:fbdae7e6d805 861 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
borlanic 0:fbdae7e6d805 862 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
borlanic 0:fbdae7e6d805 863 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
borlanic 0:fbdae7e6d805 864 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
borlanic 0:fbdae7e6d805 865 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
borlanic 0:fbdae7e6d805 866 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
borlanic 0:fbdae7e6d805 867 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
borlanic 0:fbdae7e6d805 868 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
borlanic 0:fbdae7e6d805 869 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
borlanic 0:fbdae7e6d805 870 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
borlanic 0:fbdae7e6d805 871 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
borlanic 0:fbdae7e6d805 872 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
borlanic 0:fbdae7e6d805 873 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
borlanic 0:fbdae7e6d805 874 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
borlanic 0:fbdae7e6d805 875 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
borlanic 0:fbdae7e6d805 876 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
borlanic 0:fbdae7e6d805 877 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
borlanic 0:fbdae7e6d805 878 };
borlanic 0:fbdae7e6d805 879
borlanic 0:fbdae7e6d805 880 static const unsigned char ecjpake_test_srv_two[] = {
borlanic 0:fbdae7e6d805 881 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
borlanic 0:fbdae7e6d805 882 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
borlanic 0:fbdae7e6d805 883 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
borlanic 0:fbdae7e6d805 884 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
borlanic 0:fbdae7e6d805 885 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
borlanic 0:fbdae7e6d805 886 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
borlanic 0:fbdae7e6d805 887 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
borlanic 0:fbdae7e6d805 888 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
borlanic 0:fbdae7e6d805 889 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
borlanic 0:fbdae7e6d805 890 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
borlanic 0:fbdae7e6d805 891 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
borlanic 0:fbdae7e6d805 892 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
borlanic 0:fbdae7e6d805 893 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
borlanic 0:fbdae7e6d805 894 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
borlanic 0:fbdae7e6d805 895 };
borlanic 0:fbdae7e6d805 896
borlanic 0:fbdae7e6d805 897 static const unsigned char ecjpake_test_cli_two[] = {
borlanic 0:fbdae7e6d805 898 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
borlanic 0:fbdae7e6d805 899 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
borlanic 0:fbdae7e6d805 900 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
borlanic 0:fbdae7e6d805 901 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
borlanic 0:fbdae7e6d805 902 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
borlanic 0:fbdae7e6d805 903 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
borlanic 0:fbdae7e6d805 904 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
borlanic 0:fbdae7e6d805 905 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
borlanic 0:fbdae7e6d805 906 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
borlanic 0:fbdae7e6d805 907 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
borlanic 0:fbdae7e6d805 908 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
borlanic 0:fbdae7e6d805 909 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
borlanic 0:fbdae7e6d805 910 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
borlanic 0:fbdae7e6d805 911 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
borlanic 0:fbdae7e6d805 912 };
borlanic 0:fbdae7e6d805 913
borlanic 0:fbdae7e6d805 914 static const unsigned char ecjpake_test_pms[] = {
borlanic 0:fbdae7e6d805 915 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
borlanic 0:fbdae7e6d805 916 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
borlanic 0:fbdae7e6d805 917 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
borlanic 0:fbdae7e6d805 918 };
borlanic 0:fbdae7e6d805 919
borlanic 0:fbdae7e6d805 920 /* Load my private keys and generate the correponding public keys */
borlanic 0:fbdae7e6d805 921 static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
borlanic 0:fbdae7e6d805 922 const unsigned char *xm1, size_t len1,
borlanic 0:fbdae7e6d805 923 const unsigned char *xm2, size_t len2 )
borlanic 0:fbdae7e6d805 924 {
borlanic 0:fbdae7e6d805 925 int ret;
borlanic 0:fbdae7e6d805 926
borlanic 0:fbdae7e6d805 927 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
borlanic 0:fbdae7e6d805 928 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
borlanic 0:fbdae7e6d805 929 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
borlanic 0:fbdae7e6d805 930 &ctx->grp.G, NULL, NULL ) );
borlanic 0:fbdae7e6d805 931 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
borlanic 0:fbdae7e6d805 932 &ctx->grp.G, NULL, NULL ) );
borlanic 0:fbdae7e6d805 933
borlanic 0:fbdae7e6d805 934 cleanup:
borlanic 0:fbdae7e6d805 935 return( ret );
borlanic 0:fbdae7e6d805 936 }
borlanic 0:fbdae7e6d805 937
borlanic 0:fbdae7e6d805 938 /* For tests we don't need a secure RNG;
borlanic 0:fbdae7e6d805 939 * use the LGC from Numerical Recipes for simplicity */
borlanic 0:fbdae7e6d805 940 static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
borlanic 0:fbdae7e6d805 941 {
borlanic 0:fbdae7e6d805 942 static uint32_t x = 42;
borlanic 0:fbdae7e6d805 943 (void) p;
borlanic 0:fbdae7e6d805 944
borlanic 0:fbdae7e6d805 945 while( len > 0 )
borlanic 0:fbdae7e6d805 946 {
borlanic 0:fbdae7e6d805 947 size_t use_len = len > 4 ? 4 : len;
borlanic 0:fbdae7e6d805 948 x = 1664525 * x + 1013904223;
borlanic 0:fbdae7e6d805 949 memcpy( out, &x, use_len );
borlanic 0:fbdae7e6d805 950 out += use_len;
borlanic 0:fbdae7e6d805 951 len -= use_len;
borlanic 0:fbdae7e6d805 952 }
borlanic 0:fbdae7e6d805 953
borlanic 0:fbdae7e6d805 954 return( 0 );
borlanic 0:fbdae7e6d805 955 }
borlanic 0:fbdae7e6d805 956
borlanic 0:fbdae7e6d805 957 #define TEST_ASSERT( x ) \
borlanic 0:fbdae7e6d805 958 do { \
borlanic 0:fbdae7e6d805 959 if( x ) \
borlanic 0:fbdae7e6d805 960 ret = 0; \
borlanic 0:fbdae7e6d805 961 else \
borlanic 0:fbdae7e6d805 962 { \
borlanic 0:fbdae7e6d805 963 ret = 1; \
borlanic 0:fbdae7e6d805 964 goto cleanup; \
borlanic 0:fbdae7e6d805 965 } \
borlanic 0:fbdae7e6d805 966 } while( 0 )
borlanic 0:fbdae7e6d805 967
borlanic 0:fbdae7e6d805 968 /*
borlanic 0:fbdae7e6d805 969 * Checkup routine
borlanic 0:fbdae7e6d805 970 */
borlanic 0:fbdae7e6d805 971 int mbedtls_ecjpake_self_test( int verbose )
borlanic 0:fbdae7e6d805 972 {
borlanic 0:fbdae7e6d805 973 int ret;
borlanic 0:fbdae7e6d805 974 mbedtls_ecjpake_context cli;
borlanic 0:fbdae7e6d805 975 mbedtls_ecjpake_context srv;
borlanic 0:fbdae7e6d805 976 unsigned char buf[512], pms[32];
borlanic 0:fbdae7e6d805 977 size_t len, pmslen;
borlanic 0:fbdae7e6d805 978
borlanic 0:fbdae7e6d805 979 mbedtls_ecjpake_init( &cli );
borlanic 0:fbdae7e6d805 980 mbedtls_ecjpake_init( &srv );
borlanic 0:fbdae7e6d805 981
borlanic 0:fbdae7e6d805 982 if( verbose != 0 )
borlanic 0:fbdae7e6d805 983 mbedtls_printf( " ECJPAKE test #0 (setup): " );
borlanic 0:fbdae7e6d805 984
borlanic 0:fbdae7e6d805 985 TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
borlanic 0:fbdae7e6d805 986 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
borlanic 0:fbdae7e6d805 987 ecjpake_test_password,
borlanic 0:fbdae7e6d805 988 sizeof( ecjpake_test_password ) ) == 0 );
borlanic 0:fbdae7e6d805 989
borlanic 0:fbdae7e6d805 990 TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
borlanic 0:fbdae7e6d805 991 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
borlanic 0:fbdae7e6d805 992 ecjpake_test_password,
borlanic 0:fbdae7e6d805 993 sizeof( ecjpake_test_password ) ) == 0 );
borlanic 0:fbdae7e6d805 994
borlanic 0:fbdae7e6d805 995 if( verbose != 0 )
borlanic 0:fbdae7e6d805 996 mbedtls_printf( "passed\n" );
borlanic 0:fbdae7e6d805 997
borlanic 0:fbdae7e6d805 998 if( verbose != 0 )
borlanic 0:fbdae7e6d805 999 mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
borlanic 0:fbdae7e6d805 1000
borlanic 0:fbdae7e6d805 1001 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
borlanic 0:fbdae7e6d805 1002 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1003
borlanic 0:fbdae7e6d805 1004 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
borlanic 0:fbdae7e6d805 1005
borlanic 0:fbdae7e6d805 1006 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
borlanic 0:fbdae7e6d805 1007 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1008
borlanic 0:fbdae7e6d805 1009 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
borlanic 0:fbdae7e6d805 1010
borlanic 0:fbdae7e6d805 1011 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
borlanic 0:fbdae7e6d805 1012 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1013
borlanic 0:fbdae7e6d805 1014 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
borlanic 0:fbdae7e6d805 1015
borlanic 0:fbdae7e6d805 1016 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
borlanic 0:fbdae7e6d805 1017 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1018
borlanic 0:fbdae7e6d805 1019 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
borlanic 0:fbdae7e6d805 1020 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1021
borlanic 0:fbdae7e6d805 1022 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
borlanic 0:fbdae7e6d805 1023
borlanic 0:fbdae7e6d805 1024 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
borlanic 0:fbdae7e6d805 1025 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1026
borlanic 0:fbdae7e6d805 1027 TEST_ASSERT( len == pmslen );
borlanic 0:fbdae7e6d805 1028 TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
borlanic 0:fbdae7e6d805 1029
borlanic 0:fbdae7e6d805 1030 if( verbose != 0 )
borlanic 0:fbdae7e6d805 1031 mbedtls_printf( "passed\n" );
borlanic 0:fbdae7e6d805 1032
borlanic 0:fbdae7e6d805 1033 if( verbose != 0 )
borlanic 0:fbdae7e6d805 1034 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
borlanic 0:fbdae7e6d805 1035
borlanic 0:fbdae7e6d805 1036 /* Simulate generation of round one */
borlanic 0:fbdae7e6d805 1037 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
borlanic 0:fbdae7e6d805 1038 ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
borlanic 0:fbdae7e6d805 1039 ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
borlanic 0:fbdae7e6d805 1040
borlanic 0:fbdae7e6d805 1041 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
borlanic 0:fbdae7e6d805 1042 ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
borlanic 0:fbdae7e6d805 1043 ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
borlanic 0:fbdae7e6d805 1044
borlanic 0:fbdae7e6d805 1045 /* Read round one */
borlanic 0:fbdae7e6d805 1046 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
borlanic 0:fbdae7e6d805 1047 ecjpake_test_cli_one,
borlanic 0:fbdae7e6d805 1048 sizeof( ecjpake_test_cli_one ) ) == 0 );
borlanic 0:fbdae7e6d805 1049
borlanic 0:fbdae7e6d805 1050 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
borlanic 0:fbdae7e6d805 1051 ecjpake_test_srv_one,
borlanic 0:fbdae7e6d805 1052 sizeof( ecjpake_test_srv_one ) ) == 0 );
borlanic 0:fbdae7e6d805 1053
borlanic 0:fbdae7e6d805 1054 /* Skip generation of round two, read round two */
borlanic 0:fbdae7e6d805 1055 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
borlanic 0:fbdae7e6d805 1056 ecjpake_test_srv_two,
borlanic 0:fbdae7e6d805 1057 sizeof( ecjpake_test_srv_two ) ) == 0 );
borlanic 0:fbdae7e6d805 1058
borlanic 0:fbdae7e6d805 1059 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
borlanic 0:fbdae7e6d805 1060 ecjpake_test_cli_two,
borlanic 0:fbdae7e6d805 1061 sizeof( ecjpake_test_cli_two ) ) == 0 );
borlanic 0:fbdae7e6d805 1062
borlanic 0:fbdae7e6d805 1063 /* Server derives PMS */
borlanic 0:fbdae7e6d805 1064 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
borlanic 0:fbdae7e6d805 1065 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1066
borlanic 0:fbdae7e6d805 1067 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
borlanic 0:fbdae7e6d805 1068 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
borlanic 0:fbdae7e6d805 1069
borlanic 0:fbdae7e6d805 1070 memset( buf, 0, len ); /* Avoid interferences with next step */
borlanic 0:fbdae7e6d805 1071
borlanic 0:fbdae7e6d805 1072 /* Client derives PMS */
borlanic 0:fbdae7e6d805 1073 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
borlanic 0:fbdae7e6d805 1074 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
borlanic 0:fbdae7e6d805 1075
borlanic 0:fbdae7e6d805 1076 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
borlanic 0:fbdae7e6d805 1077 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
borlanic 0:fbdae7e6d805 1078
borlanic 0:fbdae7e6d805 1079 if( verbose != 0 )
borlanic 0:fbdae7e6d805 1080 mbedtls_printf( "passed\n" );
borlanic 0:fbdae7e6d805 1081
borlanic 0:fbdae7e6d805 1082 cleanup:
borlanic 0:fbdae7e6d805 1083 mbedtls_ecjpake_free( &cli );
borlanic 0:fbdae7e6d805 1084 mbedtls_ecjpake_free( &srv );
borlanic 0:fbdae7e6d805 1085
borlanic 0:fbdae7e6d805 1086 if( ret != 0 )
borlanic 0:fbdae7e6d805 1087 {
borlanic 0:fbdae7e6d805 1088 if( verbose != 0 )
borlanic 0:fbdae7e6d805 1089 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 1090
borlanic 0:fbdae7e6d805 1091 ret = 1;
borlanic 0:fbdae7e6d805 1092 }
borlanic 0:fbdae7e6d805 1093
borlanic 0:fbdae7e6d805 1094 if( verbose != 0 )
borlanic 0:fbdae7e6d805 1095 mbedtls_printf( "\n" );
borlanic 0:fbdae7e6d805 1096
borlanic 0:fbdae7e6d805 1097 return( ret );
borlanic 0:fbdae7e6d805 1098 }
borlanic 0:fbdae7e6d805 1099
borlanic 0:fbdae7e6d805 1100 #undef TEST_ASSERT
borlanic 0:fbdae7e6d805 1101
borlanic 0:fbdae7e6d805 1102 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
borlanic 0:fbdae7e6d805 1103
borlanic 0:fbdae7e6d805 1104 #endif /* MBEDTLS_SELF_TEST */
borlanic 0:fbdae7e6d805 1105
borlanic 0:fbdae7e6d805 1106 #endif /* MBEDTLS_ECJPAKE_C */