2 * @file rsa_private_key.c
4 * @brief Implementation of rsa_private_key_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 #include "rsa_public_key.h"
30 #include "rsa_private_key.h"
32 #include <asn1/asn1.h>
34 #include <utils/randomizer.h>
37 * OIDs for hash algorithms are defined in rsa_public_key.c.
39 extern u_int8_t md2_oid
[18];
40 extern u_int8_t md5_oid
[18];
41 extern u_int8_t sha1_oid
[15];
42 extern u_int8_t sha256_oid
[19];
43 extern u_int8_t sha384_oid
[19];
44 extern u_int8_t sha512_oid
[19];
48 * defined in rsa_public_key.c
50 extern chunk_t
rsa_public_key_info_to_asn1(const mpz_t n
, const mpz_t e
);
54 * Public exponent to use for key generation.
56 #define PUBLIC_EXPONENT 0x10001
59 typedef struct private_rsa_private_key_t private_rsa_private_key_t
;
62 * Private data of a rsa_private_key_t object.
64 struct private_rsa_private_key_t
{
66 * Public interface for this signer.
68 rsa_private_key_t
public;
71 * Version of key, as encoded in PKCS#1
101 * Private exponent 1.
106 * Private exponent 2.
111 * Private coefficient.
121 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
127 * @brief Implements the RSADP algorithm specified in PKCS#1.
129 * @param this calling object
130 * @param data data to process
131 * @return processed data
133 chunk_t (*rsadp
) (private_rsa_private_key_t
*this, chunk_t data
);
136 * @brief Implements the RSASP1 algorithm specified in PKCS#1.
137 * @param this calling object
138 * @param data data to process
139 * @return processed data
141 chunk_t (*rsasp1
) (private_rsa_private_key_t
*this, chunk_t data
);
144 * @brief Generate a prime value.
146 * @param this calling object
147 * @param prime_size size of the prime, in bytes
148 * @param[out] prime uninitialized mpz
150 status_t (*compute_prime
) (private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
);
154 /* ASN.1 definition of a PKCS#1 RSA private key */
155 static const asn1Object_t privkey_objects
[] = {
156 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
157 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
158 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
159 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
160 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
161 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
162 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
163 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
164 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
165 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
166 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
167 ASN1_LOOP
}, /* 10 */
168 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
169 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
170 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
171 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
172 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
} /* 15 */
175 #define PRIV_KEY_VERSION 1
176 #define PRIV_KEY_MODULUS 2
177 #define PRIV_KEY_PUB_EXP 3
178 #define PRIV_KEY_PRIV_EXP 4
179 #define PRIV_KEY_PRIME1 5
180 #define PRIV_KEY_PRIME2 6
181 #define PRIV_KEY_EXP1 7
182 #define PRIV_KEY_EXP2 8
183 #define PRIV_KEY_COEFF 9
184 #define PRIV_KEY_ROOF 16
186 static private_rsa_private_key_t
*rsa_private_key_create_empty(void);
189 * Implementation of private_rsa_private_key_t.compute_prime.
191 static status_t
compute_prime(private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
)
193 randomizer_t
*randomizer
;
194 chunk_t random_bytes
;
197 randomizer
= randomizer_create();
202 status
= randomizer
->allocate_random_bytes(randomizer
, prime_size
, &random_bytes
);
203 if (status
!= SUCCESS
)
205 randomizer
->destroy(randomizer
);
210 /* make sure most significant bit is set */
211 random_bytes
.ptr
[0] = random_bytes
.ptr
[0] | 0x80;
213 /* convert chunk to mpz value */
214 mpz_import(*prime
, random_bytes
.len
, 1, 1, 1, 0, random_bytes
.ptr
);
217 mpz_nextprime (*prime
, *prime
);
219 free(random_bytes
.ptr
);
221 /* check if it isnt too large */
222 while (((mpz_sizeinbase(*prime
, 2) + 7) / 8) > prime_size
);
224 randomizer
->destroy(randomizer
);
229 * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
231 static chunk_t
rsadp(private_rsa_private_key_t
*this, chunk_t data
)
239 mpz_import(t1
, data
.len
, 1, 1, 1, 0, data
.ptr
);
241 mpz_powm(t2
, t1
, this->exp1
, this->p
); /* m1 = c^dP mod p */
242 mpz_powm(t1
, t1
, this->exp2
, this->q
); /* m2 = c^dQ mod Q */
243 mpz_sub(t2
, t2
, t1
); /* h = qInv (m1 - m2) mod p */
244 mpz_mod(t2
, t2
, this->p
);
245 mpz_mul(t2
, t2
, this->coeff
);
246 mpz_mod(t2
, t2
, this->p
);
248 mpz_mul(t2
, t2
, this->q
); /* m = m2 + h q */
251 decrypted
.len
= this->k
;
252 decrypted
.ptr
= mpz_export(NULL
, NULL
, 1, decrypted
.len
, 1, 0, t1
);
261 * Implementation of rsa_private_key.build_emsa_signature.
263 static status_t
build_emsa_pkcs1_signature(private_rsa_private_key_t
*this, hash_algorithm_t hash_algorithm
, chunk_t data
, chunk_t
*signature
)
270 /* get oid string prepended to hash */
271 switch (hash_algorithm
)
276 oid
.len
= sizeof(md2_oid
);
282 oid
.len
= sizeof(md5_oid
);
288 oid
.len
= sizeof(sha1_oid
);
293 oid
.ptr
= sha256_oid
;
294 oid
.len
= sizeof(sha256_oid
);
299 oid
.ptr
= sha384_oid
;
300 oid
.len
= sizeof(sha384_oid
);
305 oid
.ptr
= sha512_oid
;
306 oid
.len
= sizeof(sha512_oid
);
311 return NOT_SUPPORTED
;
316 hasher
= hasher_create(hash_algorithm
);
319 return NOT_SUPPORTED
;
323 hasher
->allocate_hash(hasher
, data
, &hash
);
324 hasher
->destroy(hasher
);
326 /* build chunk to rsa-decrypt:
327 * EM = 0x00 || 0x01 || PS || 0x00 || T.
328 * PS = 0xFF padding, with length to fill em
332 em
.ptr
= malloc(em
.len
);
334 /* fill em with padding */
335 memset(em
.ptr
, 0xFF, em
.len
);
336 /* set magic bytes */
339 *(em
.ptr
+ em
.len
- hash
.len
- oid
.len
- 1) = 0x00;
341 memcpy(em
.ptr
+ em
.len
- hash
.len
, hash
.ptr
, hash
.len
);
343 memcpy(em
.ptr
+ em
.len
- hash
.len
- oid
.len
, oid
.ptr
, oid
.len
);
345 /* build signature */
346 *signature
= this->rsasp1(this, em
);
355 * Implementation of rsa_private_key.get_key.
357 static status_t
get_key(private_rsa_private_key_t
*this, chunk_t
*key
)
359 chunk_t n
, e
, p
, q
, d
, exp1
, exp2
, coeff
;
362 n
.ptr
= mpz_export(NULL
, NULL
, 1, n
.len
, 1, 0, this->n
);
364 e
.ptr
= mpz_export(NULL
, NULL
, 1, e
.len
, 1, 0, this->e
);
366 p
.ptr
= mpz_export(NULL
, NULL
, 1, p
.len
, 1, 0, this->p
);
368 q
.ptr
= mpz_export(NULL
, NULL
, 1, q
.len
, 1, 0, this->q
);
370 d
.ptr
= mpz_export(NULL
, NULL
, 1, d
.len
, 1, 0, this->d
);
372 exp1
.ptr
= mpz_export(NULL
, NULL
, 1, exp1
.len
, 1, 0, this->exp1
);
374 exp2
.ptr
= mpz_export(NULL
, NULL
, 1, exp2
.len
, 1, 0, this->exp2
);
376 coeff
.ptr
= mpz_export(NULL
, NULL
, 1, coeff
.len
, 1, 0, this->coeff
);
378 key
->len
= this->k
* 8;
379 key
->ptr
= malloc(key
->len
);
380 memcpy(key
->ptr
+ this->k
* 0, n
.ptr
, n
.len
);
381 memcpy(key
->ptr
+ this->k
* 1, e
.ptr
, e
.len
);
382 memcpy(key
->ptr
+ this->k
* 2, p
.ptr
, p
.len
);
383 memcpy(key
->ptr
+ this->k
* 3, q
.ptr
, q
.len
);
384 memcpy(key
->ptr
+ this->k
* 4, d
.ptr
, d
.len
);
385 memcpy(key
->ptr
+ this->k
* 5, exp1
.ptr
, exp1
.len
);
386 memcpy(key
->ptr
+ this->k
* 6, exp2
.ptr
, exp2
.len
);
387 memcpy(key
->ptr
+ this->k
* 7, coeff
.ptr
, coeff
.len
);
402 * Implementation of rsa_private_key.save_key.
404 static status_t
save_key(private_rsa_private_key_t
*this, char *file
)
406 return NOT_SUPPORTED
;
410 * Implementation of rsa_private_key.get_public_key.
412 rsa_public_key_t
*get_public_key(private_rsa_private_key_t
*this)
418 * Implementation of rsa_private_key.belongs_to.
420 static bool belongs_to(private_rsa_private_key_t
*this, rsa_public_key_t
*public)
422 return chunk_equals(this->keyid
, public->get_keyid(public));
426 * Check the loaded key if it is valid and usable
429 static status_t
check(private_rsa_private_key_t
*this)
432 status_t status
= SUCCESS
;
434 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
435 * We actually require more (for security).
442 /* we picked a max modulus size to simplify buffer allocation */
443 if (this->k
> 8192/8)
452 /* check that n == p * q */
453 mpz_mul(u
, this->p
, this->q
);
454 if (mpz_cmp(u
, this->n
) != 0)
459 /* check that e divides neither p-1 nor q-1 */
460 mpz_sub_ui(t
, this->p
, 1);
461 mpz_mod(t
, t
, this->e
);
462 if (mpz_cmp_ui(t
, 0) == 0)
467 mpz_sub_ui(t
, this->q
, 1);
468 mpz_mod(t
, t
, this->e
);
469 if (mpz_cmp_ui(t
, 0) == 0)
474 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
475 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
476 mpz_sub_ui(q1
, this->q
, 1);
477 mpz_sub_ui(u
, this->p
, 1);
478 mpz_gcd(t
, u
, q1
); /* t := gcd(p-1, q-1) */
479 mpz_mul(u
, u
, q1
); /* u := (p-1) * (q-1) */
480 mpz_divexact(u
, u
, t
); /* u := lcm(p-1, q-1) */
482 mpz_mul(t
, this->d
, this->e
);
484 if (mpz_cmp_ui(t
, 1) != 0)
489 /* check that exp1 is d mod (p-1) */
490 mpz_sub_ui(u
, this->p
, 1);
491 mpz_mod(t
, this->d
, u
);
492 if (mpz_cmp(t
, this->exp1
) != 0)
497 /* check that exp2 is d mod (q-1) */
498 mpz_sub_ui(u
, this->q
, 1);
499 mpz_mod(t
, this->d
, u
);
500 if (mpz_cmp(t
, this->exp2
) != 0)
505 /* check that coeff is (q^-1) mod p */
506 mpz_mul(t
, this->coeff
, this->q
);
507 mpz_mod(t
, t
, this->p
);
508 if (mpz_cmp_ui(t
, 1) != 0)
520 * Implementation of rsa_private_key.clone.
522 static rsa_private_key_t
* _clone(private_rsa_private_key_t
*this)
524 private_rsa_private_key_t
*clone
= rsa_private_key_create_empty();
526 mpz_init_set(clone
->n
, this->n
);
527 mpz_init_set(clone
->e
, this->e
);
528 mpz_init_set(clone
->p
, this->p
);
529 mpz_init_set(clone
->q
, this->q
);
530 mpz_init_set(clone
->d
, this->d
);
531 mpz_init_set(clone
->exp1
, this->exp1
);
532 mpz_init_set(clone
->exp2
, this->exp2
);
533 mpz_init_set(clone
->coeff
, this->coeff
);
534 clone
->keyid
= chunk_clone(this->keyid
);
537 return &clone
->public;
541 * Implementation of rsa_private_key.destroy.
543 static void destroy(private_rsa_private_key_t
*this)
550 mpz_clear(this->exp1
);
551 mpz_clear(this->exp2
);
552 mpz_clear(this->coeff
);
553 free(this->keyid
.ptr
);
558 * Internal generic constructor
560 static private_rsa_private_key_t
*rsa_private_key_create_empty(void)
562 private_rsa_private_key_t
*this = malloc_thing(private_rsa_private_key_t
);
564 /* public functions */
565 this->public.build_emsa_pkcs1_signature
= (status_t (*) (rsa_private_key_t
*,hash_algorithm_t
,chunk_t
,chunk_t
*))build_emsa_pkcs1_signature
;
566 this->public.get_key
= (status_t (*) (rsa_private_key_t
*,chunk_t
*))get_key
;
567 this->public.save_key
= (status_t (*) (rsa_private_key_t
*,char*))save_key
;
568 this->public.get_public_key
= (rsa_public_key_t
*(*) (rsa_private_key_t
*))get_public_key
;
569 this->public.belongs_to
= (bool (*) (rsa_private_key_t
*,rsa_public_key_t
*))belongs_to
;
570 this->public.clone
= (rsa_private_key_t
*(*)(rsa_private_key_t
*))_clone
;
571 this->public.destroy
= (void (*) (rsa_private_key_t
*))destroy
;
573 /* private functions */
575 this->rsasp1
= rsadp
; /* same algorithm */
576 this->compute_prime
= compute_prime
;
584 rsa_private_key_t
*rsa_private_key_create(size_t key_size
)
586 mpz_t p
, q
, n
, e
, d
, exp1
, exp2
, coeff
;
588 private_rsa_private_key_t
*this;
590 this = rsa_private_key_create_empty();
591 key_size
= key_size
/ 8;
593 /* Get values of primes p and q */
594 if (this->compute_prime(this, key_size
/2, &p
) != SUCCESS
)
599 if (this->compute_prime(this, key_size
/2, &q
) != SUCCESS
)
613 /* Swapping Primes so p is larger then q */
614 if (mpz_cmp(p
, q
) < 0)
621 mpz_mul(n
, p
, q
); /* n = p*q */
622 mpz_init_set_ui(e
, PUBLIC_EXPONENT
); /* assign public exponent */
623 mpz_init_set(m
, p
); /* m = p */
624 mpz_sub_ui(m
, m
, 1); /* m = m -1 */
625 mpz_init_set(q1
, q
); /* q1 = q */
626 mpz_sub_ui(q1
, q1
, 1); /* q1 = q1 -1 */
627 mpz_gcd(t
, m
, q1
); /* t = gcd(p-1, q-1) */
628 mpz_mul(m
, m
, q1
); /* m = (p-1)*(q-1) */
629 mpz_divexact(m
, m
, t
); /* m = m / t */
630 mpz_gcd(t
, m
, e
); /* t = gcd(m, e) (greatest common divisor) */
632 mpz_invert(d
, e
, m
); /* e has an inverse mod m */
633 if (mpz_cmp_ui(d
, 0) < 0) /* make sure d is positive */
637 mpz_sub_ui(t
, p
, 1); /* t = p-1 */
638 mpz_mod(exp1
, d
, t
); /* exp1 = d mod p-1 */
639 mpz_sub_ui(t
, q
, 1); /* t = q-1 */
640 mpz_mod(exp2
, d
, t
); /* exp2 = d mod q-1 */
642 mpz_invert(coeff
, q
, p
); /* coeff = q^-1 mod p */
643 if (mpz_cmp_ui(coeff
, 0) < 0) /* make coeff d is positive */
645 mpz_add(coeff
, coeff
, p
);
658 *(this->exp1
) = *exp1
;
659 *(this->exp2
) = *exp2
;
660 *(this->coeff
) = *coeff
;
662 /* set key size in bytes */
665 return &this->public;
671 rsa_private_key_t
*rsa_private_key_create_from_chunk(chunk_t blob
)
677 private_rsa_private_key_t
*this;
679 this = rsa_private_key_create_empty();
686 mpz_init(this->exp1
);
687 mpz_init(this->exp2
);
688 mpz_init(this->coeff
);
690 asn1_init(&ctx
, blob
, 0, FALSE
);
692 while (objectID
< PRIV_KEY_ROOF
)
694 if (!extract_object(privkey_objects
, &objectID
, &object
, &level
, &ctx
))
701 case PRIV_KEY_VERSION
:
702 if (object
.len
> 0 && *object
.ptr
!= 0)
708 case PRIV_KEY_MODULUS
:
709 mpz_import(this->n
, object
.len
, 1, 1, 1, 0, object
.ptr
);
711 case PRIV_KEY_PUB_EXP
:
712 mpz_import(this->e
, object
.len
, 1, 1, 1, 0, object
.ptr
);
714 case PRIV_KEY_PRIV_EXP
:
715 mpz_import(this->d
, object
.len
, 1, 1, 1, 0, object
.ptr
);
717 case PRIV_KEY_PRIME1
:
718 mpz_import(this->p
, object
.len
, 1, 1, 1, 0, object
.ptr
);
720 case PRIV_KEY_PRIME2
:
721 mpz_import(this->q
, object
.len
, 1, 1, 1, 0, object
.ptr
);
724 mpz_import(this->exp1
, object
.len
, 1, 1, 1, 0, object
.ptr
);
727 mpz_import(this->exp2
, object
.len
, 1, 1, 1, 0, object
.ptr
);
730 mpz_import(this->coeff
, object
.len
, 1, 1, 1, 0, object
.ptr
);
736 this->k
= (mpz_sizeinbase(this->n
, 2) + 7) / 8;
738 /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
740 chunk_t publicKeyInfo
= rsa_public_key_info_to_asn1(this->n
, this->e
);
741 hasher_t
*hasher
= hasher_create(HASH_SHA1
);
743 hasher
->allocate_hash(hasher
, publicKeyInfo
, &this->keyid
);
744 hasher
->destroy(hasher
);
745 free(publicKeyInfo
.ptr
);
748 if (check(this) != SUCCESS
)
755 return &this->public;
762 rsa_private_key_t
*rsa_private_key_create_from_file(char *filename
, chunk_t
*passphrase
)
765 chunk_t chunk
= CHUNK_INITIALIZER
;
766 rsa_private_key_t
*key
= NULL
;
768 if (!pem_asn1_load_file(filename
, passphrase
, "private key", &chunk
, &pgp
))
771 key
= rsa_private_key_create_from_chunk(chunk
);