summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dh/dh_key.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/dh/dh_key.c236
1 files changed, 114 insertions, 122 deletions
diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c
index d35eb6e740..4fbedd8daa 100644
--- a/src/lib/libcrypto/dh/dh_key.c
+++ b/src/lib/libcrypto/dh/dh_key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh_key.c,v 1.18 2014/06/12 15:49:28 deraadt Exp $ */ 1/* $OpenBSD: dh_key.c,v 1.19 2014/07/09 13:26:47 miod Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -64,22 +64,22 @@
64 64
65static int generate_key(DH *dh); 65static int generate_key(DH *dh);
66static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); 66static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
67static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, 67static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a,
68 const BIGNUM *a, const BIGNUM *p, 68 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
69 const BIGNUM *m, BN_CTX *ctx,
70 BN_MONT_CTX *m_ctx);
71static int dh_init(DH *dh); 69static int dh_init(DH *dh);
72static int dh_finish(DH *dh); 70static int dh_finish(DH *dh);
73 71
74int DH_generate_key(DH *dh) 72int
75 { 73DH_generate_key(DH *dh)
74{
76 return dh->meth->generate_key(dh); 75 return dh->meth->generate_key(dh);
77 } 76}
78 77
79int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 78int
80 { 79DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
80{
81 return dh->meth->compute_key(key, pub_key, dh); 81 return dh->meth->compute_key(key, pub_key, dh);
82 } 82}
83 83
84static DH_METHOD dh_ossl = { 84static DH_METHOD dh_ossl = {
85 .name = "OpenSSL DH Method", 85 .name = "OpenSSL DH Method",
@@ -90,184 +90,176 @@ static DH_METHOD dh_ossl = {
90 .finish = dh_finish, 90 .finish = dh_finish,
91}; 91};
92 92
93const DH_METHOD *DH_OpenSSL(void) 93const DH_METHOD *
94DH_OpenSSL(void)
94{ 95{
95 return &dh_ossl; 96 return &dh_ossl;
96} 97}
97 98
98static int generate_key(DH *dh) 99static int
99 { 100generate_key(DH *dh)
100 int ok=0; 101{
101 int generate_new_key=0; 102 int ok = 0;
103 int generate_new_key = 0;
102 unsigned l; 104 unsigned l;
103 BN_CTX *ctx; 105 BN_CTX *ctx;
104 BN_MONT_CTX *mont=NULL; 106 BN_MONT_CTX *mont = NULL;
105 BIGNUM *pub_key=NULL,*priv_key=NULL; 107 BIGNUM *pub_key = NULL, *priv_key = NULL;
106 108
107 ctx = BN_CTX_new(); 109 ctx = BN_CTX_new();
108 if (ctx == NULL) goto err; 110 if (ctx == NULL)
109 111 goto err;
110 if (dh->priv_key == NULL)
111 {
112 priv_key=BN_new();
113 if (priv_key == NULL) goto err;
114 generate_new_key=1;
115 }
116 else
117 priv_key=dh->priv_key;
118 112
119 if (dh->pub_key == NULL) 113 if (dh->priv_key == NULL) {
120 { 114 priv_key = BN_new();
121 pub_key=BN_new(); 115 if (priv_key == NULL)
122 if (pub_key == NULL) goto err; 116 goto err;
123 } 117 generate_new_key = 1;
124 else 118 } else
125 pub_key=dh->pub_key; 119 priv_key = dh->priv_key;
126 120
121 if (dh->pub_key == NULL) {
122 pub_key = BN_new();
123 if (pub_key == NULL)
124 goto err;
125 } else
126 pub_key = dh->pub_key;
127 127
128 if (dh->flags & DH_FLAG_CACHE_MONT_P) 128 if (dh->flags & DH_FLAG_CACHE_MONT_P) {
129 {
130 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, 129 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
131 CRYPTO_LOCK_DH, dh->p, ctx); 130 CRYPTO_LOCK_DH, dh->p, ctx);
132 if (!mont) 131 if (!mont)
133 goto err; 132 goto err;
134 } 133 }
135 134
136 if (generate_new_key) 135 if (generate_new_key) {
137 { 136 if (dh->q) {
138 if (dh->q) 137 do {
139 {
140 do
141 {
142 if (!BN_rand_range(priv_key, dh->q)) 138 if (!BN_rand_range(priv_key, dh->q))
143 goto err; 139 goto err;
144 } 140 } while (BN_is_zero(priv_key) || BN_is_one(priv_key));
145 while (BN_is_zero(priv_key) || BN_is_one(priv_key)); 141 } else {
146 }
147 else
148 {
149 /* secret exponent length */ 142 /* secret exponent length */
150 l = dh->length ? dh->length : BN_num_bits(dh->p)-1; 143 l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
151 if (!BN_rand(priv_key, l, 0, 0)) goto err; 144 if (!BN_rand(priv_key, l, 0, 0))
152 } 145 goto err;
153 } 146 }
147 }
154 148
155 { 149 {
156 BIGNUM local_prk; 150 BIGNUM local_prk;
157 BIGNUM *prk; 151 BIGNUM *prk;
158 152
159 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) 153 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
160 {
161 BN_init(&local_prk); 154 BN_init(&local_prk);
162 prk = &local_prk; 155 prk = &local_prk;
163 BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); 156 BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
164 } 157 } else
165 else
166 prk = priv_key; 158 prk = priv_key;
167 159
168 if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; 160 if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx,
161 mont))
162 goto err;
169 } 163 }
170 164
171 dh->pub_key=pub_key; 165 dh->pub_key = pub_key;
172 dh->priv_key=priv_key; 166 dh->priv_key = priv_key;
173 ok=1; 167 ok = 1;
174err: 168err:
175 if (ok != 1) 169 if (ok != 1)
176 DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); 170 DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
177 171
178 if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); 172 if (pub_key != NULL && dh->pub_key == NULL)
179 if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); 173 BN_free(pub_key);
174 if (priv_key != NULL && dh->priv_key == NULL)
175 BN_free(priv_key);
180 BN_CTX_free(ctx); 176 BN_CTX_free(ctx);
181 return(ok); 177 return ok;
182 } 178}
183 179
184static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 180static int
185 { 181compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
186 BN_CTX *ctx=NULL; 182{
187 BN_MONT_CTX *mont=NULL; 183 BN_CTX *ctx = NULL;
184 BN_MONT_CTX *mont = NULL;
188 BIGNUM *tmp; 185 BIGNUM *tmp;
189 int ret= -1; 186 int ret = -1;
190 int check_result; 187 int check_result;
191 188
192 if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) 189 if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
193 { 190 DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
194 DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
195 goto err; 191 goto err;
196 } 192 }
197 193
198 ctx = BN_CTX_new(); 194 ctx = BN_CTX_new();
199 if (ctx == NULL) goto err; 195 if (ctx == NULL)
196 goto err;
200 BN_CTX_start(ctx); 197 BN_CTX_start(ctx);
201 tmp = BN_CTX_get(ctx); 198 tmp = BN_CTX_get(ctx);
202 199
203 if (dh->priv_key == NULL) 200 if (dh->priv_key == NULL) {
204 { 201 DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
205 DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
206 goto err; 202 goto err;
207 } 203 }
208 204
209 if (dh->flags & DH_FLAG_CACHE_MONT_P) 205 if (dh->flags & DH_FLAG_CACHE_MONT_P) {
210 {
211 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, 206 mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
212 CRYPTO_LOCK_DH, dh->p, ctx); 207 CRYPTO_LOCK_DH, dh->p, ctx);
213 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) 208 if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
214 {
215 /* XXX */ 209 /* XXX */
216 BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); 210 BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
217 } 211 }
218 if (!mont) 212 if (!mont)
219 goto err; 213 goto err;
220 } 214 }
221 215
222 if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) 216 if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
223 { 217 DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
224 DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY);
225 goto err; 218 goto err;
226 } 219 }
227 220
228 if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) 221 if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx,
229 { 222 mont)) {
230 DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB); 223 DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
231 goto err; 224 goto err;
232 } 225 }
233 226
234 ret=BN_bn2bin(tmp,key); 227 ret = BN_bn2bin(tmp, key);
235err: 228err:
236 if (ctx != NULL) 229 if (ctx != NULL) {
237 {
238 BN_CTX_end(ctx); 230 BN_CTX_end(ctx);
239 BN_CTX_free(ctx); 231 BN_CTX_free(ctx);
240 }
241 return(ret);
242 } 232 }
233 return ret;
234}
243 235
244static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, 236static int
245 const BIGNUM *a, const BIGNUM *p, 237dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
246 const BIGNUM *m, BN_CTX *ctx, 238 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
247 BN_MONT_CTX *m_ctx) 239{
248 { 240 /*
249 /* If a is only one word long and constant time is false, use the faster 241 * If a is only one word long and constant time is false, use the faster
250 * exponenentiation function. 242 * exponenentiation function.
251 */ 243 */
252 if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) 244 if (a->top == 1 && (dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0) {
253 {
254 BN_ULONG A = a->d[0]; 245 BN_ULONG A = a->d[0];
255 return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
256 }
257 else
258 return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
259 }
260 246
247 return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx);
248 } else
249 return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
250}
261 251
262static int dh_init(DH *dh) 252static int
263 { 253dh_init(DH *dh)
254{
264 dh->flags |= DH_FLAG_CACHE_MONT_P; 255 dh->flags |= DH_FLAG_CACHE_MONT_P;
265 return(1); 256 return 1;
266 } 257}
267 258
268static int dh_finish(DH *dh) 259static int
269 { 260dh_finish(DH *dh)
270 if(dh->method_mont_p) 261{
262 if (dh->method_mont_p)
271 BN_MONT_CTX_free(dh->method_mont_p); 263 BN_MONT_CTX_free(dh->method_mont_p);
272 return(1); 264 return 1;
273 } 265}