1339640Smm/*
2339640Smm   BLAKE2 reference source code package - reference C implementations
3339640Smm
4339640Smm   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
5339640Smm   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
6339640Smm   your option.  The terms of these licenses can be found at:
7339640Smm
8339640Smm   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
9339640Smm   - OpenSSL license   : https://www.openssl.org/source/license.html
10339640Smm   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
11339640Smm
12339640Smm   More information about the BLAKE2 hash function can be found at
13339640Smm   https://blake2.net.
14339640Smm*/
15339640Smm
16358090Smm#ifndef ARCHIVE_BLAKE2_IMPL_H
17358090Smm#define ARCHIVE_BLAKE2_IMPL_H
18358090Smm
19339640Smm#include <stdint.h>
20339640Smm#include <string.h>
21339640Smm
22339640Smm#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
23339640Smm  #if   defined(_MSC_VER)
24339640Smm    #define BLAKE2_INLINE __inline
25339640Smm  #elif defined(__GNUC__)
26339640Smm    #define BLAKE2_INLINE __inline__
27339640Smm  #else
28339640Smm    #define BLAKE2_INLINE
29339640Smm  #endif
30339640Smm#else
31339640Smm  #define BLAKE2_INLINE inline
32339640Smm#endif
33339640Smm
34339640Smmstatic BLAKE2_INLINE uint32_t load32( const void *src )
35339640Smm{
36339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
37339640Smm  uint32_t w;
38339640Smm  memcpy(&w, src, sizeof w);
39339640Smm  return w;
40339640Smm#else
41339640Smm  const uint8_t *p = ( const uint8_t * )src;
42339640Smm  return (( uint32_t )( p[0] ) <<  0) |
43339640Smm         (( uint32_t )( p[1] ) <<  8) |
44339640Smm         (( uint32_t )( p[2] ) << 16) |
45339640Smm         (( uint32_t )( p[3] ) << 24) ;
46339640Smm#endif
47339640Smm}
48339640Smm
49339640Smmstatic BLAKE2_INLINE uint64_t load64( const void *src )
50339640Smm{
51339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
52339640Smm  uint64_t w;
53339640Smm  memcpy(&w, src, sizeof w);
54339640Smm  return w;
55339640Smm#else
56339640Smm  const uint8_t *p = ( const uint8_t * )src;
57339640Smm  return (( uint64_t )( p[0] ) <<  0) |
58339640Smm         (( uint64_t )( p[1] ) <<  8) |
59339640Smm         (( uint64_t )( p[2] ) << 16) |
60339640Smm         (( uint64_t )( p[3] ) << 24) |
61339640Smm         (( uint64_t )( p[4] ) << 32) |
62339640Smm         (( uint64_t )( p[5] ) << 40) |
63339640Smm         (( uint64_t )( p[6] ) << 48) |
64339640Smm         (( uint64_t )( p[7] ) << 56) ;
65339640Smm#endif
66339640Smm}
67339640Smm
68339640Smmstatic BLAKE2_INLINE uint16_t load16( const void *src )
69339640Smm{
70339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
71339640Smm  uint16_t w;
72339640Smm  memcpy(&w, src, sizeof w);
73339640Smm  return w;
74339640Smm#else
75339640Smm  const uint8_t *p = ( const uint8_t * )src;
76339640Smm  return ( uint16_t )((( uint32_t )( p[0] ) <<  0) |
77339640Smm                      (( uint32_t )( p[1] ) <<  8));
78339640Smm#endif
79339640Smm}
80339640Smm
81339640Smmstatic BLAKE2_INLINE void store16( void *dst, uint16_t w )
82339640Smm{
83339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
84339640Smm  memcpy(dst, &w, sizeof w);
85339640Smm#else
86339640Smm  uint8_t *p = ( uint8_t * )dst;
87339640Smm  *p++ = ( uint8_t )w; w >>= 8;
88339640Smm  *p++ = ( uint8_t )w;
89339640Smm#endif
90339640Smm}
91339640Smm
92339640Smmstatic BLAKE2_INLINE void store32( void *dst, uint32_t w )
93339640Smm{
94339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
95339640Smm  memcpy(dst, &w, sizeof w);
96339640Smm#else
97339640Smm  uint8_t *p = ( uint8_t * )dst;
98339640Smm  p[0] = (uint8_t)(w >>  0);
99339640Smm  p[1] = (uint8_t)(w >>  8);
100339640Smm  p[2] = (uint8_t)(w >> 16);
101339640Smm  p[3] = (uint8_t)(w >> 24);
102339640Smm#endif
103339640Smm}
104339640Smm
105339640Smmstatic BLAKE2_INLINE void store64( void *dst, uint64_t w )
106339640Smm{
107339640Smm#if defined(NATIVE_LITTLE_ENDIAN)
108339640Smm  memcpy(dst, &w, sizeof w);
109339640Smm#else
110339640Smm  uint8_t *p = ( uint8_t * )dst;
111339640Smm  p[0] = (uint8_t)(w >>  0);
112339640Smm  p[1] = (uint8_t)(w >>  8);
113339640Smm  p[2] = (uint8_t)(w >> 16);
114339640Smm  p[3] = (uint8_t)(w >> 24);
115339640Smm  p[4] = (uint8_t)(w >> 32);
116339640Smm  p[5] = (uint8_t)(w >> 40);
117339640Smm  p[6] = (uint8_t)(w >> 48);
118339640Smm  p[7] = (uint8_t)(w >> 56);
119339640Smm#endif
120339640Smm}
121339640Smm
122339640Smmstatic BLAKE2_INLINE uint64_t load48( const void *src )
123339640Smm{
124339640Smm  const uint8_t *p = ( const uint8_t * )src;
125339640Smm  return (( uint64_t )( p[0] ) <<  0) |
126339640Smm         (( uint64_t )( p[1] ) <<  8) |
127339640Smm         (( uint64_t )( p[2] ) << 16) |
128339640Smm         (( uint64_t )( p[3] ) << 24) |
129339640Smm         (( uint64_t )( p[4] ) << 32) |
130339640Smm         (( uint64_t )( p[5] ) << 40) ;
131339640Smm}
132339640Smm
133339640Smmstatic BLAKE2_INLINE void store48( void *dst, uint64_t w )
134339640Smm{
135339640Smm  uint8_t *p = ( uint8_t * )dst;
136339640Smm  p[0] = (uint8_t)(w >>  0);
137339640Smm  p[1] = (uint8_t)(w >>  8);
138339640Smm  p[2] = (uint8_t)(w >> 16);
139339640Smm  p[3] = (uint8_t)(w >> 24);
140339640Smm  p[4] = (uint8_t)(w >> 32);
141339640Smm  p[5] = (uint8_t)(w >> 40);
142339640Smm}
143339640Smm
144339640Smmstatic BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
145339640Smm{
146339640Smm  return ( w >> c ) | ( w << ( 32 - c ) );
147339640Smm}
148339640Smm
149339640Smmstatic BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
150339640Smm{
151339640Smm  return ( w >> c ) | ( w << ( 64 - c ) );
152339640Smm}
153339640Smm
154339640Smm/* prevents compiler optimizing out memset() */
155339640Smmstatic BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
156339640Smm{
157339640Smm  static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
158339640Smm  memset_v(v, 0, n);
159339640Smm}
160339640Smm
161339640Smm#endif
162