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 | 32 | ||||
| -rw-r--r-- | 3rd_party/libsrp6a-sha512/README.md | 35 | ||||
| -rw-r--r-- | 3rd_party/libsrp6a-sha512/cstr.c | 184 | ||||
| -rw-r--r-- | 3rd_party/libsrp6a-sha512/cstr.h | 82 | ||||
| -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 | 444 | ||||
| -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, 4286 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..bdacb5f --- /dev/null +++ b/3rd_party/libsrp6a-sha512/Makefile.am | |||
| @@ -0,0 +1,32 @@ | |||
| 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_defines.h t_pwd.h \ | ||
| 29 | t_sha.c t_sha.h | ||
| 30 | #if !HAVE_OPENSSL | ||
| 31 | #libsrp6a_sha512_la_SOURCES += t_sha.c | ||
| 32 | #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..58a5638 --- /dev/null +++ b/3rd_party/libsrp6a-sha512/cstr.c | |||
| @@ -0,0 +1,184 @@ | |||
| 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 | |||
| 12 | _TYPE( cstr * ) | ||
| 13 | cstr_new() | ||
| 14 | { | ||
| 15 | cstr * str; | ||
| 16 | |||
| 17 | str = (cstr *) malloc(sizeof(cstr)); | ||
| 18 | if(str) { | ||
| 19 | str->data = cstr_empty_string; | ||
| 20 | str->length = str->cap = 0; | ||
| 21 | str->ref = 1; | ||
| 22 | } | ||
| 23 | return str; | ||
| 24 | } | ||
| 25 | |||
| 26 | _TYPE( cstr * ) | ||
| 27 | cstr_dup(const cstr * str) | ||
| 28 | { | ||
| 29 | cstr * nstr = cstr_new(); | ||
| 30 | if(nstr) | ||
| 31 | cstr_setn(nstr, str->data, str->length); | ||
| 32 | return nstr; | ||
| 33 | } | ||
| 34 | |||
| 35 | _TYPE( cstr * ) | ||
| 36 | cstr_create(const char * s) | ||
| 37 | { | ||
| 38 | return cstr_createn(s, strlen(s)); | ||
| 39 | } | ||
| 40 | |||
| 41 | _TYPE( cstr * ) | ||
| 42 | cstr_createn(const char * s, int len) | ||
| 43 | { | ||
| 44 | cstr * str = cstr_new(); | ||
| 45 | if(str) { | ||
| 46 | cstr_setn(str, s, len); | ||
| 47 | } | ||
| 48 | return str; | ||
| 49 | } | ||
| 50 | |||
| 51 | _TYPE( void ) | ||
| 52 | cstr_use(cstr * str) | ||
| 53 | { | ||
| 54 | ++str->ref; | ||
| 55 | } | ||
| 56 | |||
| 57 | _TYPE( void ) | ||
| 58 | cstr_clear_free(cstr * str) | ||
| 59 | { | ||
| 60 | if(--str->ref == 0) { | ||
| 61 | if(str->cap > 0) { | ||
| 62 | memset(str->data, 0, str->cap); | ||
| 63 | free(str->data); | ||
| 64 | } | ||
| 65 | free(str); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | _TYPE( void ) | ||
| 70 | cstr_free(cstr * str) | ||
| 71 | { | ||
| 72 | if(--str->ref == 0) { | ||
| 73 | if(str->cap > 0) | ||
| 74 | free(str->data); | ||
| 75 | free(str); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | _TYPE( void ) | ||
| 80 | cstr_empty(cstr * str) | ||
| 81 | { | ||
| 82 | if(str->cap > 0) | ||
| 83 | free(str->data); | ||
| 84 | str->data = cstr_empty_string; | ||
| 85 | str->length = str->cap = 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int | ||
| 89 | cstr_alloc(cstr * str, int len) | ||
| 90 | { | ||
| 91 | char * t; | ||
| 92 | |||
| 93 | if(len > str->cap) { | ||
| 94 | if(len < EXPFACTOR * str->cap) | ||
| 95 | len = EXPFACTOR * str->cap; | ||
| 96 | if(len < MINSIZE) | ||
| 97 | len = MINSIZE; | ||
| 98 | |||
| 99 | t = (char *) malloc(len * sizeof(char)); | ||
| 100 | if(t) { | ||
| 101 | if(str->data) { | ||
| 102 | t[str->length] = 0; | ||
| 103 | if(str->cap > 0) { | ||
| 104 | if(str->length > 0) | ||
| 105 | memcpy(t, str->data, str->length); | ||
| 106 | free(str->data); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | str->data = t; | ||
| 110 | str->cap = len; | ||
| 111 | return 1; | ||
| 112 | } | ||
| 113 | else | ||
| 114 | return -1; | ||
| 115 | } | ||
| 116 | else | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | _TYPE( int ) | ||
| 121 | cstr_copy(cstr * dst, const cstr * src) | ||
| 122 | { | ||
| 123 | return cstr_setn(dst, src->data, src->length); | ||
| 124 | } | ||
| 125 | |||
| 126 | _TYPE( int ) | ||
| 127 | cstr_set(cstr * str, const char * s) | ||
| 128 | { | ||
| 129 | return cstr_setn(str, s, strlen(s)); | ||
| 130 | } | ||
| 131 | |||
| 132 | _TYPE( int ) | ||
| 133 | cstr_setn(cstr * str, const char * s, int len) | ||
| 134 | { | ||
| 135 | if(cstr_alloc(str, len + 1) < 0) | ||
| 136 | return -1; | ||
| 137 | str->data[len] = 0; | ||
| 138 | if(s != NULL && len > 0) | ||
| 139 | memmove(str->data, s, len); | ||
| 140 | str->length = len; | ||
| 141 | return 1; | ||
| 142 | } | ||
| 143 | |||
| 144 | _TYPE( int ) | ||
| 145 | cstr_set_length(cstr * str, int len) | ||
| 146 | { | ||
| 147 | if(len < str->length) { | ||
| 148 | str->data[len] = 0; | ||
| 149 | str->length = len; | ||
| 150 | return 1; | ||
| 151 | } | ||
| 152 | else if(len > str->length) { | ||
| 153 | if(cstr_alloc(str, len + 1) < 0) | ||
| 154 | return -1; | ||
| 155 | memset(str->data + str->length, 0, len - str->length + 1); | ||
| 156 | str->length = len; | ||
| 157 | return 1; | ||
| 158 | } | ||
| 159 | else | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | _TYPE( int ) | ||
| 164 | cstr_append(cstr * str, const char * s) | ||
| 165 | { | ||
| 166 | return cstr_appendn(str, s, strlen(s)); | ||
| 167 | } | ||
| 168 | |||
| 169 | _TYPE( int ) | ||
| 170 | cstr_appendn(cstr * str, const char * s, int len) | ||
| 171 | { | ||
| 172 | if(cstr_alloc(str, str->length + len + 1) < 0) | ||
| 173 | return -1; | ||
| 174 | memcpy(str->data + str->length, s, len); | ||
| 175 | str->length += len; | ||
| 176 | str->data[str->length] = 0; | ||
| 177 | return 1; | ||
| 178 | } | ||
| 179 | |||
| 180 | _TYPE( int ) | ||
| 181 | cstr_append_str(cstr * dst, const cstr * src) | ||
| 182 | { | ||
| 183 | return cstr_appendn(dst, src->data, src->length); | ||
| 184 | } | ||
diff --git a/3rd_party/libsrp6a-sha512/cstr.h b/3rd_party/libsrp6a-sha512/cstr.h new file mode 100644 index 0000000..29afea7 --- /dev/null +++ b/3rd_party/libsrp6a-sha512/cstr.h | |||
| @@ -0,0 +1,82 @@ | |||
| 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 | typedef struct cstr_st { | ||
| 55 | char * data; /* Okay to access data and length fields directly */ | ||
| 56 | int length; | ||
| 57 | int cap; | ||
| 58 | int ref; /* Simple reference counter */ | ||
| 59 | } cstr; | ||
| 60 | |||
| 61 | _TYPE( cstr * ) cstr_new P((void)); | ||
| 62 | _TYPE( cstr * ) cstr_dup P((const cstr * str)); | ||
| 63 | _TYPE( cstr * ) cstr_create P((const char * s)); | ||
| 64 | _TYPE( cstr * ) cstr_createn P((const char * s, int len)); | ||
| 65 | |||
| 66 | _TYPE( void ) cstr_free P((cstr * str)); | ||
| 67 | _TYPE( void ) cstr_clear_free P((cstr * str)); | ||
| 68 | _TYPE( void ) cstr_use P((cstr * str)); | ||
| 69 | _TYPE( void ) cstr_empty P((cstr * str)); | ||
| 70 | _TYPE( int ) cstr_copy P((cstr * dst, const cstr * src)); | ||
| 71 | _TYPE( int ) cstr_set P((cstr * str, const char * s)); | ||
| 72 | _TYPE( int ) cstr_setn P((cstr * str, const char * s, int len)); | ||
| 73 | _TYPE( int ) cstr_set_length P((cstr * str, int len)); | ||
| 74 | _TYPE( int ) cstr_append P((cstr * str, const char * s)); | ||
| 75 | _TYPE( int ) cstr_appendn P((cstr * str, const char * s, int len)); | ||
| 76 | _TYPE( int ) cstr_append_str P((cstr * dst, const cstr * src)); | ||
| 77 | |||
| 78 | #ifdef __cplusplus | ||
| 79 | } | ||
| 80 | #endif /* __cplusplus */ | ||
| 81 | |||
| 82 | #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..a2a5fe5 --- /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..34b9509 --- /dev/null +++ b/3rd_party/libsrp6a-sha512/t_misc.c | |||
| @@ -0,0 +1,444 @@ | |||
| 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 | #ifdef __APPLE__ | ||
| 81 | #include <crt_externs.h> | ||
| 82 | #define environ (*_NSGetEnviron()) | ||
| 83 | #else | ||
| 84 | extern char ** environ; | ||
| 85 | #endif | ||
| 86 | |||
| 87 | static void | ||
| 88 | t_envhash(unsigned char * out) | ||
| 89 | { | ||
| 90 | char ** ptr; | ||
| 91 | char ebuf[256]; | ||
| 92 | SHA1_CTX ctxt; | ||
| 93 | |||
| 94 | SHA1Init(&ctxt); | ||
| 95 | for(ptr = environ; *ptr; ++ptr) { | ||
| 96 | strncpy(ebuf, *ptr, 255); | ||
| 97 | ebuf[255] = '\0'; | ||
| 98 | SHA1Update(&ctxt, ebuf, strlen(ebuf)); | ||
| 99 | } | ||
| 100 | SHA1Final(out, &ctxt); | ||
| 101 | } | ||
| 102 | |||
| 103 | /* | ||
| 104 | * t_fshash - Generate a 160-bit SHA hash from the file system | ||
| 105 | * | ||
| 106 | * This routine climbs up the directory tree from the current | ||
| 107 | * directory, running stat() on each directory until it hits the | ||
| 108 | * root directory. This information is sensitive to the last | ||
| 109 | * access/modification times of all the directories above you, | ||
| 110 | * so someone who lists one of those directories injects some | ||
| 111 | * entropy into the system. Obviously, this hash is very sensitive | ||
| 112 | * to your current directory when the program is run. | ||
| 113 | * | ||
| 114 | * For good measure, it also performs an fstat on the standard input, | ||
| 115 | * usually your tty, throws that into the buffer, creates a file in | ||
| 116 | * /tmp (the inode is unpredictable on a busy system), and runs stat() | ||
| 117 | * on that before deleting it. | ||
| 118 | * | ||
| 119 | * The entire buffer is run once through SHA to obtain the final result. | ||
| 120 | */ | ||
| 121 | static void | ||
| 122 | t_fshash(unsigned char * out) | ||
| 123 | { | ||
| 124 | char dotpath[128]; | ||
| 125 | struct stat st; | ||
| 126 | SHA1_CTX ctxt; | ||
| 127 | int i, pinode; | ||
| 128 | dev_t pdev; | ||
| 129 | |||
| 130 | SHA1Init(&ctxt); | ||
| 131 | if(stat(".", &st) >= 0) { | ||
| 132 | SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st)); | ||
| 133 | pinode = st.st_ino; | ||
| 134 | pdev = st.st_dev; | ||
| 135 | strcpy(dotpath, ".."); | ||
| 136 | for(i = 0; i < 40; ++i) { | ||
| 137 | if(stat(dotpath, &st) < 0) | ||
| 138 | break; | ||
| 139 | if(st.st_ino == pinode && st.st_dev == pdev) | ||
| 140 | break; | ||
| 141 | SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st)); | ||
| 142 | pinode = st.st_ino; | ||
| 143 | pdev = st.st_dev; | ||
| 144 | strcat(dotpath, "/.."); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | if(fstat(0, &st) >= 0) | ||
| 149 | SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st)); | ||
| 150 | |||
| 151 | sprintf(dotpath, "/tmp/rnd.%d", getpid()); | ||
| 152 | if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0) | ||
| 153 | SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st)); | ||
| 154 | unlink(dotpath); | ||
| 155 | |||
| 156 | SHA1Final(out, &ctxt); | ||
| 157 | } | ||
| 158 | |||
| 159 | /* | ||
| 160 | * Generate a high-entropy seed for the strong random number generator. | ||
| 161 | * This uses a wide variety of quickly gathered and somewhat unpredictable | ||
| 162 | * system information. The 'preseed' structure is assembled from: | ||
| 163 | * | ||
| 164 | * The system time in seconds | ||
| 165 | * The system time in microseconds | ||
| 166 | * The current process ID | ||
| 167 | * The parent process ID | ||
| 168 | * A hash of the user's environment | ||
| 169 | * A hash gathered from the file system | ||
| 170 | * Input from a random device, if available | ||
| 171 | * Timings of system interrupts | ||
| 172 | * | ||
| 173 | * The entire structure (60 bytes on most systems) is fed to SHA to produce | ||
| 174 | * a 160-bit seed for the strong random number generator. It is believed | ||
| 175 | * that in the worst case (on a quiet system with no random device versus | ||
| 176 | * an attacker who has access to the system already), the seed contains at | ||
| 177 | * least about 80 bits of entropy. Versus an attacker who does not have | ||
| 178 | * access to the system, the entropy should be slightly over 128 bits. | ||
| 179 | */ | ||
| 180 | static char initialized = 0; | ||
| 181 | |||
| 182 | static struct { | ||
| 183 | unsigned int trand1; | ||
| 184 | time_t sec; | ||
| 185 | time_t subsec; | ||
| 186 | short pid; | ||
| 187 | short ppid; | ||
| 188 | unsigned char envh[SHA_DIGESTSIZE]; | ||
| 189 | unsigned char fsh[SHA_DIGESTSIZE]; | ||
| 190 | unsigned char devrand[20]; | ||
| 191 | unsigned int trand2; | ||
| 192 | } preseed; | ||
| 193 | |||
| 194 | unsigned long raw_truerand(); | ||
| 195 | |||
| 196 | static void | ||
| 197 | t_initrand() | ||
| 198 | { | ||
| 199 | SHA1_CTX ctxt; | ||
| 200 | #ifdef USE_FTIME | ||
| 201 | struct timeb t; | ||
| 202 | #else | ||
| 203 | struct timeval t; | ||
| 204 | #endif | ||
| 205 | int i, r=0; | ||
| 206 | |||
| 207 | if(initialized) | ||
| 208 | return; | ||
| 209 | |||
| 210 | initialized = 1; | ||
| 211 | |||
| 212 | #if defined(OPENSSL) /* OpenSSL has nifty win32 entropy-gathering code */ | ||
| 213 | #if OPENSSL_VERSION_NUMBER >= 0x00905100 | ||
| 214 | r = RAND_status(); | ||
| 215 | #if defined(WINDOWS) || defined(_WIN32) | ||
| 216 | if(r) /* Don't do the Unix-y stuff on Windows if possible */ | ||
| 217 | return; | ||
| 218 | #else | ||
| 219 | #endif | ||
| 220 | #endif | ||
| 221 | |||
| 222 | #elif defined(TOMCRYPT) | ||
| 223 | yarrow_start(&g_rng); | ||
| 224 | r = rng_get_bytes(entropy, sizeof(entropy), NULL); | ||
| 225 | if(r > 0) { | ||
| 226 | yarrow_add_entropy(entropy, r, &g_rng); | ||
| 227 | memset(entropy, 0, sizeof(entropy)); | ||
| 228 | # if defined(WINDOWS) || defined(_WIN32) | ||
| 229 | /* Don't do the Unix-y stuff on Windows if possible */ | ||
| 230 | yarrow_ready(&g_rng); | ||
| 231 | return; | ||
| 232 | # endif | ||
| 233 | } | ||
| 234 | #endif | ||
| 235 | |||
| 236 | #if !defined(WINDOWS) && !defined(_WIN32) | ||
| 237 | i = open("/dev/urandom", O_RDONLY); | ||
| 238 | if(i > 0) { | ||
| 239 | r += read(i, preseed.devrand, sizeof(preseed.devrand)); | ||
| 240 | close(i); | ||
| 241 | } | ||
| 242 | #endif /* !WINDOWS && !_WIN32 */ | ||
| 243 | |||
| 244 | /* Resort to truerand only if desperate for some Real entropy */ | ||
| 245 | if(r == 0) | ||
| 246 | preseed.trand1 = raw_truerand(); | ||
| 247 | |||
| 248 | #ifdef USE_FTIME | ||
| 249 | ftime(&t); | ||
| 250 | preseed.sec = t.time; | ||
| 251 | preseed.subsec = t.millitm; | ||
| 252 | #else | ||
| 253 | gettimeofday(&t, NULL); | ||
| 254 | preseed.sec = t.tv_sec; | ||
| 255 | preseed.subsec = t.tv_usec; | ||
| 256 | #endif | ||
| 257 | preseed.pid = getpid(); | ||
| 258 | #ifndef _WIN32 | ||
| 259 | preseed.ppid = getppid(); | ||
| 260 | #endif | ||
| 261 | t_envhash(preseed.envh); | ||
| 262 | t_fshash(preseed.fsh); | ||
| 263 | |||
| 264 | if(r == 0) | ||
| 265 | preseed.trand2 = raw_truerand(); | ||
| 266 | |||
| 267 | #ifdef OPENSSL | ||
| 268 | RAND_seed((unsigned char *)&preseed, sizeof(preseed)); | ||
| 269 | #elif defined(TOMCRYPT) | ||
| 270 | yarrow_add_entropy((unsigned char *)&preseed, sizeof(preseed), &g_rng); | ||
| 271 | yarrow_ready(&g_rng); | ||
| 272 | #elif defined(CRYPTOLIB) | ||
| 273 | t_mgf1(crpool, sizeof(crpool), (unsigned char *) &preseed, sizeof(preseed)); | ||
| 274 | seedDesRandom(crpool, sizeof(crpool)); | ||
| 275 | memset(crpool, 0, sizeof(crpool)); | ||
| 276 | #elif defined(GCRYPT) | ||
| 277 | gcry_random_add_bytes((unsigned char *)&preseed, sizeof(preseed), -1); | ||
| 278 | #else | ||
| 279 | SHA1Init(&ctxt); | ||
| 280 | SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed)); | ||
| 281 | SHA1Final(randpool, &ctxt); | ||
| 282 | memset((unsigned char *) &ctxt, 0, sizeof(ctxt)); | ||
| 283 | outpos = 0; | ||
| 284 | #endif /* OPENSSL */ | ||
| 285 | memset((unsigned char *) &preseed, 0, sizeof(preseed)); | ||
| 286 | } | ||
| 287 | |||
| 288 | #define NUM_RANDOMS 12 | ||
| 289 | |||
| 290 | _TYPE( void ) | ||
| 291 | t_stronginitrand() | ||
| 292 | { | ||
| 293 | #if 1 /* t_initrand() has been improved enough to make this unnecessary */ | ||
| 294 | t_initrand(); | ||
| 295 | #else | ||
| 296 | SHA1_CTX ctxt; | ||
| 297 | unsigned int rawrand[NUM_RANDOMS]; | ||
| 298 | int i; | ||
| 299 | |||
| 300 | if(!initialized) | ||
| 301 | t_initrand(); | ||
| 302 | for(i = 0; i < NUM_RANDOMS; ++i) | ||
| 303 | rawrand[i] = raw_truerand(); | ||
| 304 | SHA1Init(&ctxt); | ||
| 305 | SHA1Update(&ctxt, (unsigned char *) rawrand, sizeof(rawrand)); | ||
| 306 | SHA1Final(randkey2, &ctxt); | ||
| 307 | memset(rawrand, 0, sizeof(rawrand)); | ||
| 308 | #endif | ||
| 309 | } | ||
| 310 | |||
| 311 | /* | ||
| 312 | * The strong random number generator. This uses a 160-bit seed | ||
| 313 | * and uses SHA-1 in a feedback configuration to generate successive | ||
| 314 | * outputs. If S[0] is set to the initial seed, then: | ||
| 315 | * | ||
| 316 | * S[i+1] = SHA-1(i || S[i]) | ||
| 317 | * A[i] = SHA-1(S[i]) | ||
| 318 | * | ||
| 319 | * where the A[i] are the output blocks starting with i=0. | ||
| 320 | * Each cycle generates 20 bytes of new output. | ||
| 321 | */ | ||
| 322 | _TYPE( void ) | ||
| 323 | t_random(unsigned char * data, unsigned size) | ||
| 324 | { | ||
| 325 | if(!initialized) | ||
| 326 | t_initrand(); | ||
| 327 | |||
| 328 | if(size <= 0) /* t_random(NULL, 0) forces seed initialization */ | ||
| 329 | return; | ||
| 330 | |||
| 331 | #ifdef OPENSSL | ||
| 332 | RAND_bytes(data, size); | ||
| 333 | #elif defined(TOMCRYPT) | ||
| 334 | yarrow_read(data, size, &g_rng); | ||
| 335 | #elif defined(GCRYPT) | ||
| 336 | gcry_randomize(data, size, GCRY_STRONG_RANDOM); | ||
| 337 | #elif defined(CRYPTOLIB) | ||
| 338 | randomBytes(data, size, PSEUDO); | ||
| 339 | #else | ||
| 340 | while(size > outpos) { | ||
| 341 | if(outpos > 0) { | ||
| 342 | memcpy(data, randout + (sizeof(randout) - outpos), outpos); | ||
| 343 | data += outpos; | ||
| 344 | size -= outpos; | ||
| 345 | } | ||
| 346 | |||
| 347 | /* Recycle */ | ||
| 348 | SHA1Init(&randctxt); | ||
| 349 | SHA1Update(&randctxt, randpool, sizeof(randpool)); | ||
| 350 | SHA1Final(randout, &randctxt); | ||
| 351 | SHA1Init(&randctxt); | ||
| 352 | SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt)); | ||
| 353 | SHA1Update(&randctxt, randpool, sizeof(randpool)); | ||
| 354 | SHA1Final(randpool, &randctxt); | ||
| 355 | ++randcnt; | ||
| 356 | outpos = sizeof(randout); | ||
| 357 | } | ||
| 358 | |||
| 359 | if(size > 0) { | ||
| 360 | memcpy(data, randout + (sizeof(randout) - outpos), size); | ||
| 361 | outpos -= size; | ||
| 362 | } | ||
| 363 | #endif | ||
| 364 | } | ||
| 365 | |||
| 366 | /* | ||
| 367 | * The interleaved session-key hash. This separates the even and the odd | ||
| 368 | * bytes of the input (ignoring the first byte if the input length is odd), | ||
| 369 | * hashes them separately, and re-interleaves the two outputs to form a | ||
| 370 | * single 320-bit value. | ||
| 371 | */ | ||
| 372 | _TYPE( unsigned char * ) | ||
| 373 | t_sessionkey(unsigned char * key, unsigned char * sk, unsigned sklen) | ||
| 374 | { | ||
| 375 | unsigned i, klen; | ||
| 376 | unsigned char * hbuf; | ||
| 377 | unsigned char hout[SHA_DIGESTSIZE]; | ||
| 378 | SHA1_CTX ctxt; | ||
| 379 | |||
| 380 | while(sklen > 0 && *sk == 0) { /* Skip leading 0's */ | ||
| 381 | --sklen; | ||
| 382 | ++sk; | ||
| 383 | } | ||
| 384 | |||
| 385 | klen = sklen / 2; | ||
| 386 | if((hbuf = malloc(klen * sizeof(char))) == 0) | ||
| 387 | return 0; | ||
| 388 | |||
| 389 | for(i = 0; i < klen; ++i) | ||
| 390 | hbuf[i] = sk[sklen - 2 * i - 1]; | ||
| 391 | SHA1Init(&ctxt); | ||
| 392 | SHA1Update(&ctxt, hbuf, klen); | ||
| 393 | SHA1Final(hout, &ctxt); | ||
| 394 | for(i = 0; i < sizeof(hout); ++i) | ||
| 395 | key[2 * i] = hout[i]; | ||
| 396 | |||
| 397 | for(i = 0; i < klen; ++i) | ||
| 398 | hbuf[i] = sk[sklen - 2 * i - 2]; | ||
| 399 | SHA1Init(&ctxt); | ||
| 400 | SHA1Update(&ctxt, hbuf, klen); | ||
| 401 | SHA1Final(hout, &ctxt); | ||
| 402 | for(i = 0; i < sizeof(hout); ++i) | ||
| 403 | key[2 * i + 1] = hout[i]; | ||
| 404 | |||
| 405 | memset(hout, 0, sizeof(hout)); | ||
| 406 | memset(hbuf, 0, klen); | ||
| 407 | free(hbuf); | ||
| 408 | return key; | ||
| 409 | } | ||
| 410 | |||
| 411 | _TYPE( void ) | ||
| 412 | t_mgf1(unsigned char * mask, unsigned masklen, const unsigned char * seed, unsigned seedlen) | ||
| 413 | { | ||
| 414 | SHA1_CTX ctxt; | ||
| 415 | unsigned i = 0; | ||
| 416 | unsigned pos = 0; | ||
| 417 | unsigned char cnt[4]; | ||
| 418 | unsigned char hout[SHA_DIGESTSIZE]; | ||
| 419 | |||
| 420 | while(pos < masklen) { | ||
| 421 | cnt[0] = (i >> 24) & 0xFF; | ||
| 422 | cnt[1] = (i >> 16) & 0xFF; | ||
| 423 | cnt[2] = (i >> 8) & 0xFF; | ||
| 424 | cnt[3] = i & 0xFF; | ||
| 425 | SHA1Init(&ctxt); | ||
| 426 | SHA1Update(&ctxt, seed, seedlen); | ||
| 427 | SHA1Update(&ctxt, cnt, 4); | ||
| 428 | |||
| 429 | if(pos + SHA_DIGESTSIZE > masklen) { | ||
| 430 | SHA1Final(hout, &ctxt); | ||
| 431 | memcpy(mask + pos, hout, masklen - pos); | ||
| 432 | pos = masklen; | ||
| 433 | } | ||
| 434 | else { | ||
| 435 | SHA1Final(mask + pos, &ctxt); | ||
| 436 | pos += SHA_DIGESTSIZE; | ||
| 437 | } | ||
| 438 | |||
| 439 | ++i; | ||
| 440 | } | ||
| 441 | |||
| 442 | memset(hout, 0, sizeof(hout)); | ||
| 443 | memset((unsigned char *)&ctxt, 0, sizeof(ctxt)); | ||
| 444 | } | ||
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..cd27d0d --- /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 */ | ||
