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 3 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 License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 /* This file contains the functions needed for RSA/DSA public key
25 * encryption and signatures.
28 #include <gnutls_int.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_pk.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_datum.h>
33 #include <gnutls_global.h>
34 #include <gnutls_num.h>
36 #include <x509/x509_int.h>
37 #include <x509/common.h>
40 /* Do PKCS-1 RSA encryption.
41 * params is modulus, public exp.
44 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t
* ciphertext
,
45 const gnutls_datum_t
* plaintext
,
46 gnutls_pk_params_st
* params
,
54 gnutls_datum_t to_encrypt
, encrypted
;
56 mod_bits
= _gnutls_mpi_get_nbits (params
->params
[0]);
58 if (mod_bits
% 8 != 0)
61 if (plaintext
->size
> k
- 11)
64 return GNUTLS_E_PK_ENCRYPTION_FAILED
;
67 edata
= gnutls_malloc (k
);
71 return GNUTLS_E_MEMORY_ERROR
;
74 /* EB = 00||BT||PS||00||D
75 * (use block type 'btype')
80 psize
= k
- 3 - plaintext
->size
;
86 /* using public key */
87 if (params
->params_nr
< RSA_PUBLIC_PARAMS
)
91 return GNUTLS_E_INTERNAL_ERROR
;
94 ret
= gnutls_rnd (GNUTLS_RND_RANDOM
, ps
, psize
);
101 for (i
= 0; i
< psize
; i
++)
104 ret
= gnutls_rnd (GNUTLS_RND_RANDOM
, &ps
[i
], 1);
114 /* using private key */
116 if (params
->params_nr
< RSA_PRIVATE_PARAMS
)
120 return GNUTLS_E_INTERNAL_ERROR
;
123 for (i
= 0; i
< psize
; i
++)
129 return GNUTLS_E_INTERNAL_ERROR
;
133 memcpy (&ps
[psize
+ 1], plaintext
->data
, plaintext
->size
);
135 to_encrypt
.data
= edata
;
138 if (btype
== 2) /* encrypt */
140 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, params
);
143 _gnutls_pk_sign (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, params
);
153 psize
= encrypted
.size
;
163 * no need to do anything else
165 ciphertext
->data
= encrypted
.data
;
166 ciphertext
->size
= encrypted
.size
;
170 { /* psize > k !!! */
171 /* This is an impossible situation */
173 _gnutls_free_datum (&encrypted
);
174 return GNUTLS_E_INTERNAL_ERROR
;
177 ciphertext
->data
= gnutls_malloc (psize
);
178 if (ciphertext
->data
== NULL
)
181 ret
= GNUTLS_E_MEMORY_ERROR
;
185 memcpy (&ciphertext
->data
[pad
], encrypted
.data
, encrypted
.size
);
186 for (i
= 0; i
< pad
; i
++)
187 ciphertext
->data
[i
] = 0;
189 ciphertext
->size
= k
;
194 _gnutls_free_datum (&encrypted
);
200 /* Do PKCS-1 RSA decryption.
201 * params is modulus, public exp., private key
202 * Can decrypt block type 1 and type 2 packets.
205 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t
* plaintext
,
206 const gnutls_datum_t
* ciphertext
,
207 gnutls_pk_params_st
* params
,
212 size_t esize
, mod_bits
;
214 mod_bits
= _gnutls_mpi_get_nbits (params
->params
[0]);
216 if (mod_bits
% 8 != 0)
219 esize
= ciphertext
->size
;
224 return GNUTLS_E_PK_DECRYPTION_FAILED
;
227 /* we can use btype to see if the private key is
233 _gnutls_pk_decrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, params
);
238 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, params
);
247 /* EB = 00||BT||PS||00||D
248 * (use block type 'btype')
250 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
251 * avoid attacks similar to the one described by Bleichenbacher in:
252 * "Chosen Ciphertext Attacks against Protocols Based on RSA
253 * Encryption Standard PKCS #1".
255 if (plaintext
->data
[0] != 0 || plaintext
->data
[1] != btype
)
258 return GNUTLS_E_DECRYPTION_FAILED
;
261 ret
= GNUTLS_E_DECRYPTION_FAILED
;
265 for (i
= 2; i
< plaintext
->size
; i
++)
267 if (plaintext
->data
[i
] == 0)
275 for (i
= 2; i
< plaintext
->size
; i
++)
277 if (plaintext
->data
[i
] == 0 && i
> 2)
282 if (plaintext
->data
[i
] != 0xff)
284 _gnutls_handshake_log ("PKCS #1 padding error");
285 _gnutls_free_datum (plaintext
);
286 /* PKCS #1 padding error. Don't use
287 GNUTLS_E_PKCS1_WRONG_PAD here. */
294 _gnutls_free_datum (plaintext
);
301 _gnutls_free_datum (plaintext
);
302 return GNUTLS_E_DECRYPTION_FAILED
;
306 memmove (plaintext
->data
, &plaintext
->data
[i
], esize
- i
);
307 plaintext
->size
= esize
- i
;
314 _gnutls_rsa_verify (const gnutls_datum_t
* vdata
,
315 const gnutls_datum_t
* ciphertext
,
316 gnutls_pk_params_st
* params
,
320 gnutls_datum_t plain
;
323 /* decrypt signature */
325 _gnutls_pkcs1_rsa_decrypt (&plain
, ciphertext
, params
,
332 if (plain
.size
!= vdata
->size
)
335 _gnutls_free_datum (&plain
);
336 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
339 if (memcmp (plain
.data
, vdata
->data
, plain
.size
) != 0)
342 _gnutls_free_datum (&plain
);
343 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
346 _gnutls_free_datum (&plain
);
351 /* encodes the Dss-Sig-Value structure
354 _gnutls_encode_ber_rs (gnutls_datum_t
* sig_value
, bigint_t r
, bigint_t s
)
360 asn1_create_element (_gnutls_get_gnutls_asn (),
361 "GNUTLS.DSASignatureValue",
362 &sig
)) != ASN1_SUCCESS
)
365 return _gnutls_asn2err (result
);
368 result
= _gnutls_x509_write_int (sig
, "r", r
, 1);
372 asn1_delete_structure (&sig
);
376 result
= _gnutls_x509_write_int (sig
, "s", s
, 1);
380 asn1_delete_structure (&sig
);
384 result
= _gnutls_x509_der_encode (sig
, "", sig_value
, 0);
386 asn1_delete_structure (&sig
);
398 /* decodes the Dss-Sig-Value structure
401 _gnutls_decode_ber_rs (const gnutls_datum_t
* sig_value
, bigint_t
* r
,
408 asn1_create_element (_gnutls_get_gnutls_asn (),
409 "GNUTLS.DSASignatureValue",
410 &sig
)) != ASN1_SUCCESS
)
413 return _gnutls_asn2err (result
);
416 result
= asn1_der_decoding (&sig
, sig_value
->data
, sig_value
->size
, NULL
);
417 if (result
!= ASN1_SUCCESS
)
420 asn1_delete_structure (&sig
);
421 return _gnutls_asn2err (result
);
424 result
= _gnutls_x509_read_int (sig
, "r", r
);
428 asn1_delete_structure (&sig
);
432 result
= _gnutls_x509_read_int (sig
, "s", s
);
436 _gnutls_mpi_release (s
);
437 asn1_delete_structure (&sig
);
441 asn1_delete_structure (&sig
);
446 /* some generic pk functions */
448 int _gnutls_pk_params_copy (gnutls_pk_params_st
* dst
, const gnutls_pk_params_st
* src
)
453 if (src
== NULL
|| src
->params_nr
== 0)
456 return GNUTLS_E_INVALID_REQUEST
;
459 for (i
= 0; i
< src
->params_nr
; i
++)
461 dst
->params
[i
] = _gnutls_mpi_set (NULL
, src
->params
[i
]);
462 if (dst
->params
[i
] == NULL
)
464 for (j
= 0; j
< i
; j
++)
465 _gnutls_mpi_release (&dst
->params
[j
]);
466 return GNUTLS_E_MEMORY_ERROR
;
475 gnutls_pk_params_init (gnutls_pk_params_st
* p
)
477 memset (p
, 0, sizeof (gnutls_pk_params_st
));
481 gnutls_pk_params_release (gnutls_pk_params_st
* p
)
484 for (i
= 0; i
< p
->params_nr
; i
++)
486 _gnutls_mpi_release (&p
->params
[i
]);
492 _gnutls_calc_rsa_exp (gnutls_pk_params_st
* params
)
494 bigint_t tmp
= _gnutls_mpi_alloc_like (params
->params
[0]);
496 if (params
->params_nr
< RSA_PRIVATE_PARAMS
- 2)
499 return GNUTLS_E_INTERNAL_ERROR
;
505 return GNUTLS_E_MEMORY_ERROR
;
508 /* [6] = d % p-1, [7] = d % q-1 */
509 _gnutls_mpi_sub_ui (tmp
, params
->params
[3], 1);
510 params
->params
[6] = _gnutls_mpi_mod (params
->params
[2] /*d */ , tmp
);
512 _gnutls_mpi_sub_ui (tmp
, params
->params
[4], 1);
513 params
->params
[7] = _gnutls_mpi_mod (params
->params
[2] /*d */ , tmp
);
515 _gnutls_mpi_release (&tmp
);
517 if (params
->params
[7] == NULL
|| params
->params
[6] == NULL
)
520 return GNUTLS_E_MEMORY_ERROR
;
527 _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk
,
528 gnutls_pk_params_st
* params
,
529 gnutls_digest_algorithm_t
* dig
,
534 if (pk
== GNUTLS_PK_DSA
)
540 return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t
*) dig
,