7f297be81aab7a8b73cf679938349e177f68da82
[openssl.git] / crypto / srp / srp_lib.c
1 /*
2  * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #ifndef OPENSSL_NO_SRP
11 # include "internal/cryptlib.h"
12 # include <openssl/sha.h>
13 # include <openssl/srp.h>
14 # include <openssl/evp.h>
15 # include "internal/bn_srp.h"
16
17 static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g)
18 {
19     /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
20
21     unsigned char digest[SHA_DIGEST_LENGTH];
22     unsigned char *tmp;
23     EVP_MD_CTX *ctxt = NULL;
24     int longg;
25     int longN = BN_num_bytes(N);
26     BIGNUM *res = NULL;
27
28     if (BN_ucmp(g, N) >= 0)
29         return NULL;
30
31     ctxt = EVP_MD_CTX_new();
32     if (ctxt == NULL)
33         return NULL;
34     if ((tmp = OPENSSL_malloc(longN)) == NULL)
35         goto err;
36     BN_bn2bin(N, tmp);
37
38     if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
39         || !EVP_DigestUpdate(ctxt, tmp, longN))
40         goto err;
41
42     memset(tmp, 0, longN);
43     longg = BN_bn2bin(g, tmp);
44     /* use the zeros behind to pad on left */
45     if (!EVP_DigestUpdate(ctxt, tmp + longg, longN - longg)
46         || !EVP_DigestUpdate(ctxt, tmp, longg))
47         goto err;
48     OPENSSL_free(tmp);
49
50     if (!EVP_DigestFinal_ex(ctxt, digest, NULL))
51         goto err;
52     res = BN_bin2bn(digest, sizeof(digest), NULL);
53  err:
54     EVP_MD_CTX_free(ctxt);
55     return res;
56 }
57
58 BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N)
59 {
60     /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
61
62     BIGNUM *u = NULL;
63     unsigned char cu[SHA_DIGEST_LENGTH];
64     unsigned char *cAB = NULL;
65     EVP_MD_CTX *ctxt = NULL;
66     int longN;
67     if ((A == NULL) || (B == NULL) || (N == NULL))
68         return NULL;
69
70     if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0)
71         return NULL;
72
73     longN = BN_num_bytes(N);
74
75     ctxt = EVP_MD_CTX_new();
76     if (ctxt == NULL)
77         return NULL;
78     if ((cAB = OPENSSL_malloc(2 * longN)) == NULL)
79         goto err;
80
81     memset(cAB, 0, longN);
82
83     if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
84         || !EVP_DigestUpdate(ctxt, cAB + BN_bn2bin(A, cAB + longN), longN)
85         || !EVP_DigestUpdate(ctxt, cAB + BN_bn2bin(B, cAB + longN), longN))
86         goto err;
87     OPENSSL_free(cAB);
88     if (!EVP_DigestFinal_ex(ctxt, cu, NULL))
89         goto err;
90
91     if ((u = BN_bin2bn(cu, sizeof(cu), NULL)) == NULL)
92         goto err;
93     if (BN_is_zero(u)) {
94         BN_free(u);
95         u = NULL;
96     }
97  err:
98     EVP_MD_CTX_free(ctxt);
99
100     return u;
101 }
102
103 BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u,
104                             const BIGNUM *b, const BIGNUM *N)
105 {
106     BIGNUM *tmp = NULL, *S = NULL;
107     BN_CTX *bn_ctx;
108
109     if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
110         return NULL;
111
112     if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL)
113         goto err;
114
115     /* S = (A*v**u) ** b */
116
117     if (!BN_mod_exp(tmp, v, u, N, bn_ctx))
118         goto err;
119     if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx))
120         goto err;
121
122     S = BN_new();
123     if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) {
124         BN_free(S);
125         S = NULL;
126     }
127  err:
128     BN_CTX_free(bn_ctx);
129     BN_clear_free(tmp);
130     return S;
131 }
132
133 BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g,
134                    const BIGNUM *v)
135 {
136     BIGNUM *kv = NULL, *gb = NULL;
137     BIGNUM *B = NULL, *k = NULL;
138     BN_CTX *bn_ctx;
139
140     if (b == NULL || N == NULL || g == NULL || v == NULL ||
141         (bn_ctx = BN_CTX_new()) == NULL)
142         return NULL;
143
144     if ((kv = BN_new()) == NULL ||
145         (gb = BN_new()) == NULL || (B = BN_new()) == NULL)
146         goto err;
147
148     /* B = g**b + k*v */
149
150     if (!BN_mod_exp(gb, g, b, N, bn_ctx)
151         || (k = srp_Calc_k(N, g)) == NULL
152         || !BN_mod_mul(kv, v, k, N, bn_ctx)
153         || !BN_mod_add(B, gb, kv, N, bn_ctx)) {
154         BN_free(B);
155         B = NULL;
156     }
157  err:
158     BN_CTX_free(bn_ctx);
159     BN_clear_free(kv);
160     BN_clear_free(gb);
161     BN_free(k);
162     return B;
163 }
164
165 BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass)
166 {
167     unsigned char dig[SHA_DIGEST_LENGTH];
168     EVP_MD_CTX *ctxt;
169     unsigned char *cs;
170     BIGNUM *res = NULL;
171
172     if ((s == NULL) || (user == NULL) || (pass == NULL))
173         return NULL;
174
175     ctxt = EVP_MD_CTX_new();
176     if (ctxt == NULL)
177         return NULL;
178     if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
179         goto err;
180
181     if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
182         || !EVP_DigestUpdate(ctxt, user, strlen(user))
183         || !EVP_DigestUpdate(ctxt, ":", 1)
184         || !EVP_DigestUpdate(ctxt, pass, strlen(pass))
185         || !EVP_DigestFinal_ex(ctxt, dig, NULL)
186         || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL))
187         goto err;
188     BN_bn2bin(s, cs);
189     if (!EVP_DigestUpdate(ctxt, cs, BN_num_bytes(s)))
190         goto err;
191     OPENSSL_free(cs);
192     if (!EVP_DigestUpdate(ctxt, dig, sizeof(dig))
193         || !EVP_DigestFinal_ex(ctxt, dig, NULL))
194         goto err;
195
196     res = BN_bin2bn(dig, sizeof(dig), NULL);
197  err:
198     EVP_MD_CTX_free(ctxt);
199     return res;
200 }
201
202 BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g)
203 {
204     BN_CTX *bn_ctx;
205     BIGNUM *A = NULL;
206
207     if (a == NULL || N == NULL || g == NULL || (bn_ctx = BN_CTX_new()) == NULL)
208         return NULL;
209
210     if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) {
211         BN_free(A);
212         A = NULL;
213     }
214     BN_CTX_free(bn_ctx);
215     return A;
216 }
217
218 BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g,
219                             const BIGNUM *x, const BIGNUM *a, const BIGNUM *u)
220 {
221     BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL;
222     BN_CTX *bn_ctx;
223
224     if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
225         || a == NULL || (bn_ctx = BN_CTX_new()) == NULL)
226         return NULL;
227
228     if ((tmp = BN_new()) == NULL ||
229         (tmp2 = BN_new()) == NULL ||
230         (tmp3 = BN_new()) == NULL)
231         goto err;
232
233     if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
234         goto err;
235     if ((k = srp_Calc_k(N, g)) == NULL)
236         goto err;
237     if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
238         goto err;
239     if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
240         goto err;
241     if (!BN_mul(tmp3, u, x, bn_ctx))
242         goto err;
243     if (!BN_add(tmp2, a, tmp3))
244         goto err;
245     K = BN_new();
246     if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) {
247         BN_free(K);
248         K = NULL;
249     }
250
251  err:
252     BN_CTX_free(bn_ctx);
253     BN_clear_free(tmp);
254     BN_clear_free(tmp2);
255     BN_clear_free(tmp3);
256     BN_free(k);
257     return K;
258 }
259
260 int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N)
261 {
262     BIGNUM *r;
263     BN_CTX *bn_ctx;
264     int ret = 0;
265
266     if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL)
267         return 0;
268
269     if ((r = BN_new()) == NULL)
270         goto err;
271     /* Checks if B % N == 0 */
272     if (!BN_nnmod(r, B, N, bn_ctx))
273         goto err;
274     ret = !BN_is_zero(r);
275  err:
276     BN_CTX_free(bn_ctx);
277     BN_free(r);
278     return ret;
279 }
280
281 int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N)
282 {
283     /* Checks if A % N == 0 */
284     return SRP_Verify_B_mod_N(A, N);
285 }
286
287 static SRP_gN knowngN[] = {
288     {"8192", &bn_generator_19, &bn_group_8192},
289     {"6144", &bn_generator_5, &bn_group_6144},
290     {"4096", &bn_generator_5, &bn_group_4096},
291     {"3072", &bn_generator_5, &bn_group_3072},
292     {"2048", &bn_generator_2, &bn_group_2048},
293     {"1536", &bn_generator_2, &bn_group_1536},
294     {"1024", &bn_generator_2, &bn_group_1024},
295 };
296
297 # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
298
299 /*
300  * Check if G and N are known parameters. The values have been generated
301  * from the ietf-tls-srp draft version 8
302  */
303 char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N)
304 {
305     size_t i;
306     if ((g == NULL) || (N == NULL))
307         return 0;
308
309     for (i = 0; i < KNOWN_GN_NUMBER; i++) {
310         if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
311             return knowngN[i].id;
312     }
313     return NULL;
314 }
315
316 SRP_gN *SRP_get_default_gN(const char *id)
317 {
318     size_t i;
319
320     if (id == NULL)
321         return knowngN;
322     for (i = 0; i < KNOWN_GN_NUMBER; i++) {
323         if (strcmp(knowngN[i].id, id) == 0)
324             return knowngN + i;
325     }
326     return NULL;
327 }
328 #endif