blob: 948066a106de35b167547a1a404b9d617a80027a [file] [log] [blame]
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +02001/*
2 * Example ECDSA program
3 *
4 * Copyright (C) 2013, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include "polarssl/config.h"
27
28#include "polarssl/entropy.h"
29#include "polarssl/ctr_drbg.h"
30#include "polarssl/ecdsa.h"
31
32#include <string.h>
33#include <stdio.h>
34
35/*
Manuel Pégourié-Gonnardb0a467f2013-09-21 12:31:05 +020036 * Uncomment to show key and signature details
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020037 */
Manuel Pégourié-Gonnardb0a467f2013-09-21 12:31:05 +020038#define VERBOSE
39
40/*
41 * Uncomment to force use of a specific curve
42 */
43#define ECPARAMS POLARSSL_ECP_DP_SECP192R1
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020044
45#if !defined(ECPARAMS)
Manuel Pégourié-Gonnardda179e42013-09-18 15:31:24 +020046#define ECPARAMS ecp_curve_list()->grp_id
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020047#endif
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020048
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +020049#if !defined(POLARSSL_ECDSA_C) || \
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +020050 !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C)
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020051int main( int argc, char *argv[] )
52{
53 ((void) argc);
54 ((void) argv);
55
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +020056 printf("POLARSSL_ECDSA_C and/or "
Manuel Pégourié-Gonnarda7496f02013-09-20 11:29:59 +020057 "POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C not defined\n");
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020058 return( 0 );
59}
60#else
Manuel Pégourié-Gonnardb0a467f2013-09-21 12:31:05 +020061
62#if defined(VERBOSE)
63static void dump_buf( char *title, unsigned char *buf, size_t len )
64{
65 size_t i;
66
67 printf( "%s", title );
68 for( i = 0; i < len; i++ )
69 printf("%c%c", "0123456789ABCDEF" [buf[i] / 16],
70 "0123456789ABCDEF" [buf[i] % 16] );
71 printf( "\n" );
72}
73
74static void dump_pubkey( char *title, ecdsa_context *key )
75{
76 unsigned char buf[300];
77 size_t len;
78
79 if( ecp_point_write_binary( &key->grp, &key->Q,
80 POLARSSL_ECP_PF_UNCOMPRESSED, &len, buf, sizeof buf ) != 0 )
81 {
82 printf("internal error\n");
83 return;
84 }
85
86 dump_buf( title, buf, len );
87}
88#else
89#define dump_buf( a, b, c )
90#define dump_pubkey( a, b )
91#endif
92
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020093int main( int argc, char *argv[] )
94{
95 int ret;
96 ecdsa_context ctx_sign, ctx_verify;
97 entropy_context entropy;
98 ctr_drbg_context ctr_drbg;
99 unsigned char hash[] = "This should be the hash of a message.";
100 unsigned char sig[512];
101 size_t sig_len;
102 const char *pers = "ecdsa";
103 ((void) argv);
104
105 ecdsa_init( &ctx_sign );
106 ecdsa_init( &ctx_verify );
107
108 memset(sig, 0, sizeof( sig ) );
109 ret = 1;
110
111 if( argc != 1 )
112 {
113 printf( "usage: ecdsa\n" );
114
115#if defined(_WIN32)
116 printf( "\n" );
117#endif
118
119 goto exit;
120 }
121
122 /*
123 * Generate a key pair for signing
124 */
125 printf( "\n . Seeding the random number generator..." );
126 fflush( stdout );
127
128 entropy_init( &entropy );
129 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
130 (const unsigned char *) pers,
131 strlen( pers ) ) ) != 0 )
132 {
133 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
134 goto exit;
135 }
136
137 printf( " ok\n . Generating key pair..." );
138 fflush( stdout );
139
140 if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS,
141 ctr_drbg_random, &ctr_drbg ) ) != 0 )
142 {
143 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
144 goto exit;
145 }
146
147 printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits );
148
Manuel Pégourié-Gonnardb0a467f2013-09-21 12:31:05 +0200149 dump_pubkey( " + Public key: ", &ctx_sign );
150
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200151 /*
152 * Sign some message hash
153 */
154 printf( " . Signing message..." );
155 fflush( stdout );
156
157 if( ( ret = ecdsa_write_signature( &ctx_sign,
158 hash, sizeof( hash ),
159 sig, &sig_len,
160 ctr_drbg_random, &ctr_drbg ) ) != 0 )
161 {
162 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
163 goto exit;
164 }
Manuel Pégourié-Gonnard4cf06862013-09-16 12:07:45 +0200165 printf( " ok (signature length = %zu)\n", sig_len );
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200166
Manuel Pégourié-Gonnardb0a467f2013-09-21 12:31:05 +0200167 dump_buf( " + Hash: ", hash, sizeof hash );
168 dump_buf( " + Signature: ", sig, sig_len );
169
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200170 /*
171 * Signature is serialized as defined by RFC 4492 p. 20,
172 * but one can also access 'r' and 's' directly from the context
173 */
174#ifdef POLARSSL_FS_IO
175 mpi_write_file( " r = ", &ctx_sign.r, 16, NULL );
176 mpi_write_file( " s = ", &ctx_sign.s, 16, NULL );
177#endif
178
179 /*
180 * Transfer public information to verifying context
181 */
182 printf( " . Preparing verification context..." );
183 fflush( stdout );
184
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200185 if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 )
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200186 {
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200187 printf( " failed\n ! ecp_group_copy returned %d\n", ret );
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200188 goto exit;
189 }
190
191 if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 )
192 {
193 printf( " failed\n ! ecp_copy returned %d\n", ret );
194 goto exit;
195 }
196
197 ret = 0;
198
199 /*
200 * Verify signature
201 */
202 printf( " ok\n . Verifying signature..." );
203 fflush( stdout );
204
205 if( ( ret = ecdsa_read_signature( &ctx_verify,
206 hash, sizeof( hash ),
207 sig, sig_len ) ) != 0 )
208 {
209 printf( " failed\n ! ecdsa_read_signature returned %d\n", ret );
210 goto exit;
211 }
212
213 printf( " ok\n" );
214
215exit:
216
217#if defined(_WIN32)
218 printf( " + Press Enter to exit this program.\n" );
219 fflush( stdout ); getchar();
220#endif
221
Manuel Pégourié-Gonnardbf3109f2013-08-14 21:36:01 +0200222 ecdsa_free( &ctx_verify );
223 ecdsa_free( &ctx_sign );
Paul Bakker1ffefac2013-09-28 15:23:03 +0200224 entropy_free( &entropy );
Manuel Pégourié-Gonnardbf3109f2013-08-14 21:36:01 +0200225
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200226 return( ret );
227}
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +0200228#endif /* POLARSSL_ECDSA_C && POLARSSL_ENTROPY_C && POLARSSL_CTR_DRBG_C &&
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200229 ECPARAMS */