LCOV - code coverage report
Current view: top level - crypto - siphash.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 77 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: siphash.c,v 1.5 2018/01/05 19:05:09 mikeb Exp $ */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2013 Andre Oppermann <andre@FreeBSD.org>
       5             :  * All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  * 3. The name of the author may not be used to endorse or promote
      16             :  *    products derived from this software without specific prior written
      17             :  *    permission.
      18             :  *
      19             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      20             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      21             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      22             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      23             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      24             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      25             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      26             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      27             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      28             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      29             :  * SUCH DAMAGE.
      30             :  */
      31             : 
      32             : /*
      33             :  * SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d
      34             :  * are the number of compression rounds and the number of finalization rounds.
      35             :  * A compression round is identical to a finalization round and this round
      36             :  * function is called SipRound.  Given a 128-bit key k and a (possibly empty)
      37             :  * byte string m, SipHash-c-d returns a 64-bit value SipHash-c-d(k; m).
      38             :  *
      39             :  * Implemented from the paper "SipHash: a fast short-input PRF", 2012.09.18,
      40             :  * by Jean-Philippe Aumasson and Daniel J. Bernstein,
      41             :  * Permanent Document ID b9a943a805fbfc6fde808af9fc0ecdfa
      42             :  * https://131002.net/siphash/siphash.pdf
      43             :  * https://131002.net/siphash/
      44             :  */
      45             : 
      46             : #include <sys/param.h>
      47             : #include <sys/systm.h>
      48             : 
      49             : #include <crypto/siphash.h>
      50             : 
      51             : static void     SipHash_CRounds(SIPHASH_CTX *, int);
      52             : static void     SipHash_Rounds(SIPHASH_CTX *, int);
      53             : 
      54             : void
      55           0 : SipHash_Init(SIPHASH_CTX *ctx, const SIPHASH_KEY *key)
      56             : {
      57             :         uint64_t k0, k1;
      58             : 
      59           0 :         k0 = lemtoh64(&key->k0);
      60           0 :         k1 = lemtoh64(&key->k1);
      61             : 
      62           0 :         ctx->v[0] = 0x736f6d6570736575ULL ^ k0;
      63           0 :         ctx->v[1] = 0x646f72616e646f6dULL ^ k1;
      64           0 :         ctx->v[2] = 0x6c7967656e657261ULL ^ k0;
      65           0 :         ctx->v[3] = 0x7465646279746573ULL ^ k1;
      66             : 
      67           0 :         memset(ctx->buf, 0, sizeof(ctx->buf));
      68           0 :         ctx->bytes = 0;
      69           0 : }
      70             : 
      71             : void
      72           0 : SipHash_Update(SIPHASH_CTX *ctx, int rc, int rf, const void *src, size_t len)
      73             : {
      74             :         const uint8_t *ptr = src;
      75             :         size_t left, used;
      76             : 
      77           0 :         if (len == 0)
      78           0 :                 return;
      79             : 
      80           0 :         used = ctx->bytes % sizeof(ctx->buf);
      81           0 :         ctx->bytes += len;
      82             : 
      83           0 :         if (used > 0) {
      84           0 :                 left = sizeof(ctx->buf) - used;
      85             : 
      86           0 :                 if (len >= left) {
      87           0 :                         memcpy(&ctx->buf[used], ptr, left);
      88           0 :                         SipHash_CRounds(ctx, rc);
      89           0 :                         len -= left;
      90           0 :                         ptr += left;
      91             :                 } else {
      92           0 :                         memcpy(&ctx->buf[used], ptr, len);
      93           0 :                         return;
      94             :                 }
      95           0 :         }
      96             : 
      97           0 :         while (len >= sizeof(ctx->buf)) {
      98           0 :                 memcpy(ctx->buf, ptr, sizeof(ctx->buf));
      99           0 :                 SipHash_CRounds(ctx, rc);
     100           0 :                 len -= sizeof(ctx->buf);
     101           0 :                 ptr += sizeof(ctx->buf);
     102             :         }
     103             : 
     104           0 :         if (len > 0)
     105           0 :                 memcpy(ctx->buf, ptr, len);
     106           0 : }
     107             : 
     108             : void
     109           0 : SipHash_Final(void *dst, SIPHASH_CTX *ctx, int rc, int rf)
     110             : {
     111             :         uint64_t r;
     112             : 
     113           0 :         htolem64(&r, SipHash_End(ctx, rc, rf));
     114           0 :         memcpy(dst, &r, sizeof r);
     115           0 : }
     116             : 
     117             : uint64_t
     118           0 : SipHash_End(SIPHASH_CTX *ctx, int rc, int rf)
     119             : {
     120             :         uint64_t r;
     121             :         size_t left, used;
     122             : 
     123           0 :         used = ctx->bytes % sizeof(ctx->buf);
     124           0 :         left = sizeof(ctx->buf) - used;
     125           0 :         memset(&ctx->buf[used], 0, left - 1);
     126           0 :         ctx->buf[7] = ctx->bytes;
     127             : 
     128           0 :         SipHash_CRounds(ctx, rc);
     129           0 :         ctx->v[2] ^= 0xff;
     130           0 :         SipHash_Rounds(ctx, rf);
     131             : 
     132           0 :         r = (ctx->v[0] ^ ctx->v[1]) ^ (ctx->v[2] ^ ctx->v[3]);
     133           0 :         explicit_bzero(ctx, sizeof(*ctx));
     134           0 :         return (r);
     135             : }
     136             : 
     137             : uint64_t
     138           0 : SipHash(const SIPHASH_KEY *key, int rc, int rf, const void *src, size_t len)
     139             : {
     140           0 :         SIPHASH_CTX ctx;
     141             : 
     142           0 :         SipHash_Init(&ctx, key);
     143           0 :         SipHash_Update(&ctx, rc, rf, src, len);
     144           0 :         return (SipHash_End(&ctx, rc, rf));
     145           0 : }
     146             : 
     147             : #define SIP_ROTL(x, b) ((x) << (b)) | ( (x) >> (64 - (b)))
     148             : 
     149             : static void
     150           0 : SipHash_Rounds(SIPHASH_CTX *ctx, int rounds)
     151             : {
     152           0 :         while (rounds--) {
     153           0 :                 ctx->v[0] += ctx->v[1];
     154           0 :                 ctx->v[2] += ctx->v[3];
     155           0 :                 ctx->v[1] = SIP_ROTL(ctx->v[1], 13);
     156           0 :                 ctx->v[3] = SIP_ROTL(ctx->v[3], 16);
     157             : 
     158           0 :                 ctx->v[1] ^= ctx->v[0];
     159           0 :                 ctx->v[3] ^= ctx->v[2];
     160           0 :                 ctx->v[0] = SIP_ROTL(ctx->v[0], 32);
     161             : 
     162           0 :                 ctx->v[2] += ctx->v[1];
     163           0 :                 ctx->v[0] += ctx->v[3];
     164           0 :                 ctx->v[1] = SIP_ROTL(ctx->v[1], 17);
     165           0 :                 ctx->v[3] = SIP_ROTL(ctx->v[3], 21);
     166             : 
     167           0 :                 ctx->v[1] ^= ctx->v[2];
     168           0 :                 ctx->v[3] ^= ctx->v[0];
     169           0 :                 ctx->v[2] = SIP_ROTL(ctx->v[2], 32);
     170             :         }
     171           0 : }
     172             : 
     173             : static void
     174           0 : SipHash_CRounds(SIPHASH_CTX *ctx, int rounds)
     175             : {
     176           0 :         uint64_t m = lemtoh64((uint64_t *)ctx->buf);
     177             : 
     178           0 :         ctx->v[3] ^= m;
     179           0 :         SipHash_Rounds(ctx, rounds);
     180           0 :         ctx->v[0] ^= m;
     181           0 : }

Generated by: LCOV version 1.13