2 * @file rsa_private_key.c
4 * @brief Implementation of rsa_private_key_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 #include "rsa_public_key.h"
29 #include "rsa_private_key.h"
31 #include <asn1/asn1.h>
33 #include <utils/randomizer.h>
36 * OIDs for hash algorithms are defined in rsa_public_key.c.
38 extern u_int8_t md2_oid
[18];
39 extern u_int8_t md5_oid
[18];
40 extern u_int8_t sha1_oid
[15];
41 extern u_int8_t sha256_oid
[19];
42 extern u_int8_t sha384_oid
[19];
43 extern u_int8_t sha512_oid
[19];
47 * Public exponent to use for key generation.
49 #define PUBLIC_EXPONENT 0x10001
52 typedef struct private_rsa_private_key_t private_rsa_private_key_t
;
55 * Private data of a rsa_private_key_t object.
57 struct private_rsa_private_key_t
{
59 * Public interface for this signer.
61 rsa_private_key_t
public;
64 * Version of key, as encoded in PKCS#1
104 * Private coefficient.
114 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
120 * @brief Implements the RSADP algorithm specified in PKCS#1.
122 * @param this calling object
123 * @param data data to process
124 * @return processed data
126 chunk_t (*rsadp
) (private_rsa_private_key_t
*this, chunk_t data
);
129 * @brief Implements the RSASP1 algorithm specified in PKCS#1.
130 * @param this calling object
131 * @param data data to process
132 * @return processed data
134 chunk_t (*rsasp1
) (private_rsa_private_key_t
*this, chunk_t data
);
137 * @brief Generate a prime value.
139 * @param this calling object
140 * @param prime_size size of the prime, in bytes
141 * @param[out] prime uninitialized mpz
143 status_t (*compute_prime
) (private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
);
147 /* ASN.1 definition of a PKCS#1 RSA private key */
148 static const asn1Object_t privkey_objects
[] = {
149 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
150 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
151 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
152 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
153 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
154 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
155 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
156 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
157 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
158 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
159 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
160 ASN1_LOOP
}, /* 10 */
161 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
162 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
163 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
164 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
165 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
} /* 15 */
168 #define PRIV_KEY_VERSION 1
169 #define PRIV_KEY_MODULUS 2
170 #define PRIV_KEY_PUB_EXP 3
171 #define PRIV_KEY_PRIV_EXP 4
172 #define PRIV_KEY_PRIME1 5
173 #define PRIV_KEY_PRIME2 6
174 #define PRIV_KEY_EXP1 7
175 #define PRIV_KEY_EXP2 8
176 #define PRIV_KEY_COEFF 9
177 #define PRIV_KEY_ROOF 16
179 static private_rsa_private_key_t
*rsa_private_key_create_empty(void);
182 * Implementation of private_rsa_private_key_t.compute_prime.
184 static status_t
compute_prime(private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
)
186 randomizer_t
*randomizer
;
187 chunk_t random_bytes
;
190 randomizer
= randomizer_create();
195 status
= randomizer
->allocate_random_bytes(randomizer
, prime_size
, &random_bytes
);
196 if (status
!= SUCCESS
)
198 randomizer
->destroy(randomizer
);
203 /* make sure most significant bit is set */
204 random_bytes
.ptr
[0] = random_bytes
.ptr
[0] | 0x80;
206 /* convert chunk to mpz value */
207 mpz_import(*prime
, random_bytes
.len
, 1, 1, 1, 0, random_bytes
.ptr
);
210 mpz_nextprime (*prime
, *prime
);
212 free(random_bytes
.ptr
);
214 /* check if it isnt too large */
215 while (((mpz_sizeinbase(*prime
, 2) + 7) / 8) > prime_size
);
217 randomizer
->destroy(randomizer
);
222 * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
224 static chunk_t
rsadp(private_rsa_private_key_t
*this, chunk_t data
)
232 mpz_import(t1
, data
.len
, 1, 1, 1, 0, data
.ptr
);
234 mpz_powm(t2
, t1
, this->exp1
, this->p
); /* m1 = c^dP mod p */
235 mpz_powm(t1
, t1
, this->exp2
, this->q
); /* m2 = c^dQ mod Q */
236 mpz_sub(t2
, t2
, t1
); /* h = qInv (m1 - m2) mod p */
237 mpz_mod(t2
, t2
, this->p
);
238 mpz_mul(t2
, t2
, this->coeff
);
239 mpz_mod(t2
, t2
, this->p
);
241 mpz_mul(t2
, t2
, this->q
); /* m = m2 + h q */
244 decrypted
.len
= this->k
;
245 decrypted
.ptr
= mpz_export(NULL
, NULL
, 1, decrypted
.len
, 1, 0, t1
);
254 * Implementation of rsa_private_key.build_emsa_signature.
256 static status_t
build_emsa_pkcs1_signature(private_rsa_private_key_t
*this, hash_algorithm_t hash_algorithm
, chunk_t data
, chunk_t
*signature
)
263 /* get oid string prepended to hash */
264 switch (hash_algorithm
)
269 oid
.len
= sizeof(md2_oid
);
275 oid
.len
= sizeof(md5_oid
);
281 oid
.len
= sizeof(sha1_oid
);
286 oid
.ptr
= sha256_oid
;
287 oid
.len
= sizeof(sha256_oid
);
292 oid
.ptr
= sha384_oid
;
293 oid
.len
= sizeof(sha384_oid
);
298 oid
.ptr
= sha512_oid
;
299 oid
.len
= sizeof(sha512_oid
);
304 return NOT_SUPPORTED
;
309 hasher
= hasher_create(hash_algorithm
);
312 return NOT_SUPPORTED
;
316 hasher
->allocate_hash(hasher
, data
, &hash
);
317 hasher
->destroy(hasher
);
319 /* build chunk to rsa-decrypt:
320 * EM = 0x00 || 0x01 || PS || 0x00 || T.
321 * PS = 0xFF padding, with length to fill em
325 em
.ptr
= malloc(em
.len
);
327 /* fill em with padding */
328 memset(em
.ptr
, 0xFF, em
.len
);
329 /* set magic bytes */
332 *(em
.ptr
+ em
.len
- hash
.len
- oid
.len
- 1) = 0x00;
334 memcpy(em
.ptr
+ em
.len
- hash
.len
, hash
.ptr
, hash
.len
);
336 memcpy(em
.ptr
+ em
.len
- hash
.len
- oid
.len
, oid
.ptr
, oid
.len
);
338 /* build signature */
339 *signature
= this->rsasp1(this, em
);
348 * Implementation of rsa_private_key.get_key.
350 static status_t
get_key(private_rsa_private_key_t
*this, chunk_t
*key
)
352 chunk_t n
, e
, p
, q
, d
, exp1
, exp2
, coeff
;
355 n
.ptr
= mpz_export(NULL
, NULL
, 1, n
.len
, 1, 0, this->n
);
357 e
.ptr
= mpz_export(NULL
, NULL
, 1, e
.len
, 1, 0, this->e
);
359 p
.ptr
= mpz_export(NULL
, NULL
, 1, p
.len
, 1, 0, this->p
);
361 q
.ptr
= mpz_export(NULL
, NULL
, 1, q
.len
, 1, 0, this->q
);
363 d
.ptr
= mpz_export(NULL
, NULL
, 1, d
.len
, 1, 0, this->d
);
365 exp1
.ptr
= mpz_export(NULL
, NULL
, 1, exp1
.len
, 1, 0, this->exp1
);
367 exp2
.ptr
= mpz_export(NULL
, NULL
, 1, exp2
.len
, 1, 0, this->exp2
);
369 coeff
.ptr
= mpz_export(NULL
, NULL
, 1, coeff
.len
, 1, 0, this->coeff
);
371 key
->len
= this->k
* 8;
372 key
->ptr
= malloc(key
->len
);
373 memcpy(key
->ptr
+ this->k
* 0, n
.ptr
, n
.len
);
374 memcpy(key
->ptr
+ this->k
* 1, e
.ptr
, e
.len
);
375 memcpy(key
->ptr
+ this->k
* 2, p
.ptr
, p
.len
);
376 memcpy(key
->ptr
+ this->k
* 3, q
.ptr
, q
.len
);
377 memcpy(key
->ptr
+ this->k
* 4, d
.ptr
, d
.len
);
378 memcpy(key
->ptr
+ this->k
* 5, exp1
.ptr
, exp1
.len
);
379 memcpy(key
->ptr
+ this->k
* 6, exp2
.ptr
, exp2
.len
);
380 memcpy(key
->ptr
+ this->k
* 7, coeff
.ptr
, coeff
.len
);
395 * Implementation of rsa_private_key.save_key.
397 static status_t
save_key(private_rsa_private_key_t
*this, char *file
)
399 return NOT_SUPPORTED
;
403 * Implementation of rsa_private_key.get_public_key.
405 rsa_public_key_t
*get_public_key(private_rsa_private_key_t
*this)
411 * Implementation of rsa_private_key.belongs_to.
413 static bool belongs_to(private_rsa_private_key_t
*this, rsa_public_key_t
*public)
415 return chunk_equals(this->keyid
, public->get_keyid(public));
419 * Check the loaded key if it is valid and usable
422 static status_t
check(private_rsa_private_key_t
*this)
425 status_t status
= SUCCESS
;
427 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
428 * We actually require more (for security).
435 /* we picked a max modulus size to simplify buffer allocation */
436 if (this->k
> 8192/8)
445 /* check that n == p * q */
446 mpz_mul(u
, this->p
, this->q
);
447 if (mpz_cmp(u
, this->n
) != 0)
452 /* check that e divides neither p-1 nor q-1 */
453 mpz_sub_ui(t
, this->p
, 1);
454 mpz_mod(t
, t
, this->e
);
455 if (mpz_cmp_ui(t
, 0) == 0)
460 mpz_sub_ui(t
, this->q
, 1);
461 mpz_mod(t
, t
, this->e
);
462 if (mpz_cmp_ui(t
, 0) == 0)
467 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
468 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
469 mpz_sub_ui(q1
, this->q
, 1);
470 mpz_sub_ui(u
, this->p
, 1);
471 mpz_gcd(t
, u
, q1
); /* t := gcd(p-1, q-1) */
472 mpz_mul(u
, u
, q1
); /* u := (p-1) * (q-1) */
473 mpz_divexact(u
, u
, t
); /* u := lcm(p-1, q-1) */
475 mpz_mul(t
, this->d
, this->e
);
477 if (mpz_cmp_ui(t
, 1) != 0)
482 /* check that exp1 is d mod (p-1) */
483 mpz_sub_ui(u
, this->p
, 1);
484 mpz_mod(t
, this->d
, u
);
485 if (mpz_cmp(t
, this->exp1
) != 0)
490 /* check that exp2 is d mod (q-1) */
491 mpz_sub_ui(u
, this->q
, 1);
492 mpz_mod(t
, this->d
, u
);
493 if (mpz_cmp(t
, this->exp2
) != 0)
498 /* check that coeff is (q^-1) mod p */
499 mpz_mul(t
, this->coeff
, this->q
);
500 mpz_mod(t
, t
, this->p
);
501 if (mpz_cmp_ui(t
, 1) != 0)
513 * Implementation of rsa_private_key.clone.
515 static rsa_private_key_t
* _clone(private_rsa_private_key_t
*this)
517 private_rsa_private_key_t
*clone
= rsa_private_key_create_empty();
519 mpz_init_set(clone
->n
, this->n
);
520 mpz_init_set(clone
->e
, this->e
);
521 mpz_init_set(clone
->p
, this->p
);
522 mpz_init_set(clone
->q
, this->q
);
523 mpz_init_set(clone
->d
, this->d
);
524 mpz_init_set(clone
->exp1
, this->exp1
);
525 mpz_init_set(clone
->exp2
, this->exp2
);
526 mpz_init_set(clone
->coeff
, this->coeff
);
527 clone
->keyid
= chunk_clone(this->keyid
);
530 return &clone
->public;
534 * Implementation of rsa_private_key.destroy.
536 static void destroy(private_rsa_private_key_t
*this)
543 mpz_clear(this->exp1
);
544 mpz_clear(this->exp2
);
545 mpz_clear(this->coeff
);
546 free(this->keyid
.ptr
);
551 * Internal generic constructor
553 static private_rsa_private_key_t
*rsa_private_key_create_empty(void)
555 private_rsa_private_key_t
*this = malloc_thing(private_rsa_private_key_t
);
557 /* public functions */
558 this->public.build_emsa_pkcs1_signature
= (status_t (*) (rsa_private_key_t
*,hash_algorithm_t
,chunk_t
,chunk_t
*))build_emsa_pkcs1_signature
;
559 this->public.get_key
= (status_t (*) (rsa_private_key_t
*,chunk_t
*))get_key
;
560 this->public.save_key
= (status_t (*) (rsa_private_key_t
*,char*))save_key
;
561 this->public.get_public_key
= (rsa_public_key_t
*(*) (rsa_private_key_t
*))get_public_key
;
562 this->public.belongs_to
= (bool (*) (rsa_private_key_t
*,rsa_public_key_t
*))belongs_to
;
563 this->public.clone
= (rsa_private_key_t
*(*)(rsa_private_key_t
*))_clone
;
564 this->public.destroy
= (void (*) (rsa_private_key_t
*))destroy
;
566 /* private functions */
568 this->rsasp1
= rsadp
; /* same algorithm */
569 this->compute_prime
= compute_prime
;
577 rsa_private_key_t
*rsa_private_key_create(size_t key_size
)
579 mpz_t p
, q
, n
, e
, d
, exp1
, exp2
, coeff
;
581 private_rsa_private_key_t
*this;
583 this = rsa_private_key_create_empty();
584 key_size
= key_size
/ 8;
586 /* Get values of primes p and q */
587 if (this->compute_prime(this, key_size
/2, &p
) != SUCCESS
)
592 if (this->compute_prime(this, key_size
/2, &q
) != SUCCESS
)
606 /* Swapping Primes so p is larger then q */
607 if (mpz_cmp(p
, q
) < 0)
614 mpz_mul(n
, p
, q
); /* n = p*q */
615 mpz_init_set_ui(e
, PUBLIC_EXPONENT
); /* assign public exponent */
616 mpz_init_set(m
, p
); /* m = p */
617 mpz_sub_ui(m
, m
, 1); /* m = m -1 */
618 mpz_init_set(q1
, q
); /* q1 = q */
619 mpz_sub_ui(q1
, q1
, 1); /* q1 = q1 -1 */
620 mpz_gcd(t
, m
, q1
); /* t = gcd(p-1, q-1) */
621 mpz_mul(m
, m
, q1
); /* m = (p-1)*(q-1) */
622 mpz_divexact(m
, m
, t
); /* m = m / t */
623 mpz_gcd(t
, m
, e
); /* t = gcd(m, e) (greatest common divisor) */
625 mpz_invert(d
, e
, m
); /* e has an inverse mod m */
626 if (mpz_cmp_ui(d
, 0) < 0) /* make sure d is positive */
630 mpz_sub_ui(t
, p
, 1); /* t = p-1 */
631 mpz_mod(exp1
, d
, t
); /* exp1 = d mod p-1 */
632 mpz_sub_ui(t
, q
, 1); /* t = q-1 */
633 mpz_mod(exp2
, d
, t
); /* exp2 = d mod q-1 */
635 mpz_invert(coeff
, q
, p
); /* coeff = q^-1 mod p */
636 if (mpz_cmp_ui(coeff
, 0) < 0) /* make coeff d is positive */
638 mpz_add(coeff
, coeff
, p
);
651 *(this->exp1
) = *exp1
;
652 *(this->exp2
) = *exp2
;
653 *(this->coeff
) = *coeff
;
655 /* set key size in bytes */
658 return &this->public;
664 rsa_private_key_t
*rsa_private_key_create_from_chunk(chunk_t blob
)
670 private_rsa_private_key_t
*this;
672 this = rsa_private_key_create_empty();
679 mpz_init(this->exp1
);
680 mpz_init(this->exp2
);
681 mpz_init(this->coeff
);
683 asn1_init(&ctx
, blob
, 0, FALSE
);
685 while (objectID
< PRIV_KEY_ROOF
)
687 if (!extract_object(privkey_objects
, &objectID
, &object
, &level
, &ctx
))
694 case PRIV_KEY_VERSION
:
695 if (object
.len
> 0 && *object
.ptr
!= 0)
701 case PRIV_KEY_MODULUS
:
702 mpz_import(this->n
, object
.len
, 1, 1, 1, 0, object
.ptr
);
704 case PRIV_KEY_PUB_EXP
:
705 mpz_import(this->e
, object
.len
, 1, 1, 1, 0, object
.ptr
);
707 case PRIV_KEY_PRIV_EXP
:
708 mpz_import(this->d
, object
.len
, 1, 1, 1, 0, object
.ptr
);
710 case PRIV_KEY_PRIME1
:
711 mpz_import(this->p
, object
.len
, 1, 1, 1, 0, object
.ptr
);
713 case PRIV_KEY_PRIME2
:
714 mpz_import(this->q
, object
.len
, 1, 1, 1, 0, object
.ptr
);
717 mpz_import(this->exp1
, object
.len
, 1, 1, 1, 0, object
.ptr
);
720 mpz_import(this->exp2
, object
.len
, 1, 1, 1, 0, object
.ptr
);
723 mpz_import(this->coeff
, object
.len
, 1, 1, 1, 0, object
.ptr
);
729 this->k
= (mpz_sizeinbase(this->n
, 2) + 7) / 8;
731 /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
733 chunk_t publicKeyInfo
= rsa_public_key_info_to_asn1(this->n
, this->e
);
734 hasher_t
*hasher
= hasher_create(HASH_SHA1
);
736 hasher
->allocate_hash(hasher
, publicKeyInfo
, &this->keyid
);
737 hasher
->destroy(hasher
);
738 free(publicKeyInfo
.ptr
);
741 if (check(this) != SUCCESS
)
748 return &this->public;
755 rsa_private_key_t
*rsa_private_key_create_from_file(char *filename
, char *passphrase
)
758 chunk_t chunk
= CHUNK_INITIALIZER
;
759 rsa_private_key_t
*key
= NULL
;
761 if (!pem_asn1_load_file(filename
, passphrase
, "private key", &chunk
, &pgp
))
764 key
= rsa_private_key_create_from_chunk(chunk
);