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 * Public exponent to use for key generation.
50 #define PUBLIC_EXPONENT 0x10001
53 typedef struct private_rsa_private_key_t private_rsa_private_key_t
;
56 * Private data of a rsa_private_key_t object.
58 struct private_rsa_private_key_t
{
60 * Public interface for this signer.
62 rsa_private_key_t
public;
65 * Version of key, as encoded in PKCS#1
100 * Private exponent 2.
105 * Private coefficient.
115 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
121 * @brief Implements the RSADP algorithm specified in PKCS#1.
123 * @param this calling object
124 * @param data data to process
125 * @return processed data
127 chunk_t (*rsadp
) (private_rsa_private_key_t
*this, chunk_t data
);
130 * @brief Implements the RSASP1 algorithm specified in PKCS#1.
131 * @param this calling object
132 * @param data data to process
133 * @return processed data
135 chunk_t (*rsasp1
) (private_rsa_private_key_t
*this, chunk_t data
);
138 * @brief Generate a prime value.
140 * @param this calling object
141 * @param prime_size size of the prime, in bytes
142 * @param[out] prime uninitialized mpz
144 status_t (*compute_prime
) (private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
);
148 /* ASN.1 definition of a PKCS#1 RSA private key */
149 static const asn1Object_t privkey_objects
[] = {
150 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
151 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
152 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
153 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
154 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
155 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
156 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
157 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
158 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
159 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
160 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
161 ASN1_LOOP
}, /* 10 */
162 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
163 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
164 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
165 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
166 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
} /* 15 */
169 #define PRIV_KEY_VERSION 1
170 #define PRIV_KEY_MODULUS 2
171 #define PRIV_KEY_PUB_EXP 3
172 #define PRIV_KEY_PRIV_EXP 4
173 #define PRIV_KEY_PRIME1 5
174 #define PRIV_KEY_PRIME2 6
175 #define PRIV_KEY_EXP1 7
176 #define PRIV_KEY_EXP2 8
177 #define PRIV_KEY_COEFF 9
178 #define PRIV_KEY_ROOF 16
180 static private_rsa_private_key_t
*rsa_private_key_create_empty(void);
183 * Implementation of private_rsa_private_key_t.compute_prime.
185 static status_t
compute_prime(private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
)
187 randomizer_t
*randomizer
;
188 chunk_t random_bytes
;
191 randomizer
= randomizer_create();
196 status
= randomizer
->allocate_random_bytes(randomizer
, prime_size
, &random_bytes
);
197 if (status
!= SUCCESS
)
199 randomizer
->destroy(randomizer
);
204 /* make sure most significant bit is set */
205 random_bytes
.ptr
[0] = random_bytes
.ptr
[0] | 0x80;
207 /* convert chunk to mpz value */
208 mpz_import(*prime
, random_bytes
.len
, 1, 1, 1, 0, random_bytes
.ptr
);
211 mpz_nextprime (*prime
, *prime
);
213 free(random_bytes
.ptr
);
215 /* check if it isnt too large */
216 while (((mpz_sizeinbase(*prime
, 2) + 7) / 8) > prime_size
);
218 randomizer
->destroy(randomizer
);
223 * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
225 static chunk_t
rsadp(private_rsa_private_key_t
*this, chunk_t data
)
233 mpz_import(t1
, data
.len
, 1, 1, 1, 0, data
.ptr
);
235 mpz_powm(t2
, t1
, this->exp1
, this->p
); /* m1 = c^dP mod p */
236 mpz_powm(t1
, t1
, this->exp2
, this->q
); /* m2 = c^dQ mod Q */
237 mpz_sub(t2
, t2
, t1
); /* h = qInv (m1 - m2) mod p */
238 mpz_mod(t2
, t2
, this->p
);
239 mpz_mul(t2
, t2
, this->coeff
);
240 mpz_mod(t2
, t2
, this->p
);
242 mpz_mul(t2
, t2
, this->q
); /* m = m2 + h q */
245 decrypted
.len
= this->k
;
246 decrypted
.ptr
= mpz_export(NULL
, NULL
, 1, decrypted
.len
, 1, 0, t1
);
255 * Implementation of rsa_private_key.build_emsa_signature.
257 static status_t
build_emsa_pkcs1_signature(private_rsa_private_key_t
*this, hash_algorithm_t hash_algorithm
, chunk_t data
, chunk_t
*signature
)
264 /* get oid string prepended to hash */
265 switch (hash_algorithm
)
270 oid
.len
= sizeof(md2_oid
);
276 oid
.len
= sizeof(md5_oid
);
282 oid
.len
= sizeof(sha1_oid
);
287 oid
.ptr
= sha256_oid
;
288 oid
.len
= sizeof(sha256_oid
);
293 oid
.ptr
= sha384_oid
;
294 oid
.len
= sizeof(sha384_oid
);
299 oid
.ptr
= sha512_oid
;
300 oid
.len
= sizeof(sha512_oid
);
305 return NOT_SUPPORTED
;
310 hasher
= hasher_create(hash_algorithm
);
313 return NOT_SUPPORTED
;
317 hasher
->allocate_hash(hasher
, data
, &hash
);
318 hasher
->destroy(hasher
);
320 /* build chunk to rsa-decrypt:
321 * EM = 0x00 || 0x01 || PS || 0x00 || T.
322 * PS = 0xFF padding, with length to fill em
326 em
.ptr
= malloc(em
.len
);
328 /* fill em with padding */
329 memset(em
.ptr
, 0xFF, em
.len
);
330 /* set magic bytes */
333 *(em
.ptr
+ em
.len
- hash
.len
- oid
.len
- 1) = 0x00;
335 memcpy(em
.ptr
+ em
.len
- hash
.len
, hash
.ptr
, hash
.len
);
337 memcpy(em
.ptr
+ em
.len
- hash
.len
- oid
.len
, oid
.ptr
, oid
.len
);
339 /* build signature */
340 *signature
= this->rsasp1(this, em
);
349 * Implementation of rsa_private_key.get_key.
351 static status_t
get_key(private_rsa_private_key_t
*this, chunk_t
*key
)
353 chunk_t n
, e
, p
, q
, d
, exp1
, exp2
, coeff
;
356 n
.ptr
= mpz_export(NULL
, NULL
, 1, n
.len
, 1, 0, this->n
);
358 e
.ptr
= mpz_export(NULL
, NULL
, 1, e
.len
, 1, 0, this->e
);
360 p
.ptr
= mpz_export(NULL
, NULL
, 1, p
.len
, 1, 0, this->p
);
362 q
.ptr
= mpz_export(NULL
, NULL
, 1, q
.len
, 1, 0, this->q
);
364 d
.ptr
= mpz_export(NULL
, NULL
, 1, d
.len
, 1, 0, this->d
);
366 exp1
.ptr
= mpz_export(NULL
, NULL
, 1, exp1
.len
, 1, 0, this->exp1
);
368 exp2
.ptr
= mpz_export(NULL
, NULL
, 1, exp2
.len
, 1, 0, this->exp2
);
370 coeff
.ptr
= mpz_export(NULL
, NULL
, 1, coeff
.len
, 1, 0, this->coeff
);
372 key
->len
= this->k
* 8;
373 key
->ptr
= malloc(key
->len
);
374 memcpy(key
->ptr
+ this->k
* 0, n
.ptr
, n
.len
);
375 memcpy(key
->ptr
+ this->k
* 1, e
.ptr
, e
.len
);
376 memcpy(key
->ptr
+ this->k
* 2, p
.ptr
, p
.len
);
377 memcpy(key
->ptr
+ this->k
* 3, q
.ptr
, q
.len
);
378 memcpy(key
->ptr
+ this->k
* 4, d
.ptr
, d
.len
);
379 memcpy(key
->ptr
+ this->k
* 5, exp1
.ptr
, exp1
.len
);
380 memcpy(key
->ptr
+ this->k
* 6, exp2
.ptr
, exp2
.len
);
381 memcpy(key
->ptr
+ this->k
* 7, coeff
.ptr
, coeff
.len
);
396 * Implementation of rsa_private_key.save_key.
398 static status_t
save_key(private_rsa_private_key_t
*this, char *file
)
400 return NOT_SUPPORTED
;
404 * Implementation of rsa_private_key.get_public_key.
406 rsa_public_key_t
*get_public_key(private_rsa_private_key_t
*this)
412 * Implementation of rsa_private_key.belongs_to.
414 static bool belongs_to(private_rsa_private_key_t
*this, rsa_public_key_t
*public)
416 return chunk_equals(this->keyid
, public->get_keyid(public));
420 * Check the loaded key if it is valid and usable
423 static status_t
check(private_rsa_private_key_t
*this)
426 status_t status
= SUCCESS
;
428 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
429 * We actually require more (for security).
436 /* we picked a max modulus size to simplify buffer allocation */
437 if (this->k
> 8192/8)
446 /* check that n == p * q */
447 mpz_mul(u
, this->p
, this->q
);
448 if (mpz_cmp(u
, this->n
) != 0)
453 /* check that e divides neither p-1 nor q-1 */
454 mpz_sub_ui(t
, this->p
, 1);
455 mpz_mod(t
, t
, this->e
);
456 if (mpz_cmp_ui(t
, 0) == 0)
461 mpz_sub_ui(t
, this->q
, 1);
462 mpz_mod(t
, t
, this->e
);
463 if (mpz_cmp_ui(t
, 0) == 0)
468 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
469 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
470 mpz_sub_ui(q1
, this->q
, 1);
471 mpz_sub_ui(u
, this->p
, 1);
472 mpz_gcd(t
, u
, q1
); /* t := gcd(p-1, q-1) */
473 mpz_mul(u
, u
, q1
); /* u := (p-1) * (q-1) */
474 mpz_divexact(u
, u
, t
); /* u := lcm(p-1, q-1) */
476 mpz_mul(t
, this->d
, this->e
);
478 if (mpz_cmp_ui(t
, 1) != 0)
483 /* check that exp1 is d mod (p-1) */
484 mpz_sub_ui(u
, this->p
, 1);
485 mpz_mod(t
, this->d
, u
);
486 if (mpz_cmp(t
, this->exp1
) != 0)
491 /* check that exp2 is d mod (q-1) */
492 mpz_sub_ui(u
, this->q
, 1);
493 mpz_mod(t
, this->d
, u
);
494 if (mpz_cmp(t
, this->exp2
) != 0)
499 /* check that coeff is (q^-1) mod p */
500 mpz_mul(t
, this->coeff
, this->q
);
501 mpz_mod(t
, t
, this->p
);
502 if (mpz_cmp_ui(t
, 1) != 0)
514 * Implementation of rsa_private_key.clone.
516 static rsa_private_key_t
* _clone(private_rsa_private_key_t
*this)
518 private_rsa_private_key_t
*clone
= rsa_private_key_create_empty();
520 mpz_init_set(clone
->n
, this->n
);
521 mpz_init_set(clone
->e
, this->e
);
522 mpz_init_set(clone
->p
, this->p
);
523 mpz_init_set(clone
->q
, this->q
);
524 mpz_init_set(clone
->d
, this->d
);
525 mpz_init_set(clone
->exp1
, this->exp1
);
526 mpz_init_set(clone
->exp2
, this->exp2
);
527 mpz_init_set(clone
->coeff
, this->coeff
);
528 clone
->keyid
= chunk_clone(this->keyid
);
531 return &clone
->public;
535 * Implementation of rsa_private_key.destroy.
537 static void destroy(private_rsa_private_key_t
*this)
544 mpz_clear(this->exp1
);
545 mpz_clear(this->exp2
);
546 mpz_clear(this->coeff
);
547 free(this->keyid
.ptr
);
552 * Internal generic constructor
554 static private_rsa_private_key_t
*rsa_private_key_create_empty(void)
556 private_rsa_private_key_t
*this = malloc_thing(private_rsa_private_key_t
);
558 /* public functions */
559 this->public.build_emsa_pkcs1_signature
= (status_t (*) (rsa_private_key_t
*,hash_algorithm_t
,chunk_t
,chunk_t
*))build_emsa_pkcs1_signature
;
560 this->public.get_key
= (status_t (*) (rsa_private_key_t
*,chunk_t
*))get_key
;
561 this->public.save_key
= (status_t (*) (rsa_private_key_t
*,char*))save_key
;
562 this->public.get_public_key
= (rsa_public_key_t
*(*) (rsa_private_key_t
*))get_public_key
;
563 this->public.belongs_to
= (bool (*) (rsa_private_key_t
*,rsa_public_key_t
*))belongs_to
;
564 this->public.clone
= (rsa_private_key_t
*(*)(rsa_private_key_t
*))_clone
;
565 this->public.destroy
= (void (*) (rsa_private_key_t
*))destroy
;
567 /* private functions */
569 this->rsasp1
= rsadp
; /* same algorithm */
570 this->compute_prime
= compute_prime
;
578 rsa_private_key_t
*rsa_private_key_create(size_t key_size
)
580 mpz_t p
, q
, n
, e
, d
, exp1
, exp2
, coeff
;
582 private_rsa_private_key_t
*this;
584 this = rsa_private_key_create_empty();
585 key_size
= key_size
/ 8;
587 /* Get values of primes p and q */
588 if (this->compute_prime(this, key_size
/2, &p
) != SUCCESS
)
593 if (this->compute_prime(this, key_size
/2, &q
) != SUCCESS
)
607 /* Swapping Primes so p is larger then q */
608 if (mpz_cmp(p
, q
) < 0)
615 mpz_mul(n
, p
, q
); /* n = p*q */
616 mpz_init_set_ui(e
, PUBLIC_EXPONENT
); /* assign public exponent */
617 mpz_init_set(m
, p
); /* m = p */
618 mpz_sub_ui(m
, m
, 1); /* m = m -1 */
619 mpz_init_set(q1
, q
); /* q1 = q */
620 mpz_sub_ui(q1
, q1
, 1); /* q1 = q1 -1 */
621 mpz_gcd(t
, m
, q1
); /* t = gcd(p-1, q-1) */
622 mpz_mul(m
, m
, q1
); /* m = (p-1)*(q-1) */
623 mpz_divexact(m
, m
, t
); /* m = m / t */
624 mpz_gcd(t
, m
, e
); /* t = gcd(m, e) (greatest common divisor) */
626 mpz_invert(d
, e
, m
); /* e has an inverse mod m */
627 if (mpz_cmp_ui(d
, 0) < 0) /* make sure d is positive */
631 mpz_sub_ui(t
, p
, 1); /* t = p-1 */
632 mpz_mod(exp1
, d
, t
); /* exp1 = d mod p-1 */
633 mpz_sub_ui(t
, q
, 1); /* t = q-1 */
634 mpz_mod(exp2
, d
, t
); /* exp2 = d mod q-1 */
636 mpz_invert(coeff
, q
, p
); /* coeff = q^-1 mod p */
637 if (mpz_cmp_ui(coeff
, 0) < 0) /* make coeff d is positive */
639 mpz_add(coeff
, coeff
, p
);
652 *(this->exp1
) = *exp1
;
653 *(this->exp2
) = *exp2
;
654 *(this->coeff
) = *coeff
;
656 /* set key size in bytes */
659 return &this->public;
665 rsa_private_key_t
*rsa_private_key_create_from_chunk(chunk_t blob
)
671 private_rsa_private_key_t
*this;
673 this = rsa_private_key_create_empty();
680 mpz_init(this->exp1
);
681 mpz_init(this->exp2
);
682 mpz_init(this->coeff
);
684 asn1_init(&ctx
, blob
, 0, FALSE
);
686 while (objectID
< PRIV_KEY_ROOF
)
688 if (!extract_object(privkey_objects
, &objectID
, &object
, &level
, &ctx
))
695 case PRIV_KEY_VERSION
:
696 if (object
.len
> 0 && *object
.ptr
!= 0)
702 case PRIV_KEY_MODULUS
:
703 mpz_import(this->n
, object
.len
, 1, 1, 1, 0, object
.ptr
);
705 case PRIV_KEY_PUB_EXP
:
706 mpz_import(this->e
, object
.len
, 1, 1, 1, 0, object
.ptr
);
708 case PRIV_KEY_PRIV_EXP
:
709 mpz_import(this->d
, object
.len
, 1, 1, 1, 0, object
.ptr
);
711 case PRIV_KEY_PRIME1
:
712 mpz_import(this->p
, object
.len
, 1, 1, 1, 0, object
.ptr
);
714 case PRIV_KEY_PRIME2
:
715 mpz_import(this->q
, object
.len
, 1, 1, 1, 0, object
.ptr
);
718 mpz_import(this->exp1
, object
.len
, 1, 1, 1, 0, object
.ptr
);
721 mpz_import(this->exp2
, object
.len
, 1, 1, 1, 0, object
.ptr
);
724 mpz_import(this->coeff
, object
.len
, 1, 1, 1, 0, object
.ptr
);
730 this->k
= (mpz_sizeinbase(this->n
, 2) + 7) / 8;
732 /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
734 chunk_t publicKeyInfo
= rsa_public_key_info_to_asn1(this->n
, this->e
);
735 hasher_t
*hasher
= hasher_create(HASH_SHA1
);
737 hasher
->allocate_hash(hasher
, publicKeyInfo
, &this->keyid
);
738 hasher
->destroy(hasher
);
739 free(publicKeyInfo
.ptr
);
742 if (check(this) != SUCCESS
)
749 return &this->public;
756 rsa_private_key_t
*rsa_private_key_create_from_file(char *filename
, char *passphrase
)
759 chunk_t chunk
= CHUNK_INITIALIZER
;
760 rsa_private_key_t
*key
= NULL
;
762 if (!pem_asn1_load_file(filename
, passphrase
, "private key", &chunk
, &pgp
))
765 key
= rsa_private_key_create_from_chunk(chunk
);