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