2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains the functions needed for RSA/DSA public key
24 * encryption and signatures.
27 #include <gnutls_int.h>
28 #include <gnutls_mpi.h>
29 #include <gnutls_pk.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_datum.h>
32 #include <gnutls_global.h>
33 #include <gnutls_num.h>
35 #include <x509/x509_int.h>
36 #include <x509/common.h>
39 /* Do PKCS-1 RSA encryption.
40 * params is modulus, public exp.
43 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t
* ciphertext
,
44 const gnutls_datum_t
* plaintext
,
45 gnutls_pk_params_st
* params
,
53 gnutls_datum_t to_encrypt
, encrypted
;
55 mod_bits
= _gnutls_mpi_get_nbits (params
->params
[0]);
57 if (mod_bits
% 8 != 0)
60 if (plaintext
->size
> k
- 11)
63 return GNUTLS_E_PK_ENCRYPTION_FAILED
;
66 edata
= gnutls_malloc (k
);
70 return GNUTLS_E_MEMORY_ERROR
;
73 /* EB = 00||BT||PS||00||D
74 * (use block type 'btype')
79 psize
= k
- 3 - plaintext
->size
;
85 /* using public key */
86 if (params
->params_nr
< RSA_PUBLIC_PARAMS
)
90 return GNUTLS_E_INTERNAL_ERROR
;
93 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, ps
, psize
);
100 for (i
= 0; i
< psize
; i
++)
103 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, &ps
[i
], 1);
113 /* using private key */
115 if (params
->params_nr
< RSA_PRIVATE_PARAMS
)
119 return GNUTLS_E_INTERNAL_ERROR
;
122 for (i
= 0; i
< psize
; i
++)
128 return GNUTLS_E_INTERNAL_ERROR
;
132 memcpy (&ps
[psize
+ 1], plaintext
->data
, plaintext
->size
);
134 to_encrypt
.data
= edata
;
137 if (btype
== 2) /* encrypt */
139 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, params
);
142 _gnutls_pk_sign (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, params
);
152 psize
= encrypted
.size
;
162 * no need to do anything else
164 ciphertext
->data
= encrypted
.data
;
165 ciphertext
->size
= encrypted
.size
;
169 { /* psize > k !!! */
170 /* This is an impossible situation */
172 _gnutls_free_datum (&encrypted
);
173 return GNUTLS_E_INTERNAL_ERROR
;
176 ciphertext
->data
= gnutls_malloc (psize
);
177 if (ciphertext
->data
== NULL
)
180 ret
= GNUTLS_E_MEMORY_ERROR
;
184 memcpy (&ciphertext
->data
[pad
], encrypted
.data
, encrypted
.size
);
185 for (i
= 0; i
< pad
; i
++)
186 ciphertext
->data
[i
] = 0;
188 ciphertext
->size
= k
;
193 _gnutls_free_datum (&encrypted
);
199 /* Do PKCS-1 RSA decryption.
200 * params is modulus, public exp., private key
201 * Can decrypt block type 1 and type 2 packets.
204 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t
* plaintext
,
205 const gnutls_datum_t
* ciphertext
,
206 gnutls_pk_params_st
* params
,
211 size_t esize
, mod_bits
;
213 mod_bits
= _gnutls_mpi_get_nbits (params
->params
[0]);
215 if (mod_bits
% 8 != 0)
218 esize
= ciphertext
->size
;
223 return GNUTLS_E_PK_DECRYPTION_FAILED
;
226 /* we can use btype to see if the private key is
232 _gnutls_pk_decrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, params
);
237 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, params
);
246 /* EB = 00||BT||PS||00||D
247 * (use block type 'btype')
249 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
250 * avoid attacks similar to the one described by Bleichenbacher in:
251 * "Chosen Ciphertext Attacks against Protocols Based on RSA
252 * Encryption Standard PKCS #1".
254 if (plaintext
->data
[0] != 0 || plaintext
->data
[1] != btype
)
257 _gnutls_free_datum (plaintext
);
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_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk
,
493 gnutls_pk_params_st
* params
,
494 gnutls_digest_algorithm_t
* dig
,
499 if (pk
== GNUTLS_PK_DSA
)
505 return _gnutls_x509_verify_algorithm (dig
,