LCOV - code coverage report
Current view: top level - ext - csiphash.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 47 47 100.0 %
Date: 2021-11-24 03:28:48 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* <MIT License>
       2             :  Copyright (c) 2013-2014  Marek Majkowski <marek@popcount.org>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  </MIT License>
      22             : 
      23             :  Original location:
      24             :     https://github.com/majek/csiphash/
      25             : 
      26             :  Solution inspired by code from:
      27             :     Samuel Neves (supercop/crypto_auth/siphash24/little)
      28             :     djb (supercop/crypto_auth/siphash24/little2)
      29             :     Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c)
      30             : */
      31             : 
      32             : #include "lib/cc/torint.h"
      33             : #include "lib/err/torerr.h"
      34             : 
      35             : #include "ext/siphash.h"
      36             : #include <string.h>
      37             : #include <stdlib.h>
      38             : #include "ext/byteorder.h"
      39             : 
      40             : #define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
      41             : 
      42             : #define HALF_ROUND(a,b,c,d,s,t)                 \
      43             :         a += b; c += d;                         \
      44             :         b = ROTATE(b, s) ^ a;                   \
      45             :         d = ROTATE(d, t) ^ c;                   \
      46             :         a = ROTATE(a, 32);
      47             : 
      48             : #define DOUBLE_ROUND(v0,v1,v2,v3)               \
      49             :         HALF_ROUND(v0,v1,v2,v3,13,16);          \
      50             :         HALF_ROUND(v2,v1,v0,v3,17,21);          \
      51             :         HALF_ROUND(v0,v1,v2,v3,13,16);          \
      52             :         HALF_ROUND(v2,v1,v0,v3,17,21);
      53             : 
      54             : #if 0
      55             : /* This does not seem to save very much runtime in the fast case, and it's
      56             :  * potentially a big loss in the slow case where we're misaligned and we cross
      57             :  * a cache line. */
      58             : #if (defined(__i386) || defined(__i386__) || defined(_M_IX86) ||        \
      59             :      defined(__x86_64) || defined(__x86_64__) ||                        \
      60             :      defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__))
      61             : #   define UNALIGNED_OK 1
      62             : #endif
      63             : #endif
      64             : 
      65      865118 : uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *key) {
      66      865118 :         const uint8_t *m = src;
      67      865118 :         uint64_t k0 = key->k0;
      68      865118 :         uint64_t k1 = key->k1;
      69      865118 :         uint64_t last7 = (uint64_t)(src_sz & 0xff) << 56;
      70      865118 :         size_t i, blocks;
      71             : 
      72      865118 :         uint64_t v0 = k0 ^ 0x736f6d6570736575ULL;
      73      865118 :         uint64_t v1 = k1 ^ 0x646f72616e646f6dULL;
      74      865118 :         uint64_t v2 = k0 ^ 0x6c7967656e657261ULL;
      75      865118 :         uint64_t v3 = k1 ^ 0x7465646279746573ULL;
      76             : 
      77     3292039 :         for (i = 0, blocks = (src_sz & ~7); i < blocks; i+= 8) {
      78             : #ifdef UNALIGNED_OK
      79             :                 uint64_t mi = _le64toh(*(m + i));
      80             : #else
      81     2426921 :                 uint64_t mi;
      82     2426921 :                 memcpy(&mi, m + i, 8);
      83     2426921 :                 mi = _le64toh(mi);
      84             : #endif
      85     2426921 :                 v3 ^= mi;
      86     2426921 :                 DOUBLE_ROUND(v0,v1,v2,v3);
      87     2426921 :                 v0 ^= mi;
      88             :         }
      89             : 
      90             : #ifdef __COVERITY__
      91             :         {
      92             :                 uint64_t mi = 0;
      93             :                 memcpy(&mi, m+i, (src_sz-blocks));
      94             :                 last7 = _le64toh(mi) | (uint64_t)(src_sz & 0xff) << 56;
      95             :         }
      96             : #else
      97      865118 :         switch (src_sz - blocks) {
      98        1460 :                 case 7: last7 |= (uint64_t)m[i + 6] << 48; FALLTHROUGH;
      99        9093 :                 case 6: last7 |= (uint64_t)m[i + 5] << 40; FALLTHROUGH;
     100       15272 :                 case 5: last7 |= (uint64_t)m[i + 4] << 32; FALLTHROUGH;
     101      155275 :                 case 4: last7 |= (uint64_t)m[i + 3] << 24; FALLTHROUGH;
     102      179501 :                 case 3: last7 |= (uint64_t)m[i + 2] << 16; FALLTHROUGH;
     103      183173 :                 case 2: last7 |= (uint64_t)m[i + 1] <<  8; FALLTHROUGH;
     104      183526 :                 case 1: last7 |= (uint64_t)m[i + 0]      ; FALLTHROUGH;
     105      865118 :                 case 0:
     106      865118 :                 default:;
     107             :         }
     108             : #endif
     109      865118 :         v3 ^= last7;
     110      865118 :         DOUBLE_ROUND(v0,v1,v2,v3);
     111      865118 :         v0 ^= last7;
     112      865118 :         v2 ^= 0xff;
     113      865118 :         DOUBLE_ROUND(v0,v1,v2,v3);
     114      865118 :         DOUBLE_ROUND(v0,v1,v2,v3);
     115      865118 :         return v0 ^ v1 ^ v2 ^ v3;
     116             : }
     117             : 
     118             : 
     119             : static int the_siphash_key_is_set = 0;
     120             : static struct sipkey the_siphash_key;
     121             : 
     122      800882 : uint64_t siphash24g(const void *src, unsigned long src_sz) {
     123      800882 :         raw_assert(the_siphash_key_is_set);
     124      800882 :         return siphash24(src, src_sz, &the_siphash_key);
     125             : }
     126             : 
     127       10870 : void siphash_set_global_key(const struct sipkey *key)
     128             : {
     129       10870 :         raw_assert(! the_siphash_key_is_set);
     130       10870 :         the_siphash_key.k0 = key->k0;
     131       10870 :         the_siphash_key.k1 = key->k1;
     132       10870 :         the_siphash_key_is_set = 1;
     133       10870 : }
     134             : 
     135        5544 : void siphash_unset_global_key(void)
     136             : {
     137        5544 :         the_siphash_key_is_set = 0;
     138        5544 :         memset(&the_siphash_key, 0, sizeof(the_siphash_key));
     139        5544 : }

Generated by: LCOV version 1.14