]>
Commit | Line | Data |
---|---|---|
7bf7a6d0 MTL |
1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the OpenSSL license (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_locl.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 | * If not all parameters present only calculate what we can. This allows | |
52 | * test programs to output selective parameters. | |
53 | */ | |
54 | ||
55 | if (Xp && rsa->p == NULL) { | |
56 | rsa->p = BN_new(); | |
57 | if (rsa->p == NULL) | |
58 | goto err; | |
59 | ||
60 | if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, | |
61 | Xp, Xp1, Xp2, e, ctx, cb)) | |
62 | goto err; | |
63 | } | |
64 | ||
65 | if (Xq && rsa->q == NULL) { | |
66 | rsa->q = BN_new(); | |
67 | if (rsa->q == NULL) | |
68 | goto err; | |
69 | if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, | |
70 | Xq, Xq1, Xq2, e, ctx, cb)) | |
71 | goto err; | |
72 | } | |
73 | ||
74 | if (rsa->p == NULL || rsa->q == NULL) { | |
75 | BN_CTX_end(ctx); | |
76 | BN_CTX_free(ctx); | |
77 | return 2; | |
78 | } | |
79 | ||
80 | /* | |
81 | * Since both primes are set we can now calculate all remaining | |
82 | * components. | |
83 | */ | |
84 | ||
85 | /* calculate n */ | |
86 | rsa->n = BN_new(); | |
87 | if (rsa->n == NULL) | |
88 | goto err; | |
89 | if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) | |
90 | goto err; | |
91 | ||
92 | /* calculate d */ | |
93 | if (!BN_sub(r1, rsa->p, BN_value_one())) | |
94 | goto err; /* p-1 */ | |
95 | if (!BN_sub(r2, rsa->q, BN_value_one())) | |
96 | goto err; /* q-1 */ | |
97 | if (!BN_mul(r0, r1, r2, ctx)) | |
98 | goto err; /* (p-1)(q-1) */ | |
99 | ||
100 | if (!BN_gcd(r3, r1, r2, ctx)) | |
101 | goto err; | |
102 | ||
103 | if (!BN_div(r0, NULL, r0, r3, ctx)) | |
104 | goto err; /* LCM((p-1)(q-1)) */ | |
105 | ||
106 | ctx2 = BN_CTX_new(); | |
107 | if (ctx2 == NULL) | |
108 | goto err; | |
109 | ||
110 | rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */ | |
111 | if (rsa->d == NULL) | |
112 | goto err; | |
113 | ||
114 | /* calculate d mod (p-1) */ | |
115 | rsa->dmp1 = BN_new(); | |
116 | if (rsa->dmp1 == NULL) | |
117 | goto err; | |
118 | if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx)) | |
119 | goto err; | |
120 | ||
121 | /* calculate d mod (q-1) */ | |
122 | rsa->dmq1 = BN_new(); | |
123 | if (rsa->dmq1 == NULL) | |
124 | goto err; | |
125 | if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx)) | |
126 | goto err; | |
127 | ||
128 | /* calculate inverse of q mod p */ | |
129 | rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2); | |
130 | ||
131 | ret = 1; | |
132 | err: | |
133 | if (ctx) | |
134 | BN_CTX_end(ctx); | |
135 | BN_CTX_free(ctx); | |
136 | BN_CTX_free(ctx2); | |
137 | ||
138 | return ret; | |
139 | ||
140 | } | |
141 | ||
142 | int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, | |
143 | BN_GENCB *cb) | |
144 | { | |
145 | int ok = 0; | |
146 | BIGNUM *Xp = NULL, *Xq = NULL; | |
147 | BN_CTX *ctx = NULL; | |
148 | ||
149 | ctx = BN_CTX_new(); | |
150 | if (ctx == NULL) | |
151 | goto error; | |
152 | ||
153 | BN_CTX_start(ctx); | |
154 | Xp = BN_CTX_get(ctx); | |
155 | Xq = BN_CTX_get(ctx); | |
156 | if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) | |
157 | goto error; | |
158 | ||
159 | rsa->p = BN_new(); | |
160 | rsa->q = BN_new(); | |
161 | if (rsa->p == NULL || rsa->q == NULL) | |
162 | goto error; | |
163 | ||
164 | /* Generate two primes from Xp, Xq */ | |
165 | ||
166 | if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, | |
167 | e, ctx, cb)) | |
168 | goto error; | |
169 | ||
170 | if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, | |
171 | e, ctx, cb)) | |
172 | goto error; | |
173 | ||
174 | /* | |
175 | * Since rsa->p and rsa->q are valid this call will just derive remaining | |
176 | * RSA components. | |
177 | */ | |
178 | ||
179 | if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, | |
180 | NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) | |
181 | goto error; | |
182 | ||
183 | ok = 1; | |
184 | ||
185 | error: | |
186 | if (ctx) | |
187 | BN_CTX_end(ctx); | |
188 | BN_CTX_free(ctx); | |
189 | ||
190 | if (ok) | |
191 | return 1; | |
192 | ||
193 | return 0; | |
194 | ||
195 | } |