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