2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS 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>
38 #include <x509/x509_int.h>
39 #include <x509/common.h>
42 /* Do PKCS-1 RSA encryption.
43 * params is modulus, public exp.
46 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t
* ciphertext
,
47 const gnutls_datum_t
* plaintext
,
48 bigint_t
* params
, unsigned params_len
,
56 gnutls_pk_params_st pk_params
;
57 gnutls_datum_t to_encrypt
, encrypted
;
59 for (i
= 0; i
< params_len
; i
++)
60 pk_params
.params
[i
] = params
[i
];
61 pk_params
.params_nr
= params_len
;
63 mod_bits
= _gnutls_mpi_get_nbits (params
[0]);
65 if (mod_bits
% 8 != 0)
68 if (plaintext
->size
> k
- 11)
71 return GNUTLS_E_PK_ENCRYPTION_FAILED
;
74 edata
= gnutls_malloc (k
);
78 return GNUTLS_E_MEMORY_ERROR
;
81 /* EB = 00||BT||PS||00||D
82 * (use block type 'btype')
87 psize
= k
- 3 - plaintext
->size
;
93 /* using public key */
94 if (params_len
< RSA_PUBLIC_PARAMS
)
98 return GNUTLS_E_INTERNAL_ERROR
;
101 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, ps
, psize
);
108 for (i
= 0; i
< psize
; i
++)
111 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, &ps
[i
], 1);
121 /* using private key */
123 if (params_len
< RSA_PRIVATE_PARAMS
)
127 return GNUTLS_E_INTERNAL_ERROR
;
130 for (i
= 0; i
< psize
; i
++)
136 return GNUTLS_E_INTERNAL_ERROR
;
140 memcpy (&ps
[psize
+ 1], plaintext
->data
, plaintext
->size
);
142 to_encrypt
.data
= edata
;
145 if (btype
== 2) /* encrypt */
147 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, &pk_params
);
150 _gnutls_pk_sign (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, &pk_params
);
160 psize
= encrypted
.size
;
170 * no need to do anything else
172 ciphertext
->data
= encrypted
.data
;
173 ciphertext
->size
= encrypted
.size
;
177 { /* psize > k !!! */
178 /* This is an impossible situation */
180 _gnutls_free_datum (&encrypted
);
181 return GNUTLS_E_INTERNAL_ERROR
;
184 ciphertext
->data
= gnutls_malloc (psize
);
185 if (ciphertext
->data
== NULL
)
188 _gnutls_free_datum (&encrypted
);
189 return GNUTLS_E_MEMORY_ERROR
;
192 memcpy (&ciphertext
->data
[pad
], encrypted
.data
, encrypted
.size
);
193 for (i
= 0; i
< pad
; i
++)
194 ciphertext
->data
[i
] = 0;
196 ciphertext
->size
= k
;
198 _gnutls_free_datum (&encrypted
);
204 /* Do PKCS-1 RSA decryption.
205 * params is modulus, public exp., private key
206 * Can decrypt block type 1 and type 2 packets.
209 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t
* plaintext
,
210 const gnutls_datum_t
* ciphertext
,
211 bigint_t
* params
, unsigned params_len
,
216 size_t esize
, mod_bits
;
217 gnutls_pk_params_st pk_params
;
219 for (i
= 0; i
< params_len
; i
++)
220 pk_params
.params
[i
] = params
[i
];
221 pk_params
.params_nr
= params_len
;
223 mod_bits
= _gnutls_mpi_get_nbits (params
[0]);
225 if (mod_bits
% 8 != 0)
228 esize
= ciphertext
->size
;
233 return GNUTLS_E_PK_DECRYPTION_FAILED
;
236 /* we can use btype to see if the private key is
242 _gnutls_pk_decrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, &pk_params
);
247 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, &pk_params
);
256 /* EB = 00||BT||PS||00||D
257 * (use block type 'btype')
259 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
260 * avoid attacks similar to the one described by Bleichenbacher in:
261 * "Chosen Ciphertext Attacks against Protocols Based on RSA
262 * Encryption Standard PKCS #1".
264 if (plaintext
->data
[0] != 0 || plaintext
->data
[1] != btype
)
267 return GNUTLS_E_DECRYPTION_FAILED
;
270 ret
= GNUTLS_E_DECRYPTION_FAILED
;
274 for (i
= 2; i
< plaintext
->size
; i
++)
276 if (plaintext
->data
[i
] == 0)
284 for (i
= 2; i
< plaintext
->size
; i
++)
286 if (plaintext
->data
[i
] == 0 && i
> 2)
291 if (plaintext
->data
[i
] != 0xff)
293 _gnutls_handshake_log ("PKCS #1 padding error");
294 _gnutls_free_datum (plaintext
);
295 /* PKCS #1 padding error. Don't use
296 GNUTLS_E_PKCS1_WRONG_PAD here. */
303 _gnutls_free_datum (plaintext
);
311 _gnutls_free_datum (plaintext
);
312 return GNUTLS_E_DECRYPTION_FAILED
;
315 memmove (plaintext
->data
, &plaintext
->data
[i
], esize
- i
);
316 plaintext
->size
= esize
- i
;
323 _gnutls_rsa_verify (const gnutls_datum_t
* vdata
,
324 const gnutls_datum_t
* ciphertext
, bigint_t
* params
,
325 int params_len
, int btype
)
328 gnutls_datum_t plain
;
331 /* decrypt signature */
333 _gnutls_pkcs1_rsa_decrypt (&plain
, ciphertext
, params
, params_len
,
340 if (plain
.size
!= vdata
->size
)
343 _gnutls_free_datum (&plain
);
344 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
347 if (memcmp (plain
.data
, vdata
->data
, plain
.size
) != 0)
350 _gnutls_free_datum (&plain
);
351 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
354 _gnutls_free_datum (&plain
);
359 /* encodes the Dss-Sig-Value structure
362 _gnutls_encode_ber_rs (gnutls_datum_t
* sig_value
, bigint_t r
, bigint_t s
)
368 asn1_create_element (_gnutls_get_gnutls_asn (),
369 "GNUTLS.DSASignatureValue",
370 &sig
)) != ASN1_SUCCESS
)
373 return _gnutls_asn2err (result
);
376 result
= _gnutls_x509_write_int (sig
, "r", r
, 1);
380 asn1_delete_structure (&sig
);
384 result
= _gnutls_x509_write_int (sig
, "s", s
, 1);
388 asn1_delete_structure (&sig
);
392 result
= _gnutls_x509_der_encode (sig
, "", sig_value
, 0);
394 asn1_delete_structure (&sig
);
406 /* Do DSA signature calculation. params is p, q, g, y, x in that order.
409 _gnutls_dsa_sign (gnutls_datum_t
* signature
,
410 const gnutls_datum_t
* hash
, bigint_t
* params
,
411 unsigned int params_len
)
416 gnutls_pk_params_st pk_params
;
418 for (i
= 0; i
< params_len
; i
++)
419 pk_params
.params
[i
] = params
[i
];
420 pk_params
.params_nr
= params_len
;
424 { /* SHA1 or better only */
426 return GNUTLS_E_PK_SIGN_FAILED
;
429 ret
= _gnutls_pk_sign (GNUTLS_PK_DSA
, signature
, hash
, &pk_params
);
430 /* rs[0], rs[1] now hold r,s */
441 /* decodes the Dss-Sig-Value structure
444 _gnutls_decode_ber_rs (const gnutls_datum_t
* sig_value
, bigint_t
* r
,
451 asn1_create_element (_gnutls_get_gnutls_asn (),
452 "GNUTLS.DSASignatureValue",
453 &sig
)) != ASN1_SUCCESS
)
456 return _gnutls_asn2err (result
);
459 result
= asn1_der_decoding (&sig
, sig_value
->data
, sig_value
->size
, NULL
);
460 if (result
!= ASN1_SUCCESS
)
463 asn1_delete_structure (&sig
);
464 return _gnutls_asn2err (result
);
467 result
= _gnutls_x509_read_int (sig
, "r", r
);
471 asn1_delete_structure (&sig
);
475 result
= _gnutls_x509_read_int (sig
, "s", s
);
479 _gnutls_mpi_release (s
);
480 asn1_delete_structure (&sig
);
484 asn1_delete_structure (&sig
);
489 /* params is p, q, g, y in that order
492 _gnutls_dsa_verify (const gnutls_datum_t
* vdata
,
493 const gnutls_datum_t
* sig_value
, bigint_t
* params
,
498 gnutls_pk_params_st pk_params
;
500 for (i
= 0; i
< params_len
; i
++)
501 pk_params
.params
[i
] = params
[i
];
502 pk_params
.params_nr
= params_len
;
504 if (vdata
->size
< 20)
505 { /* SHA1 or better only */
507 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
510 /* decrypt signature */
511 ret
= _gnutls_pk_verify (GNUTLS_PK_DSA
, vdata
, sig_value
, &pk_params
);
522 /* some generic pk functions */
524 _generate_params (int algo
, bigint_t
* resarr
, unsigned int *resarr_len
,
527 gnutls_pk_params_st params
;
531 ret
= _gnutls_pk_ops
.generate (algo
, bits
, ¶ms
);
539 if (resarr
&& resarr_len
&& *resarr_len
>= params
.params_nr
)
541 *resarr_len
= params
.params_nr
;
542 for (i
= 0; i
< params
.params_nr
; i
++)
543 resarr
[i
] = params
.params
[i
];
548 return GNUTLS_E_INVALID_REQUEST
;
556 _gnutls_rsa_generate_params (bigint_t
* resarr
, unsigned int *resarr_len
,
559 return _generate_params (GNUTLS_PK_RSA
, resarr
, resarr_len
, bits
);
563 _gnutls_dsa_generate_params (bigint_t
* resarr
, unsigned int *resarr_len
,
566 return _generate_params (GNUTLS_PK_DSA
, resarr
, resarr_len
, bits
);
570 _gnutls_pk_params_copy (gnutls_pk_params_st
* dst
, bigint_t
* params
,
576 if (params_len
== 0 || params
== NULL
)
579 return GNUTLS_E_INVALID_REQUEST
;
582 for (i
= 0; i
< params_len
; i
++)
584 dst
->params
[i
] = _gnutls_mpi_set (NULL
, params
[i
]);
585 if (dst
->params
[i
] == NULL
)
587 for (j
= 0; j
< i
; j
++)
588 _gnutls_mpi_release (&dst
->params
[j
]);
589 return GNUTLS_E_MEMORY_ERROR
;
598 gnutls_pk_params_init (gnutls_pk_params_st
* p
)
600 memset (p
, 0, sizeof (gnutls_pk_params_st
));
604 gnutls_pk_params_release (gnutls_pk_params_st
* p
)
607 for (i
= 0; i
< p
->params_nr
; i
++)
609 _gnutls_mpi_release (&p
->params
[i
]);
614 _gnutls_calc_rsa_exp (bigint_t
* params
, unsigned int params_size
)
616 bigint_t tmp
= _gnutls_mpi_alloc_like (params
[0]);
618 if (params_size
< RSA_PRIVATE_PARAMS
- 2)
621 return GNUTLS_E_INTERNAL_ERROR
;
627 return GNUTLS_E_MEMORY_ERROR
;
630 /* [6] = d % p-1, [7] = d % q-1 */
631 _gnutls_mpi_sub_ui (tmp
, params
[3], 1);
632 params
[6] = _gnutls_mpi_mod (params
[2] /*d */ , tmp
);
634 _gnutls_mpi_sub_ui (tmp
, params
[4], 1);
635 params
[7] = _gnutls_mpi_mod (params
[2] /*d */ , tmp
);
637 _gnutls_mpi_release (&tmp
);
639 if (params
[7] == NULL
|| params
[6] == NULL
)
642 return GNUTLS_E_MEMORY_ERROR
;
649 _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk
, bigint_t
* params
,
651 gnutls_digest_algorithm_t
* dig
,
656 if (pk
== GNUTLS_PK_DSA
)
662 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t
*) dig
,
663 NULL
, pk
, params
, params_size
);