1/*
2 * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2017 BaishanCloud. All rights reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11#include <openssl/bn.h>
12#include <openssl/err.h>
13#include "rsa_local.h"
14
15void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo)
16{
17 /* free pp and pinfo only */
18 BN_clear_free(pinfo->pp);
19 OPENSSL_free(pinfo);
20}
21
22void rsa_multip_info_free(RSA_PRIME_INFO *pinfo)
23{
24 /* free a RSA_PRIME_INFO structure */
25 BN_clear_free(pinfo->r);
26 BN_clear_free(pinfo->d);
27 BN_clear_free(pinfo->t);
28 rsa_multip_info_free_ex(pinfo);
29}
30
31RSA_PRIME_INFO *rsa_multip_info_new(void)
32{
33 RSA_PRIME_INFO *pinfo;
34
35 /* create a RSA_PRIME_INFO structure */
36 if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) {
37 RSAerr(RSA_F_RSA_MULTIP_INFO_NEW, ERR_R_MALLOC_FAILURE);
38 return NULL;
39 }
40 if ((pinfo->r = BN_secure_new()) == NULL)
41 goto err;
42 if ((pinfo->d = BN_secure_new()) == NULL)
43 goto err;
44 if ((pinfo->t = BN_secure_new()) == NULL)
45 goto err;
46 if ((pinfo->pp = BN_secure_new()) == NULL)
47 goto err;
48
49 return pinfo;
50
51 err:
52 BN_free(pinfo->r);
53 BN_free(pinfo->d);
54 BN_free(pinfo->t);
55 BN_free(pinfo->pp);
56 OPENSSL_free(pinfo);
57 return NULL;
58}
59
60/* Refill products of primes */
61int rsa_multip_calc_product(RSA *rsa)
62{
63 RSA_PRIME_INFO *pinfo;
64 BIGNUM *p1 = NULL, *p2 = NULL;
65 BN_CTX *ctx = NULL;
66 int i, rv = 0, ex_primes;
67
68 if ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0) {
69 /* invalid */
70 goto err;
71 }
72
73 if ((ctx = BN_CTX_new()) == NULL)
74 goto err;
75
76 /* calculate pinfo->pp = p * q for first 'extra' prime */
77 p1 = rsa->p;
78 p2 = rsa->q;
79
80 for (i = 0; i < ex_primes; i++) {
81 pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
82 if (pinfo->pp == NULL) {
83 pinfo->pp = BN_secure_new();
84 if (pinfo->pp == NULL)
85 goto err;
86 }
87 if (!BN_mul(pinfo->pp, p1, p2, ctx))
88 goto err;
89 /* save previous one */
90 p1 = pinfo->pp;
91 p2 = pinfo->r;
92 }
93
94 rv = 1;
95 err:
96 BN_CTX_free(ctx);
97 return rv;
98}
99
100int rsa_multip_cap(int bits)
101{
102 int cap = 5;
103
104 if (bits < 1024)
105 cap = 2;
106 else if (bits < 4096)
107 cap = 3;
108 else if (bits < 8192)
109 cap = 4;
110
111 if (cap > RSA_MAX_PRIME_NUM)
112 cap = RSA_MAX_PRIME_NUM;
113
114 return cap;
115}
116