diff options
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_gen.c')
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_gen.c | 160 |
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 | ||
71 | static 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 | 67 | RSA *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. */ | ||
78 | int 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 | |||
85 | static 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; |
205 | err: | 181 | err: |
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 | ||