2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 /* This file contains the functions needed for RSA/DSA public key
26 * encryption and signatures.
29 #include <gnutls_int.h>
30 #include <gnutls_mpi.h>
31 #include <gnutls_pk.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_datum.h>
34 #include <gnutls_global.h>
35 #include <gnutls_num.h>
37 #include <x509/x509_int.h>
38 #include <x509/common.h>
41 /* Do PKCS-1 RSA encryption.
42 * params is modulus, public exp.
45 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t
* ciphertext
,
46 const gnutls_datum_t
* plaintext
,
47 bigint_t
* params
, unsigned params_len
,
55 gnutls_pk_params_st pk_params
;
56 gnutls_datum_t to_encrypt
, encrypted
;
58 for (i
= 0; i
< params_len
; i
++)
59 pk_params
.params
[i
] = params
[i
];
60 pk_params
.params_nr
= params_len
;
62 mod_bits
= _gnutls_mpi_get_nbits (params
[0]);
64 if (mod_bits
% 8 != 0)
67 if (plaintext
->size
> k
- 11)
70 return GNUTLS_E_PK_ENCRYPTION_FAILED
;
73 edata
= gnutls_malloc (k
);
77 return GNUTLS_E_MEMORY_ERROR
;
80 /* EB = 00||BT||PS||00||D
81 * (use block type 'btype')
86 psize
= k
- 3 - plaintext
->size
;
92 /* using public key */
93 if (params_len
< RSA_PUBLIC_PARAMS
)
97 return GNUTLS_E_INTERNAL_ERROR
;
100 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, ps
, psize
);
107 for (i
= 0; i
< psize
; i
++)
110 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, &ps
[i
], 1);
120 /* using private key */
122 if (params_len
< RSA_PRIVATE_PARAMS
)
126 return GNUTLS_E_INTERNAL_ERROR
;
129 for (i
= 0; i
< psize
; i
++)
135 return GNUTLS_E_INTERNAL_ERROR
;
139 memcpy (&ps
[psize
+ 1], plaintext
->data
, plaintext
->size
);
141 to_encrypt
.data
= edata
;
144 if (btype
== 2) /* encrypt */
146 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, &pk_params
);
149 _gnutls_pk_sign (GNUTLS_PK_RSA
, &encrypted
, &to_encrypt
, &pk_params
);
159 psize
= encrypted
.size
;
169 * no need to do anything else
171 ciphertext
->data
= encrypted
.data
;
172 ciphertext
->size
= encrypted
.size
;
176 { /* psize > k !!! */
177 /* This is an impossible situation */
179 _gnutls_free_datum (&encrypted
);
180 return GNUTLS_E_INTERNAL_ERROR
;
183 ciphertext
->data
= gnutls_malloc (psize
);
184 if (ciphertext
->data
== NULL
)
187 _gnutls_free_datum (&encrypted
);
188 return GNUTLS_E_MEMORY_ERROR
;
191 memcpy (&ciphertext
->data
[pad
], encrypted
.data
, encrypted
.size
);
192 for (i
= 0; i
< pad
; i
++)
193 ciphertext
->data
[i
] = 0;
195 ciphertext
->size
= k
;
197 _gnutls_free_datum (&encrypted
);
203 /* Do PKCS-1 RSA decryption.
204 * params is modulus, public exp., private key
205 * Can decrypt block type 1 and type 2 packets.
208 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t
* plaintext
,
209 const gnutls_datum_t
* ciphertext
,
210 bigint_t
* params
, unsigned params_len
,
215 size_t esize
, mod_bits
;
216 gnutls_pk_params_st pk_params
;
218 for (i
= 0; i
< params_len
; i
++)
219 pk_params
.params
[i
] = params
[i
];
220 pk_params
.params_nr
= params_len
;
222 mod_bits
= _gnutls_mpi_get_nbits (params
[0]);
224 if (mod_bits
% 8 != 0)
227 esize
= ciphertext
->size
;
232 return GNUTLS_E_PK_DECRYPTION_FAILED
;
235 /* we can use btype to see if the private key is
241 _gnutls_pk_decrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, &pk_params
);
246 _gnutls_pk_encrypt (GNUTLS_PK_RSA
, plaintext
, ciphertext
, &pk_params
);
255 /* EB = 00||BT||PS||00||D
256 * (use block type 'btype')
258 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
259 * avoid attacks similar to the one described by Bleichenbacher in:
260 * "Chosen Ciphertext Attacks against Protocols Based on RSA
261 * Encryption Standard PKCS #1".
263 if (plaintext
->data
[0] != 0 || plaintext
->data
[1] != btype
)
266 return GNUTLS_E_DECRYPTION_FAILED
;
269 ret
= GNUTLS_E_DECRYPTION_FAILED
;
273 for (i
= 2; i
< plaintext
->size
; i
++)
275 if (plaintext
->data
[i
] == 0)
283 for (i
= 2; i
< plaintext
->size
; i
++)
285 if (plaintext
->data
[i
] == 0 && i
> 2)
290 if (plaintext
->data
[i
] != 0xff)
292 _gnutls_handshake_log ("PKCS #1 padding error");
293 _gnutls_free_datum (plaintext
);
294 /* PKCS #1 padding error. Don't use
295 GNUTLS_E_PKCS1_WRONG_PAD here. */
302 _gnutls_free_datum (plaintext
);
310 _gnutls_free_datum (plaintext
);
311 return GNUTLS_E_DECRYPTION_FAILED
;
314 memmove (plaintext
->data
, &plaintext
->data
[i
], esize
- i
);
315 plaintext
->size
= esize
- i
;
322 _gnutls_rsa_verify (const gnutls_datum_t
* vdata
,
323 const gnutls_datum_t
* ciphertext
, bigint_t
* params
,
324 int params_len
, int btype
)
327 gnutls_datum_t plain
;
330 /* decrypt signature */
332 _gnutls_pkcs1_rsa_decrypt (&plain
, ciphertext
, params
, params_len
,
339 if (plain
.size
!= vdata
->size
)
342 _gnutls_free_datum (&plain
);
343 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
346 if (memcmp (plain
.data
, vdata
->data
, plain
.size
) != 0)
349 _gnutls_free_datum (&plain
);
350 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
353 _gnutls_free_datum (&plain
);
358 /* encodes the Dss-Sig-Value structure
361 _gnutls_encode_ber_rs (gnutls_datum_t
* sig_value
, bigint_t r
, bigint_t s
)
367 asn1_create_element (_gnutls_get_gnutls_asn (),
368 "GNUTLS.DSASignatureValue",
369 &sig
)) != ASN1_SUCCESS
)
372 return _gnutls_asn2err (result
);
375 result
= _gnutls_x509_write_int (sig
, "r", r
, 1);
379 asn1_delete_structure (&sig
);
383 result
= _gnutls_x509_write_int (sig
, "s", s
, 1);
387 asn1_delete_structure (&sig
);
391 result
= _gnutls_x509_der_encode (sig
, "", sig_value
, 0);
393 asn1_delete_structure (&sig
);
405 /* Do DSA signature calculation. params is p, q, g, y, x in that order.
408 _gnutls_dsa_sign (gnutls_datum_t
* signature
,
409 const gnutls_datum_t
* hash
, bigint_t
* params
,
410 unsigned int params_len
)
415 gnutls_pk_params_st pk_params
;
417 for (i
= 0; i
< params_len
; i
++)
418 pk_params
.params
[i
] = params
[i
];
419 pk_params
.params_nr
= params_len
;
423 { /* SHA1 or better only */
425 return GNUTLS_E_PK_SIGN_FAILED
;
428 ret
= _gnutls_pk_sign (GNUTLS_PK_DSA
, signature
, hash
, &pk_params
);
429 /* rs[0], rs[1] now hold r,s */
440 /* decodes the Dss-Sig-Value structure
443 _gnutls_decode_ber_rs (const gnutls_datum_t
* sig_value
, bigint_t
* r
,
450 asn1_create_element (_gnutls_get_gnutls_asn (),
451 "GNUTLS.DSASignatureValue",
452 &sig
)) != ASN1_SUCCESS
)
455 return _gnutls_asn2err (result
);
458 result
= asn1_der_decoding (&sig
, sig_value
->data
, sig_value
->size
, NULL
);
459 if (result
!= ASN1_SUCCESS
)
462 asn1_delete_structure (&sig
);
463 return _gnutls_asn2err (result
);
466 result
= _gnutls_x509_read_int (sig
, "r", r
);
470 asn1_delete_structure (&sig
);
474 result
= _gnutls_x509_read_int (sig
, "s", s
);
478 _gnutls_mpi_release (s
);
479 asn1_delete_structure (&sig
);
483 asn1_delete_structure (&sig
);
488 /* params is p, q, g, y in that order
491 _gnutls_dsa_verify (const gnutls_datum_t
* vdata
,
492 const gnutls_datum_t
* sig_value
, bigint_t
* params
,
497 gnutls_pk_params_st pk_params
;
499 for (i
= 0; i
< params_len
; i
++)
500 pk_params
.params
[i
] = params
[i
];
501 pk_params
.params_nr
= params_len
;
503 if (vdata
->size
> 20)
504 { /* SHA1 or better only */
506 return GNUTLS_E_PK_SIG_VERIFY_FAILED
;
509 /* decrypt signature */
510 ret
= _gnutls_pk_verify (GNUTLS_PK_DSA
, vdata
, sig_value
, &pk_params
);
521 /* some generic pk functions */
523 _generate_params (int algo
, bigint_t
* resarr
, unsigned int *resarr_len
,
526 gnutls_pk_params_st params
;
530 ret
= _gnutls_pk_ops
.generate (algo
, bits
, ¶ms
);
538 if (resarr
&& resarr_len
&& *resarr_len
>= params
.params_nr
)
540 *resarr_len
= params
.params_nr
;
541 for (i
= 0; i
< params
.params_nr
; i
++)
542 resarr
[i
] = params
.params
[i
];
547 return GNUTLS_E_INVALID_REQUEST
;
555 _gnutls_rsa_generate_params (bigint_t
* resarr
, unsigned int *resarr_len
,
558 return _generate_params (GNUTLS_PK_RSA
, resarr
, resarr_len
, bits
);
562 _gnutls_dsa_generate_params (bigint_t
* resarr
, unsigned int *resarr_len
,
565 return _generate_params (GNUTLS_PK_DSA
, resarr
, resarr_len
, bits
);
569 _gnutls_pk_params_copy (gnutls_pk_params_st
* dst
, bigint_t
* params
,
575 if (params_len
== 0 || params
== NULL
)
578 return GNUTLS_E_INVALID_REQUEST
;
581 for (i
= 0; i
< params_len
; i
++)
583 dst
->params
[i
] = _gnutls_mpi_set (NULL
, params
[i
]);
584 if (dst
->params
[i
] == NULL
)
586 for (j
= 0; j
< i
; j
++)
587 _gnutls_mpi_release (&dst
->params
[j
]);
588 return GNUTLS_E_MEMORY_ERROR
;
597 gnutls_pk_params_init (gnutls_pk_params_st
* p
)
599 memset (p
, 0, sizeof (gnutls_pk_params_st
));
603 gnutls_pk_params_release (gnutls_pk_params_st
* p
)
606 for (i
= 0; i
< p
->params_nr
; i
++)
608 _gnutls_mpi_release (&p
->params
[i
]);