This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

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

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

Who changed what in which revision?

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