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