diff options
Diffstat (limited to 'src/lib/libcrypto/dh/dh_key.c')
-rw-r--r-- | src/lib/libcrypto/dh/dh_key.c | 131 |
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 | ||
65 | int DH_generate_key(dh) | 66 | static int generate_key(DH *dh); |
66 | DH *dh; | 67 | static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); |
68 | static 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); | ||
72 | static int dh_init(DH *dh); | ||
73 | static int dh_finish(DH *dh); | ||
74 | |||
75 | int DH_generate_key(DH *dh) | ||
76 | { | ||
77 | return dh->meth->generate_key(dh); | ||
78 | } | ||
79 | |||
80 | int 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 | |||
85 | static DH_METHOD dh_ossl = { | ||
86 | "OpenSSL DH Method", | ||
87 | generate_key, | ||
88 | compute_key, | ||
89 | dh_bn_mod_exp, | ||
90 | dh_init, | ||
91 | dh_finish, | ||
92 | 0, | ||
93 | NULL | ||
94 | }; | ||
95 | |||
96 | const DH_METHOD *DH_OpenSSL(void) | ||
97 | { | ||
98 | return &dh_ossl; | ||
99 | } | ||
100 | |||
101 | static 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 | ||
114 | int DH_compute_key(key,pub_key,dh) | 159 | static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) |
115 | unsigned char *key; | ||
116 | BIGNUM *pub_key; | ||
117 | DH *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); |
139 | err: | 191 | err: |
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 | |||
197 | static 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 | |||
212 | static int dh_init(DH *dh) | ||
213 | { | ||
214 | dh->flags |= DH_FLAG_CACHE_MONT_P; | ||
215 | return(1); | ||
216 | } | ||
217 | |||
218 | static 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 | } | ||