summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rsa/rsa_gen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_gen.c')
-rw-r--r--src/lib/libcrypto/rsa/rsa_gen.c160
1 files changed, 71 insertions, 89 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_gen.c b/src/lib/libcrypto/rsa/rsa_gen.c
index 767f7ab682..dd1422cc98 100644
--- a/src/lib/libcrypto/rsa/rsa_gen.c
+++ b/src/lib/libcrypto/rsa/rsa_gen.c
@@ -56,42 +56,26 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59
60/* NB: these functions have been "upgraded", the deprecated versions (which are
61 * compatibility wrappers using these functions) are in rsa_depr.c.
62 * - Geoff
63 */
64
65#include <stdio.h> 59#include <stdio.h>
66#include <time.h> 60#include <time.h>
67#include "cryptlib.h" 61#include "cryptlib.h"
68#include <openssl/bn.h> 62#include <openssl/bn.h>
69#include <openssl/rsa.h> 63#include <openssl/rsa.h>
70 64
71static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); 65#ifndef OPENSSL_FIPS
72 66
73/* NB: this wrapper would normally be placed in rsa_lib.c and the static 67RSA *RSA_generate_key(int bits, unsigned long e_value,
74 * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so 68 void (*callback)(int,int,void *), void *cb_arg)
75 * that we don't introduce a new linker dependency. Eg. any application that
76 * wasn't previously linking object code related to key-generation won't have to
77 * now just because key-generation is part of RSA_METHOD. */
78int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
79 {
80 if(rsa->meth->rsa_keygen)
81 return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
82 return rsa_builtin_keygen(rsa, bits, e_value, cb);
83 }
84
85static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
86 { 69 {
70 RSA *rsa=NULL;
87 BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; 71 BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
88 BIGNUM local_r0,local_d,local_p; 72 int bitsp,bitsq,ok= -1,n=0,i;
89 BIGNUM *pr0,*d,*p; 73 BN_CTX *ctx=NULL,*ctx2=NULL;
90 int bitsp,bitsq,ok= -1,n=0;
91 BN_CTX *ctx=NULL;
92 74
93 ctx=BN_CTX_new(); 75 ctx=BN_CTX_new();
94 if (ctx == NULL) goto err; 76 if (ctx == NULL) goto err;
77 ctx2=BN_CTX_new();
78 if (ctx2 == NULL) goto err;
95 BN_CTX_start(ctx); 79 BN_CTX_start(ctx);
96 r0 = BN_CTX_get(ctx); 80 r0 = BN_CTX_get(ctx);
97 r1 = BN_CTX_get(ctx); 81 r1 = BN_CTX_get(ctx);
@@ -101,58 +85,49 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
101 85
102 bitsp=(bits+1)/2; 86 bitsp=(bits+1)/2;
103 bitsq=bits-bitsp; 87 bitsq=bits-bitsp;
88 rsa=RSA_new();
89 if (rsa == NULL) goto err;
104 90
105 /* We need the RSA components non-NULL */ 91 /* set e */
106 if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; 92 rsa->e=BN_new();
107 if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; 93 if (rsa->e == NULL) goto err;
108 if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
109 if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
110 if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
111 if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
112 if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
113 if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
114 94
115 BN_copy(rsa->e, e_value); 95#if 1
96 /* The problem is when building with 8, 16, or 32 BN_ULONG,
97 * unsigned long can be larger */
98 for (i=0; i<sizeof(unsigned long)*8; i++)
99 {
100 if (e_value & (1UL<<i))
101 BN_set_bit(rsa->e,i);
102 }
103#else
104 if (!BN_set_word(rsa->e,e_value)) goto err;
105#endif
116 106
117 /* generate p and q */ 107 /* generate p and q */
118 for (;;) 108 for (;;)
119 { 109 {
120 if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) 110 rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg);
121 goto err; 111 if (rsa->p == NULL) goto err;
122 if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; 112 if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
123 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; 113 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
124 if (BN_is_one(r1)) break; 114 if (BN_is_one(r1)) break;
125 if(!BN_GENCB_call(cb, 2, n++)) 115 if (callback != NULL) callback(2,n++,cb_arg);
126 goto err; 116 BN_free(rsa->p);
127 } 117 }
128 if(!BN_GENCB_call(cb, 3, 0)) 118 if (callback != NULL) callback(3,0,cb_arg);
129 goto err;
130 for (;;) 119 for (;;)
131 { 120 {
132 /* When generating ridiculously small keys, we can get stuck 121 rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg);
133 * continually regenerating the same prime values. Check for 122 if (rsa->q == NULL) goto err;
134 * this and bail if it happens 3 times. */
135 unsigned int degenerate = 0;
136 do
137 {
138 if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
139 goto err;
140 } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
141 if(degenerate == 3)
142 {
143 ok = 0; /* we set our own err */
144 RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
145 goto err;
146 }
147 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; 123 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
148 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; 124 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
149 if (BN_is_one(r1)) 125 if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0))
150 break; 126 break;
151 if(!BN_GENCB_call(cb, 2, n++)) 127 if (callback != NULL) callback(2,n++,cb_arg);
152 goto err; 128 BN_free(rsa->q);
153 } 129 }
154 if(!BN_GENCB_call(cb, 3, 1)) 130 if (callback != NULL) callback(3,1,cb_arg);
155 goto err;
156 if (BN_cmp(rsa->p,rsa->q) < 0) 131 if (BN_cmp(rsa->p,rsa->q) < 0)
157 { 132 {
158 tmp=rsa->p; 133 tmp=rsa->p;
@@ -161,59 +136,66 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
161 } 136 }
162 137
163 /* calculate n */ 138 /* calculate n */
139 rsa->n=BN_new();
140 if (rsa->n == NULL) goto err;
164 if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; 141 if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
165 142
166 /* calculate d */ 143 /* calculate d */
167 if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ 144 if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
168 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ 145 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
169 if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ 146 if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
170 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
171 {
172 pr0 = &local_r0;
173 BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
174 }
175 else
176 pr0 = r0;
177 if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
178 147
179 /* set up d for correct BN_FLG_CONSTTIME flag */ 148/* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */
180 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) 149/* for (;;)
181 { 150 {
182 d = &local_d; 151 if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err;
183 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); 152 if (BN_is_one(r3)) break;
153
154 if (1)
155 {
156 if (!BN_add_word(rsa->e,2L)) goto err;
157 continue;
158 }
159 RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE);
160 goto err;
184 } 161 }
185 else 162*/
186 d = rsa->d; 163 rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */
164 if (rsa->d == NULL) goto err;
187 165
188 /* calculate d mod (p-1) */ 166 /* calculate d mod (p-1) */
189 if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; 167 rsa->dmp1=BN_new();
168 if (rsa->dmp1 == NULL) goto err;
169 if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
190 170
191 /* calculate d mod (q-1) */ 171 /* calculate d mod (q-1) */
192 if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; 172 rsa->dmq1=BN_new();
173 if (rsa->dmq1 == NULL) goto err;
174 if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
193 175
194 /* calculate inverse of q mod p */ 176 /* calculate inverse of q mod p */
195 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) 177 rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
196 { 178 if (rsa->iqmp == NULL) goto err;
197 p = &local_p;
198 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
199 }
200 else
201 p = rsa->p;
202 if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
203 179
204 ok=1; 180 ok=1;
205err: 181err:
206 if (ok == -1) 182 if (ok == -1)
207 { 183 {
208 RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); 184 RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
209 ok=0; 185 ok=0;
210 } 186 }
211 if (ctx != NULL) 187 if (ctx != NULL)
212 {
213 BN_CTX_end(ctx); 188 BN_CTX_end(ctx);
214 BN_CTX_free(ctx); 189 BN_CTX_free(ctx);
190 BN_CTX_free(ctx2);
191
192 if (!ok)
193 {
194 if (rsa != NULL) RSA_free(rsa);
195 return(NULL);
215 } 196 }
216 197 else
217 return ok; 198 return(rsa);
218 } 199 }
219 200
201#endif