1 | /* |
2 | BLAKE2 reference source code package - optimized C implementations |
3 | |
4 | Written in 2012 by Samuel Neves <[email protected]> |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
118 | static inline uint32_t rotl32( const uint32_t w, const unsigned c ) |
119 | { |
120 | return ( w << c ) | ( w >> ( 32 - c ) ); |
121 | } |
122 | |
123 | static inline uint64_t rotl64( const uint64_t w, const unsigned c ) |
124 | { |
125 | return ( w << c ) | ( w >> ( 64 - c ) ); |
126 | } |
127 | |
128 | static inline uint32_t rotr32( const uint32_t w, const unsigned c ) |
129 | { |
130 | return ( w >> c ) | ( w << ( 32 - c ) ); |
131 | } |
132 | |
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() */ |
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 | |