3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* This file contains the functions needed for RSA/DSA public key
27 * encryption and signatures.
30 #include <gnutls_int.h>
31 #include <gnutls_mpi.h>
32 #include <gnutls_pk.h>
33 #include <gnutls_errors.h>
34 #include <gnutls_datum.h>
35 #include <gnutls_global.h>
36 #include <gnutls_num.h>
37 #include <x509/x509_int.h>
38 #include <x509/common.h>
40 #include <gnutls_pk.h>
41 #include <nettle/dsa.h>
42 #include <nettle/rsa.h>
44 #include <gnutls/crypto.h>
46 #define TOMPZ(x) (*((mpz_t*)(x)))
49 rnd_func (void *_ctx
, unsigned length
, uint8_t * data
)
51 _gnutls_rnd (GNUTLS_RND_RANDOM
, data
, length
);
55 _dsa_params_to_pubkey (const gnutls_pk_params_st
* pk_params
,
56 struct dsa_public_key
*pub
)
58 memcpy (&pub
->p
, pk_params
->params
[0], sizeof (mpz_t
));
59 memcpy (&pub
->q
, pk_params
->params
[1], sizeof (mpz_t
));
60 memcpy (&pub
->g
, pk_params
->params
[2], sizeof (mpz_t
));
61 memcpy (&pub
->y
, pk_params
->params
[3], sizeof (mpz_t
));
65 _dsa_params_to_privkey (const gnutls_pk_params_st
* pk_params
,
66 struct dsa_private_key
*pub
)
68 memcpy (&pub
->x
, pk_params
->params
[4], sizeof (mpz_t
));
72 _rsa_params_to_privkey (const gnutls_pk_params_st
* pk_params
,
73 struct rsa_private_key
*priv
)
75 memcpy (&priv
->d
, pk_params
->params
[2], sizeof (mpz_t
));
76 memcpy (&priv
->p
, pk_params
->params
[3], sizeof (mpz_t
));
77 memcpy (&priv
->q
, pk_params
->params
[4], sizeof (mpz_t
));
78 memcpy (&priv
->c
, pk_params
->params
[5], sizeof (mpz_t
));
79 memcpy (&priv
->a
, pk_params
->params
[6], sizeof (mpz_t
));
80 memcpy (&priv
->b
, pk_params
->params
[7], sizeof (mpz_t
));
85 _wrap_nettle_pk_encrypt (gnutls_pk_algorithm_t algo
,
86 gnutls_datum_t
* ciphertext
,
87 const gnutls_datum_t
* plaintext
,
88 const gnutls_pk_params_st
* pk_params
)
92 /* make a sexp from pkey */
99 if (_gnutls_mpi_scan_nz (&p
, plaintext
->data
, plaintext
->size
) != 0)
102 return GNUTLS_E_MPI_SCAN_FAILED
;
105 mpz_powm (p
, p
, TOMPZ (pk_params
->params
[1]) /*e */ ,
106 TOMPZ (pk_params
->params
[0] /*m */ ));
108 ret
= _gnutls_mpi_dprint_size (p
, ciphertext
, plaintext
->size
);
109 _gnutls_mpi_release (&p
);
121 ret
= GNUTLS_E_INTERNAL_ERROR
;
132 /* returns the blinded c and the inverse of a random
136 rsa_blind (bigint_t c
, bigint_t e
, bigint_t n
, bigint_t
* _ri
)
138 bigint_t nc
= NULL
, r
= NULL
, ri
= NULL
;
143 nc
= _gnutls_mpi_alloc_like (n
);
150 ri
= _gnutls_mpi_alloc_like (n
);
157 r
= _gnutls_mpi_randomize (NULL
, _gnutls_mpi_get_nbits (n
),
166 if (mpz_invert (ri
, r
, n
) == 0)
174 _gnutls_mpi_powm (r
, r
, e
, n
);
176 _gnutls_mpi_mulm (nc
, c
, r
, n
);
180 _gnutls_mpi_release (&r
);
184 _gnutls_mpi_release (&nc
);
185 _gnutls_mpi_release (&r
);
192 rsa_unblind (bigint_t c
, bigint_t ri
, bigint_t n
)
194 _gnutls_mpi_mulm (c
, c
, ri
, n
);
198 _wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo
,
199 gnutls_datum_t
* plaintext
,
200 const gnutls_datum_t
* ciphertext
,
201 const gnutls_pk_params_st
* pk_params
)
205 /* make a sexp from pkey */
210 struct rsa_private_key priv
;
213 if (_gnutls_mpi_scan_nz (&c
, ciphertext
->data
, ciphertext
->size
) != 0)
216 return GNUTLS_E_MPI_SCAN_FAILED
;
219 nc
= rsa_blind (c
, pk_params
->params
[1] /*e */ ,
220 pk_params
->params
[0] /*m */ , &ri
);
221 _gnutls_mpi_release (&c
);
225 return GNUTLS_E_MEMORY_ERROR
;
228 memset(&priv
, 0, sizeof(priv
));
229 _rsa_params_to_privkey (pk_params
, &priv
);
231 rsa_compute_root (&priv
, TOMPZ (nc
), TOMPZ (nc
));
233 rsa_unblind (nc
, ri
, pk_params
->params
[0] /*m */ );
235 ret
= _gnutls_mpi_dprint_size (nc
, plaintext
, ciphertext
->size
);
237 _gnutls_mpi_release (&nc
);
238 _gnutls_mpi_release (&ri
);
250 ret
= GNUTLS_E_INTERNAL_ERROR
;
261 /* in case of DSA puts into data, r,s
264 _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo
,
265 gnutls_datum_t
* signature
,
266 const gnutls_datum_t
* vdata
,
267 const gnutls_pk_params_st
* pk_params
)
276 struct dsa_public_key pub
;
277 struct dsa_private_key priv
;
278 struct dsa_signature sig
;
279 unsigned int hash_len
;
281 memset(&priv
, 0, sizeof(priv
));
282 memset(&pub
, 0, sizeof(pub
));
283 _dsa_params_to_pubkey (pk_params
, &pub
);
284 _dsa_params_to_privkey (pk_params
, &priv
);
286 dsa_signature_init (&sig
);
288 hash
= _gnutls_dsa_q_to_hash (pub
.q
, &hash_len
);
289 if (hash_len
> vdata
->size
)
292 _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash
), hash_len
);
293 hash_len
= vdata
->size
;
297 _dsa_sign (&pub
, &priv
, NULL
, rnd_func
,
298 hash_len
, vdata
->data
, &sig
);
302 ret
= GNUTLS_E_PK_SIGN_FAILED
;
306 ret
= _gnutls_encode_ber_rs (signature
, &sig
.r
, &sig
.s
);
309 dsa_signature_clear (&sig
);
320 struct rsa_private_key priv
;
321 bigint_t hash
, nc
, ri
;
323 if (_gnutls_mpi_scan_nz (&hash
, vdata
->data
, vdata
->size
) != 0)
326 return GNUTLS_E_MPI_SCAN_FAILED
;
329 memset(&priv
, 0, sizeof(priv
));
330 _rsa_params_to_privkey (pk_params
, &priv
);
332 nc
= rsa_blind (hash
, pk_params
->params
[1] /*e */ ,
333 pk_params
->params
[0] /*m */ , &ri
);
335 _gnutls_mpi_release (&hash
);
340 ret
= GNUTLS_E_MEMORY_ERROR
;
344 rsa_compute_root (&priv
, TOMPZ (nc
), TOMPZ (nc
));
346 rsa_unblind (nc
, ri
, pk_params
->params
[0] /*m */ );
348 ret
= _gnutls_mpi_dprint (nc
, signature
);
351 _gnutls_mpi_release (&nc
);
352 _gnutls_mpi_release (&ri
);
364 ret
= GNUTLS_E_INTERNAL_ERROR
;
376 _int_rsa_verify (const gnutls_pk_params_st
* pk_params
,
377 bigint_t m
, bigint_t s
)
383 if ((mpz_sgn (TOMPZ (s
)) <= 0)
384 || (mpz_cmp (TOMPZ (s
), TOMPZ (pk_params
->params
[0])) >= 0))
385 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
389 mpz_powm (m1
, TOMPZ (s
), TOMPZ (pk_params
->params
[1]),
390 TOMPZ (pk_params
->params
[0]));
392 res
= !mpz_cmp (TOMPZ (m
), m1
);
397 res
= GNUTLS_E_PK_SIG_VERIFY_FAILED
;
405 _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo
,
406 const gnutls_datum_t
* vdata
,
407 const gnutls_datum_t
* signature
,
408 const gnutls_pk_params_st
* pk_params
)
411 bigint_t tmp
[2] = { NULL
, NULL
};
417 struct dsa_public_key pub
;
418 struct dsa_signature sig
;
419 unsigned int hash_len
;
421 ret
= _gnutls_decode_ber_rs (signature
, &tmp
[0], &tmp
[1]);
427 memset(&pub
, 0, sizeof(pub
));
428 _dsa_params_to_pubkey (pk_params
, &pub
);
429 memcpy (&sig
.r
, tmp
[0], sizeof (sig
.r
));
430 memcpy (&sig
.s
, tmp
[1], sizeof (sig
.s
));
432 hash
= _gnutls_dsa_q_to_hash (pub
.q
, &hash_len
);
434 if (hash_len
> vdata
->size
)
437 _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash
), hash_len
);
438 hash_len
= vdata
->size
;
441 ret
= _dsa_verify (&pub
, hash_len
, vdata
->data
, &sig
);
445 ret
= GNUTLS_E_PK_SIG_VERIFY_FAILED
;
450 _gnutls_mpi_release (&tmp
[0]);
451 _gnutls_mpi_release (&tmp
[1]);
458 if (_gnutls_mpi_scan_nz (&hash
, vdata
->data
, vdata
->size
) != 0)
461 return GNUTLS_E_MPI_SCAN_FAILED
;
464 ret
= _gnutls_mpi_scan_nz (&tmp
[0], signature
->data
, signature
->size
);
471 ret
= _int_rsa_verify (pk_params
, hash
, tmp
[0]);
472 _gnutls_mpi_release (&tmp
[0]);
473 _gnutls_mpi_release (&hash
);
478 ret
= GNUTLS_E_INTERNAL_ERROR
;
488 wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo
,
489 unsigned int level
/*bits */ ,
490 gnutls_pk_params_st
* params
)
495 memset(params
, 0, sizeof(*params
));
502 struct dsa_public_key pub
;
503 struct dsa_private_key priv
;
505 dsa_public_key_init (&pub
);
506 dsa_private_key_init (&priv
);
508 /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
509 * but we do NIST DSA here */
516 dsa_generate_keypair (&pub
, &priv
, NULL
,
517 rnd_func
, NULL
, NULL
, level
, q_bits
);
521 ret
= GNUTLS_E_INTERNAL_ERROR
;
525 params
->params_nr
= 0;
526 for (i
= 0; i
< DSA_PRIVATE_PARAMS
; i
++)
528 params
->params
[i
] = _gnutls_mpi_alloc_like (&pub
.p
);
529 if (params
->params
[i
] == NULL
)
531 ret
= GNUTLS_E_MEMORY_ERROR
;
538 _gnutls_mpi_set (params
->params
[0], pub
.p
);
539 _gnutls_mpi_set (params
->params
[1], pub
.q
);
540 _gnutls_mpi_set (params
->params
[2], pub
.g
);
541 _gnutls_mpi_set (params
->params
[3], pub
.y
);
542 _gnutls_mpi_set (params
->params
[4], priv
.x
);
545 dsa_private_key_clear (&priv
);
546 dsa_public_key_clear (&pub
);
555 struct rsa_public_key pub
;
556 struct rsa_private_key priv
;
558 rsa_public_key_init (&pub
);
559 rsa_private_key_init (&priv
);
561 _gnutls_mpi_set_ui (&pub
.e
, 65537);
564 rsa_generate_keypair (&pub
, &priv
, NULL
,
565 rnd_func
, NULL
, NULL
, level
, 0);
569 ret
= GNUTLS_E_INTERNAL_ERROR
;
573 params
->params_nr
= 0;
574 for (i
= 0; i
< RSA_PRIVATE_PARAMS
; i
++)
576 params
->params
[i
] = _gnutls_mpi_alloc_like (&pub
.n
);
577 if (params
->params
[i
] == NULL
)
579 ret
= GNUTLS_E_MEMORY_ERROR
;
588 _gnutls_mpi_set (params
->params
[0], pub
.n
);
589 _gnutls_mpi_set (params
->params
[1], pub
.e
);
590 _gnutls_mpi_set (params
->params
[2], priv
.d
);
591 _gnutls_mpi_set (params
->params
[3], priv
.p
);
592 _gnutls_mpi_set (params
->params
[4], priv
.q
);
593 _gnutls_mpi_set (params
->params
[5], priv
.c
);
594 _gnutls_mpi_set (params
->params
[6], priv
.a
);
595 _gnutls_mpi_set (params
->params
[7], priv
.b
);
598 rsa_private_key_clear (&priv
);
599 rsa_public_key_clear (&pub
);
608 return GNUTLS_E_INVALID_REQUEST
;
615 for (i
= 0; i
< params
->params_nr
; i
++)
617 _gnutls_mpi_release (¶ms
->params
[i
]);
619 params
->params_nr
= 0;
626 wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo
,
627 gnutls_direction_t direction
,
628 gnutls_pk_params_st
* params
)
632 if (direction
== GNUTLS_IMPORT
&& algo
== GNUTLS_PK_RSA
)
634 /* do not trust the generated values. Some old private keys
635 * generated by us have mess on the values. Those were very
636 * old but it seemed some of the shipped example private
639 mpz_invert (TOMPZ (params
->params
[5]),
640 TOMPZ (params
->params
[4]), TOMPZ (params
->params
[3]));
642 /* calculate exp1 [6] and exp2 [7] */
643 _gnutls_mpi_release (¶ms
->params
[6]);
644 _gnutls_mpi_release (¶ms
->params
[7]);
646 result
= _gnutls_calc_rsa_exp (params
->params
, RSA_PRIVATE_PARAMS
- 2);
652 params
->params_nr
= RSA_PRIVATE_PARAMS
;
658 int crypto_pk_prio
= INT_MAX
;
660 gnutls_crypto_pk_st _gnutls_pk_ops
= {
661 .encrypt
= _wrap_nettle_pk_encrypt
,
662 .decrypt
= _wrap_nettle_pk_decrypt
,
663 .sign
= _wrap_nettle_pk_sign
,
664 .verify
= _wrap_nettle_pk_verify
,
665 .generate
= wrap_nettle_pk_generate_params
,
666 .pk_fixup_private_params
= wrap_nettle_pk_fixup
,