blob: fef9ab6914b54f1d0c709611b492d4dc708bf913 [file] [log] [blame]
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +01001/*
2 * Elliptic curves over GF(p)
3 *
Paul Bakkercf4365f2013-01-16 17:00:43 +01004 * Copyright (C) 2006-2013, Brainspark B.V.
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +01005 *
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/*
27 * References:
28 *
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +010029 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +010030 * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +010031 * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +010032 * RFC 4492 for the related TLS structures and constants
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +020033 *
34 * [1] OKEYA, Katsuyuki and TAKAGI, Tsuyoshi. The width-w NAF method provides
35 * small memory and fast elliptic scalar multiplications secure against
36 * side channel attacks. In : Topics in Cryptology—CT-RSA 2003. Springer
37 * Berlin Heidelberg, 2003. p. 328-343.
38 * <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
39 *
40 * [2] CORON, Jean-Sébastien. Resistance against differential power analysis
41 * for elliptic curve cryptosystems. In : Cryptographic Hardware and
42 * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
43 * <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +010044 */
45
46#include "polarssl/config.h"
47
48#if defined(POLARSSL_ECP_C)
49
50#include "polarssl/ecp.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020051
52#if defined(POLARSSL_MEMORY_C)
53#include "polarssl/memory.h"
54#else
55#define polarssl_malloc malloc
56#define polarssl_free free
57#endif
58
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +010059#include <limits.h>
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +010060#include <stdlib.h>
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +010061
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +010062#if defined(POLARSSL_SELF_TEST)
63/*
64 * Counts of point addition and doubling operations.
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +020065 * Used to test resistance of point multiplication to simple timing attacks.
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +010066 */
67unsigned long add_count, dbl_count;
68#endif
69
Manuel Pégourié-Gonnard1e8c8ec2012-10-31 19:24:21 +010070/*
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +020071 * List of supported curves:
72 * - internal ID
73 * - TLS NamedCurve number (RFC 4492 section 5.1.1)
74 * - size in bits
75 */
76ecp_curve_info ecp_supported_curves[] =
77{
78#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
79 { POLARSSL_ECP_DP_SECP521R1, 25, 521, },
80#endif
81#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
82 { POLARSSL_ECP_DP_SECP384R1, 24, 384, },
83#endif
84#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
85 { POLARSSL_ECP_DP_SECP256R1, 23, 256, },
86#endif
87#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
88 { POLARSSL_ECP_DP_SECP224R1, 21, 224, },
89#endif
90#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
91 { POLARSSL_ECP_DP_SECP192R1, 19, 192, },
92#endif
93 { POLARSSL_ECP_DP_NONE, 0, 0 },
94};
95
96/*
Manuel Pégourié-Gonnardb505c272012-11-05 17:27:54 +010097 * Initialize (the components of) a point
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +010098 */
99void ecp_point_init( ecp_point *pt )
100{
101 if( pt == NULL )
102 return;
103
Manuel Pégourié-Gonnardb505c272012-11-05 17:27:54 +0100104 mpi_init( &pt->X );
105 mpi_init( &pt->Y );
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100106 mpi_init( &pt->Z );
Manuel Pégourié-Gonnardb505c272012-11-05 17:27:54 +0100107}
108
109/*
110 * Initialize (the components of) a group
111 */
112void ecp_group_init( ecp_group *grp )
113{
114 if( grp == NULL )
115 return;
116
Manuel Pégourié-Gonnard46106a92013-02-10 12:51:17 +0100117 grp->id = 0;
118
Manuel Pégourié-Gonnardb505c272012-11-05 17:27:54 +0100119 mpi_init( &grp->P );
120 mpi_init( &grp->B );
121 ecp_point_init( &grp->G );
122 mpi_init( &grp->N );
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100123
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100124 grp->pbits = 0;
Manuel Pégourié-Gonnard773ed542012-11-18 13:19:07 +0100125 grp->nbits = 0;
126
127 grp->modp = NULL;
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100128}
129
130/*
Manuel Pégourié-Gonnardb8c6e0e2013-07-01 13:40:52 +0200131 * Initialize (the components of) a key pair
132 */
133void ecp_keypair_init( ecp_keypair *key )
134{
135 if ( key == NULL )
136 return;
137
138 ecp_group_init( &key->grp );
139 mpi_init( &key->d );
140 ecp_point_init( &key->Q );
Manuel Pégourié-Gonnardb8c6e0e2013-07-01 13:40:52 +0200141}
142
143/*
Manuel Pégourié-Gonnard1e8c8ec2012-10-31 19:24:21 +0100144 * Unallocate (the components of) a point
145 */
146void ecp_point_free( ecp_point *pt )
147{
148 if( pt == NULL )
149 return;
150
151 mpi_free( &( pt->X ) );
152 mpi_free( &( pt->Y ) );
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100153 mpi_free( &( pt->Z ) );
Manuel Pégourié-Gonnard1e8c8ec2012-10-31 19:24:21 +0100154}
155
156/*
157 * Unallocate (the components of) a group
158 */
159void ecp_group_free( ecp_group *grp )
160{
161 if( grp == NULL )
162 return;
163
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100164 mpi_free( &grp->P );
165 mpi_free( &grp->B );
166 ecp_point_free( &grp->G );
167 mpi_free( &grp->N );
Manuel Pégourié-Gonnard1e8c8ec2012-10-31 19:24:21 +0100168}
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +0100169
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100170/*
Manuel Pégourié-Gonnardb8c6e0e2013-07-01 13:40:52 +0200171 * Unallocate (the components of) a key pair
172 */
173void ecp_keypair_free( ecp_keypair *key )
174{
175 if ( key == NULL )
176 return;
177
178 ecp_group_free( &key->grp );
179 mpi_free( &key->d );
180 ecp_point_free( &key->Q );
Manuel Pégourié-Gonnardb8c6e0e2013-07-01 13:40:52 +0200181}
182
183/*
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100184 * Set point to zero
185 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100186int ecp_set_zero( ecp_point *pt )
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100187{
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100188 int ret;
189
190 MPI_CHK( mpi_lset( &pt->X , 1 ) );
191 MPI_CHK( mpi_lset( &pt->Y , 1 ) );
192 MPI_CHK( mpi_lset( &pt->Z , 0 ) );
193
194cleanup:
195 return( ret );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100196}
197
198/*
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100199 * Tell if a point is zero
200 */
201int ecp_is_zero( ecp_point *pt )
202{
203 return( mpi_cmp_int( &pt->Z, 0 ) == 0 );
204}
205
206/*
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100207 * Copy the contents of Q into P
208 */
209int ecp_copy( ecp_point *P, const ecp_point *Q )
210{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100211 int ret;
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100212
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100213 MPI_CHK( mpi_copy( &P->X, &Q->X ) );
214 MPI_CHK( mpi_copy( &P->Y, &Q->Y ) );
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100215 MPI_CHK( mpi_copy( &P->Z, &Q->Z ) );
Manuel Pégourié-Gonnard883f3132012-11-02 09:40:25 +0100216
217cleanup:
218 return( ret );
219}
Manuel Pégourié-Gonnard5179e462012-10-31 19:37:54 +0100220
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100221/*
Manuel Pégourié-Gonnarde09631b2013-08-12 15:44:31 +0200222 * Copy the contents of a group object
223 */
224int ecp_group_copy( ecp_group *dst, const ecp_group *src )
225{
226 return ecp_use_known_dp( dst, src->id );
227}
228
229/*
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100230 * Import a non-zero point from ASCII strings
231 */
232int ecp_point_read_string( ecp_point *P, int radix,
233 const char *x, const char *y )
234{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100235 int ret;
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100236
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100237 MPI_CHK( mpi_read_string( &P->X, radix, x ) );
238 MPI_CHK( mpi_read_string( &P->Y, radix, y ) );
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100239 MPI_CHK( mpi_lset( &P->Z, 1 ) );
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100240
241cleanup:
242 return( ret );
243}
244
245/*
246 * Import an ECP group from ASCII strings
247 */
248int ecp_group_read_string( ecp_group *grp, int radix,
249 const char *p, const char *b,
250 const char *gx, const char *gy, const char *n)
251{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100252 int ret;
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100253
254 MPI_CHK( mpi_read_string( &grp->P, radix, p ) );
255 MPI_CHK( mpi_read_string( &grp->B, radix, b ) );
256 MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) );
257 MPI_CHK( mpi_read_string( &grp->N, radix, n ) );
258
Manuel Pégourié-Gonnard773ed542012-11-18 13:19:07 +0100259 grp->pbits = mpi_msb( &grp->P );
260 grp->nbits = mpi_msb( &grp->N );
261
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100262cleanup:
263 return( ret );
264}
265
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100266/*
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100267 * Export a point into unsigned binary data (SEC1 2.3.3)
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100268 */
Manuel Pégourié-Gonnard7e860252013-02-10 10:58:48 +0100269int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100270 int format, size_t *olen,
Manuel Pégourié-Gonnard7e860252013-02-10 10:58:48 +0100271 unsigned char *buf, size_t buflen )
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100272{
Paul Bakkera280d0f2013-04-08 13:40:17 +0200273 int ret = 0;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100274 size_t plen;
275
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100276 if( format != POLARSSL_ECP_PF_UNCOMPRESSED &&
277 format != POLARSSL_ECP_PF_COMPRESSED )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100278 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100279
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100280 /*
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100281 * Common case: P == 0
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100282 */
283 if( mpi_cmp_int( &P->Z, 0 ) == 0 )
284 {
285 if( buflen < 1 )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100286 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100287
288 buf[0] = 0x00;
289 *olen = 1;
290
291 return( 0 );
292 }
293
294 plen = mpi_size( &grp->P );
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100295
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100296 if( format == POLARSSL_ECP_PF_UNCOMPRESSED )
297 {
298 *olen = 2 * plen + 1;
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100299
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100300 if( buflen < *olen )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100301 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100302
303 buf[0] = 0x04;
304 MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
305 MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
306 }
307 else if( format == POLARSSL_ECP_PF_COMPRESSED )
308 {
309 *olen = plen + 1;
310
311 if( buflen < *olen )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100312 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
Manuel Pégourié-Gonnard37d218a2012-11-24 15:19:55 +0100313
314 buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 );
315 MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) );
316 }
Manuel Pégourié-Gonnarde19feb52012-11-24 14:10:14 +0100317
318cleanup:
319 return( ret );
320}
321
322/*
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100323 * Import a point from unsigned binary data (SEC1 2.3.4)
324 */
Manuel Pégourié-Gonnard7e860252013-02-10 10:58:48 +0100325int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt,
326 const unsigned char *buf, size_t ilen ) {
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100327 int ret;
328 size_t plen;
329
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100330 if( ilen == 1 && buf[0] == 0x00 )
Manuel Pégourié-Gonnardd84895d2013-02-10 10:53:04 +0100331 return( ecp_set_zero( pt ) );
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100332
Manuel Pégourié-Gonnardd84895d2013-02-10 10:53:04 +0100333 plen = mpi_size( &grp->P );
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100334
335 if( ilen != 2 * plen + 1 || buf[0] != 0x04 )
Manuel Pégourié-Gonnardd84895d2013-02-10 10:53:04 +0100336 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100337
Manuel Pégourié-Gonnardd84895d2013-02-10 10:53:04 +0100338 MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) );
339 MPI_CHK( mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
340 MPI_CHK( mpi_lset( &pt->Z, 1 ) );
Manuel Pégourié-Gonnard5e402d82012-11-24 16:19:42 +0100341
342cleanup:
343 return( ret );
344}
345
346/*
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100347 * Import a point from a TLS ECPoint record (RFC 4492)
348 * struct {
349 * opaque point <1..2^8-1>;
350 * } ECPoint;
351 */
352int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100353 const unsigned char **buf, size_t buf_len )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100354{
355 unsigned char data_len;
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100356 const unsigned char *buf_start;
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100357
358 /*
359 * We must have at least two bytes (1 for length, at least of for data)
360 */
361 if( buf_len < 2 )
362 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
363
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100364 data_len = *(*buf)++;
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100365 if( data_len < 1 || data_len > buf_len - 1 )
366 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
367
Manuel Pégourié-Gonnard98f51812013-02-10 13:38:29 +0100368 /*
369 * Save buffer start for read_binary and update buf
370 */
371 buf_start = *buf;
372 *buf += data_len;
373
374 return ecp_point_read_binary( grp, pt, buf_start, data_len );
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100375}
376
377/*
378 * Export a point as a TLS ECPoint record (RFC 4492)
379 * struct {
380 * opaque point <1..2^8-1>;
381 * } ECPoint;
382 */
383int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100384 int format, size_t *olen,
385 unsigned char *buf, size_t blen )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100386{
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100387 int ret;
388
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100389 /*
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100390 * buffer length must be at least one, for our length byte
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100391 */
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100392 if( blen < 1 )
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100393 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
394
Manuel Pégourié-Gonnard420f1eb2013-02-10 12:22:46 +0100395 if( ( ret = ecp_point_write_binary( grp, pt, format,
396 olen, buf + 1, blen - 1) ) != 0 )
397 return( ret );
398
399 /*
400 * write length to the first byte and update total length
401 */
402 buf[0] = *olen;
403 ++*olen;
404
405 return 0;
Manuel Pégourié-Gonnard00794052013-02-09 19:00:07 +0100406}
407
408/*
Manuel Pégourié-Gonnard773ed542012-11-18 13:19:07 +0100409 * Wrapper around fast quasi-modp functions, with fall-back to mpi_mod_mpi.
410 * See the documentation of struct ecp_group.
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100411 */
412static int ecp_modp( mpi *N, const ecp_group *grp )
413{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100414 int ret;
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100415
416 if( grp->modp == NULL )
417 return( mpi_mod_mpi( N, N, &grp->P ) );
418
419 if( mpi_cmp_int( N, 0 ) < 0 || mpi_msb( N ) > 2 * grp->pbits )
420 return( POLARSSL_ERR_ECP_GENERIC );
421
422 MPI_CHK( grp->modp( N ) );
423
424 while( mpi_cmp_int( N, 0 ) < 0 )
425 MPI_CHK( mpi_add_mpi( N, N, &grp->P ) );
426
427 while( mpi_cmp_mpi( N, &grp->P ) >= 0 )
428 MPI_CHK( mpi_sub_mpi( N, N, &grp->P ) );
429
430cleanup:
431 return( ret );
432}
433
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200434#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100435/*
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100436 * 192 bits in terms of t_uint
437 */
438#define P192_SIZE_INT ( 192 / CHAR_BIT / sizeof( t_uint ) )
439
440/*
441 * Table to get S1, S2, S3 of FIPS 186-3 D.2.1:
442 * -1 means let this chunk be 0
443 * a positive value i means A_i.
444 */
445#define P192_CHUNKS 3
446#define P192_CHUNK_CHAR ( 64 / CHAR_BIT )
447#define P192_CHUNK_INT ( P192_CHUNK_CHAR / sizeof( t_uint ) )
448
449const signed char p192_tbl[][P192_CHUNKS] = {
450 { -1, 3, 3 }, /* S1 */
451 { 4, 4, -1 }, /* S2 */
452 { 5, 5, 5 }, /* S3 */
453};
454
455/*
456 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
457 */
458static int ecp_mod_p192( mpi *N )
459{
460 int ret;
461 unsigned char i, j, offset;
462 signed char chunk;
463 mpi tmp, acc;
464 t_uint tmp_p[P192_SIZE_INT], acc_p[P192_SIZE_INT + 1];
465
466 tmp.s = 1;
467 tmp.n = sizeof( tmp_p ) / sizeof( tmp_p[0] );
468 tmp.p = tmp_p;
469
470 acc.s = 1;
471 acc.n = sizeof( acc_p ) / sizeof( acc_p[0] );
472 acc.p = acc_p;
473
474 MPI_CHK( mpi_grow( N, P192_SIZE_INT * 2 ) );
475
476 /*
477 * acc = T
478 */
479 memset( acc_p, 0, sizeof( acc_p ) );
480 memcpy( acc_p, N->p, P192_CHUNK_CHAR * P192_CHUNKS );
481
482 for( i = 0; i < sizeof( p192_tbl ) / sizeof( p192_tbl[0] ); i++)
483 {
484 /*
485 * tmp = S_i
486 */
487 memset( tmp_p, 0, sizeof( tmp_p ) );
488 for( j = 0, offset = P192_CHUNKS - 1; j < P192_CHUNKS; j++, offset-- )
489 {
490 chunk = p192_tbl[i][j];
491 if( chunk >= 0 )
492 memcpy( tmp_p + offset * P192_CHUNK_INT,
493 N->p + chunk * P192_CHUNK_INT,
494 P192_CHUNK_CHAR );
495 }
496
497 /*
498 * acc += tmp
499 */
500 MPI_CHK( mpi_add_abs( &acc, &acc, &tmp ) );
501 }
502
503 MPI_CHK( mpi_copy( N, &acc ) );
504
505cleanup:
506 return( ret );
507}
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200508#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100509
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200510#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100511/*
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100512 * Size of p521 in terms of t_uint
513 */
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100514#define P521_SIZE_INT ( 521 / CHAR_BIT / sizeof( t_uint ) + 1 )
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100515
516/*
517 * Bits to keep in the most significant t_uint
518 */
519#if defined(POLARSS_HAVE_INT8)
520#define P521_MASK 0x01
521#else
522#define P521_MASK 0x01FF
523#endif
524
525/*
526 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100527 */
528static int ecp_mod_p521( mpi *N )
529{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100530 int ret;
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100531 t_uint Mp[P521_SIZE_INT];
532 mpi M;
533
534 if( N->n < P521_SIZE_INT )
535 return( 0 );
536
537 memset( Mp, 0, P521_SIZE_INT * sizeof( t_uint ) );
538 memcpy( Mp, N->p, P521_SIZE_INT * sizeof( t_uint ) );
539 Mp[P521_SIZE_INT - 1] &= P521_MASK;
540
541 M.s = 1;
542 M.n = P521_SIZE_INT;
543 M.p = Mp;
544
545 MPI_CHK( mpi_shift_r( N, 521 ) );
546
547 MPI_CHK( mpi_add_abs( N, N, &M ) );
548
549cleanup:
550 return( ret );
551}
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200552#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100553
554/*
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100555 * Domain parameters for secp192r1
556 */
557#define SECP192R1_P \
558 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"
559#define SECP192R1_B \
560 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"
561#define SECP192R1_GX \
562 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
563#define SECP192R1_GY \
564 "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"
565#define SECP192R1_N \
566 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"
567
568/*
569 * Domain parameters for secp224r1
570 */
571#define SECP224R1_P \
572 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"
573#define SECP224R1_B \
574 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"
575#define SECP224R1_GX \
576 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
577#define SECP224R1_GY \
578 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"
579#define SECP224R1_N \
580 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"
581
582/*
583 * Domain parameters for secp256r1
584 */
585#define SECP256R1_P \
586 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"
587#define SECP256R1_B \
588 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"
589#define SECP256R1_GX \
590 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
591#define SECP256R1_GY \
592 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
593#define SECP256R1_N \
594 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"
595
596/*
597 * Domain parameters for secp384r1
598 */
599#define SECP384R1_P \
600 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
601 "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"
602#define SECP384R1_B \
603 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \
604 "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"
605#define SECP384R1_GX \
606 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \
607 "59F741E082542A385502F25DBF55296C3A545E3872760AB7"
608#define SECP384R1_GY \
609 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \
610 "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
611#define SECP384R1_N \
612 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
613 "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"
614
615/*
616 * Domain parameters for secp521r1
617 */
618#define SECP521R1_P \
619 "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
620 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
621 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
622#define SECP521R1_B \
623 "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \
624 "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \
625 "3BB1BF073573DF883D2C34F1EF451FD46B503F00"
626#define SECP521R1_GX \
627 "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \
628 "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \
629 "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
630#define SECP521R1_GY \
631 "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \
632 "579B446817AFBD17273E662C97EE72995EF42640C550B901" \
633 "3FAD0761353C7086A272C24088BE94769FD16650"
634#define SECP521R1_N \
635 "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \
636 "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \
637 "F709A5D03BB5C9B8899C47AEBB6FB71E91386409"
638
639/*
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100640 * Set a group using well-known domain parameters
641 */
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100642int ecp_use_known_dp( ecp_group *grp, ecp_group_id id )
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100643{
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100644 grp->id = id;
645
646 switch( id )
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100647 {
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200648#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100649 case POLARSSL_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard84338242012-11-11 20:45:18 +0100650 grp->modp = ecp_mod_p192;
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100651 return( ecp_group_read_string( grp, 16,
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100652 SECP192R1_P, SECP192R1_B,
653 SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200654#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100655
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200656#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100657 case POLARSSL_ECP_DP_SECP224R1:
658 return( ecp_group_read_string( grp, 16,
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100659 SECP224R1_P, SECP224R1_B,
660 SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200661#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100662
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200663#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100664 case POLARSSL_ECP_DP_SECP256R1:
665 return( ecp_group_read_string( grp, 16,
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100666 SECP256R1_P, SECP256R1_B,
667 SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200668#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100669
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200670#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100671 case POLARSSL_ECP_DP_SECP384R1:
672 return( ecp_group_read_string( grp, 16,
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100673 SECP384R1_P, SECP384R1_B,
674 SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200675#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100676
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200677#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100678 case POLARSSL_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100679 grp->modp = ecp_mod_p521;
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100680 return( ecp_group_read_string( grp, 16,
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100681 SECP521R1_P, SECP521R1_B,
682 SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +0200683#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100684
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200685 default:
686 grp->id = POLARSSL_ECP_DP_NONE;
687 return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE );
688 }
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +0100689}
690
691/*
692 * Set a group from an ECParameters record (RFC 4492)
693 */
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100694int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len )
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +0100695{
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200696 unsigned int named_curve;
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +0100697
698 /*
699 * We expect at least three bytes (see below)
700 */
701 if( len < 3 )
702 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
703
704 /*
705 * First byte is curve_type; only named_curve is handled
706 */
Manuel Pégourié-Gonnard7c145c62013-02-10 13:20:52 +0100707 if( *(*buf)++ != POLARSSL_ECP_TLS_NAMED_CURVE )
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +0100708 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
709
710 /*
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100711 * Next two bytes are the namedcurve value
Manuel Pégourié-Gonnard1a967282013-02-09 17:03:58 +0100712 */
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200713 named_curve = *(*buf)++;
714 named_curve <<= 8;
715 named_curve |= *(*buf)++;
716 return ecp_use_known_dp( grp, ecp_grp_id_from_named_curve( named_curve ) );
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100717}
718
719/*
720 * Write the ECParameters record corresponding to a group (RFC 4492)
721 */
722int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
723 unsigned char *buf, size_t blen )
724{
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200725 unsigned int named_curve;
726
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100727 /*
728 * We are going to write 3 bytes (see below)
729 */
730 *olen = 3;
731 if( blen < *olen )
732 return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL );
733
734 /*
735 * First byte is curve_type, always named_curve
736 */
737 *buf++ = POLARSSL_ECP_TLS_NAMED_CURVE;
738
739 /*
740 * Next two bytes are the namedcurve value
741 */
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200742 named_curve = ecp_named_curve_from_grp_id( grp->id );
743 buf[0] = named_curve >> 8;
744 buf[1] = named_curve & 0xFF;
Manuel Pégourié-Gonnardb3258872013-02-10 12:06:19 +0100745
746 return 0;
Manuel Pégourié-Gonnarda5402fe2012-11-07 20:24:05 +0100747}
Manuel Pégourié-Gonnardab38b702012-11-05 17:34:55 +0100748
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200749/*
750 * Get the internal identifer from the TLS name
751 */
752ecp_group_id ecp_grp_id_from_named_curve( uint16_t name )
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200753{
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200754 ecp_curve_info *curve_info;
755
756 for( curve_info = ecp_supported_curves;
757 curve_info->grp_id != POLARSSL_ECP_DP_NONE;
758 curve_info++ )
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200759 {
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200760 if( curve_info->name == name )
761 return( curve_info->grp_id );
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200762 }
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200763
764 return( POLARSSL_ECP_DP_NONE );
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200765}
766
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200767/*
768 * Get the TLS name for the internal identifer
769 */
770uint16_t ecp_named_curve_from_grp_id( ecp_group_id id )
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200771{
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200772 ecp_curve_info *curve_info;
773
774 for( curve_info = ecp_supported_curves;
775 curve_info->grp_id != POLARSSL_ECP_DP_NONE;
776 curve_info++ )
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200777 {
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200778 if( curve_info->grp_id == id )
779 return( curve_info->name );
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200780 }
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200781
782 return( 0 );
Manuel Pégourié-Gonnard70380392013-09-16 16:19:53 +0200783}
Manuel Pégourié-Gonnard568c9cf2013-09-16 17:30:04 +0200784
Manuel Pégourié-Gonnard847395a2012-11-05 13:13:44 +0100785/*
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100786 * Fast mod-p functions expect their argument to be in the 0..p^2 range.
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100787 *
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100788 * In order to guarantee that, we need to ensure that operands of
789 * mpi_mul_mpi are in the 0..p range. So, after each operation we will
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100790 * bring the result back to this range.
791 *
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100792 * The following macros are shortcuts for doing that.
Manuel Pégourié-Gonnarddada4da2012-11-10 14:23:17 +0100793 */
794
795/*
Manuel Pégourié-Gonnard84d1aea2012-11-09 02:09:38 +0100796 * Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi
797 */
Manuel Pégourié-Gonnard62aad142012-11-10 00:27:12 +0100798#define MOD_MUL( N ) MPI_CHK( ecp_modp( &N, grp ) )
Manuel Pégourié-Gonnard84d1aea2012-11-09 02:09:38 +0100799
800/*
801 * Reduce a mpi mod p in-place, to use after mpi_sub_mpi
802 */
803#define MOD_SUB( N ) \
804 while( mpi_cmp_int( &N, 0 ) < 0 ) \
805 MPI_CHK( mpi_add_mpi( &N, &N, &grp->P ) )
806
807/*
808 * Reduce a mpi mod p in-place, to use after mpi_add_mpi and mpi_mul_int
809 */
810#define MOD_ADD( N ) \
811 while( mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \
812 MPI_CHK( mpi_sub_mpi( &N, &N, &grp->P ) )
813
814/*
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100815 * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1)
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100816 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100817static int ecp_normalize( const ecp_group *grp, ecp_point *pt )
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100818{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100819 int ret;
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100820 mpi Zi, ZZi;
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100821
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100822 if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100823 return( 0 );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100824
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100825 mpi_init( &Zi ); mpi_init( &ZZi );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100826
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100827 /*
828 * X = X / Z^2 mod p
829 */
830 MPI_CHK( mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
831 MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
832 MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100833
834 /*
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100835 * Y = Y / Z^3 mod p
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100836 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100837 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
838 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100839
840 /*
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100841 * Z = 1
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100842 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100843 MPI_CHK( mpi_lset( &pt->Z, 1 ) );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100844
845cleanup:
846
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100847 mpi_free( &Zi ); mpi_free( &ZZi );
Manuel Pégourié-Gonnardd070f512012-11-08 17:40:51 +0100848
849 return( ret );
850}
851
852/*
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100853 * Normalize jacobian coordinates of an array of points,
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +0100854 * using Montgomery's trick to perform only one inversion mod P.
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100855 * (See for example Cohen's "A Course in Computational Algebraic Number
856 * Theory", Algorithm 10.3.4.)
857 *
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +0200858 * Warning: fails (returning an error) if one of the points is zero!
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +0100859 * This should never happen, see choice of w in ecp_mul().
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100860 */
861static int ecp_normalize_many( const ecp_group *grp,
862 ecp_point T[], size_t t_len )
863{
864 int ret;
865 size_t i;
866 mpi *c, u, Zi, ZZi;
867
868 if( t_len < 2 )
869 return( ecp_normalize( grp, T ) );
870
Paul Bakker6e339b52013-07-03 13:37:05 +0200871 if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL )
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100872 return( POLARSSL_ERR_ECP_GENERIC );
873
874 mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi );
875 for( i = 0; i < t_len; i++ )
876 mpi_init( &c[i] );
877
878 /*
879 * c[i] = Z_0 * ... * Z_i
880 */
881 MPI_CHK( mpi_copy( &c[0], &T[0].Z ) );
882 for( i = 1; i < t_len; i++ )
883 {
884 MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i].Z ) );
885 MOD_MUL( c[i] );
886 }
887
888 /*
889 * u = 1 / (Z_0 * ... * Z_n) mod P
890 */
891 MPI_CHK( mpi_inv_mod( &u, &c[t_len-1], &grp->P ) );
892
893 for( i = t_len - 1; ; i-- )
894 {
895 /*
896 * Zi = 1 / Z_i mod p
897 * u = 1 / (Z_0 * ... * Z_i) mod P
898 */
899 if( i == 0 ) {
900 MPI_CHK( mpi_copy( &Zi, &u ) );
901 }
902 else
903 {
904 MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
905 MPI_CHK( mpi_mul_mpi( &u, &u, &T[i].Z ) ); MOD_MUL( u );
906 }
907
908 /*
909 * proceed as in normalize()
910 */
911 MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
912 MPI_CHK( mpi_mul_mpi( &T[i].X, &T[i].X, &ZZi ) ); MOD_MUL( T[i].X );
913 MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &ZZi ) ); MOD_MUL( T[i].Y );
914 MPI_CHK( mpi_mul_mpi( &T[i].Y, &T[i].Y, &Zi ) ); MOD_MUL( T[i].Y );
915 MPI_CHK( mpi_lset( &T[i].Z, 1 ) );
916
917 if( i == 0 )
918 break;
919 }
920
921cleanup:
922
923 mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi );
924 for( i = 0; i < t_len; i++ )
925 mpi_free( &c[i] );
Paul Bakker6e339b52013-07-03 13:37:05 +0200926 polarssl_free( c );
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +0100927
928 return( ret );
929}
930
931
932/*
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100933 * Point doubling R = 2 P, Jacobian coordinates (GECC 3.21)
934 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100935static int ecp_double_jac( const ecp_group *grp, ecp_point *R,
936 const ecp_point *P )
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100937{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100938 int ret;
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100939 mpi T1, T2, T3, X, Y, Z;
940
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +0100941#if defined(POLARSSL_SELF_TEST)
942 dbl_count++;
943#endif
944
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +0100945 if( mpi_cmp_int( &P->Z, 0 ) == 0 )
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +0100946 return( ecp_set_zero( R ) );
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +0100947
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100948 mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 );
949 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
950
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100951 MPI_CHK( mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
952 MPI_CHK( mpi_sub_mpi( &T2, &P->X, &T1 ) ); MOD_SUB( T2 );
953 MPI_CHK( mpi_add_mpi( &T1, &P->X, &T1 ) ); MOD_ADD( T1 );
954 MPI_CHK( mpi_mul_mpi( &T2, &T2, &T1 ) ); MOD_MUL( T2 );
955 MPI_CHK( mpi_mul_int( &T2, &T2, 3 ) ); MOD_ADD( T2 );
956 MPI_CHK( mpi_mul_int( &Y, &P->Y, 2 ) ); MOD_ADD( Y );
957 MPI_CHK( mpi_mul_mpi( &Z, &Y, &P->Z ) ); MOD_MUL( Z );
958 MPI_CHK( mpi_mul_mpi( &Y, &Y, &Y ) ); MOD_MUL( Y );
959 MPI_CHK( mpi_mul_mpi( &T3, &Y, &P->X ) ); MOD_MUL( T3 );
960 MPI_CHK( mpi_mul_mpi( &Y, &Y, &Y ) ); MOD_MUL( Y );
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100961
Manuel Pégourié-Gonnard84d1aea2012-11-09 02:09:38 +0100962 /*
963 * For Y = Y / 2 mod p, we must make sure that Y is even before
964 * using right-shift. No need to reduce mod p afterwards.
965 */
966 if( mpi_get_bit( &Y, 0 ) == 1 )
967 MPI_CHK( mpi_add_mpi( &Y, &Y, &grp->P ) );
968 MPI_CHK( mpi_shift_r( &Y, 1 ) );
969
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +0100970 MPI_CHK( mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
971 MPI_CHK( mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
972 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
973 MPI_CHK( mpi_sub_mpi( &T1, &T3, &X ) ); MOD_SUB( T1 );
974 MPI_CHK( mpi_mul_mpi( &T1, &T1, &T2 ) ); MOD_MUL( T1 );
975 MPI_CHK( mpi_sub_mpi( &Y, &T1, &Y ) ); MOD_SUB( Y );
Manuel Pégourié-Gonnard84d1aea2012-11-09 02:09:38 +0100976
977 MPI_CHK( mpi_copy( &R->X, &X ) );
978 MPI_CHK( mpi_copy( &R->Y, &Y ) );
979 MPI_CHK( mpi_copy( &R->Z, &Z ) );
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +0100980
981cleanup:
982
983 mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 );
984 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
985
986 return( ret );
987}
988
989/*
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +0100990 * Addition or subtraction: R = P + Q or R = P + Q,
991 * mixed affine-Jacobian coordinates (GECC 3.22)
992 *
993 * The coordinates of Q must be normalized (= affine),
994 * but those of P don't need to. R is not normalized.
995 *
996 * If sign >= 0, perform addition, otherwise perform subtraction,
997 * taking advantage of the fact that, for Q != 0, we have
998 * -Q = (Q.X, -Q.Y, Q.Z)
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +0100999 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001000static int ecp_add_mixed( const ecp_group *grp, ecp_point *R,
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +01001001 const ecp_point *P, const ecp_point *Q,
1002 signed char sign )
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001003{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001004 int ret;
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001005 mpi T1, T2, T3, T4, X, Y, Z;
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001006
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001007#if defined(POLARSSL_SELF_TEST)
1008 add_count++;
1009#endif
1010
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001011 /*
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001012 * Trivial cases: P == 0 or Q == 0
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +01001013 * (Check Q first, so that we know Q != 0 when we compute -Q.)
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001014 */
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001015 if( mpi_cmp_int( &Q->Z, 0 ) == 0 )
1016 return( ecp_copy( R, P ) );
1017
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +01001018 if( mpi_cmp_int( &P->Z, 0 ) == 0 )
1019 {
1020 ret = ecp_copy( R, Q );
1021
1022 /*
1023 * -R.Y mod P = P - R.Y unless R.Y == 0
1024 */
1025 if( ret == 0 && sign < 0)
1026 if( mpi_cmp_int( &R->Y, 0 ) != 0 )
1027 ret = mpi_sub_mpi( &R->Y, &grp->P, &R->Y );
1028
1029 return( ret );
1030 }
1031
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001032 /*
1033 * Make sure Q coordinates are normalized
1034 */
1035 if( mpi_cmp_int( &Q->Z, 1 ) != 0 )
1036 return( POLARSSL_ERR_ECP_GENERIC );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001037
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001038 mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 );
1039 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
Manuel Pégourié-Gonnardab38b702012-11-05 17:34:55 +01001040
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001041 MPI_CHK( mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
1042 MPI_CHK( mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
1043 MPI_CHK( mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
1044 MPI_CHK( mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +01001045
1046 /*
1047 * For subtraction, -Q.Y should have been used instead of Q.Y,
1048 * so we replace T2 by -T2, which is P - T2 mod P
1049 */
1050 if( sign < 0 )
1051 {
1052 MPI_CHK( mpi_sub_mpi( &T2, &grp->P, &T2 ) );
1053 MOD_SUB( T2 );
1054 }
1055
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001056 MPI_CHK( mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
1057 MPI_CHK( mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001058
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001059 if( mpi_cmp_int( &T1, 0 ) == 0 )
1060 {
1061 if( mpi_cmp_int( &T2, 0 ) == 0 )
1062 {
1063 ret = ecp_double_jac( grp, R, P );
1064 goto cleanup;
1065 }
1066 else
1067 {
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001068 ret = ecp_set_zero( R );
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001069 goto cleanup;
1070 }
1071 }
1072
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001073 MPI_CHK( mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
1074 MPI_CHK( mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
1075 MPI_CHK( mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
1076 MPI_CHK( mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
1077 MPI_CHK( mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
1078 MPI_CHK( mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
1079 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
1080 MPI_CHK( mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
1081 MPI_CHK( mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
1082 MPI_CHK( mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
1083 MPI_CHK( mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
1084 MPI_CHK( mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001085
Manuel Pégourié-Gonnard84d1aea2012-11-09 02:09:38 +01001086 MPI_CHK( mpi_copy( &R->X, &X ) );
1087 MPI_CHK( mpi_copy( &R->Y, &Y ) );
1088 MPI_CHK( mpi_copy( &R->Z, &Z ) );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001089
1090cleanup:
1091
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001092 mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); mpi_free( &T4 );
1093 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001094
1095 return( ret );
1096}
1097
1098/*
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001099 * Addition: R = P + Q, result's coordinates normalized
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001100 */
1101int ecp_add( const ecp_group *grp, ecp_point *R,
1102 const ecp_point *P, const ecp_point *Q )
1103{
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001104 int ret;
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +01001105
Manuel Pégourié-Gonnard9674fd02012-11-19 21:23:27 +01001106 MPI_CHK( ecp_add_mixed( grp, R, P, Q , 1 ) );
1107 MPI_CHK( ecp_normalize( grp, R ) );
1108
1109cleanup:
1110 return( ret );
1111}
1112
1113/*
1114 * Subtraction: R = P - Q, result's coordinates normalized
1115 */
1116int ecp_sub( const ecp_group *grp, ecp_point *R,
1117 const ecp_point *P, const ecp_point *Q )
1118{
1119 int ret;
1120
1121 MPI_CHK( ecp_add_mixed( grp, R, P, Q, -1 ) );
Manuel Pégourié-Gonnard1c2782c2012-11-19 20:16:28 +01001122 MPI_CHK( ecp_normalize( grp, R ) );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001123
Manuel Pégourié-Gonnard989c32b2012-11-08 22:02:42 +01001124cleanup:
Manuel Pégourié-Gonnard7e0adfb2012-11-08 23:21:46 +01001125 return( ret );
Manuel Pégourié-Gonnardae180d02012-11-02 18:14:40 +01001126}
1127
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001128/*
Manuel Pégourié-Gonnard85556072012-11-17 19:54:20 +01001129 * Compute a modified width-w non-adjacent form (NAF) of a number,
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +02001130 * with a fixed pattern for resistance to simple timing attacks (even SPA),
1131 * see [1]. (The resulting multiplication algorithm can also been seen as a
1132 * modification of 2^w-ary multiplication, with signed coefficients, all of
1133 * them odd.)
Manuel Pégourié-Gonnard85556072012-11-17 19:54:20 +01001134 *
1135 * Input:
1136 * m must be an odd positive mpi less than w * k bits long
1137 * x must be an array of k elements
1138 * w must be less than a certain maximum (currently 8)
1139 *
1140 * The result is a sequence x[0], ..., x[k-1] with x[i] in the range
1141 * - 2^(width - 1) .. 2^(width - 1) - 1 such that
1142 * m = (2 * x[0] + 1) + 2^width * (2 * x[1] + 1) + ...
1143 * + 2^((k-1) * width) * (2 * x[k-1] + 1)
1144 *
1145 * Compared to "Algorithm SPA-resistant Width-w NAF with Odd Scalar"
1146 * p. 335 of the cited reference, here we return only u, not d_w since
1147 * it is known that the other d_w[j] will be 0. Moreover, the returned
1148 * string doesn't actually store u_i but x_i = u_i / 2 since it is known
1149 * that u_i is odd. Also, since we always select a positive value for d
1150 * mod 2^w, we don't need to check the sign of u[i-1] when the reference
1151 * does. Finally, there is an off-by-one error in the reference: the
1152 * last index should be k-1, not k.
1153 */
Manuel Pégourié-Gonnard7652a592012-11-21 10:00:45 +01001154static int ecp_w_naf_fixed( signed char x[], size_t k,
1155 unsigned char w, const mpi *m )
Manuel Pégourié-Gonnard85556072012-11-17 19:54:20 +01001156{
1157 int ret;
1158 unsigned int i, u, mask, carry;
1159 mpi M;
1160
1161 mpi_init( &M );
1162
1163 MPI_CHK( mpi_copy( &M, m ) );
1164 mask = ( 1 << w ) - 1;
1165 carry = 1 << ( w - 1 );
1166
1167 for( i = 0; i < k; i++ )
1168 {
1169 u = M.p[0] & mask;
1170
1171 if( ( u & 1 ) == 0 && i > 0 )
1172 x[i - 1] -= carry;
1173
1174 x[i] = u >> 1;
1175 mpi_shift_r( &M, w );
1176 }
1177
1178 /*
1179 * We should have consumed all the bits now
1180 */
1181 if( mpi_cmp_int( &M, 0 ) != 0 )
1182 ret = POLARSSL_ERR_ECP_GENERIC;
1183
1184cleanup:
1185
1186 mpi_free( &M );
1187
1188 return( ret );
1189}
1190
1191/*
Manuel Pégourié-Gonnard7652a592012-11-21 10:00:45 +01001192 * Precompute odd multiples of P up to (2 * t_len - 1) P.
1193 * The table is filled with T[i] = (2 * i + 1) P.
1194 */
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001195static int ecp_precompute( const ecp_group *grp,
1196 ecp_point T[], size_t t_len,
1197 const ecp_point *P )
Manuel Pégourié-Gonnard7652a592012-11-21 10:00:45 +01001198{
1199 int ret;
1200 size_t i;
1201 ecp_point PP;
1202
1203 ecp_point_init( &PP );
1204
1205 MPI_CHK( ecp_add( grp, &PP, P, P ) );
1206
1207 MPI_CHK( ecp_copy( &T[0], P ) );
1208
Manuel Pégourié-Gonnard7652a592012-11-21 10:00:45 +01001209 for( i = 1; i < t_len; i++ )
Manuel Pégourié-Gonnardcdd44322012-11-21 16:00:55 +01001210 MPI_CHK( ecp_add_mixed( grp, &T[i], &T[i-1], &PP, +1 ) );
1211
1212 /*
1213 * T[0] = P already has normalized coordinates
1214 */
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001215 MPI_CHK( ecp_normalize_many( grp, T + 1, t_len - 1 ) );
Manuel Pégourié-Gonnard7652a592012-11-21 10:00:45 +01001216
1217cleanup:
1218
1219 ecp_point_free( &PP );
1220
1221 return( ret );
1222}
1223
1224/*
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +02001225 * Randomize jacobian coordinates:
1226 * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
1227 * This is sort of the reverse operation of ecp_normalize().
1228 */
1229static int ecp_randomize_coordinates( const ecp_group *grp, ecp_point *pt,
1230 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1231{
1232 int ret;
1233 mpi l, ll;
1234 size_t p_size = (grp->pbits + 7) / 8;
1235 int count = 0;
1236
1237 mpi_init( &l ); mpi_init( &ll );
1238
1239 /* Generate l such that 1 < l < p */
1240 do
1241 {
1242 mpi_fill_random( &l, p_size, f_rng, p_rng );
1243
1244 while( mpi_cmp_mpi( &l, &grp->P ) >= 0 )
1245 mpi_shift_r( &l, 1 );
1246
1247 if( count++ > 10 )
1248 return( POLARSSL_ERR_ECP_GENERIC );
1249 }
1250 while( mpi_cmp_int( &l, 1 ) <= 0 );
1251
1252 /* Z = l * Z */
1253 MPI_CHK( mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
1254
1255 /* X = l^2 * X */
1256 MPI_CHK( mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
1257 MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
1258
1259 /* Y = l^3 * Y */
1260 MPI_CHK( mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
1261 MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
1262
1263cleanup:
1264 mpi_free( &l ); mpi_free( &ll );
1265
1266 return( ret );
1267}
1268
1269/*
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001270 * Maximum length of the precomputed table
1271 */
1272#define MAX_PRE_LEN ( 1 << (POLARSSL_ECP_WINDOW_SIZE - 1) )
1273
1274/*
1275 * Maximum length of the NAF: ceil( grp->nbits + 1 ) / w
1276 * (that is: grp->nbits / w + 1)
1277 * Allow p_bits + 1 bits in case M = grp->N + 1 is one bit longer than N.
1278 */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +02001279#define MAX_NAF_LEN ( POLARSSL_ECP_MAX_BITS / 2 + 1 )
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001280
1281/*
1282 * Integer multiplication: R = m * P
1283 *
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +02001284 * Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed().
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001285 *
1286 * This function executes a fixed number of operations for
1287 * random m in the range 0 .. 2^nbits - 1.
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +02001288 *
1289 * As an additional countermeasure against potential elaborate timing attacks,
1290 * we randomize coordinates after each addition. This was suggested as a
1291 * countermeasure against DPA in 5.3 of [2] (with the obvious adaptation that
1292 * we use jacobian coordinates, not standard projective coordinates).
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001293 */
1294int ecp_mul( const ecp_group *grp, ecp_point *R,
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001295 const mpi *m, const ecp_point *P,
1296 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001297{
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001298 int ret;
1299 unsigned char w, m_is_odd;
1300 size_t pre_len, naf_len, i, j;
1301 signed char naf[ MAX_NAF_LEN ];
1302 ecp_point Q, T[ MAX_PRE_LEN ];
1303 mpi M;
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001304
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001305 if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits )
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001306 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard4bdd47d2012-11-11 14:33:59 +01001307
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001308 w = grp->nbits >= 521 ? 6 :
1309 grp->nbits >= 224 ? 5 :
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001310 4;
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001311
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001312 /*
1313 * Make sure w is within the limits.
1314 * The last test ensures that none of the precomputed points is zero,
1315 * which wouldn't be handled correctly by ecp_normalize_many().
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001316 * It is only useful for very small curves, as used in the test suite.
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001317 */
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001318 if( w > POLARSSL_ECP_WINDOW_SIZE )
1319 w = POLARSSL_ECP_WINDOW_SIZE;
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001320 if( w < 2 || w >= grp->nbits )
1321 w = 2;
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001322
1323 pre_len = 1 << ( w - 1 );
1324 naf_len = grp->nbits / w + 1;
1325
1326 mpi_init( &M );
1327 ecp_point_init( &Q );
1328 for( i = 0; i < pre_len; i++ )
1329 ecp_point_init( &T[i] );
1330
1331 m_is_odd = ( mpi_get_bit( m, 0 ) == 1 );
1332
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001333 /*
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001334 * Make sure M is odd:
1335 * later we'll get m * P by subtracting * P or 2 * P to M * P.
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001336 */
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001337 MPI_CHK( mpi_copy( &M, m ) );
1338 MPI_CHK( mpi_add_int( &M, &M, 1 + m_is_odd ) );
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001339
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001340 /*
1341 * Compute the fixed-pattern NAF and precompute odd multiples
1342 */
1343 MPI_CHK( ecp_w_naf_fixed( naf, naf_len, w, &M ) );
1344 MPI_CHK( ecp_precompute( grp, T, pre_len, P ) );
Manuel Pégourié-Gonnard47123252012-11-10 14:44:24 +01001345
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001346 /*
1347 * Compute M * P, using a variant of left-to-right 2^w-ary multiplication:
1348 * at each step we add (2 * naf[i] + 1) P, then multiply by 2^w.
1349 *
1350 * If naf[i] >= 0, we have (2 * naf[i] + 1) P == T[ naf[i] ]
1351 * Otherwise, (2 * naf[i] + 1) P == - ( 2 * ( - naf[i] - 1 ) + 1) P
1352 * == T[ - naf[i] - 1 ]
1353 */
1354 MPI_CHK( ecp_set_zero( &Q ) );
1355 i = naf_len - 1;
1356 while( 1 )
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001357 {
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001358 if( naf[i] < 0 )
1359 {
1360 MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ - naf[i] - 1 ], -1 ) );
1361 }
1362 else
1363 {
1364 MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) );
1365 }
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001366
Manuel Pégourié-Gonnard07de4b12013-09-02 16:26:04 +02001367 /* Countermeasure (see comments above) */
1368 if( f_rng != NULL )
1369 ecp_randomize_coordinates( grp, &Q, f_rng, p_rng );
1370
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001371 if( i == 0 )
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001372 break;
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001373 i--;
1374
1375 for( j = 0; j < w; j++ )
1376 {
1377 MPI_CHK( ecp_double_jac( grp, &Q, &Q ) );
1378 }
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001379 }
1380
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001381 /*
1382 * Now get m * P from M * P.
1383 * Since we don't need T[] any more, we can recycle it:
1384 * we already have T[0] = P, now set T[1] = 2 * P.
1385 */
1386 MPI_CHK( ecp_add( grp, &T[1], P, P ) );
1387 MPI_CHK( ecp_sub( grp, R, &Q, &T[m_is_odd] ) );
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001388
Manuel Pégourié-Gonnard3680c822012-11-21 18:49:45 +01001389
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001390cleanup:
1391
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001392 mpi_free( &M );
1393 ecp_point_free( &Q );
1394 for( i = 0; i < pre_len; i++ )
1395 ecp_point_free( &T[i] );
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001396
1397 return( ret );
1398}
1399
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001400/*
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +02001401 * Check that a point is valid as a public key (SEC1 3.2.3.1)
1402 */
1403int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt )
1404{
1405 int ret;
1406 mpi YY, RHS;
1407
1408 if( mpi_cmp_int( &pt->Z, 0 ) == 0 )
1409 return( POLARSSL_ERR_ECP_GENERIC );
1410
1411 /*
1412 * pt coordinates must be normalized for our checks
1413 */
1414 if( mpi_cmp_int( &pt->Z, 1 ) != 0 )
1415 return( POLARSSL_ERR_ECP_GENERIC );
1416
1417 if( mpi_cmp_int( &pt->X, 0 ) < 0 ||
1418 mpi_cmp_int( &pt->Y, 0 ) < 0 ||
1419 mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
1420 mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
1421 return( POLARSSL_ERR_ECP_GENERIC );
1422
1423 mpi_init( &YY ); mpi_init( &RHS );
1424
1425 /*
1426 * YY = Y^2
1427 * RHS = X (X^2 - 3) + B = X^3 - 3X + B
1428 */
1429 MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
1430 MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
1431 MPI_CHK( mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS );
1432 MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
1433 MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
1434
1435 if( mpi_cmp_mpi( &YY, &RHS ) != 0 )
1436 ret = POLARSSL_ERR_ECP_GENERIC;
1437
1438cleanup:
1439
1440 mpi_free( &YY ); mpi_free( &RHS );
1441
1442 return( ret );
1443}
1444
1445/*
1446 * Check that an mpi is valid as a private key (SEC1 3.2)
1447 */
Manuel Pégourié-Gonnardde44a4a2013-07-09 16:05:52 +02001448int ecp_check_privkey( const ecp_group *grp, const mpi *d )
Manuel Pégourié-Gonnardc8dc2952013-07-01 14:06:13 +02001449{
1450 /* We want 1 <= d <= N-1 */
1451 if ( mpi_cmp_int( d, 1 ) < 0 || mpi_cmp_mpi( d, &grp->N ) >= 0 )
1452 return( POLARSSL_ERR_ECP_GENERIC );
1453
1454 return( 0 );
1455}
1456
1457/*
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001458 * Generate a keypair (SEC1 3.2.1)
1459 */
1460int ecp_gen_keypair( const ecp_group *grp, mpi *d, ecp_point *Q,
1461 int (*f_rng)(void *, unsigned char *, size_t),
1462 void *p_rng )
1463{
1464 int count = 0;
1465 size_t n_size = (grp->nbits + 7) / 8;
1466
1467 /*
1468 * Generate d such that 1 <= n < N
1469 */
1470 do
1471 {
1472 mpi_fill_random( d, n_size, f_rng, p_rng );
1473
1474 while( mpi_cmp_mpi( d, &grp->N ) >= 0 )
1475 mpi_shift_r( d, 1 );
1476
1477 if( count++ > 10 )
1478 return( POLARSSL_ERR_ECP_GENERIC );
1479 }
1480 while( mpi_cmp_int( d, 1 ) < 0 );
1481
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001482 return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) );
Manuel Pégourié-Gonnard45a035a2013-01-26 14:42:45 +01001483}
Manuel Pégourié-Gonnardefaa31e2012-11-06 21:34:35 +01001484
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +01001485#if defined(POLARSSL_SELF_TEST)
1486
Manuel Pégourié-Gonnardb505c272012-11-05 17:27:54 +01001487/*
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +01001488 * Checkup routine
1489 */
1490int ecp_self_test( int verbose )
1491{
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001492 int ret;
1493 size_t i;
1494 ecp_group grp;
1495 ecp_point R;
1496 mpi m;
1497 unsigned long add_c_prev, dbl_c_prev;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02001498 const char *exponents[] =
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001499 {
Manuel Pégourié-Gonnardb63f9e92012-11-21 13:00:58 +01001500 "000000000000000000000000000000000000000000000000", /* zero */
1501 "000000000000000000000000000000000000000000000001", /* one */
1502 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* N */
1503 "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001504 "400000000000000000000000000000000000000000000000",
1505 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
1506 "555555555555555555555555555555555555555555555555",
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001507 };
1508
1509 ecp_group_init( &grp );
1510 ecp_point_init( &R );
1511 mpi_init( &m );
1512
Paul Bakker5dc6b5f2013-06-29 23:26:34 +02001513#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001514 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) );
Paul Bakker5dc6b5f2013-06-29 23:26:34 +02001515#else
1516#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED)
1517 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP224R1 ) );
1518#else
1519#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED)
1520 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP256R1 ) );
1521#else
1522#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED)
1523 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP384R1 ) );
1524#else
1525#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
1526 MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP521R1 ) );
1527#else
1528#error No curves defines
1529#endif /* POLARSSL_ECP_DP_SECP512R1_ENABLED */
1530#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */
1531#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */
1532#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */
1533#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001534
1535 if( verbose != 0 )
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001536 printf( " ECP test #1 (resistance to simple timing attacks): " );
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001537
1538 add_count = 0;
1539 dbl_count = 0;
1540 MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001541 MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001542
1543 for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
1544 {
1545 add_c_prev = add_count;
1546 dbl_c_prev = dbl_count;
1547 add_count = 0;
1548 dbl_count = 0;
1549
1550 MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +02001551 MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
Manuel Pégourié-Gonnardb4a310b2012-11-13 20:57:00 +01001552
1553 if( add_count != add_c_prev || dbl_count != dbl_c_prev )
1554 {
1555 if( verbose != 0 )
1556 printf( "failed (%zu)\n", i );
1557
1558 ret = 1;
1559 goto cleanup;
1560 }
1561 }
1562
1563 if( verbose != 0 )
1564 printf( "passed\n" );
1565
1566cleanup:
1567
1568 if( ret < 0 && verbose != 0 )
1569 printf( "Unexpected error, return code = %08X\n", ret );
1570
1571 ecp_group_free( &grp );
1572 ecp_point_free( &R );
1573 mpi_free( &m );
1574
1575 if( verbose != 0 )
1576 printf( "\n" );
1577
1578 return( ret );
Manuel Pégourié-Gonnard39d2adb2012-10-31 09:26:55 +01001579}
1580
1581#endif
1582
1583#endif