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