1/* 2 BLAKE2 reference source code package - optimized C implementations 3 4 Written in 2012 by Samuel Neves <sneves@dei.uc.pt> 5 6 To the extent possible under law, the author(s) have dedicated all copyright 7 and related and neighboring rights to this software to the public domain 8 worldwide. This software is distributed without any warranty. 9 10 You should have received a copy of the CC0 Public Domain Dedication along with 11 this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. 12*/ 13#pragma once 14#ifndef __BLAKE2_IMPL_H__ 15#define __BLAKE2_IMPL_H__ 16 17#if defined(_WIN32) || defined(WIN32) 18#include <windows.h> 19#endif 20 21#include <stddef.h> 22#include <stdint.h> 23#include <string.h> 24 25#define BLAKE2_IMPL_CAT(x,y) x ## y 26#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y) 27#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX) 28 29static inline uint32_t load32( const void *src ) 30{ 31#if defined(NATIVE_LITTLE_ENDIAN) 32 uint32_t w; 33 memcpy( &w, src, sizeof( w ) ); 34 return w; 35#else 36 const uint8_t *p = ( uint8_t * )src; 37 uint32_t w = *p++; 38 w |= ( uint32_t )( *p++ ) << 8; 39 w |= ( uint32_t )( *p++ ) << 16; 40 w |= ( uint32_t )( *p++ ) << 24; 41 return w; 42#endif 43} 44 45static inline uint64_t load64( const void *src ) 46{ 47#if defined(NATIVE_LITTLE_ENDIAN) 48 uint64_t w; 49 memcpy( &w, src, sizeof( w ) ); 50 return w; 51#else 52 const uint8_t *p = ( uint8_t * )src; 53 uint64_t w = *p++; 54 w |= ( uint64_t )( *p++ ) << 8; 55 w |= ( uint64_t )( *p++ ) << 16; 56 w |= ( uint64_t )( *p++ ) << 24; 57 w |= ( uint64_t )( *p++ ) << 32; 58 w |= ( uint64_t )( *p++ ) << 40; 59 w |= ( uint64_t )( *p++ ) << 48; 60 w |= ( uint64_t )( *p++ ) << 56; 61 return w; 62#endif 63} 64 65static inline void store32( void *dst, uint32_t w ) 66{ 67#if defined(NATIVE_LITTLE_ENDIAN) 68 memcpy( dst, &w, sizeof( w ) ); 69#else 70 uint8_t *p = ( uint8_t * )dst; 71 *p++ = ( uint8_t )w; w >>= 8; 72 *p++ = ( uint8_t )w; w >>= 8; 73 *p++ = ( uint8_t )w; w >>= 8; 74 *p++ = ( uint8_t )w; 75#endif 76} 77 78static inline void store64( void *dst, uint64_t w ) 79{ 80#if defined(NATIVE_LITTLE_ENDIAN) 81 memcpy( dst, &w, sizeof( w ) ); 82#else 83 uint8_t *p = ( uint8_t * )dst; 84 *p++ = ( uint8_t )w; w >>= 8; 85 *p++ = ( uint8_t )w; w >>= 8; 86 *p++ = ( uint8_t )w; w >>= 8; 87 *p++ = ( uint8_t )w; w >>= 8; 88 *p++ = ( uint8_t )w; w >>= 8; 89 *p++ = ( uint8_t )w; w >>= 8; 90 *p++ = ( uint8_t )w; w >>= 8; 91 *p++ = ( uint8_t )w; 92#endif 93} 94 95static inline uint64_t load48( const void *src ) 96{ 97 const uint8_t *p = ( const uint8_t * )src; 98 uint64_t w = *p++; 99 w |= ( uint64_t )( *p++ ) << 8; 100 w |= ( uint64_t )( *p++ ) << 16; 101 w |= ( uint64_t )( *p++ ) << 24; 102 w |= ( uint64_t )( *p++ ) << 32; 103 w |= ( uint64_t )( *p++ ) << 40; 104 return w; 105} 106 107static inline void store48( void *dst, uint64_t w ) 108{ 109 uint8_t *p = ( uint8_t * )dst; 110 *p++ = ( uint8_t )w; w >>= 8; 111 *p++ = ( uint8_t )w; w >>= 8; 112 *p++ = ( uint8_t )w; w >>= 8; 113 *p++ = ( uint8_t )w; w >>= 8; 114 *p++ = ( uint8_t )w; w >>= 8; 115 *p++ = ( uint8_t )w; 116} 117 118static inline uint32_t rotl32( const uint32_t w, const unsigned c ) 119{ 120 return ( w << c ) | ( w >> ( 32 - c ) ); 121} 122 123static inline uint64_t rotl64( const uint64_t w, const unsigned c ) 124{ 125 return ( w << c ) | ( w >> ( 64 - c ) ); 126} 127 128static inline uint32_t rotr32( const uint32_t w, const unsigned c ) 129{ 130 return ( w >> c ) | ( w << ( 32 - c ) ); 131} 132 133static inline uint64_t rotr64( const uint64_t w, const unsigned c ) 134{ 135 return ( w >> c ) | ( w << ( 64 - c ) ); 136} 137 138/* prevents compiler optimizing out memset() */ 139static inline void secure_zero_memory(void *v, size_t n) 140{ 141#if defined(_WIN32) || defined(WIN32) 142 SecureZeroMemory(v, n); 143#elif defined(__hpux) 144 static void *(*const volatile memset_v)(void *, int, size_t) = &memset; 145 memset_v(v, 0, n); 146#else 147// prioritize first the general C11 call 148#if defined(HAVE_MEMSET_S) 149 memset_s(v, n, 0, n); 150#elif defined(HAVE_EXPLICIT_BZERO) 151 explicit_bzero(v, n); 152#elif defined(HAVE_EXPLICIT_MEMSET) 153 explicit_memset(v, 0, n); 154#else 155 memset(v, 0, n); 156 __asm__ __volatile__("" :: "r"(v) : "memory"); 157#endif 158#endif 159} 160 161#endif 162 163