summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dh/dh_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/dh/dh_key.c')
-rw-r--r--src/lib/libcrypto/dh/dh_key.c131
1 files changed, 106 insertions, 25 deletions
diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c
index 7576772bcd..1a0efca2c4 100644
--- a/src/lib/libcrypto/dh/dh_key.c
+++ b/src/lib/libcrypto/dh/dh_key.c
@@ -58,32 +58,63 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn.h" 61#include <openssl/bn.h>
62#include "rand.h" 62#include <openssl/rand.h>
63#include "dh.h" 63#include <openssl/dh.h>
64#include <openssl/engine.h>
64 65
65int DH_generate_key(dh) 66static int generate_key(DH *dh);
66DH *dh; 67static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
68static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
69 const BIGNUM *a, const BIGNUM *p,
70 const BIGNUM *m, BN_CTX *ctx,
71 BN_MONT_CTX *m_ctx);
72static int dh_init(DH *dh);
73static int dh_finish(DH *dh);
74
75int DH_generate_key(DH *dh)
76 {
77 return dh->meth->generate_key(dh);
78 }
79
80int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
81 {
82 return dh->meth->compute_key(key, pub_key, dh);
83 }
84
85static DH_METHOD dh_ossl = {
86"OpenSSL DH Method",
87generate_key,
88compute_key,
89dh_bn_mod_exp,
90dh_init,
91dh_finish,
920,
93NULL
94};
95
96const DH_METHOD *DH_OpenSSL(void)
97{
98 return &dh_ossl;
99}
100
101static int generate_key(DH *dh)
67 { 102 {
68 int ok=0; 103 int ok=0;
69 unsigned int i; 104 int generate_new_key=0;
70 BN_CTX *ctx=NULL; 105 unsigned l;
106 BN_CTX *ctx;
107 BN_MONT_CTX *mont;
71 BIGNUM *pub_key=NULL,*priv_key=NULL; 108 BIGNUM *pub_key=NULL,*priv_key=NULL;
72 109
73 ctx=BN_CTX_new(); 110 ctx = BN_CTX_new();
74 if (ctx == NULL) goto err; 111 if (ctx == NULL) goto err;
75 112
76 if (dh->priv_key == NULL) 113 if (dh->priv_key == NULL)
77 { 114 {
78 i=dh->length;
79 if (i == 0)
80 {
81 /* Make the number p-1 bits long */
82 i=BN_num_bits(dh->p)-1;
83 }
84 priv_key=BN_new(); 115 priv_key=BN_new();
85 if (priv_key == NULL) goto err; 116 if (priv_key == NULL) goto err;
86 if (!BN_rand(priv_key,i,0,0)) goto err; 117 generate_new_key=1;
87 } 118 }
88 else 119 else
89 priv_key=dh->priv_key; 120 priv_key=dh->priv_key;
@@ -96,7 +127,21 @@ DH *dh;
96 else 127 else
97 pub_key=dh->pub_key; 128 pub_key=dh->pub_key;
98 129
99 if (!BN_mod_exp(pub_key,dh->g,priv_key,dh->p,ctx)) goto err; 130 if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
131 {
132 if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
133 if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
134 dh->p,ctx)) goto err;
135 }
136 mont=(BN_MONT_CTX *)dh->method_mont_p;
137
138 if (generate_new_key)
139 {
140 l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
141 if (!BN_rand(priv_key, l, 0, 0)) goto err;
142 }
143 if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key,dh->p,ctx,mont))
144 goto err;
100 145
101 dh->pub_key=pub_key; 146 dh->pub_key=pub_key;
102 dh->priv_key=priv_key; 147 dh->priv_key=priv_key;
@@ -107,29 +152,36 @@ err:
107 152
108 if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); 153 if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key);
109 if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); 154 if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
110 if (ctx != NULL) BN_CTX_free(ctx); 155 BN_CTX_free(ctx);
111 return(ok); 156 return(ok);
112 } 157 }
113 158
114int DH_compute_key(key,pub_key,dh) 159static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
115unsigned char *key;
116BIGNUM *pub_key;
117DH *dh;
118 { 160 {
119 BN_CTX *ctx; 161 BN_CTX *ctx;
162 BN_MONT_CTX *mont;
120 BIGNUM *tmp; 163 BIGNUM *tmp;
121 int ret= -1; 164 int ret= -1;
122 165
123 ctx=BN_CTX_new(); 166 ctx = BN_CTX_new();
124 if (ctx == NULL) goto err; 167 if (ctx == NULL) goto err;
125 tmp=ctx->bn[ctx->tos++]; 168 BN_CTX_start(ctx);
169 tmp = BN_CTX_get(ctx);
126 170
127 if (dh->priv_key == NULL) 171 if (dh->priv_key == NULL)
128 { 172 {
129 DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); 173 DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
130 goto err; 174 goto err;
131 } 175 }
132 if (!BN_mod_exp(tmp,pub_key,dh->priv_key,dh->p,ctx)) 176 if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
177 {
178 if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
179 if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
180 dh->p,ctx)) goto err;
181 }
182
183 mont=(BN_MONT_CTX *)dh->method_mont_p;
184 if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
133 { 185 {
134 DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); 186 DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
135 goto err; 187 goto err;
@@ -137,6 +189,35 @@ DH *dh;
137 189
138 ret=BN_bn2bin(tmp,key); 190 ret=BN_bn2bin(tmp,key);
139err: 191err:
140 if (ctx != NULL) BN_CTX_free(ctx); 192 BN_CTX_end(ctx);
193 BN_CTX_free(ctx);
141 return(ret); 194 return(ret);
142 } 195 }
196
197static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
198 const BIGNUM *a, const BIGNUM *p,
199 const BIGNUM *m, BN_CTX *ctx,
200 BN_MONT_CTX *m_ctx)
201 {
202 if (a->top == 1)
203 {
204 BN_ULONG A = a->d[0];
205 return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
206 }
207 else
208 return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
209 }
210
211
212static int dh_init(DH *dh)
213 {
214 dh->flags |= DH_FLAG_CACHE_MONT_P;
215 return(1);
216 }
217
218static int dh_finish(DH *dh)
219 {
220 if(dh->method_mont_p)
221 BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
222 return(1);
223 }