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
) );
71 * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
72 * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
74 int mbedtls_ecdsa_sign( mbedtls_ecp_group
*grp
, mbedtls_mpi
*r
, mbedtls_mpi
*s
,
75 const mbedtls_mpi
*d
, const unsigned char *buf
, size_t blen
,
76 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
78 int ret
, key_tries
, sign_tries
, blind_tries
;
82 /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
83 if( grp
->N
.p
== NULL
)
84 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
86 mbedtls_ecp_point_init( &R
);
87 mbedtls_mpi_init( &k
); mbedtls_mpi_init( &e
); mbedtls_mpi_init( &t
);
93 * Steps 1-3: generate a suitable ephemeral keypair
94 * and set r = xR mod n
99 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp
, &k
, &R
, f_rng
, p_rng
) );
100 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r
, &R
.X
, &grp
->N
) );
102 if( key_tries
++ > 10 )
104 ret
= MBEDTLS_ERR_ECP_RANDOM_FAILED
;
108 while( mbedtls_mpi_cmp_int( r
, 0 ) == 0 );
111 * Step 5: derive MPI from hashed message
113 MBEDTLS_MPI_CHK( derive_mpi( grp
, &e
, buf
, blen
) );
116 * Generate a random value to blind inv_mod in next step,
117 * avoiding a potential timing leak.
122 size_t n_size
= ( grp
->nbits
+ 7 ) / 8;
123 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t
, n_size
, f_rng
, p_rng
) );
124 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t
, 8 * n_size
- grp
->nbits
) );
126 /* See mbedtls_ecp_gen_keypair() */
127 if( ++blind_tries
> 30 )
128 return( MBEDTLS_ERR_ECP_RANDOM_FAILED
);
130 while( mbedtls_mpi_cmp_int( &t
, 1 ) < 0 ||
131 mbedtls_mpi_cmp_mpi( &t
, &grp
->N
) >= 0 );
134 * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
136 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s
, r
, d
) );
137 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e
, &e
, s
) );
138 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e
, &e
, &t
) );
139 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k
, &k
, &t
) );
140 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s
, &k
, &grp
->N
) );
141 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s
, s
, &e
) );
142 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s
, s
, &grp
->N
) );
144 if( sign_tries
++ > 10 )
146 ret
= MBEDTLS_ERR_ECP_RANDOM_FAILED
;
150 while( mbedtls_mpi_cmp_int( s
, 0 ) == 0 );
153 mbedtls_ecp_point_free( &R
);
154 mbedtls_mpi_free( &k
); mbedtls_mpi_free( &e
); mbedtls_mpi_free( &t
);
159 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
161 * Deterministic signature wrapper
163 int mbedtls_ecdsa_sign_det( mbedtls_ecp_group
*grp
, mbedtls_mpi
*r
, mbedtls_mpi
*s
,
164 const mbedtls_mpi
*d
, const unsigned char *buf
, size_t blen
,
165 mbedtls_md_type_t md_alg
)
168 mbedtls_hmac_drbg_context rng_ctx
;
169 unsigned char data
[2 * MBEDTLS_ECP_MAX_BYTES
];
170 size_t grp_len
= ( grp
->nbits
+ 7 ) / 8;
171 const mbedtls_md_info_t
*md_info
;
174 if( ( md_info
= mbedtls_md_info_from_type( md_alg
) ) == NULL
)
175 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
177 mbedtls_mpi_init( &h
);
178 mbedtls_hmac_drbg_init( &rng_ctx
);
180 /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
181 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d
, data
, grp_len
) );
182 MBEDTLS_MPI_CHK( derive_mpi( grp
, &h
, buf
, blen
) );
183 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h
, data
+ grp_len
, grp_len
) );
184 mbedtls_hmac_drbg_seed_buf( &rng_ctx
, md_info
, data
, 2 * grp_len
);
186 ret
= mbedtls_ecdsa_sign( grp
, r
, s
, d
, buf
, blen
,
187 mbedtls_hmac_drbg_random
, &rng_ctx
);
190 mbedtls_hmac_drbg_free( &rng_ctx
);
191 mbedtls_mpi_free( &h
);
195 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
198 * Verify ECDSA signature of hashed message (SEC1 4.1.4)
199 * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
201 int mbedtls_ecdsa_verify( mbedtls_ecp_group
*grp
,
202 const unsigned char *buf
, size_t blen
,
203 const mbedtls_ecp_point
*Q
, const mbedtls_mpi
*r
, const mbedtls_mpi
*s
)
206 mbedtls_mpi e
, s_inv
, u1
, u2
;
209 mbedtls_ecp_point_init( &R
);
210 mbedtls_mpi_init( &e
); mbedtls_mpi_init( &s_inv
); mbedtls_mpi_init( &u1
); mbedtls_mpi_init( &u2
);
212 /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
213 if( grp
->N
.p
== NULL
)
214 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
217 * Step 1: make sure r and s are in range 1..n-1
219 if( mbedtls_mpi_cmp_int( r
, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r
, &grp
->N
) >= 0 ||
220 mbedtls_mpi_cmp_int( s
, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s
, &grp
->N
) >= 0 )
222 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
227 * Additional precaution: make sure Q is valid
229 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp
, Q
) );
232 * Step 3: derive MPI from hashed message
234 MBEDTLS_MPI_CHK( derive_mpi( grp
, &e
, buf
, blen
) );
237 * Step 4: u1 = e / s mod n, u2 = r / s mod n
239 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv
, s
, &grp
->N
) );
241 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1
, &e
, &s_inv
) );
242 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1
, &u1
, &grp
->N
) );
244 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2
, r
, &s_inv
) );
245 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2
, &u2
, &grp
->N
) );
248 * Step 5: R = u1 G + u2 Q
250 * Since we're not using any secret data, no need to pass a RNG to
251 * mbedtls_ecp_mul() for countermesures.
253 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp
, &R
, &u1
, &grp
->G
, &u2
, Q
) );
255 if( mbedtls_ecp_is_zero( &R
) )
257 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
262 * Step 6: convert xR to an integer (no-op)
263 * Step 7: reduce xR mod n (gives v)
265 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R
.X
, &R
.X
, &grp
->N
) );
268 * Step 8: check if v (that is, R.X) is equal to r
270 if( mbedtls_mpi_cmp_mpi( &R
.X
, r
) != 0 )
272 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
277 mbedtls_ecp_point_free( &R
);
278 mbedtls_mpi_free( &e
); mbedtls_mpi_free( &s_inv
); mbedtls_mpi_free( &u1
); mbedtls_mpi_free( &u2
);
284 * Convert a signature (given by context) to ASN.1
286 static int ecdsa_signature_to_asn1( const mbedtls_mpi
*r
, const mbedtls_mpi
*s
,
287 unsigned char *sig
, size_t *slen
)
290 unsigned char buf
[MBEDTLS_ECDSA_MAX_LEN
];
291 unsigned char *p
= buf
+ sizeof( buf
);
294 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &p
, buf
, s
) );
295 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &p
, buf
, r
) );
297 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &p
, buf
, len
) );
298 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &p
, buf
,
299 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) );
301 memcpy( sig
, p
, len
);
308 * Compute and write signature
310 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context
*ctx
, mbedtls_md_type_t md_alg
,
311 const unsigned char *hash
, size_t hlen
,
312 unsigned char *sig
, size_t *slen
,
313 int (*f_rng
)(void *, unsigned char *, size_t),
319 mbedtls_mpi_init( &r
);
320 mbedtls_mpi_init( &s
);
322 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
326 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx
->grp
, &r
, &s
, &ctx
->d
,
327 hash
, hlen
, md_alg
) );
331 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx
->grp
, &r
, &s
, &ctx
->d
,
332 hash
, hlen
, f_rng
, p_rng
) );
335 MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r
, &s
, sig
, slen
) );
338 mbedtls_mpi_free( &r
);
339 mbedtls_mpi_free( &s
);
344 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
345 defined(MBEDTLS_ECDSA_DETERMINISTIC)
346 int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context
*ctx
,
347 const unsigned char *hash
, size_t hlen
,
348 unsigned char *sig
, size_t *slen
,
349 mbedtls_md_type_t md_alg
)
351 return( mbedtls_ecdsa_write_signature( ctx
, md_alg
, hash
, hlen
, sig
, slen
,
357 * Read and check signature
359 int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context
*ctx
,
360 const unsigned char *hash
, size_t hlen
,
361 const unsigned char *sig
, size_t slen
)
364 unsigned char *p
= (unsigned char *) sig
;
365 const unsigned char *end
= sig
+ slen
;
369 mbedtls_mpi_init( &r
);
370 mbedtls_mpi_init( &s
);
372 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
373 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
375 ret
+= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
381 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
382 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
;
386 if( ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &r
) ) != 0 ||
387 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &s
) ) != 0 )
389 ret
+= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
393 if( ( ret
= mbedtls_ecdsa_verify( &ctx
->grp
, hash
, hlen
,
394 &ctx
->Q
, &r
, &s
) ) != 0 )
398 ret
= MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH
;
401 mbedtls_mpi_free( &r
);
402 mbedtls_mpi_free( &s
);
410 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context
*ctx
, mbedtls_ecp_group_id gid
,
411 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
413 return( mbedtls_ecp_group_load( &ctx
->grp
, gid
) ||
414 mbedtls_ecp_gen_keypair( &ctx
->grp
, &ctx
->d
, &ctx
->Q
, f_rng
, p_rng
) );
418 * Set context from an mbedtls_ecp_keypair
420 int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context
*ctx
, const mbedtls_ecp_keypair
*key
)
424 if( ( ret
= mbedtls_ecp_group_copy( &ctx
->grp
, &key
->grp
) ) != 0 ||
425 ( ret
= mbedtls_mpi_copy( &ctx
->d
, &key
->d
) ) != 0 ||
426 ( ret
= mbedtls_ecp_copy( &ctx
->Q
, &key
->Q
) ) != 0 )
428 mbedtls_ecdsa_free( ctx
);
437 void mbedtls_ecdsa_init( mbedtls_ecdsa_context
*ctx
)
439 mbedtls_ecp_keypair_init( ctx
);
445 void mbedtls_ecdsa_free( mbedtls_ecdsa_context
*ctx
)
447 mbedtls_ecp_keypair_free( ctx
);
450 #endif /* MBEDTLS_ECDSA_C */