Coverage Report

Created: 2026-02-14 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/hcrypto/rsa-ltm.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2006 - 2007, 2010 Kungliga Tekniska Högskolan
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
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.
16
 *
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.
20
 *
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.
32
 */
33
34
#include <config.h>
35
#include <roken.h>
36
#include <krb5-types.h>
37
#include <assert.h>
38
39
#include <rsa.h>
40
41
#include "tommath.h"
42
43
#define CHECK(f)                                                        \
44
    do { where = __LINE__ + 1; if (ret == MP_OKAY && ((ret = f)) != MP_OKAY) { goto out; } } while (0)
45
0
#define FIRST(e) do { ret = (e); } while (0)
46
#define FIRST_ALLOC(e)                                                  \
47
    do { where = __LINE__; ret = ((e)) ? MP_OKAY : MP_MEM; } while (0)
48
#define THEN_MP(e)                                                      \
49
0
    do { where = __LINE__ + 1; if (ret == MP_OKAY) ret = (e); } while (0)
50
#define THEN_IF_MP(cond, e)                                             \
51
0
    do { where = __LINE__ + 1; if (ret == MP_OKAY && (cond)) ret = (e); } while (0)
52
#define THEN_IF_VOID(cond, e)                                           \
53
    do { where = __LINE__ + 1; if (ret == MP_OKAY && (cond)) e; } while (0)
54
#define THEN_VOID(e)                                                    \
55
0
    do { where = __LINE__ + 1; if (ret == MP_OKAY) e; } while (0)
56
#define THEN_ALLOC(e)                                                   \
57
0
    do { where = __LINE__ + 1; if (ret == MP_OKAY) ret = ((e)) ? MP_OKAY : MP_MEM; } while (0)
58
59
static mp_err
60
random_num(mp_int *num, size_t len)
61
0
{
62
0
    unsigned char *p;
63
0
    mp_err ret = MP_MEM;
64
65
0
    len = (len + 7) / 8; /* bits to bytes */
66
0
    if ((p = malloc(len)) && RAND_bytes(p, len) != 1)
67
0
        ret = MP_ERR;
68
0
    if (p)
69
0
        ret = mp_from_ubin(num, p, len);
70
0
    free(p);
71
0
    return ret;
72
0
}
73
74
static mp_err
75
BN2mpz(mp_int *s, const BIGNUM *bn)
76
0
{
77
0
    size_t len;
78
0
    mp_err ret = MP_MEM;
79
0
    void *p;
80
81
0
    len = BN_num_bytes(bn);
82
0
    p = malloc(len);
83
0
    if (p) {
84
0
        BN_bn2bin(bn, p);
85
0
        ret = mp_from_ubin(s, p, len);
86
0
    }
87
0
    free(p);
88
0
    return ret;
89
0
}
90
91
static mp_err
92
setup_blind(mp_int *n, mp_int *b, mp_int *bi)
93
0
{
94
0
    mp_err ret;
95
96
0
    ret = random_num(b, mp_count_bits(n));
97
0
    if (ret == MP_OKAY) ret = mp_mod(b, n, b);
98
0
    if (ret == MP_OKAY) ret = mp_invmod(b, n, bi);
99
0
    return ret;
100
0
}
101
102
static mp_err
103
blind(mp_int *in, mp_int *b, mp_int *e, mp_int *n)
104
0
{
105
0
    mp_err ret;
106
0
    mp_int t1;
107
108
0
    ret = mp_init(&t1);
109
    /* in' = (in * b^e) mod n */
110
0
    if (ret == MP_OKAY) ret = mp_exptmod(b, e, n, &t1);
111
0
    if (ret == MP_OKAY) ret = mp_mul(&t1, in, in);
112
0
    if (ret == MP_OKAY) ret = mp_mod(in, n, in);
113
0
    mp_clear(&t1);
114
0
    return ret;
115
0
}
116
117
static mp_err
118
unblind(mp_int *out, mp_int *bi, mp_int *n)
119
0
{
120
0
    mp_err ret;
121
122
    /* out' = (out * 1/b) mod n */
123
0
    ret = mp_mul(out, bi, out);
124
0
    if (ret == MP_OKAY) ret = mp_mod(out, n, out);
125
0
    return ret;
126
0
}
127
128
static mp_err
129
ltm_rsa_private_calculate(mp_int * in, mp_int * p,  mp_int * q,
130
        mp_int * dmp1, mp_int * dmq1, mp_int * iqmp,
131
        mp_int * out)
132
0
{
133
0
    mp_err ret;
134
0
    mp_int vp, vq, u;
135
0
    int where HEIMDAL_UNUSED_ATTRIBUTE = 0;
136
137
0
    FIRST(mp_init_multi(&vp, &vq, &u, NULL));
138
139
    /* vq = c ^ (d mod (q - 1)) mod q */
140
    /* vp = c ^ (d mod (p - 1)) mod p */
141
0
    THEN_MP(mp_mod(in, p, &u));
142
0
    THEN_MP(mp_exptmod(&u, dmp1, p, &vp));
143
0
    THEN_MP(mp_mod(in, q, &u));
144
0
    THEN_MP(mp_exptmod(&u, dmq1, q, &vq));
145
146
    /* C2 = 1/q mod p  (iqmp) */
147
    /* u = (vp - vq)C2 mod p. */
148
0
    THEN_MP(mp_sub(&vp, &vq, &u));
149
0
    THEN_IF_MP(mp_isneg(&u), mp_add(&u, p, &u));
150
0
    THEN_MP(mp_mul(&u, iqmp, &u));
151
0
    THEN_MP(mp_mod(&u, p, &u));
152
153
    /* c ^ d mod n = vq + u q */
154
0
    THEN_MP(mp_mul(&u, q, &u));
155
0
    THEN_MP(mp_add(&u, &vq, out));
156
157
0
    mp_clear_multi(&vp, &vq, &u, NULL);
158
0
    return ret;
159
0
}
160
161
/*
162
 *
163
 */
164
165
static int
166
ltm_rsa_public_encrypt(int flen, const unsigned char* from,
167
      unsigned char* to, RSA* rsa, int padding)
168
0
{
169
0
    unsigned char *p = NULL, *p0 = NULL;
170
0
    size_t size, ssize = 0, padlen;
171
0
    mp_int enc, dec, n, e;
172
0
    mp_err ret;
173
0
    int where = __LINE__;
174
175
0
    if (padding != RSA_PKCS1_PADDING)
176
0
  return -1;
177
178
0
    FIRST(mp_init_multi(&n, &e, &enc, &dec, NULL));
179
180
0
    size = RSA_size(rsa);
181
0
    THEN_IF_MP((size < RSA_PKCS1_PADDING_SIZE ||
182
0
                size - RSA_PKCS1_PADDING_SIZE < flen),
183
0
               MP_ERR);
184
0
    THEN_MP(BN2mpz(&n, rsa->n));
185
0
    THEN_MP(BN2mpz(&e, rsa->e));
186
0
    THEN_IF_MP((mp_cmp_d(&e, 3) == MP_LT), MP_ERR);
187
0
    THEN_ALLOC((p = p0 = malloc(size - 1)));
188
189
0
    if (ret == MP_OKAY) {
190
0
        padlen = size - flen - 3;
191
0
        *p++ = 2;
192
0
    }
193
0
    THEN_IF_MP((RAND_bytes(p, padlen) != 1), MP_ERR);
194
195
0
    if (ret == MP_OKAY) {
196
0
        while (padlen) {
197
0
            if (*p == 0)
198
0
                *p = 1;
199
0
            padlen--;
200
0
            p++;
201
0
        }
202
0
        *p++ = 0;
203
0
        memcpy(p, from, flen);
204
0
        p += flen;
205
0
        assert((p - p0) == size - 1);
206
0
    }
207
208
0
    THEN_MP(mp_from_ubin(&dec, p0, size - 1));
209
0
    THEN_MP(mp_exptmod(&dec, &e, &n, &enc));
210
0
    THEN_VOID(ssize = mp_ubin_size(&enc));
211
0
    THEN_VOID(assert(size >= ssize));
212
0
    THEN_MP(mp_to_ubin(&enc, to, SIZE_MAX, NULL));
213
0
    THEN_VOID(size = ssize);
214
215
0
    mp_clear_multi(&dec, &e, &n, NULL);
216
0
    mp_clear(&enc);
217
0
    free(p0);
218
0
    return ret == MP_OKAY ? size : -where;
219
0
}
220
221
static int
222
ltm_rsa_public_decrypt(int flen, const unsigned char* from,
223
           unsigned char* to, RSA* rsa, int padding)
224
0
{
225
0
    unsigned char *p = NULL;
226
0
    mp_err ret;
227
0
    size_t size = 0;
228
0
    mp_int s, us, n, e;
229
0
    int where = __LINE__;
230
231
0
    if (padding != RSA_PKCS1_PADDING)
232
0
  return -1;
233
234
0
    if (flen > RSA_size(rsa))
235
0
  return -2;
236
237
0
    FIRST(mp_init_multi(&e, &n, &s, &us, NULL));
238
0
    THEN_MP(BN2mpz(&n, rsa->n));
239
0
    THEN_MP(BN2mpz(&e, rsa->e));
240
0
    THEN_MP((mp_cmp_d(&e, 3) == MP_LT) ? MP_ERR : MP_OKAY);
241
0
    THEN_MP(mp_from_ubin(&s, rk_UNCONST(from), (size_t)flen));
242
0
    THEN_MP((mp_cmp(&s, &n) >= 0) ? MP_ERR : MP_OKAY);
243
0
    THEN_MP(mp_exptmod(&s, &e, &n, &us));
244
245
0
    THEN_VOID(p = to);
246
0
    THEN_VOID(size = mp_ubin_size(&us));
247
0
    THEN_VOID(assert(size <= RSA_size(rsa)));
248
0
    THEN_MP(mp_to_ubin(&us, p, SIZE_MAX, NULL));
249
250
0
    mp_clear_multi(&e, &n, &s, NULL);
251
0
    mp_clear(&us);
252
253
0
    if (ret != MP_OKAY || size == 0)
254
0
        return -where;
255
256
    /* head zero was skipped by mp_to_unsigned_bin */
257
0
    if (*p == 0)
258
0
        return -where;
259
0
    if (*p != 1)
260
0
        return -(where + 1);
261
0
    size--; p++;
262
0
    while (size && *p == 0xff) {
263
0
        size--; p++;
264
0
    }
265
0
    if (size == 0 || *p != 0)
266
0
        return -(where + 2);
267
0
    size--; p++;
268
0
    memmove(to, p, size);
269
0
    return size;
270
0
}
271
272
static int
273
ltm_rsa_private_encrypt(int flen, const unsigned char* from,
274
      unsigned char* to, RSA* rsa, int padding)
275
0
{
276
0
    unsigned char *ptr = NULL, *ptr0 = NULL;
277
0
    mp_err ret;
278
0
    mp_int in, out, n, e;
279
0
    mp_int bi, b;
280
0
    size_t size;
281
0
    int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
282
0
    int do_unblind = 0;
283
0
    int where = __LINE__;
284
285
0
    if (padding != RSA_PKCS1_PADDING)
286
0
  return -1;
287
288
0
    FIRST(mp_init_multi(&e, &n, &in, &out, &b, &bi, NULL));
289
290
0
    size = RSA_size(rsa);
291
0
    if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen)
292
0
  return -2;
293
294
0
    THEN_ALLOC((ptr0 = ptr = malloc(size)));
295
0
    if (ret == MP_OKAY) {
296
0
        *ptr++ = 0;
297
0
        *ptr++ = 1;
298
0
        memset(ptr, 0xff, size - flen - 3);
299
0
        ptr += size - flen - 3;
300
0
        *ptr++ = 0;
301
0
        memcpy(ptr, from, flen);
302
0
        ptr += flen;
303
0
        assert((ptr - ptr0) == size);
304
0
    }
305
306
0
    THEN_MP(BN2mpz(&n, rsa->n));
307
0
    THEN_MP(BN2mpz(&e, rsa->e));
308
0
    THEN_IF_MP((mp_cmp_d(&e, 3) == MP_LT), MP_ERR);
309
0
    THEN_MP(mp_from_ubin(&in, ptr0, size));
310
0
    free(ptr0);
311
312
0
    THEN_IF_MP((mp_isneg(&in) || mp_cmp(&in, &n) >= 0), MP_ERR);
313
314
0
    if (blinding) {
315
0
  THEN_MP(setup_blind(&n, &b, &bi));
316
0
  THEN_MP(blind(&in, &b, &e, &n));
317
0
  do_unblind = 1;
318
0
    }
319
320
0
    if (ret == MP_OKAY && rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 &&
321
0
        rsa->iqmp) {
322
0
  mp_int p, q, dmp1, dmq1, iqmp;
323
324
0
  FIRST(mp_init_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL));
325
0
  THEN_MP(BN2mpz(&p, rsa->p));
326
0
  THEN_MP(BN2mpz(&q, rsa->q));
327
0
  THEN_MP(BN2mpz(&dmp1, rsa->dmp1));
328
0
  THEN_MP(BN2mpz(&dmq1, rsa->dmq1));
329
0
  THEN_MP(BN2mpz(&iqmp, rsa->iqmp));
330
0
        THEN_MP(ltm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp,
331
0
                                          &out));
332
0
  mp_clear_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
333
0
  if (ret != MP_OKAY) goto out;
334
0
    } else if (ret == MP_OKAY) {
335
0
  mp_int d;
336
337
0
  THEN_MP(BN2mpz(&d, rsa->d));
338
0
  THEN_MP(mp_exptmod(&in, &d, &n, &out));
339
0
  mp_clear(&d);
340
0
  if (ret != MP_OKAY) goto out;
341
0
    }
342
343
0
    if (do_unblind)
344
0
  THEN_MP(unblind(&out, &bi, &n));
345
346
0
    if (ret == MP_OKAY && size > 0) {
347
0
  size_t ssize;
348
349
0
  ssize = mp_ubin_size(&out);
350
0
  assert(size >= ssize);
351
0
  THEN_MP(mp_to_ubin(&out, to, SIZE_MAX, NULL));
352
0
  size = ssize;
353
0
    }
354
355
0
 out:
356
0
    mp_clear_multi(&e, &n, &in, &out, &b, &bi, NULL);
357
0
    return ret == MP_OKAY ? size : -where;
358
0
}
359
360
static int
361
ltm_rsa_private_decrypt(int flen, const unsigned char* from,
362
      unsigned char* to, RSA* rsa, int padding)
363
0
{
364
0
    unsigned char *ptr;
365
0
    size_t size;
366
0
    mp_err ret;
367
0
    mp_int in, out, n, e, b, bi;
368
0
    int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
369
0
    int do_unblind = 0;
370
0
    int where = __LINE__;
371
372
0
    if (padding != RSA_PKCS1_PADDING)
373
0
  return -1;
374
375
0
    size = RSA_size(rsa);
376
0
    if (flen > size)
377
0
  return -2;
378
379
0
    FIRST(mp_init_multi(&in, &n, &e, &out, &b, &bi, NULL));
380
0
    THEN_MP(BN2mpz(&n, rsa->n));
381
0
    THEN_MP(BN2mpz(&e, rsa->e));
382
0
    THEN_IF_MP((mp_cmp_d(&e, 3) == MP_LT), MP_ERR);
383
0
    THEN_MP(mp_from_ubin(&in, rk_UNCONST(from), flen));
384
0
    THEN_IF_MP((mp_isneg(&in) || mp_cmp(&in, &n) >= 0), MP_ERR);
385
386
0
    if (blinding) {
387
0
  THEN_MP(setup_blind(&n, &b, &bi));
388
0
  THEN_MP(blind(&in, &b, &e, &n));
389
0
  do_unblind = 1;
390
0
    }
391
392
0
    if (ret == MP_OKAY && rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 &&
393
0
        rsa->iqmp) {
394
0
  mp_int p, q, dmp1, dmq1, iqmp;
395
396
0
  THEN_MP(mp_init_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL));
397
0
  THEN_MP(BN2mpz(&p, rsa->p));
398
0
  THEN_MP(BN2mpz(&q, rsa->q));
399
0
  THEN_MP(BN2mpz(&dmp1, rsa->dmp1));
400
0
  THEN_MP(BN2mpz(&dmq1, rsa->dmq1));
401
0
  THEN_MP(BN2mpz(&iqmp, rsa->iqmp));
402
0
  THEN_MP(ltm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out));
403
0
  mp_clear_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
404
0
  if (ret != MP_OKAY) goto out;
405
0
    } else if (ret == MP_OKAY) {
406
0
  mp_int d;
407
408
0
  THEN_IF_MP((mp_isneg(&in) || mp_cmp(&in, &n) >= 0), MP_ERR);
409
0
  THEN_MP(BN2mpz(&d, rsa->d));
410
0
  THEN_MP(mp_exptmod(&in, &d, &n, &out));
411
0
  mp_clear(&d);
412
0
  if (ret != MP_OKAY) goto out;
413
0
    }
414
415
0
    if (do_unblind)
416
0
  THEN_MP(unblind(&out, &bi, &n));
417
418
0
    if (ret == MP_OKAY) {
419
0
        size_t ssize;
420
421
0
        ptr = to;
422
0
        ssize = mp_ubin_size(&out);
423
0
        assert(size >= ssize);
424
0
        ret = mp_to_ubin(&out, ptr, SIZE_MAX, NULL);
425
0
        if (ret != MP_OKAY) goto out;
426
0
  size = ssize;
427
428
        /* head zero was skipped by mp_int_to_unsigned */
429
0
        if (*ptr != 2) {
430
0
            where = __LINE__;
431
0
            goto out;
432
0
        }
433
0
        size--; ptr++;
434
0
        while (size && *ptr != 0) {
435
0
            size--; ptr++;
436
0
        }
437
0
        if (size == 0) {
438
0
            where = __LINE__;
439
0
            goto out;
440
0
        }
441
0
        size--; ptr++;
442
0
        memmove(to, ptr, size);
443
0
    }
444
445
0
 out:
446
0
    mp_clear_multi(&e, &n, &in, &out, &b, &bi, NULL);
447
0
    return (ret == MP_OKAY) ? size : -where;
448
0
}
449
450
static BIGNUM *
451
mpz2BN(mp_int *s)
452
0
{
453
0
    size_t size;
454
0
    BIGNUM *bn;
455
0
    mp_err ret;
456
0
    void *p;
457
458
0
    size = mp_ubin_size(s);
459
0
    if (size == 0)
460
0
  return NULL;
461
462
0
    p = malloc(size);
463
0
    if (p == NULL)
464
0
  return NULL;
465
466
0
    ret = mp_to_ubin(s, p, SIZE_MAX, NULL);
467
0
    if (ret == MP_OKAY)
468
0
        bn = BN_bin2bn(p, size, NULL);
469
0
    free(p);
470
0
    return (ret == MP_OKAY) ? bn : NULL;
471
0
}
472
473
enum gen_pq_type { GEN_P, GEN_Q };
474
475
static int
476
gen_p(int bits, enum gen_pq_type pq_type, uint8_t nibble_pair, mp_int *p, mp_int *e, BN_GENCB *cb)
477
0
{
478
0
    unsigned char *buf = NULL;
479
0
    mp_bool res;
480
0
    mp_err ret = MP_MEM;
481
0
    mp_int t1, t2;
482
0
    size_t len = (bits + 7) / 8;
483
0
    int trials = mp_prime_rabin_miller_trials(bits);
484
0
    int counter = 0;
485
0
    int where HEIMDAL_UNUSED_ATTRIBUTE = 0;
486
487
488
0
    FIRST(mp_init_multi(&t1, &t2, NULL));
489
0
    if (ret == MP_OKAY && (buf = malloc(len))) do {
490
0
        BN_GENCB_call(cb, 2, counter++);
491
        /* random bytes */
492
0
        ret = (RAND_bytes(buf, len) == 1) ? MP_OKAY : MP_ERR;
493
494
        /* make it odd */
495
0
        buf[len - 1] |= 1;
496
497
        /* ensure the high nibble of the product is at least 128 */
498
0
        if (pq_type == GEN_P)
499
0
            buf[0] = (nibble_pair & 0xf0)         | (buf[0] & 0x0f);
500
0
        else
501
0
            buf[0] = ((nibble_pair & 0x0f) << 4)  | (buf[0] & 0x0f);
502
503
        /* load number */
504
0
        THEN_MP(mp_from_ubin(p, buf, len));
505
506
        /* test primality; repeat if not */
507
0
        THEN_MP(mp_prime_is_prime(p, trials, &res));
508
0
        if (ret == MP_OKAY && res == MP_NO) continue;
509
510
        /* check gcd(p - 1, e) == 1 */
511
0
  THEN_MP(mp_sub_d(p, 1, &t1));
512
0
  THEN_MP(mp_gcd(&t1, e, &t2));
513
0
    } while (ret == MP_OKAY && mp_cmp_d(&t2, 1) != MP_EQ);
514
515
0
    mp_clear_multi(&t1, &t2, NULL);
516
0
    free(buf);
517
0
    return ret;
518
0
}
519
520
static uint8_t pq_high_nibble_pairs[] = {
521
0x9f, 0xad, 0xae, 0xaf, 0xbc, 0xbd, 0xbe, 0xbf, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
522
0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf9,
523
0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
524
};
525
526
static int
527
ltm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
528
0
{
529
0
    mp_int el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
530
0
    mp_err ret;
531
0
    uint8_t high_nibbles = 0;
532
0
    int bitsp;
533
0
    int where = __LINE__;
534
535
0
    if (bits < 789)
536
0
  return -1;
537
538
0
    bitsp = (bits + 1) / 2;
539
540
0
    FIRST(mp_init_multi(&el, &p, &q, &n, &d,
541
0
                        &dmp1, &dmq1, &iqmp,
542
0
                        &t1, &t2, &t3, NULL));
543
0
    THEN_MP(BN2mpz(&el, e));
544
545
    /*
546
     * randomly pick a pair of high nibbles for p and q to ensure the product's
547
     * high nibble is at least 128
548
     */
549
0
    if (ret == MP_OKAY)
550
0
        ret = (RAND_bytes(&high_nibbles, 1) == 1) ? MP_OKAY : MP_ERR;
551
0
    high_nibbles %= sizeof(pq_high_nibble_pairs);
552
0
    high_nibbles = pq_high_nibble_pairs[high_nibbles];
553
554
    /* generate p and q so that p != q and bits(pq) ~ bits */
555
0
    THEN_MP(gen_p(bitsp, GEN_P, high_nibbles, &p, &el, cb));
556
0
    BN_GENCB_call(cb, 3, 0);
557
0
    THEN_MP(gen_p(bitsp, GEN_Q, high_nibbles, &q, &el, cb));
558
559
    /* make p > q */
560
0
    if (mp_cmp(&p, &q) < 0) {
561
0
  mp_int c;
562
0
  c = p;
563
0
  p = q;
564
0
  q = c;
565
0
    }
566
567
0
    BN_GENCB_call(cb, 3, 1);
568
569
    /* calculate n,     n = p * q */
570
0
    THEN_MP(mp_mul(&p, &q, &n));
571
572
    /* calculate d,     d = 1/e mod (p - 1)(q - 1) */
573
0
    THEN_MP(mp_sub_d(&p, 1, &t1));
574
0
    THEN_MP(mp_sub_d(&q, 1, &t2));
575
0
    THEN_MP(mp_mul(&t1, &t2, &t3));
576
0
    THEN_MP(mp_invmod(&el, &t3, &d));
577
578
    /* calculate dmp1   dmp1 = d mod (p-1) */
579
0
    THEN_MP(mp_mod(&d, &t1, &dmp1));
580
    /* calculate dmq1   dmq1 = d mod (q-1) */
581
0
    THEN_MP(mp_mod(&d, &t2, &dmq1));
582
    /* calculate iqmp     iqmp = 1/q mod p */
583
0
    THEN_MP(mp_invmod(&q, &p, &iqmp));
584
585
    /* fill in RSA key */
586
587
0
    if (ret == MP_OKAY) {
588
0
        rsa->e = mpz2BN(&el);
589
0
        rsa->p = mpz2BN(&p);
590
0
        rsa->q = mpz2BN(&q);
591
0
        rsa->n = mpz2BN(&n);
592
0
        rsa->d = mpz2BN(&d);
593
0
        rsa->dmp1 = mpz2BN(&dmp1);
594
0
        rsa->dmq1 = mpz2BN(&dmq1);
595
0
        rsa->iqmp = mpz2BN(&iqmp);
596
0
    }
597
598
0
    mp_clear_multi(&el, &p, &q, &n, &d,
599
0
       &dmp1, &dmq1, &iqmp,
600
0
       &t1, &t2, &t3, NULL);
601
0
    return (ret == MP_OKAY) ? 1 : -where;
602
0
}
603
604
static int
605
ltm_rsa_init(RSA *rsa)
606
0
{
607
0
    return 1;
608
0
}
609
610
static int
611
ltm_rsa_finish(RSA *rsa)
612
0
{
613
0
    return 1;
614
0
}
615
616
const RSA_METHOD hc_rsa_ltm_method = {
617
    "hcrypto ltm RSA",
618
    ltm_rsa_public_encrypt,
619
    ltm_rsa_public_decrypt,
620
    ltm_rsa_private_encrypt,
621
    ltm_rsa_private_decrypt,
622
    NULL,
623
    NULL,
624
    ltm_rsa_init,
625
    ltm_rsa_finish,
626
    0,
627
    NULL,
628
    NULL,
629
    NULL,
630
    ltm_rsa_generate_key
631
};
632
633
const RSA_METHOD *
634
RSA_ltm_method(void)
635
0
{
636
0
    return &hc_rsa_ltm_method;
637
0
}