Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HannesTschofenig 0:796d0f61a05b 1 /*
HannesTschofenig 0:796d0f61a05b 2 * Elliptic curve Diffie-Hellman
HannesTschofenig 0:796d0f61a05b 3 *
HannesTschofenig 0:796d0f61a05b 4 * Copyright (C) 2006-2014, Brainspark B.V.
HannesTschofenig 0:796d0f61a05b 5 *
HannesTschofenig 0:796d0f61a05b 6 * This file is part of PolarSSL (http://www.polarssl.org)
HannesTschofenig 0:796d0f61a05b 7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
HannesTschofenig 0:796d0f61a05b 8 *
HannesTschofenig 0:796d0f61a05b 9 * All rights reserved.
HannesTschofenig 0:796d0f61a05b 10 *
HannesTschofenig 0:796d0f61a05b 11 * This program is free software; you can redistribute it and/or modify
HannesTschofenig 0:796d0f61a05b 12 * it under the terms of the GNU General Public License as published by
HannesTschofenig 0:796d0f61a05b 13 * the Free Software Foundation; either version 2 of the License, or
HannesTschofenig 0:796d0f61a05b 14 * (at your option) any later version.
HannesTschofenig 0:796d0f61a05b 15 *
HannesTschofenig 0:796d0f61a05b 16 * This program is distributed in the hope that it will be useful,
HannesTschofenig 0:796d0f61a05b 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
HannesTschofenig 0:796d0f61a05b 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
HannesTschofenig 0:796d0f61a05b 19 * GNU General Public License for more details.
HannesTschofenig 0:796d0f61a05b 20 *
HannesTschofenig 0:796d0f61a05b 21 * You should have received a copy of the GNU General Public License along
HannesTschofenig 0:796d0f61a05b 22 * with this program; if not, write to the Free Software Foundation, Inc.,
HannesTschofenig 0:796d0f61a05b 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
HannesTschofenig 0:796d0f61a05b 24 */
HannesTschofenig 0:796d0f61a05b 25
HannesTschofenig 0:796d0f61a05b 26 /*
HannesTschofenig 0:796d0f61a05b 27 * References:
HannesTschofenig 0:796d0f61a05b 28 *
HannesTschofenig 0:796d0f61a05b 29 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
HannesTschofenig 0:796d0f61a05b 30 * RFC 4492
HannesTschofenig 0:796d0f61a05b 31 */
HannesTschofenig 0:796d0f61a05b 32
HannesTschofenig 0:796d0f61a05b 33 #if !defined(POLARSSL_CONFIG_FILE)
HannesTschofenig 0:796d0f61a05b 34 #include "polarssl/config.h"
HannesTschofenig 0:796d0f61a05b 35 #else
HannesTschofenig 0:796d0f61a05b 36 #include POLARSSL_CONFIG_FILE
HannesTschofenig 0:796d0f61a05b 37 #endif
HannesTschofenig 0:796d0f61a05b 38
HannesTschofenig 0:796d0f61a05b 39 #if defined(POLARSSL_ECDH_C)
HannesTschofenig 0:796d0f61a05b 40
HannesTschofenig 0:796d0f61a05b 41 #include "polarssl/ecdh.h"
HannesTschofenig 0:796d0f61a05b 42
HannesTschofenig 0:796d0f61a05b 43 /*
HannesTschofenig 0:796d0f61a05b 44 * Generate public key: simple wrapper around ecp_gen_keypair
HannesTschofenig 0:796d0f61a05b 45 */
HannesTschofenig 0:796d0f61a05b 46 int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q,
HannesTschofenig 0:796d0f61a05b 47 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 48 void *p_rng )
HannesTschofenig 0:796d0f61a05b 49 {
HannesTschofenig 0:796d0f61a05b 50 return ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
HannesTschofenig 0:796d0f61a05b 51 }
HannesTschofenig 0:796d0f61a05b 52
HannesTschofenig 0:796d0f61a05b 53 /*
HannesTschofenig 0:796d0f61a05b 54 * Compute shared secret (SEC1 3.3.1)
HannesTschofenig 0:796d0f61a05b 55 */
HannesTschofenig 0:796d0f61a05b 56 int ecdh_compute_shared( ecp_group *grp, mpi *z,
HannesTschofenig 0:796d0f61a05b 57 const ecp_point *Q, const mpi *d,
HannesTschofenig 0:796d0f61a05b 58 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 59 void *p_rng )
HannesTschofenig 0:796d0f61a05b 60 {
HannesTschofenig 0:796d0f61a05b 61 int ret;
HannesTschofenig 0:796d0f61a05b 62 ecp_point P;
HannesTschofenig 0:796d0f61a05b 63
HannesTschofenig 0:796d0f61a05b 64 ecp_point_init( &P );
HannesTschofenig 0:796d0f61a05b 65
HannesTschofenig 0:796d0f61a05b 66 /*
HannesTschofenig 0:796d0f61a05b 67 * Make sure Q is a valid pubkey before using it
HannesTschofenig 0:796d0f61a05b 68 */
HannesTschofenig 0:796d0f61a05b 69 MPI_CHK( ecp_check_pubkey( grp, Q ) );
HannesTschofenig 0:796d0f61a05b 70
HannesTschofenig 0:796d0f61a05b 71 MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
HannesTschofenig 0:796d0f61a05b 72
HannesTschofenig 0:796d0f61a05b 73 if( ecp_is_zero( &P ) )
HannesTschofenig 0:796d0f61a05b 74 {
HannesTschofenig 0:796d0f61a05b 75 ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
HannesTschofenig 0:796d0f61a05b 76 goto cleanup;
HannesTschofenig 0:796d0f61a05b 77 }
HannesTschofenig 0:796d0f61a05b 78
HannesTschofenig 0:796d0f61a05b 79 MPI_CHK( mpi_copy( z, &P.X ) );
HannesTschofenig 0:796d0f61a05b 80
HannesTschofenig 0:796d0f61a05b 81 cleanup:
HannesTschofenig 0:796d0f61a05b 82 ecp_point_free( &P );
HannesTschofenig 0:796d0f61a05b 83
HannesTschofenig 0:796d0f61a05b 84 return( ret );
HannesTschofenig 0:796d0f61a05b 85 }
HannesTschofenig 0:796d0f61a05b 86
HannesTschofenig 0:796d0f61a05b 87 /*
HannesTschofenig 0:796d0f61a05b 88 * Initialize context
HannesTschofenig 0:796d0f61a05b 89 */
HannesTschofenig 0:796d0f61a05b 90 void ecdh_init( ecdh_context *ctx )
HannesTschofenig 0:796d0f61a05b 91 {
HannesTschofenig 0:796d0f61a05b 92 memset( ctx, 0, sizeof( ecdh_context ) );
HannesTschofenig 0:796d0f61a05b 93 }
HannesTschofenig 0:796d0f61a05b 94
HannesTschofenig 0:796d0f61a05b 95 /*
HannesTschofenig 0:796d0f61a05b 96 * Free context
HannesTschofenig 0:796d0f61a05b 97 */
HannesTschofenig 0:796d0f61a05b 98 void ecdh_free( ecdh_context *ctx )
HannesTschofenig 0:796d0f61a05b 99 {
HannesTschofenig 0:796d0f61a05b 100 if( ctx == NULL )
HannesTschofenig 0:796d0f61a05b 101 return;
HannesTschofenig 0:796d0f61a05b 102
HannesTschofenig 0:796d0f61a05b 103 ecp_group_free( &ctx->grp );
HannesTschofenig 0:796d0f61a05b 104 mpi_free ( &ctx->d );
HannesTschofenig 0:796d0f61a05b 105 ecp_point_free( &ctx->Q );
HannesTschofenig 0:796d0f61a05b 106 ecp_point_free( &ctx->Qp );
HannesTschofenig 0:796d0f61a05b 107 mpi_free ( &ctx->z );
HannesTschofenig 0:796d0f61a05b 108 ecp_point_free( &ctx->Vi );
HannesTschofenig 0:796d0f61a05b 109 ecp_point_free( &ctx->Vf );
HannesTschofenig 0:796d0f61a05b 110 mpi_free ( &ctx->_d );
HannesTschofenig 0:796d0f61a05b 111 }
HannesTschofenig 0:796d0f61a05b 112
HannesTschofenig 0:796d0f61a05b 113 /*
HannesTschofenig 0:796d0f61a05b 114 * Setup and write the ServerKeyExhange parameters (RFC 4492)
HannesTschofenig 0:796d0f61a05b 115 * struct {
HannesTschofenig 0:796d0f61a05b 116 * ECParameters curve_params;
HannesTschofenig 0:796d0f61a05b 117 * ECPoint public;
HannesTschofenig 0:796d0f61a05b 118 * } ServerECDHParams;
HannesTschofenig 0:796d0f61a05b 119 */
HannesTschofenig 0:796d0f61a05b 120 int ecdh_make_params( ecdh_context *ctx, size_t *olen,
HannesTschofenig 0:796d0f61a05b 121 unsigned char *buf, size_t blen,
HannesTschofenig 0:796d0f61a05b 122 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 123 void *p_rng )
HannesTschofenig 0:796d0f61a05b 124 {
HannesTschofenig 0:796d0f61a05b 125 int ret;
HannesTschofenig 0:796d0f61a05b 126 size_t grp_len, pt_len;
HannesTschofenig 0:796d0f61a05b 127
HannesTschofenig 0:796d0f61a05b 128 if( ctx == NULL || ctx->grp.pbits == 0 )
HannesTschofenig 0:796d0f61a05b 129 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 130
HannesTschofenig 0:796d0f61a05b 131 if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
HannesTschofenig 0:796d0f61a05b 132 != 0 )
HannesTschofenig 0:796d0f61a05b 133 return( ret );
HannesTschofenig 0:796d0f61a05b 134
HannesTschofenig 0:796d0f61a05b 135 if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
HannesTschofenig 0:796d0f61a05b 136 != 0 )
HannesTschofenig 0:796d0f61a05b 137 return( ret );
HannesTschofenig 0:796d0f61a05b 138
HannesTschofenig 0:796d0f61a05b 139 buf += grp_len;
HannesTschofenig 0:796d0f61a05b 140 blen -= grp_len;
HannesTschofenig 0:796d0f61a05b 141
HannesTschofenig 0:796d0f61a05b 142 if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
HannesTschofenig 0:796d0f61a05b 143 &pt_len, buf, blen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 144 return( ret );
HannesTschofenig 0:796d0f61a05b 145
HannesTschofenig 0:796d0f61a05b 146 *olen = grp_len + pt_len;
HannesTschofenig 0:796d0f61a05b 147 return 0;
HannesTschofenig 0:796d0f61a05b 148 }
HannesTschofenig 0:796d0f61a05b 149
HannesTschofenig 0:796d0f61a05b 150 /*
HannesTschofenig 0:796d0f61a05b 151 * Read the ServerKeyExhange parameters (RFC 4492)
HannesTschofenig 0:796d0f61a05b 152 * struct {
HannesTschofenig 0:796d0f61a05b 153 * ECParameters curve_params;
HannesTschofenig 0:796d0f61a05b 154 * ECPoint public;
HannesTschofenig 0:796d0f61a05b 155 * } ServerECDHParams;
HannesTschofenig 0:796d0f61a05b 156 */
HannesTschofenig 0:796d0f61a05b 157 int ecdh_read_params( ecdh_context *ctx,
HannesTschofenig 0:796d0f61a05b 158 const unsigned char **buf, const unsigned char *end )
HannesTschofenig 0:796d0f61a05b 159 {
HannesTschofenig 0:796d0f61a05b 160 int ret;
HannesTschofenig 0:796d0f61a05b 161
HannesTschofenig 0:796d0f61a05b 162 if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 163 return( ret );
HannesTschofenig 0:796d0f61a05b 164
HannesTschofenig 0:796d0f61a05b 165 if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
HannesTschofenig 0:796d0f61a05b 166 != 0 )
HannesTschofenig 0:796d0f61a05b 167 return( ret );
HannesTschofenig 0:796d0f61a05b 168
HannesTschofenig 0:796d0f61a05b 169 return 0;
HannesTschofenig 0:796d0f61a05b 170 }
HannesTschofenig 0:796d0f61a05b 171
HannesTschofenig 0:796d0f61a05b 172 /*
HannesTschofenig 0:796d0f61a05b 173 * Get parameters from a keypair
HannesTschofenig 0:796d0f61a05b 174 */
HannesTschofenig 0:796d0f61a05b 175 int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
HannesTschofenig 0:796d0f61a05b 176 ecdh_side side )
HannesTschofenig 0:796d0f61a05b 177 {
HannesTschofenig 0:796d0f61a05b 178 int ret;
HannesTschofenig 0:796d0f61a05b 179
HannesTschofenig 0:796d0f61a05b 180 if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 181 return( ret );
HannesTschofenig 0:796d0f61a05b 182
HannesTschofenig 0:796d0f61a05b 183 /* If it's not our key, just import the public part as Qp */
HannesTschofenig 0:796d0f61a05b 184 if( side == POLARSSL_ECDH_THEIRS )
HannesTschofenig 0:796d0f61a05b 185 return( ecp_copy( &ctx->Qp, &key->Q ) );
HannesTschofenig 0:796d0f61a05b 186
HannesTschofenig 0:796d0f61a05b 187 /* Our key: import public (as Q) and private parts */
HannesTschofenig 0:796d0f61a05b 188 if( side != POLARSSL_ECDH_OURS )
HannesTschofenig 0:796d0f61a05b 189 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 190
HannesTschofenig 0:796d0f61a05b 191 if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
HannesTschofenig 0:796d0f61a05b 192 ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 193 return( ret );
HannesTschofenig 0:796d0f61a05b 194
HannesTschofenig 0:796d0f61a05b 195 return( 0 );
HannesTschofenig 0:796d0f61a05b 196 }
HannesTschofenig 0:796d0f61a05b 197
HannesTschofenig 0:796d0f61a05b 198 /*
HannesTschofenig 0:796d0f61a05b 199 * Setup and export the client public value
HannesTschofenig 0:796d0f61a05b 200 */
HannesTschofenig 0:796d0f61a05b 201 int ecdh_make_public( ecdh_context *ctx, size_t *olen,
HannesTschofenig 0:796d0f61a05b 202 unsigned char *buf, size_t blen,
HannesTschofenig 0:796d0f61a05b 203 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 204 void *p_rng )
HannesTschofenig 0:796d0f61a05b 205 {
HannesTschofenig 0:796d0f61a05b 206 int ret;
HannesTschofenig 0:796d0f61a05b 207
HannesTschofenig 0:796d0f61a05b 208 if( ctx == NULL || ctx->grp.pbits == 0 )
HannesTschofenig 0:796d0f61a05b 209 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 210
HannesTschofenig 0:796d0f61a05b 211 if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
HannesTschofenig 0:796d0f61a05b 212 != 0 )
HannesTschofenig 0:796d0f61a05b 213 return( ret );
HannesTschofenig 0:796d0f61a05b 214
HannesTschofenig 0:796d0f61a05b 215 return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
HannesTschofenig 0:796d0f61a05b 216 olen, buf, blen );
HannesTschofenig 0:796d0f61a05b 217 }
HannesTschofenig 0:796d0f61a05b 218
HannesTschofenig 0:796d0f61a05b 219 /*
HannesTschofenig 0:796d0f61a05b 220 * Parse and import the client's public value
HannesTschofenig 0:796d0f61a05b 221 */
HannesTschofenig 0:796d0f61a05b 222 int ecdh_read_public( ecdh_context *ctx,
HannesTschofenig 0:796d0f61a05b 223 const unsigned char *buf, size_t blen )
HannesTschofenig 0:796d0f61a05b 224 {
HannesTschofenig 0:796d0f61a05b 225 int ret;
HannesTschofenig 0:796d0f61a05b 226 const unsigned char *p = buf;
HannesTschofenig 0:796d0f61a05b 227
HannesTschofenig 0:796d0f61a05b 228 if( ctx == NULL )
HannesTschofenig 0:796d0f61a05b 229 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 230
HannesTschofenig 0:796d0f61a05b 231 if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 232 return( ret );
HannesTschofenig 0:796d0f61a05b 233
HannesTschofenig 0:796d0f61a05b 234 if( (size_t)( p - buf ) != blen )
HannesTschofenig 0:796d0f61a05b 235 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 236
HannesTschofenig 0:796d0f61a05b 237 return( 0 );
HannesTschofenig 0:796d0f61a05b 238 }
HannesTschofenig 0:796d0f61a05b 239
HannesTschofenig 0:796d0f61a05b 240 /*
HannesTschofenig 0:796d0f61a05b 241 * Derive and export the shared secret
HannesTschofenig 0:796d0f61a05b 242 */
HannesTschofenig 0:796d0f61a05b 243 int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
HannesTschofenig 0:796d0f61a05b 244 unsigned char *buf, size_t blen,
HannesTschofenig 0:796d0f61a05b 245 int (*f_rng)(void *, unsigned char *, size_t),
HannesTschofenig 0:796d0f61a05b 246 void *p_rng )
HannesTschofenig 0:796d0f61a05b 247 {
HannesTschofenig 0:796d0f61a05b 248 int ret;
HannesTschofenig 0:796d0f61a05b 249
HannesTschofenig 0:796d0f61a05b 250 if( ctx == NULL )
HannesTschofenig 0:796d0f61a05b 251 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 252
HannesTschofenig 0:796d0f61a05b 253 if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
HannesTschofenig 0:796d0f61a05b 254 f_rng, p_rng ) ) != 0 )
HannesTschofenig 0:796d0f61a05b 255 {
HannesTschofenig 0:796d0f61a05b 256 return( ret );
HannesTschofenig 0:796d0f61a05b 257 }
HannesTschofenig 0:796d0f61a05b 258
HannesTschofenig 0:796d0f61a05b 259 if( mpi_size( &ctx->z ) > blen )
HannesTschofenig 0:796d0f61a05b 260 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 261
HannesTschofenig 0:796d0f61a05b 262 *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
HannesTschofenig 0:796d0f61a05b 263 return mpi_write_binary( &ctx->z, buf, *olen );
HannesTschofenig 0:796d0f61a05b 264 }
HannesTschofenig 0:796d0f61a05b 265
HannesTschofenig 0:796d0f61a05b 266
HannesTschofenig 0:796d0f61a05b 267 #if defined(POLARSSL_SELF_TEST)
HannesTschofenig 0:796d0f61a05b 268
HannesTschofenig 0:796d0f61a05b 269 /*
HannesTschofenig 0:796d0f61a05b 270 * Checkup routine
HannesTschofenig 0:796d0f61a05b 271 */
HannesTschofenig 0:796d0f61a05b 272 int ecdh_self_test( int verbose )
HannesTschofenig 0:796d0f61a05b 273 {
HannesTschofenig 0:796d0f61a05b 274 ((void) verbose );
HannesTschofenig 0:796d0f61a05b 275 return( 0 );
HannesTschofenig 0:796d0f61a05b 276 }
HannesTschofenig 0:796d0f61a05b 277
HannesTschofenig 0:796d0f61a05b 278 #endif /* POLARSSL_SELF_TEST */
HannesTschofenig 0:796d0f61a05b 279
HannesTschofenig 0:796d0f61a05b 280 #endif /* POLARSSL_ECDH_C */
HannesTschofenig 0:796d0f61a05b 281
HannesTschofenig 0:796d0f61a05b 282