LCOV - code coverage report
Current view: top level - basic - siphash24.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 96 96 100.0 %
Date: 2019-08-23 13:36:53 Functions: 7 7 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 29 39 74.4 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    SipHash reference C implementation
       3                 :            : 
       4                 :            :    Written in 2012 by
       5                 :            :    Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
       6                 :            :    Daniel J. Bernstein <djb@cr.yp.to>
       7                 :            : 
       8                 :            :    To the extent possible under law, the author(s) have dedicated all copyright
       9                 :            :    and related and neighboring rights to this software to the public domain
      10                 :            :    worldwide. This software is distributed without any warranty.
      11                 :            : 
      12                 :            :    You should have received a copy of the CC0 Public Domain Dedication along with
      13                 :            :    this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
      14                 :            : 
      15                 :            :    (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd)
      16                 :            :    (Refactored by Tom Gundersen to split up in several functions and follow systemd
      17                 :            :     coding style)
      18                 :            : */
      19                 :            : 
      20                 :            : #include <stdio.h>
      21                 :            : 
      22                 :            : #include "macro.h"
      23                 :            : #include "siphash24.h"
      24                 :            : #include "unaligned.h"
      25                 :            : 
      26                 : 4255244748 : static uint64_t rotate_left(uint64_t x, uint8_t b) {
      27         [ -  + ]: 4255244748 :         assert(b < 64);
      28                 :            : 
      29                 : 4255244748 :         return (x << b) | (x >> (64 - b));
      30                 :            : }
      31                 :            : 
      32                 :  709207458 : static void sipround(struct siphash *state) {
      33         [ -  + ]:  709207458 :         assert(state);
      34                 :            : 
      35                 :  709207458 :         state->v0 += state->v1;
      36                 :  709207458 :         state->v1 = rotate_left(state->v1, 13);
      37                 :  709207458 :         state->v1 ^= state->v0;
      38                 :  709207458 :         state->v0 = rotate_left(state->v0, 32);
      39                 :  709207458 :         state->v2 += state->v3;
      40                 :  709207458 :         state->v3 = rotate_left(state->v3, 16);
      41                 :  709207458 :         state->v3 ^= state->v2;
      42                 :  709207458 :         state->v0 += state->v3;
      43                 :  709207458 :         state->v3 = rotate_left(state->v3, 21);
      44                 :  709207458 :         state->v3 ^= state->v0;
      45                 :  709207458 :         state->v2 += state->v1;
      46                 :  709207458 :         state->v1 = rotate_left(state->v1, 17);
      47                 :  709207458 :         state->v1 ^= state->v2;
      48                 :  709207458 :         state->v2 = rotate_left(state->v2, 32);
      49                 :  709207458 : }
      50                 :            : 
      51                 :   94727969 : void siphash24_init(struct siphash *state, const uint8_t k[static 16]) {
      52                 :            :         uint64_t k0, k1;
      53                 :            : 
      54         [ -  + ]:   94727969 :         assert(state);
      55         [ -  + ]:   94727969 :         assert(k);
      56                 :            : 
      57                 :   94727969 :         k0 = unaligned_read_le64(k);
      58                 :   94727969 :         k1 = unaligned_read_le64(k + 8);
      59                 :            : 
      60                 :   94727969 :         *state = (struct siphash) {
      61                 :            :                 /* "somepseudorandomlygeneratedbytes" */
      62                 :   94727969 :                 .v0 = 0x736f6d6570736575ULL ^ k0,
      63                 :   94727969 :                 .v1 = 0x646f72616e646f6dULL ^ k1,
      64                 :   94727969 :                 .v2 = 0x6c7967656e657261ULL ^ k0,
      65                 :   94727969 :                 .v3 = 0x7465646279746573ULL ^ k1,
      66                 :            :                 .padding = 0,
      67                 :            :                 .inlen = 0,
      68                 :            :         };
      69                 :   94727969 : }
      70                 :            : 
      71                 :   97712272 : void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
      72                 :            : 
      73                 :   97712272 :         const uint8_t *in = _in;
      74                 :   97712272 :         const uint8_t *end = in + inlen;
      75                 :   97712272 :         size_t left = state->inlen & 7;
      76                 :            :         uint64_t m;
      77                 :            : 
      78         [ -  + ]:   97712272 :         assert(in);
      79         [ -  + ]:   97712272 :         assert(state);
      80                 :            : 
      81                 :            :         /* Update total length */
      82                 :   97712272 :         state->inlen += inlen;
      83                 :            : 
      84                 :            :         /* If padding exists, fill it out */
      85         [ +  + ]:   97712272 :         if (left > 0) {
      86   [ +  +  +  + ]:   10531005 :                 for ( ; in < end && left < 8; in ++, left ++)
      87                 :    7965996 :                         state->padding |= ((uint64_t) *in) << (left * 8);
      88                 :            : 
      89   [ +  +  +  + ]:    2565009 :                 if (in == end && left < 8)
      90                 :            :                         /* We did not have enough input to fill out the padding completely */
      91                 :    1261359 :                         return;
      92                 :            : 
      93                 :            : #if ENABLE_DEBUG_SIPHASH
      94                 :            :                 printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
      95                 :            :                 printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
      96                 :            :                 printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
      97                 :            :                 printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
      98                 :            :                 printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding);
      99                 :            : #endif
     100                 :            : 
     101                 :    1303650 :                 state->v3 ^= state->padding;
     102                 :    1303650 :                 sipround(state);
     103                 :    1303650 :                 sipround(state);
     104                 :    1303650 :                 state->v0 ^= state->padding;
     105                 :            : 
     106                 :    1303650 :                 state->padding = 0;
     107                 :            :         }
     108                 :            : 
     109                 :   96450913 :         end -= (state->inlen % sizeof(uint64_t));
     110                 :            : 
     111         [ +  + ]:  165567109 :         for ( ; in < end; in += 8) {
     112                 :   69116196 :                 m = unaligned_read_le64(in);
     113                 :            : #if ENABLE_DEBUG_SIPHASH
     114                 :            :                 printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     115                 :            :                 printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     116                 :            :                 printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     117                 :            :                 printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     118                 :            :                 printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m);
     119                 :            : #endif
     120                 :   69116196 :                 state->v3 ^= m;
     121                 :   69116196 :                 sipround(state);
     122                 :   69116196 :                 sipround(state);
     123                 :   69116196 :                 state->v0 ^= m;
     124                 :            :         }
     125                 :            : 
     126                 :   96450913 :         left = state->inlen & 7;
     127   [ +  +  +  +  :   96450913 :         switch (left) {
             +  +  +  +  
                      - ]
     128                 :   21229785 :                 case 7:
     129                 :   21229785 :                         state->padding |= ((uint64_t) in[6]) << 48;
     130                 :            :                         _fallthrough_;
     131                 :   27155787 :                 case 6:
     132                 :   27155787 :                         state->padding |= ((uint64_t) in[5]) << 40;
     133                 :            :                         _fallthrough_;
     134                 :   28288449 :                 case 5:
     135                 :   28288449 :                         state->padding |= ((uint64_t) in[4]) << 32;
     136                 :            :                         _fallthrough_;
     137                 :   28574064 :                 case 4:
     138                 :   28574064 :                         state->padding |= ((uint64_t) in[3]) << 24;
     139                 :            :                         _fallthrough_;
     140                 :   28970118 :                 case 3:
     141                 :   28970118 :                         state->padding |= ((uint64_t) in[2]) << 16;
     142                 :            :                         _fallthrough_;
     143                 :   29246262 :                 case 2:
     144                 :   29246262 :                         state->padding |= ((uint64_t) in[1]) <<  8;
     145                 :            :                         _fallthrough_;
     146                 :   30209667 :                 case 1:
     147                 :   30209667 :                         state->padding |= ((uint64_t) in[0]);
     148                 :            :                         _fallthrough_;
     149                 :   96450913 :                 case 0:
     150                 :   96450913 :                         break;
     151                 :            :         }
     152                 :            : }
     153                 :            : 
     154                 :         28 : void siphash24_compress_boolean(bool in, struct siphash *state) {
     155                 :         28 :         int i = in;
     156                 :            : 
     157                 :         28 :         siphash24_compress(&i, sizeof i, state);
     158                 :         28 : }
     159                 :            : 
     160                 :   94727961 : uint64_t siphash24_finalize(struct siphash *state) {
     161                 :            :         uint64_t b;
     162                 :            : 
     163         [ -  + ]:   94727961 :         assert(state);
     164                 :            : 
     165                 :   94727961 :         b = state->padding | (((uint64_t) state->inlen) << 56);
     166                 :            : 
     167                 :            : #if ENABLE_DEBUG_SIPHASH
     168                 :            :         printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     169                 :            :         printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     170                 :            :         printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     171                 :            :         printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     172                 :            :         printf("(%3zu) padding   %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding);
     173                 :            : #endif
     174                 :            : 
     175                 :   94727961 :         state->v3 ^= b;
     176                 :   94727961 :         sipround(state);
     177                 :   94727961 :         sipround(state);
     178                 :   94727961 :         state->v0 ^= b;
     179                 :            : 
     180                 :            : #if ENABLE_DEBUG_SIPHASH
     181                 :            :         printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     182                 :            :         printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     183                 :            :         printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     184                 :            :         printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     185                 :            : #endif
     186                 :   94727961 :         state->v2 ^= 0xff;
     187                 :            : 
     188                 :   94727961 :         sipround(state);
     189                 :   94727961 :         sipround(state);
     190                 :   94727961 :         sipround(state);
     191                 :   94727961 :         sipround(state);
     192                 :            : 
     193                 :   94727961 :         return state->v0 ^ state->v1 ^ state->v2  ^ state->v3;
     194                 :            : }
     195                 :            : 
     196                 :         96 : uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[static 16]) {
     197                 :            :         struct siphash state;
     198                 :            : 
     199         [ -  + ]:         96 :         assert(in);
     200         [ -  + ]:         96 :         assert(k);
     201                 :            : 
     202                 :         96 :         siphash24_init(&state, k);
     203                 :         96 :         siphash24_compress(in, inlen, &state);
     204                 :            : 
     205                 :         96 :         return siphash24_finalize(&state);
     206                 :            : }

Generated by: LCOV version 1.14