10e33efe4SConrad Meyer /*
20e33efe4SConrad Meyer BLAKE2 reference source code package - optimized C implementations
30e33efe4SConrad Meyer
40e33efe4SConrad Meyer Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
50e33efe4SConrad Meyer
60e33efe4SConrad Meyer To the extent possible under law, the author(s) have dedicated all copyright
70e33efe4SConrad Meyer and related and neighboring rights to this software to the public domain
80e33efe4SConrad Meyer worldwide. This software is distributed without any warranty.
90e33efe4SConrad Meyer
100e33efe4SConrad Meyer You should have received a copy of the CC0 Public Domain Dedication along with
110e33efe4SConrad Meyer this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
120e33efe4SConrad Meyer */
130e33efe4SConrad Meyer #pragma once
140e33efe4SConrad Meyer #ifndef __BLAKE2_IMPL_H__
150e33efe4SConrad Meyer #define __BLAKE2_IMPL_H__
160e33efe4SConrad Meyer
170e33efe4SConrad Meyer #include <stddef.h>
180e33efe4SConrad Meyer #include <stdint.h>
190e33efe4SConrad Meyer #include <string.h>
200e33efe4SConrad Meyer #include "config.h"
210e33efe4SConrad Meyer
220e33efe4SConrad Meyer #define BLAKE2_IMPL_CAT(x,y) x ## y
230e33efe4SConrad Meyer #define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y)
240e33efe4SConrad Meyer #define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX)
250e33efe4SConrad Meyer
load32(const void * src)260e33efe4SConrad Meyer static inline uint32_t load32( const void *src )
270e33efe4SConrad Meyer {
280e33efe4SConrad Meyer #if defined(NATIVE_LITTLE_ENDIAN) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
290e33efe4SConrad Meyer return *( uint32_t * )( src );
300e33efe4SConrad Meyer #else
310e33efe4SConrad Meyer const uint8_t *p = ( uint8_t * )src;
320e33efe4SConrad Meyer uint32_t w = *p++;
330e33efe4SConrad Meyer w |= ( uint32_t )( *p++ ) << 8;
340e33efe4SConrad Meyer w |= ( uint32_t )( *p++ ) << 16;
350e33efe4SConrad Meyer w |= ( uint32_t )( *p++ ) << 24;
360e33efe4SConrad Meyer return w;
370e33efe4SConrad Meyer #endif
380e33efe4SConrad Meyer }
390e33efe4SConrad Meyer
load64(const void * src)400e33efe4SConrad Meyer static inline uint64_t load64( const void *src )
410e33efe4SConrad Meyer {
420e33efe4SConrad Meyer #if defined(NATIVE_LITTLE_ENDIAN) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
430e33efe4SConrad Meyer return *( uint64_t * )( src );
440e33efe4SConrad Meyer #else
450e33efe4SConrad Meyer const uint8_t *p = ( uint8_t * )src;
460e33efe4SConrad Meyer uint64_t w = *p++;
470e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 8;
480e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 16;
490e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 24;
500e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 32;
510e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 40;
520e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 48;
530e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 56;
540e33efe4SConrad Meyer return w;
550e33efe4SConrad Meyer #endif
560e33efe4SConrad Meyer }
570e33efe4SConrad Meyer
store32(void * dst,uint32_t w)580e33efe4SConrad Meyer static inline void store32( void *dst, uint32_t w )
590e33efe4SConrad Meyer {
600e33efe4SConrad Meyer #if defined(NATIVE_LITTLE_ENDIAN) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
610e33efe4SConrad Meyer *( uint32_t * )( dst ) = w;
620e33efe4SConrad Meyer #else
630e33efe4SConrad Meyer uint8_t *p = ( uint8_t * )dst;
640e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
650e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
660e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
670e33efe4SConrad Meyer *p++ = ( uint8_t )w;
680e33efe4SConrad Meyer #endif
690e33efe4SConrad Meyer }
700e33efe4SConrad Meyer
store64(void * dst,uint64_t w)710e33efe4SConrad Meyer static inline void store64( void *dst, uint64_t w )
720e33efe4SConrad Meyer {
730e33efe4SConrad Meyer #if defined(NATIVE_LITTLE_ENDIAN) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
740e33efe4SConrad Meyer *( uint64_t * )( dst ) = w;
750e33efe4SConrad Meyer #else
760e33efe4SConrad Meyer uint8_t *p = ( uint8_t * )dst;
770e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
780e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
790e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
800e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
810e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
820e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
830e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
840e33efe4SConrad Meyer *p++ = ( uint8_t )w;
850e33efe4SConrad Meyer #endif
860e33efe4SConrad Meyer }
870e33efe4SConrad Meyer
load48(const void * src)880e33efe4SConrad Meyer static inline uint64_t load48( const void *src )
890e33efe4SConrad Meyer {
900e33efe4SConrad Meyer const uint8_t *p = ( const uint8_t * )src;
910e33efe4SConrad Meyer uint64_t w = *p++;
920e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 8;
930e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 16;
940e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 24;
950e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 32;
960e33efe4SConrad Meyer w |= ( uint64_t )( *p++ ) << 40;
970e33efe4SConrad Meyer return w;
980e33efe4SConrad Meyer }
990e33efe4SConrad Meyer
store48(void * dst,uint64_t w)1000e33efe4SConrad Meyer static inline void store48( void *dst, uint64_t w )
1010e33efe4SConrad Meyer {
1020e33efe4SConrad Meyer uint8_t *p = ( uint8_t * )dst;
1030e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
1040e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
1050e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
1060e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
1070e33efe4SConrad Meyer *p++ = ( uint8_t )w; w >>= 8;
1080e33efe4SConrad Meyer *p++ = ( uint8_t )w;
1090e33efe4SConrad Meyer }
1100e33efe4SConrad Meyer
rotl32(const uint32_t w,const unsigned c)1110e33efe4SConrad Meyer static inline uint32_t rotl32( const uint32_t w, const unsigned c )
1120e33efe4SConrad Meyer {
1130e33efe4SConrad Meyer return ( w << c ) | ( w >> ( 32 - c ) );
1140e33efe4SConrad Meyer }
1150e33efe4SConrad Meyer
rotl64(const uint64_t w,const unsigned c)1160e33efe4SConrad Meyer static inline uint64_t rotl64( const uint64_t w, const unsigned c )
1170e33efe4SConrad Meyer {
1180e33efe4SConrad Meyer return ( w << c ) | ( w >> ( 64 - c ) );
1190e33efe4SConrad Meyer }
1200e33efe4SConrad Meyer
rotr32(const uint32_t w,const unsigned c)1210e33efe4SConrad Meyer static inline uint32_t rotr32( const uint32_t w, const unsigned c )
1220e33efe4SConrad Meyer {
1230e33efe4SConrad Meyer return ( w >> c ) | ( w << ( 32 - c ) );
1240e33efe4SConrad Meyer }
1250e33efe4SConrad Meyer
rotr64(const uint64_t w,const unsigned c)1260e33efe4SConrad Meyer static inline uint64_t rotr64( const uint64_t w, const unsigned c )
1270e33efe4SConrad Meyer {
1280e33efe4SConrad Meyer return ( w >> c ) | ( w << ( 64 - c ) );
1290e33efe4SConrad Meyer }
1300e33efe4SConrad Meyer
1310e33efe4SConrad Meyer /* prevents compiler optimizing out memset() */
secure_zero_memory(void * v,size_t n)1320e33efe4SConrad Meyer static inline void secure_zero_memory(void *v, size_t n)
1330e33efe4SConrad Meyer {
134*2cb2ba6dSConrad Meyer #if defined(_WIN32) || defined(WIN32)
135*2cb2ba6dSConrad Meyer SecureZeroMemory(v, n);
1360e33efe4SConrad Meyer #else
137*2cb2ba6dSConrad Meyer // prioritize first the general C11 call
138*2cb2ba6dSConrad Meyer #if defined(HAVE_MEMSET_S)
139*2cb2ba6dSConrad Meyer memset_s(v, n, 0, n);
140*2cb2ba6dSConrad Meyer #elif defined(HAVE_EXPLICIT_BZERO)
141*2cb2ba6dSConrad Meyer explicit_bzero(v, n);
142*2cb2ba6dSConrad Meyer #elif defined(HAVE_EXPLICIT_MEMSET)
143*2cb2ba6dSConrad Meyer explicit_memset(v, 0, n);
144*2cb2ba6dSConrad Meyer #else
145*2cb2ba6dSConrad Meyer memset(v, 0, n);
146*2cb2ba6dSConrad Meyer __asm__ __volatile__("" :: "r"(v) : "memory");
147*2cb2ba6dSConrad Meyer #endif
1480e33efe4SConrad Meyer #endif
1490e33efe4SConrad Meyer }
1500e33efe4SConrad Meyer
1510e33efe4SConrad Meyer #endif
1520e33efe4SConrad Meyer
153