17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci   BLAKE2 reference source code package - optimized C implementations
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci   To the extent possible under law, the author(s) have dedicated all copyright
77db96d56Sopenharmony_ci   and related and neighboring rights to this software to the public domain
87db96d56Sopenharmony_ci   worldwide. This software is distributed without any warranty.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci   You should have received a copy of the CC0 Public Domain Dedication along with
117db96d56Sopenharmony_ci   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
127db96d56Sopenharmony_ci*/
137db96d56Sopenharmony_ci#pragma once
147db96d56Sopenharmony_ci#ifndef __BLAKE2_IMPL_H__
157db96d56Sopenharmony_ci#define __BLAKE2_IMPL_H__
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci#if defined(_WIN32) || defined(WIN32)
187db96d56Sopenharmony_ci#include <windows.h>
197db96d56Sopenharmony_ci#endif
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci#include <stddef.h>
227db96d56Sopenharmony_ci#include <stdint.h>
237db96d56Sopenharmony_ci#include <string.h>
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci#define BLAKE2_IMPL_CAT(x,y) x ## y
267db96d56Sopenharmony_ci#define BLAKE2_IMPL_EVAL(x,y)  BLAKE2_IMPL_CAT(x,y)
277db96d56Sopenharmony_ci#define BLAKE2_IMPL_NAME(fun)  BLAKE2_IMPL_EVAL(fun, SUFFIX)
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_cistatic inline uint32_t load32( const void *src )
307db96d56Sopenharmony_ci{
317db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN)
327db96d56Sopenharmony_ci  uint32_t w;
337db96d56Sopenharmony_ci  memcpy( &w, src, sizeof( w ) );
347db96d56Sopenharmony_ci  return w;
357db96d56Sopenharmony_ci#else
367db96d56Sopenharmony_ci  const uint8_t *p = ( uint8_t * )src;
377db96d56Sopenharmony_ci  uint32_t w = *p++;
387db96d56Sopenharmony_ci  w |= ( uint32_t )( *p++ ) <<  8;
397db96d56Sopenharmony_ci  w |= ( uint32_t )( *p++ ) << 16;
407db96d56Sopenharmony_ci  w |= ( uint32_t )( *p++ ) << 24;
417db96d56Sopenharmony_ci  return w;
427db96d56Sopenharmony_ci#endif
437db96d56Sopenharmony_ci}
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_cistatic inline uint64_t load64( const void *src )
467db96d56Sopenharmony_ci{
477db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN)
487db96d56Sopenharmony_ci  uint64_t w;
497db96d56Sopenharmony_ci  memcpy( &w, src, sizeof( w ) );
507db96d56Sopenharmony_ci  return w;
517db96d56Sopenharmony_ci#else
527db96d56Sopenharmony_ci  const uint8_t *p = ( uint8_t * )src;
537db96d56Sopenharmony_ci  uint64_t w = *p++;
547db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) <<  8;
557db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 16;
567db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 24;
577db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 32;
587db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 40;
597db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 48;
607db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 56;
617db96d56Sopenharmony_ci  return w;
627db96d56Sopenharmony_ci#endif
637db96d56Sopenharmony_ci}
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_cistatic inline void store32( void *dst, uint32_t w )
667db96d56Sopenharmony_ci{
677db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN)
687db96d56Sopenharmony_ci  memcpy( dst, &w, sizeof( w ) );
697db96d56Sopenharmony_ci#else
707db96d56Sopenharmony_ci  uint8_t *p = ( uint8_t * )dst;
717db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
727db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
737db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
747db96d56Sopenharmony_ci  *p++ = ( uint8_t )w;
757db96d56Sopenharmony_ci#endif
767db96d56Sopenharmony_ci}
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_cistatic inline void store64( void *dst, uint64_t w )
797db96d56Sopenharmony_ci{
807db96d56Sopenharmony_ci#if defined(NATIVE_LITTLE_ENDIAN)
817db96d56Sopenharmony_ci  memcpy( dst, &w, sizeof( w ) );
827db96d56Sopenharmony_ci#else
837db96d56Sopenharmony_ci  uint8_t *p = ( uint8_t * )dst;
847db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
857db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
867db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
877db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
887db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
897db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
907db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
917db96d56Sopenharmony_ci  *p++ = ( uint8_t )w;
927db96d56Sopenharmony_ci#endif
937db96d56Sopenharmony_ci}
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_cistatic inline uint64_t load48( const void *src )
967db96d56Sopenharmony_ci{
977db96d56Sopenharmony_ci  const uint8_t *p = ( const uint8_t * )src;
987db96d56Sopenharmony_ci  uint64_t w = *p++;
997db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) <<  8;
1007db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 16;
1017db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 24;
1027db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 32;
1037db96d56Sopenharmony_ci  w |= ( uint64_t )( *p++ ) << 40;
1047db96d56Sopenharmony_ci  return w;
1057db96d56Sopenharmony_ci}
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_cistatic inline void store48( void *dst, uint64_t w )
1087db96d56Sopenharmony_ci{
1097db96d56Sopenharmony_ci  uint8_t *p = ( uint8_t * )dst;
1107db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
1117db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
1127db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
1137db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
1147db96d56Sopenharmony_ci  *p++ = ( uint8_t )w; w >>= 8;
1157db96d56Sopenharmony_ci  *p++ = ( uint8_t )w;
1167db96d56Sopenharmony_ci}
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_cistatic inline uint32_t rotl32( const uint32_t w, const unsigned c )
1197db96d56Sopenharmony_ci{
1207db96d56Sopenharmony_ci  return ( w << c ) | ( w >> ( 32 - c ) );
1217db96d56Sopenharmony_ci}
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_cistatic inline uint64_t rotl64( const uint64_t w, const unsigned c )
1247db96d56Sopenharmony_ci{
1257db96d56Sopenharmony_ci  return ( w << c ) | ( w >> ( 64 - c ) );
1267db96d56Sopenharmony_ci}
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_cistatic inline uint32_t rotr32( const uint32_t w, const unsigned c )
1297db96d56Sopenharmony_ci{
1307db96d56Sopenharmony_ci  return ( w >> c ) | ( w << ( 32 - c ) );
1317db96d56Sopenharmony_ci}
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_cistatic inline uint64_t rotr64( const uint64_t w, const unsigned c )
1347db96d56Sopenharmony_ci{
1357db96d56Sopenharmony_ci  return ( w >> c ) | ( w << ( 64 - c ) );
1367db96d56Sopenharmony_ci}
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci/* prevents compiler optimizing out memset() */
1397db96d56Sopenharmony_cistatic inline void secure_zero_memory(void *v, size_t n)
1407db96d56Sopenharmony_ci{
1417db96d56Sopenharmony_ci#if defined(_WIN32) || defined(WIN32)
1427db96d56Sopenharmony_ci  SecureZeroMemory(v, n);
1437db96d56Sopenharmony_ci#elif defined(__hpux)
1447db96d56Sopenharmony_ci  static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
1457db96d56Sopenharmony_ci  memset_v(v, 0, n);
1467db96d56Sopenharmony_ci#else
1477db96d56Sopenharmony_ci// prioritize first the general C11 call
1487db96d56Sopenharmony_ci#if defined(HAVE_MEMSET_S)
1497db96d56Sopenharmony_ci  memset_s(v, n, 0, n);
1507db96d56Sopenharmony_ci#elif defined(HAVE_EXPLICIT_BZERO)
1517db96d56Sopenharmony_ci  explicit_bzero(v, n);
1527db96d56Sopenharmony_ci#elif defined(HAVE_EXPLICIT_MEMSET)
1537db96d56Sopenharmony_ci  explicit_memset(v, 0, n);
1547db96d56Sopenharmony_ci#else
1557db96d56Sopenharmony_ci  memset(v, 0, n);
1567db96d56Sopenharmony_ci  __asm__ __volatile__("" :: "r"(v) : "memory");
1577db96d56Sopenharmony_ci#endif
1587db96d56Sopenharmony_ci#endif
1597db96d56Sopenharmony_ci}
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci#endif
1627db96d56Sopenharmony_ci
163