diff --git a/CMakeLists.txt b/CMakeLists.txt index 16901a4..de4d079 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,10 +292,11 @@ set(3PROXY_CORE_SOURCES src/stringtable.c ) -# MD4/MD5 sources for mycrypt +# MD4/MD5/BLAKE2 sources for 3proxy_crypt set(MD_SOURCES src/libs/md4.c src/libs/md5.c + src/libs/blake2b-ref.c ) # ============================================================================ @@ -348,9 +349,9 @@ target_compile_definitions(mainfunc PRIVATE MODULEMAINFUNC=mainfunc) add_library(ftp_obj OBJECT src/ftp.c) target_include_directories(ftp_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -# mycrypt object for 3proxy (without WITHMAIN) -add_library(mycrypt_obj OBJECT src/mycrypt.c) -target_include_directories(mycrypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) +# 3proxy_crypt object for 3proxy (without WITHMAIN) +add_library(3proxy_crypt_obj OBJECT src/3proxy_crypt.c) +target_include_directories(3proxy_crypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) # ============================================================================ # Main 3proxy executable @@ -365,7 +366,7 @@ add_executable(3proxy $ $ $ - $ + $ ) target_include_directories(3proxy PRIVATE @@ -398,18 +399,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() endif() -# Build mycrypt utility -add_executable(mycrypt - src/mycrypt.c +# Build 3proxy_crypt utility +add_executable(3proxy_crypt + src/3proxy_crypt.c ${MD_SOURCES} $ ) -target_compile_definitions(mycrypt PRIVATE WITHMAIN) -target_include_directories(mycrypt PRIVATE +target_compile_definitions(3proxy_crypt PRIVATE WITHMAIN) +target_include_directories(3proxy_crypt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/libs ) -target_link_libraries(mycrypt PRIVATE Threads::Threads) +target_link_libraries(3proxy_crypt PRIVATE Threads::Threads) # Build standalone proxy executables foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr) @@ -496,7 +497,7 @@ if(PAM_FOUND) endif() # Installation rules -install(TARGETS 3proxy mycrypt proxy socks pop3p smtpp ftppr tcppm udppm tlspr +install(TARGETS 3proxy 3proxy_crypt proxy socks pop3p smtpp ftppr tcppm udppm tlspr RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/bin/3proxy_crypt b/bin/3proxy_crypt new file mode 100644 index 0000000..3eb0ef0 Binary files /dev/null and b/bin/3proxy_crypt differ diff --git a/src/mycrypt.c b/src/3proxy_crypt.c similarity index 75% rename from src/mycrypt.c rename to src/3proxy_crypt.c index ada3f5e..2c10716 100644 --- a/src/mycrypt.c +++ b/src/3proxy_crypt.c @@ -5,8 +5,11 @@ please read License Agreement */ +#ifndef WITHMAIN #include "libs/md5.h" +#endif #include "libs/md4.h" +#include "libs/blake2.h" #include #define MD5_SIZE 16 @@ -64,20 +67,20 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){ const unsigned char *ep; + unsigned char *magic; + unsigned char *p; + const unsigned char *sp; + unsigned char final[MD5_SIZE]; + int sl,pl,i; + unsigned long l; + +#ifndef WITHMAIN if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) { - static unsigned char *magic = (unsigned char *)"$1$"; - unsigned char *p; - const unsigned char *sp; - unsigned char final[MD5_SIZE]; - int sl,pl,i; MD5_CTX ctx,ctx1; - unsigned long l; - /* Refine the Salt first */ sp = salt +3; - - /* get the length of the true salt */ sl = (int)(ep - sp); + magic = (unsigned char *)"$1$"; MD5Init(&ctx); @@ -109,10 +112,6 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi else MD5Update(&ctx, pw, 1); - /* Now make the output string */ - strcpy((char *)passwd,(char *)magic); - strncat((char *)passwd,(char *)sp,sl); - strcat((char *)passwd,"$"); MD5Final(final,&ctx); @@ -141,28 +140,42 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi MD5Final(final,&ctx1); } - p = passwd + strlen((char *)passwd); - - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; - _crypt_to64(p,l,4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; - _crypt_to64(p,l,4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; - _crypt_to64(p,l,4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; - _crypt_to64(p,l,4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; - _crypt_to64(p,l,4); p += 4; - l = final[11] ; - _crypt_to64(p,l,2); p += 2; - *p = '\0'; /* Don't leave anything around in vm they could use. */ memset(final,0,sizeof final); } + else +#endif + if(salt[0] == '$' && salt[1] == '3' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) { + sp = salt +3; + sl = (int)(ep - sp); + magic = (unsigned char *)"$3$"; + + blake2b(final, MD5_SIZE, pw, strlen((char *)pw), salt, strlen((char *)salt) ); + } else { *passwd = 0; + return passwd; } + + strcpy((char *)passwd,(char *)magic); + strncat((char *)passwd,(char *)sp,sl); + strcat((char *)passwd,"$"); + p = passwd + strlen((char *)passwd); + + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; + _crypt_to64(p,l,4); p += 4; + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; + _crypt_to64(p,l,4); p += 4; + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; + _crypt_to64(p,l,4); p += 4; + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; + _crypt_to64(p,l,4); p += 4; + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; + _crypt_to64(p,l,4); p += 4; + l = final[11] ; + _crypt_to64(p,l,2); p += 2; + *p = '\0'; return passwd; } @@ -176,7 +189,7 @@ int main(int argc, char* argv[]){ fprintf(stderr, "usage: \n" "\t%s \n" "\t%s \n" - "Performs NT crypt if no salt specified, MD5 crypt with salt\n" + "Performs NT crypt if no salt specified, BLAKE2 crypt with salt\n" "This software uses:\n" " RSA Data Security, Inc. MD4 Message-Digest Algorithm\n" " RSA Data Security, Inc. MD5 Message-Digest Algorithm\n", @@ -190,7 +203,7 @@ int main(int argc, char* argv[]){ else { i = (int)strlen((char *)argv[1]); if (i > 64) argv[1][64] = 0; - sprintf((char *)buf, "$1$%s$", argv[1]); + sprintf((char *)buf, "$3$%s$", argv[1]); printf("CR:%s\n", mycrypt((unsigned char *)argv[2], buf, buf+256)); } return 0; diff --git a/src/Makefile.inc b/src/Makefile.inc index 099e7b6..ff8cb83 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -2,7 +2,7 @@ # 3 proxy common Makefile # -all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins +all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h @@ -122,6 +122,9 @@ auth$(OBJSUFFICS): auth.c proxy.h structures.h hash$(OBJSUFFICS): hash.c proxy.h structures.h $(CC) $(COUT)hash$(OBJSUFFICS) $(CFLAGS) hash.c +resolve$(OBJSUFFICS): resolve.c proxy.h structures.h + $(CC) $(COUT)resolve$(OBJSUFFICS) $(CFLAGS) resolve.c + authradius$(OBJSUFFICS): authradius.c proxy.h structures.h $(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c @@ -134,15 +137,11 @@ log$(OBJSUFFICS): log.c proxy.h structures.h datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h $(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c -mycrypt$(OBJSUFFICS): mycrypt.c - $(CC) $(COUT)mycrypt$(OBJSUFFICS) $(CFLAGS) mycrypt.c - -mycryptmain$(OBJSUFFICS): mycrypt.c - $(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c - -$(BUILDDIR)mycrypt$(EXESUFFICS): md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycryptmain$(OBJSUFFICS) base64$(OBJSUFFICS) - $(LN) $(LNOUT)$(BUILDDIR)mycrypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) base64$(OBJSUFFICS) mycryptmain$(OBJSUFFICS) +3proxy_crypt$(OBJSUFFICS): 3proxy_crypt.c + $(CC) $(COUT)3proxy_crypt$(OBJSUFFICS) $(CFLAGS) 3proxy_crypt.c +3proxy_cryptmain$(OBJSUFFICS): 3proxy_crypt.c + $(CC) $(COUT)3proxy_cryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN 3proxy_crypt.c md4$(OBJSUFFICS): libs/md4.h libs/md4.c $(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c @@ -150,9 +149,15 @@ md4$(OBJSUFFICS): libs/md4.h libs/md4.c md5$(OBJSUFFICS): libs/md5.h libs/md5.c $(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c +blake2$(OBJSUFFICS): libs/blake2.h libs/blake2-impl.h libs/blake2b-ref.c + $(CC) $(COUT)blake2$(OBJSUFFICS) $(CFLAGS) libs/blake2b-ref.c + +$(BUILDDIR)3proxy_crypt$(EXESUFFICS): md4$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS) + $(LN) $(LNOUT)$(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) + stringtable$(OBJSUFFICS): stringtable.c $(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c -$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP) - $(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS) +$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP) + $(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS) diff --git a/src/hash.c b/src/hash.c index 5745bba..584c446 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1,21 +1,16 @@ #include "proxy.h" +#include "libs/blake2.h" - -static unsigned hashindex(struct hashtable *ht, const unsigned char* hash){ - unsigned t1, t2, t3, t4; - t1 = *(unsigned *)hash; - t2 = *(unsigned *)(hash + sizeof(unsigned)); - t3 = *(unsigned *)(hash + (2*sizeof(unsigned))); - t4 = *(unsigned *)(hash + (3*sizeof(unsigned))); - return (t1 + (t2 * 7) + (t3 * 17) + (t4 * 29) ) % (ht->tablesize); +static unsigned hashindex(struct hashtable *ht, const uint8_t* hash){ + return (*(unsigned *)hash ) % (ht->tablesize); } void destroyhashtable(struct hashtable *ht){ pthread_mutex_lock(&hash_mutex); - if(ht->hashtable){ - myfree(ht->hashtable); - ht->hashtable = NULL; + if(ht->ihashtable){ + myfree(ht->ihashtable); + ht->ihashtable = NULL; } if(ht->hashvalues){ myfree(ht->hashvalues); @@ -26,7 +21,7 @@ void destroyhashtable(struct hashtable *ht){ pthread_mutex_unlock(&hash_mutex); } -#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I)*(sizeof(struct hashentry) + ht->recsize - 4))) +#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4))) int inithashtable(struct hashtable *ht, unsigned nhashsize){ unsigned i; @@ -47,124 +42,124 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){ if(nhashsize<4) return 1; pthread_mutex_lock(&hash_mutex); - if(ht->hashtable){ - myfree(ht->hashtable); - ht->hashtable = NULL; + if(ht->ihashtable){ + myfree(ht->ihashtable); + ht->ihashtable = NULL; } if(ht->hashvalues){ myfree(ht->hashvalues); ht->hashvalues = NULL; } ht->hashsize = 0; - if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){ + if(!(ht->ihashtable = myalloc((nhashsize>>2) * sizeof(int)))){ pthread_mutex_unlock(&hash_mutex); return 2; } if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){ - myfree(ht->hashtable); - ht->hashtable = NULL; + myfree(ht->ihashtable); + ht->ihashtable = NULL; pthread_mutex_unlock(&hash_mutex); return 3; } ht->hashsize = nhashsize; ht->tablesize = (nhashsize>>2); ht->rnd[0] = myrand(&tb, sizeof(tb)); - ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable)); + ht->rnd[1] = myrand(ht->ihashtable, sizeof(ht->ihashtable)); ht->rnd[2] = myrand(&c, sizeof(c)); ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues)); - memset(ht->hashtable, 0, ht->tablesize * sizeof(struct hashentry *)); + memset(ht->ihashtable, 0, ht->tablesize * sizeof(struct hashentry *)); memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize - 4)); - for(i = 0; i< (ht->hashsize - 1); i++) { - hvalue(ht,i)->next = hvalue(ht,i+1); + for(i = 1; i < ht->hashsize; i++) { + hvalue(ht,i)->inext = i+1; } - ht->hashempty = (struct hashentry *)ht->hashvalues; + ht->ihashempty = 1; pthread_mutex_unlock(&hash_mutex); return 0; } static void hashcompact(struct hashtable *ht){ int i; - struct hashentry *he, **hep; + int he, *hep; - if((conf.time - ht->compacted) < 60) return; + if((conf.time - ht->compacted) < 60 || !ht->tablesize || !ht->hashsize || ht->hashsize/ht->tablesize >= 4 ) return; for(i = 0; i < ht->tablesize; i++){ - for(hep = ht->hashtable + i; (he = *hep)!=NULL; ){ - if(he->expires < conf.time ) { - (*hep) = he->next; - he->expires = 0; - he->next = ht->hashempty; - ht->hashempty = he; + for(hep = ht->ihashtable + i; (he = *hep) != 0; ){ + if(hvalue(ht,he)->expires < conf.time ) { + (*hep) = hvalue(ht,he)->inext; + hvalue(ht,he)->expires = 0; + hvalue(ht,he)->inext = ht->ihashempty; + ht->ihashempty = he; } - else hep=&(he->next); + else hep=&(hvalue(ht,he)->inext); } } ht->compacted = conf.time; } void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires){ - struct hashentry * hen, *he; - struct hashentry ** hep; + int hen, he; + int *hep; unsigned index; pthread_mutex_lock(&hash_mutex); - if(!ht->hashempty){ + if(!ht->ihashempty){ hashcompact(ht); } - if(!ht||!value||!name||!ht->hashtable||!ht->hashempty) { + if(!ht||!value||!name||!ht->ihashtable||!ht->ihashempty) { pthread_mutex_unlock(&hash_mutex); return; } - hen = ht->hashempty; - ht->hashempty = ht->hashempty->next; - ht->index2hash(name, hen->hash, (unsigned char *)ht->rnd); - memcpy(hen->value, value, ht->recsize); - hen->expires = expires; - hen->next = NULL; - index = hashindex(ht, hen->hash); + hen = ht->ihashempty; + ht->ihashempty = hvalue(ht,ht->ihashempty)->inext; + ht->index2hash(name, hvalue(ht,hen)->hash, (unsigned char *)ht->rnd); + memcpy(hvalue(ht,hen)->value, value, ht->recsize); + hvalue(ht,hen)->expires = expires; + hvalue(ht,hen)->inext = 0; + index = hashindex(ht, hvalue(ht,hen)->hash); - for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){ - if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) { - (*hep) = he->next; - he->expires = 0; - he->next = ht->hashempty; - ht->hashempty = he; + for(hep = ht->ihashtable + index; (he = *hep)!=0; ){ + if(hvalue(ht,he)->expires < conf.time || !memcmp(hvalue(ht,hen)->hash, hvalue(ht,he)->hash, HASH_SIZE)) { + (*hep) = hvalue(ht,he)->inext; + hvalue(ht,he)->expires = 0; + hvalue(ht,he)->inext = ht->ihashempty; + ht->ihashempty = he; } - else hep=&(he->next); + else hep=&(hvalue(ht,he)->inext); } - hen->next = ht->hashtable[index]; - ht->hashtable[index] = hen; + hvalue(ht,hen)->inext = ht->ihashtable[index]; + ht->ihashtable[index] = hen; pthread_mutex_unlock(&hash_mutex); } int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl){ - unsigned char hash[sizeof(unsigned)*4]; - struct hashentry ** hep; - struct hashentry *he; + uint8_t hash[HASH_SIZE]; + int *hep; + int he; unsigned index; pthread_mutex_lock(&hash_mutex); - if(!ht || !ht->hashtable || !name) { + if(!ht || !ht->ihashtable || !name) { pthread_mutex_unlock(&hash_mutex); return 0; } ht->index2hash(name, hash, (unsigned char *)ht->rnd); index = hashindex(ht, hash); - for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){ - if(he->expires < conf.time) { - (*hep) = he->next; - he->expires = 0; - he->next = ht->hashempty; - ht->hashempty = he; + for(hep = ht->ihashtable + index; (he = *hep)!=0; ){ + if(hvalue(ht, he)->expires < conf.time) { + (*hep) = hvalue(ht,he)->inext; + hvalue(ht,he)->expires = 0; + hvalue(ht,he)->inext = ht->ihashempty; + ht->ihashempty = he; } - else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){ - if(ttl) *ttl = (uint32_t)(he->expires - conf.time); - memcpy(value, he->value, ht->recsize); + else if(!memcmp(hash, hvalue(ht,he)->hash, HASH_SIZE)){ + if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time); + memcpy(value, hvalue(ht,he)->value, ht->recsize); pthread_mutex_unlock(&hash_mutex); return 1; } - else hep=&(he->next); + else hep=&(hvalue(ht,he)->inext); } pthread_mutex_unlock(&hash_mutex); return 0; diff --git a/src/libs/blake2-impl.h b/src/libs/blake2-impl.h new file mode 100644 index 0000000..c1df82e --- /dev/null +++ b/src/libs/blake2-impl.h @@ -0,0 +1,160 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#ifndef BLAKE2_IMPL_H +#define BLAKE2_IMPL_H + +#include +#include + +#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) + #if defined(_MSC_VER) + #define BLAKE2_INLINE __inline + #elif defined(__GNUC__) + #define BLAKE2_INLINE __inline__ + #else + #define BLAKE2_INLINE + #endif +#else + #define BLAKE2_INLINE inline +#endif + +static BLAKE2_INLINE uint32_t load32( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8) | + (( uint32_t )( p[2] ) << 16) | + (( uint32_t )( p[3] ) << 24) ; +#endif +} + +static BLAKE2_INLINE uint64_t load64( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) | + (( uint64_t )( p[6] ) << 48) | + (( uint64_t )( p[7] ) << 56) ; +#endif +} + +static BLAKE2_INLINE uint16_t load16( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint16_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return ( uint16_t )((( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8)); +#endif +} + +static BLAKE2_INLINE void store16( void *dst, uint16_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static BLAKE2_INLINE void store32( void *dst, uint32_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); +#endif +} + +static BLAKE2_INLINE void store64( void *dst, uint64_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); + p[6] = (uint8_t)(w >> 48); + p[7] = (uint8_t)(w >> 56); +#endif +} + +static BLAKE2_INLINE uint64_t load48( const void *src ) +{ + const uint8_t *p = ( const uint8_t * )src; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) ; +} + +static BLAKE2_INLINE void store48( void *dst, uint64_t w ) +{ + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); +} + +static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/* prevents compiler optimizing out memset() */ +static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) +{ + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); +} + +#endif diff --git a/src/libs/blake2.h b/src/libs/blake2.h new file mode 100644 index 0000000..ca39030 --- /dev/null +++ b/src/libs/blake2.h @@ -0,0 +1,195 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#ifndef BLAKE2_H +#define BLAKE2_H + +#include +#include + +#if defined(_MSC_VER) +#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) +#else +#define BLAKE2_PACKED(x) x __attribute__((packed)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + + typedef struct blake2s_state__ + { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; + } blake2s_state; + + typedef struct blake2b_state__ + { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; + } blake2b_state; + + typedef struct blake2sp_state__ + { + blake2s_state S[8][1]; + blake2s_state R[1]; + uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; + } blake2sp_state; + + typedef struct blake2bp_state__ + { + blake2b_state S[4][1]; + blake2b_state R[1]; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + } blake2bp_state; + + + BLAKE2_PACKED(struct blake2s_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint16_t xof_length; /* 14 */ + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ + /* uint8_t reserved[0]; */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + }); + + typedef struct blake2s_param__ blake2s_param; + + BLAKE2_PACKED(struct blake2b_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + }); + + typedef struct blake2b_param__ blake2b_param; + + typedef struct blake2xs_state__ + { + blake2s_state S[1]; + blake2s_param P[1]; + } blake2xs_state; + + typedef struct blake2xb_state__ + { + blake2b_state S[1]; + blake2b_param P[1]; + } blake2xb_state; + + /* Padded structs result in a compile-time error */ + enum { + BLAKE2_DUMMY_1 = 1/(int)(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), + BLAKE2_DUMMY_2 = 1/(int)(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) + }; + + /* Streaming API */ + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); + int blake2s_final( blake2s_state *S, void *out, size_t outlen ); + + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); + int blake2b_final( blake2b_state *S, void *out, size_t outlen ); + + int blake2sp_init( blake2sp_state *S, size_t outlen ); + int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); + int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); + + int blake2bp_init( blake2bp_state *S, size_t outlen ); + int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); + int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); + + /* Variable output length API */ + int blake2xs_init( blake2xs_state *S, const size_t outlen ); + int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); + int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); + + int blake2xb_init( blake2xb_state *S, const size_t outlen ); + int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); + int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); + + /* Simple API */ + int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + /* This is simply an alias for blake2b */ + int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/libs/blake2b-ref.c b/src/libs/blake2b-ref.c new file mode 100644 index 0000000..cd38b1b --- /dev/null +++ b/src/libs/blake2b-ref.c @@ -0,0 +1,379 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +static void blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = (uint64_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2b_is_lastblock( const blake2b_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = (uint64_t)-1; +} + +static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2b_init0( blake2b_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; +} + +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + const uint8_t *p = ( const uint8_t * )( P ); + size_t i; + + blake2b_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + S->outlen = P->digest_length; + return 0; +} + + + +int blake2b_init( blake2b_state *S, size_t outlen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store32( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2b_init_param( S, P ); +} + + +int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store32( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load64( block + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress( S, in ); + in += BLAKE2B_BLOCKBYTES; + inlen -= BLAKE2B_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +int blake2b_final( blake2b_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2b_is_lastblock( S ) ) + return -1; + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, S->outlen ); + secure_zero_memory(buffer, sizeof(buffer)); + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + + blake2b_update( S, ( const uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); + return 0; +} + +int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { + return blake2b(out, outlen, in, inlen, key, keylen); +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + +#if defined(BLAKE2B_SELFTEST) +#include +#include "blake2-kat.h" +int main( void ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[BLAKE2_KAT_LENGTH]; + size_t i, step; + + for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); + + if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8_t hash[BLAKE2B_OUTBYTES]; + blake2b_state S; + uint8_t * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2b_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2b_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { + goto fail; + } + } + } + + puts( "ok" ); + return 0; +fail: + puts("error"); + return -1; +} +#endif diff --git a/src/proxy.h b/src/proxy.h index 6cc36be..bb4df97 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -204,7 +204,6 @@ uint32_t getip46(int family, unsigned char *name, struct sockaddr *sa); int afdetect(unsigned char *name); uint32_t myresolver(int, unsigned char *, unsigned char *); uint32_t fakeresolver (int, unsigned char *, unsigned char*); -int inithashtable(struct hashtable *hashtable, unsigned nhashsize); void freeparam(struct clientparam * param); void clearstat(struct clientparam * param); void dumpcounters(struct trafcount *tl, int counterd); diff --git a/src/resolve.c b/src/resolve.c index 5bc6686..05cec1f 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1,20 +1,15 @@ #include "proxy.h" +#include "libs/blake2.h" -void char_index2hash(const void *index, unsigned char *hash, const unsigned char *rnd){ + +void char_index2hash(const void *index, uint8_t *hash, const unsigned char *rnd){ const char* name = index; - unsigned i, j, k; - memcpy(hash, rnd, sizeof(unsigned)*4); - for(i=0, j=0, k=0; name[j]; j++){ - hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16]; - if(++i == sizeof(unsigned)*4) { - i = 0; - k++; - } - } + + blake2b(hash, HASH_SIZE, index, strlen((const char*)index), rnd, 4*sizeof(unsigned) ); } -struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL, char_index2hash}; -struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL, char_index2hash}; +struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, 0, char_index2hash}; +struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, 0, char_index2hash}; struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}}; struct nserver authnserver; diff --git a/src/structures.h b/src/structures.h index 7d1a083..0ffbb5c 100644 --- a/src/structures.h +++ b/src/structures.h @@ -754,10 +754,12 @@ struct child { unsigned char **argv; }; +#define HASH_SIZE (16) + struct hashentry { - unsigned char hash[sizeof(unsigned)*4]; + uint8_t hash[HASH_SIZE]; time_t expires; - struct hashentry *next; + int inext; char value[4]; }; @@ -765,9 +767,9 @@ struct hashtable { unsigned hashsize; unsigned recsize; unsigned rnd[4]; - struct hashentry ** hashtable; + int * ihashtable; uint8_t * hashvalues; - struct hashentry * hashempty; + int ihashempty; void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd); int grow; time_t compacted;