/src/openssl/crypto/rsa/rsa_x931g.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | /* |
11 | | * RSA low level APIs are deprecated for public use, but still ok for |
12 | | * internal use. |
13 | | */ |
14 | | #define OPENSSL_SUPPRESS_DEPRECATED |
15 | | |
16 | | #include <stdio.h> |
17 | | #include <string.h> |
18 | | #include <time.h> |
19 | | #include <openssl/err.h> |
20 | | #include <openssl/bn.h> |
21 | | #include "rsa_local.h" |
22 | | |
23 | | /* X9.31 RSA key derivation and generation */ |
24 | | |
25 | | int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, |
26 | | BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, |
27 | | const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, |
28 | | const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb) |
29 | 0 | { |
30 | 0 | BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL; |
31 | 0 | BN_CTX *ctx = NULL, *ctx2 = NULL; |
32 | 0 | int ret = 0; |
33 | |
|
34 | 0 | if (!rsa) |
35 | 0 | goto err; |
36 | | |
37 | 0 | ctx = BN_CTX_new(); |
38 | 0 | if (ctx == NULL) |
39 | 0 | goto err; |
40 | 0 | BN_CTX_start(ctx); |
41 | |
|
42 | 0 | r0 = BN_CTX_get(ctx); |
43 | 0 | r1 = BN_CTX_get(ctx); |
44 | 0 | r2 = BN_CTX_get(ctx); |
45 | 0 | r3 = BN_CTX_get(ctx); |
46 | |
|
47 | 0 | if (r3 == NULL) |
48 | 0 | goto err; |
49 | 0 | if (!rsa->e) { |
50 | 0 | rsa->e = BN_dup(e); |
51 | 0 | if (!rsa->e) |
52 | 0 | goto err; |
53 | 0 | } else { |
54 | 0 | e = rsa->e; |
55 | 0 | } |
56 | | |
57 | | /* |
58 | | * If not all parameters present only calculate what we can. This allows |
59 | | * test programs to output selective parameters. |
60 | | */ |
61 | | |
62 | 0 | if (Xp && rsa->p == NULL) { |
63 | 0 | rsa->p = BN_new(); |
64 | 0 | if (rsa->p == NULL) |
65 | 0 | goto err; |
66 | | |
67 | 0 | if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, |
68 | 0 | Xp, Xp1, Xp2, e, ctx, cb)) |
69 | 0 | goto err; |
70 | 0 | } |
71 | | |
72 | 0 | if (Xq && rsa->q == NULL) { |
73 | 0 | rsa->q = BN_new(); |
74 | 0 | if (rsa->q == NULL) |
75 | 0 | goto err; |
76 | 0 | if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, |
77 | 0 | Xq, Xq1, Xq2, e, ctx, cb)) |
78 | 0 | goto err; |
79 | 0 | } |
80 | | |
81 | 0 | if (rsa->p == NULL || rsa->q == NULL) { |
82 | 0 | BN_CTX_end(ctx); |
83 | 0 | BN_CTX_free(ctx); |
84 | 0 | return 2; |
85 | 0 | } |
86 | | |
87 | | /* |
88 | | * Since both primes are set we can now calculate all remaining |
89 | | * components. |
90 | | */ |
91 | | |
92 | | /* calculate n */ |
93 | 0 | rsa->n = BN_new(); |
94 | 0 | if (rsa->n == NULL) |
95 | 0 | goto err; |
96 | 0 | if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) |
97 | 0 | goto err; |
98 | | |
99 | | /* calculate d */ |
100 | 0 | if (!BN_sub(r1, rsa->p, BN_value_one())) |
101 | 0 | goto err; /* p-1 */ |
102 | 0 | if (!BN_sub(r2, rsa->q, BN_value_one())) |
103 | 0 | goto err; /* q-1 */ |
104 | 0 | if (!BN_mul(r0, r1, r2, ctx)) |
105 | 0 | goto err; /* (p-1)(q-1) */ |
106 | | |
107 | 0 | if (!BN_gcd(r3, r1, r2, ctx)) |
108 | 0 | goto err; |
109 | | |
110 | 0 | if (!BN_div(r0, NULL, r0, r3, ctx)) |
111 | 0 | goto err; /* LCM((p-1)(q-1)) */ |
112 | | |
113 | 0 | ctx2 = BN_CTX_new(); |
114 | 0 | if (ctx2 == NULL) |
115 | 0 | goto err; |
116 | | |
117 | 0 | rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */ |
118 | 0 | if (rsa->d == NULL) |
119 | 0 | goto err; |
120 | | |
121 | | /* calculate d mod (p-1) */ |
122 | 0 | rsa->dmp1 = BN_new(); |
123 | 0 | if (rsa->dmp1 == NULL) |
124 | 0 | goto err; |
125 | 0 | if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx)) |
126 | 0 | goto err; |
127 | | |
128 | | /* calculate d mod (q-1) */ |
129 | 0 | rsa->dmq1 = BN_new(); |
130 | 0 | if (rsa->dmq1 == NULL) |
131 | 0 | goto err; |
132 | 0 | if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx)) |
133 | 0 | goto err; |
134 | | |
135 | | /* calculate inverse of q mod p */ |
136 | 0 | rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2); |
137 | 0 | if (rsa->iqmp == NULL) |
138 | 0 | goto err; |
139 | | |
140 | 0 | rsa->dirty_cnt++; |
141 | 0 | ret = 1; |
142 | 0 | err: |
143 | 0 | BN_CTX_end(ctx); |
144 | 0 | BN_CTX_free(ctx); |
145 | 0 | BN_CTX_free(ctx2); |
146 | |
|
147 | 0 | return ret; |
148 | |
|
149 | 0 | } |
150 | | |
151 | | int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, |
152 | | BN_GENCB *cb) |
153 | 0 | { |
154 | 0 | int ok = 0; |
155 | 0 | BIGNUM *Xp = NULL, *Xq = NULL; |
156 | 0 | BN_CTX *ctx = NULL; |
157 | |
|
158 | 0 | ctx = BN_CTX_new(); |
159 | 0 | if (ctx == NULL) |
160 | 0 | goto error; |
161 | | |
162 | 0 | BN_CTX_start(ctx); |
163 | 0 | Xp = BN_CTX_get(ctx); |
164 | 0 | Xq = BN_CTX_get(ctx); |
165 | 0 | if (Xq == NULL) |
166 | 0 | goto error; |
167 | 0 | if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) |
168 | 0 | goto error; |
169 | | |
170 | 0 | rsa->p = BN_new(); |
171 | 0 | rsa->q = BN_new(); |
172 | 0 | if (rsa->p == NULL || rsa->q == NULL) |
173 | 0 | goto error; |
174 | | |
175 | | /* Generate two primes from Xp, Xq */ |
176 | | |
177 | 0 | if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, |
178 | 0 | e, ctx, cb)) |
179 | 0 | goto error; |
180 | | |
181 | 0 | if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, |
182 | 0 | e, ctx, cb)) |
183 | 0 | goto error; |
184 | | |
185 | | /* |
186 | | * Since rsa->p and rsa->q are valid this call will just derive remaining |
187 | | * RSA components. |
188 | | */ |
189 | | |
190 | 0 | if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, |
191 | 0 | NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) |
192 | 0 | goto error; |
193 | | |
194 | 0 | rsa->dirty_cnt++; |
195 | 0 | ok = 1; |
196 | |
|
197 | 0 | error: |
198 | 0 | BN_CTX_end(ctx); |
199 | 0 | BN_CTX_free(ctx); |
200 | |
|
201 | 0 | if (ok) |
202 | 0 | return 1; |
203 | | |
204 | 0 | return 0; |
205 | |
|
206 | 0 | } |