Browse Source
Password hashing functions are designed to be slow. Make them slower, but also useful.coverity_scan
Frank Denis
5 years ago
19 changed files with 592 additions and 1 deletions
@ -0,0 +1,214 @@ |
|||
AC_DEFUN([LIBCURL_CHECK_CONFIG], |
|||
[ |
|||
AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI]) |
|||
AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM]) |
|||
|
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP]) |
|||
AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP]) |
|||
|
|||
AC_ARG_WITH(libcurl, |
|||
AS_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]), |
|||
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) |
|||
|
|||
if test "$_libcurl_with" != "no" ; then |
|||
|
|||
AC_PROG_AWK |
|||
|
|||
_libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" |
|||
|
|||
_libcurl_try_link=yes |
|||
|
|||
if test -d "$_libcurl_with" ; then |
|||
LIBCURL_CPPFLAGS="-I$withval/include" |
|||
_libcurl_ldflags="-L$withval/lib" |
|||
AC_PATH_PROG([_libcurl_config],[curl-config],[], |
|||
["$withval/bin"]) |
|||
else |
|||
AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH]) |
|||
fi |
|||
|
|||
if test x$_libcurl_config != "x" ; then |
|||
AC_CACHE_CHECK([for the version of libcurl], |
|||
[libcurl_cv_lib_curl_version], |
|||
[libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) |
|||
|
|||
_libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` |
|||
_libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` |
|||
|
|||
if test $_libcurl_wanted -gt 0 ; then |
|||
AC_CACHE_CHECK([for libcurl >= version $2], |
|||
[libcurl_cv_lib_version_ok], |
|||
[ |
|||
if test $_libcurl_version -ge $_libcurl_wanted ; then |
|||
libcurl_cv_lib_version_ok=yes |
|||
else |
|||
libcurl_cv_lib_version_ok=no |
|||
fi |
|||
]) |
|||
fi |
|||
|
|||
if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then |
|||
if test x"$LIBCURL_CPPFLAGS" = "x" ; then |
|||
LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` |
|||
fi |
|||
if test x"$LIBCURL" = "x" ; then |
|||
LIBCURL=`$_libcurl_config --libs` |
|||
|
|||
# This is so silly, but Apple actually has a bug in their |
|||
# curl-config script. Fixed in Tiger, but there are still |
|||
# lots of Panther installs around. |
|||
case "${host}" in |
|||
powerpc-apple-darwin7*) |
|||
LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` |
|||
;; |
|||
esac |
|||
fi |
|||
|
|||
# All curl-config scripts support --feature |
|||
_libcurl_features=`$_libcurl_config --feature` |
|||
|
|||
# Is it modern enough to have --protocols? (7.12.4) |
|||
if test $_libcurl_version -ge 461828 ; then |
|||
_libcurl_protocols=`$_libcurl_config --protocols` |
|||
fi |
|||
else |
|||
_libcurl_try_link=no |
|||
fi |
|||
|
|||
unset _libcurl_wanted |
|||
fi |
|||
|
|||
if test $_libcurl_try_link = yes ; then |
|||
|
|||
# we didn't find curl-config, so let's see if the user-supplied |
|||
# link line (or failing that, "-lcurl") is enough. |
|||
LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"} |
|||
|
|||
AC_CACHE_CHECK([whether libcurl is usable], |
|||
[libcurl_cv_lib_curl_usable], |
|||
[ |
|||
_libcurl_save_cppflags=$CPPFLAGS |
|||
CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS" |
|||
_libcurl_save_libs=$LIBS |
|||
LIBS="$LIBCURL $LIBS" |
|||
|
|||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[ |
|||
/* Try and use a few common options to force a failure if we are |
|||
missing symbols or can't link. */ |
|||
int x; |
|||
curl_easy_setopt(NULL,CURLOPT_URL,NULL); |
|||
x=CURL_ERROR_SIZE; |
|||
x=CURLOPT_WRITEFUNCTION; |
|||
x=CURLOPT_WRITEDATA; |
|||
x=CURLOPT_ERRORBUFFER; |
|||
x=CURLOPT_STDERR; |
|||
x=CURLOPT_VERBOSE; |
|||
if (x) {;} |
|||
]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) |
|||
|
|||
CPPFLAGS=$_libcurl_save_cppflags |
|||
LIBS=$_libcurl_save_libs |
|||
unset _libcurl_save_cppflags |
|||
unset _libcurl_save_libs |
|||
]) |
|||
|
|||
if test $libcurl_cv_lib_curl_usable = yes ; then |
|||
|
|||
# Does curl_free() exist in this version of libcurl? |
|||
# If not, fake it with free() |
|||
|
|||
_libcurl_save_cppflags=$CPPFLAGS |
|||
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" |
|||
_libcurl_save_libs=$LIBS |
|||
LIBS="$LIBS $LIBCURL" |
|||
|
|||
AC_CHECK_FUNC(curl_free,, |
|||
AC_DEFINE(curl_free,free, |
|||
[Define curl_free() as free() if our version of curl lacks curl_free.])) |
|||
|
|||
CPPFLAGS=$_libcurl_save_cppflags |
|||
LIBS=$_libcurl_save_libs |
|||
unset _libcurl_save_cppflags |
|||
unset _libcurl_save_libs |
|||
|
|||
AC_DEFINE(HAVE_LIBCURL,1, |
|||
[Define to 1 if you have a functional curl library.]) |
|||
AC_SUBST(LIBCURL_CPPFLAGS) |
|||
AC_SUBST(LIBCURL) |
|||
|
|||
for _libcurl_feature in $_libcurl_features ; do |
|||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) |
|||
eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes |
|||
done |
|||
|
|||
if test "x$_libcurl_protocols" = "x" ; then |
|||
|
|||
# We don't have --protocols, so just assume that all |
|||
# protocols are available |
|||
_libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP" |
|||
|
|||
if test x$libcurl_feature_SSL = xyes ; then |
|||
_libcurl_protocols="$_libcurl_protocols HTTPS" |
|||
|
|||
# FTPS wasn't standards-compliant until version |
|||
# 7.11.0 (0x070b00 == 461568) |
|||
if test $_libcurl_version -ge 461568; then |
|||
_libcurl_protocols="$_libcurl_protocols FTPS" |
|||
fi |
|||
fi |
|||
|
|||
# RTSP, IMAP, POP3 and SMTP were added in |
|||
# 7.20.0 (0x071400 == 463872) |
|||
if test $_libcurl_version -ge 463872; then |
|||
_libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP" |
|||
fi |
|||
fi |
|||
|
|||
for _libcurl_protocol in $_libcurl_protocols ; do |
|||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) |
|||
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes |
|||
done |
|||
else |
|||
unset LIBCURL |
|||
unset LIBCURL_CPPFLAGS |
|||
fi |
|||
fi |
|||
|
|||
unset _libcurl_try_link |
|||
unset _libcurl_version_parse |
|||
unset _libcurl_config |
|||
unset _libcurl_feature |
|||
unset _libcurl_features |
|||
unset _libcurl_protocol |
|||
unset _libcurl_protocols |
|||
unset _libcurl_version |
|||
unset _libcurl_ldflags |
|||
fi |
|||
|
|||
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then |
|||
# This is the IF-NO path |
|||
ifelse([$4],,:,[$4]) |
|||
else |
|||
# This is the IF-YES path |
|||
ifelse([$3],,:,[$3]) |
|||
fi |
|||
|
|||
unset _libcurl_with |
|||
])dnl |
@ -0,0 +1,307 @@ |
|||
#include <limits.h> |
|||
#include <stdint.h> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
#include <curl/curl.h> |
|||
|
|||
#define ARENA_SIZE ((size_t) 1000000) |
|||
#define LEVEL_FIRST 1 |
|||
#define LEVEL_LAST 5 |
|||
#define LEVELS (LEVEL_LAST - LEVEL_FIRST + 1) |
|||
#define URL "https://crypto.sx/hedgehogcoin/miner"
|
|||
|
|||
#define SUFFIX_LEN 32 |
|||
#define HASHSEQ_LOCATIONS 8 |
|||
#define ROTR32(X, B) (uint32_t)(((X) >> (B)) | ((X) << (32 - (B)))) |
|||
|
|||
#define G(A, B, C, D) \ |
|||
do { \ |
|||
(A) += (B); \ |
|||
(D) = ROTR32((D) ^ (A), 16); \ |
|||
(C) += (D); \ |
|||
(B) = ROTR32((B) ^ (C), 12); \ |
|||
(A) += (B); \ |
|||
(D) = ROTR32((D) ^ (A), 8); \ |
|||
(C) += (D); \ |
|||
(B) = ROTR32((B) ^ (C), 7); \ |
|||
} while (0) |
|||
|
|||
static const uint32_t IV[8] = { |
|||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, |
|||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 |
|||
}; |
|||
|
|||
typedef struct DynBuf { |
|||
char * ptr; |
|||
size_t len; |
|||
} DynBuf; |
|||
|
|||
typedef struct Mask_ { |
|||
uint32_t m0; |
|||
uint32_t m1; |
|||
} Mask; |
|||
|
|||
typedef struct HashSeqArena_ { |
|||
uint32_t *base; |
|||
uint32_t mask; |
|||
uint32_t size; |
|||
} HashSeqArena; |
|||
|
|||
typedef struct HashSeqSolution_ { |
|||
uint32_t s0; |
|||
uint32_t s1; |
|||
} HashSeqSolution; |
|||
|
|||
static inline void |
|||
permute(uint32_t state[16]) |
|||
{ |
|||
G(state[0], state[4], state[8], state[12]); |
|||
G(state[1], state[5], state[9], state[13]); |
|||
G(state[2], state[6], state[10], state[14]); |
|||
G(state[3], state[7], state[11], state[15]); |
|||
|
|||
G(state[0], state[5], state[10], state[15]); |
|||
G(state[1], state[6], state[11], state[12]); |
|||
G(state[2], state[7], state[8], state[13]); |
|||
G(state[3], state[4], state[9], state[14]); |
|||
} |
|||
|
|||
static inline void |
|||
hash_init(uint32_t state[16], const uint32_t suffix[8], uint32_t level, |
|||
uint32_t iteration) |
|||
{ |
|||
int i; |
|||
|
|||
memcpy(&state[0], IV, 8 * sizeof state[0]); |
|||
state[7] ^= (level << 16) | iteration; |
|||
for (i = 0; i < 8; i++) { |
|||
state[8 + i] = IV[i] ^ suffix[i]; |
|||
} |
|||
} |
|||
|
|||
static int |
|||
hash_try(HashSeqArena *arena, uint32_t ostate[16], uint32_t istate[16], |
|||
const HashSeqSolution *proposal, const Mask *mask) |
|||
{ |
|||
uint32_t *locations[2 * HASHSEQ_LOCATIONS], *location1, *location2; |
|||
uint32_t f0, f1; |
|||
uint32_t pass, passes; |
|||
uint32_t off; |
|||
size_t i, j; |
|||
|
|||
passes = arena->size; |
|||
istate[0] = IV[0] ^ proposal->s0; |
|||
istate[1] = IV[1] ^ proposal->s1; |
|||
memcpy(ostate, istate, 16 * sizeof ostate[0]); |
|||
for (i = 0; i < 5; i++) { |
|||
permute(ostate); |
|||
} |
|||
for (pass = 0; pass < passes; pass++) { |
|||
for (i = 0; i < sizeof locations / sizeof locations[0]; i++) { |
|||
permute(ostate); |
|||
locations[i] = &arena->base[ostate[0] & arena->mask]; |
|||
} |
|||
for (i = 0; i < sizeof locations / sizeof locations[0] / 2; i++) { |
|||
location1 = locations[i]; |
|||
location2 = |
|||
locations[i + sizeof locations / sizeof locations[0] / 2]; |
|||
permute(ostate); |
|||
for (j = 0; j < 16; j++) { |
|||
location1[i] ^= location2[i] + ostate[i]; |
|||
} |
|||
} |
|||
} |
|||
for (off = 0; off <= arena->size - 8 * sizeof ostate[0]; |
|||
off += 8 * sizeof ostate[0]) { |
|||
for (i = 0; i < 8; i++) { |
|||
ostate[i] ^= arena->base[off + i]; |
|||
} |
|||
permute(ostate); |
|||
} |
|||
f0 = ostate[0]; |
|||
f1 = ostate[1]; |
|||
for (i = 2; i < 16; i += 2) { |
|||
f0 ^= ostate[i]; |
|||
f1 ^= ostate[i + 1]; |
|||
} |
|||
return ((f0 & mask->m0) | (f1 & mask->m1)) == 0U; |
|||
} |
|||
|
|||
static void |
|||
mask_from_level(Mask *mask, uint32_t level) |
|||
{ |
|||
if (level > 32U) { |
|||
mask->m0 = ~0U; |
|||
mask->m1 = (1U << (level - 32)) - 1U; |
|||
} else { |
|||
mask->m1 = 0U; |
|||
mask->m0 = (1U << level) - 1U; |
|||
} |
|||
} |
|||
|
|||
static int |
|||
solve1(HashSeqArena *arena, HashSeqSolution *solution, uint32_t suffix[8], |
|||
uint32_t level, uint32_t iteration) |
|||
{ |
|||
uint32_t istate[16], ostate[16]; |
|||
Mask mask; |
|||
HashSeqSolution proposal; |
|||
|
|||
hash_init(istate, suffix, level, iteration); |
|||
mask_from_level(&mask, level); |
|||
proposal.s0 = proposal.s1 = 0U; |
|||
while (hash_try(arena, ostate, istate, &proposal, &mask) == 0) { |
|||
if (++proposal.s0 == 0U) { |
|||
proposal.s1++; |
|||
} |
|||
} |
|||
memcpy(suffix, &ostate[8], 8 * sizeof ostate[0]); |
|||
memcpy(solution, &proposal, sizeof *solution); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static int |
|||
hashseq_arena_init(HashSeqArena *arena, uint32_t *base, size_t size) |
|||
{ |
|||
uint32_t mask; |
|||
|
|||
memset(base, 0, size); |
|||
size /= sizeof base[0]; |
|||
if (size < 32 || size > (size_t)(uint32_t) -1) { |
|||
return -1; |
|||
} |
|||
arena->base = base; |
|||
arena->size = (uint32_t) size; |
|||
mask = 0U; |
|||
while (mask < (size >> 1)) { |
|||
mask = (mask << 1) | 1; |
|||
} |
|||
mask &= ~15U; |
|||
if (mask == 0U) { |
|||
return -1; |
|||
} |
|||
arena->mask = mask; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static int |
|||
hashseq_solve(HashSeqArena *arena, HashSeqSolution *solutions, |
|||
const uint32_t suffix[8], uint32_t level_first, |
|||
uint32_t level_last, uint32_t iterations) |
|||
{ |
|||
uint32_t suffix_[8]; |
|||
uint32_t level, iteration; |
|||
int i = 0; |
|||
|
|||
memcpy(suffix_, suffix, sizeof suffix_); |
|||
for (level = level_first; level <= level_last; level++) { |
|||
for (iteration = 0; iteration < iterations; iteration++) { |
|||
if (solve1(arena, &solutions[i++], suffix_, level, iteration)) { |
|||
return -1; |
|||
} |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static size_t |
|||
writefunc(void *ptr, size_t size, size_t nmemb, DynBuf *db) |
|||
{ |
|||
size_t new_len; |
|||
|
|||
if (SIZE_MAX - db->len < size * nmemb) { |
|||
abort(); |
|||
} |
|||
new_len = db->len + size * nmemb; |
|||
db->ptr = (char *) realloc(db->ptr, new_len + 1); |
|||
if (db->ptr == NULL) { |
|||
abort(); |
|||
} |
|||
memcpy(db->ptr + db->len, ptr, size * nmemb); |
|||
db->ptr[new_len] = 0; |
|||
db->len = new_len; |
|||
|
|||
return size * nmemb; |
|||
} |
|||
|
|||
static int |
|||
mine(HashSeqSolution solutions[LEVELS], const char *suffix_) |
|||
{ |
|||
HashSeqArena arena; |
|||
const uint32_t *suffix = (const uint32_t *) (const void *) suffix_; |
|||
uint32_t * buf; |
|||
|
|||
if ((buf = malloc(ARENA_SIZE)) == NULL) { |
|||
abort(); |
|||
} |
|||
hashseq_arena_init(&arena, buf, ARENA_SIZE); |
|||
hashseq_solve(&arena, solutions, suffix, LEVEL_FIRST, LEVEL_LAST, 1); |
|||
free(buf); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
int |
|||
crypto_pwhash_hedgehogcoin_mine(void) |
|||
{ |
|||
const char * url = URL; |
|||
unsigned char * response; |
|||
CURL * curl; |
|||
struct curl_slist *headers; |
|||
char * suffix; |
|||
HashSeqSolution solutions[LEVELS]; |
|||
DynBuf db; |
|||
CURLcode res; |
|||
size_t response_len; |
|||
|
|||
curl_global_init(CURL_GLOBAL_DEFAULT); |
|||
curl = curl_easy_init(); |
|||
if (curl == NULL) { |
|||
return -1; |
|||
} |
|||
curl_easy_setopt(curl, CURLOPT_URL, url); |
|||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); |
|||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); |
|||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); |
|||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &db); |
|||
db.len = 0; |
|||
db.ptr = NULL; |
|||
res = curl_easy_perform(curl); |
|||
if (res != CURLE_OK && db.len != SUFFIX_LEN) { |
|||
curl_easy_cleanup(curl); |
|||
curl_global_cleanup(); |
|||
return -1; |
|||
} |
|||
suffix = db.ptr; |
|||
mine(solutions, suffix); |
|||
|
|||
response_len = SUFFIX_LEN + sizeof solutions; |
|||
if ((response = malloc(response_len)) == NULL) { |
|||
free(suffix); |
|||
curl_easy_cleanup(curl); |
|||
curl_global_cleanup(); |
|||
return -1; |
|||
} |
|||
memcpy(response, suffix, SUFFIX_LEN); |
|||
memcpy(response + SUFFIX_LEN, solutions, sizeof solutions); |
|||
free(suffix); |
|||
|
|||
db.len = 0; |
|||
db.ptr = NULL; |
|||
headers = curl_slist_append(NULL, "Content-Type: application/hedgehogcoin"); |
|||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); |
|||
curl_easy_setopt(curl, CURLOPT_POST, 1L); |
|||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (const void *) solutions); |
|||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, sizeof solutions); |
|||
(void) curl_easy_perform(curl); |
|||
free(db.ptr); |
|||
curl_slist_free_all(headers); |
|||
curl_easy_cleanup(curl); |
|||
curl_global_cleanup(); |
|||
|
|||
return 0; |
|||
} |
@ -0,0 +1,6 @@ |
|||
#ifndef crypto_pwhash_hedgehogcoin_H |
|||
#define crypto_pwhash_hedgehogcoin_H |
|||
|
|||
int crypto_pwhash_hedgehogcoin_mine(void); |
|||
|
|||
#endif |
Loading…
Reference in new issue