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 
load32(const void * src)29 static 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 
load64(const void * src)45 static 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 
store32(void * dst,uint32_t w)65 static 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 
store64(void * dst,uint64_t w)78 static 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 
load48(const void * src)95 static 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 
store48(void * dst,uint64_t w)107 static 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 
rotl32(const uint32_t w,const unsigned c)118 static inline uint32_t rotl32( const uint32_t w, const unsigned c )
119 {
120   return ( w << c ) | ( w >> ( 32 - c ) );
121 }
122 
rotl64(const uint64_t w,const unsigned c)123 static inline uint64_t rotl64( const uint64_t w, const unsigned c )
124 {
125   return ( w << c ) | ( w >> ( 64 - c ) );
126 }
127 
rotr32(const uint32_t w,const unsigned c)128 static inline uint32_t rotr32( const uint32_t w, const unsigned c )
129 {
130   return ( w >> c ) | ( w << ( 32 - c ) );
131 }
132 
rotr64(const uint64_t w,const unsigned c)133 static 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() */
secure_zero_memory(void * v,size_t n)139 static 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