blob: 8d52b6726b1c66aa8fb09a43d6075b7bf737f403 [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)
41#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
42#define ECPARAMS POLARSSL_ECP_DP_SECP192R1
43#elif defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
44#define ECPARAMS POLARSSL_ECP_DP_SECP224R1
45#elif defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
46#define ECPARAMS POLARSSL_ECP_DP_SECP256R1
47#elif defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
48#define ECPARAMS POLARSSL_ECP_DP_SECP384R1
49#elif defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
50#define ECPARAMS POLARSSL_ECP_DP_SECP521R1
51#endif
52#endif /* !defined(ECPARAMS) */
53
54#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_ECDSA_C) || \
55 !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_CTR_DRBG_C) || \
56 !defined(ECPARAMS)
57int main( int argc, char *argv[] )
58{
59 ((void) argc);
60 ((void) argv);
61
62 printf("POLARSSL_BIGNUM_C and/or POLARSSL_ECDSA_C and/or "
63 "POLARSSL_ENTROPY_C and/or POLARSSL_CTR_DRBG_C not defined,"
64 "and/or not EC domain parameter available\n" );
65 return( 0 );
66}
67#else
68int main( int argc, char *argv[] )
69{
70 int ret;
71 ecdsa_context ctx_sign, ctx_verify;
72 entropy_context entropy;
73 ctr_drbg_context ctr_drbg;
74 unsigned char hash[] = "This should be the hash of a message.";
75 unsigned char sig[512];
76 size_t sig_len;
77 const char *pers = "ecdsa";
78 ((void) argv);
79
80 ecdsa_init( &ctx_sign );
81 ecdsa_init( &ctx_verify );
82
83 memset(sig, 0, sizeof( sig ) );
84 ret = 1;
85
86 if( argc != 1 )
87 {
88 printf( "usage: ecdsa\n" );
89
90#if defined(_WIN32)
91 printf( "\n" );
92#endif
93
94 goto exit;
95 }
96
97 /*
98 * Generate a key pair for signing
99 */
100 printf( "\n . Seeding the random number generator..." );
101 fflush( stdout );
102
103 entropy_init( &entropy );
104 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
105 (const unsigned char *) pers,
106 strlen( pers ) ) ) != 0 )
107 {
108 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
109 goto exit;
110 }
111
112 printf( " ok\n . Generating key pair..." );
113 fflush( stdout );
114
115 if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS,
116 ctr_drbg_random, &ctr_drbg ) ) != 0 )
117 {
118 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
119 goto exit;
120 }
121
122 printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits );
123
124 /*
125 * Sign some message hash
126 */
127 printf( " . Signing message..." );
128 fflush( stdout );
129
130 if( ( ret = ecdsa_write_signature( &ctx_sign,
131 hash, sizeof( hash ),
132 sig, &sig_len,
133 ctr_drbg_random, &ctr_drbg ) ) != 0 )
134 {
135 printf( " failed\n ! ecdsa_genkey returned %d\n", ret );
136 goto exit;
137 }
138 printf( " ok\n" );
139
140 /*
141 * Signature is serialized as defined by RFC 4492 p. 20,
142 * but one can also access 'r' and 's' directly from the context
143 */
144#ifdef POLARSSL_FS_IO
145 mpi_write_file( " r = ", &ctx_sign.r, 16, NULL );
146 mpi_write_file( " s = ", &ctx_sign.s, 16, NULL );
147#endif
148
149 /*
150 * Transfer public information to verifying context
151 */
152 printf( " . Preparing verification context..." );
153 fflush( stdout );
154
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200155 if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 )
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200156 {
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200157 printf( " failed\n ! ecp_group_copy returned %d\n", ret );
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200158 goto exit;
159 }
160
161 if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 )
162 {
163 printf( " failed\n ! ecp_copy returned %d\n", ret );
164 goto exit;
165 }
166
167 ret = 0;
168
169 /*
170 * Verify signature
171 */
172 printf( " ok\n . Verifying signature..." );
173 fflush( stdout );
174
175 if( ( ret = ecdsa_read_signature( &ctx_verify,
176 hash, sizeof( hash ),
177 sig, sig_len ) ) != 0 )
178 {
179 printf( " failed\n ! ecdsa_read_signature returned %d\n", ret );
180 goto exit;
181 }
182
183 printf( " ok\n" );
184
185exit:
186
187#if defined(_WIN32)
188 printf( " + Press Enter to exit this program.\n" );
189 fflush( stdout ); getchar();
190#endif
191
Manuel Pégourié-Gonnardbf3109f2013-08-14 21:36:01 +0200192 ecdsa_free( &ctx_verify );
193 ecdsa_free( &ctx_sign );
194
Manuel Pégourié-Gonnardaa431612013-08-09 17:10:27 +0200195 return( ret );
196}
197#endif /* POLARSSL_BIGNUM_C && POLARSSL_ECDSA_C &&
198 POLARSSL_ENTROPY_C && POLARSSL_CTR_DRBG_C &&
199 ECPARAMS */