summaryrefslogtreecommitdiffstats
path: root/3rd_party/libsrp6a-sha512
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2022-02-09 04:04:36 +0100
committerGravatar Nikias Bassen2022-02-09 04:04:36 +0100
commite41dbc3ddbe30a414e73fa25d9c7c304ffe6989e (patch)
tree599c99a2f32bc18f1e9ebc740d0a12d71c49bb10 /3rd_party/libsrp6a-sha512
parentee9104bcb8d494b579e122a2dcc94a2b79d38e4b (diff)
downloadlibimobiledevice-e41dbc3ddbe30a414e73fa25d9c7c304ffe6989e.tar.gz
libimobiledevice-e41dbc3ddbe30a414e73fa25d9c7c304ffe6989e.tar.bz2
Add support for wireless pairing
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.c258
-rw-r--r--3rd_party/libsrp6a-sha512/t_defines.h137
-rw-r--r--3rd_party/libsrp6a-sha512/t_math.c1008
-rw-r--r--3rd_party/libsrp6a-sha512/t_misc.c450
-rw-r--r--3rd_party/libsrp6a-sha512/t_pwd.h246
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.c276
-rw-r--r--3rd_party/libsrp6a-sha512/t_sha.h125
-rw-r--r--3rd_party/libsrp6a-sha512/t_truerand.c241
17 files changed, 4344 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..8c6e2f5
--- /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
8include_HEADERS = srp.h srp_aux.h cstr.h
9
10AM_CFLAGS = -DHAVE_CONFIG_H
11if HAVE_OPENSSL
12AM_CFLAGS += -DOPENSSL=1 -DOPENSSL_ENGINE=1 $(openssl_CFLAGS)
13else
14if HAVE_GCRYPT
15AM_CFLAGS += -DGCRYPT=1 $(libgcrypt_CFLAGS)
16else
17if HAVE_MBEDTLS
18AM_CFLAGS += -DMBEDTLS=1 $(mbedtls_CFLAGS)
19endif
20endif
21endif
22
23noinst_LTLIBRARIES = libsrp6a-sha512.la
24
25libsrp6a_sha512_la_SOURCES = \
26 t_conv.c t_math.c t_misc.c \
27 t_truerand.c cstr.c \
28 srp.c srp6a_sha512_client.c
29if !HAVE_OPENSSL
30libsrp6a_sha512_la_SOURCES += t_sha.c
31endif
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..f7f50e2
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_conv.c
@@ -0,0 +1,258 @@
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(c)
37 char c;
38{
39 if(c >= '0' && c <= '9')
40 return c - '0';
41 else if(c >= 'a' && c <= 'f')
42 return c - 'a' + 10;
43 else if(c >= 'A' && c <= 'F')
44 return c - 'A' + 10;
45 else
46 return 0;
47}
48
49/*
50 * Convert a hex string to a string of bytes; return size of dst
51 */
52_TYPE( int )
53t_fromhex(dst, src)
54 char * dst;
55 const char * src;
56{
57 register char *chp = dst;
58 register unsigned size = strlen(src);
59
60 /* FIXME: handle whitespace and non-hex digits by setting size and src
61 appropriately. */
62
63 if(size % 2 == 1) {
64 *chp++ = hexDigitToInt(*src++);
65 --size;
66 }
67 while(size > 0) {
68 *chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
69 src += 2;
70 size -= 2;
71 }
72 return chp - dst;
73}
74
75/*
76 * Convert a string of bytes to their hex representation
77 */
78_TYPE( char * )
79t_tohex(dst, src, size)
80 char * dst;
81 const char * src;
82 unsigned size;
83{
84 int notleading = 0;
85
86 register char *chp = dst;
87 *dst = '\0';
88 if (size != 0) do {
89 if(notleading || *src != '\0') {
90 if(!notleading && (*src & 0xf0) == 0) {
91 sprintf(chp, "%.1X", * (unsigned char *) src);
92 chp += 1;
93 }
94 else {
95 sprintf(chp, "%.2X", * (unsigned char *) src);
96 chp += 2;
97 }
98 notleading = 1;
99 }
100 ++src;
101 } while (--size != 0);
102 return dst;
103}
104
105_TYPE( char * )
106t_tohexcstr(dst, src, size)
107 cstr * dst;
108 const char * src;
109 unsigned size;
110{
111 cstr_set_length(dst, 2 * size + 1);
112 return t_tohex(dst->data, src, size);
113}
114
115static char b64table[] =
116 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
117
118/*
119 * Convert a base64 string into raw byte array representation.
120 */
121_TYPE( int )
122t_fromb64(dst, src)
123 char * dst;
124 const char * src;
125{
126 unsigned char *a;
127 char *loc;
128 int i, j;
129 unsigned int size;
130
131 while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
132 ++src;
133 size = strlen(src);
134
135 a = malloc((size + 1) * sizeof(unsigned char));
136 if(a == (unsigned char *) 0)
137 return -1;
138
139 i = 0;
140 while(i < size) {
141 loc = strchr(b64table, src[i]);
142 if(loc == (char *) 0)
143 break;
144 else
145 a[i] = loc - b64table;
146 ++i;
147 }
148 size = i;
149
150 i = size - 1;
151 j = size;
152 while(1) {
153 a[j] = a[i];
154 if(--i < 0)
155 break;
156 a[j] |= (a[i] & 3) << 6;
157 --j;
158 a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
159 if(--i < 0)
160 break;
161 a[j] |= (a[i] & 0xf) << 4;
162 --j;
163 a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
164 if(--i < 0)
165 break;
166 a[j] |= (a[i] << 2);
167
168 a[--j] = 0;
169 if(--i < 0)
170 break;
171 }
172
173 while(a[j] == 0 && j <= size)
174 ++j;
175
176 memcpy(dst, a + j, size - j + 1);
177 free(a);
178 return size - j + 1;
179}
180
181_TYPE( int )
182t_cstrfromb64(dst, src)
183 cstr * dst;
184 const char * src;
185{
186 int len;
187 cstr_set_length(dst, (strlen(src) * 6 + 7) / 8);
188 len = t_fromb64(dst->data, src);
189 cstr_set_length(dst, len);
190 return len;
191}
192
193/*
194 * Convert a raw byte string into a null-terminated base64 ASCII string.
195 */
196_TYPE( char * )
197t_tob64(dst, src, size)
198 char * dst;
199 const char * src;
200 unsigned size;
201{
202 int c, pos = size % 3;
203 unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
204 char *olddst = dst;
205
206 switch(pos) {
207 case 1:
208 b2 = src[0];
209 break;
210 case 2:
211 b1 = src[0];
212 b2 = src[1];
213 break;
214 }
215
216 while(1) {
217 c = (b0 & 0xfc) >> 2;
218 if(notleading || c != 0) {
219 *dst++ = b64table[c];
220 notleading = 1;
221 }
222 c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
223 if(notleading || c != 0) {
224 *dst++ = b64table[c];
225 notleading = 1;
226 }
227 c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
228 if(notleading || c != 0) {
229 *dst++ = b64table[c];
230 notleading = 1;
231 }
232 c = b2 & 0x3f;
233 if(notleading || c != 0) {
234 *dst++ = b64table[c];
235 notleading = 1;
236 }
237 if(pos >= size)
238 break;
239 else {
240 b0 = src[pos++];
241 b1 = src[pos++];
242 b2 = src[pos++];
243 }
244 }
245
246 *dst++ = '\0';
247 return olddst;
248}
249
250_TYPE( char * )
251t_tob64cstr(dst, src, sz)
252 cstr * dst;
253 const char * src;
254 unsigned int sz;
255{
256 cstr_set_length(dst, (sz * 8 + 5) / 6 + 1);
257 return t_tob64(dst->data, src, sz);
258}
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..88ae12f
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_math.c
@@ -0,0 +1,1008 @@
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# ifdef OPENSSL_ENGINE
43# include "openssl/engine.h"
44static ENGINE * default_engine = NULL;
45# endif /* OPENSSL_ENGINE */
46typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
47 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx);
48static modexp_meth default_modexp = NULL;
49#elif defined(CRYPTOLIB)
50# include "libcrypt.h"
51typedef BigInt BigInteger;
52typedef void * BigIntegerCtx;
53typedef void * BigIntegerModAccel;
54#elif defined(GNU_MP)
55# include "gmp.h"
56typedef MP_INT * BigInteger;
57typedef void * BigIntegerCtx;
58typedef void * BigIntegerModAccel;
59# if __GNU_MP_VERSION >= 4 || (__GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1)
60/* GMP 4.1 and up has fast import/export routines for integer conversion */
61# define GMP_IMPEXP 1
62# endif
63#elif defined(TOMMATH)
64# ifdef TOMCRYPT
65 /* as of v0.96 */
66# include "ltc_tommath.h"
67# else
68# include "tommath.h"
69# endif
70typedef mp_int * BigInteger;
71typedef void * BigIntegerCtx;
72typedef void * BigIntegerModAccel;
73#elif defined(GCRYPT)
74# include "gcrypt.h"
75typedef gcry_mpi_t BigInteger;
76typedef void * BigIntegerCtx;
77typedef void * BigIntegerModAccel;
78#elif defined(MPI)
79# include "mpi.h"
80typedef mp_int * BigInteger;
81typedef void * BigIntegerCtx;
82typedef void * BigIntegerModAccel;
83#elif defined(MBEDTLS)
84#include <mbedtls/bignum.h>
85#include <mbedtls/error.h>
86typedef mbedtls_mpi* BigInteger;
87typedef void * BigIntegerCtx;
88typedef void * BigIntegerModAccel;
89#else
90# error "no math library specified"
91#endif
92#define MATH_PRIV
93
94#include "t_defines.h"
95#include "t_pwd.h"
96#include "srp_aux.h"
97
98/* Math library interface stubs */
99
100BigInteger
101BigIntegerFromInt(n)
102 unsigned int n;
103{
104#ifdef OPENSSL
105 BIGNUM * a = BN_new();
106 if(a)
107 BN_set_word(a, n);
108 return a;
109#elif defined(CRYPTOLIB)
110 return bigInit(n);
111#elif defined(GNU_MP)
112 BigInteger rv = (BigInteger) malloc(sizeof(MP_INT));
113 if(rv)
114 mpz_init_set_ui(rv, n);
115 return rv;
116#elif defined(GCRYPT)
117 BigInteger rv = gcry_mpi_new(32);
118 gcry_mpi_set_ui(rv, n);
119 return rv;
120#elif defined(MPI) || defined(TOMMATH)
121 BigInteger rv = (BigInteger) malloc(sizeof(mp_int));
122 if(rv) {
123 mp_init(rv);
124 mp_set_int(rv, n);
125 }
126 return rv;
127#elif defined(MBEDTLS)
128 mbedtls_mpi* a = (mbedtls_mpi*)malloc(sizeof(mbedtls_mpi));
129 if (a) {
130 mbedtls_mpi_init(a);
131 mbedtls_mpi_lset(a, n);
132 }
133 return a;
134#endif
135}
136
137BigInteger
138BigIntegerFromBytes(bytes, length)
139 const unsigned char * bytes;
140 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(src, dest, destlen)
209 BigInteger src;
210 unsigned char * dest;
211 int destlen;
212{
213#ifdef OPENSSL
214 return BN_bn2bin(src, dest);
215#elif defined(CRYPTOLIB)
216 int i, j;
217 cstr * rawbuf;
218
219 trim(src);
220 i = bigBytes(src);
221 j = (bigBits(src) + 7) / 8;
222 if(i == j)
223 RSA_bigToBuf(src, i, dest);
224 else { /* Wouldn't need this if cryptolib behaved better */
225 rawbuf = cstr_new();
226 cstr_set_length(rawbuf, i);
227 RSA_bigToBuf(src, i, rawbuf->data);
228 memcpy(dest, rawbuf->data + (i-j), j);
229 cstr_clear_free(rawbuf);
230 }
231 return j;
232#elif defined(GNU_MP)
233 size_t r = 0;
234# ifdef GMP_IMPEXP
235 mpz_export(dest, &r, 1, 1, 1, 0, src);
236# else
237 cstr * hexbuf = cstr_new();
238
239 if(hexbuf) {
240 cstr_set_length(hexbuf, mpz_sizeinbase(src, 16) + 1);
241 mpz_get_str(hexbuf->data, 16, src);
242 r = t_fromhex(dest, hexbuf->data);
243 cstr_clear_free(hexbuf);
244 }
245# endif
246 return r;
247#elif defined(GCRYPT)
248 size_t r = 0;
249 gcry_mpi_print(GCRYMPI_FMT_USG, dest, destlen, &r, src);
250 return r;
251#elif defined(MPI) || defined(TOMMATH)
252 mp_to_unsigned_bin(src, dest);
253 return mp_unsigned_bin_size(src);
254#elif defined(MBEDTLS)
255 size_t r = mbedtls_mpi_size(src);
256 mbedtls_mpi_write_binary(src, dest, r);
257 return r;
258#endif
259}
260
261BigIntegerResult
262BigIntegerToCstr(BigInteger x, cstr * out)
263{
264 int n = BigIntegerByteLen(x);
265 if(cstr_set_length(out, n) < 0)
266 return BIG_INTEGER_ERROR;
267 if(cstr_set_length(out, BigIntegerToBytes(x, (unsigned char*)out->data, n)) < 0)
268 return BIG_INTEGER_ERROR;
269 return BIG_INTEGER_SUCCESS;
270}
271
272BigIntegerResult
273BigIntegerToCstrEx(BigInteger x, cstr * out, int len)
274{
275 int n;
276 if(cstr_set_length(out, len) < 0)
277 return BIG_INTEGER_ERROR;
278#if defined(MBEDTLS)
279 /* mbedtls will prefix the output with zeros if the buffer is larger */
280 mbedtls_mpi_write_binary(x, (unsigned char*)out->data, len);
281#else
282 n = BigIntegerToBytes(x, (unsigned char*)out->data, len);
283 if(n < len) {
284 memmove(out->data + (len - n), out->data, n);
285 memset(out->data, 0, len - n);
286 }
287#endif
288 return BIG_INTEGER_SUCCESS;
289}
290
291BigIntegerResult
292BigIntegerToHex(src, dest, destlen)
293 BigInteger src;
294 char * dest;
295 int destlen;
296{
297#ifdef OPENSSL
298 strncpy(dest, BN_bn2hex(src), destlen);
299#elif defined(CRYPTOLIB)
300 trim(src);
301 bigsprint(src, dest);
302#elif defined(GNU_MP)
303 mpz_get_str(dest, 16, src);
304#elif defined(GCRYPT)
305 gcry_mpi_print(GCRYMPI_FMT_HEX, dest, destlen, NULL, src);
306#elif defined(MPI) || defined(TOMMATH)
307 mp_toradix(src, dest, 16);
308#elif defined(MBEDTLS)
309 size_t olen = 0;
310 mbedtls_mpi_write_string(src, 16, dest, destlen, &olen);
311#endif
312 return BIG_INTEGER_SUCCESS;
313}
314
315static char b64table[] =
316 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
317
318BigIntegerResult
319BigIntegerToString(src, dest, destlen, radix)
320 BigInteger src;
321 char * dest;
322 int destlen;
323 unsigned int radix;
324{
325 BigInteger t = BigIntegerFromInt(0);
326 char * p = dest;
327 char c;
328
329 *p++ = b64table[BigIntegerModInt(src, radix, NULL)];
330 BigIntegerDivInt(t, src, radix, NULL);
331 while(BigIntegerCmpInt(t, 0) > 0) {
332 *p++ = b64table[BigIntegerModInt(t, radix, NULL)];
333 BigIntegerDivInt(t, t, radix, NULL);
334 }
335 BigIntegerFree(t);
336 *p-- = '\0';
337 /* reverse the string */
338 while(p > dest) {
339 c = *p;
340 *p-- = *dest;
341 *dest++ = c;
342 }
343 return BIG_INTEGER_SUCCESS;
344}
345
346int
347BigIntegerBitLen(b)
348 BigInteger b;
349{
350#ifdef OPENSSL
351 return BN_num_bits(b);
352#elif defined(CRYPTOLIB)
353 return bigBits(b);
354#elif defined(GNU_MP)
355 return mpz_sizeinbase(b, 2);
356#elif defined(GCRYPT)
357 return gcry_mpi_get_nbits(b);
358#elif defined(MPI) || defined(TOMMATH)
359 return mp_count_bits(b);
360#elif defined(MBEDTLS)
361 return (int)mbedtls_mpi_bitlen(b);
362#endif
363}
364
365int
366BigIntegerCmp(c1, c2)
367 BigInteger c1, c2;
368{
369#ifdef OPENSSL
370 return BN_cmp(c1, c2);
371#elif defined(CRYPTOLIB)
372 return bigCompare(c1, c2);
373#elif defined(GNU_MP)
374 return mpz_cmp(c1, c2);
375#elif defined(GCRYPT)
376 return gcry_mpi_cmp(c1, c2);
377#elif defined(MPI) || defined(TOMMATH)
378 return mp_cmp(c1, c2);
379#elif defined(MBEDTLS)
380 return mbedtls_mpi_cmp_mpi(c1, c2);
381#endif
382}
383
384int
385BigIntegerCmpInt(c1, c2)
386 BigInteger c1;
387 unsigned int c2;
388{
389#ifdef OPENSSL
390 BigInteger bc2 = BigIntegerFromInt(c2);
391 int rv = BigIntegerCmp(c1, bc2);
392 BigIntegerFree(bc2);
393 return rv;
394#elif defined(CRYPTOLIB)
395 BigInteger t;
396 int rv;
397
398 t = bigInit(c2);
399 rv = bigCompare(c1, t);
400 freeBignum(t);
401 return rv;
402#elif defined(GNU_MP)
403 return mpz_cmp_ui(c1, c2);
404#elif defined(TOMMATH)
405 return mp_cmp_d(c1, c2);
406#elif defined(GCRYPT)
407 return gcry_mpi_cmp_ui(c1, c2);
408#elif defined(MPI)
409 return mp_cmp_int(c1, c2);
410#elif defined(MBEDTLS)
411 return mbedtls_mpi_cmp_int(c1, c2);
412#endif
413}
414
415BigIntegerResult
416BigIntegerLShift(result, x, bits)
417 BigInteger result, x;
418 unsigned int bits;
419{
420#ifdef OPENSSL
421 BN_lshift(result, x, bits);
422#elif defined(CRYPTOLIB)
423 bigLeftShift(x, bits, result);
424#elif defined(GNU_MP)
425 mpz_mul_2exp(result, x, bits);
426#elif defined(GCRYPT)
427 gcry_mpi_mul_2exp(result, x, bits);
428#elif defined(MPI) || defined(TOMMATH)
429 mp_mul_2d(x, bits, result);
430#elif defined(MBEDTLS)
431 mbedtls_mpi_copy(result, x);
432 mbedtls_mpi_shift_l(result, bits);
433#endif
434 return BIG_INTEGER_SUCCESS;
435}
436
437BigIntegerResult
438BigIntegerAdd(result, a1, a2)
439 BigInteger result, a1, a2;
440{
441#ifdef OPENSSL
442 BN_add(result, a1, a2);
443#elif defined(CRYPTOLIB)
444 bigAdd(a1, a2, result);
445#elif defined(GNU_MP)
446 mpz_add(result, a1, a2);
447#elif defined(GCRYPT)
448 gcry_mpi_add(result, a1, a2);
449#elif defined(MPI) || defined(TOMMATH)
450 mp_add(a1, a2, result);
451#elif defined(MBEDTLS)
452 mbedtls_mpi_add_mpi(result, a1, a2);
453#endif
454 return BIG_INTEGER_SUCCESS;
455}
456
457BigIntegerResult
458BigIntegerAddInt(result, a1, a2)
459 BigInteger result, a1;
460 unsigned int a2;
461{
462#ifdef OPENSSL
463 if(result != a1)
464 BN_copy(result, a1);
465 BN_add_word(result, a2);
466#elif defined(CRYPTOLIB)
467 BigInteger t;
468
469 t = bigInit(a2);
470 bigAdd(a1, t, result);
471 freeBignum(t);
472#elif defined(GNU_MP)
473 mpz_add_ui(result, a1, a2);
474#elif defined(GCRYPT)
475 gcry_mpi_add_ui(result, a1, a2);
476#elif defined(MPI) || defined(TOMMATH)
477 mp_add_d(a1, a2, result);
478#elif defined(MBEDTLS)
479 mbedtls_mpi_add_int(result, a1, a2);
480#endif
481 return BIG_INTEGER_SUCCESS;
482}
483
484BigIntegerResult
485BigIntegerSub(result, s1, s2)
486 BigInteger result, s1, s2;
487{
488#ifdef OPENSSL
489 BN_sub(result, s1, s2);
490#elif defined(CRYPTOLIB)
491 bigSubtract(s1, s2, result);
492#elif defined(GNU_MP)
493 mpz_sub(result, s1, s2);
494#elif defined(GCRYPT)
495 gcry_mpi_sub(result, s1, s2);
496#elif defined(MPI) || defined(TOMMATH)
497 mp_sub(s1, s2, result);
498#elif defined(MBEDTLS)
499 mbedtls_mpi_sub_mpi(result, s1, s2);
500#endif
501 return BIG_INTEGER_SUCCESS;
502}
503
504BigIntegerResult
505BigIntegerSubInt(result, s1, s2)
506 BigInteger result, s1;
507 unsigned int s2;
508{
509#ifdef OPENSSL
510 if(result != s1)
511 BN_copy(result, s1);
512 BN_sub_word(result, s2);
513#elif defined(CRYPTOLIB)
514 BigInteger t;
515
516 t = bigInit(s2);
517 bigSubtract(s1, t, result);
518 freeBignum(t);
519#elif defined(GNU_MP)
520 mpz_sub_ui(result, s1, s2);
521#elif defined(GCRYPT)
522 gcry_mpi_sub_ui(result, s1, s2);
523#elif defined(MPI) || defined(TOMMATH)
524 mp_sub_d(s1, s2, result);
525#elif defined(MBEDTLS)
526 mbedtls_mpi_sub_int(result, s1, s2);
527#endif
528 return BIG_INTEGER_SUCCESS;
529}
530
531BigIntegerResult
532BigIntegerMul(result, m1, m2, c)
533 BigInteger result, m1, m2;
534 BigIntegerCtx c;
535{
536#ifdef OPENSSL
537 BN_CTX * ctx = NULL;
538 if(c == NULL)
539 c = ctx = BN_CTX_new();
540 BN_mul(result, m1, m2, c);
541 if(ctx)
542 BN_CTX_free(ctx);
543#elif defined(CRYPTOLIB)
544 bigMultiply(m1, m2, result);
545#elif defined(GNU_MP)
546 mpz_mul(result, m1, m2);
547#elif defined(GCRYPT)
548 gcry_mpi_mul(result, m1, m2);
549#elif defined(MPI) || defined(TOMMATH)
550 mp_mul(m1, m2, result);
551#elif defined(MBEDTLS)
552 mbedtls_mpi_mul_mpi(result, m1, m2);
553#endif
554 return BIG_INTEGER_SUCCESS;
555}
556
557BigIntegerResult
558BigIntegerMulInt(result, m1, m2, c)
559 BigInteger result, m1;
560 unsigned int m2;
561 BigIntegerCtx c;
562{
563#ifdef OPENSSL
564 if(result != m1)
565 BN_copy(result, m1);
566 BN_mul_word(result, m2);
567#elif defined(CRYPTOLIB)
568 BigInteger t;
569
570 t = bigInit(m2);
571 bigMultiply(m1, t, result);
572 freeBignum(t);
573#elif defined(GNU_MP)
574 mpz_mul_ui(result, m1, m2);
575#elif defined(GCRYPT)
576 gcry_mpi_mul_ui(result, m1, m2);
577#elif defined(MPI) || defined(TOMMATH)
578 mp_mul_d(m1, m2, result);
579#elif defined(MBEDTLS)
580 mbedtls_mpi_mul_int(result, m1, m2);
581#endif
582 return BIG_INTEGER_SUCCESS;
583}
584
585BigIntegerResult
586BigIntegerDivInt(result, d, m, c)
587 BigInteger result, d;
588 unsigned int m;
589 BigIntegerCtx c;
590{
591#ifdef OPENSSL
592 if(result != d)
593 BN_copy(result, d);
594 BN_div_word(result, m);
595#elif defined(CRYPTOLIB)
596 BigInteger t, u, q;
597
598 t = bigInit(m);
599 u = bigInit(0);
600 /* We use a separate variable q because cryptolib breaks if result == d */
601 q = bigInit(0);
602 bigDivide(d, t, q, u);
603 freeBignum(t);
604 freeBignum(u);
605 bigCopy(q, result);
606 freeBignum(q);
607#elif defined(GNU_MP)
608# ifdef GMP2
609 mpz_fdiv_q_ui(result, d, m);
610# else
611 mpz_div_ui(result, d, m);
612# endif
613#elif defined(GCRYPT)
614 BigInteger t = BigIntegerFromInt(m);
615 gcry_mpi_div(result, NULL, d, t, -1);
616 BigIntegerFree(t);
617#elif defined(MPI) || defined(TOMMATH)
618 mp_div_d(d, m, result, NULL);
619#elif defined(MBEDTLS)
620 mbedtls_mpi_div_int(result, NULL, d, m);
621#endif
622 return BIG_INTEGER_SUCCESS;
623}
624
625BigIntegerResult
626BigIntegerMod(result, d, m, c)
627 BigInteger result, d, m;
628 BigIntegerCtx c;
629{
630#ifdef OPENSSL
631 BN_CTX * ctx = NULL;
632 if(c == NULL)
633 c = ctx = BN_CTX_new();
634 BN_mod(result, d, m, c);
635 if(ctx)
636 BN_CTX_free(ctx);
637#elif defined(CRYPTOLIB)
638 bigMod(d, m, result);
639#elif defined(GNU_MP)
640 mpz_mod(result, d, m);
641#elif defined(GCRYPT)
642 gcry_mpi_mod(result, d, m);
643#elif defined(MPI) || defined(TOMMATH)
644 mp_mod(d, m, result);
645#elif defined(MBEDTLS)
646 mbedtls_mpi_mod_mpi(result, d, m);
647#endif
648 return BIG_INTEGER_SUCCESS;
649}
650
651unsigned int
652BigIntegerModInt(d, m, c)
653 BigInteger d;
654 unsigned int m;
655 BigIntegerCtx c;
656{
657#ifdef OPENSSL
658 return BN_mod_word(d, m);
659#elif defined(CRYPTOLIB)
660 BigInteger t, u;
661 unsigned char r[4];
662
663 t = bigInit(m);
664 u = bigInit(0);
665 bigMod(d, t, u);
666 bigToBuf(u, sizeof(r), r);
667 freeBignum(t);
668 freeBignum(u);
669 return r[0] | (r[1] << 8) | (r[2] << 16) | (r[3] << 24);
670#elif defined(GNU_MP)
671 MP_INT result;
672 unsigned int i;
673
674 mpz_init(&result);
675
676/* Define GMP2 if you're using an old gmp.h but want to link against a
677 * newer libgmp.a (e.g. 2.0 or later). */
678
679# ifdef GMP2
680 mpz_fdiv_r_ui(&result, d, m);
681# else
682 mpz_mod_ui(&result, d, m);
683# endif
684 i = mpz_get_ui(&result);
685 mpz_clear(&result);
686 return i;
687#elif defined(GCRYPT)
688 /* TODO: any way to clean this up??? */
689 unsigned char r[4];
690 size_t len, i;
691 unsigned int ret = 0;
692 BigInteger t = BigIntegerFromInt(m);
693 BigInteger a = BigIntegerFromInt(0);
694 gcry_mpi_mod(a, d, t);
695 gcry_mpi_print(GCRYMPI_FMT_USG, r, 4, &len, a);
696 for(i = 0; i < len; ++i)
697 ret = (ret << 8) | r[i];
698 BigIntegerFree(t);
699 BigIntegerFree(a);
700 return ret;
701#elif defined(MPI) || defined(TOMMATH)
702 mp_digit r;
703 mp_mod_d(d, m, &r);
704 return r;
705#elif defined(MBEDTLS)
706 mbedtls_mpi_uint r = 0;
707 mbedtls_mpi_mod_int(&r, d, m);
708 return r;
709#endif
710}
711
712BigIntegerResult
713BigIntegerModMul(r, m1, m2, modulus, c)
714 BigInteger r, m1, m2, modulus;
715 BigIntegerCtx c;
716{
717#ifdef OPENSSL
718 BN_CTX * ctx = NULL;
719 if(c == NULL)
720 c = ctx = BN_CTX_new();
721 BN_mod_mul(r, m1, m2, modulus, c);
722 if(ctx)
723 BN_CTX_free(ctx);
724#elif defined(CRYPTOLIB)
725 bigMultiply(m1, m2, r);
726 bigMod(r, modulus, r);
727#elif defined(GNU_MP)
728 mpz_mul(r, m1, m2);
729 mpz_mod(r, r, modulus);
730#elif defined(GCRYPT)
731 gcry_mpi_mulm(r, m1, m2, modulus);
732#elif defined(MPI) || defined(TOMMATH)
733 mp_mulmod(m1, m2, modulus, r);
734#elif defined(MBEDTLS)
735 mbedtls_mpi d;
736 mbedtls_mpi_init(&d);
737 mbedtls_mpi_mul_mpi(&d, m1, m2);
738 mbedtls_mpi_mod_mpi(r, &d, modulus);
739 mbedtls_mpi_free(&d);
740#endif
741 return BIG_INTEGER_SUCCESS;
742}
743
744BigIntegerResult
745BigIntegerModExp(r, b, e, m, c, a)
746 BigInteger r, b, e, m;
747 BigIntegerCtx c;
748 BigIntegerModAccel a;
749{
750#ifdef OPENSSL
751#if OPENSSL_VERSION_NUMBER >= 0x00906000
752 BN_ULONG B = BN_get_word(b);
753#endif
754 BN_CTX * ctx = NULL;
755 if(c == NULL)
756 c = ctx = BN_CTX_new();
757 if(default_modexp) {
758 (*default_modexp)(r, b, e, m, c, a);
759 }
760 else if(a == NULL) {
761 BN_mod_exp(r, b, e, m, c);
762 }
763#if OPENSSL_VERSION_NUMBER >= 0x00906000
764 else if(B > 0 && B < ULONG_MAX) { /* 0.9.6 and above has mont_word optimization */
765 BN_mod_exp_mont_word(r, B, e, m, c, a);
766 }
767#endif
768 else
769 BN_mod_exp_mont(r, b, e, m, c, a);
770 if(ctx)
771 BN_CTX_free(ctx);
772#elif defined(CRYPTOLIB)
773 bigPow(b, e, m, r);
774#elif defined(GNU_MP)
775 mpz_powm(r, b, e, m);
776#elif defined(GCRYPT)
777 gcry_mpi_powm(r, b, e, m);
778#elif defined(MPI) || defined(TOMMATH)
779 mp_exptmod(b, e, m, r);
780#elif defined(MBEDTLS)
781 mbedtls_mpi_exp_mod(r, b, e, m, NULL);
782#endif
783 return BIG_INTEGER_SUCCESS;
784}
785
786#if defined(MBEDTLS)
787int _mbedtls_f_rng(void* unused, unsigned char *buf, size_t size)
788{
789 t_random(buf, size);
790 return 0;
791}
792#endif
793
794int
795BigIntegerCheckPrime(n, c)
796 BigInteger n;
797 BigIntegerCtx c;
798{
799#ifdef OPENSSL
800 int rv;
801 BN_CTX * ctx = NULL;
802 if(c == NULL)
803 c = ctx = BN_CTX_new();
804#if OPENSSL_VERSION_NUMBER >= 0x00908000
805 rv = BN_is_prime_ex(n, 25, c, NULL);
806#else
807 rv = BN_is_prime(n, 25, NULL, c, NULL);
808#endif
809 if(ctx)
810 BN_CTX_free(ctx);
811 return rv;
812#elif defined(CRYPTOLIB)
813#if 0
814 /*
815 * Ugh. Not only is cryptolib's bigDivide sensitive to inputs
816 * and outputs being the same, but now the primeTest needs random
817 * numbers, which it gets by calling cryptolib's broken truerand
818 * implementation(!) We have to fake it out by doing our own
819 * seeding explicitly.
820 */
821 static int seeded = 0;
822 static unsigned char seedbuf[64];
823 if(!seeded) {
824 t_random(seedbuf, sizeof(seedbuf));
825 seedDesRandom(seedbuf, sizeof(seedbuf));
826 memset(seedbuf, 0, sizeof(seedbuf));
827 seeded = 1;
828 }
829#endif /* 0 */
830 t_random(NULL, 0);
831 return primeTest(n);
832#elif defined(GNU_MP)
833 return mpz_probab_prime_p(n, 25);
834#elif defined(GCRYPT)
835 return (gcry_prime_check(n, 0) == GPG_ERR_NO_ERROR);
836#elif defined(TOMMATH)
837 int rv;
838 mp_prime_is_prime(n, 25, &rv);
839 return rv;
840#elif defined(MPI)
841 return (mpp_pprime(n, 25) == MP_YES);
842#elif defined(MBEDTLS)
843 return mbedtls_mpi_is_prime_ext(n, 25, _mbedtls_f_rng, NULL);
844#endif
845}
846
847BigIntegerResult
848BigIntegerFree(b)
849 BigInteger b;
850{
851#ifdef OPENSSL
852 BN_free(b);
853#elif defined(CRYPTOLIB)
854 freeBignum(b);
855#elif defined(GNU_MP)
856 mpz_clear(b);
857 free(b);
858#elif defined(GCRYPT)
859 gcry_mpi_release(b);
860#elif defined(MPI) || defined(TOMMATH)
861 mp_clear(b);
862 free(b);
863#elif defined(MBEDTLS)
864 mbedtls_mpi_free(b);
865 free(b);
866#endif
867 return BIG_INTEGER_SUCCESS;
868}
869
870BigIntegerResult
871BigIntegerClearFree(b)
872 BigInteger b;
873{
874#ifdef OPENSSL
875 BN_clear_free(b);
876#elif defined(CRYPTOLIB)
877 /* TODO */
878 freeBignum(b);
879#elif defined(GNU_MP)
880 /* TODO */
881 mpz_clear(b);
882 free(b);
883#elif defined(GCRYPT)
884 /* TODO */
885 gcry_mpi_release(b);
886#elif defined(MPI) || defined(TOMMATH)
887 /* TODO */
888 mp_clear(b);
889 free(b);
890#elif defined(MBEDTLS)
891 mbedtls_mpi_free(b);
892 free(b);
893#endif
894 return BIG_INTEGER_SUCCESS;
895}
896
897BigIntegerCtx
898BigIntegerCtxNew()
899{
900#ifdef OPENSSL
901 return BN_CTX_new();
902#else
903 return NULL;
904#endif
905}
906
907BigIntegerResult
908BigIntegerCtxFree(ctx)
909 BigIntegerCtx ctx;
910{
911#ifdef OPENSSL
912 if(ctx)
913 BN_CTX_free(ctx);
914#endif
915 return BIG_INTEGER_SUCCESS;
916}
917
918BigIntegerModAccel
919BigIntegerModAccelNew(m, c)
920 BigInteger m;
921 BigIntegerCtx c;
922{
923#ifdef OPENSSL
924 BN_CTX * ctx = NULL;
925 BN_MONT_CTX * mctx;
926 if(default_modexp)
927 return NULL;
928 if(c == NULL)
929 c = ctx = BN_CTX_new();
930 mctx = BN_MONT_CTX_new();
931 BN_MONT_CTX_set(mctx, m, c);
932 if(ctx)
933 BN_CTX_free(ctx);
934 return mctx;
935#else
936 return NULL;
937#endif
938}
939
940BigIntegerResult
941BigIntegerModAccelFree(accel)
942 BigIntegerModAccel accel;
943{
944#ifdef OPENSSL
945 if(accel)
946 BN_MONT_CTX_free(accel);
947#endif
948 return BIG_INTEGER_SUCCESS;
949}
950
951BigIntegerResult
952BigIntegerInitialize()
953{
954#if OPENSSL_VERSION_NUMBER >= 0x00907000
955 ENGINE_load_builtin_engines();
956#endif
957 return BIG_INTEGER_SUCCESS;
958}
959
960BigIntegerResult
961BigIntegerFinalize()
962{
963 return BigIntegerReleaseEngine();
964}
965
966BigIntegerResult
967BigIntegerUseEngine(const char * engine)
968{
969#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
970 ENGINE * e = ENGINE_by_id(engine);
971 if(e) {
972 if(ENGINE_init(e) > 0) {
973#if OPENSSL_VERSION_NUMBER >= 0x00907000
974 /* 0.9.7 loses the BN_mod_exp method. Pity. */
975 const RSA_METHOD * rsa = ENGINE_get_RSA(e);
976 if(rsa)
977#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3000000fL) || (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100005L)
978 default_modexp = (modexp_meth)RSA_meth_get_bn_mod_exp(rsa);
979#else
980 default_modexp = (modexp_meth)rsa->bn_mod_exp;
981#endif
982#else
983 default_modexp = (modexp_meth)ENGINE_get_BN_mod_exp(e);
984#endif
985 BigIntegerReleaseEngine();
986 default_engine = e;
987 return BIG_INTEGER_SUCCESS;
988 }
989 else
990 ENGINE_free(e);
991 }
992#endif
993 return BIG_INTEGER_ERROR;
994}
995
996BigIntegerResult
997BigIntegerReleaseEngine()
998{
999#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
1000 if(default_engine) {
1001 ENGINE_finish(default_engine);
1002 ENGINE_free(default_engine);
1003 default_engine = NULL;
1004 default_modexp = NULL;
1005 }
1006#endif
1007 return BIG_INTEGER_SUCCESS;
1008}
diff --git a/3rd_party/libsrp6a-sha512/t_misc.c b/3rd_party/libsrp6a-sha512/t_misc.c
new file mode 100644
index 0000000..3053358
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_misc.c
@@ -0,0 +1,450 @@
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(out)
84 unsigned char * out;
85{
86 char ** ptr;
87 char ebuf[256];
88 SHA1_CTX ctxt;
89
90 SHA1Init(&ctxt);
91 for(ptr = environ; *ptr; ++ptr) {
92 strncpy(ebuf, *ptr, 255);
93 ebuf[255] = '\0';
94 SHA1Update(&ctxt, ebuf, strlen(ebuf));
95 }
96 SHA1Final(out, &ctxt);
97}
98
99/*
100 * t_fshash - Generate a 160-bit SHA hash from the file system
101 *
102 * This routine climbs up the directory tree from the current
103 * directory, running stat() on each directory until it hits the
104 * root directory. This information is sensitive to the last
105 * access/modification times of all the directories above you,
106 * so someone who lists one of those directories injects some
107 * entropy into the system. Obviously, this hash is very sensitive
108 * to your current directory when the program is run.
109 *
110 * For good measure, it also performs an fstat on the standard input,
111 * usually your tty, throws that into the buffer, creates a file in
112 * /tmp (the inode is unpredictable on a busy system), and runs stat()
113 * on that before deleting it.
114 *
115 * The entire buffer is run once through SHA to obtain the final result.
116 */
117static void
118t_fshash(out)
119 unsigned char * out;
120{
121 char dotpath[128];
122 struct stat st;
123 SHA1_CTX ctxt;
124 int i, pinode;
125 dev_t pdev;
126
127 SHA1Init(&ctxt);
128 if(stat(".", &st) >= 0) {
129 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
130 pinode = st.st_ino;
131 pdev = st.st_dev;
132 strcpy(dotpath, "..");
133 for(i = 0; i < 40; ++i) {
134 if(stat(dotpath, &st) < 0)
135 break;
136 if(st.st_ino == pinode && st.st_dev == pdev)
137 break;
138 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
139 pinode = st.st_ino;
140 pdev = st.st_dev;
141 strcat(dotpath, "/..");
142 }
143 }
144
145 if(fstat(0, &st) >= 0)
146 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
147
148 sprintf(dotpath, "/tmp/rnd.%d", getpid());
149 if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
150 SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
151 unlink(dotpath);
152
153 SHA1Final(out, &ctxt);
154}
155
156/*
157 * Generate a high-entropy seed for the strong random number generator.
158 * This uses a wide variety of quickly gathered and somewhat unpredictable
159 * system information. The 'preseed' structure is assembled from:
160 *
161 * The system time in seconds
162 * The system time in microseconds
163 * The current process ID
164 * The parent process ID
165 * A hash of the user's environment
166 * A hash gathered from the file system
167 * Input from a random device, if available
168 * Timings of system interrupts
169 *
170 * The entire structure (60 bytes on most systems) is fed to SHA to produce
171 * a 160-bit seed for the strong random number generator. It is believed
172 * that in the worst case (on a quiet system with no random device versus
173 * an attacker who has access to the system already), the seed contains at
174 * least about 80 bits of entropy. Versus an attacker who does not have
175 * access to the system, the entropy should be slightly over 128 bits.
176 */
177static char initialized = 0;
178
179static struct {
180 unsigned int trand1;
181 time_t sec;
182 time_t subsec;
183 short pid;
184 short ppid;
185 unsigned char envh[SHA_DIGESTSIZE];
186 unsigned char fsh[SHA_DIGESTSIZE];
187 unsigned char devrand[20];
188 unsigned int trand2;
189} preseed;
190
191unsigned long raw_truerand();
192
193static void
194t_initrand()
195{
196 SHA1_CTX ctxt;
197#ifdef USE_FTIME
198 struct timeb t;
199#else
200 struct timeval t;
201#endif
202 int i, r=0;
203
204 if(initialized)
205 return;
206
207 initialized = 1;
208
209#if defined(OPENSSL) /* OpenSSL has nifty win32 entropy-gathering code */
210#if OPENSSL_VERSION_NUMBER >= 0x00905100
211 r = RAND_status();
212#if defined(WINDOWS) || defined(WIN32)
213 if(r) /* Don't do the Unix-y stuff on Windows if possible */
214 return;
215#else
216#endif
217#endif
218
219#elif defined(TOMCRYPT)
220 yarrow_start(&g_rng);
221 r = rng_get_bytes(entropy, sizeof(entropy), NULL);
222 if(r > 0) {
223 yarrow_add_entropy(entropy, r, &g_rng);
224 memset(entropy, 0, sizeof(entropy));
225# if defined(WINDOWS) || defined(WIN32)
226 /* Don't do the Unix-y stuff on Windows if possible */
227 yarrow_ready(&g_rng);
228 return;
229# endif
230 }
231#endif
232
233#if !defined(WINDOWS) && !defined(WIN32)
234 i = open("/dev/urandom", O_RDONLY);
235 if(i > 0) {
236 r += read(i, preseed.devrand, sizeof(preseed.devrand));
237 close(i);
238 }
239#endif /* !WINDOWS && !WIN32 */
240
241 /* Resort to truerand only if desperate for some Real entropy */
242 if(r == 0)
243 preseed.trand1 = raw_truerand();
244
245#ifdef USE_FTIME
246 ftime(&t);
247 preseed.sec = t.time;
248 preseed.subsec = t.millitm;
249#else
250 gettimeofday(&t, NULL);
251 preseed.sec = t.tv_sec;
252 preseed.subsec = t.tv_usec;
253#endif
254 preseed.pid = getpid();
255#ifndef WIN32
256 preseed.ppid = getppid();
257#endif
258 t_envhash(preseed.envh);
259 t_fshash(preseed.fsh);
260
261 if(r == 0)
262 preseed.trand2 = raw_truerand();
263
264#ifdef OPENSSL
265 RAND_seed((unsigned char *)&preseed, sizeof(preseed));
266#elif defined(TOMCRYPT)
267 yarrow_add_entropy((unsigned char *)&preseed, sizeof(preseed), &g_rng);
268 yarrow_ready(&g_rng);
269#elif defined(CRYPTOLIB)
270 t_mgf1(crpool, sizeof(crpool), (unsigned char *) &preseed, sizeof(preseed));
271 seedDesRandom(crpool, sizeof(crpool));
272 memset(crpool, 0, sizeof(crpool));
273#elif defined(GCRYPT)
274 gcry_random_add_bytes((unsigned char *)&preseed, sizeof(preseed), -1);
275#else
276 SHA1Init(&ctxt);
277 SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
278 SHA1Final(randpool, &ctxt);
279 memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
280 outpos = 0;
281#endif /* OPENSSL */
282 memset((unsigned char *) &preseed, 0, sizeof(preseed));
283}
284
285#define NUM_RANDOMS 12
286
287_TYPE( void )
288t_stronginitrand()
289{
290#if 1 /* t_initrand() has been improved enough to make this unnecessary */
291 t_initrand();
292#else
293 SHA1_CTX ctxt;
294 unsigned int rawrand[NUM_RANDOMS];
295 int i;
296
297 if(!initialized)
298 t_initrand();
299 for(i = 0; i < NUM_RANDOMS; ++i)
300 rawrand[i] = raw_truerand();
301 SHA1Init(&ctxt);
302 SHA1Update(&ctxt, (unsigned char *) rawrand, sizeof(rawrand));
303 SHA1Final(randkey2, &ctxt);
304 memset(rawrand, 0, sizeof(rawrand));
305#endif
306}
307
308/*
309 * The strong random number generator. This uses a 160-bit seed
310 * and uses SHA-1 in a feedback configuration to generate successive
311 * outputs. If S[0] is set to the initial seed, then:
312 *
313 * S[i+1] = SHA-1(i || S[i])
314 * A[i] = SHA-1(S[i])
315 *
316 * where the A[i] are the output blocks starting with i=0.
317 * Each cycle generates 20 bytes of new output.
318 */
319_TYPE( void )
320t_random(data, size)
321 unsigned char * data;
322 unsigned size;
323{
324 if(!initialized)
325 t_initrand();
326
327 if(size <= 0) /* t_random(NULL, 0) forces seed initialization */
328 return;
329
330#ifdef OPENSSL
331 RAND_bytes(data, size);
332#elif defined(TOMCRYPT)
333 yarrow_read(data, size, &g_rng);
334#elif defined(GCRYPT)
335 gcry_randomize(data, size, GCRY_STRONG_RANDOM);
336#elif defined(CRYPTOLIB)
337 randomBytes(data, size, PSEUDO);
338#else
339 while(size > outpos) {
340 if(outpos > 0) {
341 memcpy(data, randout + (sizeof(randout) - outpos), outpos);
342 data += outpos;
343 size -= outpos;
344 }
345
346 /* Recycle */
347 SHA1Init(&randctxt);
348 SHA1Update(&randctxt, randpool, sizeof(randpool));
349 SHA1Final(randout, &randctxt);
350 SHA1Init(&randctxt);
351 SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
352 SHA1Update(&randctxt, randpool, sizeof(randpool));
353 SHA1Final(randpool, &randctxt);
354 ++randcnt;
355 outpos = sizeof(randout);
356 }
357
358 if(size > 0) {
359 memcpy(data, randout + (sizeof(randout) - outpos), size);
360 outpos -= size;
361 }
362#endif
363}
364
365/*
366 * The interleaved session-key hash. This separates the even and the odd
367 * bytes of the input (ignoring the first byte if the input length is odd),
368 * hashes them separately, and re-interleaves the two outputs to form a
369 * single 320-bit value.
370 */
371_TYPE( unsigned char * )
372t_sessionkey(key, sk, sklen)
373 unsigned char * key;
374 unsigned char * sk;
375 unsigned sklen;
376{
377 unsigned i, klen;
378 unsigned char * hbuf;
379 unsigned char hout[SHA_DIGESTSIZE];
380 SHA1_CTX ctxt;
381
382 while(sklen > 0 && *sk == 0) { /* Skip leading 0's */
383 --sklen;
384 ++sk;
385 }
386
387 klen = sklen / 2;
388 if((hbuf = malloc(klen * sizeof(char))) == 0)
389 return 0;
390
391 for(i = 0; i < klen; ++i)
392 hbuf[i] = sk[sklen - 2 * i - 1];
393 SHA1Init(&ctxt);
394 SHA1Update(&ctxt, hbuf, klen);
395 SHA1Final(hout, &ctxt);
396 for(i = 0; i < sizeof(hout); ++i)
397 key[2 * i] = hout[i];
398
399 for(i = 0; i < klen; ++i)
400 hbuf[i] = sk[sklen - 2 * i - 2];
401 SHA1Init(&ctxt);
402 SHA1Update(&ctxt, hbuf, klen);
403 SHA1Final(hout, &ctxt);
404 for(i = 0; i < sizeof(hout); ++i)
405 key[2 * i + 1] = hout[i];
406
407 memset(hout, 0, sizeof(hout));
408 memset(hbuf, 0, klen);
409 free(hbuf);
410 return key;
411}
412
413_TYPE( void )
414t_mgf1(mask, masklen, seed, seedlen)
415 unsigned char * mask;
416 unsigned masklen;
417 const unsigned char * seed;
418 unsigned seedlen;
419{
420 SHA1_CTX ctxt;
421 unsigned i = 0;
422 unsigned pos = 0;
423 unsigned char cnt[4];
424 unsigned char hout[SHA_DIGESTSIZE];
425
426 while(pos < masklen) {
427 cnt[0] = (i >> 24) & 0xFF;
428 cnt[1] = (i >> 16) & 0xFF;
429 cnt[2] = (i >> 8) & 0xFF;
430 cnt[3] = i & 0xFF;
431 SHA1Init(&ctxt);
432 SHA1Update(&ctxt, seed, seedlen);
433 SHA1Update(&ctxt, cnt, 4);
434
435 if(pos + SHA_DIGESTSIZE > masklen) {
436 SHA1Final(hout, &ctxt);
437 memcpy(mask + pos, hout, masklen - pos);
438 pos = masklen;
439 }
440 else {
441 SHA1Final(mask + pos, &ctxt);
442 pos += SHA_DIGESTSIZE;
443 }
444
445 ++i;
446 }
447
448 memset(hout, 0, sizeof(hout));
449 memset((unsigned char *)&ctxt, 0, sizeof(ctxt));
450}
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..4029de8
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_sha.c
@@ -0,0 +1,276 @@
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) && !defined(TOMCRYPT_SHA)
111/* Use the free SHA1 if the library doesn't have it */
112
113/*
114SHA-1 in C
115By Steve Reid <steve@edmweb.com>
116100% Public Domain
117
118Test Vectors (from FIPS PUB 180-1)
119"abc"
120 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
121"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
122 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
123A million repetitions of "a"
124 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
125*/
126
127/* #define LITTLE_ENDIAN * This should be #define'd if true. */
128/* #define SHA1HANDSOFF * Copies data before messing with it. */
129
130#include <stdio.h>
131#include <string.h>
132
133static void SHA1Transform(uint32 state[5], const unsigned char buffer[64]);
134
135#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
136
137/* blk0() and blk() perform the initial expand. */
138/* I got the idea of expanding during the round function from SSLeay */
139#ifndef WORDS_BIGENDIAN
140#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
141 |(rol(block->l[i],8)&0x00FF00FF))
142#else
143#define blk0(i) block->l[i]
144#endif
145#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
146 ^block->l[(i+2)&15]^block->l[i&15],1))
147
148/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
149#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
150#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
151#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
152#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
153#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
154
155/* Hash a single 512-bit block. This is the core of the algorithm. */
156
157static void SHA1Transform(uint32 state[5], const unsigned char buffer[64])
158{
159uint32 a, b, c, d, e;
160typedef union {
161 unsigned char c[64];
162 uint32 l[16];
163} CHAR64LONG16;
164CHAR64LONG16* block;
165#ifdef SHA1HANDSOFF
166static unsigned char workspace[64];
167 block = (CHAR64LONG16*)workspace;
168 memcpy(block, buffer, 64);
169#else
170 block = (CHAR64LONG16*)buffer;
171#endif
172 /* Copy context->state[] to working vars */
173 a = state[0];
174 b = state[1];
175 c = state[2];
176 d = state[3];
177 e = state[4];
178 /* 4 rounds of 20 operations each. Loop unrolled. */
179 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);
180 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);
181 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);
182 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);
183 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);
184 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);
185 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);
186 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);
187 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);
188 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);
189 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);
190 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);
191 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);
192 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);
193 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);
194 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);
195 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);
196 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);
197 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);
198 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);
199 /* Add the working vars back into context.state[] */
200 state[0] += a;
201 state[1] += b;
202 state[2] += c;
203 state[3] += d;
204 state[4] += e;
205 /* Wipe variables */
206 a = b = c = d = e = 0;
207}
208
209
210/* SHA1Init - Initialize new context */
211
212void SHA1Init(SHA1_CTX* context)
213{
214 /* SHA1 initialization constants */
215 context->state[0] = 0x67452301;
216 context->state[1] = 0xEFCDAB89;
217 context->state[2] = 0x98BADCFE;
218 context->state[3] = 0x10325476;
219 context->state[4] = 0xC3D2E1F0;
220 context->count[0] = context->count[1] = 0;
221}
222
223
224/* Run your data through this. */
225
226void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
227{
228unsigned int i, j;
229
230 j = (context->count[0] >> 3) & 63;
231 if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
232 context->count[1] += (len >> 29);
233 if ((j + len) > 63) {
234 memcpy(&context->buffer[j], data, (i = 64-j));
235 SHA1Transform(context->state, context->buffer);
236 for ( ; i + 63 < len; i += 64) {
237 SHA1Transform(context->state, &data[i]);
238 }
239 j = 0;
240 }
241 else i = 0;
242 memcpy(&context->buffer[j], &data[i], len - i);
243}
244
245
246/* Add padding and return the message digest. */
247
248void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
249{
250uint32 i, j;
251unsigned char finalcount[8];
252
253 for (i = 0; i < 8; i++) {
254 finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
255 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
256 }
257 SHA1Update(context, (unsigned char *)"\200", 1);
258 while ((context->count[0] & 504) != 448) {
259 SHA1Update(context, (unsigned char *)"\0", 1);
260 }
261 SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
262 for (i = 0; i < 20; i++) {
263 digest[i] = (unsigned char)
264 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
265 }
266 /* Wipe variables */
267 i = j = 0;
268 memset(context->buffer, 0, 64);
269 memset(context->state, 0, 20);
270 memset(context->count, 0, 8);
271 memset(&finalcount, 0, 8);
272#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
273 SHA1Transform(context->state, context->buffer);
274#endif
275}
276#endif /* OPENSSL */
diff --git a/3rd_party/libsrp6a-sha512/t_sha.h b/3rd_party/libsrp6a-sha512/t_sha.h
new file mode 100644
index 0000000..18deec5
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_sha.h
@@ -0,0 +1,125 @@
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/sha.h>
42
43typedef SHA_CTX SHA1_CTX;
44#define SHA1Init SHA1_Init
45#define SHA1Update SHA1_Update
46#define SHA1Final SHA1_Final
47
48#define SHA512Init SHA512_Init
49#define SHA512Update SHA512_Update
50#define SHA512Final SHA512_Final
51
52#elif defined(TOMCRYPT_SHA)
53/* mycrypt.h already included above */
54
55typedef hash_state SHA1_CTX;
56#define SHA1Init sha1_init
57#define SHA1Update sha1_process
58#define SHA1Final(D,C) sha1_done(C,D)
59
60#elif defined(GCRYPT_SHA)
61#include "gcrypt.h"
62
63typedef gcry_md_hd_t SHA1_CTX;
64#define SHA1Init SHA1Init_gcry
65#define SHA1Update SHA1Update_gcry
66#define SHA1Final SHA1Final_gcry
67typedef gcry_md_hd_t SHA512_CTX;
68#define SHA512Init SHA512Init_gcry
69#define SHA512Update SHA512Update_gcry
70#define SHA512Final SHA512Final_gcry
71
72void SHA1Init_gcry(SHA1_CTX * ctx);
73void SHA1Update_gcry(SHA1_CTX * ctx, const void *data, unsigned int len);
74void SHA1Final_gcry(unsigned char digest[20], SHA1_CTX * ctx);
75
76void SHA512Init_gcry(SHA512_CTX * ctx);
77void SHA512Update_gcry(SHA512_CTX * ctx, const void *data, unsigned int len);
78void SHA512Final_gcry(unsigned char digest[64], SHA512_CTX * ctx);
79
80#elif defined(MBEDTLS_SHA)
81#include <mbedtls/md.h>
82
83typedef mbedtls_md_context_t SHA1_CTX;
84#define SHA1Init SHA1Init_mbed
85#define SHA1Update SHA1Update_mbed
86#define SHA1Final SHA1Final_mbed
87
88typedef mbedtls_md_context_t SHA512_CTX;
89#define SHA512Init SHA512Init_mbed
90#define SHA512Update SHA512Update_mbed
91#define SHA512Final SHA512Final_mbed
92
93void SHA1Init_mbed(SHA1_CTX * ctx);
94void SHA1Update_mbed(SHA1_CTX * ctx, const void *data, unsigned int len);
95void SHA1Final_mbed(unsigned char digest[20], SHA1_CTX * ctx);
96
97void SHA512Init_mbed(SHA512_CTX * ctx);
98void SHA512Update_mbed(SHA512_CTX * ctx, const void *data, unsigned int len);
99void SHA512Final_mbed(unsigned char digest[64], SHA512_CTX * ctx);
100
101#elif defined(CRYPTOLIB_SHA)
102#include "libcrypt.h"
103
104typedef SHS_CTX SHA1_CTX;
105#define SHA1Init shsInit
106#define SHA1Update shsUpdate
107#define SHA1Final shsFinalBytes
108
109void shsFinalBytes P((unsigned char digest[20], SHS_CTX* context));
110
111#else
112typedef unsigned int uint32;
113
114typedef struct {
115 uint32 state[5];
116 uint32 count[2];
117 unsigned char buffer[64];
118} SHA1_CTX;
119
120void SHA1Init P((SHA1_CTX* context));
121void SHA1Update P((SHA1_CTX* context, const unsigned char* data, unsigned int len));
122void SHA1Final P((unsigned char digest[20], SHA1_CTX* context));
123#endif /* !OPENSSL && !CRYPTOLIB */
124
125#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..2617b5e
--- /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 <wtypes.h>
75#include <winbase.h>
76#include <windef.h>
77#include <winnt.h>
78#include <winuser.h>
79#include <process.h>
80
81volatile unsigned long count, ocount, randbuf;
82volatile int dontstop;
83char outbuf[1024], *bufp;
84
85static void counter() {
86 while (dontstop)
87 count++;
88 _endthread();
89}
90
91
92static unsigned long roulette() {
93 unsigned long thread;
94
95 count = 0;
96 dontstop= 1;
97 while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0)
98 ;
99
100 Sleep(16);
101 dontstop = 0;
102 Sleep(1);
103
104 count ^= (count>>3) ^ (count>>6) ^ (ocount);
105 count &= 0x7;
106 ocount = count;
107 randbuf = (randbuf<<3) ^ count;
108 return randbuf;
109}
110
111
112unsigned long
113raw_truerand() {
114
115 roulette();
116 roulette();
117 roulette();
118 roulette();
119 roulette();
120 roulette();
121 roulette();
122 roulette();
123 roulette();
124 roulette();
125 return roulette();
126}
127
128# endif /* CRYPTOLIB */
129
130#else /* !WIN32 */
131
132#include <signal.h>
133#include <setjmp.h>
134#include <sys/time.h>
135#include <math.h>
136#include <stdio.h>
137
138#ifdef OLD_TRUERAND
139static jmp_buf env;
140#endif
141static unsigned volatile count
142#ifndef OLD_TRUERAND
143 , done = 0
144#endif
145;
146
147static unsigned ocount;
148static unsigned buffer;
149
150static void
151tick()
152{
153 struct itimerval it, oit;
154
155 it.it_interval.tv_sec = 0;
156 it.it_interval.tv_usec = 0;
157 it.it_value.tv_sec = 0;
158 it.it_value.tv_usec = 16665;
159 if (setitimer(ITIMER_REAL, &it, &oit) < 0)
160 perror("tick");
161}
162
163static void
164interrupt()
165{
166 if (count) {
167#ifdef OLD_TRUERAND
168 longjmp(env, 1);
169#else
170 ++done;
171 return;
172#endif
173 }
174
175 (void) signal(SIGALRM, interrupt);
176 tick();
177}
178
179static unsigned long
180roulette()
181{
182#ifdef OLD_TRUERAND
183 if (setjmp(env)) {
184 count ^= (count>>3) ^ (count>>6) ^ ocount;
185 count &= 0x7;
186 ocount=count;
187 buffer = (buffer<<3) ^ count;
188 return buffer;
189 }
190#else
191 done = 0;
192#endif
193 (void) signal(SIGALRM, interrupt);
194 count = 0;
195 tick();
196#ifdef OLD_TRUERAND
197 for (;;)
198#else
199 while(done == 0)
200#endif
201 count++; /* about 1 MHz on VAX 11/780 */
202#ifndef OLD_TRUERAND
203 count ^= (count>>3) ^ (count>>6) ^ ocount;
204 count &= 0x7;
205 ocount=count;
206 buffer = (buffer<<3) ^ count;
207 return buffer;
208#endif
209}
210
211unsigned long
212raw_truerand()
213{
214 count=0;
215 (void) roulette();
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 return roulette();
226}
227
228int
229raw_n_truerand(n)
230int 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 */