Line data Source code
1 : /* crypto/srp/srp_lib.c */
2 : /*
3 : * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
4 : * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
5 : * EdelKey project and contributed to the OpenSSL project 2004.
6 : */
7 : /* ====================================================================
8 : * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
9 : *
10 : * Redistribution and use in source and binary forms, with or without
11 : * modification, are permitted provided that the following conditions
12 : * are met:
13 : *
14 : * 1. Redistributions of source code must retain the above copyright
15 : * notice, this list of conditions and the following disclaimer.
16 : *
17 : * 2. Redistributions in binary form must reproduce the above copyright
18 : * notice, this list of conditions and the following disclaimer in
19 : * the documentation and/or other materials provided with the
20 : * distribution.
21 : *
22 : * 3. All advertising materials mentioning features or use of this
23 : * software must display the following acknowledgment:
24 : * "This product includes software developed by the OpenSSL Project
25 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 : *
27 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
28 : * endorse or promote products derived from this software without
29 : * prior written permission. For written permission, please contact
30 : * licensing@OpenSSL.org.
31 : *
32 : * 5. Products derived from this software may not be called "OpenSSL"
33 : * nor may "OpenSSL" appear in their names without prior written
34 : * permission of the OpenSSL Project.
35 : *
36 : * 6. Redistributions of any form whatsoever must retain the following
37 : * acknowledgment:
38 : * "This product includes software developed by the OpenSSL Project
39 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
42 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
45 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52 : * OF THE POSSIBILITY OF SUCH DAMAGE.
53 : * ====================================================================
54 : *
55 : * This product includes cryptographic software written by Eric Young
56 : * (eay@cryptsoft.com). This product includes software written by Tim
57 : * Hudson (tjh@cryptsoft.com).
58 : *
59 : */
60 : #ifndef OPENSSL_NO_SRP
61 : # include "cryptlib.h"
62 : # include "srp_lcl.h"
63 : # include <openssl/srp.h>
64 : # include <openssl/evp.h>
65 :
66 : # if (BN_BYTES == 8)
67 : # if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
68 : # define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64)
69 : # elif defined(__arch64__)
70 : # define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL)
71 : # else
72 : # define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL)
73 : # endif
74 : # elif (BN_BYTES == 4)
75 : # define bn_pack4(a1,a2,a3,a4) ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL)
76 : # else
77 : # error "unsupported BN_BYTES"
78 : # endif
79 :
80 : # include "srp_grps.h"
81 :
82 0 : static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
83 : {
84 : /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
85 :
86 : unsigned char digest[SHA_DIGEST_LENGTH];
87 : unsigned char *tmp;
88 : EVP_MD_CTX ctxt;
89 : int longg;
90 0 : int longN = BN_num_bytes(N);
91 :
92 0 : if (BN_ucmp(g, N) >= 0)
93 : return NULL;
94 :
95 0 : if ((tmp = OPENSSL_malloc(longN)) == NULL)
96 : return NULL;
97 0 : BN_bn2bin(N, tmp);
98 :
99 0 : EVP_MD_CTX_init(&ctxt);
100 0 : EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
101 0 : EVP_DigestUpdate(&ctxt, tmp, longN);
102 :
103 : memset(tmp, 0, longN);
104 0 : longg = BN_bn2bin(g, tmp);
105 : /* use the zeros behind to pad on left */
106 0 : EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg);
107 0 : EVP_DigestUpdate(&ctxt, tmp, longg);
108 0 : OPENSSL_free(tmp);
109 :
110 0 : EVP_DigestFinal_ex(&ctxt, digest, NULL);
111 0 : EVP_MD_CTX_cleanup(&ctxt);
112 0 : return BN_bin2bn(digest, sizeof(digest), NULL);
113 : }
114 :
115 0 : BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
116 : {
117 : /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
118 :
119 : BIGNUM *u;
120 : unsigned char cu[SHA_DIGEST_LENGTH];
121 : unsigned char *cAB;
122 : EVP_MD_CTX ctxt;
123 : int longN;
124 0 : if ((A == NULL) || (B == NULL) || (N == NULL))
125 : return NULL;
126 :
127 0 : if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0)
128 : return NULL;
129 :
130 0 : longN = BN_num_bytes(N);
131 :
132 0 : if ((cAB = OPENSSL_malloc(2 * longN)) == NULL)
133 : return NULL;
134 :
135 0 : memset(cAB, 0, longN);
136 :
137 0 : EVP_MD_CTX_init(&ctxt);
138 0 : EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
139 0 : EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN);
140 0 : EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN);
141 0 : OPENSSL_free(cAB);
142 0 : EVP_DigestFinal_ex(&ctxt, cu, NULL);
143 0 : EVP_MD_CTX_cleanup(&ctxt);
144 :
145 0 : if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
146 : return NULL;
147 0 : if (!BN_is_zero(u))
148 : return u;
149 0 : BN_free(u);
150 0 : return NULL;
151 : }
152 :
153 0 : BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
154 : BIGNUM *N)
155 : {
156 : BIGNUM *tmp = NULL, *S = NULL;
157 : BN_CTX *bn_ctx;
158 :
159 0 : if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
160 : return NULL;
161 :
162 0 : if ((bn_ctx = BN_CTX_new()) == NULL ||
163 0 : (tmp = BN_new()) == NULL || (S = BN_new()) == NULL)
164 : goto err;
165 :
166 : /* S = (A*v**u) ** b */
167 :
168 0 : if (!BN_mod_exp(tmp, v, u, N, bn_ctx))
169 : goto err;
170 0 : if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx))
171 : goto err;
172 0 : if (!BN_mod_exp(S, tmp, b, N, bn_ctx))
173 : goto err;
174 : err:
175 0 : BN_CTX_free(bn_ctx);
176 0 : BN_clear_free(tmp);
177 0 : return S;
178 : }
179 :
180 0 : BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
181 : {
182 : BIGNUM *kv = NULL, *gb = NULL;
183 : BIGNUM *B = NULL, *k = NULL;
184 : BN_CTX *bn_ctx;
185 :
186 0 : if (b == NULL || N == NULL || g == NULL || v == NULL ||
187 : (bn_ctx = BN_CTX_new()) == NULL)
188 : return NULL;
189 :
190 0 : if ((kv = BN_new()) == NULL ||
191 0 : (gb = BN_new()) == NULL || (B = BN_new()) == NULL)
192 : goto err;
193 :
194 : /* B = g**b + k*v */
195 :
196 0 : if (!BN_mod_exp(gb, g, b, N, bn_ctx) ||
197 0 : !(k = srp_Calc_k(N, g)) ||
198 0 : !BN_mod_mul(kv, v, k, N, bn_ctx) ||
199 0 : !BN_mod_add(B, gb, kv, N, bn_ctx)) {
200 0 : BN_free(B);
201 : B = NULL;
202 : }
203 : err:
204 0 : BN_CTX_free(bn_ctx);
205 0 : BN_clear_free(kv);
206 0 : BN_clear_free(gb);
207 0 : BN_free(k);
208 0 : return B;
209 : }
210 :
211 0 : BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
212 : {
213 : unsigned char dig[SHA_DIGEST_LENGTH];
214 : EVP_MD_CTX ctxt;
215 : unsigned char *cs;
216 :
217 0 : if ((s == NULL) || (user == NULL) || (pass == NULL))
218 : return NULL;
219 :
220 0 : if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
221 : return NULL;
222 :
223 0 : EVP_MD_CTX_init(&ctxt);
224 0 : EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
225 0 : EVP_DigestUpdate(&ctxt, user, strlen(user));
226 0 : EVP_DigestUpdate(&ctxt, ":", 1);
227 0 : EVP_DigestUpdate(&ctxt, pass, strlen(pass));
228 0 : EVP_DigestFinal_ex(&ctxt, dig, NULL);
229 :
230 0 : EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
231 0 : BN_bn2bin(s, cs);
232 0 : EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
233 0 : OPENSSL_free(cs);
234 0 : EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
235 0 : EVP_DigestFinal_ex(&ctxt, dig, NULL);
236 0 : EVP_MD_CTX_cleanup(&ctxt);
237 :
238 0 : return BN_bin2bn(dig, sizeof(dig), NULL);
239 : }
240 :
241 0 : BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
242 : {
243 : BN_CTX *bn_ctx;
244 : BIGNUM *A = NULL;
245 :
246 0 : if (a == NULL || N == NULL || g == NULL ||
247 : (bn_ctx = BN_CTX_new()) == NULL)
248 : return NULL;
249 :
250 0 : if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) {
251 0 : BN_free(A);
252 : A = NULL;
253 : }
254 0 : BN_CTX_free(bn_ctx);
255 0 : return A;
256 : }
257 :
258 0 : BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
259 : BIGNUM *a, BIGNUM *u)
260 : {
261 : BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL;
262 : BN_CTX *bn_ctx;
263 :
264 0 : if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
265 0 : || a == NULL || (bn_ctx = BN_CTX_new()) == NULL)
266 : return NULL;
267 :
268 0 : if ((tmp = BN_new()) == NULL ||
269 0 : (tmp2 = BN_new()) == NULL ||
270 0 : (tmp3 = BN_new()) == NULL || (K = BN_new()) == NULL)
271 : goto err;
272 :
273 0 : if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
274 : goto err;
275 0 : if (!(k = srp_Calc_k(N, g)))
276 : goto err;
277 0 : if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
278 : goto err;
279 0 : if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
280 : goto err;
281 :
282 0 : if (!BN_mod_mul(tmp3, u, x, N, bn_ctx))
283 : goto err;
284 0 : if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx))
285 : goto err;
286 0 : if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx))
287 : goto err;
288 :
289 : err:
290 0 : BN_CTX_free(bn_ctx);
291 0 : BN_clear_free(tmp);
292 0 : BN_clear_free(tmp2);
293 0 : BN_clear_free(tmp3);
294 0 : BN_free(k);
295 0 : return K;
296 : }
297 :
298 0 : int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
299 : {
300 : BIGNUM *r;
301 : BN_CTX *bn_ctx;
302 : int ret = 0;
303 :
304 0 : if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL)
305 : return 0;
306 :
307 0 : if ((r = BN_new()) == NULL)
308 : goto err;
309 : /* Checks if B % N == 0 */
310 0 : if (!BN_nnmod(r, B, N, bn_ctx))
311 : goto err;
312 0 : ret = !BN_is_zero(r);
313 : err:
314 0 : BN_CTX_free(bn_ctx);
315 0 : BN_free(r);
316 0 : return ret;
317 : }
318 :
319 0 : int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
320 : {
321 : /* Checks if A % N == 0 */
322 0 : return SRP_Verify_B_mod_N(A, N);
323 : }
324 :
325 : /*
326 : * Check if G and N are kwown parameters. The values have been generated
327 : * from the ietf-tls-srp draft version 8
328 : */
329 0 : char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
330 : {
331 : size_t i;
332 0 : if ((g == NULL) || (N == NULL))
333 : return 0;
334 :
335 : srp_bn_print(g);
336 : srp_bn_print(N);
337 :
338 0 : for (i = 0; i < KNOWN_GN_NUMBER; i++) {
339 0 : if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
340 0 : return knowngN[i].id;
341 : }
342 : return NULL;
343 : }
344 :
345 0 : SRP_gN *SRP_get_default_gN(const char *id)
346 : {
347 : size_t i;
348 :
349 0 : if (id == NULL)
350 : return knowngN;
351 0 : for (i = 0; i < KNOWN_GN_NUMBER; i++) {
352 0 : if (strcmp(knowngN[i].id, id) == 0)
353 0 : return knowngN + i;
354 : }
355 : return NULL;
356 : }
357 : #endif
|