Add missing ',' between parameters [HEIMDAL-599]
[heimdal.git] / lib / hcrypto / rsa-imath.c
blob4926a0c4e080729a43c7744e302273ab8df21945
1 /*
2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 RCSID("$Id$");
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <krb5-types.h>
43 #include <assert.h>
45 #include <rsa.h>
47 #include <roken.h>
49 #include "imath/imath.h"
50 #include "imath/iprime.h"
52 static void
53 BN2mpz(mpz_t *s, const BIGNUM *bn)
55 size_t len;
56 void *p;
58 mp_int_init(s);
60 len = BN_num_bytes(bn);
61 p = malloc(len);
62 BN_bn2bin(bn, p);
63 mp_int_read_unsigned(s, p, len);
64 free(p);
67 static BIGNUM *
68 mpz2BN(mpz_t *s)
70 size_t size;
71 BIGNUM *bn;
72 void *p;
74 size = mp_int_unsigned_len(s);
75 p = malloc(size);
76 if (p == NULL && size != 0)
77 return NULL;
78 mp_int_to_unsigned(s, p, size);
80 bn = BN_bin2bn(p, size, NULL);
81 free(p);
82 return bn;
85 static int random_num(mp_int, size_t);
87 static void
88 setup_blind(mp_int n, mp_int b, mp_int bi)
90 mp_int_init(b);
91 mp_int_init(bi);
92 random_num(b, mp_int_count_bits(n));
93 mp_int_mod(b, n, b);
94 mp_int_invmod(b, n, bi);
97 static void
98 blind(mp_int in, mp_int b, mp_int e, mp_int n)
100 mpz_t t1;
101 mp_int_init(&t1);
102 /* in' = (in * b^e) mod n */
103 mp_int_exptmod(b, e, n, &t1);
104 mp_int_mul(&t1, in, in);
105 mp_int_mod(in, n, in);
106 mp_int_clear(&t1);
109 static void
110 unblind(mp_int out, mp_int bi, mp_int n)
112 /* out' = (out * 1/b) mod n */
113 mp_int_mul(out, bi, out);
114 mp_int_mod(out, n, out);
117 static mp_result
118 rsa_private_calculate(mp_int in, mp_int p, mp_int q,
119 mp_int dmp1, mp_int dmq1, mp_int iqmp,
120 mp_int out)
122 mpz_t vp, vq, u;
123 mp_int_init(&vp); mp_int_init(&vq); mp_int_init(&u);
125 /* vq = c ^ (d mod (q - 1)) mod q */
126 /* vp = c ^ (d mod (p - 1)) mod p */
127 mp_int_mod(in, p, &u);
128 mp_int_exptmod(&u, dmp1, p, &vp);
129 mp_int_mod(in, q, &u);
130 mp_int_exptmod(&u, dmq1, q, &vq);
132 /* C2 = 1/q mod p (iqmp) */
133 /* u = (vp - vq)C2 mod p. */
134 mp_int_sub(&vp, &vq, &u);
135 if (mp_int_compare_zero(&u) < 0)
136 mp_int_add(&u, p, &u);
137 mp_int_mul(&u, iqmp, &u);
138 mp_int_mod(&u, p, &u);
140 /* c ^ d mod n = vq + u q */
141 mp_int_mul(&u, q, &u);
142 mp_int_add(&u, &vq, out);
144 mp_int_clear(&vp);
145 mp_int_clear(&vq);
146 mp_int_clear(&u);
148 return MP_OK;
155 static int
156 imath_rsa_public_encrypt(int flen, const unsigned char* from,
157 unsigned char* to, RSA* rsa, int padding)
159 unsigned char *p, *p0;
160 mp_result res;
161 size_t size, padlen;
162 mpz_t enc, dec, n, e;
164 if (padding != RSA_PKCS1_PADDING)
165 return -1;
167 size = RSA_size(rsa);
169 if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen)
170 return -2;
172 BN2mpz(&n, rsa->n);
173 BN2mpz(&e, rsa->e);
175 p = p0 = malloc(size - 1);
176 if (p0 == NULL) {
177 mp_int_clear(&e);
178 mp_int_clear(&n);
179 return -3;
182 padlen = size - flen - 3;
184 *p++ = 2;
185 if (RAND_bytes(p, padlen) != 1) {
186 mp_int_clear(&e);
187 mp_int_clear(&n);
188 free(p0);
189 return -4;
191 while(padlen) {
192 if (*p == 0)
193 *p = 1;
194 padlen--;
195 p++;
197 *p++ = 0;
198 memcpy(p, from, flen);
199 p += flen;
200 assert((p - p0) == size - 1);
202 mp_int_init(&enc);
203 mp_int_init(&dec);
204 mp_int_read_unsigned(&dec, p0, size - 1);
205 free(p0);
207 res = mp_int_exptmod(&dec, &e, &n, &enc);
209 mp_int_clear(&dec);
210 mp_int_clear(&e);
211 mp_int_clear(&n);
213 size_t ssize;
214 ssize = mp_int_unsigned_len(&enc);
215 assert(size >= ssize);
216 mp_int_to_unsigned(&enc, to, ssize);
217 size = ssize;
219 mp_int_clear(&enc);
221 return size;
224 static int
225 imath_rsa_public_decrypt(int flen, const unsigned char* from,
226 unsigned char* to, RSA* rsa, int padding)
228 unsigned char *p;
229 mp_result res;
230 size_t size;
231 mpz_t s, us, n, e;
233 if (padding != RSA_PKCS1_PADDING)
234 return -1;
236 if (flen > RSA_size(rsa))
237 return -2;
239 BN2mpz(&n, rsa->n);
240 BN2mpz(&e, rsa->e);
242 #if 0
243 /* Check that the exponent is larger then 3 */
244 if (mp_int_compare_value(&e, 3) <= 0) {
245 mp_int_clear(&n);
246 mp_int_clear(&e);
247 return -3;
249 #endif
251 mp_int_init(&s);
252 mp_int_init(&us);
253 mp_int_read_unsigned(&s, rk_UNCONST(from), flen);
255 if (mp_int_compare(&s, &n) >= 0) {
256 mp_int_clear(&n);
257 mp_int_clear(&e);
258 return -4;
261 res = mp_int_exptmod(&s, &e, &n, &us);
263 mp_int_clear(&s);
264 mp_int_clear(&n);
265 mp_int_clear(&e);
267 if (res != MP_OK)
268 return -5;
269 p = to;
272 size = mp_int_unsigned_len(&us);
273 assert(size <= RSA_size(rsa));
274 mp_int_to_unsigned(&us, p, size);
276 mp_int_clear(&us);
278 /* head zero was skipped by mp_int_to_unsigned */
279 if (*p == 0)
280 return -6;
281 if (*p != 1)
282 return -7;
283 size--; p++;
284 while (size && *p == 0xff) {
285 size--; p++;
287 if (size == 0 || *p != 0)
288 return -8;
289 size--; p++;
291 memmove(to, p, size);
293 return size;
296 static int
297 imath_rsa_private_encrypt(int flen, const unsigned char* from,
298 unsigned char* to, RSA* rsa, int padding)
300 unsigned char *p, *p0;
301 mp_result res;
302 size_t size;
303 mpz_t in, out, n, e, b, bi;
304 int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
306 if (padding != RSA_PKCS1_PADDING)
307 return -1;
309 size = RSA_size(rsa);
311 if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen)
312 return -2;
314 p0 = p = malloc(size);
315 *p++ = 0;
316 *p++ = 1;
317 memset(p, 0xff, size - flen - 3);
318 p += size - flen - 3;
319 *p++ = 0;
320 memcpy(p, from, flen);
321 p += flen;
322 assert((p - p0) == size);
324 BN2mpz(&n, rsa->n);
325 BN2mpz(&e, rsa->e);
327 mp_int_init(&in);
328 mp_int_init(&out);
329 mp_int_read_unsigned(&in, p0, size);
330 free(p0);
332 if(mp_int_compare_zero(&in) < 0 ||
333 mp_int_compare(&in, &n) >= 0) {
334 size = 0;
335 goto out;
338 if (blinding) {
339 setup_blind(&n, &b, &bi);
340 blind(&in, &b, &e, &n);
343 if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
344 mpz_t p, q, dmp1, dmq1, iqmp;
346 BN2mpz(&p, rsa->p);
347 BN2mpz(&q, rsa->q);
348 BN2mpz(&dmp1, rsa->dmp1);
349 BN2mpz(&dmq1, rsa->dmq1);
350 BN2mpz(&iqmp, rsa->iqmp);
352 res = rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out);
354 mp_int_clear(&p);
355 mp_int_clear(&q);
356 mp_int_clear(&dmp1);
357 mp_int_clear(&dmq1);
358 mp_int_clear(&iqmp);
359 } else {
360 mpz_t d;
362 BN2mpz(&d, rsa->d);
363 res = mp_int_exptmod(&in, &d, &n, &out);
364 mp_int_clear(&d);
365 if (res != MP_OK) {
366 size = 0;
367 goto out;
371 if (blinding) {
372 unblind(&out, &bi, &n);
373 mp_int_clear(&b);
374 mp_int_clear(&bi);
378 size_t ssize;
379 ssize = mp_int_unsigned_len(&out);
380 assert(size >= ssize);
381 mp_int_to_unsigned(&out, to, size);
382 size = ssize;
385 out:
386 mp_int_clear(&e);
387 mp_int_clear(&n);
388 mp_int_clear(&in);
389 mp_int_clear(&out);
391 return size;
394 static int
395 imath_rsa_private_decrypt(int flen, const unsigned char* from,
396 unsigned char* to, RSA* rsa, int padding)
398 unsigned char *ptr;
399 mp_result res;
400 size_t size;
401 mpz_t in, out, n, e, b, bi;
402 int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
404 if (padding != RSA_PKCS1_PADDING)
405 return -1;
407 size = RSA_size(rsa);
408 if (flen > size)
409 return -2;
411 mp_int_init(&in);
412 mp_int_init(&out);
414 BN2mpz(&n, rsa->n);
415 BN2mpz(&e, rsa->e);
417 res = mp_int_read_unsigned(&in, rk_UNCONST(from), flen);
418 if (res != MP_OK) {
419 size = -1;
420 goto out;
423 if(mp_int_compare_zero(&in) < 0 ||
424 mp_int_compare(&in, &n) >= 0) {
425 size = 0;
426 goto out;
429 if (blinding) {
430 setup_blind(&n, &b, &bi);
431 blind(&in, &b, &e, &n);
434 if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
435 mpz_t p, q, dmp1, dmq1, iqmp;
437 BN2mpz(&p, rsa->p);
438 BN2mpz(&q, rsa->q);
439 BN2mpz(&dmp1, rsa->dmp1);
440 BN2mpz(&dmq1, rsa->dmq1);
441 BN2mpz(&iqmp, rsa->iqmp);
443 res = rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out);
445 mp_int_clear(&p);
446 mp_int_clear(&q);
447 mp_int_clear(&dmp1);
448 mp_int_clear(&dmq1);
449 mp_int_clear(&iqmp);
450 } else {
451 mpz_t d;
453 if(mp_int_compare_zero(&in) < 0 ||
454 mp_int_compare(&in, &n) >= 0)
455 return MP_RANGE;
457 BN2mpz(&d, rsa->d);
458 res = mp_int_exptmod(&in, &d, &n, &out);
459 mp_int_clear(&d);
460 if (res != MP_OK) {
461 size = 0;
462 goto out;
466 if (blinding) {
467 unblind(&out, &bi, &n);
468 mp_int_clear(&b);
469 mp_int_clear(&bi);
472 ptr = to;
474 size_t ssize;
475 ssize = mp_int_unsigned_len(&out);
476 assert(size >= ssize);
477 mp_int_to_unsigned(&out, ptr, ssize);
478 size = ssize;
481 /* head zero was skipped by mp_int_to_unsigned */
482 if (*ptr != 2)
483 return -3;
484 size--; ptr++;
485 while (size && *ptr != 0) {
486 size--; ptr++;
488 if (size == 0)
489 return -4;
490 size--; ptr++;
492 memmove(to, ptr, size);
494 out:
495 mp_int_clear(&e);
496 mp_int_clear(&n);
497 mp_int_clear(&in);
498 mp_int_clear(&out);
500 return size;
503 static int
504 random_num(mp_int num, size_t len)
506 unsigned char *p;
507 mp_result res;
509 len = (len + 7) / 8;
510 p = malloc(len);
511 if (p == NULL)
512 return 1;
513 if (RAND_bytes(p, len) != 1) {
514 free(p);
515 return 1;
517 res = mp_int_read_unsigned(num, p, len);
518 free(p);
519 if (res != MP_OK)
520 return 1;
521 return 0;
524 #define CHECK(f, v) if ((f) != (v)) { goto out; }
526 static int
527 imath_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
529 mpz_t el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
530 int counter, ret;
532 if (bits < 789)
533 return -1;
535 ret = -1;
537 mp_int_init(&el);
538 mp_int_init(&p);
539 mp_int_init(&q);
540 mp_int_init(&n);
541 mp_int_init(&d);
542 mp_int_init(&dmp1);
543 mp_int_init(&dmq1);
544 mp_int_init(&iqmp);
545 mp_int_init(&t1);
546 mp_int_init(&t2);
547 mp_int_init(&t3);
549 BN2mpz(&el, e);
551 /* generate p and q so that p != q and bits(pq) ~ bits */
552 counter = 0;
553 do {
554 BN_GENCB_call(cb, 2, counter++);
555 CHECK(random_num(&p, bits / 2 + 1), 0);
556 CHECK(mp_int_find_prime(&p), MP_TRUE);
558 CHECK(mp_int_sub_value(&p, 1, &t1), MP_OK);
559 CHECK(mp_int_gcd(&t1, &el, &t2), MP_OK);
560 } while(mp_int_compare_value(&t2, 1) != 0);
562 BN_GENCB_call(cb, 3, 0);
564 counter = 0;
565 do {
566 BN_GENCB_call(cb, 2, counter++);
567 CHECK(random_num(&q, bits / 2 + 1), 0);
568 CHECK(mp_int_find_prime(&q), MP_TRUE);
570 if (mp_int_compare(&p, &q) == 0) /* don't let p and q be the same */
571 continue;
573 CHECK(mp_int_sub_value(&q, 1, &t1), MP_OK);
574 CHECK(mp_int_gcd(&t1, &el, &t2), MP_OK);
575 } while(mp_int_compare_value(&t2, 1) != 0);
577 /* make p > q */
578 if (mp_int_compare(&p, &q) < 0)
579 mp_int_swap(&p, &q);
581 BN_GENCB_call(cb, 3, 1);
583 /* calculate n, n = p * q */
584 CHECK(mp_int_mul(&p, &q, &n), MP_OK);
586 /* calculate d, d = 1/e mod (p - 1)(q - 1) */
587 CHECK(mp_int_sub_value(&p, 1, &t1), MP_OK);
588 CHECK(mp_int_sub_value(&q, 1, &t2), MP_OK);
589 CHECK(mp_int_mul(&t1, &t2, &t3), MP_OK);
590 CHECK(mp_int_invmod(&el, &t3, &d), MP_OK);
592 /* calculate dmp1 dmp1 = d mod (p-1) */
593 CHECK(mp_int_mod(&d, &t1, &dmp1), MP_OK);
594 /* calculate dmq1 dmq1 = d mod (q-1) */
595 CHECK(mp_int_mod(&d, &t2, &dmq1), MP_OK);
596 /* calculate iqmp iqmp = 1/q mod p */
597 CHECK(mp_int_invmod(&q, &p, &iqmp), MP_OK);
599 /* fill in RSA key */
601 rsa->e = mpz2BN(&el);
602 rsa->p = mpz2BN(&p);
603 rsa->q = mpz2BN(&q);
604 rsa->n = mpz2BN(&n);
605 rsa->d = mpz2BN(&d);
606 rsa->dmp1 = mpz2BN(&dmp1);
607 rsa->dmq1 = mpz2BN(&dmq1);
608 rsa->iqmp = mpz2BN(&iqmp);
610 ret = 1;
611 out:
612 mp_int_clear(&el);
613 mp_int_clear(&p);
614 mp_int_clear(&q);
615 mp_int_clear(&n);
616 mp_int_clear(&d);
617 mp_int_clear(&dmp1);
618 mp_int_clear(&dmq1);
619 mp_int_clear(&iqmp);
620 mp_int_clear(&t1);
621 mp_int_clear(&t2);
622 mp_int_clear(&t3);
624 return ret;
627 static int
628 imath_rsa_init(RSA *rsa)
630 return 1;
633 static int
634 imath_rsa_finish(RSA *rsa)
636 return 1;
639 const RSA_METHOD hc_rsa_imath_method = {
640 "hcrypto imath RSA",
641 imath_rsa_public_encrypt,
642 imath_rsa_public_decrypt,
643 imath_rsa_private_encrypt,
644 imath_rsa_private_decrypt,
645 NULL,
646 NULL,
647 imath_rsa_init,
648 imath_rsa_finish,
650 NULL,
651 NULL,
652 NULL,
653 imath_rsa_generate_key
656 const RSA_METHOD *
657 RSA_imath_method(void)
659 return &hc_rsa_imath_method;