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 * defined in rsa_public_key.c
39 extern chunk_t
rsa_public_key_info_to_asn1(const mpz_t n
, const mpz_t e
);
42 * Public exponent to use for key generation.
44 #define PUBLIC_EXPONENT 0x10001
46 typedef struct private_rsa_private_key_t private_rsa_private_key_t
;
49 * Private data of a rsa_private_key_t object.
51 struct private_rsa_private_key_t
{
53 * Public interface for this signer.
55 rsa_private_key_t
public;
58 * Version of key, as encoded in PKCS#1
98 * Private coefficient.
108 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
114 * @brief Implements the RSADP algorithm specified in PKCS#1.
116 * @param this calling object
117 * @param data data to process
118 * @return processed data
120 chunk_t (*rsadp
) (private_rsa_private_key_t
*this, chunk_t data
);
123 * @brief Implements the RSASP1 algorithm specified in PKCS#1.
124 * @param this calling object
125 * @param data data to process
126 * @return processed data
128 chunk_t (*rsasp1
) (private_rsa_private_key_t
*this, chunk_t data
);
131 * @brief Generate a prime value.
133 * @param this calling object
134 * @param prime_size size of the prime, in bytes
135 * @param[out] prime uninitialized mpz
137 status_t (*compute_prime
) (private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
);
141 /* ASN.1 definition of a PKCS#1 RSA private key */
142 static const asn1Object_t privkey_objects
[] = {
143 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
144 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
145 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
146 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
147 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
148 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
149 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
150 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
151 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
152 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
153 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
154 ASN1_LOOP
}, /* 10 */
155 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
156 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
157 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
158 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
159 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
} /* 15 */
162 #define PRIV_KEY_VERSION 1
163 #define PRIV_KEY_MODULUS 2
164 #define PRIV_KEY_PUB_EXP 3
165 #define PRIV_KEY_PRIV_EXP 4
166 #define PRIV_KEY_PRIME1 5
167 #define PRIV_KEY_PRIME2 6
168 #define PRIV_KEY_EXP1 7
169 #define PRIV_KEY_EXP2 8
170 #define PRIV_KEY_COEFF 9
171 #define PRIV_KEY_ROOF 16
173 static private_rsa_private_key_t
*rsa_private_key_create_empty(void);
176 * Auxiliary function overwriting private key material with
177 * pseudo-random bytes before releasing it
179 static mpz_clear_randomized(mpz_t z
)
181 size_t len
= mpz_size(z
) * GMP_LIMB_BITS
/ BITS_PER_BYTE
;
182 u_int8_t
*random_bytes
= alloca(len
);
184 randomizer_t
*randomizer
= randomizer_create();
186 randomizer
->get_pseudo_random_bytes(randomizer
, len
, random_bytes
);
188 /* overwrite mpz_t with pseudo-random bytes before clearing it */
189 mpz_import(z
, len
, 1, 1, 1, 0, random_bytes
);
192 randomizer
->destroy(randomizer
);
196 * Implementation of private_rsa_private_key_t.compute_prime.
198 static status_t
compute_prime(private_rsa_private_key_t
*this, size_t prime_size
, mpz_t
*prime
)
200 randomizer_t
*randomizer
;
201 chunk_t random_bytes
;
204 randomizer
= randomizer_create();
209 status
= randomizer
->allocate_random_bytes(randomizer
, prime_size
, &random_bytes
);
210 if (status
!= SUCCESS
)
212 randomizer
->destroy(randomizer
);
217 /* make sure most significant bit is set */
218 random_bytes
.ptr
[0] = random_bytes
.ptr
[0] | 0x80;
220 /* convert chunk to mpz value */
221 mpz_import(*prime
, random_bytes
.len
, 1, 1, 1, 0, random_bytes
.ptr
);
224 mpz_nextprime (*prime
, *prime
);
226 /* free the random_bytes after overwriting them with a pseudo-random sequence */
227 chunk_free_randomized(&random_bytes
);
229 /* check if it isnt too large */
230 while (((mpz_sizeinbase(*prime
, 2) + 7) / 8) > prime_size
);
232 randomizer
->destroy(randomizer
);
237 * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
239 static chunk_t
rsadp(private_rsa_private_key_t
*this, chunk_t data
)
247 mpz_import(t1
, data
.len
, 1, 1, 1, 0, data
.ptr
);
249 mpz_powm(t2
, t1
, this->exp1
, this->p
); /* m1 = c^dP mod p */
250 mpz_powm(t1
, t1
, this->exp2
, this->q
); /* m2 = c^dQ mod Q */
251 mpz_sub(t2
, t2
, t1
); /* h = qInv (m1 - m2) mod p */
252 mpz_mod(t2
, t2
, this->p
);
253 mpz_mul(t2
, t2
, this->coeff
);
254 mpz_mod(t2
, t2
, this->p
);
256 mpz_mul(t2
, t2
, this->q
); /* m = m2 + h q */
259 decrypted
.len
= this->k
;
260 decrypted
.ptr
= mpz_export(NULL
, NULL
, 1, decrypted
.len
, 1, 0, t1
);
262 mpz_clear_randomized(t1
);
263 mpz_clear_randomized(t2
);
269 * Implementation of rsa_private_key.build_emsa_signature.
271 static status_t
build_emsa_pkcs1_signature(private_rsa_private_key_t
*this,
272 hash_algorithm_t hash_algorithm
,
273 chunk_t data
, chunk_t
*signature
)
276 chunk_t em
, encoded_hash
, hash_id
, hash
;
278 /* get oid string prepended to hash */
279 switch (hash_algorithm
)
283 hash_id
=ASN1_md2_id
;
288 hash_id
= ASN1_md5_id
;
293 hash_id
= ASN1_sha1_id
;
298 hash_id
= ASN1_sha256_id
;
303 hash_id
= ASN1_sha384_id
;
308 hash_id
= ASN1_sha512_id
;
313 return NOT_SUPPORTED
;
318 hasher
= hasher_create(hash_algorithm
);
321 return NOT_SUPPORTED
;
325 hasher
->allocate_hash(hasher
, data
, &hash
);
326 hasher
->destroy(hasher
);
328 /* build DER-encoded hash */
329 encoded_hash
= asn1_wrap(ASN1_SEQUENCE
, "cm",
331 asn1_simple_object(ASN1_OCTET_STRING
, hash
)
334 /* build chunk to rsa-decrypt:
335 * EM = 0x00 || 0x01 || PS || 0x00 || T.
336 * PS = 0xFF padding, with length to fill em
340 em
.ptr
= malloc(em
.len
);
342 /* fill em with padding */
343 memset(em
.ptr
, 0xFF, em
.len
);
344 /* set magic bytes */
347 *(em
.ptr
+ em
.len
- encoded_hash
.len
- 1) = 0x00;
348 /* set DER-encoded hash */
349 memcpy(em
.ptr
+ em
.len
- encoded_hash
.len
, encoded_hash
.ptr
, encoded_hash
.len
);
351 /* build signature */
352 *signature
= this->rsasp1(this, em
);
354 free(encoded_hash
.ptr
);
361 * Implementation of rsa_private_key.save_key.
363 static status_t
save_key(private_rsa_private_key_t
*this, char *file
)
365 return NOT_SUPPORTED
;
369 * Implementation of rsa_private_key.get_public_key.
371 rsa_public_key_t
*get_public_key(private_rsa_private_key_t
*this)
377 * Implementation of rsa_private_key.belongs_to.
379 static bool belongs_to(private_rsa_private_key_t
*this, rsa_public_key_t
*public)
381 return chunk_equals(this->keyid
, public->get_keyid(public));
385 * Check the loaded key if it is valid and usable
388 static status_t
check(private_rsa_private_key_t
*this)
391 status_t status
= SUCCESS
;
393 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
394 * We actually require more (for security).
401 /* we picked a max modulus size to simplify buffer allocation */
402 if (this->k
> 8192/8)
411 /* check that n == p * q */
412 mpz_mul(u
, this->p
, this->q
);
413 if (mpz_cmp(u
, this->n
) != 0)
418 /* check that e divides neither p-1 nor q-1 */
419 mpz_sub_ui(t
, this->p
, 1);
420 mpz_mod(t
, t
, this->e
);
421 if (mpz_cmp_ui(t
, 0) == 0)
426 mpz_sub_ui(t
, this->q
, 1);
427 mpz_mod(t
, t
, this->e
);
428 if (mpz_cmp_ui(t
, 0) == 0)
433 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
434 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
435 mpz_sub_ui(q1
, this->q
, 1);
436 mpz_sub_ui(u
, this->p
, 1);
437 mpz_gcd(t
, u
, q1
); /* t := gcd(p-1, q-1) */
438 mpz_mul(u
, u
, q1
); /* u := (p-1) * (q-1) */
439 mpz_divexact(u
, u
, t
); /* u := lcm(p-1, q-1) */
441 mpz_mul(t
, this->d
, this->e
);
443 if (mpz_cmp_ui(t
, 1) != 0)
448 /* check that exp1 is d mod (p-1) */
449 mpz_sub_ui(u
, this->p
, 1);
450 mpz_mod(t
, this->d
, u
);
451 if (mpz_cmp(t
, this->exp1
) != 0)
456 /* check that exp2 is d mod (q-1) */
457 mpz_sub_ui(u
, this->q
, 1);
458 mpz_mod(t
, this->d
, u
);
459 if (mpz_cmp(t
, this->exp2
) != 0)
464 /* check that coeff is (q^-1) mod p */
465 mpz_mul(t
, this->coeff
, this->q
);
466 mpz_mod(t
, t
, this->p
);
467 if (mpz_cmp_ui(t
, 1) != 0)
472 mpz_clear_randomized(t
);
473 mpz_clear_randomized(u
);
474 mpz_clear_randomized(q1
);
479 * Implementation of rsa_private_key.destroy.
481 static void destroy(private_rsa_private_key_t
*this)
483 mpz_clear_randomized(this->n
);
484 mpz_clear_randomized(this->e
);
485 mpz_clear_randomized(this->p
);
486 mpz_clear_randomized(this->q
);
487 mpz_clear_randomized(this->d
);
488 mpz_clear_randomized(this->exp1
);
489 mpz_clear_randomized(this->exp2
);
490 mpz_clear_randomized(this->coeff
);
491 chunk_free_randomized(&this->keyid
);
496 * Internal generic constructor
498 static private_rsa_private_key_t
*rsa_private_key_create_empty(void)
500 private_rsa_private_key_t
*this = malloc_thing(private_rsa_private_key_t
);
502 /* public functions */
503 this->public.build_emsa_pkcs1_signature
= (status_t (*) (rsa_private_key_t
*,hash_algorithm_t
,chunk_t
,chunk_t
*))build_emsa_pkcs1_signature
;
504 this->public.save_key
= (status_t (*) (rsa_private_key_t
*,char*))save_key
;
505 this->public.get_public_key
= (rsa_public_key_t
*(*) (rsa_private_key_t
*))get_public_key
;
506 this->public.belongs_to
= (bool (*) (rsa_private_key_t
*,rsa_public_key_t
*))belongs_to
;
507 this->public.destroy
= (void (*) (rsa_private_key_t
*))destroy
;
509 /* private functions */
511 this->rsasp1
= rsadp
; /* same algorithm */
512 this->compute_prime
= compute_prime
;
514 this->keyid
= chunk_empty
;
522 rsa_private_key_t
*rsa_private_key_create(size_t key_size
)
524 mpz_t p
, q
, n
, e
, d
, exp1
, exp2
, coeff
;
526 private_rsa_private_key_t
*this;
528 this = rsa_private_key_create_empty();
529 key_size
= key_size
/ 8;
531 /* Get values of primes p and q */
532 if (this->compute_prime(this, key_size
/2, &p
) != SUCCESS
)
537 if (this->compute_prime(this, key_size
/2, &q
) != SUCCESS
)
551 /* Swapping Primes so p is larger then q */
552 if (mpz_cmp(p
, q
) < 0)
557 mpz_mul(n
, p
, q
); /* n = p*q */
558 mpz_init_set_ui(e
, PUBLIC_EXPONENT
); /* assign public exponent */
559 mpz_init_set(m
, p
); /* m = p */
560 mpz_sub_ui(m
, m
, 1); /* m = m -1 */
561 mpz_init_set(q1
, q
); /* q1 = q */
562 mpz_sub_ui(q1
, q1
, 1); /* q1 = q1 -1 */
563 mpz_gcd(t
, m
, q1
); /* t = gcd(p-1, q-1) */
564 mpz_mul(m
, m
, q1
); /* m = (p-1)*(q-1) */
565 mpz_divexact(m
, m
, t
); /* m = m / t */
566 mpz_gcd(t
, m
, e
); /* t = gcd(m, e) (greatest common divisor) */
568 mpz_invert(d
, e
, m
); /* e has an inverse mod m */
569 if (mpz_cmp_ui(d
, 0) < 0) /* make sure d is positive */
573 mpz_sub_ui(t
, p
, 1); /* t = p-1 */
574 mpz_mod(exp1
, d
, t
); /* exp1 = d mod p-1 */
575 mpz_sub_ui(t
, q
, 1); /* t = q-1 */
576 mpz_mod(exp2
, d
, t
); /* exp2 = d mod q-1 */
578 mpz_invert(coeff
, q
, p
); /* coeff = q^-1 mod p */
579 if (mpz_cmp_ui(coeff
, 0) < 0) /* make coeff d is positive */
581 mpz_add(coeff
, coeff
, p
);
584 mpz_clear_randomized(q1
);
585 mpz_clear_randomized(m
);
586 mpz_clear_randomized(t
);
594 *(this->exp1
) = *exp1
;
595 *(this->exp2
) = *exp2
;
596 *(this->coeff
) = *coeff
;
598 /* set key size in bytes */
601 return &this->public;
607 rsa_private_key_t
*rsa_private_key_create_from_chunk(chunk_t blob
)
613 private_rsa_private_key_t
*this;
615 this = rsa_private_key_create_empty();
622 mpz_init(this->exp1
);
623 mpz_init(this->exp2
);
624 mpz_init(this->coeff
);
626 asn1_init(&ctx
, blob
, 0, FALSE
, TRUE
);
628 while (objectID
< PRIV_KEY_ROOF
)
630 if (!extract_object(privkey_objects
, &objectID
, &object
, &level
, &ctx
))
637 case PRIV_KEY_VERSION
:
638 if (object
.len
> 0 && *object
.ptr
!= 0)
644 case PRIV_KEY_MODULUS
:
645 mpz_import(this->n
, object
.len
, 1, 1, 1, 0, object
.ptr
);
647 case PRIV_KEY_PUB_EXP
:
648 mpz_import(this->e
, object
.len
, 1, 1, 1, 0, object
.ptr
);
650 case PRIV_KEY_PRIV_EXP
:
651 mpz_import(this->d
, object
.len
, 1, 1, 1, 0, object
.ptr
);
653 case PRIV_KEY_PRIME1
:
654 mpz_import(this->p
, object
.len
, 1, 1, 1, 0, object
.ptr
);
656 case PRIV_KEY_PRIME2
:
657 mpz_import(this->q
, object
.len
, 1, 1, 1, 0, object
.ptr
);
660 mpz_import(this->exp1
, object
.len
, 1, 1, 1, 0, object
.ptr
);
663 mpz_import(this->exp2
, object
.len
, 1, 1, 1, 0, object
.ptr
);
666 mpz_import(this->coeff
, object
.len
, 1, 1, 1, 0, object
.ptr
);
672 this->k
= (mpz_sizeinbase(this->n
, 2) + 7) / 8;
674 /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
676 chunk_t publicKeyInfo
= rsa_public_key_info_to_asn1(this->n
, this->e
);
677 hasher_t
*hasher
= hasher_create(HASH_SHA1
);
679 hasher
->allocate_hash(hasher
, publicKeyInfo
, &this->keyid
);
680 hasher
->destroy(hasher
);
681 free(publicKeyInfo
.ptr
);
684 if (check(this) != SUCCESS
)
691 return &this->public;
698 rsa_private_key_t
*rsa_private_key_create_from_file(char *filename
, chunk_t
*passphrase
)
701 chunk_t chunk
= chunk_empty
;
702 rsa_private_key_t
*key
= NULL
;
704 if (!pem_asn1_load_file(filename
, passphrase
, "private key", &chunk
, &pgp
))
707 key
= rsa_private_key_create_from_chunk(chunk
);
708 chunk_free_randomized(&chunk
);