blob: ac3bdeee9c63a95ce934a48181bbbcb25a804098 [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/*
36 * Uncomment to force use of a specific curve
37#define ECPARAMS POLARSSL_ECP_DP_SECP256R1
38 */
39
40#if !defined(ECPARAMS)
Manuel Pégourié-Gonnardda179e42013-09-18 15:31:24 +020041#define ECPARAMS ecp_curve_list()->grp_id
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020042#endif
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020043
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +020044#if !defined(POLARSSL_ECDSA_C) || \
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +020045 !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C)
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020046int main( int argc, char *argv[] )
47{
48 ((void) argc);
49 ((void) argv);
50
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +020051 printf("POLARSSL_ECDSA_C and/or "
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +020052 "POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C not defined\n"
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +020053 return( 0 );
54}
55#else
56int main( int argc, char *argv[] )
57{
58 int ret;
59 ecdsa_context ctx_sign, ctx_verify;
60 entropy_context entropy;
61 ctr_drbg_context ctr_drbg;
62 unsigned char hash[] = "This should be the hash of a message.";
63 unsigned char sig[512];
64 size_t sig_len;
65 const char *pers = "ecdsa";
66 ((void) argv);
67
68 ecdsa_init( &ctx_sign );
69 ecdsa_init( &ctx_verify );
70
71 memset(sig, 0, sizeof( sig ) );
72 ret = 1;
73
74 if( argc != 1 )
75 {
76 printf( "usage: ecdsa\n" );
77
78#if defined(_WIN32)
79 printf( "\n" );
80#endif
81
82 goto exit;
83 }
84
85 /*
86 * Generate a key pair for signing
87 */
88 printf( "\n . Seeding the random number generator..." );
89 fflush( stdout );
90
91 entropy_init( &entropy );
92 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
93 (const unsigned char *) pers,
94 strlen( pers ) ) ) != 0 )
95 {
96 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
97 goto exit;
98 }
99
100 printf( " ok\n . Generating key pair..." );
101 fflush( stdout );
102
103 if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS,
104 ctr_drbg_random, &ctr_drbg ) ) != 0 )
105 {
106 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
107 goto exit;
108 }
109
110 printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits );
111
112 /*
113 * Sign some message hash
114 */
115 printf( " . Signing message..." );
116 fflush( stdout );
117
118 if( ( ret = ecdsa_write_signature( &ctx_sign,
119 hash, sizeof( hash ),
120 sig, &sig_len,
121 ctr_drbg_random, &ctr_drbg ) ) != 0 )
122 {
123 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
124 goto exit;
125 }
Manuel Pégourié-Gonnard4cf06862013-09-16 12:07:45 +0200126 printf( " ok (signature length = %zu)\n", sig_len );
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200127
128 /*
129 * Signature is serialized as defined by RFC 4492 p. 20,
130 * but one can also access 'r' and 's' directly from the context
131 */
132#ifdef POLARSSL_FS_IO
133 mpi_write_file( " r = ", &ctx_sign.r, 16, NULL );
134 mpi_write_file( " s = ", &ctx_sign.s, 16, NULL );
135#endif
136
137 /*
138 * Transfer public information to verifying context
139 */
140 printf( " . Preparing verification context..." );
141 fflush( stdout );
142
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200143 if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 )
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200144 {
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200145 printf( " failed\n ! ecp_group_copy returned %d\n", ret );
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200146 goto exit;
147 }
148
149 if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 )
150 {
151 printf( " failed\n ! ecp_copy returned %d\n", ret );
152 goto exit;
153 }
154
155 ret = 0;
156
157 /*
158 * Verify signature
159 */
160 printf( " ok\n . Verifying signature..." );
161 fflush( stdout );
162
163 if( ( ret = ecdsa_read_signature( &ctx_verify,
164 hash, sizeof( hash ),
165 sig, sig_len ) ) != 0 )
166 {
167 printf( " failed\n ! ecdsa_read_signature returned %d\n", ret );
168 goto exit;
169 }
170
171 printf( " ok\n" );
172
173exit:
174
175#if defined(_WIN32)
176 printf( " + Press Enter to exit this program.\n" );
177 fflush( stdout ); getchar();
178#endif
179
Manuel Pégourié-Gonnardbf3109f2013-08-14 21:36:01 +0200180 ecdsa_free( &ctx_verify );
181 ecdsa_free( &ctx_sign );
182
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200183 return( ret );
184}
Manuel Pégourié-Gonnardee731792013-09-11 22:48:40 +0200185#endif /* POLARSSL_ECDSA_C && POLARSSL_ENTROPY_C && POLARSSL_CTR_DRBG_C &&
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200186 ECPARAMS */