]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/srp/srp_lib.c
2 * Copyright 2004-2021 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 OSSL_LIB_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
,
56 /* k = SHA1(N | PAD(g)) -- tls-srp RFC 5054 */
57 return srp_Calc_xy(N
, g
, N
, libctx
, propq
);
60 BIGNUM
*SRP_Calc_u_ex(const BIGNUM
*A
, const BIGNUM
*B
, const BIGNUM
*N
,
61 OSSL_LIB_CTX
*libctx
, const char *propq
)
63 /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */
64 return srp_Calc_xy(A
, B
, N
, libctx
, propq
);
67 BIGNUM
*SRP_Calc_u(const BIGNUM
*A
, const BIGNUM
*B
, const BIGNUM
*N
)
69 /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */
70 return srp_Calc_xy(A
, B
, N
, NULL
, NULL
);
73 BIGNUM
*SRP_Calc_server_key(const BIGNUM
*A
, const BIGNUM
*v
, const BIGNUM
*u
,
74 const BIGNUM
*b
, const BIGNUM
*N
)
76 BIGNUM
*tmp
= NULL
, *S
= NULL
;
79 if (u
== NULL
|| A
== NULL
|| v
== NULL
|| b
== NULL
|| N
== NULL
)
82 if ((bn_ctx
= BN_CTX_new()) == NULL
|| (tmp
= BN_new()) == NULL
)
85 /* S = (A*v**u) ** b */
87 if (!BN_mod_exp(tmp
, v
, u
, N
, bn_ctx
))
89 if (!BN_mod_mul(tmp
, A
, tmp
, N
, bn_ctx
))
93 if (S
!= NULL
&& !BN_mod_exp(S
, tmp
, b
, N
, bn_ctx
)) {
103 BIGNUM
*SRP_Calc_B_ex(const BIGNUM
*b
, const BIGNUM
*N
, const BIGNUM
*g
,
104 const BIGNUM
*v
, OSSL_LIB_CTX
*libctx
, const char *propq
)
106 BIGNUM
*kv
= NULL
, *gb
= NULL
;
107 BIGNUM
*B
= NULL
, *k
= NULL
;
110 if (b
== NULL
|| N
== NULL
|| g
== NULL
|| v
== NULL
||
111 (bn_ctx
= BN_CTX_new_ex(libctx
)) == NULL
)
114 if ((kv
= BN_new()) == NULL
||
115 (gb
= BN_new()) == NULL
|| (B
= BN_new()) == NULL
)
120 if (!BN_mod_exp(gb
, g
, b
, N
, bn_ctx
)
121 || (k
= srp_Calc_k(N
, g
, libctx
, propq
)) == NULL
122 || !BN_mod_mul(kv
, v
, k
, N
, bn_ctx
)
123 || !BN_mod_add(B
, gb
, kv
, N
, bn_ctx
)) {
135 BIGNUM
*SRP_Calc_B(const BIGNUM
*b
, const BIGNUM
*N
, const BIGNUM
*g
,
138 return SRP_Calc_B_ex(b
, N
, g
, v
, NULL
, NULL
);
141 BIGNUM
*SRP_Calc_x_ex(const BIGNUM
*s
, const char *user
, const char *pass
,
142 OSSL_LIB_CTX
*libctx
, const char *propq
)
144 unsigned char dig
[SHA_DIGEST_LENGTH
];
146 unsigned char *cs
= NULL
;
150 if ((s
== NULL
) || (user
== NULL
) || (pass
== NULL
))
153 ctxt
= EVP_MD_CTX_new();
156 if ((cs
= OPENSSL_malloc(BN_num_bytes(s
))) == NULL
)
159 sha1
= EVP_MD_fetch(libctx
, "SHA1", propq
);
163 if (!EVP_DigestInit_ex(ctxt
, sha1
, NULL
)
164 || !EVP_DigestUpdate(ctxt
, user
, strlen(user
))
165 || !EVP_DigestUpdate(ctxt
, ":", 1)
166 || !EVP_DigestUpdate(ctxt
, pass
, strlen(pass
))
167 || !EVP_DigestFinal_ex(ctxt
, dig
, NULL
)
168 || !EVP_DigestInit_ex(ctxt
, sha1
, NULL
))
170 if (BN_bn2bin(s
, cs
) < 0)
172 if (!EVP_DigestUpdate(ctxt
, cs
, BN_num_bytes(s
)))
175 if (!EVP_DigestUpdate(ctxt
, dig
, sizeof(dig
))
176 || !EVP_DigestFinal_ex(ctxt
, dig
, NULL
))
179 res
= BN_bin2bn(dig
, sizeof(dig
), NULL
);
184 EVP_MD_CTX_free(ctxt
);
188 BIGNUM
*SRP_Calc_x(const BIGNUM
*s
, const char *user
, const char *pass
)
190 return SRP_Calc_x_ex(s
, user
, pass
, NULL
, NULL
);
193 BIGNUM
*SRP_Calc_A(const BIGNUM
*a
, const BIGNUM
*N
, const BIGNUM
*g
)
198 if (a
== NULL
|| N
== NULL
|| g
== NULL
|| (bn_ctx
= BN_CTX_new()) == NULL
)
201 if ((A
= BN_new()) != NULL
&& !BN_mod_exp(A
, g
, a
, N
, bn_ctx
)) {
209 BIGNUM
*SRP_Calc_client_key_ex(const BIGNUM
*N
, const BIGNUM
*B
, const BIGNUM
*g
,
210 const BIGNUM
*x
, const BIGNUM
*a
, const BIGNUM
*u
,
211 OSSL_LIB_CTX
*libctx
, const char *propq
)
213 BIGNUM
*tmp
= NULL
, *tmp2
= NULL
, *tmp3
= NULL
, *k
= NULL
, *K
= NULL
;
217 if (u
== NULL
|| B
== NULL
|| N
== NULL
|| g
== NULL
|| x
== NULL
218 || a
== NULL
|| (bn_ctx
= BN_CTX_new_ex(libctx
)) == NULL
)
221 if ((tmp
= BN_new()) == NULL
||
222 (tmp2
= BN_new()) == NULL
||
223 (tmp3
= BN_new()) == NULL
||
224 (xtmp
= BN_new()) == NULL
)
227 BN_with_flags(xtmp
, x
, BN_FLG_CONSTTIME
);
228 BN_set_flags(tmp
, BN_FLG_CONSTTIME
);
229 if (!BN_mod_exp(tmp
, g
, xtmp
, N
, bn_ctx
))
231 if ((k
= srp_Calc_k(N
, g
, libctx
, propq
)) == NULL
)
233 if (!BN_mod_mul(tmp2
, tmp
, k
, N
, bn_ctx
))
235 if (!BN_mod_sub(tmp
, B
, tmp2
, N
, bn_ctx
))
237 if (!BN_mul(tmp3
, u
, xtmp
, bn_ctx
))
239 if (!BN_add(tmp2
, a
, tmp3
))
242 if (K
!= NULL
&& !BN_mod_exp(K
, tmp
, tmp2
, N
, bn_ctx
)) {
257 BIGNUM
*SRP_Calc_client_key(const BIGNUM
*N
, const BIGNUM
*B
, const BIGNUM
*g
,
258 const BIGNUM
*x
, const BIGNUM
*a
, const BIGNUM
*u
)
260 return SRP_Calc_client_key_ex(N
, B
, g
, x
, a
, u
, NULL
, NULL
);
263 int SRP_Verify_B_mod_N(const BIGNUM
*B
, const BIGNUM
*N
)
269 if (B
== NULL
|| N
== NULL
|| (bn_ctx
= BN_CTX_new()) == NULL
)
272 if ((r
= BN_new()) == NULL
)
274 /* Checks if B % N == 0 */
275 if (!BN_nnmod(r
, B
, N
, bn_ctx
))
277 ret
= !BN_is_zero(r
);
284 int SRP_Verify_A_mod_N(const BIGNUM
*A
, const BIGNUM
*N
)
286 /* Checks if A % N == 0 */
287 return SRP_Verify_B_mod_N(A
, N
);
290 static SRP_gN knowngN
[] = {
291 {"8192", &bn_generator_19
, &bn_group_8192
},
292 {"6144", &bn_generator_5
, &bn_group_6144
},
293 {"4096", &bn_generator_5
, &bn_group_4096
},
294 {"3072", &bn_generator_5
, &bn_group_3072
},
295 {"2048", &bn_generator_2
, &bn_group_2048
},
296 {"1536", &bn_generator_2
, &bn_group_1536
},
297 {"1024", &bn_generator_2
, &bn_group_1024
},
300 # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
303 * Check if G and N are known parameters. The values have been generated
304 * from the IETF RFC 5054
306 char *SRP_check_known_gN_param(const BIGNUM
*g
, const BIGNUM
*N
)
309 if ((g
== NULL
) || (N
== NULL
))
312 for (i
= 0; i
< KNOWN_GN_NUMBER
; i
++) {
313 if (BN_cmp(knowngN
[i
].g
, g
) == 0 && BN_cmp(knowngN
[i
].N
, N
) == 0)
314 return knowngN
[i
].id
;
319 SRP_gN
*SRP_get_default_gN(const char *id
)
325 for (i
= 0; i
< KNOWN_GN_NUMBER
; i
++) {
326 if (strcmp(knowngN
[i
].id
, id
) == 0)