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, 89 insertions, 71 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_gen.c b/src/lib/libcrypto/rsa/rsa_gen.c
index dd1422cc98..767f7ab682 100644
--- a/src/lib/libcrypto/rsa/rsa_gen.c
+++ b/src/lib/libcrypto/rsa/rsa_gen.c
@@ -56,26 +56,42 @@
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
59#include <stdio.h> 65#include <stdio.h>
60#include <time.h> 66#include <time.h>
61#include "cryptlib.h" 67#include "cryptlib.h"
62#include <openssl/bn.h> 68#include <openssl/bn.h>
63#include <openssl/rsa.h> 69#include <openssl/rsa.h>
64 70
65#ifndef OPENSSL_FIPS 71static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
66 72
67RSA *RSA_generate_key(int bits, unsigned long e_value, 73/* NB: this wrapper would normally be placed in rsa_lib.c and the static
68 void (*callback)(int,int,void *), void *cb_arg) 74 * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
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)
69 { 86 {
70 RSA *rsa=NULL;
71 BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; 87 BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
72 int bitsp,bitsq,ok= -1,n=0,i; 88 BIGNUM local_r0,local_d,local_p;
73 BN_CTX *ctx=NULL,*ctx2=NULL; 89 BIGNUM *pr0,*d,*p;
90 int bitsp,bitsq,ok= -1,n=0;
91 BN_CTX *ctx=NULL;
74 92
75 ctx=BN_CTX_new(); 93 ctx=BN_CTX_new();
76 if (ctx == NULL) goto err; 94 if (ctx == NULL) goto err;
77 ctx2=BN_CTX_new();
78 if (ctx2 == NULL) goto err;
79 BN_CTX_start(ctx); 95 BN_CTX_start(ctx);
80 r0 = BN_CTX_get(ctx); 96 r0 = BN_CTX_get(ctx);
81 r1 = BN_CTX_get(ctx); 97 r1 = BN_CTX_get(ctx);
@@ -85,49 +101,58 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
85 101
86 bitsp=(bits+1)/2; 102 bitsp=(bits+1)/2;
87 bitsq=bits-bitsp; 103 bitsq=bits-bitsp;
88 rsa=RSA_new();
89 if (rsa == NULL) goto err;
90 104
91 /* set e */ 105 /* We need the RSA components non-NULL */
92 rsa->e=BN_new(); 106 if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
93 if (rsa->e == NULL) goto err; 107 if(!rsa->d && ((rsa->d=BN_new()) == 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;
94 114
95#if 1 115 BN_copy(rsa->e, e_value);
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
106 116
107 /* generate p and q */ 117 /* generate p and q */
108 for (;;) 118 for (;;)
109 { 119 {
110 rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg); 120 if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
111 if (rsa->p == NULL) goto err; 121 goto err;
112 if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; 122 if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
113 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; 123 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
114 if (BN_is_one(r1)) break; 124 if (BN_is_one(r1)) break;
115 if (callback != NULL) callback(2,n++,cb_arg); 125 if(!BN_GENCB_call(cb, 2, n++))
116 BN_free(rsa->p); 126 goto err;
117 } 127 }
118 if (callback != NULL) callback(3,0,cb_arg); 128 if(!BN_GENCB_call(cb, 3, 0))
129 goto err;
119 for (;;) 130 for (;;)
120 { 131 {
121 rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg); 132 /* When generating ridiculously small keys, we can get stuck
122 if (rsa->q == NULL) goto err; 133 * continually regenerating the same prime values. Check for
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 }
123 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; 147 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
124 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; 148 if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
125 if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0)) 149 if (BN_is_one(r1))
126 break; 150 break;
127 if (callback != NULL) callback(2,n++,cb_arg); 151 if(!BN_GENCB_call(cb, 2, n++))
128 BN_free(rsa->q); 152 goto err;
129 } 153 }
130 if (callback != NULL) callback(3,1,cb_arg); 154 if(!BN_GENCB_call(cb, 3, 1))
155 goto err;
131 if (BN_cmp(rsa->p,rsa->q) < 0) 156 if (BN_cmp(rsa->p,rsa->q) < 0)
132 { 157 {
133 tmp=rsa->p; 158 tmp=rsa->p;
@@ -136,66 +161,59 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
136 } 161 }
137 162
138 /* calculate n */ 163 /* calculate n */
139 rsa->n=BN_new();
140 if (rsa->n == NULL) goto err;
141 if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; 164 if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
142 165
143 /* calculate d */ 166 /* calculate d */
144 if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ 167 if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
145 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ 168 if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
146 if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ 169 if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
147 170 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
148/* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */
149/* for (;;)
150 { 171 {
151 if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err; 172 pr0 = &local_r0;
152 if (BN_is_one(r3)) break; 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 */
153 178
154 if (1) 179 /* set up d for correct BN_FLG_CONSTTIME flag */
155 { 180 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
156 if (!BN_add_word(rsa->e,2L)) goto err; 181 {
157 continue; 182 d = &local_d;
158 } 183 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
159 RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE);
160 goto err;
161 } 184 }
162*/ 185 else
163 rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ 186 d = rsa->d;
164 if (rsa->d == NULL) goto err;
165 187
166 /* calculate d mod (p-1) */ 188 /* calculate d mod (p-1) */
167 rsa->dmp1=BN_new(); 189 if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
168 if (rsa->dmp1 == NULL) goto err;
169 if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
170 190
171 /* calculate d mod (q-1) */ 191 /* calculate d mod (q-1) */
172 rsa->dmq1=BN_new(); 192 if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
173 if (rsa->dmq1 == NULL) goto err;
174 if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
175 193
176 /* calculate inverse of q mod p */ 194 /* calculate inverse of q mod p */
177 rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); 195 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
178 if (rsa->iqmp == NULL) goto err; 196 {
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;
179 203
180 ok=1; 204 ok=1;
181err: 205err:
182 if (ok == -1) 206 if (ok == -1)
183 { 207 {
184 RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN); 208 RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
185 ok=0; 209 ok=0;
186 } 210 }
187 if (ctx != NULL) 211 if (ctx != NULL)
188 BN_CTX_end(ctx);
189 BN_CTX_free(ctx);
190 BN_CTX_free(ctx2);
191
192 if (!ok)
193 { 212 {
194 if (rsa != NULL) RSA_free(rsa); 213 BN_CTX_end(ctx);
195 return(NULL); 214 BN_CTX_free(ctx);
196 } 215 }
197 else 216
198 return(rsa); 217 return ok;
199 } 218 }
200 219
201#endif