summaryrefslogtreecommitdiffstats
path: root/3rd_party/libsrp6a-sha512
diff options
context:
space:
mode:
Diffstat (limited to '3rd_party/libsrp6a-sha512')
-rw-r--r--3rd_party/libsrp6a-sha512/LICENSE62
-rw-r--r--3rd_party/libsrp6a-sha512/Makefile.am31
-rw-r--r--3rd_party/libsrp6a-sha512/README.md35
-rw-r--r--3rd_party/libsrp6a-sha512/cstr.c226
-rw-r--r--3rd_party/libsrp6a-sha512/cstr.h94
-rw-r--r--3rd_party/libsrp6a-sha512/srp.c274
-rw-r--r--3rd_party/libsrp6a-sha512/srp.h372
-rw-r--r--3rd_party/libsrp6a-sha512/srp6a_sha512_client.c363
-rw-r--r--3rd_party/libsrp6a-sha512/srp_aux.h146
-rw-r--r--3rd_party/libsrp6a-sha512/t_conv.c239
-rw-r--r--3rd_party/libsrp6a-sha512/t_defines.h137
-rw-r--r--3rd_party/libsrp6a-sha512/t_math.c968
-rw-r--r--3rd_party/libsrp6a-sha512/t_misc.c439
-rw-r--r--3rd_party/libsrp6a-sha512/t_pwd.h246
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.c314
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.h147
-rw-r--r--3rd_party/libsrp6a-sha512/t_truerand.c241
17 files changed, 4334 insertions, 0 deletions
diff --git a/3rd_party/libsrp6a-sha512/LICENSE b/3rd_party/libsrp6a-sha512/LICENSE
new file mode 100644
index 0000000..7f70640
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/LICENSE
@@ -0,0 +1,62 @@
1Licensing
2---------
3
4SRP is royalty-free worldwide for commercial and non-commercial use.
5The SRP library has been carefully written not to depend on any
6encumbered algorithms, and it is distributed under a standard
7BSD-style Open Source license which is shown below. This license
8covers implementations based on the SRP library as well as
9independent implementations based on RFC 2945.
10
11The SRP distribution itself contains algorithms and code from
12various freeware packages; these parts fall under both the SRP
13Open Source license and the packages' own licenses. Care has
14been taken to ensure that these licenses are compatible with
15Open Source distribution, but it is the responsibility of the
16licensee to comply with the terms of these licenses. This
17disclaimer also applies to third-party libraries that may be
18linked into the distribution, since they may contain patented
19intellectual property. The file "Copyrights" contains a list
20of the copyrights incorporated by portions of the software.
21
22Broader use of the SRP authentication technology, such as variants
23incorporating the use of an explicit server secret (SRP-Z), may
24require a license; please contact the Stanford Office of Technology
25Licensing (http://otl.stanford.edu/) for more information about
26terms and conditions.
27
28This software is covered under the following copyright:
29
30/*
31 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
32 * All Rights Reserved.
33 *
34 * Permission is hereby granted, free of charge, to any person obtaining
35 * a copy of this software and associated documentation files (the
36 * "Software"), to deal in the Software without restriction, including
37 * without limitation the rights to use, copy, modify, merge, publish,
38 * distribute, sublicense, and/or sell copies of the Software, and to
39 * permit persons to whom the Software is furnished to do so, subject to
40 * the following conditions:
41 *
42 * The above copyright notice and this permission notice shall be
43 * included in all copies or substantial portions of the Software.
44 *
45 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
46 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
47 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
48 *
49 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
50 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
51 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
52 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
53 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54 *
55 * Redistributions in source or binary form must retain an intact copy
56 * of this copyright notice.
57 */
58
59Address all questions regarding this license to:
60
61 Tom Wu
62 tjw@cs.Stanford.EDU
diff --git a/3rd_party/libsrp6a-sha512/Makefile.am b/3rd_party/libsrp6a-sha512/Makefile.am
new file mode 100644
index 0000000..2acd582
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/Makefile.am
@@ -0,0 +1,31 @@
1AUTOMAKE_OPTIONS = foreign no-dependencies
2
3AM_CPPFLAGS = \
4 -I$(top_srcdir)/include \
5 -I$(top_srcdir) \
6 -Wno-incompatible-pointer-types
7
8AM_CFLAGS = -DHAVE_CONFIG_H
9if HAVE_OPENSSL
10AM_CFLAGS += -DOPENSSL=1 $(openssl_CFLAGS)
11else
12if HAVE_GCRYPT
13AM_CFLAGS += -DGCRYPT=1 $(libgcrypt_CFLAGS)
14else
15if HAVE_MBEDTLS
16AM_CFLAGS += -DMBEDTLS=1 $(mbedtls_CFLAGS)
17endif
18endif
19endif
20
21noinst_LTLIBRARIES = libsrp6a-sha512.la
22
23libsrp6a_sha512_la_SOURCES = \
24 t_conv.c t_math.c t_misc.c \
25 t_truerand.c cstr.c \
26 srp.c srp6a_sha512_client.c \
27 srp.h srp_aux.h cstr.h \
28 t_sha.c
29#if !HAVE_OPENSSL
30#libsrp6a_sha512_la_SOURCES += t_sha.c
31#endif
diff --git a/3rd_party/libsrp6a-sha512/README.md b/3rd_party/libsrp6a-sha512/README.md
new file mode 100644
index 0000000..4affe4a
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/README.md
@@ -0,0 +1,35 @@
1# SRP6a-sha512 library
2
3## About
4
5This library is based on Stanford's Secure Remote Password (SRP) protocol
6implementation, or more precise on the `libsrp` part thereof.
7The entire source code for the SRP project can be obtained from [here](https://github.com/secure-remote-password/stanford-srp).
8
9It has been adapted to the needs of the libimobiledevice project, and
10contains just a part of the original code; it only supports the SRP6a
11client method which has been modified to use SHA512 instead of SHA1.
12The only supported SRP method is `SRP6a_sha512_client_method()`.
13Besides that, support for MbedTLS has been added.
14
15Also, all server-side code has been removed, and the client-side code
16has been reduced to a minimum, so that basically only the following
17functions remain operational:
18
19- `SRP_initialize_library`
20- `SRP_new`
21- `SRP_free`
22- `SRP_set_user_raw`
23- `SRP_set_params`
24- `SRP_set_auth_password`
25- `SRP_gen_pub`
26- `SRP_compute_key`
27- `SRP_respond`
28- `SRP_verify`
29
30Anything else has not been tested and must be considered non-functional.
31
32## License
33
34The license of the original work does still apply and can be found in the
35LICENSE file that comes with the code.
diff --git a/3rd_party/libsrp6a-sha512/cstr.c b/3rd_party/libsrp6a-sha512/cstr.c
new file mode 100644
index 0000000..9856f46
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/cstr.c
@@ -0,0 +1,226 @@
1#include <stdlib.h>
2#include <string.h>
3
4#include "config.h"
5#include "cstr.h"
6
7#define EXPFACTOR 2 /* Minimum expansion factor */
8#define MINSIZE 4 /* Absolute minimum - one word */
9
10static char cstr_empty_string[] = { '\0' };
11static cstr_allocator * default_alloc = NULL;
12
13/*
14 * It is assumed, for efficiency, that it is okay to pass more arguments
15 * to a function than are called for, as long as the required arguments
16 * are in proper form. If extra arguments to malloc() and free() cause
17 * problems, define PEDANTIC_ARGS below.
18 */
19#ifdef PEDANTIC_ARGS
20static void * Cmalloc(int n, void * heap) { return malloc(n); }
21static void Cfree(void * p, void * heap) { free(p); }
22static cstr_allocator malloc_allocator = { Cmalloc, Cfree, NULL };
23#else
24static cstr_allocator malloc_allocator = { malloc, free, NULL };
25#endif
26
27_TYPE( void )
28cstr_set_allocator(cstr_allocator * alloc)
29{
30 default_alloc = alloc;
31}
32
33_TYPE( cstr * )
34cstr_new_alloc(cstr_allocator * alloc)
35{
36 cstr * str;
37
38 if(alloc == NULL) {
39 if(default_alloc == NULL) {
40 default_alloc = &malloc_allocator;
41 }
42 alloc = default_alloc;
43 }
44
45 str = (cstr *) (*alloc->alloc)(sizeof(cstr), alloc->heap);
46 if(str) {
47 str->data = cstr_empty_string;
48 str->length = str->cap = 0;
49 str->ref = 1;
50 str->allocator = alloc;
51 }
52 return str;
53}
54
55_TYPE( cstr * )
56cstr_new()
57{
58 return cstr_new_alloc(NULL);
59}
60
61_TYPE( cstr * )
62cstr_dup_alloc(const cstr * str, cstr_allocator * alloc)
63{
64 cstr * nstr = cstr_new_alloc(alloc);
65 if(nstr)
66 cstr_setn(nstr, str->data, str->length);
67 return nstr;
68}
69
70_TYPE( cstr * )
71cstr_dup(const cstr * str)
72{
73 return cstr_dup_alloc(str, NULL);
74}
75
76_TYPE( cstr * )
77cstr_create(const char * s)
78{
79 return cstr_createn(s, strlen(s));
80}
81
82_TYPE( cstr * )
83cstr_createn(const char * s, int len)
84{
85 cstr * str = cstr_new();
86 if(str) {
87 cstr_setn(str, s, len);
88 }
89 return str;
90}
91
92_TYPE( void )
93cstr_use(cstr * str)
94{
95 ++str->ref;
96}
97
98_TYPE( void )
99cstr_clear_free(cstr * str)
100{
101 if(--str->ref == 0) {
102 if(str->cap > 0) {
103 memset(str->data, 0, str->cap);
104 (*str->allocator->free)(str->data, str->allocator->heap);
105 }
106 (*str->allocator->free)(str, str->allocator->heap);
107 }
108}
109
110_TYPE( void )
111cstr_free(cstr * str)
112{
113 if(--str->ref == 0) {
114 if(str->cap > 0)
115 (*str->allocator->free)(str->data, str->allocator->heap);
116 (*str->allocator->free)(str, str->allocator->heap);
117 }
118}
119
120_TYPE( void )
121cstr_empty(cstr * str)
122{
123 if(str->cap > 0)
124 (*str->allocator->free)(str->data, str->allocator->heap);
125 str->data = cstr_empty_string;
126 str->length = str->cap = 0;
127}
128
129static int
130cstr_alloc(cstr * str, int len)
131{
132 char * t;
133
134 if(len > str->cap) {
135 if(len < EXPFACTOR * str->cap)
136 len = EXPFACTOR * str->cap;
137 if(len < MINSIZE)
138 len = MINSIZE;
139
140 t = (char *) (*str->allocator->alloc)(len * sizeof(char),
141 str->allocator->heap);
142 if(t) {
143 if(str->data) {
144 t[str->length] = 0;
145 if(str->cap > 0) {
146 if(str->length > 0)
147 memcpy(t, str->data, str->length);
148 free(str->data);
149 }
150 }
151 str->data = t;
152 str->cap = len;
153 return 1;
154 }
155 else
156 return -1;
157 }
158 else
159 return 0;
160}
161
162_TYPE( int )
163cstr_copy(cstr * dst, const cstr * src)
164{
165 return cstr_setn(dst, src->data, src->length);
166}
167
168_TYPE( int )
169cstr_set(cstr * str, const char * s)
170{
171 return cstr_setn(str, s, strlen(s));
172}
173
174_TYPE( int )
175cstr_setn(cstr * str, const char * s, int len)
176{
177 if(cstr_alloc(str, len + 1) < 0)
178 return -1;
179 str->data[len] = 0;
180 if(s != NULL && len > 0)
181 memmove(str->data, s, len);
182 str->length = len;
183 return 1;
184}
185
186_TYPE( int )
187cstr_set_length(cstr * str, int len)
188{
189 if(len < str->length) {
190 str->data[len] = 0;
191 str->length = len;
192 return 1;
193 }
194 else if(len > str->length) {
195 if(cstr_alloc(str, len + 1) < 0)
196 return -1;
197 memset(str->data + str->length, 0, len - str->length + 1);
198 str->length = len;
199 return 1;
200 }
201 else
202 return 0;
203}
204
205_TYPE( int )
206cstr_append(cstr * str, const char * s)
207{
208 return cstr_appendn(str, s, strlen(s));
209}
210
211_TYPE( int )
212cstr_appendn(cstr * str, const char * s, int len)
213{
214 if(cstr_alloc(str, str->length + len + 1) < 0)
215 return -1;
216 memcpy(str->data + str->length, s, len);
217 str->length += len;
218 str->data[str->length] = 0;
219 return 1;
220}
221
222_TYPE( int )
223cstr_append_str(cstr * dst, const cstr * src)
224{
225 return cstr_appendn(dst, src->data, src->length);
226}
diff --git a/3rd_party/libsrp6a-sha512/cstr.h b/3rd_party/libsrp6a-sha512/cstr.h
new file mode 100644
index 0000000..7cc019a
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/cstr.h
@@ -0,0 +1,94 @@
1#ifndef _CSTR_H_
2#define _CSTR_H_
3
4/* A general-purpose string "class" for C */
5
6#if !defined(P)
7#ifdef __STDC__
8#define P(x) x
9#else
10#define P(x) ()
11#endif
12#endif
13
14/* For building dynamic link libraries under windows, windows NT
15 * using MSVC1.5 or MSVC2.0
16 */
17
18#ifndef _DLLDECL
19#define _DLLDECL
20
21#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
22#define _MSVC15EXPORT _export
23#define _MSVC20EXPORT
24#define _DLLAPI _export _pascal
25#define _CDECL
26#define _TYPE(a) a _MSVC15EXPORT
27#define DLLEXPORT 1
28
29#elif defined(MSVC20) || (defined(_USRDLL) && defined(SRP_EXPORTS))
30#define _MSVC15EXPORT
31#define _MSVC20EXPORT _declspec(dllexport)
32#define _DLLAPI
33#define _CDECL
34#define _TYPE(a) _MSVC20EXPORT a
35#define DLLEXPORT 1
36
37#else /* Default, non-dll. Use this for Unix or DOS */
38#define _MSVC15DEXPORT
39#define _MSVC20EXPORT
40#define _DLLAPI
41#if defined(WINDOWS) || defined(WIN32)
42#define _CDECL _cdecl
43#else
44#define _CDECL
45#endif
46#define _TYPE(a) a _CDECL
47#endif
48#endif /* _DLLDECL */
49
50#ifdef __cplusplus
51extern "C" {
52#endif /* __cplusplus */
53
54/* Arguments to allocator methods ordered this way for compatibility */
55typedef struct cstr_alloc_st {
56 void * (_CDECL * alloc)(size_t n, void * heap);
57 void (_CDECL * free)(void * p, void * heap);
58 void * heap;
59} cstr_allocator;
60
61typedef struct cstr_st {
62 char * data; /* Okay to access data and length fields directly */
63 int length;
64 int cap;
65 int ref; /* Simple reference counter */
66 cstr_allocator * allocator;
67} cstr;
68
69_TYPE( void ) cstr_set_allocator P((cstr_allocator * alloc));
70
71_TYPE( cstr * ) cstr_new P((void));
72_TYPE( cstr * ) cstr_new_alloc P((cstr_allocator * alloc));
73_TYPE( cstr * ) cstr_dup P((const cstr * str));
74_TYPE( cstr * ) cstr_dup_alloc P((const cstr * str, cstr_allocator * alloc));
75_TYPE( cstr * ) cstr_create P((const char * s));
76_TYPE( cstr * ) cstr_createn P((const char * s, int len));
77
78_TYPE( void ) cstr_free P((cstr * str));
79_TYPE( void ) cstr_clear_free P((cstr * str));
80_TYPE( void ) cstr_use P((cstr * str));
81_TYPE( void ) cstr_empty P((cstr * str));
82_TYPE( int ) cstr_copy P((cstr * dst, const cstr * src));
83_TYPE( int ) cstr_set P((cstr * str, const char * s));
84_TYPE( int ) cstr_setn P((cstr * str, const char * s, int len));
85_TYPE( int ) cstr_set_length P((cstr * str, int len));
86_TYPE( int ) cstr_append P((cstr * str, const char * s));
87_TYPE( int ) cstr_appendn P((cstr * str, const char * s, int len));
88_TYPE( int ) cstr_append_str P((cstr * dst, const cstr * src));
89
90#ifdef __cplusplus
91}
92#endif /* __cplusplus */
93
94#endif /* _CSTR_H_ */
diff --git a/3rd_party/libsrp6a-sha512/srp.c b/3rd_party/libsrp6a-sha512/srp.c
new file mode 100644
index 0000000..74e1f98
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/srp.c
@@ -0,0 +1,274 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#include "t_defines.h"
31#include "srp.h"
32
33static int library_initialized = 0;
34
35_TYPE( SRP_RESULT )
36SRP_initialize_library()
37{
38 if(library_initialized == 0) {
39 BigIntegerInitialize();
40 t_stronginitrand();
41 library_initialized = 1;
42 }
43 return SRP_SUCCESS;
44}
45
46_TYPE( SRP_RESULT )
47SRP_finalize_library()
48{
49 if(library_initialized > 0) {
50 library_initialized = 0;
51 BigIntegerFinalize();
52 }
53 return SRP_SUCCESS;
54}
55
56static int srp_modulus_min_bits = SRP_DEFAULT_MIN_BITS;
57
58_TYPE( SRP_RESULT )
59SRP_set_modulus_min_bits(int minbits)
60{
61 srp_modulus_min_bits = minbits;
62 return SRP_SUCCESS;
63}
64
65_TYPE( int )
66SRP_get_modulus_min_bits()
67{
68 return srp_modulus_min_bits;
69}
70
71static int
72default_secret_bits_cb(int modsize)
73{
74 return 256;
75 /*return modsize;*/ /* Warning: Very Slow */
76}
77
78static SRP_SECRET_BITS_CB srp_sb_cb = default_secret_bits_cb;
79
80_TYPE( SRP_RESULT )
81SRP_set_secret_bits_cb(SRP_SECRET_BITS_CB cb)
82{
83 srp_sb_cb = cb;
84 return SRP_SUCCESS;
85}
86
87_TYPE( int )
88SRP_get_secret_bits(int modsize)
89{
90 return (*srp_sb_cb)(modsize);
91}
92
93_TYPE( SRP * )
94SRP_new(SRP_METHOD * meth)
95{
96 SRP * srp = (SRP *) malloc(sizeof(SRP));
97
98 if(srp == NULL)
99 return NULL;
100
101 srp->flags = 0;
102 srp->username = cstr_new();
103 srp->bctx = BigIntegerCtxNew();
104 srp->modulus = NULL;
105 srp->accel = NULL;
106 srp->generator = NULL;
107 srp->salt = NULL;
108 srp->verifier = NULL;
109 srp->password = NULL;
110 srp->pubkey = NULL;
111 srp->secret = NULL;
112 srp->u = NULL;
113 srp->key = NULL;
114 srp->ex_data = cstr_new();
115 srp->param_cb = NULL;
116 srp->meth = meth;
117 srp->meth_data = NULL;
118 //srp->slu = NULL;
119 if(srp->meth->init == NULL || (*srp->meth->init)(srp) == SRP_SUCCESS)
120 return srp;
121 free(srp);
122 return NULL;
123}
124
125_TYPE( SRP_RESULT )
126SRP_free(SRP * srp)
127{
128 if(srp->meth->finish)
129 (*srp->meth->finish)(srp);
130
131 if(srp->username)
132 cstr_clear_free(srp->username);
133 if(srp->modulus)
134 BigIntegerFree(srp->modulus);
135 if(srp->accel)
136 BigIntegerModAccelFree(srp->accel);
137 if(srp->generator)
138 BigIntegerFree(srp->generator);
139 if(srp->salt)
140 cstr_clear_free(srp->salt);
141 if(srp->verifier)
142 BigIntegerClearFree(srp->verifier);
143 if(srp->password)
144 BigIntegerClearFree(srp->password);
145 if(srp->pubkey)
146 BigIntegerFree(srp->pubkey);
147 if(srp->secret)
148 BigIntegerClearFree(srp->secret);
149 if(srp->u)
150 BigIntegerFree(srp->u);
151 if(srp->key)
152 BigIntegerClearFree(srp->key);
153 if(srp->bctx)
154 BigIntegerCtxFree(srp->bctx);
155 if(srp->ex_data)
156 cstr_clear_free(srp->ex_data);
157 free(srp);
158 return SRP_SUCCESS;
159}
160
161_TYPE( SRP_RESULT )
162SRP_set_client_param_verify_cb(SRP * srp, SRP_CLIENT_PARAM_VERIFY_CB cb)
163{
164 srp->param_cb = cb;
165 return SRP_SUCCESS;
166}
167
168_TYPE( SRP_RESULT )
169SRP_set_username(SRP * srp, const char * username)
170{
171 cstr_set(srp->username, username);
172 return SRP_SUCCESS;
173}
174
175_TYPE( SRP_RESULT )
176SRP_set_user_raw(SRP * srp, const unsigned char * user, int userlen)
177{
178 cstr_setn(srp->username, (const char*)user, userlen);
179 return SRP_SUCCESS;
180}
181
182_TYPE( SRP_RESULT )
183SRP_set_params(SRP * srp, const unsigned char * modulus, int modlen,
184 const unsigned char * generator, int genlen,
185 const unsigned char * salt, int saltlen)
186{
187 SRP_RESULT rc;
188
189 if(modulus == NULL || generator == NULL || salt == NULL)
190 return SRP_ERROR;
191
192 /* Set fields in SRP context */
193 srp->modulus = BigIntegerFromBytes(modulus, modlen);
194 if(srp->flags & SRP_FLAG_MOD_ACCEL)
195 srp->accel = BigIntegerModAccelNew(srp->modulus, srp->bctx);
196 srp->generator = BigIntegerFromBytes(generator, genlen);
197 if(srp->salt == NULL)
198 srp->salt = cstr_new();
199 cstr_setn(srp->salt, (const char*)salt, saltlen);
200
201 /* Now attempt to validate parameters */
202 if(BigIntegerBitLen(srp->modulus) < SRP_get_modulus_min_bits())
203 return SRP_ERROR;
204
205 if(srp->param_cb) {
206 rc = (*srp->param_cb)(srp, modulus, modlen, generator, genlen);
207 if(!SRP_OK(rc))
208 return rc;
209 }
210
211 return (*srp->meth->params)(srp, modulus, modlen, generator, genlen,
212 salt, saltlen);
213}
214
215_TYPE( SRP_RESULT )
216SRP_set_authenticator(SRP * srp, const unsigned char * a, int alen)
217{
218 return (*srp->meth->auth)(srp, a, alen);
219}
220
221_TYPE( SRP_RESULT )
222SRP_set_auth_password(SRP * srp, const char * password)
223{
224 return (*srp->meth->passwd)(srp, (const unsigned char *)password,
225 strlen(password));
226}
227
228_TYPE( SRP_RESULT )
229SRP_set_auth_password_raw(SRP * srp,
230 const unsigned char * password, int passlen)
231{
232 return (*srp->meth->passwd)(srp, password, passlen);
233}
234
235_TYPE( SRP_RESULT )
236SRP_gen_pub(SRP * srp, cstr ** result)
237{
238 return (*srp->meth->genpub)(srp, result);
239}
240
241_TYPE( SRP_RESULT )
242SRP_add_ex_data(SRP * srp, const unsigned char * data, int datalen)
243{
244 cstr_appendn(srp->ex_data, (const char*)data, datalen);
245 return SRP_SUCCESS;
246}
247
248_TYPE( SRP_RESULT )
249SRP_compute_key(SRP * srp, cstr ** result,
250 const unsigned char * pubkey, int pubkeylen)
251{
252 return (*srp->meth->key)(srp, result, pubkey, pubkeylen);
253}
254
255_TYPE( SRP_RESULT )
256SRP_verify(SRP * srp, const unsigned char * proof, int prooflen)
257{
258 return (*srp->meth->verify)(srp, proof, prooflen);
259}
260
261_TYPE( SRP_RESULT )
262SRP_respond(SRP * srp, cstr ** proof)
263{
264 return (*srp->meth->respond)(srp, proof);
265}
266
267_TYPE( SRP_RESULT )
268SRP_use_engine(const char * engine)
269{
270 if(BigIntegerOK(BigIntegerUseEngine(engine)))
271 return SRP_SUCCESS;
272 else
273 return SRP_ERROR;
274}
diff --git a/3rd_party/libsrp6a-sha512/srp.h b/3rd_party/libsrp6a-sha512/srp.h
new file mode 100644
index 0000000..b1d46af
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/srp.h
@@ -0,0 +1,372 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29#ifndef _SRP_H_
30#define _SRP_H_
31
32#include "cstr.h"
33#include "srp_aux.h"
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/* SRP library version identification */
40#define SRP_VERSION_MAJOR 2
41#define SRP_VERSION_MINOR 0
42#define SRP_VERSION_PATCHLEVEL 1
43
44typedef int SRP_RESULT;
45/* Returned codes for SRP API functions */
46#define SRP_OK(v) ((v) == SRP_SUCCESS)
47#define SRP_SUCCESS 0
48#define SRP_ERROR -1
49
50/* Set the minimum number of bits acceptable in an SRP modulus */
51#define SRP_DEFAULT_MIN_BITS 512
52_TYPE( SRP_RESULT ) SRP_set_modulus_min_bits P((int minbits));
53_TYPE( int ) SRP_get_modulus_min_bits P((void));
54
55/*
56 * Sets the "secret size callback" function.
57 * This function is called with the modulus size in bits,
58 * and returns the size of the secret exponent in bits.
59 * The default function always returns 256 bits.
60 */
61typedef int (_CDECL * SRP_SECRET_BITS_CB)(int modsize);
62_TYPE( SRP_RESULT ) SRP_set_secret_bits_cb P((SRP_SECRET_BITS_CB cb));
63_TYPE( int ) SRP_get_secret_bits P((int modsize));
64
65typedef struct srp_st SRP;
66
67#if 0
68/* Server Lookup API */
69typedef struct srp_server_lu_st SRP_SERVER_LOOKUP;
70
71typedef struct srp_s_lu_meth_st {
72 const char * name;
73
74 SRP_RESULT (_CDECL * init)(SRP_SERVER_LOOKUP * slu);
75 SRP_RESULT (_CDECL * finish)(SRP_SERVER_LOOKUP * slu);
76
77 SRP_RESULT (_CDECL * lookup)(SRP_SERVER_LOOKUP * slu, SRP * srp, cstr * username);
78
79 void * meth_data;
80} SRP_SERVER_LOOKUP_METHOD;
81
82struct srp_server_lu_st {
83 SRP_SERVER_LOOKUP_METHOD * meth;
84 void * data;
85};
86
87/*
88 * The Server Lookup API deals with the server-side issue of
89 * mapping usernames to verifiers. Given a username, a lookup
90 * mechanism needs to provide parameters (N, g), salt (s), and
91 * password verifier (v) for that user.
92 *
93 * A SRP_SERVER_LOOKUP_METHOD describes the general mechanism
94 * for performing lookups (e.g. files, LDAP, database, etc.)
95 * A SRP_SERVER_LOOKUP is an active "object" that is actually
96 * called to do lookups.
97 */
98_TYPE( SRP_SERVER_LOOKUP * )
99 SRP_SERVER_LOOKUP_new P((SRP_SERVER_LOOKUP_METHOD * meth));
100_TYPE( SRP_RESULT ) SRP_SERVER_LOOKUP_free P((SRP_SERVER_LOOKUP * slu));
101_TYPE( SRP_RESULT ) SRP_SERVER_do_lookup P((SRP_SERVER_LOOKUP * slu,
102 SRP * srp, cstr * username));
103
104/*
105 * SRP_SERVER_system_lookup supercedes SRP_server_init_user.
106 */
107_TYPE( SRP_SERVER_LOOKUP * ) SRP_SERVER_system_lookup P((void));
108#endif
109
110/*
111 * Client Parameter Verification API
112 *
113 * This callback is called from the SRP client when the
114 * parameters (modulus and generator) are set. The callback
115 * should return SRP_SUCCESS if the parameters are okay,
116 * otherwise some error code to indicate that the parameters
117 * should be rejected.
118 */
119typedef SRP_RESULT (_CDECL * SRP_CLIENT_PARAM_VERIFY_CB)(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
120
121#if 0
122/* The default parameter verifier function */
123_TYPE( SRP_RESULT ) SRP_CLIENT_default_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
124/* A parameter verifier that only accepts builtin params (no prime test) */
125_TYPE( SRP_RESULT ) SRP_CLIENT_builtin_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
126/* The "classic" parameter verifier that accepts either builtin params
127 * immediately, and performs safe-prime tests on N and primitive-root
128 * tests on g otherwise. SECURITY WARNING: This may allow for certain
129 * attacks based on "trapdoor" moduli, so this is not recommended. */
130_TYPE( SRP_RESULT ) SRP_CLIENT_compat_param_verify_cb(SRP * srp, const unsigned char * mod, int modlen, const unsigned char * gen, int genlen);
131
132#endif
133
134/*
135 * Main SRP API - SRP and SRP_METHOD
136 */
137
138/* SRP method definitions */
139typedef struct srp_meth_st {
140 const char * name;
141
142 SRP_RESULT (_CDECL * init)(SRP * srp);
143 SRP_RESULT (_CDECL * finish)(SRP * srp);
144
145 SRP_RESULT (_CDECL * params)(SRP * srp,
146 const unsigned char * modulus, int modlen,
147 const unsigned char * generator, int genlen,
148 const unsigned char * salt, int saltlen);
149 SRP_RESULT (_CDECL * auth)(SRP * srp, const unsigned char * a, int alen);
150 SRP_RESULT (_CDECL * passwd)(SRP * srp,
151 const unsigned char * pass, int passlen);
152 SRP_RESULT (_CDECL * genpub)(SRP * srp, cstr ** result);
153 SRP_RESULT (_CDECL * key)(SRP * srp, cstr ** result,
154 const unsigned char * pubkey, int pubkeylen);
155 SRP_RESULT (_CDECL * verify)(SRP * srp,
156 const unsigned char * proof, int prooflen);
157 SRP_RESULT (_CDECL * respond)(SRP * srp, cstr ** proof);
158
159 void * data;
160} SRP_METHOD;
161
162/* Magic numbers for the SRP context header */
163#define SRP_MAGIC_CLIENT 12
164#define SRP_MAGIC_SERVER 28
165
166/* Flag bits for SRP struct */
167#define SRP_FLAG_MOD_ACCEL 0x1 /* accelerate modexp operations */
168#define SRP_FLAG_LEFT_PAD 0x2 /* left-pad to length-of-N inside hashes */
169
170/*
171 * A hybrid structure that represents either client or server state.
172 */
173struct srp_st {
174 int magic; /* To distinguish client from server (and for sanity) */
175
176 int flags;
177
178 cstr * username;
179
180 BigInteger modulus;
181 BigInteger generator;
182 cstr * salt;
183
184 BigInteger verifier;
185 BigInteger password;
186
187 BigInteger pubkey;
188 BigInteger secret;
189 BigInteger u;
190
191 BigInteger key;
192
193 cstr * ex_data;
194
195 SRP_METHOD * meth;
196 void * meth_data;
197
198 BigIntegerCtx bctx; /* to cache temporaries if available */
199 BigIntegerModAccel accel; /* to accelerate modexp if available */
200
201 SRP_CLIENT_PARAM_VERIFY_CB param_cb; /* to verify params */
202 //SRP_SERVER_LOOKUP * slu; /* to look up users */
203};
204
205/*
206 * Global initialization/de-initialization functions.
207 * Call SRP_initialize_library before using the library,
208 * and SRP_finalize_library when done.
209 */
210_TYPE( SRP_RESULT ) SRP_initialize_library();
211_TYPE( SRP_RESULT ) SRP_finalize_library();
212
213/*
214 * SRP_new() creates a new SRP context object -
215 * the method determines which "sense" (client or server)
216 * the object operates in. SRP_free() frees it.
217 * (See RFC2945 method definitions below.)
218 */
219_TYPE( SRP * ) SRP_new P((SRP_METHOD * meth));
220_TYPE( SRP_RESULT ) SRP_free P((SRP * srp));
221
222#if 0
223/*
224 * Use the supplied lookup object to look up user parameters and
225 * password verifier. The lookup function gets called during
226 * SRP_set_username/SRP_set_user_raw below. Using this function
227 * means that the server can avoid calling SRP_set_params and
228 * SRP_set_authenticator, since the lookup function handles that
229 * internally.
230 */
231_TYPE( SRP_RESULT ) SRP_set_server_lookup P((SRP * srp,
232 SRP_SERVER_LOOKUP * lookup));
233#endif
234
235/*
236 * Use the supplied callback function to verify parameters
237 * (modulus, generator) given to the client.
238 */
239_TYPE( SRP_RESULT )
240 SRP_set_client_param_verify_cb P((SRP * srp,
241 SRP_CLIENT_PARAM_VERIFY_CB cb));
242
243/*
244 * Both client and server must call both SRP_set_username and
245 * SRP_set_params, in that order, before calling anything else.
246 * SRP_set_user_raw is an alternative to SRP_set_username that
247 * accepts an arbitrary length-bounded octet string as input.
248 */
249_TYPE( SRP_RESULT ) SRP_set_username P((SRP * srp, const char * username));
250_TYPE( SRP_RESULT ) SRP_set_user_raw P((SRP * srp, const unsigned char * user,
251 int userlen));
252_TYPE( SRP_RESULT )
253 SRP_set_params P((SRP * srp,
254 const unsigned char * modulus, int modlen,
255 const unsigned char * generator, int genlen,
256 const unsigned char * salt, int saltlen));
257
258/*
259 * On the client, SRP_set_authenticator, SRP_gen_exp, and
260 * SRP_add_ex_data can be called in any order.
261 * On the server, SRP_set_authenticator must come first,
262 * followed by SRP_gen_exp and SRP_add_ex_data in either order.
263 */
264/*
265 * The authenticator is the secret possessed by either side.
266 * For the server, this is the bigendian verifier, as an octet string.
267 * For the client, this is the bigendian raw secret, as an octet string.
268 * The server's authenticator must be the generator raised to the power
269 * of the client's raw secret modulo the common modulus for authentication
270 * to succeed.
271 *
272 * SRP_set_auth_password computes the authenticator from a plaintext
273 * password and then calls SRP_set_authenticator automatically. This is
274 * usually used on the client side, while the server usually uses
275 * SRP_set_authenticator (since it doesn't know the plaintext password).
276 */
277_TYPE( SRP_RESULT )
278 SRP_set_authenticator P((SRP * srp, const unsigned char * a, int alen));
279_TYPE( SRP_RESULT )
280 SRP_set_auth_password P((SRP * srp, const char * password));
281_TYPE( SRP_RESULT )
282 SRP_set_auth_password_raw P((SRP * srp,
283 const unsigned char * password,
284 int passlen));
285
286/*
287 * SRP_gen_pub generates the random exponential residue to send
288 * to the other side. If using SRP-3/RFC2945, the server must
289 * withhold its result until it receives the client's number.
290 * If using SRP-6, the server can send its value immediately
291 * without waiting for the client.
292 *
293 * If "result" points to a NULL pointer, a new cstr object will be
294 * created to hold the result, and "result" will point to it.
295 * If "result" points to a non-NULL cstr pointer, the result will be
296 * placed there.
297 * If "result" itself is NULL, no result will be returned,
298 * although the big integer value will still be available
299 * through srp->pubkey in the SRP struct.
300 */
301_TYPE( SRP_RESULT ) SRP_gen_pub P((SRP * srp, cstr ** result));
302/*
303 * Append the data to the extra data segment. Authentication will
304 * not succeed unless both sides add precisely the same data in
305 * the same order.
306 */
307_TYPE( SRP_RESULT ) SRP_add_ex_data P((SRP * srp, const unsigned char * data,
308 int datalen));
309
310/*
311 * SRP_compute_key must be called after the previous three methods.
312 */
313_TYPE( SRP_RESULT ) SRP_compute_key P((SRP * srp, cstr ** result,
314 const unsigned char * pubkey,
315 int pubkeylen));
316
317/*
318 * On the client, call SRP_respond first to get the response to send
319 * to the server, and call SRP_verify to verify the server's response.
320 * On the server, call SRP_verify first to verify the client's response,
321 * and call SRP_respond ONLY if verification succeeds.
322 *
323 * It is an error to call SRP_respond with a NULL pointer.
324 */
325_TYPE( SRP_RESULT ) SRP_verify P((SRP * srp,
326 const unsigned char * proof, int prooflen));
327_TYPE( SRP_RESULT ) SRP_respond P((SRP * srp, cstr ** response));
328
329/* RFC2945-style SRP authentication */
330
331#define RFC2945_KEY_LEN 40 /* length of session key (bytes) */
332#define RFC2945_RESP_LEN 20 /* length of proof hashes (bytes) */
333
334/*
335 * RFC2945-style SRP authentication methods. Use these like:
336 * SRP * srp = SRP_new(SRP_RFC2945_client_method());
337 */
338_TYPE( SRP_METHOD * ) SRP_RFC2945_client_method P((void));
339_TYPE( SRP_METHOD * ) SRP_RFC2945_server_method P((void));
340
341/*
342 * SRP-6 and SRP-6a authentication methods.
343 * SRP-6a is recommended for better resistance to 2-for-1 attacks.
344 */
345_TYPE( SRP_METHOD * ) SRP6_client_method P((void));
346_TYPE( SRP_METHOD * ) SRP6_server_method P((void));
347_TYPE( SRP_METHOD * ) SRP6a_client_method P((void));
348_TYPE( SRP_METHOD * ) SRP6a_server_method P((void));
349
350_TYPE( SRP_METHOD * ) SRP6a_sha512_client_method P((void));
351
352/*
353 * Convenience function - SRP_server_init_user
354 * Looks up the username from the system EPS configuration and calls
355 * SRP_set_username, SRP_set_params, and SRP_set_authenticator to
356 * initialize server state for that user.
357 *
358 * This is deprecated in favor of SRP_SERVER_system_lookup() and
359 * the Server Lookup API.
360 */
361_TYPE( SRP_RESULT ) SRP_server_init_user P((SRP * srp, const char * username));
362
363/*
364 * Use the named engine for acceleration.
365 */
366_TYPE( SRP_RESULT ) SRP_use_engine P((const char * engine));
367
368#ifdef __cplusplus
369}
370#endif
371
372#endif /* _SRP_H_ */
diff --git a/3rd_party/libsrp6a-sha512/srp6a_sha512_client.c b/3rd_party/libsrp6a-sha512/srp6a_sha512_client.c
new file mode 100644
index 0000000..db59fe8
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/srp6a_sha512_client.c
@@ -0,0 +1,363 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29#include "t_defines.h"
30#include "srp.h"
31#include "t_sha.h"
32
33/*
34 * SRP-6/6a has two minor refinements relative to SRP-3/RFC2945:
35 * 1. The "g^x" value is multipled by three in the client's
36 * calculation of its session key.
37 * SRP-6a: The "g^x" value is multiplied by the hash of
38 * N and g in the client's session key calculation.
39 * 2. The value of u is taken as the hash of A and B,
40 * instead of the top 32 bits of the hash of B.
41 * This eliminates the old restriction where the
42 * server had to receive A before it could send B.
43 */
44
45/****************************/
46#define SHA512_DIGESTSIZE 64
47#define SRP6_SHA512_KEY_LEN 64
48
49/*
50 * The client keeps track of the running hash
51 * state via SHA512_CTX structures pointed to by the
52 * meth_data pointer. The "hash" member is the hash value that
53 * will be sent to the other side; the "ckhash" member is the
54 * hash value expected from the other side.
55 */
56struct sha512_client_meth_st {
57 SHA512_CTX hash;
58 SHA512_CTX ckhash;
59 unsigned char k[SRP6_SHA512_KEY_LEN];
60};
61
62#define SHA512_CLIENT_CTXP(srp) ((struct sha512_client_meth_st *)(srp)->meth_data)
63
64static SRP_RESULT
65srp6a_sha512_client_init(SRP * srp)
66{
67 srp->magic = SRP_MAGIC_CLIENT;
68 srp->flags = SRP_FLAG_MOD_ACCEL | SRP_FLAG_LEFT_PAD;
69 srp->meth_data = malloc(sizeof(struct sha512_client_meth_st));
70 SHA512Init(&SHA512_CLIENT_CTXP(srp)->hash);
71 SHA512Init(&SHA512_CLIENT_CTXP(srp)->ckhash);
72 return SRP_SUCCESS;
73}
74
75static SRP_RESULT
76srp6_sha512_client_finish(SRP * srp)
77{
78 if(srp->meth_data) {
79 memset(srp->meth_data, 0, sizeof(struct sha512_client_meth_st));
80 free(srp->meth_data);
81 }
82 return SRP_SUCCESS;
83}
84
85static SRP_RESULT
86srp6_sha512_client_params(SRP * srp, const unsigned char * modulus, int modlen,
87 const unsigned char * generator, int genlen,
88 const unsigned char * salt, int saltlen)
89{
90 int i;
91 unsigned char buf1[SHA512_DIGESTSIZE], buf2[SHA512_DIGESTSIZE];
92 SHA512_CTX ctxt;
93
94 /* Fields set by SRP_set_params */
95
96 /* Update hash state */
97 SHA512Init(&ctxt);
98 SHA512Update(&ctxt, modulus, modlen);
99 SHA512Final(buf1, &ctxt); /* buf1 = H(modulus) */
100
101 SHA512Init(&ctxt);
102 SHA512Update(&ctxt, generator, genlen);
103 SHA512Final(buf2, &ctxt); /* buf2 = H(generator) */
104
105 for(i = 0; i < sizeof(buf1); ++i)
106 buf1[i] ^= buf2[i]; /* buf1 = H(modulus) xor H(generator) */
107
108 /* hash: H(N) xor H(g) */
109 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, buf1, sizeof(buf1));
110
111 SHA512Init(&ctxt);
112 SHA512Update(&ctxt, srp->username->data, srp->username->length);
113 SHA512Final(buf1, &ctxt); /* buf1 = H(user) */
114
115 /* hash: (H(N) xor H(g)) | H(U) */
116 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, buf1, sizeof(buf1));
117
118 /* hash: (H(N) xor H(g)) | H(U) | s */
119 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, salt, saltlen);
120
121 return SRP_SUCCESS;
122}
123
124static SRP_RESULT
125srp6_sha512_client_auth(SRP * srp, const unsigned char * a, int alen)
126{
127 /* On the client, the authenticator is the raw password-derived hash */
128 srp->password = BigIntegerFromBytes(a, alen);
129
130 /* verifier = g^x mod N */
131 srp->verifier = BigIntegerFromInt(0);
132 BigIntegerModExp(srp->verifier, srp->generator, srp->password, srp->modulus, srp->bctx, srp->accel);
133
134 return SRP_SUCCESS;
135}
136
137static SRP_RESULT
138srp6_sha512_client_passwd(SRP * srp, const unsigned char * p, int plen)
139{
140 SHA512_CTX ctxt;
141 unsigned char dig[SHA512_DIGESTSIZE];
142 int r;
143
144 SHA512Init(&ctxt);
145 SHA512Update(&ctxt, srp->username->data, srp->username->length);
146 SHA512Update(&ctxt, ":", 1);
147 SHA512Update(&ctxt, p, plen);
148 SHA512Final(dig, &ctxt); /* dig = H(U | ":" | P) */
149
150 SHA512Init(&ctxt);
151 SHA512Update(&ctxt, srp->salt->data, srp->salt->length);
152 SHA512Update(&ctxt, dig, sizeof(dig));
153 SHA512Final(dig, &ctxt); /* dig = H(s | H(U | ":" | P)) */
154 memset(&ctxt, 0, sizeof(ctxt));
155
156 r = SRP_set_authenticator(srp, dig, sizeof(dig));
157 memset(dig, 0, sizeof(dig));
158
159 return r;
160}
161
162static SRP_RESULT
163srp6_sha512_client_genpub(SRP * srp, cstr ** result)
164{
165 cstr * astr;
166 int slen = (SRP_get_secret_bits(BigIntegerBitLen(srp->modulus)) + 7) / 8;
167
168 if(result == NULL)
169 astr = cstr_new();
170 else {
171 if(*result == NULL)
172 *result = cstr_new();
173 astr = *result;
174 }
175
176 cstr_set_length(astr, BigIntegerByteLen(srp->modulus));
177 t_random((unsigned char*)astr->data, slen);
178 srp->secret = BigIntegerFromBytes((const unsigned char*)astr->data, slen);
179 /* Force g^a mod n to "wrap around" by adding log[2](n) to "a". */
180 BigIntegerAddInt(srp->secret, srp->secret, BigIntegerBitLen(srp->modulus));
181 /* A = g^a mod n */
182 srp->pubkey = BigIntegerFromInt(0);
183 BigIntegerModExp(srp->pubkey, srp->generator, srp->secret, srp->modulus, srp->bctx, srp->accel);
184 BigIntegerToCstr(srp->pubkey, astr);
185
186 /* hash: (H(N) xor H(g)) | H(U) | s | A */
187 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, astr->data, astr->length);
188 /* ckhash: A */
189 SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, astr->data, astr->length);
190
191 if(result == NULL) /* astr was a temporary */
192 cstr_clear_free(astr);
193
194 return SRP_SUCCESS;
195}
196
197static SRP_RESULT
198srp6_sha512_client_key_ex(SRP * srp, cstr ** result,
199 const unsigned char * pubkey, int pubkeylen, BigInteger k)
200{
201 SHA512_CTX ctxt;
202 unsigned char dig[SHA512_DIGESTSIZE];
203 BigInteger gb, e;
204 cstr * s;
205 int modlen;
206
207 modlen = BigIntegerByteLen(srp->modulus);
208 if(pubkeylen > modlen)
209 return SRP_ERROR;
210
211 /* Compute u from client's and server's values */
212 SHA512Init(&ctxt);
213 /* Use s as a temporary to store client's value */
214 s = cstr_new();
215 if(srp->flags & SRP_FLAG_LEFT_PAD) {
216 BigIntegerToCstrEx(srp->pubkey, s, modlen);
217 SHA512Update(&ctxt, s->data, s->length);
218 if(pubkeylen < modlen) {
219 memcpy(s->data + (modlen - pubkeylen), pubkey, pubkeylen);
220 memset(s->data, 0, modlen - pubkeylen);
221 SHA512Update(&ctxt, s->data, modlen);
222 }
223 else
224 SHA512Update(&ctxt, pubkey, pubkeylen);
225 }
226 else {
227 BigIntegerToCstr(srp->pubkey, s);
228 SHA512Update(&ctxt, s->data, s->length);
229 SHA512Update(&ctxt, pubkey, pubkeylen);
230 }
231 SHA512Final(dig, &ctxt);
232 srp->u = BigIntegerFromBytes(dig, SHA512_DIGESTSIZE);
233
234 /* hash: (H(N) xor H(g)) | H(U) | s | A | B */
235 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, pubkey, pubkeylen);
236
237 gb = BigIntegerFromBytes(pubkey, pubkeylen);
238 /* reject B == 0, B >= modulus */
239 if(BigIntegerCmp(gb, srp->modulus) >= 0 || BigIntegerCmpInt(gb, 0) == 0) {
240 BigIntegerFree(gb);
241 cstr_clear_free(s);
242 return SRP_ERROR;
243 }
244 e = BigIntegerFromInt(0);
245 srp->key = BigIntegerFromInt(0);
246 /* unblind g^b (mod N) */
247 BigIntegerSub(srp->key, srp->modulus, srp->verifier);
248 /* use e as temporary, e == -k*v (mod N) */
249 BigIntegerMul(e, k, srp->key, srp->bctx);
250 BigIntegerAdd(e, e, gb);
251 BigIntegerMod(gb, e, srp->modulus, srp->bctx);
252
253 /* compute gb^(a + ux) (mod N) */
254 BigIntegerMul(e, srp->password, srp->u, srp->bctx);
255 BigIntegerAdd(e, e, srp->secret); /* e = a + ux */
256
257 BigIntegerModExp(srp->key, gb, e, srp->modulus, srp->bctx, srp->accel);
258 BigIntegerClearFree(e);
259 BigIntegerClearFree(gb);
260
261 /* convert srp->key into a session key, update hash states */
262 BigIntegerToCstr(srp->key, s);
263 SHA512Init(&ctxt);
264 SHA512Update(&ctxt, s->data, s->length);
265 SHA512Final((unsigned char*)&SHA512_CLIENT_CTXP(srp)->k, &ctxt);
266 cstr_clear_free(s);
267
268 /* hash: (H(N) xor H(g)) | H(U) | s | A | B | K */
269 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash, SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
270 /* hash: (H(N) xor H(g)) | H(U) | s | A | B | K | ex_data */
271 if(srp->ex_data->length > 0)
272 SHA512Update(&SHA512_CLIENT_CTXP(srp)->hash,
273 srp->ex_data->data, srp->ex_data->length);
274 if(result) {
275 if(*result == NULL)
276 *result = cstr_new();
277 cstr_setn(*result, (const char*)SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
278 }
279
280 return SRP_SUCCESS;
281}
282
283static SRP_RESULT
284srp6a_sha512_client_key(SRP * srp, cstr ** result,
285 const unsigned char * pubkey, int pubkeylen)
286{
287 SRP_RESULT ret;
288 BigInteger k;
289 cstr * s;
290 SHA512_CTX ctxt;
291 unsigned char dig[SHA512_DIGESTSIZE];
292
293 SHA512Init(&ctxt);
294 s = cstr_new();
295 BigIntegerToCstr(srp->modulus, s);
296 SHA512Update(&ctxt, s->data, s->length);
297 if(srp->flags & SRP_FLAG_LEFT_PAD)
298 BigIntegerToCstrEx(srp->generator, s, s->length);
299 else
300 BigIntegerToCstr(srp->generator, s);
301 SHA512Update(&ctxt, s->data, s->length);
302 SHA512Final(dig, &ctxt);
303 cstr_free(s);
304
305 k = BigIntegerFromBytes(dig, SHA512_DIGESTSIZE);
306 if(BigIntegerCmpInt(k, 0) == 0)
307 ret = SRP_ERROR;
308 else
309 ret = srp6_sha512_client_key_ex(srp, result, pubkey, pubkeylen, k);
310 BigIntegerClearFree(k);
311 return ret;
312}
313
314static SRP_RESULT
315srp6_sha512_client_verify(SRP * srp, const unsigned char * proof, int prooflen)
316{
317 unsigned char expected[SHA512_DIGESTSIZE];
318
319 SHA512Final(expected, &SHA512_CLIENT_CTXP(srp)->ckhash);
320 if(prooflen == SHA512_DIGESTSIZE && memcmp(expected, proof, prooflen) == 0)
321 return SRP_SUCCESS;
322 else
323 return SRP_ERROR;
324}
325
326static SRP_RESULT
327srp6_sha512_client_respond(SRP * srp, cstr ** proof)
328{
329 if(proof == NULL)
330 return SRP_ERROR;
331
332 if(*proof == NULL)
333 *proof = cstr_new();
334
335 /* proof contains client's response */
336 cstr_set_length(*proof, SHA512_DIGESTSIZE);
337 SHA512Final((unsigned char*)(*proof)->data, &SHA512_CLIENT_CTXP(srp)->hash);
338
339 /* ckhash: A | M | K */
340 SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, (*proof)->data, (*proof)->length);
341 SHA512Update(&SHA512_CLIENT_CTXP(srp)->ckhash, SHA512_CLIENT_CTXP(srp)->k, SRP6_SHA512_KEY_LEN);
342 return SRP_SUCCESS;
343}
344
345static SRP_METHOD srp6a_sha512_client_meth = {
346 "SRP-6a sha512 client (tjw)",
347 srp6a_sha512_client_init,
348 srp6_sha512_client_finish,
349 srp6_sha512_client_params,
350 srp6_sha512_client_auth,
351 srp6_sha512_client_passwd,
352 srp6_sha512_client_genpub,
353 srp6a_sha512_client_key,
354 srp6_sha512_client_verify,
355 srp6_sha512_client_respond,
356 NULL
357};
358
359_TYPE( SRP_METHOD * )
360SRP6a_sha512_client_method()
361{
362 return &srp6a_sha512_client_meth;
363}
diff --git a/3rd_party/libsrp6a-sha512/srp_aux.h b/3rd_party/libsrp6a-sha512/srp_aux.h
new file mode 100644
index 0000000..5088f08
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/srp_aux.h
@@ -0,0 +1,146 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#ifndef SRP_AUX_H
31#define SRP_AUX_H
32
33#include "cstr.h"
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/* BigInteger abstraction API */
40
41#ifndef MATH_PRIV
42typedef void * BigInteger;
43typedef void * BigIntegerCtx;
44typedef void * BigIntegerModAccel;
45#endif
46
47/*
48 * Some functions return a BigIntegerResult.
49 * Use BigIntegerOK to test for success.
50 */
51#define BIG_INTEGER_SUCCESS 0
52#define BIG_INTEGER_ERROR -1
53#define BigIntegerOK(v) ((v) == BIG_INTEGER_SUCCESS)
54typedef int BigIntegerResult;
55
56_TYPE( BigInteger ) BigIntegerFromInt P((unsigned int number));
57_TYPE( BigInteger ) BigIntegerFromBytes P((const unsigned char * bytes,
58 int length));
59#define BigIntegerByteLen(X) ((BigIntegerBitLen(X)+7)/8)
60_TYPE( int ) BigIntegerToBytes P((BigInteger src,
61 unsigned char * dest, int destlen));
62_TYPE( BigIntegerResult ) BigIntegerToCstr P((BigInteger src, cstr * dest));
63_TYPE( BigIntegerResult ) BigIntegerToCstrEx P((BigInteger src, cstr * dest, int len));
64_TYPE( BigIntegerResult ) BigIntegerToHex P((BigInteger src,
65 char * dest, int destlen));
66_TYPE( BigIntegerResult ) BigIntegerToString P((BigInteger src,
67 char * dest, int destlen,
68 unsigned int radix));
69_TYPE( int ) BigIntegerBitLen P((BigInteger b));
70_TYPE( int ) BigIntegerCmp P((BigInteger c1, BigInteger c2));
71_TYPE( int ) BigIntegerCmpInt P((BigInteger c1, unsigned int c2));
72_TYPE( BigIntegerResult ) BigIntegerLShift P((BigInteger result, BigInteger x,
73 unsigned int bits));
74_TYPE( BigIntegerResult ) BigIntegerAdd P((BigInteger result,
75 BigInteger a1, BigInteger a2));
76_TYPE( BigIntegerResult ) BigIntegerAddInt P((BigInteger result,
77 BigInteger a1, unsigned int a2));
78_TYPE( BigIntegerResult ) BigIntegerSub P((BigInteger result,
79 BigInteger s1, BigInteger s2));
80_TYPE( BigIntegerResult ) BigIntegerSubInt P((BigInteger result,
81 BigInteger s1, unsigned int s2));
82/* For BigIntegerMul{,Int}: result != m1, m2 */
83_TYPE( BigIntegerResult ) BigIntegerMul P((BigInteger result, BigInteger m1,
84 BigInteger m2, BigIntegerCtx ctx));
85_TYPE( BigIntegerResult ) BigIntegerMulInt P((BigInteger result,
86 BigInteger m1, unsigned int m2,
87 BigIntegerCtx ctx));
88_TYPE( BigIntegerResult ) BigIntegerDivInt P((BigInteger result,
89 BigInteger d, unsigned int m,
90 BigIntegerCtx ctx));
91_TYPE( BigIntegerResult ) BigIntegerMod P((BigInteger result, BigInteger d,
92 BigInteger m, BigIntegerCtx ctx));
93_TYPE( unsigned int ) BigIntegerModInt P((BigInteger d, unsigned int m,
94 BigIntegerCtx ctx));
95_TYPE( BigIntegerResult ) BigIntegerModMul P((BigInteger result,
96 BigInteger m1, BigInteger m2,
97 BigInteger m, BigIntegerCtx ctx));
98_TYPE( BigIntegerResult ) BigIntegerModExp P((BigInteger result,
99 BigInteger base, BigInteger expt,
100 BigInteger modulus,
101 BigIntegerCtx ctx,
102 BigIntegerModAccel accel));
103_TYPE( int ) BigIntegerCheckPrime P((BigInteger n, BigIntegerCtx ctx));
104
105_TYPE( BigIntegerResult ) BigIntegerFree P((BigInteger b));
106_TYPE( BigIntegerResult ) BigIntegerClearFree P((BigInteger b));
107
108_TYPE( BigIntegerCtx ) BigIntegerCtxNew();
109_TYPE( BigIntegerResult ) BigIntegerCtxFree P((BigIntegerCtx ctx));
110
111_TYPE( BigIntegerModAccel ) BigIntegerModAccelNew P((BigInteger m,
112 BigIntegerCtx ctx));
113_TYPE( BigIntegerResult ) BigIntegerModAccelFree P((BigIntegerModAccel accel));
114
115_TYPE( BigIntegerResult ) BigIntegerInitialize();
116_TYPE( BigIntegerResult ) BigIntegerFinalize();
117
118_TYPE( BigIntegerResult ) BigIntegerUseEngine P((const char * engine));
119_TYPE( BigIntegerResult ) BigIntegerReleaseEngine();
120
121/* Miscellaneous functions - formerly in t_pwd.h */
122
123/*
124 * "t_random" is a cryptographic random number generator, which is seeded
125 * from various high-entropy sources and uses a one-way hash function
126 * in a feedback configuration.
127 * "t_sessionkey" is the interleaved hash used to generate session keys
128 * from a large integer.
129 * "t_mgf1" is an implementation of MGF1 using SHA1 to generate session
130 * keys from large integers, and is preferred over the older
131 * interleaved hash, and is used with SRP6.
132 * "t_getpass" reads a password from the terminal without echoing.
133 */
134_TYPE( void ) t_random P((unsigned char *, unsigned));
135_TYPE( void ) t_stronginitrand();
136_TYPE( unsigned char * )
137 t_sessionkey P((unsigned char *, unsigned char *, unsigned));
138_TYPE( void ) t_mgf1 P((unsigned char *, unsigned,
139 const unsigned char *, unsigned));
140_TYPE( int ) t_getpass P((char *, unsigned, const char *));
141
142#ifdef __cplusplus
143}
144#endif
145
146#endif /* SRP_AUX_H */
diff --git a/3rd_party/libsrp6a-sha512/t_conv.c b/3rd_party/libsrp6a-sha512/t_conv.c
new file mode 100644
index 0000000..76d4e58
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_conv.c
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30/*#define _POSIX_SOURCE*/
31#include <stdio.h>
32#include "t_defines.h"
33#include "cstr.h"
34
35static int
36hexDigitToInt(char c)
37{
38 if(c >= '0' && c <= '9')
39 return c - '0';
40 else if(c >= 'a' && c <= 'f')
41 return c - 'a' + 10;
42 else if(c >= 'A' && c <= 'F')
43 return c - 'A' + 10;
44 else
45 return 0;
46}
47
48/*
49 * Convert a hex string to a string of bytes; return size of dst
50 */
51_TYPE( int )
52t_fromhex(char *dst, const char *src)
53{
54 register char *chp = dst;
55 register unsigned size = strlen(src);
56
57 /* FIXME: handle whitespace and non-hex digits by setting size and src
58 appropriately. */
59
60 if(size % 2 == 1) {
61 *chp++ = hexDigitToInt(*src++);
62 --size;
63 }
64 while(size > 0) {
65 *chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
66 src += 2;
67 size -= 2;
68 }
69 return chp - dst;
70}
71
72/*
73 * Convert a string of bytes to their hex representation
74 */
75_TYPE( char * )
76t_tohex(char *dst, const char *src, unsigned size)
77{
78 int notleading = 0;
79
80 register char *chp = dst;
81 *dst = '\0';
82 if (size != 0) do {
83 if(notleading || *src != '\0') {
84 if(!notleading && (*src & 0xf0) == 0) {
85 sprintf(chp, "%.1X", * (unsigned char *) src);
86 chp += 1;
87 }
88 else {
89 sprintf(chp, "%.2X", * (unsigned char *) src);
90 chp += 2;
91 }
92 notleading = 1;
93 }
94 ++src;
95 } while (--size != 0);
96 return dst;
97}
98
99_TYPE( char * )
100t_tohexcstr(cstr *dst, const char *src, unsigned size)
101{
102 cstr_set_length(dst, 2 * size + 1);
103 return t_tohex(dst->data, src, size);
104}
105
106static char b64table[] =
107 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
108
109/*
110 * Convert a base64 string into raw byte array representation.
111 */
112_TYPE( int )
113t_fromb64(char *dst, const char *src)
114{
115 unsigned char *a;
116 char *loc;
117 int i, j;
118 unsigned int size;
119
120 while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
121 ++src;
122 size = strlen(src);
123
124 a = malloc((size + 1) * sizeof(unsigned char));
125 if(a == (unsigned char *) 0)
126 return -1;
127
128 i = 0;
129 while(i < size) {
130 loc = strchr(b64table, src[i]);
131 if(loc == (char *) 0)
132 break;
133 else
134 a[i] = loc - b64table;
135 ++i;
136 }
137 size = i;
138
139 i = size - 1;
140 j = size;
141 while(1) {
142 a[j] = a[i];
143 if(--i < 0)
144 break;
145 a[j] |= (a[i] & 3) << 6;
146 --j;
147 a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
148 if(--i < 0)
149 break;
150 a[j] |= (a[i] & 0xf) << 4;
151 --j;
152 a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
153 if(--i < 0)
154 break;
155 a[j] |= (a[i] << 2);
156
157 a[--j] = 0;
158 if(--i < 0)
159 break;
160 }
161
162 while(a[j] == 0 && j <= size)
163 ++j;
164
165 memcpy(dst, a + j, size - j + 1);
166 free(a);
167 return size - j + 1;
168}
169
170_TYPE( int )
171t_cstrfromb64(cstr *dst, const char *src)
172{
173 int len;
174 cstr_set_length(dst, (strlen(src) * 6 + 7) / 8);
175 len = t_fromb64(dst->data, src);
176 cstr_set_length(dst, len);
177 return len;
178}
179
180/*
181 * Convert a raw byte string into a null-terminated base64 ASCII string.
182 */
183_TYPE( char * )
184t_tob64(char *dst, const char *src, unsigned size)
185{
186 int c, pos = size % 3;
187 unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
188 char *olddst = dst;
189
190 switch(pos) {
191 case 1:
192 b2 = src[0];
193 break;
194 case 2:
195 b1 = src[0];
196 b2 = src[1];
197 break;
198 }
199
200 while(1) {
201 c = (b0 & 0xfc) >> 2;
202 if(notleading || c != 0) {
203 *dst++ = b64table[c];
204 notleading = 1;
205 }
206 c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
207 if(notleading || c != 0) {
208 *dst++ = b64table[c];
209 notleading = 1;
210 }
211 c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
212 if(notleading || c != 0) {
213 *dst++ = b64table[c];
214 notleading = 1;
215 }
216 c = b2 & 0x3f;
217 if(notleading || c != 0) {
218 *dst++ = b64table[c];
219 notleading = 1;
220 }
221 if(pos >= size)
222 break;
223 else {
224 b0 = src[pos++];
225 b1 = src[pos++];
226 b2 = src[pos++];
227 }
228 }
229
230 *dst++ = '\0';
231 return olddst;
232}
233
234_TYPE( char * )
235t_tob64cstr(cstr *dst, const char *src, unsigned int sz)
236{
237 cstr_set_length(dst, (sz * 8 + 5) / 6 + 1);
238 return t_tob64(dst->data, src, sz);
239}
diff --git a/3rd_party/libsrp6a-sha512/t_defines.h b/3rd_party/libsrp6a-sha512/t_defines.h
new file mode 100644
index 0000000..447263f
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_defines.h
@@ -0,0 +1,137 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#ifndef T_DEFINES_H
31#define T_DEFINES_H
32
33#ifndef P
34#if defined(__STDC__) || defined(__cplusplus)
35#define P(x) x
36#else
37#define P(x) ()
38#endif
39#endif
40
41#ifdef HAVE_CONFIG_H
42#include "config.h"
43#endif /* HAVE_CONFIG_H */
44
45#ifndef _DLLDECL
46#define _DLLDECL
47
48#ifdef MSVC15 /* MSVC1.5 support for 16 bit apps */
49#define _MSVC15EXPORT _export
50#define _MSVC20EXPORT
51#define _DLLAPI _export _pascal
52#define _CDECL
53#define _TYPE(a) a _MSVC15EXPORT
54#define DLLEXPORT 1
55
56#elif defined(MSVC20) || (defined(_USRDLL) && defined(SRP_EXPORTS))
57#define _MSVC15EXPORT
58#define _MSVC20EXPORT _declspec(dllexport)
59#define _DLLAPI
60#define _CDECL
61#define _TYPE(a) _MSVC20EXPORT a
62#define DLLEXPORT 1
63
64#else /* Default, non-dll. Use this for Unix or DOS */
65#define _MSVC15DEXPORT
66#define _MSVC20EXPORT
67#define _DLLAPI
68#if defined(WINDOWS) || defined(WIN32)
69#define _CDECL _cdecl
70#else
71#define _CDECL
72#endif
73#define _TYPE(a) a _CDECL
74#endif
75#endif
76
77#if STDC_HEADERS
78#include <stdlib.h>
79#include <string.h>
80#else /* not STDC_HEADERS */
81#ifndef HAVE_STRCHR
82#define strchr index
83#define strrchr rindex
84#endif
85char *strchr(), *strrchr(), *strtok();
86#ifndef HAVE_MEMCPY
87#define memcpy(d, s, n) bcopy((s), (d), (n))
88#endif
89#endif /* not STDC_HEADERS */
90
91#include <sys/types.h>
92
93#if TIME_WITH_SYS_TIME
94#include <sys/time.h>
95#include <time.h>
96#else /* not TIME_WITH_SYS_TIME */
97#if HAVE_SYS_TIME_H
98#include <sys/time.h>
99#else
100#include <time.h>
101#endif
102#endif /* not TIME_WITH_SYS_TIME */
103
104#if HAVE_TERMIOS_H
105#include <termios.h>
106#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
107#define GTTY(fd, termio) tcgetattr(fd, termio)
108#define TERMIO struct termios
109#define USE_TERMIOS
110#elif HAVE_TERMIO_H
111#include <sys/ioctl.h>
112#include <termio.h>
113#define STTY(fd, termio) ioctl(fd, TCSETA, termio)
114#define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
115#define TEMRIO struct termio
116#define USE_TERMIO
117#elif HAVE_SGTTY_H
118#include <sgtty.h>
119#define STTY(fd, termio) stty(fd, termio)
120#define GTTY(fd, termio) gtty(fd, termio)
121#define TERMIO struct sgttyb
122#define USE_SGTTY
123#endif
124
125#ifdef WIN32
126#define USE_FTIME 1
127#define USE_RENAME 1
128#define NO_FCHMOD 1
129#endif
130
131#ifdef USE_FTIME
132#include <sys/timeb.h>
133#endif
134
135/* Looking for BigInteger math functions? They've moved to <srp_aux.h>. */
136
137#endif
diff --git a/3rd_party/libsrp6a-sha512/t_math.c b/3rd_party/libsrp6a-sha512/t_math.c
new file mode 100644
index 0000000..dac19ec
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_math.c
@@ -0,0 +1,968 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#include <stdio.h>
31#include <sys/types.h>
32
33#include "config.h"
34
35#ifdef OPENSSL
36# include "openssl/opensslv.h"
37# include "openssl/bn.h"
38typedef BIGNUM * BigInteger;
39typedef BN_CTX * BigIntegerCtx;
40typedef BN_MONT_CTX * BigIntegerModAccel;
41#include <limits.h>
42#if OPENSSL_VERSION_NUMBER < 0x30000000L
43# ifndef OPENSSL_NO_ENGINE
44# define OPENSSL_ENGINE
45# include "openssl/engine.h"
46static ENGINE * default_engine = NULL;
47# endif /* OPENSSL_ENGINE */
48#endif
49typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
50 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx);
51static modexp_meth default_modexp = NULL;
52#elif defined(CRYPTOLIB)
53# include "libcrypt.h"
54typedef BigInt BigInteger;
55typedef void * BigIntegerCtx;
56typedef void * BigIntegerModAccel;
57#elif defined(GNU_MP)
58# include "gmp.h"
59typedef MP_INT * BigInteger;
60typedef void * BigIntegerCtx;
61typedef void * BigIntegerModAccel;
62# if __GNU_MP_VERSION >= 4 || (__GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1)
63/* GMP 4.1 and up has fast import/export routines for integer conversion */
64# define GMP_IMPEXP 1
65# endif
66#elif defined(TOMMATH)
67# ifdef TOMCRYPT
68 /* as of v0.96 */
69# include "ltc_tommath.h"
70# else
71# include "tommath.h"
72# endif
73typedef mp_int * BigInteger;
74typedef void * BigIntegerCtx;
75typedef void * BigIntegerModAccel;
76#elif defined(GCRYPT)
77# include "gcrypt.h"
78typedef gcry_mpi_t BigInteger;
79typedef void * BigIntegerCtx;
80typedef void * BigIntegerModAccel;
81#elif defined(MPI)
82# include "mpi.h"
83typedef mp_int * BigInteger;
84typedef void * BigIntegerCtx;
85typedef void * BigIntegerModAccel;
86#elif defined(MBEDTLS)
87#include <mbedtls/bignum.h>
88#include <mbedtls/error.h>
89typedef mbedtls_mpi* BigInteger;
90typedef void * BigIntegerCtx;
91typedef void * BigIntegerModAccel;
92#else
93# error "no math library specified"
94#endif
95#define MATH_PRIV
96
97#include "t_defines.h"
98#include "t_pwd.h"
99#include "srp_aux.h"
100
101/* Math library interface stubs */
102
103BigInteger
104BigIntegerFromInt(unsigned int n)
105{
106#ifdef OPENSSL
107 BIGNUM * a = BN_new();
108 if(a)
109 BN_set_word(a, n);
110 return a;
111#elif defined(CRYPTOLIB)
112 return bigInit(n);
113#elif defined(GNU_MP)
114 BigInteger rv = (BigInteger) malloc(sizeof(MP_INT));
115 if(rv)
116 mpz_init_set_ui(rv, n);
117 return rv;
118#elif defined(GCRYPT)
119 BigInteger rv = gcry_mpi_new(32);
120 gcry_mpi_set_ui(rv, n);
121 return rv;
122#elif defined(MPI) || defined(TOMMATH)
123 BigInteger rv = (BigInteger) malloc(sizeof(mp_int));
124 if(rv) {
125 mp_init(rv);
126 mp_set_int(rv, n);
127 }
128 return rv;
129#elif defined(MBEDTLS)
130 mbedtls_mpi* a = (mbedtls_mpi*)malloc(sizeof(mbedtls_mpi));
131 if (a) {
132 mbedtls_mpi_init(a);
133 mbedtls_mpi_lset(a, n);
134 }
135 return a;
136#endif
137}
138
139BigInteger
140BigIntegerFromBytes(const unsigned char *bytes, int length)
141{
142#ifdef OPENSSL
143 BIGNUM * a = BN_new();
144 BN_bin2bn(bytes, length, a);
145 return a;
146#elif defined(CRYPTOLIB)
147 BigInteger rv, t;
148 int i, n;
149
150 rv = bigInit(0);
151 if(rv == NULL)
152 return rv;
153 if(length % 4 == 0)
154 RSA_bufToBig(bytes, length, rv);
155 else { /* Wouldn't need this if cryptolib behaved better */
156 i = length & 0x3;
157 if(length > i)
158 RSA_bufToBig(bytes + i, length - i, rv);
159 for(n = 0; i > 0; --i)
160 n = (n << 8) | *bytes++;
161 t = bigInit(n);
162 bigLeftShift(t, (length & ~0x3) << 3, t);
163 bigAdd(rv, t, rv);
164 freeBignum(t);
165 }
166 return rv;
167#elif defined(GNU_MP)
168 BigInteger rv = (BigInteger) malloc(sizeof(MP_INT));
169
170# ifdef GMP_IMPEXP
171 if(rv) {
172 mpz_init(rv);
173 mpz_import(rv, length, 1, 1, 1, 0, bytes);
174 }
175# else
176 cstr * hexbuf = cstr_new();
177
178 if(hexbuf) {
179 if(rv)
180 mpz_init_set_str(rv, t_tohexcstr(hexbuf, bytes, length), 16);
181 cstr_clear_free(hexbuf);
182 }
183# endif /* GMP_IMPEXP */
184
185 return rv;
186#elif defined(GCRYPT)
187 BigInteger rv;
188 gcry_mpi_scan(&rv, GCRYMPI_FMT_USG, bytes, length, NULL);
189 return rv;
190#elif defined(MPI) || defined(TOMMATH)
191 BigInteger rv = (BigInteger) malloc(sizeof(mp_int));
192 if(rv) {
193 mp_init(rv);
194 mp_read_unsigned_bin(rv, (unsigned char *)bytes, length);
195 }
196 return rv;
197#elif defined(MBEDTLS)
198 mbedtls_mpi* a = (mbedtls_mpi*)malloc(sizeof(mbedtls_mpi));
199 if (a) {
200 mbedtls_mpi_init(a);
201 mbedtls_mpi_read_binary(a, bytes, length);
202 }
203 return a;
204#endif
205}
206
207int
208BigIntegerToBytes(BigInteger src, unsigned char *dest, int destlen)
209{
210#ifdef OPENSSL
211 return BN_bn2bin(src, dest);
212#elif defined(CRYPTOLIB)
213 int i, j;
214 cstr * rawbuf;
215
216 trim(src);
217 i = bigBytes(src);
218 j = (bigBits(src) + 7) / 8;
219 if(i == j)
220 RSA_bigToBuf(src, i, dest);
221 else { /* Wouldn't need this if cryptolib behaved better */
222 rawbuf = cstr_new();
223 cstr_set_length(rawbuf, i);
224 RSA_bigToBuf(src, i, rawbuf->data);
225 memcpy(dest, rawbuf->data + (i-j), j);
226 cstr_clear_free(rawbuf);
227 }
228 return j;
229#elif defined(GNU_MP)
230 size_t r = 0;
231# ifdef GMP_IMPEXP
232 mpz_export(dest, &r, 1, 1, 1, 0, src);
233# else
234 cstr * hexbuf = cstr_new();
235
236 if(hexbuf) {
237 cstr_set_length(hexbuf, mpz_sizeinbase(src, 16) + 1);
238 mpz_get_str(hexbuf->data, 16, src);
239 r = t_fromhex(dest, hexbuf->data);
240 cstr_clear_free(hexbuf);
241 }
242# endif
243 return r;
244#elif defined(GCRYPT)
245 size_t r = 0;
246 gcry_mpi_print(GCRYMPI_FMT_USG, dest, destlen, &r, src);
247 return r;
248#elif defined(MPI) || defined(TOMMATH)
249 mp_to_unsigned_bin(src, dest);
250 return mp_unsigned_bin_size(src);
251#elif defined(MBEDTLS)
252 size_t r = mbedtls_mpi_size(src);
253 mbedtls_mpi_write_binary(src, dest, r);
254 return r;
255#endif
256}
257
258BigIntegerResult
259BigIntegerToCstr(BigInteger x, cstr * out)
260{
261 int n = BigIntegerByteLen(x);
262 if(cstr_set_length(out, n) < 0)
263 return BIG_INTEGER_ERROR;
264 if(cstr_set_length(out, BigIntegerToBytes(x, (unsigned char*)out->data, n)) < 0)
265 return BIG_INTEGER_ERROR;
266 return BIG_INTEGER_SUCCESS;
267}
268
269BigIntegerResult
270BigIntegerToCstrEx(BigInteger x, cstr * out, int len)
271{
272 int n;
273 if(cstr_set_length(out, len) < 0)
274 return BIG_INTEGER_ERROR;
275#if defined(MBEDTLS)
276 /* mbedtls will prefix the output with zeros if the buffer is larger */
277 mbedtls_mpi_write_binary(x, (unsigned char*)out->data, len);
278#else
279 n = BigIntegerToBytes(x, (unsigned char*)out->data, len);
280 if(n < len) {
281 memmove(out->data + (len - n), out->data, n);
282 memset(out->data, 0, len - n);
283 }
284#endif
285 return BIG_INTEGER_SUCCESS;
286}
287
288BigIntegerResult
289BigIntegerToHex(BigInteger src, char *dest, int destlen)
290{
291#ifdef OPENSSL
292 strncpy(dest, BN_bn2hex(src), destlen);
293#elif defined(CRYPTOLIB)
294 trim(src);
295 bigsprint(src, dest);
296#elif defined(GNU_MP)
297 mpz_get_str(dest, 16, src);
298#elif defined(GCRYPT)
299 gcry_mpi_print(GCRYMPI_FMT_HEX, dest, destlen, NULL, src);
300#elif defined(MPI) || defined(TOMMATH)
301 mp_toradix(src, dest, 16);
302#elif defined(MBEDTLS)
303 size_t olen = 0;
304 mbedtls_mpi_write_string(src, 16, dest, destlen, &olen);
305#endif
306 return BIG_INTEGER_SUCCESS;
307}
308
309static char b64table[] =
310 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
311
312BigIntegerResult
313BigIntegerToString(BigInteger src, char *dest, int destlen, unsigned int radix)
314{
315 BigInteger t = BigIntegerFromInt(0);
316 char * p = dest;
317 char c;
318
319 *p++ = b64table[BigIntegerModInt(src, radix, NULL)];
320 BigIntegerDivInt(t, src, radix, NULL);
321 while(BigIntegerCmpInt(t, 0) > 0) {
322 *p++ = b64table[BigIntegerModInt(t, radix, NULL)];
323 BigIntegerDivInt(t, t, radix, NULL);
324 }
325 BigIntegerFree(t);
326 *p-- = '\0';
327 /* reverse the string */
328 while(p > dest) {
329 c = *p;
330 *p-- = *dest;
331 *dest++ = c;
332 }
333 return BIG_INTEGER_SUCCESS;
334}
335
336int
337BigIntegerBitLen(BigInteger b)
338{
339#ifdef OPENSSL
340 return BN_num_bits(b);
341#elif defined(CRYPTOLIB)
342 return bigBits(b);
343#elif defined(GNU_MP)
344 return mpz_sizeinbase(b, 2);
345#elif defined(GCRYPT)
346 return gcry_mpi_get_nbits(b);
347#elif defined(MPI) || defined(TOMMATH)
348 return mp_count_bits(b);
349#elif defined(MBEDTLS)
350 return (int)mbedtls_mpi_bitlen(b);
351#endif
352}
353
354int
355BigIntegerCmp(BigInteger c1, BigInteger c2)
356{
357#ifdef OPENSSL
358 return BN_cmp(c1, c2);
359#elif defined(CRYPTOLIB)
360 return bigCompare(c1, c2);
361#elif defined(GNU_MP)
362 return mpz_cmp(c1, c2);
363#elif defined(GCRYPT)
364 return gcry_mpi_cmp(c1, c2);
365#elif defined(MPI) || defined(TOMMATH)
366 return mp_cmp(c1, c2);
367#elif defined(MBEDTLS)
368 return mbedtls_mpi_cmp_mpi(c1, c2);
369#endif
370}
371
372int
373BigIntegerCmpInt(BigInteger c1, unsigned int c2)
374{
375#ifdef OPENSSL
376 BigInteger bc2 = BigIntegerFromInt(c2);
377 int rv = BigIntegerCmp(c1, bc2);
378 BigIntegerFree(bc2);
379 return rv;
380#elif defined(CRYPTOLIB)
381 BigInteger t;
382 int rv;
383
384 t = bigInit(c2);
385 rv = bigCompare(c1, t);
386 freeBignum(t);
387 return rv;
388#elif defined(GNU_MP)
389 return mpz_cmp_ui(c1, c2);
390#elif defined(TOMMATH)
391 return mp_cmp_d(c1, c2);
392#elif defined(GCRYPT)
393 return gcry_mpi_cmp_ui(c1, c2);
394#elif defined(MPI)
395 return mp_cmp_int(c1, c2);
396#elif defined(MBEDTLS)
397 return mbedtls_mpi_cmp_int(c1, c2);
398#endif
399}
400
401BigIntegerResult
402BigIntegerLShift(BigInteger result, BigInteger x, unsigned int bits)
403{
404#ifdef OPENSSL
405 BN_lshift(result, x, bits);
406#elif defined(CRYPTOLIB)
407 bigLeftShift(x, bits, result);
408#elif defined(GNU_MP)
409 mpz_mul_2exp(result, x, bits);
410#elif defined(GCRYPT)
411 gcry_mpi_mul_2exp(result, x, bits);
412#elif defined(MPI) || defined(TOMMATH)
413 mp_mul_2d(x, bits, result);
414#elif defined(MBEDTLS)
415 mbedtls_mpi_copy(result, x);
416 mbedtls_mpi_shift_l(result, bits);
417#endif
418 return BIG_INTEGER_SUCCESS;
419}
420
421BigIntegerResult
422BigIntegerAdd(BigInteger result, BigInteger a1, BigInteger a2)
423{
424#ifdef OPENSSL
425 BN_add(result, a1, a2);
426#elif defined(CRYPTOLIB)
427 bigAdd(a1, a2, result);
428#elif defined(GNU_MP)
429 mpz_add(result, a1, a2);
430#elif defined(GCRYPT)
431 gcry_mpi_add(result, a1, a2);
432#elif defined(MPI) || defined(TOMMATH)
433 mp_add(a1, a2, result);
434#elif defined(MBEDTLS)
435 mbedtls_mpi_add_mpi(result, a1, a2);
436#endif
437 return BIG_INTEGER_SUCCESS;
438}
439
440BigIntegerResult
441BigIntegerAddInt(BigInteger result, BigInteger a1, unsigned int a2)
442{
443#ifdef OPENSSL
444 if(result != a1)
445 BN_copy(result, a1);
446 BN_add_word(result, a2);
447#elif defined(CRYPTOLIB)
448 BigInteger t;
449
450 t = bigInit(a2);
451 bigAdd(a1, t, result);
452 freeBignum(t);
453#elif defined(GNU_MP)
454 mpz_add_ui(result, a1, a2);
455#elif defined(GCRYPT)
456 gcry_mpi_add_ui(result, a1, a2);
457#elif defined(MPI) || defined(TOMMATH)
458 mp_add_d(a1, a2, result);
459#elif defined(MBEDTLS)
460 mbedtls_mpi_add_int(result, a1, a2);
461#endif
462 return BIG_INTEGER_SUCCESS;
463}
464
465BigIntegerResult
466BigIntegerSub(BigInteger result, BigInteger s1, BigInteger s2)
467{
468#ifdef OPENSSL
469 BN_sub(result, s1, s2);
470#elif defined(CRYPTOLIB)
471 bigSubtract(s1, s2, result);
472#elif defined(GNU_MP)
473 mpz_sub(result, s1, s2);
474#elif defined(GCRYPT)
475 gcry_mpi_sub(result, s1, s2);
476#elif defined(MPI) || defined(TOMMATH)
477 mp_sub(s1, s2, result);
478#elif defined(MBEDTLS)
479 mbedtls_mpi_sub_mpi(result, s1, s2);
480#endif
481 return BIG_INTEGER_SUCCESS;
482}
483
484BigIntegerResult
485BigIntegerSubInt(BigInteger result, BigInteger s1, unsigned int s2)
486{
487#ifdef OPENSSL
488 if(result != s1)
489 BN_copy(result, s1);
490 BN_sub_word(result, s2);
491#elif defined(CRYPTOLIB)
492 BigInteger t;
493
494 t = bigInit(s2);
495 bigSubtract(s1, t, result);
496 freeBignum(t);
497#elif defined(GNU_MP)
498 mpz_sub_ui(result, s1, s2);
499#elif defined(GCRYPT)
500 gcry_mpi_sub_ui(result, s1, s2);
501#elif defined(MPI) || defined(TOMMATH)
502 mp_sub_d(s1, s2, result);
503#elif defined(MBEDTLS)
504 mbedtls_mpi_sub_int(result, s1, s2);
505#endif
506 return BIG_INTEGER_SUCCESS;
507}
508
509BigIntegerResult
510BigIntegerMul(BigInteger result, BigInteger m1, BigInteger m2, BigIntegerCtx c)
511{
512#ifdef OPENSSL
513 BN_CTX * ctx = NULL;
514 if(c == NULL)
515 c = ctx = BN_CTX_new();
516 BN_mul(result, m1, m2, c);
517 if(ctx)
518 BN_CTX_free(ctx);
519#elif defined(CRYPTOLIB)
520 bigMultiply(m1, m2, result);
521#elif defined(GNU_MP)
522 mpz_mul(result, m1, m2);
523#elif defined(GCRYPT)
524 gcry_mpi_mul(result, m1, m2);
525#elif defined(MPI) || defined(TOMMATH)
526 mp_mul(m1, m2, result);
527#elif defined(MBEDTLS)
528 mbedtls_mpi_mul_mpi(result, m1, m2);
529#endif
530 return BIG_INTEGER_SUCCESS;
531}
532
533BigIntegerResult
534BigIntegerMulInt(BigInteger result, BigInteger m1, unsigned int m2, BigIntegerCtx c)
535{
536#ifdef OPENSSL
537 if(result != m1)
538 BN_copy(result, m1);
539 BN_mul_word(result, m2);
540#elif defined(CRYPTOLIB)
541 BigInteger t;
542
543 t = bigInit(m2);
544 bigMultiply(m1, t, result);
545 freeBignum(t);
546#elif defined(GNU_MP)
547 mpz_mul_ui(result, m1, m2);
548#elif defined(GCRYPT)
549 gcry_mpi_mul_ui(result, m1, m2);
550#elif defined(MPI) || defined(TOMMATH)
551 mp_mul_d(m1, m2, result);
552#elif defined(MBEDTLS)
553 mbedtls_mpi_mul_int(result, m1, m2);
554#endif
555 return BIG_INTEGER_SUCCESS;
556}
557
558BigIntegerResult
559BigIntegerDivInt(BigInteger result, BigInteger d, unsigned int m, BigIntegerCtx c)
560{
561#ifdef OPENSSL
562 if(result != d)
563 BN_copy(result, d);
564 BN_div_word(result, m);
565#elif defined(CRYPTOLIB)
566 BigInteger t, u, q;
567
568 t = bigInit(m);
569 u = bigInit(0);
570 /* We use a separate variable q because cryptolib breaks if result == d */
571 q = bigInit(0);
572 bigDivide(d, t, q, u);
573 freeBignum(t);
574 freeBignum(u);
575 bigCopy(q, result);
576 freeBignum(q);
577#elif defined(GNU_MP)
578# ifdef GMP2
579 mpz_fdiv_q_ui(result, d, m);
580# else
581 mpz_div_ui(result, d, m);
582# endif
583#elif defined(GCRYPT)
584 BigInteger t = BigIntegerFromInt(m);
585 gcry_mpi_div(result, NULL, d, t, -1);
586 BigIntegerFree(t);
587#elif defined(MPI) || defined(TOMMATH)
588 mp_div_d(d, m, result, NULL);
589#elif defined(MBEDTLS)
590 mbedtls_mpi_div_int(result, NULL, d, m);
591#endif
592 return BIG_INTEGER_SUCCESS;
593}
594
595BigIntegerResult
596BigIntegerMod(BigInteger result, BigInteger d, BigInteger m, BigIntegerCtx c)
597{
598#ifdef OPENSSL
599 BN_CTX * ctx = NULL;
600 if(c == NULL)
601 c = ctx = BN_CTX_new();
602 BN_mod(result, d, m, c);
603 if(ctx)
604 BN_CTX_free(ctx);
605#elif defined(CRYPTOLIB)
606 bigMod(d, m, result);
607#elif defined(GNU_MP)
608 mpz_mod(result, d, m);
609#elif defined(GCRYPT)
610 gcry_mpi_mod(result, d, m);
611#elif defined(MPI) || defined(TOMMATH)
612 mp_mod(d, m, result);
613#elif defined(MBEDTLS)
614 mbedtls_mpi_mod_mpi(result, d, m);
615#endif
616 return BIG_INTEGER_SUCCESS;
617}
618
619unsigned int
620BigIntegerModInt(BigInteger d, unsigned int m, BigIntegerCtx c)
621{
622#ifdef OPENSSL
623 return BN_mod_word(d, m);
624#elif defined(CRYPTOLIB)
625 BigInteger t, u;
626 unsigned char r[4];
627
628 t = bigInit(m);
629 u = bigInit(0);
630 bigMod(d, t, u);
631 bigToBuf(u, sizeof(r), r);
632 freeBignum(t);
633 freeBignum(u);
634 return r[0] | (r[1] << 8) | (r[2] << 16) | (r[3] << 24);
635#elif defined(GNU_MP)
636 MP_INT result;
637 unsigned int i;
638
639 mpz_init(&result);
640
641/* Define GMP2 if you're using an old gmp.h but want to link against a
642 * newer libgmp.a (e.g. 2.0 or later). */
643
644# ifdef GMP2
645 mpz_fdiv_r_ui(&result, d, m);
646# else
647 mpz_mod_ui(&result, d, m);
648# endif
649 i = mpz_get_ui(&result);
650 mpz_clear(&result);
651 return i;
652#elif defined(GCRYPT)
653 /* TODO: any way to clean this up??? */
654 unsigned char r[4];
655 size_t len, i;
656 unsigned int ret = 0;
657 BigInteger t = BigIntegerFromInt(m);
658 BigInteger a = BigIntegerFromInt(0);
659 gcry_mpi_mod(a, d, t);
660 gcry_mpi_print(GCRYMPI_FMT_USG, r, 4, &len, a);
661 for(i = 0; i < len; ++i)
662 ret = (ret << 8) | r[i];
663 BigIntegerFree(t);
664 BigIntegerFree(a);
665 return ret;
666#elif defined(MPI) || defined(TOMMATH)
667 mp_digit r;
668 mp_mod_d(d, m, &r);
669 return r;
670#elif defined(MBEDTLS)
671 mbedtls_mpi_uint r = 0;
672 mbedtls_mpi_mod_int(&r, d, m);
673 return r;
674#endif
675}
676
677BigIntegerResult
678BigIntegerModMul(BigInteger r, BigInteger m1, BigInteger m2, BigInteger modulus, BigIntegerCtx c)
679{
680#ifdef OPENSSL
681 BN_CTX * ctx = NULL;
682 if(c == NULL)
683 c = ctx = BN_CTX_new();
684 BN_mod_mul(r, m1, m2, modulus, c);
685 if(ctx)
686 BN_CTX_free(ctx);
687#elif defined(CRYPTOLIB)
688 bigMultiply(m1, m2, r);
689 bigMod(r, modulus, r);
690#elif defined(GNU_MP)
691 mpz_mul(r, m1, m2);
692 mpz_mod(r, r, modulus);
693#elif defined(GCRYPT)
694 gcry_mpi_mulm(r, m1, m2, modulus);
695#elif defined(MPI) || defined(TOMMATH)
696 mp_mulmod(m1, m2, modulus, r);
697#elif defined(MBEDTLS)
698 mbedtls_mpi d;
699 mbedtls_mpi_init(&d);
700 mbedtls_mpi_mul_mpi(&d, m1, m2);
701 mbedtls_mpi_mod_mpi(r, &d, modulus);
702 mbedtls_mpi_free(&d);
703#endif
704 return BIG_INTEGER_SUCCESS;
705}
706
707BigIntegerResult
708BigIntegerModExp(BigInteger r, BigInteger b, BigInteger e, BigInteger m, BigIntegerCtx c, BigIntegerModAccel a)
709{
710#ifdef OPENSSL
711#if OPENSSL_VERSION_NUMBER >= 0x00906000
712 BN_ULONG B = BN_get_word(b);
713#endif
714 BN_CTX * ctx = NULL;
715 if(c == NULL)
716 c = ctx = BN_CTX_new();
717 if(default_modexp) {
718 (*default_modexp)(r, b, e, m, c, a);
719 }
720 else if(a == NULL) {
721 BN_mod_exp(r, b, e, m, c);
722 }
723/*
724 * In LibreSSL BN_mod_exp_mont_word() is not a public symbol where BN_mod_exp()
725 * and BN_mod_exp_mont() will use the word optimization when appropriate.
726 */
727#if OPENSSL_VERSION_NUMBER >= 0x00906000 && !defined(LIBRESSL_VERSION_NUMBER)
728 else if(B > 0 && B < ULONG_MAX) { /* 0.9.6 and above has mont_word optimization */
729 BN_mod_exp_mont_word(r, B, e, m, c, a);
730 }
731#endif
732 else
733 BN_mod_exp_mont(r, b, e, m, c, a);
734 if(ctx)
735 BN_CTX_free(ctx);
736#elif defined(CRYPTOLIB)
737 bigPow(b, e, m, r);
738#elif defined(GNU_MP)
739 mpz_powm(r, b, e, m);
740#elif defined(GCRYPT)
741 gcry_mpi_powm(r, b, e, m);
742#elif defined(MPI) || defined(TOMMATH)
743 mp_exptmod(b, e, m, r);
744#elif defined(MBEDTLS)
745 mbedtls_mpi_exp_mod(r, b, e, m, NULL);
746#endif
747 return BIG_INTEGER_SUCCESS;
748}
749
750#if defined(MBEDTLS)
751int _mbedtls_f_rng(void* unused, unsigned char *buf, size_t size)
752{
753 t_random(buf, size);
754 return 0;
755}
756#endif
757
758int
759BigIntegerCheckPrime(BigInteger n, BigIntegerCtx c)
760{
761#ifdef OPENSSL
762 int rv;
763 BN_CTX * ctx = NULL;
764 if(c == NULL)
765 c = ctx = BN_CTX_new();
766#if OPENSSL_VERSION_NUMBER >= 0x00908000
767 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
768 rv = BN_check_prime(n, c, NULL);
769 #else
770 rv = BN_is_prime_ex(n, 25, c, NULL);
771 #endif
772#else
773 rv = BN_is_prime(n, 25, NULL, c, NULL);
774#endif
775 if(ctx)
776 BN_CTX_free(ctx);
777 return rv;
778#elif defined(CRYPTOLIB)
779#if 0
780 /*
781 * Ugh. Not only is cryptolib's bigDivide sensitive to inputs
782 * and outputs being the same, but now the primeTest needs random
783 * numbers, which it gets by calling cryptolib's broken truerand
784 * implementation(!) We have to fake it out by doing our own
785 * seeding explicitly.
786 */
787 static int seeded = 0;
788 static unsigned char seedbuf[64];
789 if(!seeded) {
790 t_random(seedbuf, sizeof(seedbuf));
791 seedDesRandom(seedbuf, sizeof(seedbuf));
792 memset(seedbuf, 0, sizeof(seedbuf));
793 seeded = 1;
794 }
795#endif /* 0 */
796 t_random(NULL, 0);
797 return primeTest(n);
798#elif defined(GNU_MP)
799 return mpz_probab_prime_p(n, 25);
800#elif defined(GCRYPT)
801 return (gcry_prime_check(n, 0) == GPG_ERR_NO_ERROR);
802#elif defined(TOMMATH)
803 int rv;
804 mp_prime_is_prime(n, 25, &rv);
805 return rv;
806#elif defined(MPI)
807 return (mpp_pprime(n, 25) == MP_YES);
808#elif defined(MBEDTLS)
809 return mbedtls_mpi_is_prime_ext(n, 25, _mbedtls_f_rng, NULL);
810#endif
811}
812
813BigIntegerResult
814BigIntegerFree(BigInteger b)
815{
816#ifdef OPENSSL
817 BN_free(b);
818#elif defined(CRYPTOLIB)
819 freeBignum(b);
820#elif defined(GNU_MP)
821 mpz_clear(b);
822 free(b);
823#elif defined(GCRYPT)
824 gcry_mpi_release(b);
825#elif defined(MPI) || defined(TOMMATH)
826 mp_clear(b);
827 free(b);
828#elif defined(MBEDTLS)
829 mbedtls_mpi_free(b);
830 free(b);
831#endif
832 return BIG_INTEGER_SUCCESS;
833}
834
835BigIntegerResult
836BigIntegerClearFree(BigInteger b)
837{
838#ifdef OPENSSL
839 BN_clear_free(b);
840#elif defined(CRYPTOLIB)
841 /* TODO */
842 freeBignum(b);
843#elif defined(GNU_MP)
844 /* TODO */
845 mpz_clear(b);
846 free(b);
847#elif defined(GCRYPT)
848 /* TODO */
849 gcry_mpi_release(b);
850#elif defined(MPI) || defined(TOMMATH)
851 /* TODO */
852 mp_clear(b);
853 free(b);
854#elif defined(MBEDTLS)
855 mbedtls_mpi_free(b);
856 free(b);
857#endif
858 return BIG_INTEGER_SUCCESS;
859}
860
861BigIntegerCtx
862BigIntegerCtxNew()
863{
864#ifdef OPENSSL
865 return BN_CTX_new();
866#else
867 return NULL;
868#endif
869}
870
871BigIntegerResult
872BigIntegerCtxFree(BigIntegerCtx ctx)
873{
874#ifdef OPENSSL
875 if(ctx)
876 BN_CTX_free(ctx);
877#endif
878 return BIG_INTEGER_SUCCESS;
879}
880
881BigIntegerModAccel
882BigIntegerModAccelNew(BigInteger m, BigIntegerCtx c)
883{
884#ifdef OPENSSL
885 BN_CTX * ctx = NULL;
886 BN_MONT_CTX * mctx;
887 if(default_modexp)
888 return NULL;
889 if(c == NULL)
890 c = ctx = BN_CTX_new();
891 mctx = BN_MONT_CTX_new();
892 BN_MONT_CTX_set(mctx, m, c);
893 if(ctx)
894 BN_CTX_free(ctx);
895 return mctx;
896#else
897 return NULL;
898#endif
899}
900
901BigIntegerResult
902BigIntegerModAccelFree(BigIntegerModAccel accel)
903{
904#ifdef OPENSSL
905 if(accel)
906 BN_MONT_CTX_free(accel);
907#endif
908 return BIG_INTEGER_SUCCESS;
909}
910
911BigIntegerResult
912BigIntegerInitialize()
913{
914#if OPENSSL_VERSION_NUMBER >= 0x00907000 && defined(OPENSSL_ENGINE)
915 ENGINE_load_builtin_engines();
916#endif
917 return BIG_INTEGER_SUCCESS;
918}
919
920BigIntegerResult
921BigIntegerFinalize()
922{
923 return BigIntegerReleaseEngine();
924}
925
926BigIntegerResult
927BigIntegerUseEngine(const char * engine)
928{
929#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
930 ENGINE * e = ENGINE_by_id(engine);
931 if(e) {
932 if(ENGINE_init(e) > 0) {
933#if OPENSSL_VERSION_NUMBER >= 0x00907000
934 /* 0.9.7 loses the BN_mod_exp method. Pity. */
935 const RSA_METHOD * rsa = ENGINE_get_RSA(e);
936 if(rsa)
937#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3000000fL) || (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100005L)
938 default_modexp = (modexp_meth)RSA_meth_get_bn_mod_exp(rsa);
939#else
940 default_modexp = (modexp_meth)rsa->bn_mod_exp;
941#endif
942#else
943 default_modexp = (modexp_meth)ENGINE_get_BN_mod_exp(e);
944#endif
945 BigIntegerReleaseEngine();
946 default_engine = e;
947 return BIG_INTEGER_SUCCESS;
948 }
949 else
950 ENGINE_free(e);
951 }
952#endif
953 return BIG_INTEGER_ERROR;
954}
955
956BigIntegerResult
957BigIntegerReleaseEngine()
958{
959#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
960 if(default_engine) {
961 ENGINE_finish(default_engine);
962 ENGINE_free(default_engine);
963 default_engine = NULL;
964 default_modexp = NULL;
965 }
966#endif
967 return BIG_INTEGER_SUCCESS;
968}
diff --git a/3rd_party/libsrp6a-sha512/t_misc.c b/3rd_party/libsrp6a-sha512/t_misc.c
new file mode 100644
index 0000000..3a2cda1
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_misc.c
@@ -0,0 +1,439 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#include "t_defines.h"
31
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif /* HAVE_UNISTD_H */
35
36#include <stdio.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <fcntl.h>
40
41#ifdef WIN32
42#include <process.h>
43#include <io.h>
44#endif
45
46#include "t_sha.h"
47
48#ifndef NULL
49#define NULL 0
50#endif
51
52#ifdef OPENSSL
53#include <openssl/opensslv.h>
54#include <openssl/rand.h>
55#elif defined(TOMCRYPT)
56#include "tomcrypt.h"
57static prng_state g_rng;
58static unsigned char entropy[32];
59#elif defined(CRYPTOLIB)
60# include "libcrypt.h"
61static unsigned char crpool[64];
62#else
63static unsigned char randpool[SHA_DIGESTSIZE], randout[SHA_DIGESTSIZE];
64static unsigned long randcnt = 0;
65static unsigned int outpos = 0;
66SHA1_CTX randctxt;
67#endif /* OPENSSL */
68
69/*
70 * t_envhash - Generate a 160-bit SHA hash of the environment
71 *
72 * This routine performs an SHA hash of all the "name=value" pairs
73 * in the environment concatenated together and dumps them in the
74 * output. While it is true that anyone on the system can see
75 * your environment, someone not on the system will have a very
76 * difficult time guessing it, especially since some systems play
77 * tricks with variable ordering and sometimes define quirky
78 * environment variables like $WINDOWID or $_.
79 */
80extern char ** environ;
81
82static void
83t_envhash(unsigned char * out)
84{
85 char ** ptr;
86 char ebuf[256];
87 SHA1_CTX ctxt;
88
89 SHA1Init(&ctxt);
90 for(ptr = environ; *ptr; ++ptr) {
91 strncpy(ebuf, *ptr, 255);
92 ebuf[255] = '\0';
93 SHA1Update(&ctxt, ebuf, strlen(ebuf));
94 }
95 SHA1Final(out, &ctxt);
96}
97
98/*
99 * t_fshash - Generate a 160-bit SHA hash from the file system
100 *
101 * This routine climbs up the directory tree from the current
102 * directory, running stat() on each directory until it hits the
103 * root directory. This information is sensitive to the last
104 * access/modification times of all the directories above you,
105 * so someone who lists one of those directories injects some
106 * entropy into the system. Obviously, this hash is very sensitive
107 * to your current directory when the program is run.
108 *
109 * For good measure, it also performs an fstat on the standard input,
110 * usually your tty, throws that into the buffer, creates a file in
111 * /tmp (the inode is unpredictable on a busy system), and runs stat()
112 * on that before deleting it.
113 *
114 * The entire buffer is run once through SHA to obtain the final result.
115 */
116static void
117t_fshash(unsigned char * out)
118{
119 char dotpath[128];
120 struct stat st;
121 SHA1_CTX ctxt;
122 int i, pinode;
123 dev_t pdev;
124
125 SHA1Init(&ctxt);
126 if(stat(".", &st) >= 0) {
127 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
128 pinode = st.st_ino;
129 pdev = st.st_dev;
130 strcpy(dotpath, "..");
131 for(i = 0; i < 40; ++i) {
132 if(stat(dotpath, &st) < 0)
133 break;
134 if(st.st_ino == pinode && st.st_dev == pdev)
135 break;
136 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
137 pinode = st.st_ino;
138 pdev = st.st_dev;
139 strcat(dotpath, "/..");
140 }
141 }
142
143 if(fstat(0, &st) >= 0)
144 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
145
146 sprintf(dotpath, "/tmp/rnd.%d", getpid());
147 if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
148 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
149 unlink(dotpath);
150
151 SHA1Final(out, &ctxt);
152}
153
154/*
155 * Generate a high-entropy seed for the strong random number generator.
156 * This uses a wide variety of quickly gathered and somewhat unpredictable
157 * system information. The 'preseed' structure is assembled from:
158 *
159 * The system time in seconds
160 * The system time in microseconds
161 * The current process ID
162 * The parent process ID
163 * A hash of the user's environment
164 * A hash gathered from the file system
165 * Input from a random device, if available
166 * Timings of system interrupts
167 *
168 * The entire structure (60 bytes on most systems) is fed to SHA to produce
169 * a 160-bit seed for the strong random number generator. It is believed
170 * that in the worst case (on a quiet system with no random device versus
171 * an attacker who has access to the system already), the seed contains at
172 * least about 80 bits of entropy. Versus an attacker who does not have
173 * access to the system, the entropy should be slightly over 128 bits.
174 */
175static char initialized = 0;
176
177static struct {
178 unsigned int trand1;
179 time_t sec;
180 time_t subsec;
181 short pid;
182 short ppid;
183 unsigned char envh[SHA_DIGESTSIZE];
184 unsigned char fsh[SHA_DIGESTSIZE];
185 unsigned char devrand[20];
186 unsigned int trand2;
187} preseed;
188
189unsigned long raw_truerand();
190
191static void
192t_initrand()
193{
194 SHA1_CTX ctxt;
195#ifdef USE_FTIME
196 struct timeb t;
197#else
198 struct timeval t;
199#endif
200 int i, r=0;
201
202 if(initialized)
203 return;
204
205 initialized = 1;
206
207#if defined(OPENSSL) /* OpenSSL has nifty win32 entropy-gathering code */
208#if OPENSSL_VERSION_NUMBER >= 0x00905100
209 r = RAND_status();
210#if defined(WINDOWS) || defined(WIN32)
211 if(r) /* Don't do the Unix-y stuff on Windows if possible */
212 return;
213#else
214#endif
215#endif
216
217#elif defined(TOMCRYPT)
218 yarrow_start(&g_rng);
219 r = rng_get_bytes(entropy, sizeof(entropy), NULL);
220 if(r > 0) {
221 yarrow_add_entropy(entropy, r, &g_rng);
222 memset(entropy, 0, sizeof(entropy));
223# if defined(WINDOWS) || defined(WIN32)
224 /* Don't do the Unix-y stuff on Windows if possible */
225 yarrow_ready(&g_rng);
226 return;
227# endif
228 }
229#endif
230
231#if !defined(WINDOWS) && !defined(WIN32)
232 i = open("/dev/urandom", O_RDONLY);
233 if(i > 0) {
234 r += read(i, preseed.devrand, sizeof(preseed.devrand));
235 close(i);
236 }
237#endif /* !WINDOWS && !WIN32 */
238
239 /* Resort to truerand only if desperate for some Real entropy */
240 if(r == 0)
241 preseed.trand1 = raw_truerand();
242
243#ifdef USE_FTIME
244 ftime(&t);
245 preseed.sec = t.time;
246 preseed.subsec = t.millitm;
247#else
248 gettimeofday(&t, NULL);
249 preseed.sec = t.tv_sec;
250 preseed.subsec = t.tv_usec;
251#endif
252 preseed.pid = getpid();
253#ifndef WIN32
254 preseed.ppid = getppid();
255#endif
256 t_envhash(preseed.envh);
257 t_fshash(preseed.fsh);
258
259 if(r == 0)
260 preseed.trand2 = raw_truerand();
261
262#ifdef OPENSSL
263 RAND_seed((unsigned char *)&preseed, sizeof(preseed));
264#elif defined(TOMCRYPT)
265 yarrow_add_entropy((unsigned char *)&preseed, sizeof(preseed), &g_rng);
266 yarrow_ready(&g_rng);
267#elif defined(CRYPTOLIB)
268 t_mgf1(crpool, sizeof(crpool), (unsigned char *) &preseed, sizeof(preseed));
269 seedDesRandom(crpool, sizeof(crpool));
270 memset(crpool, 0, sizeof(crpool));
271#elif defined(GCRYPT)
272 gcry_random_add_bytes((unsigned char *)&preseed, sizeof(preseed), -1);
273#else
274 SHA1Init(&ctxt);
275 SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
276 SHA1Final(randpool, &ctxt);
277 memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
278 outpos = 0;
279#endif /* OPENSSL */
280 memset((unsigned char *) &preseed, 0, sizeof(preseed));
281}
282
283#define NUM_RANDOMS 12
284
285_TYPE( void )
286t_stronginitrand()
287{
288#if 1 /* t_initrand() has been improved enough to make this unnecessary */
289 t_initrand();
290#else
291 SHA1_CTX ctxt;
292 unsigned int rawrand[NUM_RANDOMS];
293 int i;
294
295 if(!initialized)
296 t_initrand();
297 for(i = 0; i < NUM_RANDOMS; ++i)
298 rawrand[i] = raw_truerand();
299 SHA1Init(&ctxt);
300 SHA1Update(&ctxt, (unsigned char *) rawrand, sizeof(rawrand));
301 SHA1Final(randkey2, &ctxt);
302 memset(rawrand, 0, sizeof(rawrand));
303#endif
304}
305
306/*
307 * The strong random number generator. This uses a 160-bit seed
308 * and uses SHA-1 in a feedback configuration to generate successive
309 * outputs. If S[0] is set to the initial seed, then:
310 *
311 * S[i+1] = SHA-1(i || S[i])
312 * A[i] = SHA-1(S[i])
313 *
314 * where the A[i] are the output blocks starting with i=0.
315 * Each cycle generates 20 bytes of new output.
316 */
317_TYPE( void )
318t_random(unsigned char * data, unsigned size)
319{
320 if(!initialized)
321 t_initrand();
322
323 if(size <= 0) /* t_random(NULL, 0) forces seed initialization */
324 return;
325
326#ifdef OPENSSL
327 RAND_bytes(data, size);
328#elif defined(TOMCRYPT)
329 yarrow_read(data, size, &g_rng);
330#elif defined(GCRYPT)
331 gcry_randomize(data, size, GCRY_STRONG_RANDOM);
332#elif defined(CRYPTOLIB)
333 randomBytes(data, size, PSEUDO);
334#else
335 while(size > outpos) {
336 if(outpos > 0) {
337 memcpy(data, randout + (sizeof(randout) - outpos), outpos);
338 data += outpos;
339 size -= outpos;
340 }
341
342 /* Recycle */
343 SHA1Init(&randctxt);
344 SHA1Update(&randctxt, randpool, sizeof(randpool));
345 SHA1Final(randout, &randctxt);
346 SHA1Init(&randctxt);
347 SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
348 SHA1Update(&randctxt, randpool, sizeof(randpool));
349 SHA1Final(randpool, &randctxt);
350 ++randcnt;
351 outpos = sizeof(randout);
352 }
353
354 if(size > 0) {
355 memcpy(data, randout + (sizeof(randout) - outpos), size);
356 outpos -= size;
357 }
358#endif
359}
360
361/*
362 * The interleaved session-key hash. This separates the even and the odd
363 * bytes of the input (ignoring the first byte if the input length is odd),
364 * hashes them separately, and re-interleaves the two outputs to form a
365 * single 320-bit value.
366 */
367_TYPE( unsigned char * )
368t_sessionkey(unsigned char * key, unsigned char * sk, unsigned sklen)
369{
370 unsigned i, klen;
371 unsigned char * hbuf;
372 unsigned char hout[SHA_DIGESTSIZE];
373 SHA1_CTX ctxt;
374
375 while(sklen > 0 && *sk == 0) { /* Skip leading 0's */
376 --sklen;
377 ++sk;
378 }
379
380 klen = sklen / 2;
381 if((hbuf = malloc(klen * sizeof(char))) == 0)
382 return 0;
383
384 for(i = 0; i < klen; ++i)
385 hbuf[i] = sk[sklen - 2 * i - 1];
386 SHA1Init(&ctxt);
387 SHA1Update(&ctxt, hbuf, klen);
388 SHA1Final(hout, &ctxt);
389 for(i = 0; i < sizeof(hout); ++i)
390 key[2 * i] = hout[i];
391
392 for(i = 0; i < klen; ++i)
393 hbuf[i] = sk[sklen - 2 * i - 2];
394 SHA1Init(&ctxt);
395 SHA1Update(&ctxt, hbuf, klen);
396 SHA1Final(hout, &ctxt);
397 for(i = 0; i < sizeof(hout); ++i)
398 key[2 * i + 1] = hout[i];
399
400 memset(hout, 0, sizeof(hout));
401 memset(hbuf, 0, klen);
402 free(hbuf);
403 return key;
404}
405
406_TYPE( void )
407t_mgf1(unsigned char * mask, unsigned masklen, const unsigned char * seed, unsigned seedlen)
408{
409 SHA1_CTX ctxt;
410 unsigned i = 0;
411 unsigned pos = 0;
412 unsigned char cnt[4];
413 unsigned char hout[SHA_DIGESTSIZE];
414
415 while(pos < masklen) {
416 cnt[0] = (i >> 24) & 0xFF;
417 cnt[1] = (i >> 16) & 0xFF;
418 cnt[2] = (i >> 8) & 0xFF;
419 cnt[3] = i & 0xFF;
420 SHA1Init(&ctxt);
421 SHA1Update(&ctxt, seed, seedlen);
422 SHA1Update(&ctxt, cnt, 4);
423
424 if(pos + SHA_DIGESTSIZE > masklen) {
425 SHA1Final(hout, &ctxt);
426 memcpy(mask + pos, hout, masklen - pos);
427 pos = masklen;
428 }
429 else {
430 SHA1Final(mask + pos, &ctxt);
431 pos += SHA_DIGESTSIZE;
432 }
433
434 ++i;
435 }
436
437 memset(hout, 0, sizeof(hout));
438 memset((unsigned char *)&ctxt, 0, sizeof(ctxt));
439}
diff --git a/3rd_party/libsrp6a-sha512/t_pwd.h b/3rd_party/libsrp6a-sha512/t_pwd.h
new file mode 100644
index 0000000..a90a364
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_pwd.h
@@ -0,0 +1,246 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#ifndef T_PWD_H
31#define T_PWD_H
32
33#include <stdio.h>
34#include "cstr.h"
35
36#define MAXPARAMBITS 2048
37#define MAXPARAMLEN ((MAXPARAMBITS + 7) / 8)
38#define MAXB64PARAMLEN ((MAXPARAMBITS + 5) / 6 + 1)
39#define MAXHEXPARAMLEN ((MAXPARAMBITS + 3) / 4 + 1)
40#define MAXOCTPARAMLEN ((MAXPARAMBITS + 2) / 3 + 1)
41
42#define MAXUSERLEN 32
43#define MAXSALTLEN 32
44#define MAXB64SALTLEN 44 /* 256 bits in b64 + null */
45#define SALTLEN 10 /* Normally 80 bits */
46
47#define RESPONSE_LEN 20 /* 160-bit proof hashes */
48#define SESSION_KEY_LEN (2 * RESPONSE_LEN) /* 320-bit session key */
49
50#define DEFAULT_PASSWD "/etc/tpasswd"
51#define DEFAULT_CONF "/etc/tpasswd.conf"
52
53struct t_num { /* Standard byte-oriented integer representation */
54 int len;
55 unsigned char * data;
56};
57
58struct t_preconf { /* Structure returned by t_getpreparam() */
59 char * mod_b64;
60 char * gen_b64;
61 char * comment;
62
63 struct t_num modulus;
64 struct t_num generator;
65};
66
67/*
68 * The built-in (known good) parameters access routines
69 *
70 * "t_getprecount" returns the number of precompiled parameter sets.
71 * "t_getpreparam" returns the indicated parameter set.
72 * Memory is statically allocated - callers need not perform any memory mgmt.
73 */
74_TYPE( int ) t_getprecount();
75_TYPE( struct t_preconf * ) t_getpreparam P((int));
76
77struct t_confent { /* One configuration file entry (index, N, g) */
78 int index;
79 struct t_num modulus;
80 struct t_num generator;
81};
82
83struct t_conf { /* An open configuration file */
84 FILE * instream;
85 char close_on_exit;
86 cstr * modbuf;
87 cstr * genbuf;
88 struct t_confent tcbuf;
89};
90
91/*
92 * The configuration file routines are designed along the lines of the
93 * "getpw" functions in the standard C library.
94 *
95 * "t_openconf" accepts a stdio stream and interprets it as a config file.
96 * "t_openconfbyname" accepts a filename and does the same thing.
97 * "t_closeconf" closes the config file.
98 * "t_getconfent" fetches the next sequential configuration entry.
99 * "t_getconfbyindex" fetches the configuration entry whose index
100 * matches the one supplied, or NULL if one can't be found.
101 * "t_getconflast" fetches the last configuration entry in the file.
102 * "t_makeconfent" generates a set of configuration entry parameters
103 * randomly.
104 * "t_newconfent" returns an empty configuration entry.
105 * "t_cmpconfent" compares two configuration entries a la strcmp.
106 * "t_checkconfent" verifies that a set of configuration parameters
107 * are suitable. N must be prime and should be a safe prime.
108 * "t_putconfent" writes a configuration entry to a stream.
109 */
110_TYPE( struct t_conf * ) t_openconf P((FILE *));
111_TYPE( struct t_conf * ) t_openconfbyname P((const char *));
112_TYPE( void ) t_closeconf P((struct t_conf *));
113_TYPE( void ) t_rewindconf P((struct t_conf *));
114_TYPE( struct t_confent * ) t_getconfent P((struct t_conf *));
115_TYPE( struct t_confent * ) t_getconfbyindex P((struct t_conf *, int));
116_TYPE( struct t_confent * ) t_getconflast P((struct t_conf *));
117_TYPE( struct t_confent * ) t_makeconfent P((struct t_conf *, int));
118_TYPE( struct t_confent * ) t_makeconfent_c P((struct t_conf *, int));
119_TYPE( struct t_confent * ) t_newconfent P((struct t_conf *));
120_TYPE( int ) t_cmpconfent P((const struct t_confent *, const struct t_confent *));
121_TYPE( int ) t_checkconfent P((const struct t_confent *));
122_TYPE( void ) t_putconfent P((const struct t_confent *, FILE *));
123
124/* libc-style system conf file access */
125_TYPE( struct t_confent *) gettcent();
126_TYPE( struct t_confent *) gettcid P((int));
127_TYPE( void ) settcent();
128_TYPE( void ) endtcent();
129
130#ifdef ENABLE_NSW
131extern struct t_confent * _gettcent();
132extern struct t_confent * _gettcid P((int));
133extern void _settcent();
134extern void _endtcent();
135#endif
136
137/* A hack to support '+'-style entries in the passwd file */
138
139typedef enum fstate {
140 FILE_ONLY, /* Ordinary file, don't consult NIS ever */
141 FILE_NIS, /* Currently accessing file, use NIS if encountered */
142 IN_NIS, /* Currently in a '+' entry; use NIS for getXXent */
143} FILE_STATE;
144
145struct t_pwent { /* A single password file entry */
146 char * name;
147 struct t_num password;
148 struct t_num salt;
149 int index;
150};
151
152struct t_pw { /* An open password file */
153 FILE * instream;
154 char close_on_exit;
155 FILE_STATE state;
156 char userbuf[MAXUSERLEN];
157 cstr * pwbuf;
158 unsigned char saltbuf[SALTLEN];
159 struct t_pwent pebuf;
160};
161
162/*
163 * The password manipulation routines are patterned after the getpw*
164 * standard C library function calls.
165 *
166 * "t_openpw" reads a stream as if it were a password file.
167 * "t_openpwbyname" opens the named file as a password file.
168 * "t_closepw" closes an open password file.
169 * "t_rewindpw" starts the internal file pointer from the beginning
170 * of the password file.
171 * "t_getpwent" retrieves the next sequential password entry.
172 * "t_getpwbyname" looks up the password entry corresponding to the
173 * specified user.
174 * "t_makepwent" constructs a password entry from a username, password,
175 * numeric salt, and configuration entry.
176 * "t_putpwent" writes a password entry to a stream.
177 */
178_TYPE( struct t_pw * ) t_newpw();
179_TYPE( struct t_pw * ) t_openpw P((FILE *));
180_TYPE( struct t_pw * ) t_openpwbyname P((const char *));
181_TYPE( void ) t_closepw P((struct t_pw *));
182_TYPE( void ) t_rewindpw P((struct t_pw *));
183_TYPE( struct t_pwent * ) t_getpwent P((struct t_pw *));
184_TYPE( struct t_pwent * ) t_getpwbyname P((struct t_pw *, const char *));
185_TYPE( struct t_pwent * ) t_makepwent P((struct t_pw *, const char *,
186 const char *, const struct t_num *,
187 const struct t_confent *));
188_TYPE( void ) t_putpwent P((const struct t_pwent *, FILE *));
189
190struct t_passwd {
191 struct t_pwent tp;
192 struct t_confent tc;
193};
194
195/* libc-style system password file access */
196_TYPE( struct t_passwd * ) gettpent();
197_TYPE( struct t_passwd * ) gettpnam P((const char *));
198_TYPE( void ) settpent();
199_TYPE( void ) endtpent();
200
201#ifdef ENABLE_NSW
202extern struct t_passwd * _gettpent();
203extern struct t_passwd * _gettpnam P((const char *));
204extern void _settpent();
205extern void _endtpent();
206#endif
207
208/*
209 * Utility functions
210 *
211 * "t_verifypw" accepts a username and password, and checks against the
212 * system password file to see if the password for that user is correct.
213 * Returns > 0 if it is correct, 0 if not, and -1 if some error occurred
214 * (i.e. the user doesn't exist on the system). This is intended ONLY
215 * for local authentication; for remote authentication, look at the
216 * t_client and t_server source. (That's the whole point of SRP!)
217 * "t_changepw" modifies the specified file, substituting the given password
218 * entry for the one already in the file. If no matching entry is found,
219 * the new entry is simply appended to the file.
220 * "t_deletepw" removes the specified user from the specified file.
221 */
222_TYPE( int ) t_verifypw P((const char *, const char *));
223_TYPE( int ) t_changepw P((const char *, const struct t_pwent *));
224_TYPE( int ) t_deletepw P((const char *, const char *));
225
226/* Conversion utilities */
227
228/*
229 * All these calls accept output as the first parameter. In the case of
230 * t_tohex and t_tob64, the last argument is the length of the byte-string
231 * input.
232 */
233_TYPE( char * ) t_tohex P((char *, const char *, unsigned));
234_TYPE( int ) t_fromhex P((char *, const char *));
235_TYPE( char * ) t_tob64 P((char *, const char *, unsigned));
236_TYPE( int ) t_fromb64 P((char *, const char *));
237
238/* These functions put their output in a cstr object */
239_TYPE( char * ) t_tohexcstr P((cstr *, const char *, unsigned));
240_TYPE( int ) t_cstrfromhex P((cstr *, const char *));
241_TYPE( char * ) t_tob64cstr P((cstr *, const char *, unsigned));
242_TYPE( int ) t_cstrfromb64 P((cstr *, const char *));
243
244/* Miscellaneous utilities (moved to t_defines.h) */
245
246#endif
diff --git a/3rd_party/libsrp6a-sha512/t_sha.c b/3rd_party/libsrp6a-sha512/t_sha.c
new file mode 100644
index 0000000..8e54cb6
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_sha.c
@@ -0,0 +1,314 @@
1#include "t_defines.h"
2#include "t_sha.h"
3
4#ifdef CRYPTOLIB_SHA
5
6/* A wrapper around CryptoLib's shsFinal that delivers output in octets */
7void
8shsFinalBytes(unsigned char digest[20], SHS_CTX* context)
9{
10 int i;
11 unsigned long r;
12 unsigned char *p = digest;
13
14 shsFinal(context);
15 for(i = 0; i < 5; ++i) {
16 r = context->h[i];
17 *p++ = (unsigned char)((r >> 24) & 0xff);
18 *p++ = (unsigned char)((r >> 16) & 0xff);
19 *p++ = (unsigned char)((r >> 8) & 0xff);
20 *p++ = (unsigned char)(r & 0xff);
21 }
22}
23
24#elif defined(GCRYPT_SHA)
25/* Wrappers for gcrypt's md interface */
26
27void
28SHA1Init_gcry(SHA1_CTX * ctx)
29{
30 gcry_md_open(ctx, GCRY_MD_SHA1, 0);
31}
32
33void
34SHA1Update_gcry(SHA1_CTX * ctx, const void *data, unsigned int len)
35{
36 gcry_md_write(*ctx, data, len);
37}
38
39void
40SHA1Final_gcry(unsigned char digest[20], SHA1_CTX * ctx)
41{
42 memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA1), 20);
43 gcry_md_close(*ctx);
44}
45
46void
47SHA512Init_gcry(SHA512_CTX * ctx)
48{
49 gcry_md_open(ctx, GCRY_MD_SHA512, 0);
50}
51
52void
53SHA512Update_gcry(SHA512_CTX * ctx, const void *data, unsigned int len)
54{
55 gcry_md_write(*ctx, data, len);
56}
57
58void
59SHA512Final_gcry(unsigned char digest[64], SHA512_CTX * ctx)
60{
61 memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA512), 64);
62 gcry_md_close(*ctx);
63}
64
65#elif defined(MBEDTLS_SHA)
66/* Wrappers for mbedtls's md interface */
67
68void
69SHA1Init_mbed(SHA1_CTX * ctx)
70{
71 mbedtls_md_init(ctx);
72 mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 0);
73 mbedtls_md_starts(ctx);
74}
75
76void
77SHA1Update_mbed(SHA1_CTX * ctx, const void *data, unsigned int len)
78{
79 mbedtls_md_update(ctx, data, len);
80}
81
82void
83SHA1Final_mbed(unsigned char digest[20], SHA1_CTX * ctx)
84{
85 mbedtls_md_finish(ctx, digest);
86 mbedtls_md_free(ctx);
87}
88
89void
90SHA512Init_mbed(SHA512_CTX * ctx)
91{
92 mbedtls_md_init(ctx);
93 mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), 0);
94 mbedtls_md_starts(ctx);
95}
96
97void
98SHA512Update_mbed(SHA512_CTX * ctx, const void *data, unsigned int len)
99{
100 mbedtls_md_update(ctx, data, len);
101}
102
103void
104SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx)
105{
106 mbedtls_md_finish(ctx, digest);
107 mbedtls_md_free(ctx);
108}
109
110#elif defined(OPENSSL_SHA)
111#if OPENSSL_VERSION_NUMBER >= 0x30000000L
112void
113SHA1Init_openssl(SHA1_CTX *ctx)
114{
115 *ctx = EVP_MD_CTX_new();
116 EVP_DigestInit(*ctx, EVP_sha1());
117}
118
119void SHA1Update_openssl(SHA1_CTX *ctx, const void *data, unsigned int len)
120{
121 EVP_DigestUpdate(*ctx, data, (size_t)len);
122}
123
124void SHA1Final_openssl(unsigned char digest[20], SHA1_CTX *ctx)
125{
126 EVP_DigestFinal(*ctx, digest, NULL);
127 EVP_MD_CTX_destroy(*ctx);
128}
129
130void
131SHA512Init_openssl(SHA512_CTX *ctx)
132{
133 *ctx = EVP_MD_CTX_new();
134 EVP_DigestInit(*ctx, EVP_sha512());
135}
136
137void SHA512Update_openssl(SHA512_CTX *ctx, const void *data, unsigned int len)
138{
139 EVP_DigestUpdate(*ctx, data, (size_t)len);
140}
141
142void SHA512Final_openssl(unsigned char digest[64], SHA512_CTX *ctx)
143{
144 EVP_DigestFinal(*ctx, digest, NULL);
145 EVP_MD_CTX_destroy(*ctx);
146}
147#endif
148#elif !defined(OPENSSL_SHA) && !defined(TOMCRYPT_SHA)
149/* Use the free SHA1 if the library doesn't have it */
150
151/*
152SHA-1 in C
153By Steve Reid <steve@edmweb.com>
154100% Public Domain
155
156Test Vectors (from FIPS PUB 180-1)
157"abc"
158 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
159"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
160 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
161A million repetitions of "a"
162 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
163*/
164
165/* #define LITTLE_ENDIAN * This should be #define'd if true. */
166/* #define SHA1HANDSOFF * Copies data before messing with it. */
167
168#include <stdio.h>
169#include <string.h>
170
171static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]);
172
173#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
174
175/* blk0() and blk() perform the initial expand. */
176/* I got the idea of expanding during the round function from SSLeay */
177#ifndef WORDS_BIGENDIAN
178#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
179 |(rol(block->l[i],8)&0x00FF00FF))
180#else
181#define blk0(i) block->l[i]
182#endif
183#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
184 ^block->l[(i+2)&15]^block->l[i&15],1))
185
186/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
187#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
188#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
189#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
190#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
191#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
192
193/* Hash a single 512-bit block. This is the core of the algorithm. */
194
195static void SHA1Transform(uint32 state[5], const unsigned char buffer[64])
196{
197uint32 a, b, c, d, e;
198typedef union {
199 unsigned char c[64];
200 uint32 l[16];
201} CHAR64LONG16;
202CHAR64LONG16* block;
203#ifdef SHA1HANDSOFF
204static unsigned char workspace[64];
205 block = (CHAR64LONG16*)workspace;
206 memcpy(block, buffer, 64);
207#else
208 block = (CHAR64LONG16*)buffer;
209#endif
210 /* Copy context->state[] to working vars */
211 a = state[0];
212 b = state[1];
213 c = state[2];
214 d = state[3];
215 e = state[4];
216 /* 4 rounds of 20 operations each. Loop unrolled. */
217 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
218 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
219 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
220 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
221 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
222 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
223 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
224 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
225 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
226 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
227 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
228 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
229 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
230 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
231 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
232 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
233 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
234 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
235 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
236 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
237 /* Add the working vars back into context.state[] */
238 state[0] += a;
239 state[1] += b;
240 state[2] += c;
241 state[3] += d;
242 state[4] += e;
243 /* Wipe variables */
244 a = b = c = d = e = 0;
245}
246
247
248/* SHA1Init - Initialize new context */
249
250void SHA1Init(SHA1_CTX* context)
251{
252 /* SHA1 initialization constants */
253 context->state[0] = 0x67452301;
254 context->state[1] = 0xEFCDAB89;
255 context->state[2] = 0x98BADCFE;
256 context->state[3] = 0x10325476;
257 context->state[4] = 0xC3D2E1F0;
258 context->count[0] = context->count[1] = 0;
259}
260
261
262/* Run your data through this. */
263
264void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
265{
266unsigned int i, j;
267
268 j = (context->count[0] >> 3) & 63;
269 if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
270 context->count[1] += (len >> 29);
271 if ((j + len) > 63) {
272 memcpy(&context->buffer[j], data, (i = 64-j));
273 SHA1Transform(context->state, context->buffer);
274 for ( ; i + 63 < len; i += 64) {
275 SHA1Transform(context->state, &data[i]);
276 }
277 j = 0;
278 }
279 else i = 0;
280 memcpy(&context->buffer[j], &data[i], len - i);
281}
282
283
284/* Add padding and return the message digest. */
285
286void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
287{
288uint32 i, j;
289unsigned char finalcount[8];
290
291 for (i = 0; i < 8; i++) {
292 finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
293 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
294 }
295 SHA1Update(context, (unsigned char *)"\200", 1);
296 while ((context->count[0] & 504) != 448) {
297 SHA1Update(context, (unsigned char *)"\0", 1);
298 }
299 SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
300 for (i = 0; i < 20; i++) {
301 digest[i] = (unsigned char)
302 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
303 }
304 /* Wipe variables */
305 i = j = 0;
306 memset(context->buffer, 0, 64);
307 memset(context->state, 0, 20);
308 memset(context->count, 0, 8);
309 memset(&finalcount, 0, 8);
310#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
311 SHA1Transform(context->state, context->buffer);
312#endif
313}
314#endif
diff --git a/3rd_party/libsrp6a-sha512/t_sha.h b/3rd_party/libsrp6a-sha512/t_sha.h
new file mode 100644
index 0000000..2e38067
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_sha.h
@@ -0,0 +1,147 @@
1#ifndef T_SHA_H
2#define T_SHA_H
3
4#if !defined(P)
5#ifdef __STDC__
6#define P(x) x
7#else
8#define P(x) ()
9#endif
10#endif
11
12#define SHA_DIGESTSIZE 20
13
14#ifdef OPENSSL
15#define OPENSSL_SHA 1
16#endif
17
18#ifdef TOMCRYPT
19# include <tomcrypt.h>
20# ifdef SHA1
21# define TOMCRYPT_SHA 1
22# endif
23#endif
24
25#ifdef CRYPTOLIB
26/* The SHA (shs) implementation in CryptoLib 1.x breaks when Update
27 * is called multiple times, so we still use our own code.
28 * Uncomment below if you think your copy of CryptoLib is fixed. */
29/*#define CRYPTOLIB_SHA 1*/
30#endif
31
32#ifdef GCRYPT
33# define GCRYPT_SHA 1
34#endif
35
36#ifdef MBEDTLS
37# define MBEDTLS_SHA 1
38#endif
39
40#ifdef OPENSSL_SHA
41#include <openssl/err.h>
42#if OPENSSL_VERSION_NUMBER >= 0x30000000L
43#include <openssl/evp.h>
44
45typedef EVP_MD_CTX* SHA1_CTX;
46#define SHA1Init SHA1Init_openssl
47#define SHA1Update SHA1Update_openssl
48#define SHA1Final SHA1Final_openssl
49
50typedef EVP_MD_CTX* SHA512_CTX;
51#define SHA512Init SHA512Init_openssl
52#define SHA512Update SHA512Update_openssl
53#define SHA512Final SHA512Final_openssl
54
55void SHA1Init_openssl(SHA1_CTX *ctx);
56void SHA1Update_openssl(SHA1_CTX *ctx, const void *data, unsigned int len);
57void SHA1Final_openssl(unsigned char digest[20], SHA1_CTX *ctx);
58
59void SHA512Init_openssl(SHA512_CTX *ctx);
60void SHA512Update_openssl(SHA512_CTX *ctx, const void *data, unsigned int len);
61void SHA512Final_openssl(unsigned char digest[64], SHA1_CTX *ctx);
62#else /* for OpenSSL < 3.0 */
63#include <openssl/sha.h>
64
65typedef SHA_CTX SHA1_CTX;
66#define SHA1Init SHA1_Init
67#define SHA1Update SHA1_Update
68#define SHA1Final SHA1_Final
69
70#define SHA512Init SHA512_Init
71#define SHA512Update SHA512_Update
72#define SHA512Final SHA512_Final
73#endif /* for OpenSSL < 3.0 */
74#elif defined(TOMCRYPT_SHA)
75/* mycrypt.h already included above */
76
77typedef hash_state SHA1_CTX;
78#define SHA1Init sha1_init
79#define SHA1Update sha1_process
80#define SHA1Final(D,C) sha1_done(C,D)
81
82#elif defined(GCRYPT_SHA)
83#include "gcrypt.h"
84
85typedef gcry_md_hd_t SHA1_CTX;
86#define SHA1Init SHA1Init_gcry
87#define SHA1Update SHA1Update_gcry
88#define SHA1Final SHA1Final_gcry
89typedef gcry_md_hd_t SHA512_CTX;
90#define SHA512Init SHA512Init_gcry
91#define SHA512Update SHA512Update_gcry
92#define SHA512Final SHA512Final_gcry
93
94void SHA1Init_gcry(SHA1_CTX * ctx);
95void SHA1Update_gcry(SHA1_CTX * ctx, const void *data, unsigned int len);
96void SHA1Final_gcry(unsigned char digest[20], SHA1_CTX * ctx);
97
98void SHA512Init_gcry(SHA512_CTX * ctx);
99void SHA512Update_gcry(SHA512_CTX * ctx, const void *data, unsigned int len);
100void SHA512Final_gcry(unsigned char digest[64], SHA512_CTX * ctx);
101
102#elif defined(MBEDTLS_SHA)
103#include <mbedtls/md.h>
104
105typedef mbedtls_md_context_t SHA1_CTX;
106#define SHA1Init SHA1Init_mbed
107#define SHA1Update SHA1Update_mbed
108#define SHA1Final SHA1Final_mbed
109
110typedef mbedtls_md_context_t SHA512_CTX;
111#define SHA512Init SHA512Init_mbed
112#define SHA512Update SHA512Update_mbed
113#define SHA512Final SHA512Final_mbed
114
115void SHA1Init_mbed(SHA1_CTX * ctx);
116void SHA1Update_mbed(SHA1_CTX * ctx, const void *data, unsigned int len);
117void SHA1Final_mbed(unsigned char digest[20], SHA1_CTX * ctx);
118
119void SHA512Init_mbed(SHA512_CTX * ctx);
120void SHA512Update_mbed(SHA512_CTX * ctx, const void *data, unsigned int len);
121void SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx);
122
123#elif defined(CRYPTOLIB_SHA)
124#include "libcrypt.h"
125
126typedef SHS_CTX SHA1_CTX;
127#define SHA1Init shsInit
128#define SHA1Update shsUpdate
129#define SHA1Final shsFinalBytes
130
131void shsFinalBytes P((unsigned char digest[20], SHS_CTX* context));
132
133#else
134typedef unsigned int uint32;
135
136typedef struct {
137 uint32 state[5];
138 uint32 count[2];
139 unsigned char buffer[64];
140} SHA1_CTX;
141
142void SHA1Init P((SHA1_CTX* context));
143void SHA1Update P((SHA1_CTX* context, const unsigned char* data, unsigned int len));
144void SHA1Final P((unsigned char digest[20], SHA1_CTX* context));
145#endif /* !OPENSSL && !CRYPTOLIB */
146
147#endif /* T_SHA_H */
diff --git a/3rd_party/libsrp6a-sha512/t_truerand.c b/3rd_party/libsrp6a-sha512/t_truerand.c
new file mode 100644
index 0000000..f995ed7
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_truerand.c
@@ -0,0 +1,241 @@
1/*
2 * Physically random numbers (very nearly uniform)
3 * D. P. Mitchell
4 * Modified by Matt Blaze 7/95
5 */
6/*
7 * The authors of this software are Don Mitchell and Matt Blaze.
8 * Copyright (c) 1995 by AT&T.
9 * Permission to use, copy, and modify this software without fee
10 * is hereby granted, provided that this entire notice is included in
11 * all copies of any software which is or includes a copy or
12 * modification of this software and in all copies of the supporting
13 * documentation for such software.
14 *
15 * This software may be subject to United States export controls.
16 *
17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
20 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
21 */
22
23/*
24 * WARNING: depending on the particular platform, raw_truerand()
25 * output may be biased or correlated. In general, you can expect
26 * about 16 bits of "pseudo-entropy" out of each 32 bit word returned
27 * by truerand(), but it may not be uniformly diffused. You should
28 * raw_therefore run the output through some post-whitening function
29 * (like MD5 or DES or whatever) before using it to generate key
30 * material. (RSAREF's random package does this for you when you feed
31 * raw_truerand() bits to the seed input function.)
32 *
33 * The application interface, for 8, 16, and 32 bit properly "whitened"
34 * random numbers, can be found in trand8(), trand16(), and trand32().
35 * Use those instead of calling raw_truerand() directly.
36 *
37 * The basic idea here is that between clock "skew" and various
38 * hard-to-predict OS event arrivals, counting a tight loop will yield
39 * a little (maybe a third of a bit or so) of "good" randomness per
40 * interval clock tick. This seems to work well even on unloaded
41 * machines. If there is a human operator at the machine, you should
42 * augment truerand with other measure, like keyboard event timing.
43 * On server machines (e.g., when you need to generate a
44 * Diffie-Hellman secret) truerand alone may be good enough.
45 *
46 * Test these assumptions on your own platform before fielding a
47 * system based on this software or these techniques.
48 *
49 * This software seems to work well (at 10 or so bits per
50 * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
51 * P100 under BSDI 2.0. You're on your own elsewhere.
52 *
53 */
54
55#include "t_defines.h"
56
57#ifdef WIN32
58
59# ifdef CRYPTOLIB
60
61/* Cryptolib contains its own truerand() on both UNIX and Windows. */
62/* Only use cryptolib's truerand under Windows */
63
64# include "libcrypt.h"
65
66unsigned long
67raw_truerand()
68{
69 return truerand();
70}
71
72# else /* !CRYPTOLIB && WIN32 */
73
74#include <windows.h>
75#include <wtypes.h>
76#include <winbase.h>
77#include <windef.h>
78#include <winnt.h>
79#include <winuser.h>
80#include <process.h>
81
82volatile unsigned long count, ocount, randbuf;
83volatile int dontstop;
84char outbuf[1024], *bufp;
85
86static void counter() {
87 while (dontstop)
88 count++;
89 _endthread();
90}
91
92
93static unsigned long roulette() {
94 unsigned long thread;
95
96 count = 0;
97 dontstop= 1;
98 while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0)
99 ;
100
101 Sleep(16);
102 dontstop = 0;
103 Sleep(1);
104
105 count ^= (count>>3) ^ (count>>6) ^ (ocount);
106 count &= 0x7;
107 ocount = count;
108 randbuf = (randbuf<<3) ^ count;
109 return randbuf;
110}
111
112
113unsigned long
114raw_truerand() {
115
116 roulette();
117 roulette();
118 roulette();
119 roulette();
120 roulette();
121 roulette();
122 roulette();
123 roulette();
124 roulette();
125 roulette();
126 return roulette();
127}
128
129# endif /* CRYPTOLIB */
130
131#else /* !WIN32 */
132
133#include <signal.h>
134#include <setjmp.h>
135#include <sys/time.h>
136#include <math.h>
137#include <stdio.h>
138
139#ifdef OLD_TRUERAND
140static jmp_buf env;
141#endif
142static unsigned volatile count
143#ifndef OLD_TRUERAND
144 , done = 0
145#endif
146;
147
148static unsigned ocount;
149static unsigned buffer;
150
151static void
152tick()
153{
154 struct itimerval it, oit;
155
156 it.it_interval.tv_sec = 0;
157 it.it_interval.tv_usec = 0;
158 it.it_value.tv_sec = 0;
159 it.it_value.tv_usec = 16665;
160 if (setitimer(ITIMER_REAL, &it, &oit) < 0)
161 perror("tick");
162}
163
164static void
165interrupt()
166{
167 if (count) {
168#ifdef OLD_TRUERAND
169 longjmp(env, 1);
170#else
171 ++done;
172 return;
173#endif
174 }
175
176 (void) signal(SIGALRM, interrupt);
177 tick();
178}
179
180static unsigned long
181roulette()
182{
183#ifdef OLD_TRUERAND
184 if (setjmp(env)) {
185 count ^= (count>>3) ^ (count>>6) ^ ocount;
186 count &= 0x7;
187 ocount=count;
188 buffer = (buffer<<3) ^ count;
189 return buffer;
190 }
191#else
192 done = 0;
193#endif
194 (void) signal(SIGALRM, interrupt);
195 count = 0;
196 tick();
197#ifdef OLD_TRUERAND
198 for (;;)
199#else
200 while(done == 0)
201#endif
202 count++; /* about 1 MHz on VAX 11/780 */
203#ifndef OLD_TRUERAND
204 count ^= (count>>3) ^ (count>>6) ^ ocount;
205 count &= 0x7;
206 ocount=count;
207 buffer = (buffer<<3) ^ count;
208 return buffer;
209#endif
210}
211
212unsigned long
213raw_truerand()
214{
215 count=0;
216 (void) roulette();
217 (void) roulette();
218 (void) roulette();
219 (void) roulette();
220 (void) roulette();
221 (void) roulette();
222 (void) roulette();
223 (void) roulette();
224 (void) roulette();
225 (void) roulette();
226 return roulette();
227}
228
229int
230raw_n_truerand(int n)
231{
232 int slop, v;
233
234 slop = 0x7FFFFFFF % n;
235 do {
236 v = raw_truerand() >> 1;
237 } while (v <= slop);
238 return v % n;
239}
240
241#endif /* !CRYPTOLIB || !WIN32 */