]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
credentials: Added void *params to public_key encrypt() and private_key decrypt(...
[people/ms/strongswan.git] / src / libstrongswan / plugins / gmp / gmp_rsa_private_key.c
CommitLineData
552cc11b 1/*
5955db5b 2 * Copyright (C) 2017-2018 Tobias Brunner
552cc11b 3 * Copyright (C) 2005 Jan Hutter
48b23d06 4 * Copyright (C) 2005-2009 Martin Willi
e36af6fc 5 * Copyright (C) 2012-2019 Andreas Steffen
48b23d06 6 * HSR Hochschule fuer Technik Rapperswil
552cc11b
MW
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
552cc11b
MW
17 */
18
19#include <gmp.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#include <string.h>
23
24#include "gmp_rsa_private_key.h"
25#include "gmp_rsa_public_key.h"
26
f05b4272 27#include <utils/debug.h>
d3d7e46b 28#include <asn1/oid.h>
552cc11b 29#include <asn1/asn1.h>
d3d7e46b 30#include <asn1/asn1_parser.h>
154ee7f6 31#include <credentials/keys/signature_params.h>
552cc11b 32
3e35a6e7
MW
33#ifdef HAVE_MPZ_POWM_SEC
34# undef mpz_powm
35# define mpz_powm mpz_powm_sec
36#endif
37
552cc11b
MW
38/**
39 * Public exponent to use for key generation.
40 */
41#define PUBLIC_EXPONENT 0x10001
42
43typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
44
45/**
46 * Private data of a gmp_rsa_private_key_t object.
47 */
48struct private_gmp_rsa_private_key_t {
49 /**
50 * Public interface for this signer.
51 */
52 gmp_rsa_private_key_t public;
7daf5226 53
552cc11b
MW
54 /**
55 * Public modulus.
56 */
57 mpz_t n;
7daf5226 58
552cc11b
MW
59 /**
60 * Public exponent.
61 */
62 mpz_t e;
7daf5226 63
552cc11b
MW
64 /**
65 * Private prime 1.
66 */
67 mpz_t p;
7daf5226 68
552cc11b
MW
69 /**
70 * Private Prime 2.
71 */
72 mpz_t q;
7daf5226 73
552cc11b 74 /**
48b23d06
AS
75 * Carmichael function m = lambda(n) = lcm(p-1,q-1).
76 */
77 mpz_t m;
78
79 /**
80 * Private exponent and optional secret sharing polynomial coefficients.
552cc11b 81 */
48b23d06 82 mpz_t *d;
7daf5226 83
552cc11b
MW
84 /**
85 * Private exponent 1.
86 */
87 mpz_t exp1;
7daf5226 88
552cc11b
MW
89 /**
90 * Private exponent 2.
91 */
92 mpz_t exp2;
7daf5226 93
552cc11b
MW
94 /**
95 * Private coefficient.
96 */
97 mpz_t coeff;
7daf5226 98
48b23d06
AS
99 /**
100 * Total number of private key shares
101 */
102 u_int shares;
103
104 /**
105 * Secret sharing threshold
106 */
107 u_int threshold;
108
109 /**
110 * Optional verification key (threshold > 1).
111 */
112 mpz_t v;
113
552cc11b
MW
114 /**
115 * Keysize in bytes.
116 */
117 size_t k;
7daf5226 118
552cc11b
MW
119 /**
120 * reference count
121 */
741680d1 122 refcount_t ref;
552cc11b
MW
123};
124
552cc11b 125/**
741680d1 126 * Convert a MP integer into a chunk_t
552cc11b 127 */
741680d1
MW
128chunk_t gmp_mpz_to_chunk(const mpz_t value)
129{
130 chunk_t n;
7daf5226 131
741680d1
MW
132 n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE;
133 n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
134 if (n.ptr == NULL)
135 { /* if we have zero in "value", gmp returns NULL */
136 n.len = 0;
137 }
138 return n;
139}
552cc11b
MW
140
141/**
6a365f07 142 * Auxiliary function overwriting private key material with zero bytes
552cc11b 143 */
741680d1 144static void mpz_clear_sensitive(mpz_t z)
552cc11b
MW
145{
146 size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
b12c53ce 147 uint8_t *zeros = alloca(len);
7daf5226 148
48b23d06 149 memset(zeros, 0, len);
6a365f07 150 /* overwrite mpz_t with zero bytes before clearing it */
48b23d06 151 mpz_import(z, len, 1, 1, 1, 0, zeros);
552cc11b 152 mpz_clear(z);
552cc11b
MW
153}
154
155/**
156 * Create a mpz prime of at least prime_size
157 */
e36af6fc 158static status_t compute_prime(drbg_t *drbg, size_t prime_size, bool safe, mpz_t *p, mpz_t *q)
552cc11b 159{
552cc11b 160 chunk_t random_bytes;
48b23d06 161 int count = 0;
7daf5226 162
48b23d06
AS
163 mpz_init(*p);
164 mpz_init(*q);
e36af6fc 165 random_bytes = chunk_alloc(prime_size);
168ee460 166
552cc11b
MW
167 do
168 {
e36af6fc 169 if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
5025135f
TB
170 {
171 DBG1(DBG_LIB, "failed to allocate random prime");
48b23d06
AS
172 mpz_clear(*p);
173 mpz_clear(*q);
e36af6fc 174 chunk_free(&random_bytes);
5025135f
TB
175 return FAILED;
176 }
7daf5226 177
168ee460
AS
178 /* make sure the two most significant bits are set */
179 if (safe)
180 {
181 random_bytes.ptr[0] &= 0x7F;
182 random_bytes.ptr[0] |= 0x60;
48b23d06 183 mpz_import(*q, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
168ee460
AS
184 do
185 {
48b23d06
AS
186 count++;
187 mpz_nextprime (*q, *q);
188 mpz_mul_ui(*p, *q, 2);
189 mpz_add_ui(*p, *p, 1);
168ee460 190 }
48b23d06
AS
191 while (mpz_probab_prime_p(*p, 10) == 0);
192 DBG2(DBG_LIB, "safe prime found after %d iterations", count);
168ee460
AS
193 }
194 else
195 {
196 random_bytes.ptr[0] |= 0xC0;
48b23d06
AS
197 mpz_import(*p, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
198 mpz_nextprime (*p, *p);
168ee460 199 }
552cc11b 200 }
168ee460 201 /* check if the prime isn't too large */
48b23d06 202 while (((mpz_sizeinbase(*p, 2) + 7) / 8) > prime_size);
7daf5226 203
e36af6fc 204 chunk_clear(&random_bytes);
48b23d06 205
ef33a4ab 206 /* additionally return p-1 */
48b23d06 207 mpz_sub_ui(*q, *p, 1);
168ee460 208
552cc11b
MW
209 return SUCCESS;
210}
211
212/**
213 * PKCS#1 RSADP function
214 */
215static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
216{
217 mpz_t t1, t2;
218 chunk_t decrypted;
7daf5226 219
552cc11b
MW
220 mpz_init(t1);
221 mpz_init(t2);
7daf5226 222
552cc11b 223 mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
7daf5226 224
552cc11b
MW
225 mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
226 mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
227 mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
228 mpz_mod(t2, t2, this->p);
229 mpz_mul(t2, t2, this->coeff);
230 mpz_mod(t2, t2, this->p);
7daf5226 231
552cc11b
MW
232 mpz_mul(t2, t2, this->q); /* m = m2 + h q */
233 mpz_add(t1, t1, t2);
7daf5226 234
552cc11b
MW
235 decrypted.len = this->k;
236 decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
73f6886a
MW
237 if (decrypted.ptr == NULL)
238 {
239 decrypted.len = 0;
240 }
7daf5226 241
741680d1
MW
242 mpz_clear_sensitive(t1);
243 mpz_clear_sensitive(t2);
7daf5226 244
552cc11b
MW
245 return decrypted;
246}
247
248/**
249 * PKCS#1 RSASP1 function
250 */
251static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
252{
253 return rsadp(this, data);
254}
255
256/**
5955db5b
TB
257 * Hashes the data and builds the plaintext signature value with EMSA
258 * PKCS#1 v1.5 padding.
259 *
260 * Allocates the signature data.
552cc11b 261 */
5955db5b
TB
262bool gmp_emsa_pkcs1_signature_data(hash_algorithm_t hash_algorithm,
263 chunk_t data, size_t keylen, chunk_t *em)
552cc11b 264{
8b799d55 265 chunk_t digestInfo = chunk_empty;
552cc11b 266
8b799d55 267 if (hash_algorithm != HASH_UNKNOWN)
552cc11b 268 {
8b799d55
AS
269 hasher_t *hasher;
270 chunk_t hash;
271 int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
7daf5226 272
8b799d55
AS
273 if (hash_oid == OID_UNKNOWN)
274 {
275 return FALSE;
276 }
277
278 hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
87dd205b 279 if (!hasher || !hasher->allocate_hash(hasher, data, &hash))
8b799d55 280 {
87dd205b 281 DESTROY_IF(hasher);
8b799d55
AS
282 return FALSE;
283 }
8b799d55 284 hasher->destroy(hasher);
7daf5226 285
8b799d55 286 /* build DER-encoded digestInfo */
eb73685d 287 digestInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
8b799d55 288 asn1_algorithmIdentifier(hash_oid),
5955db5b
TB
289 asn1_wrap(ASN1_OCTET_STRING, "m", hash));
290
8b799d55
AS
291 data = digestInfo;
292 }
552cc11b 293
129ab919 294 if (keylen < 11 || data.len > keylen - 11)
3176e442 295 {
5955db5b
TB
296 chunk_free(&digestInfo);
297 DBG1(DBG_LIB, "signature value of %zu bytes is too long for key of "
298 "%zu bytes", data.len, keylen);
3176e442
MW
299 return FALSE;
300 }
7daf5226 301
5955db5b
TB
302 /* EM = 0x00 || 0x01 || PS || 0x00 || T.
303 * PS = 0xFF padding, with length to fill em (at least 8 bytes)
552cc11b
MW
304 * T = encoded_hash
305 */
5955db5b 306 *em = chunk_alloc(keylen);
7daf5226 307
552cc11b 308 /* fill em with padding */
5955db5b 309 memset(em->ptr, 0xFF, em->len);
552cc11b 310 /* set magic bytes */
5955db5b
TB
311 *(em->ptr) = 0x00;
312 *(em->ptr+1) = 0x01;
313 *(em->ptr + em->len - data.len - 1) = 0x00;
314 /* set encoded hash */
315 memcpy(em->ptr + em->len - data.len, data.ptr, data.len);
316
317 chunk_clear(&digestInfo);
318 return TRUE;
319}
320
321/**
322 * Build a signature using the PKCS#1 EMSA scheme
323 */
324static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
325 hash_algorithm_t hash_algorithm,
326 chunk_t data, chunk_t *signature)
327{
328 chunk_t em;
329
330 if (!gmp_emsa_pkcs1_signature_data(hash_algorithm, data, this->k, &em))
331 {
332 return FALSE;
333 }
552cc11b
MW
334
335 /* build signature */
336 *signature = rsasp1(this, em);
7daf5226 337
5955db5b 338 chunk_free(&em);
7daf5226 339 return TRUE;
552cc11b
MW
340}
341
154ee7f6
TB
342/**
343 * Build a signature using the PKCS#1 EMSA PSS scheme
344 */
345static bool build_emsa_pss_signature(private_gmp_rsa_private_key_t *this,
346 rsa_pss_params_t *params, chunk_t data,
347 chunk_t *signature)
348{
349 ext_out_function_t xof;
350 hasher_t *hasher = NULL;
351 rng_t *rng = NULL;
352 xof_t *mgf = NULL;
353 chunk_t hash, salt = chunk_empty, m, ps, db, dbmask, em;
354 size_t embits, emlen, maskbits;
355 bool success = FALSE;
356
357 if (!params)
358 {
359 return FALSE;
360 }
126fd8af
TB
361 xof = xof_mgf1_from_hash_algorithm(params->mgf1_hash);
362 if (xof == XOF_UNDEFINED)
154ee7f6 363 {
126fd8af
TB
364 DBG1(DBG_LIB, "%N is not supported for MGF1", hash_algorithm_names,
365 params->mgf1_hash);
366 return FALSE;
154ee7f6
TB
367 }
368 /* emBits = modBits - 1 */
369 embits = mpz_sizeinbase(this->n, 2) - 1;
370 /* emLen = ceil(emBits/8) */
371 emlen = (embits + 7) / BITS_PER_BYTE;
372 /* mHash = Hash(M) */
373 hasher = lib->crypto->create_hasher(lib->crypto, params->hash);
374 if (!hasher)
375 {
376 DBG1(DBG_LIB, "hash algorithm %N not supported",
377 hash_algorithm_names, params->hash);
378 return FALSE;
379 }
380 hash = chunk_alloca(hasher->get_hash_size(hasher));
381 if (!hasher->get_hash(hasher, data, hash.ptr))
382 {
383 goto error;
384 }
385
ecfe6755 386 salt.len = params->salt_len;
f241a981
TB
387 if (params->salt.len)
388 {
389 salt = params->salt;
390 }
154ee7f6
TB
391 if (emlen < (hash.len + salt.len + 2))
392 { /* too long */
393 goto error;
394 }
f241a981 395 if (salt.len && !params->salt.len)
154ee7f6
TB
396 {
397 salt = chunk_alloca(salt.len);
398 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
399 if (!rng || !rng->get_bytes(rng, salt.len, salt.ptr))
400 {
401 goto error;
402 }
403 }
404 /* M' = 0x0000000000000000 | mHash | salt */
405 m = chunk_cata("ccc",
406 chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
407 hash, salt);
408 /* H = Hash(M') */
409 if (!hasher->get_hash(hasher, m, hash.ptr))
410 {
411 goto error;
412 }
413 /* PS = 00...<padding depending on hash and salt length> */
414 ps = chunk_alloca(emlen - salt.len - hash.len - 2);
415 memset(ps.ptr, 0, ps.len);
416 /* DB = PS | 0x01 | salt */
417 db = chunk_cata("ccc", ps, chunk_from_chars(0x01), salt);
418 /* dbMask = MGF(H, emLen - hLen - 1) */
419 mgf = lib->crypto->create_xof(lib->crypto, xof);
420 dbmask = chunk_alloca(db.len);
421 if (!mgf)
422 {
423 DBG1(DBG_LIB, "%N not supported", ext_out_function_names, xof);
424 goto error;
425 }
426 if (!mgf->set_seed(mgf, hash) ||
427 !mgf->get_bytes(mgf, dbmask.len, dbmask.ptr))
428 {
429 goto error;
430 }
431 /* maskedDB = DB xor dbMask */
432 memxor(db.ptr, dbmask.ptr, db.len);
433 /* zero out unused bits */
434 maskbits = (8 * emlen) - embits;
435 if (maskbits)
436 {
437 db.ptr[0] &= (0xff >> maskbits);
438 }
439 /* EM = maskedDB | H | 0xbc */
440 em = chunk_cata("ccc", db, hash, chunk_from_chars(0xbc));
441 /* S = RSASP1(K, EM) */
442 *signature = rsasp1(this, em);
443 success = TRUE;
444
445error:
446 DESTROY_IF(hasher);
447 DESTROY_IF(rng);
448 DESTROY_IF(mgf);
449 return success;
450}
451
876b61e1
MW
452METHOD(private_key_t, get_type, key_type_t,
453 private_gmp_rsa_private_key_t *this)
552cc11b
MW
454{
455 return KEY_RSA;
456}
457
876b61e1
MW
458METHOD(private_key_t, sign, bool,
459 private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
de280c2e 460 void *params, chunk_t data, chunk_t *signature)
552cc11b
MW
461{
462 switch (scheme)
463 {
8b799d55
AS
464 case SIGN_RSA_EMSA_PKCS1_NULL:
465 return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
40f2589a 466 case SIGN_RSA_EMSA_PKCS1_SHA2_224:
b6f739c1 467 return build_emsa_pkcs1_signature(this, HASH_SHA224, data, signature);
40f2589a 468 case SIGN_RSA_EMSA_PKCS1_SHA2_256:
552cc11b 469 return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
40f2589a 470 case SIGN_RSA_EMSA_PKCS1_SHA2_384:
552cc11b 471 return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
40f2589a 472 case SIGN_RSA_EMSA_PKCS1_SHA2_512:
552cc11b 473 return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
40f2589a
AS
474 case SIGN_RSA_EMSA_PKCS1_SHA3_224:
475 return build_emsa_pkcs1_signature(this, HASH_SHA3_224, data, signature);
476 case SIGN_RSA_EMSA_PKCS1_SHA3_256:
477 return build_emsa_pkcs1_signature(this, HASH_SHA3_256, data, signature);
478 case SIGN_RSA_EMSA_PKCS1_SHA3_384:
479 return build_emsa_pkcs1_signature(this, HASH_SHA3_384, data, signature);
480 case SIGN_RSA_EMSA_PKCS1_SHA3_512:
481 return build_emsa_pkcs1_signature(this, HASH_SHA3_512, data, signature);
482 case SIGN_RSA_EMSA_PKCS1_SHA1:
483 return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
552cc11b
MW
484 case SIGN_RSA_EMSA_PKCS1_MD5:
485 return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
154ee7f6
TB
486 case SIGN_RSA_EMSA_PSS:
487 return build_emsa_pss_signature(this, params, data, signature);
552cc11b 488 default:
8b0e0910 489 DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
552cc11b
MW
490 signature_scheme_names, scheme);
491 return FALSE;
492 }
493}
494
876b61e1 495METHOD(private_key_t, decrypt, bool,
33ddaaab 496 private_gmp_rsa_private_key_t *this, encryption_scheme_t scheme,
4abb29f6 497 void *params, chunk_t crypto, chunk_t *plain)
552cc11b 498{
d615ffdc
AS
499 chunk_t em, stripped;
500 bool success = FALSE;
7daf5226 501
33ddaaab
MW
502 if (scheme != ENCRYPT_RSA_PKCS1)
503 {
504 DBG1(DBG_LIB, "encryption scheme %N not supported",
505 encryption_scheme_names, scheme);
506 return FALSE;
507 }
d615ffdc
AS
508 /* rsa decryption using PKCS#1 RSADP */
509 stripped = em = rsadp(this, crypto);
510
511 /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
512
513 /* check for hex pattern 00 02 in decrypted message */
514 if ((*stripped.ptr++ != 0x00) || (*(stripped.ptr++) != 0x02))
515 {
8b0e0910 516 DBG1(DBG_LIB, "incorrect padding - probably wrong rsa key");
d615ffdc
AS
517 goto end;
518 }
519 stripped.len -= 2;
520
521 /* the plaintext data starts after first 0x00 byte */
522 while (stripped.len-- > 0 && *stripped.ptr++ != 0x00)
523
524 if (stripped.len == 0)
525 {
8b0e0910 526 DBG1(DBG_LIB, "no plaintext data");
d615ffdc
AS
527 goto end;
528 }
529
530 *plain = chunk_clone(stripped);
531 success = TRUE;
532
533end:
534 chunk_clear(&em);
535 return success;
552cc11b
MW
536}
537
a944d209 538METHOD(private_key_t, get_keysize, int,
876b61e1 539 private_gmp_rsa_private_key_t *this)
552cc11b 540{
a944d209 541 return mpz_sizeinbase(this->n, 2);
552cc11b
MW
542}
543
876b61e1
MW
544METHOD(private_key_t, get_public_key, public_key_t*,
545 private_gmp_rsa_private_key_t *this)
552cc11b 546{
831520d8
MW
547 chunk_t n, e;
548 public_key_t *public;
7daf5226 549
831520d8
MW
550 n = gmp_mpz_to_chunk(this->n);
551 e = gmp_mpz_to_chunk(this->e);
7daf5226 552
831520d8
MW
553 public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
554 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
555 chunk_free(&n);
556 chunk_free(&e);
7daf5226 557
831520d8 558 return public;
552cc11b
MW
559}
560
876b61e1
MW
561METHOD(private_key_t, get_encoding, bool,
562 private_gmp_rsa_private_key_t *this, cred_encoding_type_t type,
563 chunk_t *encoding)
741680d1
MW
564{
565 chunk_t n, e, d, p, q, exp1, exp2, coeff;
dd04a68f 566 bool success;
7daf5226 567
741680d1
MW
568 n = gmp_mpz_to_chunk(this->n);
569 e = gmp_mpz_to_chunk(this->e);
48b23d06 570 d = gmp_mpz_to_chunk(*this->d);
741680d1
MW
571 p = gmp_mpz_to_chunk(this->p);
572 q = gmp_mpz_to_chunk(this->q);
573 exp1 = gmp_mpz_to_chunk(this->exp1);
574 exp2 = gmp_mpz_to_chunk(this->exp2);
575 coeff = gmp_mpz_to_chunk(this->coeff);
7daf5226 576
741680d1 577 success = lib->encoding->encode(lib->encoding,
da9724e6
MW
578 type, NULL, encoding, CRED_PART_RSA_MODULUS, n,
579 CRED_PART_RSA_PUB_EXP, e, CRED_PART_RSA_PRIV_EXP, d,
580 CRED_PART_RSA_PRIME1, p, CRED_PART_RSA_PRIME2, q,
581 CRED_PART_RSA_EXP1, exp1, CRED_PART_RSA_EXP2, exp2,
582 CRED_PART_RSA_COEFF, coeff, CRED_PART_END);
741680d1
MW
583 chunk_free(&n);
584 chunk_free(&e);
585 chunk_clear(&d);
586 chunk_clear(&p);
587 chunk_clear(&q);
588 chunk_clear(&exp1);
589 chunk_clear(&exp2);
590 chunk_clear(&coeff);
7daf5226 591
741680d1 592 return success;
552cc11b
MW
593}
594
876b61e1
MW
595METHOD(private_key_t, get_fingerprint, bool,
596 private_gmp_rsa_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
552cc11b 597{
741680d1
MW
598 chunk_t n, e;
599 bool success;
7daf5226 600
741680d1
MW
601 if (lib->encoding->get_cache(lib->encoding, type, this, fp))
602 {
603 return TRUE;
604 }
605 n = gmp_mpz_to_chunk(this->n);
606 e = gmp_mpz_to_chunk(this->e);
7daf5226 607
741680d1 608 success = lib->encoding->encode(lib->encoding, type, this, fp,
da9724e6 609 CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
741680d1
MW
610 chunk_free(&n);
611 chunk_free(&e);
7daf5226 612
741680d1 613 return success;
552cc11b
MW
614}
615
876b61e1
MW
616METHOD(private_key_t, get_ref, private_key_t*,
617 private_gmp_rsa_private_key_t *this)
552cc11b
MW
618{
619 ref_get(&this->ref);
876b61e1 620 return &this->public.key;
552cc11b
MW
621}
622
876b61e1
MW
623METHOD(private_key_t, destroy, void,
624 private_gmp_rsa_private_key_t *this)
552cc11b
MW
625{
626 if (ref_put(&this->ref))
627 {
48b23d06
AS
628 int i;
629
630 mpz_clear(this->n);
631 mpz_clear(this->e);
632 mpz_clear(this->v);
741680d1
MW
633 mpz_clear_sensitive(this->p);
634 mpz_clear_sensitive(this->q);
48b23d06 635 mpz_clear_sensitive(this->m);
741680d1
MW
636 mpz_clear_sensitive(this->exp1);
637 mpz_clear_sensitive(this->exp2);
638 mpz_clear_sensitive(this->coeff);
48b23d06
AS
639
640 for (i = 0; i < this->threshold; i++)
641 {
642 mpz_clear_sensitive(*this->d + i);
643 }
644 free(this->d);
645
741680d1 646 lib->encoding->clear_cache(lib->encoding, this);
552cc11b
MW
647 free(this);
648 }
649}
650
651/**
652 * Check the loaded key if it is valid and usable
653 */
654static status_t check(private_gmp_rsa_private_key_t *this)
655{
48b23d06 656 mpz_t u, p1, q1;
552cc11b 657 status_t status = SUCCESS;
7daf5226 658
552cc11b 659 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
1d56d328
TB
660 * We actually require more (for security).
661 */
8b799d55 662 if (this->k < 512 / BITS_PER_BYTE)
552cc11b 663 {
8b0e0910 664 DBG1(DBG_LIB, "key shorter than 512 bits");
552cc11b
MW
665 return FAILED;
666 }
7daf5226 667
552cc11b 668 /* we picked a max modulus size to simplify buffer allocation */
8b799d55 669 if (this->k > 8192 / BITS_PER_BYTE)
552cc11b 670 {
8b0e0910 671 DBG1(DBG_LIB, "key larger than 8192 bits");
552cc11b
MW
672 return FAILED;
673 }
7daf5226 674
552cc11b 675 mpz_init(u);
48b23d06 676 mpz_init(p1);
552cc11b 677 mpz_init(q1);
7daf5226 678
48b23d06
AS
679 /* precompute p1 = p-1 and q1 = q-1 */
680 mpz_sub_ui(p1, this->p, 1);
681 mpz_sub_ui(q1, this->q, 1);
682
552cc11b
MW
683 /* check that n == p * q */
684 mpz_mul(u, this->p, this->q);
685 if (mpz_cmp(u, this->n) != 0)
686 {
687 status = FAILED;
688 }
7daf5226 689
552cc11b 690 /* check that e divides neither p-1 nor q-1 */
48b23d06
AS
691 mpz_mod(u, p1, this->e);
692 if (mpz_cmp_ui(u, 0) == 0)
552cc11b
MW
693 {
694 status = FAILED;
695 }
7daf5226 696
48b23d06
AS
697 mpz_mod(u, q1, this->e);
698 if (mpz_cmp_ui(u, 0) == 0)
552cc11b
MW
699 {
700 status = FAILED;
701 }
7daf5226 702
552cc11b
MW
703 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
704 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
48b23d06
AS
705 mpz_lcm(this->m, p1, q1);
706 mpz_mul(u, *this->d, this->e);
707 mpz_mod(u, u, this->m);
708 if (mpz_cmp_ui(u, 1) != 0)
552cc11b
MW
709 {
710 status = FAILED;
711 }
7daf5226 712
552cc11b 713 /* check that exp1 is d mod (p-1) */
48b23d06
AS
714 mpz_mod(u, *this->d, p1);
715 if (mpz_cmp(u, this->exp1) != 0)
552cc11b
MW
716 {
717 status = FAILED;
718 }
7daf5226 719
552cc11b 720 /* check that exp2 is d mod (q-1) */
48b23d06
AS
721 mpz_mod(u, *this->d, q1);
722 if (mpz_cmp(u, this->exp2) != 0)
552cc11b
MW
723 {
724 status = FAILED;
725 }
7daf5226 726
552cc11b 727 /* check that coeff is (q^-1) mod p */
48b23d06
AS
728 mpz_mul(u, this->coeff, this->q);
729 mpz_mod(u, u, this->p);
730 if (mpz_cmp_ui(u, 1) != 0)
552cc11b
MW
731 {
732 status = FAILED;
733 }
7daf5226 734
741680d1 735 mpz_clear_sensitive(u);
48b23d06 736 mpz_clear_sensitive(p1);
741680d1 737 mpz_clear_sensitive(q1);
48b23d06 738
552cc11b
MW
739 if (status != SUCCESS)
740 {
8b0e0910 741 DBG1(DBG_LIB, "key integrity tests failed");
552cc11b
MW
742 }
743 return status;
744}
745
746/**
747 * Internal generic constructor
748 */
749static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
750{
876b61e1 751 private_gmp_rsa_private_key_t *this;
7daf5226 752
876b61e1 753 INIT(this,
ba31fe1f
MW
754 .public = {
755 .key = {
756 .get_type = _get_type,
757 .sign = _sign,
758 .decrypt = _decrypt,
759 .get_keysize = _get_keysize,
760 .get_public_key = _get_public_key,
761 .equals = private_key_equals,
762 .belongs_to = private_key_belongs_to,
763 .get_fingerprint = _get_fingerprint,
764 .has_fingerprint = private_key_has_fingerprint,
765 .get_encoding = _get_encoding,
766 .get_ref = _get_ref,
767 .destroy = _destroy,
768 },
876b61e1 769 },
48b23d06 770 .threshold = 1,
876b61e1
MW
771 .ref = 1,
772 );
552cc11b
MW
773 return this;
774}
775
776/**
1086d00e 777 * See header.
552cc11b 778 */
1086d00e 779gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
552cc11b 780{
1086d00e 781 private_gmp_rsa_private_key_t *this;
e36af6fc
AS
782 drbg_type_t drbg_type = DRBG_HMAC_SHA512;
783 drbg_t* drbg;
784 rng_t *rng;
785 u_int strength = 256, key_size = 0, shares = 0, threshold = 1;
786 bool safe_prime = FALSE, drbg_failed = FALSE, invert_failed = FALSE;
787 mpz_t p, q, p1, q1;
788 int i;
789
7daf5226 790
1086d00e
MW
791 while (TRUE)
792 {
793 switch (va_arg(args, builder_part_t))
794 {
795 case BUILD_KEY_SIZE:
796 key_size = va_arg(args, u_int);
797 continue;
168ee460
AS
798 case BUILD_SAFE_PRIMES:
799 safe_prime = TRUE;
800 continue;
48b23d06
AS
801 case BUILD_SHARES:
802 shares = va_arg(args, u_int);
803 continue;
804 case BUILD_THRESHOLD:
805 threshold = va_arg(args, u_int);
806 continue;
1086d00e
MW
807 case BUILD_END:
808 break;
809 default:
810 return NULL;
811 }
812 break;
813 }
814 if (!key_size)
815 {
816 return NULL;
817 }
8b799d55 818 key_size = key_size / BITS_PER_BYTE;
7daf5226 819
11e9d2b8 820 /* Initiate a NIST SP 800-90A DRBG fed by a true rng owned by the drbg */
e36af6fc
AS
821 rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
822 if (!rng)
823 {
824 DBG1(DBG_LIB, "no RNG of quality %N found", rng_quality_names, RNG_TRUE);
825 return NULL;
826 }
827 drbg = lib->crypto->create_drbg(lib->crypto, drbg_type, strength, rng,
828 chunk_empty);
829 if (!drbg)
830 {
831 DBG1(DBG_LIB, "instantiation of %N failed", drbg_type_names, drbg_type);
832 rng->destroy(rng);
833 return NULL;
834 }
835
552cc11b 836 /* Get values of primes p and q */
e36af6fc 837 if (compute_prime(drbg, key_size/2, safe_prime, &p, &p1) != SUCCESS)
552cc11b 838 {
e36af6fc 839 drbg->destroy(drbg);
552cc11b 840 return NULL;
7daf5226 841 }
e36af6fc 842 if (compute_prime(drbg, key_size/2, safe_prime, &q, &q1) != SUCCESS)
552cc11b
MW
843 {
844 mpz_clear(p);
48b23d06 845 mpz_clear(p1);
e36af6fc 846 drbg->destroy(drbg);
552cc11b
MW
847 return NULL;
848 }
7daf5226 849
552cc11b
MW
850 /* Swapping Primes so p is larger then q */
851 if (mpz_cmp(p, q) < 0)
852 {
853 mpz_swap(p, q);
48b23d06 854 mpz_swap(p1, q1);
552cc11b 855 }
7daf5226 856
48b23d06
AS
857 /* Create and initialize RSA private key object */
858 this = gmp_rsa_private_key_create_empty();
e36af6fc
AS
859 *this->p = *p;
860 *this->q = *q;
861
862 /* allocate space for private exponent d with optional threshold scheme */
48b23d06
AS
863 this->shares = shares;
864 this->threshold = threshold;
865 this->d = malloc(threshold * sizeof(mpz_t));
e36af6fc
AS
866 for (i = 0; i < threshold; i++)
867 {
868 mpz_init(this->d[i]);
869 }
552cc11b 870
48b23d06
AS
871 mpz_init_set_ui(this->e, PUBLIC_EXPONENT);
872 mpz_init(this->n);
873 mpz_init(this->m);
874 mpz_init(this->exp1);
875 mpz_init(this->exp2);
876 mpz_init(this->coeff);
877 mpz_init(this->v);
48b23d06 878
e36af6fc
AS
879 mpz_mul(this->n, p, q); /* n = p*q */
880 mpz_lcm(this->m, p1, q1); /* m = lcm(p-1,q-1) */
881 mpz_invert(this->d[0], this->e, this->m); /* e has an inverse mod m */
882 mpz_mod(this->exp1, this->d[0], p1); /* exp1 = d mod p-1 */
883 mpz_mod(this->exp2, this->d[0], q1); /* exp2 = d mod q-1 */
884 mpz_invert(this->coeff, q, p); /* coeff = q^-1 mod p */
48b23d06
AS
885
886 invert_failed = mpz_cmp_ui(this->m, 0) == 0 ||
887 mpz_cmp_ui(this->coeff, 0) == 0;
7daf5226 888
48b23d06
AS
889 /* generate and store random coefficients of secret sharing polynomial */
890 if (threshold > 1)
552cc11b 891 {
48b23d06
AS
892 chunk_t random_bytes;
893 mpz_t u;
48b23d06 894
48b23d06 895 mpz_init(u);
e36af6fc 896 random_bytes = chunk_alloc(key_size);
48b23d06
AS
897
898 for (i = 1; i < threshold; i++)
899 {
e36af6fc 900 if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
48b23d06 901 {
e36af6fc 902 drbg_failed = TRUE;
48b23d06
AS
903 continue;
904 }
e36af6fc
AS
905 mpz_import(this->d[i], random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
906 mpz_mod(this->d[i], this->d[i], this->m);
48b23d06
AS
907 }
908
909 /* generate verification key v as a square number */
910 do
911 {
e36af6fc 912 if (!drbg->generate(drbg, random_bytes.len, random_bytes.ptr))
48b23d06 913 {
e36af6fc 914 drbg_failed = TRUE;
48b23d06
AS
915 break;
916 }
917 mpz_import(this->v, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
918 mpz_mul(this->v, this->v, this->v);
919 mpz_mod(this->v, this->v, this->n);
920 mpz_gcd(u, this->v, this->n);
48b23d06
AS
921 }
922 while (mpz_cmp_ui(u, 1) != 0);
923
924 mpz_clear(u);
e36af6fc 925 chunk_clear(&random_bytes);
552cc11b
MW
926 }
927
48b23d06 928 mpz_clear_sensitive(p1);
741680d1 929 mpz_clear_sensitive(q1);
e36af6fc 930 drbg->destroy(drbg);
552cc11b 931
e36af6fc 932 if (drbg_failed || invert_failed)
48b23d06
AS
933 {
934 DBG1(DBG_LIB, "rsa key generation failed");
935 destroy(this);
936 return NULL;
937 }
7daf5226 938
552cc11b
MW
939 /* set key size in bytes */
940 this->k = key_size;
7daf5226 941
552cc11b
MW
942 return &this->public;
943}
944
bd4df68a
TB
945/**
946 * Recover the primes from n, e and d using the algorithm described in
947 * Appendix C of NIST SP 800-56B.
948 */
949static bool calculate_pq(private_gmp_rsa_private_key_t *this)
950{
951 gmp_randstate_t rstate;
952 mpz_t k, r, g, y, n1, x;
953 int i, t, j;
954 bool success = FALSE;
955
956 gmp_randinit_default(rstate);
4a84fb07
TB
957 mpz_init(k);
958 mpz_init(r);
959 mpz_init(g);
960 mpz_init(y);
961 mpz_init(n1);
962 mpz_init(x);
bd4df68a
TB
963 /* k = (d * e) - 1 */
964 mpz_mul(k, *this->d, this->e);
965 mpz_sub_ui(k, k, 1);
966 if (mpz_odd_p(k))
967 {
968 goto error;
969 }
970 /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
971 mpz_set(r, k);
972 for (t = 0; !mpz_odd_p(r); t++)
973 { /* r = r/2 */
974 mpz_divexact_ui(r, r, 2);
975 }
976 /* we need n-1 below */
977 mpz_sub_ui(n1, this->n, 1);
978 for (i = 0; i < 100; i++)
979 { /* generate random integer g in [0, n-1] */
980 mpz_urandomm(g, rstate, this->n);
981 /* y = g^r mod n */
4a84fb07 982 mpz_powm(y, g, r, this->n);
bd4df68a
TB
983 /* try again if y == 1 or y == n-1 */
984 if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, n1) == 0)
985 {
986 continue;
987 }
988 for (j = 0; j < t; j++)
989 { /* x = y^2 mod n */
990 mpz_powm_ui(x, y, 2, this->n);
991 /* stop if x == 1 */
992 if (mpz_cmp_ui(x, 1) == 0)
993 {
994 goto done;
995 }
996 /* retry with new g if x = n-1 */
997 if (mpz_cmp(x, n1) == 0)
998 {
999 break;
1000 }
1001 /* y = x */
1002 mpz_set(y, x);
1003 }
1004 }
1005 goto error;
1006
1007done:
1008 /* p = gcd(y-1, n) */
1009 mpz_sub_ui(y, y, 1);
1010 mpz_gcd(this->p, y, this->n);
1011 /* q = n/p */
1012 mpz_divexact(this->q, this->n, this->p);
1013 success = TRUE;
1014
1015error:
1016 mpz_clear_sensitive(k);
1017 mpz_clear_sensitive(r);
1018 mpz_clear_sensitive(g);
1019 mpz_clear_sensitive(y);
1020 mpz_clear_sensitive(x);
1021 mpz_clear(n1);
1022 gmp_randclear(rstate);
1023 return success;
1024}
1025
460025e2 1026/**
1086d00e 1027 * See header.
552cc11b 1028 */
1086d00e 1029gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
552cc11b 1030{
1086d00e 1031 private_gmp_rsa_private_key_t *this;
48b23d06 1032 chunk_t n, e, d, p, q, exp1, exp2, coeff;
1086d00e
MW
1033
1034 n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty;
1035 while (TRUE)
1036 {
1037 switch (va_arg(args, builder_part_t))
1038 {
1039 case BUILD_RSA_MODULUS:
1040 n = va_arg(args, chunk_t);
1041 continue;
1042 case BUILD_RSA_PUB_EXP:
1043 e = va_arg(args, chunk_t);
1044 continue;
1045 case BUILD_RSA_PRIV_EXP:
1046 d = va_arg(args, chunk_t);
1047 continue;
1048 case BUILD_RSA_PRIME1:
1049 p = va_arg(args, chunk_t);
1050 continue;
1051 case BUILD_RSA_PRIME2:
1052 q = va_arg(args, chunk_t);
1053 continue;
1054 case BUILD_RSA_EXP1:
1055 exp1 = va_arg(args, chunk_t);
1056 continue;
1057 case BUILD_RSA_EXP2:
1058 exp2 = va_arg(args, chunk_t);
1059 continue;
1060 case BUILD_RSA_COEFF:
1061 coeff = va_arg(args, chunk_t);
1062 continue;
1063 case BUILD_END:
1064 break;
1065 default:
1066 return NULL;
1067 }
1068 break;
1069 }
1070
1071 this = gmp_rsa_private_key_create_empty();
7daf5226 1072
48b23d06 1073 this->d = malloc(sizeof(mpz_t));
552cc11b
MW
1074 mpz_init(this->n);
1075 mpz_init(this->e);
48b23d06 1076 mpz_init(*this->d);
552cc11b
MW
1077 mpz_init(this->p);
1078 mpz_init(this->q);
48b23d06 1079 mpz_init(this->m);
552cc11b
MW
1080 mpz_init(this->exp1);
1081 mpz_init(this->exp2);
1082 mpz_init(this->coeff);
48b23d06 1083 mpz_init(this->v);
7daf5226 1084
7033a70f
MW
1085 mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr);
1086 mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr);
48b23d06 1087 mpz_import(*this->d, d.len, 1, 1, 1, 0, d.ptr);
bd4df68a
TB
1088 if (p.len)
1089 {
1090 mpz_import(this->p, p.len, 1, 1, 1, 0, p.ptr);
1091 }
1092 if (q.len)
1093 {
1094 mpz_import(this->q, q.len, 1, 1, 1, 0, q.ptr);
1095 }
1096 if (!p.len && !q.len)
1097 { /* p and q missing in key, recalculate from n, e and d */
1098 if (!calculate_pq(this))
1099 {
1100 destroy(this);
1101 return NULL;
1102 }
1103 }
1104 else if (!p.len)
1105 { /* p missing in key, recalculate: p = n / q */
1106 mpz_divexact(this->p, this->n, this->q);
1107 }
1108 else if (!q.len)
1109 { /* q missing in key, recalculate: q = n / p */
1110 mpz_divexact(this->q, this->n, this->p);
1111 }
7033a70f
MW
1112 if (!exp1.len)
1113 { /* exp1 missing in key, recalculate: exp1 = d mod (p-1) */
1114 mpz_sub_ui(this->exp1, this->p, 1);
48b23d06 1115 mpz_mod(this->exp1, *this->d, this->exp1);
552cc11b 1116 }
7033a70f 1117 else
d3d7e46b 1118 {
7033a70f 1119 mpz_import(this->exp1, exp1.len, 1, 1, 1, 0, exp1.ptr);
d3d7e46b 1120 }
7033a70f
MW
1121 if (!exp2.len)
1122 { /* exp2 missing in key, recalculate: exp2 = d mod (q-1) */
1123 mpz_sub_ui(this->exp2, this->q, 1);
48b23d06 1124 mpz_mod(this->exp2, *this->d, this->exp2);
8b799d55 1125 }
7033a70f 1126 else
8b799d55 1127 {
7033a70f 1128 mpz_import(this->exp2, exp2.len, 1, 1, 1, 0, exp2.ptr);
8b799d55 1129 }
bd4df68a
TB
1130 if (!coeff.len)
1131 { /* coeff missing in key, recalculate: coeff = q^-1 mod p */
1132 mpz_invert(this->coeff, this->q, this->p);
1133 }
1134 else
1135 {
1136 mpz_import(this->coeff, coeff.len, 1, 1, 1, 0, coeff.ptr);
1137 }
8b799d55 1138 this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
552cc11b
MW
1139 if (check(this) != SUCCESS)
1140 {
1141 destroy(this);
1142 return NULL;
1143 }
1144 return &this->public;
1145}