17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci BLAKE2 reference source code package - optimized C implementations 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci Written in 2012 by Samuel Neves <sneves@dei.uc.pt> 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci To the extent possible under law, the author(s) have dedicated all copyright 77db96d56Sopenharmony_ci and related and neighboring rights to this software to the public domain 87db96d56Sopenharmony_ci worldwide. This software is distributed without any warranty. 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci You should have received a copy of the CC0 Public Domain Dedication along with 117db96d56Sopenharmony_ci this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. 127db96d56Sopenharmony_ci*/ 137db96d56Sopenharmony_ci#pragma once 147db96d56Sopenharmony_ci#ifndef __BLAKE2_IMPL_H__ 157db96d56Sopenharmony_ci#define __BLAKE2_IMPL_H__ 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci#if defined(_WIN32) || defined(WIN32) 187db96d56Sopenharmony_ci#include <windows.h> 197db96d56Sopenharmony_ci#endif 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci#include <stddef.h> 227db96d56Sopenharmony_ci#include <stdint.h> 237db96d56Sopenharmony_ci#include <string.h> 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci#define BLAKE2_IMPL_CAT(x,y) x ## y 267db96d56Sopenharmony_ci#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y) 277db96d56Sopenharmony_ci#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX) 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_cistatic inline uint32_t load32( const void *src ) 307db96d56Sopenharmony_ci{ 317db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN) 327db96d56Sopenharmony_ci uint32_t w; 337db96d56Sopenharmony_ci memcpy( &w, src, sizeof( w ) ); 347db96d56Sopenharmony_ci return w; 357db96d56Sopenharmony_ci#else 367db96d56Sopenharmony_ci const uint8_t *p = ( uint8_t * )src; 377db96d56Sopenharmony_ci uint32_t w = *p++; 387db96d56Sopenharmony_ci w |= ( uint32_t )( *p++ ) << 8; 397db96d56Sopenharmony_ci w |= ( uint32_t )( *p++ ) << 16; 407db96d56Sopenharmony_ci w |= ( uint32_t )( *p++ ) << 24; 417db96d56Sopenharmony_ci return w; 427db96d56Sopenharmony_ci#endif 437db96d56Sopenharmony_ci} 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_cistatic inline uint64_t load64( const void *src ) 467db96d56Sopenharmony_ci{ 477db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN) 487db96d56Sopenharmony_ci uint64_t w; 497db96d56Sopenharmony_ci memcpy( &w, src, sizeof( w ) ); 507db96d56Sopenharmony_ci return w; 517db96d56Sopenharmony_ci#else 527db96d56Sopenharmony_ci const uint8_t *p = ( uint8_t * )src; 537db96d56Sopenharmony_ci uint64_t w = *p++; 547db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 8; 557db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 16; 567db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 24; 577db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 32; 587db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 40; 597db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 48; 607db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 56; 617db96d56Sopenharmony_ci return w; 627db96d56Sopenharmony_ci#endif 637db96d56Sopenharmony_ci} 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_cistatic inline void store32( void *dst, uint32_t w ) 667db96d56Sopenharmony_ci{ 677db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN) 687db96d56Sopenharmony_ci memcpy( dst, &w, sizeof( w ) ); 697db96d56Sopenharmony_ci#else 707db96d56Sopenharmony_ci uint8_t *p = ( uint8_t * )dst; 717db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 727db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 737db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 747db96d56Sopenharmony_ci *p++ = ( uint8_t )w; 757db96d56Sopenharmony_ci#endif 767db96d56Sopenharmony_ci} 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_cistatic inline void store64( void *dst, uint64_t w ) 797db96d56Sopenharmony_ci{ 807db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN) 817db96d56Sopenharmony_ci memcpy( dst, &w, sizeof( w ) ); 827db96d56Sopenharmony_ci#else 837db96d56Sopenharmony_ci uint8_t *p = ( uint8_t * )dst; 847db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 857db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 867db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 877db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 887db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 897db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 907db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 917db96d56Sopenharmony_ci *p++ = ( uint8_t )w; 927db96d56Sopenharmony_ci#endif 937db96d56Sopenharmony_ci} 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_cistatic inline uint64_t load48( const void *src ) 967db96d56Sopenharmony_ci{ 977db96d56Sopenharmony_ci const uint8_t *p = ( const uint8_t * )src; 987db96d56Sopenharmony_ci uint64_t w = *p++; 997db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 8; 1007db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 16; 1017db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 24; 1027db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 32; 1037db96d56Sopenharmony_ci w |= ( uint64_t )( *p++ ) << 40; 1047db96d56Sopenharmony_ci return w; 1057db96d56Sopenharmony_ci} 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_cistatic inline void store48( void *dst, uint64_t w ) 1087db96d56Sopenharmony_ci{ 1097db96d56Sopenharmony_ci uint8_t *p = ( uint8_t * )dst; 1107db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 1117db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 1127db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 1137db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 1147db96d56Sopenharmony_ci *p++ = ( uint8_t )w; w >>= 8; 1157db96d56Sopenharmony_ci *p++ = ( uint8_t )w; 1167db96d56Sopenharmony_ci} 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_cistatic inline uint32_t rotl32( const uint32_t w, const unsigned c ) 1197db96d56Sopenharmony_ci{ 1207db96d56Sopenharmony_ci return ( w << c ) | ( w >> ( 32 - c ) ); 1217db96d56Sopenharmony_ci} 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_cistatic inline uint64_t rotl64( const uint64_t w, const unsigned c ) 1247db96d56Sopenharmony_ci{ 1257db96d56Sopenharmony_ci return ( w << c ) | ( w >> ( 64 - c ) ); 1267db96d56Sopenharmony_ci} 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_cistatic inline uint32_t rotr32( const uint32_t w, const unsigned c ) 1297db96d56Sopenharmony_ci{ 1307db96d56Sopenharmony_ci return ( w >> c ) | ( w << ( 32 - c ) ); 1317db96d56Sopenharmony_ci} 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_cistatic inline uint64_t rotr64( const uint64_t w, const unsigned c ) 1347db96d56Sopenharmony_ci{ 1357db96d56Sopenharmony_ci return ( w >> c ) | ( w << ( 64 - c ) ); 1367db96d56Sopenharmony_ci} 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci/* prevents compiler optimizing out memset() */ 1397db96d56Sopenharmony_cistatic inline void secure_zero_memory(void *v, size_t n) 1407db96d56Sopenharmony_ci{ 1417db96d56Sopenharmony_ci#if defined(_WIN32) || defined(WIN32) 1427db96d56Sopenharmony_ci SecureZeroMemory(v, n); 1437db96d56Sopenharmony_ci#elif defined(__hpux) 1447db96d56Sopenharmony_ci static void *(*const volatile memset_v)(void *, int, size_t) = &memset; 1457db96d56Sopenharmony_ci memset_v(v, 0, n); 1467db96d56Sopenharmony_ci#else 1477db96d56Sopenharmony_ci// prioritize first the general C11 call 1487db96d56Sopenharmony_ci#if defined(HAVE_MEMSET_S) 1497db96d56Sopenharmony_ci memset_s(v, n, 0, n); 1507db96d56Sopenharmony_ci#elif defined(HAVE_EXPLICIT_BZERO) 1517db96d56Sopenharmony_ci explicit_bzero(v, n); 1527db96d56Sopenharmony_ci#elif defined(HAVE_EXPLICIT_MEMSET) 1537db96d56Sopenharmony_ci explicit_memset(v, 0, n); 1547db96d56Sopenharmony_ci#else 1557db96d56Sopenharmony_ci memset(v, 0, n); 1567db96d56Sopenharmony_ci __asm__ __volatile__("" :: "r"(v) : "memory"); 1577db96d56Sopenharmony_ci#endif 1587db96d56Sopenharmony_ci#endif 1597db96d56Sopenharmony_ci} 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci#endif 1627db96d56Sopenharmony_ci 163