2 * Copyright (C) 2005-2009 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include "gmp_rsa_private_key.h"
23 #include "gmp_rsa_public_key.h"
27 #include <asn1/asn1.h>
28 #include <asn1/asn1_parser.h>
30 #ifdef HAVE_MPZ_POWM_SEC
32 # define mpz_powm mpz_powm_sec
36 * Public exponent to use for key generation.
38 #define PUBLIC_EXPONENT 0x10001
40 typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t
;
43 * Private data of a gmp_rsa_private_key_t object.
45 struct private_gmp_rsa_private_key_t
{
47 * Public interface for this signer.
49 gmp_rsa_private_key_t
public;
87 * Private coefficient.
103 * Convert a MP integer into a chunk_t
105 chunk_t
gmp_mpz_to_chunk(const mpz_t value
)
109 n
.len
= 1 + mpz_sizeinbase(value
, 2) / BITS_PER_BYTE
;
110 n
.ptr
= mpz_export(NULL
, NULL
, 1, n
.len
, 1, 0, value
);
112 { /* if we have zero in "value", gmp returns NULL */
119 * Auxiliary function overwriting private key material with zero bytes
121 static void mpz_clear_sensitive(mpz_t z
)
123 size_t len
= mpz_size(z
) * GMP_LIMB_BITS
/ BITS_PER_BYTE
;
124 u_int8_t
*random
= alloca(len
);
126 memset(random
, 0, len
);
127 /* overwrite mpz_t with zero bytes before clearing it */
128 mpz_import(z
, len
, 1, 1, 1, 0, random
);
133 * Create a mpz prime of at least prime_size
135 static status_t
compute_prime(private_gmp_rsa_private_key_t
*this,
136 size_t prime_size
, mpz_t
*prime
)
139 chunk_t random_bytes
;
141 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_TRUE
);
144 DBG1(DBG_LIB
, "no RNG of quality %N found", rng_quality_names
,
152 if (!rng
->allocate_bytes(rng
, prime_size
, &random_bytes
))
154 DBG1(DBG_LIB
, "failed to allocate random prime");
158 /* make sure the two most significant bits are set */
159 random_bytes
.ptr
[0] = random_bytes
.ptr
[0] | 0xC0;
161 mpz_import(*prime
, random_bytes
.len
, 1, 1, 1, 0, random_bytes
.ptr
);
162 mpz_nextprime (*prime
, *prime
);
163 chunk_clear(&random_bytes
);
165 /* check if it isn't too large */
166 while (((mpz_sizeinbase(*prime
, 2) + 7) / 8) > prime_size
);
173 * PKCS#1 RSADP function
175 static chunk_t
rsadp(private_gmp_rsa_private_key_t
*this, chunk_t data
)
183 mpz_import(t1
, data
.len
, 1, 1, 1, 0, data
.ptr
);
185 mpz_powm(t2
, t1
, this->exp1
, this->p
); /* m1 = c^dP mod p */
186 mpz_powm(t1
, t1
, this->exp2
, this->q
); /* m2 = c^dQ mod Q */
187 mpz_sub(t2
, t2
, t1
); /* h = qInv (m1 - m2) mod p */
188 mpz_mod(t2
, t2
, this->p
);
189 mpz_mul(t2
, t2
, this->coeff
);
190 mpz_mod(t2
, t2
, this->p
);
192 mpz_mul(t2
, t2
, this->q
); /* m = m2 + h q */
195 decrypted
.len
= this->k
;
196 decrypted
.ptr
= mpz_export(NULL
, NULL
, 1, decrypted
.len
, 1, 0, t1
);
197 if (decrypted
.ptr
== NULL
)
202 mpz_clear_sensitive(t1
);
203 mpz_clear_sensitive(t2
);
209 * PKCS#1 RSASP1 function
211 static chunk_t
rsasp1(private_gmp_rsa_private_key_t
*this, chunk_t data
)
213 return rsadp(this, data
);
217 * Build a signature using the PKCS#1 EMSA scheme
219 static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t
*this,
220 hash_algorithm_t hash_algorithm
,
221 chunk_t data
, chunk_t
*signature
)
223 chunk_t digestInfo
= chunk_empty
;
226 if (hash_algorithm
!= HASH_UNKNOWN
)
230 int hash_oid
= hasher_algorithm_to_oid(hash_algorithm
);
232 if (hash_oid
== OID_UNKNOWN
)
237 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, hash_algorithm
);
238 if (!hasher
|| !hasher
->allocate_hash(hasher
, data
, &hash
))
243 hasher
->destroy(hasher
);
245 /* build DER-encoded digestInfo */
246 digestInfo
= asn1_wrap(ASN1_SEQUENCE
, "mm",
247 asn1_algorithmIdentifier(hash_oid
),
248 asn1_simple_object(ASN1_OCTET_STRING
, hash
)
254 if (data
.len
> this->k
- 3)
256 free(digestInfo
.ptr
);
257 DBG1(DBG_LIB
, "unable to sign %d bytes using a %dbit key", data
.len
,
258 mpz_sizeinbase(this->n
, 2));
262 /* build chunk to rsa-decrypt:
263 * EM = 0x00 || 0x01 || PS || 0x00 || T.
264 * PS = 0xFF padding, with length to fill em
268 em
.ptr
= malloc(em
.len
);
270 /* fill em with padding */
271 memset(em
.ptr
, 0xFF, em
.len
);
272 /* set magic bytes */
275 *(em
.ptr
+ em
.len
- data
.len
- 1) = 0x00;
276 /* set DER-encoded hash */
277 memcpy(em
.ptr
+ em
.len
- data
.len
, data
.ptr
, data
.len
);
279 /* build signature */
280 *signature
= rsasp1(this, em
);
282 free(digestInfo
.ptr
);
288 METHOD(private_key_t
, get_type
, key_type_t
,
289 private_gmp_rsa_private_key_t
*this)
294 METHOD(private_key_t
, sign
, bool,
295 private_gmp_rsa_private_key_t
*this, signature_scheme_t scheme
,
296 chunk_t data
, chunk_t
*signature
)
300 case SIGN_RSA_EMSA_PKCS1_NULL
:
301 return build_emsa_pkcs1_signature(this, HASH_UNKNOWN
, data
, signature
);
302 case SIGN_RSA_EMSA_PKCS1_SHA1
:
303 return build_emsa_pkcs1_signature(this, HASH_SHA1
, data
, signature
);
304 case SIGN_RSA_EMSA_PKCS1_SHA224
:
305 return build_emsa_pkcs1_signature(this, HASH_SHA224
, data
, signature
);
306 case SIGN_RSA_EMSA_PKCS1_SHA256
:
307 return build_emsa_pkcs1_signature(this, HASH_SHA256
, data
, signature
);
308 case SIGN_RSA_EMSA_PKCS1_SHA384
:
309 return build_emsa_pkcs1_signature(this, HASH_SHA384
, data
, signature
);
310 case SIGN_RSA_EMSA_PKCS1_SHA512
:
311 return build_emsa_pkcs1_signature(this, HASH_SHA512
, data
, signature
);
312 case SIGN_RSA_EMSA_PKCS1_MD5
:
313 return build_emsa_pkcs1_signature(this, HASH_MD5
, data
, signature
);
315 DBG1(DBG_LIB
, "signature scheme %N not supported in RSA",
316 signature_scheme_names
, scheme
);
321 METHOD(private_key_t
, decrypt
, bool,
322 private_gmp_rsa_private_key_t
*this, encryption_scheme_t scheme
,
323 chunk_t crypto
, chunk_t
*plain
)
325 chunk_t em
, stripped
;
326 bool success
= FALSE
;
328 if (scheme
!= ENCRYPT_RSA_PKCS1
)
330 DBG1(DBG_LIB
, "encryption scheme %N not supported",
331 encryption_scheme_names
, scheme
);
334 /* rsa decryption using PKCS#1 RSADP */
335 stripped
= em
= rsadp(this, crypto
);
337 /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
339 /* check for hex pattern 00 02 in decrypted message */
340 if ((*stripped
.ptr
++ != 0x00) || (*(stripped
.ptr
++) != 0x02))
342 DBG1(DBG_LIB
, "incorrect padding - probably wrong rsa key");
347 /* the plaintext data starts after first 0x00 byte */
348 while (stripped
.len
-- > 0 && *stripped
.ptr
++ != 0x00)
350 if (stripped
.len
== 0)
352 DBG1(DBG_LIB
, "no plaintext data");
356 *plain
= chunk_clone(stripped
);
364 METHOD(private_key_t
, get_keysize
, int,
365 private_gmp_rsa_private_key_t
*this)
367 return mpz_sizeinbase(this->n
, 2);
370 METHOD(private_key_t
, get_public_key
, public_key_t
*,
371 private_gmp_rsa_private_key_t
*this)
374 public_key_t
*public;
376 n
= gmp_mpz_to_chunk(this->n
);
377 e
= gmp_mpz_to_chunk(this->e
);
379 public = lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
380 BUILD_RSA_MODULUS
, n
, BUILD_RSA_PUB_EXP
, e
, BUILD_END
);
387 METHOD(private_key_t
, get_encoding
, bool,
388 private_gmp_rsa_private_key_t
*this, cred_encoding_type_t type
,
391 chunk_t n
, e
, d
, p
, q
, exp1
, exp2
, coeff
;
394 n
= gmp_mpz_to_chunk(this->n
);
395 e
= gmp_mpz_to_chunk(this->e
);
396 d
= gmp_mpz_to_chunk(this->d
);
397 p
= gmp_mpz_to_chunk(this->p
);
398 q
= gmp_mpz_to_chunk(this->q
);
399 exp1
= gmp_mpz_to_chunk(this->exp1
);
400 exp2
= gmp_mpz_to_chunk(this->exp2
);
401 coeff
= gmp_mpz_to_chunk(this->coeff
);
403 success
= lib
->encoding
->encode(lib
->encoding
,
404 type
, NULL
, encoding
, CRED_PART_RSA_MODULUS
, n
,
405 CRED_PART_RSA_PUB_EXP
, e
, CRED_PART_RSA_PRIV_EXP
, d
,
406 CRED_PART_RSA_PRIME1
, p
, CRED_PART_RSA_PRIME2
, q
,
407 CRED_PART_RSA_EXP1
, exp1
, CRED_PART_RSA_EXP2
, exp2
,
408 CRED_PART_RSA_COEFF
, coeff
, CRED_PART_END
);
421 METHOD(private_key_t
, get_fingerprint
, bool,
422 private_gmp_rsa_private_key_t
*this, cred_encoding_type_t type
, chunk_t
*fp
)
427 if (lib
->encoding
->get_cache(lib
->encoding
, type
, this, fp
))
431 n
= gmp_mpz_to_chunk(this->n
);
432 e
= gmp_mpz_to_chunk(this->e
);
434 success
= lib
->encoding
->encode(lib
->encoding
, type
, this, fp
,
435 CRED_PART_RSA_MODULUS
, n
, CRED_PART_RSA_PUB_EXP
, e
, CRED_PART_END
);
442 METHOD(private_key_t
, get_ref
, private_key_t
*,
443 private_gmp_rsa_private_key_t
*this)
446 return &this->public.key
;
449 METHOD(private_key_t
, destroy
, void,
450 private_gmp_rsa_private_key_t
*this)
452 if (ref_put(&this->ref
))
454 mpz_clear_sensitive(this->n
);
455 mpz_clear_sensitive(this->e
);
456 mpz_clear_sensitive(this->p
);
457 mpz_clear_sensitive(this->q
);
458 mpz_clear_sensitive(this->d
);
459 mpz_clear_sensitive(this->exp1
);
460 mpz_clear_sensitive(this->exp2
);
461 mpz_clear_sensitive(this->coeff
);
462 lib
->encoding
->clear_cache(lib
->encoding
, this);
468 * Check the loaded key if it is valid and usable
470 static status_t
check(private_gmp_rsa_private_key_t
*this)
473 status_t status
= SUCCESS
;
475 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
476 * We actually require more (for security).
478 if (this->k
< 512 / BITS_PER_BYTE
)
480 DBG1(DBG_LIB
, "key shorter than 512 bits");
484 /* we picked a max modulus size to simplify buffer allocation */
485 if (this->k
> 8192 / BITS_PER_BYTE
)
487 DBG1(DBG_LIB
, "key larger than 8192 bits");
495 /* check that n == p * q */
496 mpz_mul(u
, this->p
, this->q
);
497 if (mpz_cmp(u
, this->n
) != 0)
502 /* check that e divides neither p-1 nor q-1 */
503 mpz_sub_ui(t
, this->p
, 1);
504 mpz_mod(t
, t
, this->e
);
505 if (mpz_cmp_ui(t
, 0) == 0)
510 mpz_sub_ui(t
, this->q
, 1);
511 mpz_mod(t
, t
, this->e
);
512 if (mpz_cmp_ui(t
, 0) == 0)
517 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
518 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
519 mpz_sub_ui(q1
, this->q
, 1);
520 mpz_sub_ui(u
, this->p
, 1);
521 mpz_gcd(t
, u
, q1
); /* t := gcd(p-1, q-1) */
522 mpz_mul(u
, u
, q1
); /* u := (p-1) * (q-1) */
523 mpz_divexact(u
, u
, t
); /* u := lcm(p-1, q-1) */
525 mpz_mul(t
, this->d
, this->e
);
527 if (mpz_cmp_ui(t
, 1) != 0)
532 /* check that exp1 is d mod (p-1) */
533 mpz_sub_ui(u
, this->p
, 1);
534 mpz_mod(t
, this->d
, u
);
535 if (mpz_cmp(t
, this->exp1
) != 0)
540 /* check that exp2 is d mod (q-1) */
541 mpz_sub_ui(u
, this->q
, 1);
542 mpz_mod(t
, this->d
, u
);
543 if (mpz_cmp(t
, this->exp2
) != 0)
548 /* check that coeff is (q^-1) mod p */
549 mpz_mul(t
, this->coeff
, this->q
);
550 mpz_mod(t
, t
, this->p
);
551 if (mpz_cmp_ui(t
, 1) != 0)
556 mpz_clear_sensitive(t
);
557 mpz_clear_sensitive(u
);
558 mpz_clear_sensitive(q1
);
559 if (status
!= SUCCESS
)
561 DBG1(DBG_LIB
, "key integrity tests failed");
567 * Internal generic constructor
569 static private_gmp_rsa_private_key_t
*gmp_rsa_private_key_create_empty(void)
571 private_gmp_rsa_private_key_t
*this;
576 .get_type
= _get_type
,
579 .get_keysize
= _get_keysize
,
580 .get_public_key
= _get_public_key
,
581 .equals
= private_key_equals
,
582 .belongs_to
= private_key_belongs_to
,
583 .get_fingerprint
= _get_fingerprint
,
584 .has_fingerprint
= private_key_has_fingerprint
,
585 .get_encoding
= _get_encoding
,
598 gmp_rsa_private_key_t
*gmp_rsa_private_key_gen(key_type_t type
, va_list args
)
600 mpz_t p
, q
, n
, e
, d
, exp1
, exp2
, coeff
, m
, q1
, t
;
601 private_gmp_rsa_private_key_t
*this;
606 switch (va_arg(args
, builder_part_t
))
609 key_size
= va_arg(args
, u_int
);
623 this = gmp_rsa_private_key_create_empty();
624 key_size
= key_size
/ BITS_PER_BYTE
;
626 /* Get values of primes p and q */
627 if (compute_prime(this, key_size
/2, &p
) != SUCCESS
)
632 if (compute_prime(this, key_size
/2, &q
) != SUCCESS
)
646 /* Swapping Primes so p is larger then q */
647 if (mpz_cmp(p
, q
) < 0)
652 mpz_mul(n
, p
, q
); /* n = p*q */
653 mpz_init_set_ui(e
, PUBLIC_EXPONENT
); /* assign public exponent */
654 mpz_init_set(m
, p
); /* m = p */
655 mpz_sub_ui(m
, m
, 1); /* m = m -1 */
656 mpz_init_set(q1
, q
); /* q1 = q */
657 mpz_sub_ui(q1
, q1
, 1); /* q1 = q1 -1 */
658 mpz_gcd(t
, m
, q1
); /* t = gcd(p-1, q-1) */
659 mpz_mul(m
, m
, q1
); /* m = (p-1)*(q-1) */
660 mpz_divexact(m
, m
, t
); /* m = m / t */
661 mpz_gcd(t
, m
, e
); /* t = gcd(m, e) */
663 mpz_invert(d
, e
, m
); /* e has an inverse mod m */
664 if (mpz_cmp_ui(d
, 0) < 0) /* make sure d is positive */
668 mpz_sub_ui(t
, p
, 1); /* t = p-1 */
669 mpz_mod(exp1
, d
, t
); /* exp1 = d mod p-1 */
670 mpz_sub_ui(t
, q
, 1); /* t = q-1 */
671 mpz_mod(exp2
, d
, t
); /* exp2 = d mod q-1 */
673 mpz_invert(coeff
, q
, p
); /* coeff = q^-1 mod p */
674 if (mpz_cmp_ui(coeff
, 0) < 0) /* make coeff d is positive */
676 mpz_add(coeff
, coeff
, p
);
679 mpz_clear_sensitive(q1
);
680 mpz_clear_sensitive(m
);
681 mpz_clear_sensitive(t
);
689 *(this->exp1
) = *exp1
;
690 *(this->exp2
) = *exp2
;
691 *(this->coeff
) = *coeff
;
693 /* set key size in bytes */
696 return &this->public;
702 gmp_rsa_private_key_t
*gmp_rsa_private_key_load(key_type_t type
, va_list args
)
704 chunk_t n
, e
, d
, p
, q
, exp1
, exp2
, coeff
;
705 private_gmp_rsa_private_key_t
*this;
707 n
= e
= d
= p
= q
= exp1
= exp2
= coeff
= chunk_empty
;
710 switch (va_arg(args
, builder_part_t
))
712 case BUILD_RSA_MODULUS
:
713 n
= va_arg(args
, chunk_t
);
715 case BUILD_RSA_PUB_EXP
:
716 e
= va_arg(args
, chunk_t
);
718 case BUILD_RSA_PRIV_EXP
:
719 d
= va_arg(args
, chunk_t
);
721 case BUILD_RSA_PRIME1
:
722 p
= va_arg(args
, chunk_t
);
724 case BUILD_RSA_PRIME2
:
725 q
= va_arg(args
, chunk_t
);
728 exp1
= va_arg(args
, chunk_t
);
731 exp2
= va_arg(args
, chunk_t
);
733 case BUILD_RSA_COEFF
:
734 coeff
= va_arg(args
, chunk_t
);
744 this = gmp_rsa_private_key_create_empty();
751 mpz_init(this->exp1
);
752 mpz_init(this->exp2
);
753 mpz_init(this->coeff
);
755 mpz_import(this->n
, n
.len
, 1, 1, 1, 0, n
.ptr
);
756 mpz_import(this->e
, e
.len
, 1, 1, 1, 0, e
.ptr
);
757 mpz_import(this->d
, d
.len
, 1, 1, 1, 0, d
.ptr
);
758 mpz_import(this->p
, p
.len
, 1, 1, 1, 0, p
.ptr
);
759 mpz_import(this->q
, q
.len
, 1, 1, 1, 0, q
.ptr
);
760 mpz_import(this->coeff
, coeff
.len
, 1, 1, 1, 0, coeff
.ptr
);
762 { /* exp1 missing in key, recalculate: exp1 = d mod (p-1) */
763 mpz_sub_ui(this->exp1
, this->p
, 1);
764 mpz_mod(this->exp1
, this->d
, this->exp1
);
768 mpz_import(this->exp1
, exp1
.len
, 1, 1, 1, 0, exp1
.ptr
);
771 { /* exp2 missing in key, recalculate: exp2 = d mod (q-1) */
772 mpz_sub_ui(this->exp2
, this->q
, 1);
773 mpz_mod(this->exp2
, this->d
, this->exp2
);
777 mpz_import(this->exp2
, exp2
.len
, 1, 1, 1, 0, exp2
.ptr
);
779 this->k
= (mpz_sizeinbase(this->n
, 2) + 7) / BITS_PER_BYTE
;
780 if (check(this) != SUCCESS
)
785 return &this->public;