4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
27 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
30 #if !defined(MBEDTLS_CONFIG_FILE)
31 #include "mbedtls/config.h"
33 #include MBEDTLS_CONFIG_FILE
36 #if defined(MBEDTLS_ECDSA_C)
38 #include "mbedtls/ecdsa.h"
39 #include "mbedtls/asn1write.h"
43 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
44 #include "mbedtls/hmac_drbg.h"
48 * Derive a suitable integer for group grp from a buffer of length len
49 * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
51 static int derive_mpi( const mbedtls_ecp_group
*grp
, mbedtls_mpi
*x
,
52 const unsigned char *buf
, size_t blen
)
55 size_t n_size
= ( grp
->nbits
+ 7 ) / 8;
56 size_t use_size
= blen
> n_size
? n_size
: blen
;
58 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x
, buf
, use_size
) );
59 if( use_size
* 8 > grp
->nbits
)
60 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x
, use_size
* 8 - grp
->nbits
) );
62 /* While at it, reduce modulo N */
63 if( mbedtls_mpi_cmp_mpi( x
, &grp
->N
) >= 0 )
64 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x
, x
, &grp
->N
) );
70 #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
72 * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
73 * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
75 int mbedtls_ecdsa_sign( mbedtls_ecp_group
*grp
, mbedtls_mpi
*r
, mbedtls_mpi
*s
,
76 const mbedtls_mpi
*d
, const unsigned char *buf
, size_t blen
,
77 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
79 int ret
, key_tries
, sign_tries
, blind_tries
;
83 /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
84 if( grp
->N
.p
== NULL
)
85 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
87 /* Make sure d is in range 1..n-1 */
88 if( mbedtls_mpi_cmp_int( d
, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d
, &grp
->N
) >= 0 )
89 return( MBEDTLS_ERR_ECP_INVALID_KEY
);
91 mbedtls_ecp_point_init( &R
);
92 mbedtls_mpi_init( &k
); mbedtls_mpi_init( &e
); mbedtls_mpi_init( &t
);
98 * Steps 1-3: generate a suitable ephemeral keypair
99 * and set r = xR mod n
104 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp
, &k
, &R
, f_rng
, p_rng
) );
105 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r
, &R
.X
, &grp
->N
) );
107 if( key_tries
++ > 10 )
109 ret
= MBEDTLS_ERR_ECP_RANDOM_FAILED
;
113 while( mbedtls_mpi_cmp_int( r
, 0 ) == 0 );
116 * Step 5: derive MPI from hashed message
118 MBEDTLS_MPI_CHK( derive_mpi( grp
, &e
, buf
, blen
) );
121 * Generate a random value to blind inv_mod in next step,
122 * avoiding a potential timing leak.
127 size_t n_size
= ( grp
->nbits
+ 7 ) / 8;
128 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t
, n_size
, f_rng
, p_rng
) );
129 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t
, 8 * n_size
- grp
->nbits
) );
131 /* See mbedtls_ecp_gen_keypair() */
132 if( ++blind_tries
> 30 )
133 return( MBEDTLS_ERR_ECP_RANDOM_FAILED
);
135 while( mbedtls_mpi_cmp_int( &t
, 1 ) < 0 ||
136 mbedtls_mpi_cmp_mpi( &t
, &grp
->N
) >= 0 );
139 * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
141 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s
, r
, d
) );
142 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e
, &e
, s
) );
143 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e
, &e
, &t
) );
144 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k
, &k
, &t
) );
145 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s
, &k
, &grp
->N
) );
146 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s
, s
, &e
) );
147 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s
, s
, &grp
->N
) );
149 if( sign_tries
++ > 10 )
151 ret
= MBEDTLS_ERR_ECP_RANDOM_FAILED
;
155 while( mbedtls_mpi_cmp_int( s
, 0 ) == 0 );
158 mbedtls_ecp_point_free( &R
);
159 mbedtls_mpi_free( &k
); mbedtls_mpi_free( &e
); mbedtls_mpi_free( &t
);
163 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
165 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
167 * Deterministic signature wrapper
169 int mbedtls_ecdsa_sign_det( mbedtls_ecp_group
*grp
, mbedtls_mpi
*r
, mbedtls_mpi
*s
,
170 const mbedtls_mpi
*d
, const unsigned char *buf
, size_t blen
,
171 mbedtls_md_type_t md_alg
)
174 mbedtls_hmac_drbg_context rng_ctx
;
175 unsigned char data
[2 * MBEDTLS_ECP_MAX_BYTES
];
176 size_t grp_len
= ( grp
->nbits
+ 7 ) / 8;
177 const mbedtls_md_info_t
*md_info
;
180 if( ( md_info
= mbedtls_md_info_from_type( md_alg
) ) == NULL
)
181 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
183 mbedtls_mpi_init( &h
);
184 mbedtls_hmac_drbg_init( &rng_ctx
);
186 /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
187 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d
, data
, grp_len
) );
188 MBEDTLS_MPI_CHK( derive_mpi( grp
, &h
, buf
, blen
) );
189 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h
, data
+ grp_len
, grp_len
) );
190 mbedtls_hmac_drbg_seed_buf( &rng_ctx
, md_info
, data
, 2 * grp_len
);
192 ret
= mbedtls_ecdsa_sign( grp
, r
, s
, d
, buf
, blen
,
193 mbedtls_hmac_drbg_random
, &rng_ctx
);
196 mbedtls_hmac_drbg_free( &rng_ctx
);
197 mbedtls_mpi_free( &h
);
201 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
203 #if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
205 * Verify ECDSA signature of hashed message (SEC1 4.1.4)
206 * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
208 int mbedtls_ecdsa_verify( mbedtls_ecp_group
*grp
,
209 const unsigned char *buf
, size_t blen
,
210 const mbedtls_ecp_point
*Q
, const mbedtls_mpi
*r
, const mbedtls_mpi
*s
)
213 mbedtls_mpi e
, s_inv
, u1
, u2
;
216 mbedtls_ecp_point_init( &R
);
217 mbedtls_mpi_init( &e
); mbedtls_mpi_init( &s_inv
); mbedtls_mpi_init( &u1
); mbedtls_mpi_init( &u2
);
219 /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
220 if( grp
->N
.p
== NULL
)
221 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
224 * Step 1: make sure r and s are in range 1..n-1
226 if( mbedtls_mpi_cmp_int( r
, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r
, &grp
->N
) >= 0 ||
227 mbedtls_mpi_cmp_int( s
, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s
, &grp
->N
) >= 0 )
229 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
234 * Additional precaution: make sure Q is valid
236 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp
, Q
) );
239 * Step 3: derive MPI from hashed message
241 MBEDTLS_MPI_CHK( derive_mpi( grp
, &e
, buf
, blen
) );
244 * Step 4: u1 = e / s mod n, u2 = r / s mod n
246 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv
, s
, &grp
->N
) );
248 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1
, &e
, &s_inv
) );
249 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1
, &u1
, &grp
->N
) );
251 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2
, r
, &s_inv
) );
252 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2
, &u2
, &grp
->N
) );
255 * Step 5: R = u1 G + u2 Q
257 * Since we're not using any secret data, no need to pass a RNG to
258 * mbedtls_ecp_mul() for countermesures.
260 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp
, &R
, &u1
, &grp
->G
, &u2
, Q
) );
262 if( mbedtls_ecp_is_zero( &R
) )
264 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
269 * Step 6: convert xR to an integer (no-op)
270 * Step 7: reduce xR mod n (gives v)
272 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R
.X
, &R
.X
, &grp
->N
) );
275 * Step 8: check if v (that is, R.X) is equal to r
277 if( mbedtls_mpi_cmp_mpi( &R
.X
, r
) != 0 )
279 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
284 mbedtls_ecp_point_free( &R
);
285 mbedtls_mpi_free( &e
); mbedtls_mpi_free( &s_inv
); mbedtls_mpi_free( &u1
); mbedtls_mpi_free( &u2
);
289 #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
292 * Convert a signature (given by context) to ASN.1
294 int ecdsa_signature_to_asn1( const mbedtls_mpi
*r
, const mbedtls_mpi
*s
,
295 unsigned char *sig
, size_t *slen
)
298 unsigned char buf
[MBEDTLS_ECDSA_MAX_LEN
];
299 unsigned char *p
= buf
+ sizeof( buf
);
302 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &p
, buf
, s
) );
303 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &p
, buf
, r
) );
305 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &p
, buf
, len
) );
306 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &p
, buf
,
307 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) );
309 memcpy( sig
, p
, len
);
316 * Compute and write signature
318 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context
*ctx
, mbedtls_md_type_t md_alg
,
319 const unsigned char *hash
, size_t hlen
,
320 unsigned char *sig
, size_t *slen
,
321 int (*f_rng
)(void *, unsigned char *, size_t),
327 mbedtls_mpi_init( &r
);
328 mbedtls_mpi_init( &s
);
330 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
334 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx
->grp
, &r
, &s
, &ctx
->d
,
335 hash
, hlen
, md_alg
) );
339 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx
->grp
, &r
, &s
, &ctx
->d
,
340 hash
, hlen
, f_rng
, p_rng
) );
343 MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r
, &s
, sig
, slen
) );
346 mbedtls_mpi_free( &r
);
347 mbedtls_mpi_free( &s
);
352 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
353 defined(MBEDTLS_ECDSA_DETERMINISTIC)
354 int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context
*ctx
,
355 const unsigned char *hash
, size_t hlen
,
356 unsigned char *sig
, size_t *slen
,
357 mbedtls_md_type_t md_alg
)
359 return( mbedtls_ecdsa_write_signature( ctx
, md_alg
, hash
, hlen
, sig
, slen
,
365 * Read and check signature
367 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context
*ctx
,
368 const unsigned char *hash
, size_t hlen
,
369 const unsigned char *sig
, size_t slen
)
372 unsigned char *p
= (unsigned char *) sig
;
373 const unsigned char *end
= sig
+ slen
;
377 mbedtls_mpi_init( &r
);
378 mbedtls_mpi_init( &s
);
380 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
381 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
383 ret
+= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
389 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
390 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
;
394 if( ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &r
) ) != 0 ||
395 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &s
) ) != 0 )
397 ret
+= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
401 if( ( ret
= mbedtls_ecdsa_verify( &ctx
->grp
, hash
, hlen
,
402 &ctx
->Q
, &r
, &s
) ) != 0 )
405 /* At this point we know that the buffer starts with a valid signature.
406 * Return 0 if the buffer just contains the signature, and a specific
407 * error code if the valid signature is followed by more data. */
409 ret
= MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH
;
412 mbedtls_mpi_free( &r
);
413 mbedtls_mpi_free( &s
);
418 #if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
422 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context
*ctx
, mbedtls_ecp_group_id gid
,
423 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
425 return( mbedtls_ecp_group_load( &ctx
->grp
, gid
) ||
426 mbedtls_ecp_gen_keypair( &ctx
->grp
, &ctx
->d
, &ctx
->Q
, f_rng
, p_rng
) );
428 #endif /* MBEDTLS_ECDSA_GENKEY_ALT */
431 * Set context from an mbedtls_ecp_keypair
433 int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context
*ctx
, const mbedtls_ecp_keypair
*key
)
437 if( ( ret
= mbedtls_ecp_group_copy( &ctx
->grp
, &key
->grp
) ) != 0 ||
438 ( ret
= mbedtls_mpi_copy( &ctx
->d
, &key
->d
) ) != 0 ||
439 ( ret
= mbedtls_ecp_copy( &ctx
->Q
, &key
->Q
) ) != 0 )
441 mbedtls_ecdsa_free( ctx
);
450 void mbedtls_ecdsa_init( mbedtls_ecdsa_context
*ctx
)
452 mbedtls_ecp_keypair_init( ctx
);
458 void mbedtls_ecdsa_free( mbedtls_ecdsa_context
*ctx
)
460 mbedtls_ecp_keypair_free( ctx
);
463 #endif /* MBEDTLS_ECDSA_C */