]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/srp/srp_lib.c
253aaf9a5791efa02d1e7fd0bd293a7b56ef5c93
2 * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
10 * Originally written by Christophe Renou and Peter Sylvester,
11 * for the EdelKey project.
14 #ifndef OPENSSL_NO_SRP
15 # include "internal/cryptlib.h"
16 # include <openssl/sha.h>
17 # include <openssl/srp.h>
18 # include <openssl/evp.h>
19 # include "crypto/bn_srp.h"
21 /* calculate = SHA1(PAD(x) || PAD(y)) */
23 static BIGNUM
*srp_Calc_xy(const BIGNUM
*x
, const BIGNUM
*y
, const BIGNUM
*N
,
24 OPENSSL_CTX
*libctx
, const char *propq
)
26 unsigned char digest
[SHA_DIGEST_LENGTH
];
27 unsigned char *tmp
= NULL
;
28 int numN
= BN_num_bytes(N
);
30 EVP_MD
*sha1
= EVP_MD_fetch(libctx
, "SHA1", propq
);
35 if (x
!= N
&& BN_ucmp(x
, N
) >= 0)
37 if (y
!= N
&& BN_ucmp(y
, N
) >= 0)
39 if ((tmp
= OPENSSL_malloc(numN
* 2)) == NULL
)
41 if (BN_bn2binpad(x
, tmp
, numN
) < 0
42 || BN_bn2binpad(y
, tmp
+ numN
, numN
) < 0
43 || !EVP_Digest(tmp
, numN
* 2, digest
, NULL
, sha1
, NULL
))
45 res
= BN_bin2bn(digest
, sizeof(digest
), NULL
);
52 static BIGNUM
*srp_Calc_k(const BIGNUM
*N
, const BIGNUM
*g
, OPENSSL_CTX
*libctx
,
55 /* k = SHA1(N | PAD(g)) -- tls-srp RFC 5054 */
56 return srp_Calc_xy(N
, g
, N
, libctx
, propq
);
59 BIGNUM
*SRP_Calc_u_ex(const BIGNUM
*A
, const BIGNUM
*B
, const BIGNUM
*N
,
60 OPENSSL_CTX
*libctx
, const char *propq
)
62 /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */
63 return srp_Calc_xy(A
, B
, N
, libctx
, propq
);
66 BIGNUM
*SRP_Calc_u(const BIGNUM
*A
, const BIGNUM
*B
, const BIGNUM
*N
)
68 /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */
69 return srp_Calc_xy(A
, B
, N
, NULL
, NULL
);
72 BIGNUM
*SRP_Calc_server_key(const BIGNUM
*A
, const BIGNUM
*v
, const BIGNUM
*u
,
73 const BIGNUM
*b
, const BIGNUM
*N
)
75 BIGNUM
*tmp
= NULL
, *S
= NULL
;
78 if (u
== NULL
|| A
== NULL
|| v
== NULL
|| b
== NULL
|| N
== NULL
)
81 if ((bn_ctx
= BN_CTX_new()) == NULL
|| (tmp
= BN_new()) == NULL
)
84 /* S = (A*v**u) ** b */
86 if (!BN_mod_exp(tmp
, v
, u
, N
, bn_ctx
))
88 if (!BN_mod_mul(tmp
, A
, tmp
, N
, bn_ctx
))
92 if (S
!= NULL
&& !BN_mod_exp(S
, tmp
, b
, N
, bn_ctx
)) {
102 BIGNUM
*SRP_Calc_B_ex(const BIGNUM
*b
, const BIGNUM
*N
, const BIGNUM
*g
,
103 const BIGNUM
*v
, OPENSSL_CTX
*libctx
, const char *propq
)
105 BIGNUM
*kv
= NULL
, *gb
= NULL
;
106 BIGNUM
*B
= NULL
, *k
= NULL
;
109 if (b
== NULL
|| N
== NULL
|| g
== NULL
|| v
== NULL
||
110 (bn_ctx
= BN_CTX_new_ex(libctx
)) == NULL
)
113 if ((kv
= BN_new()) == NULL
||
114 (gb
= BN_new()) == NULL
|| (B
= BN_new()) == NULL
)
119 if (!BN_mod_exp(gb
, g
, b
, N
, bn_ctx
)
120 || (k
= srp_Calc_k(N
, g
, libctx
, propq
)) == NULL
121 || !BN_mod_mul(kv
, v
, k
, N
, bn_ctx
)
122 || !BN_mod_add(B
, gb
, kv
, N
, bn_ctx
)) {
134 BIGNUM
*SRP_Calc_B(const BIGNUM
*b
, const BIGNUM
*N
, const BIGNUM
*g
,
137 return SRP_Calc_B_ex(b
, N
, g
, v
, NULL
, NULL
);
140 BIGNUM
*SRP_Calc_x_ex(const BIGNUM
*s
, const char *user
, const char *pass
,
141 OPENSSL_CTX
*libctx
, const char *propq
)
143 unsigned char dig
[SHA_DIGEST_LENGTH
];
145 unsigned char *cs
= NULL
;
149 if ((s
== NULL
) || (user
== NULL
) || (pass
== NULL
))
152 ctxt
= EVP_MD_CTX_new();
155 if ((cs
= OPENSSL_malloc(BN_num_bytes(s
))) == NULL
)
158 sha1
= EVP_MD_fetch(libctx
, "SHA1", propq
);
162 if (!EVP_DigestInit_ex(ctxt
, sha1
, NULL
)
163 || !EVP_DigestUpdate(ctxt
, user
, strlen(user
))
164 || !EVP_DigestUpdate(ctxt
, ":", 1)
165 || !EVP_DigestUpdate(ctxt
, pass
, strlen(pass
))
166 || !EVP_DigestFinal_ex(ctxt
, dig
, NULL
)
167 || !EVP_DigestInit_ex(ctxt
, sha1
, NULL
))
169 if (BN_bn2bin(s
, cs
) < 0)
171 if (!EVP_DigestUpdate(ctxt
, cs
, BN_num_bytes(s
)))
174 if (!EVP_DigestUpdate(ctxt
, dig
, sizeof(dig
))
175 || !EVP_DigestFinal_ex(ctxt
, dig
, NULL
))
178 res
= BN_bin2bn(dig
, sizeof(dig
), NULL
);
183 EVP_MD_CTX_free(ctxt
);
187 BIGNUM
*SRP_Calc_x(const BIGNUM
*s
, const char *user
, const char *pass
)
189 return SRP_Calc_x_ex(s
, user
, pass
, NULL
, NULL
);
192 BIGNUM
*SRP_Calc_A(const BIGNUM
*a
, const BIGNUM
*N
, const BIGNUM
*g
)
197 if (a
== NULL
|| N
== NULL
|| g
== NULL
|| (bn_ctx
= BN_CTX_new()) == NULL
)
200 if ((A
= BN_new()) != NULL
&& !BN_mod_exp(A
, g
, a
, N
, bn_ctx
)) {
208 BIGNUM
*SRP_Calc_client_key_ex(const BIGNUM
*N
, const BIGNUM
*B
, const BIGNUM
*g
,
209 const BIGNUM
*x
, const BIGNUM
*a
, const BIGNUM
*u
,
210 OPENSSL_CTX
*libctx
, const char *propq
)
212 BIGNUM
*tmp
= NULL
, *tmp2
= NULL
, *tmp3
= NULL
, *k
= NULL
, *K
= NULL
;
215 if (u
== NULL
|| B
== NULL
|| N
== NULL
|| g
== NULL
|| x
== NULL
216 || a
== NULL
|| (bn_ctx
= BN_CTX_new_ex(libctx
)) == NULL
)
219 if ((tmp
= BN_new()) == NULL
||
220 (tmp2
= BN_new()) == NULL
||
221 (tmp3
= BN_new()) == NULL
)
224 if (!BN_mod_exp(tmp
, g
, x
, N
, bn_ctx
))
226 if ((k
= srp_Calc_k(N
, g
, libctx
, propq
)) == NULL
)
228 if (!BN_mod_mul(tmp2
, tmp
, k
, N
, bn_ctx
))
230 if (!BN_mod_sub(tmp
, B
, tmp2
, N
, bn_ctx
))
232 if (!BN_mul(tmp3
, u
, x
, bn_ctx
))
234 if (!BN_add(tmp2
, a
, tmp3
))
237 if (K
!= NULL
&& !BN_mod_exp(K
, tmp
, tmp2
, N
, bn_ctx
)) {
251 BIGNUM
*SRP_Calc_client_key(const BIGNUM
*N
, const BIGNUM
*B
, const BIGNUM
*g
,
252 const BIGNUM
*x
, const BIGNUM
*a
, const BIGNUM
*u
)
254 return SRP_Calc_client_key_ex(N
, B
, g
, x
, a
, u
, NULL
, NULL
);
257 int SRP_Verify_B_mod_N(const BIGNUM
*B
, const BIGNUM
*N
)
263 if (B
== NULL
|| N
== NULL
|| (bn_ctx
= BN_CTX_new()) == NULL
)
266 if ((r
= BN_new()) == NULL
)
268 /* Checks if B % N == 0 */
269 if (!BN_nnmod(r
, B
, N
, bn_ctx
))
271 ret
= !BN_is_zero(r
);
278 int SRP_Verify_A_mod_N(const BIGNUM
*A
, const BIGNUM
*N
)
280 /* Checks if A % N == 0 */
281 return SRP_Verify_B_mod_N(A
, N
);
284 static SRP_gN knowngN
[] = {
285 {"8192", &bn_generator_19
, &bn_group_8192
},
286 {"6144", &bn_generator_5
, &bn_group_6144
},
287 {"4096", &bn_generator_5
, &bn_group_4096
},
288 {"3072", &bn_generator_5
, &bn_group_3072
},
289 {"2048", &bn_generator_2
, &bn_group_2048
},
290 {"1536", &bn_generator_2
, &bn_group_1536
},
291 {"1024", &bn_generator_2
, &bn_group_1024
},
294 # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
297 * Check if G and N are known parameters. The values have been generated
298 * from the IETF RFC 5054
300 char *SRP_check_known_gN_param(const BIGNUM
*g
, const BIGNUM
*N
)
303 if ((g
== NULL
) || (N
== NULL
))
306 for (i
= 0; i
< KNOWN_GN_NUMBER
; i
++) {
307 if (BN_cmp(knowngN
[i
].g
, g
) == 0 && BN_cmp(knowngN
[i
].N
, N
) == 0)
308 return knowngN
[i
].id
;
313 SRP_gN
*SRP_get_default_gN(const char *id
)
319 for (i
= 0; i
< KNOWN_GN_NUMBER
; i
++) {
320 if (strcmp(knowngN
[i
].id
, id
) == 0)