1 // SPDX-License-Identifier: BSD-3-Clause 1 2 /* $OpenBSD: siphash.c,v 1.3 2015/02/20 1 3 4 /*- 5 * Copyright (c) 2013 Andre Oppermann <andre@F 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary 9 * modification, are permitted provided that t 10 * are met: 11 * 1. Redistributions of source code must reta 12 * notice, this list of conditions and the 13 * 2. Redistributions in binary form must repr 14 * notice, this list of conditions and the 15 * documentation and/or other materials pro 16 * 3. The name of the author may not be used t 17 * products derived from this software with 18 * permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDIN 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND F 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTH 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECI 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PRO 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILI 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF AD 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * SipHash is a family of PRFs SipHash-c-d whe 35 * are the number of compression rounds and th 36 * A compression round is identical to a final 37 * function is called SipRound. Given a 128-b 38 * byte string m, SipHash-c-d returns a 64-bit 39 * 40 * Implemented from the paper "SipHash: a fast 41 * by Jean-Philippe Aumasson and Daniel J. Ber 42 * Permanent Document ID b9a943a805fbfc6fde808 43 * https://131002.net/siphash/siphash.pdf 44 * https://131002.net/siphash/ 45 */ 46 47 #include <asm/byteorder.h> 48 #include <linux/unaligned.h> 49 #include <linux/bitops.h> 50 #include <linux/string.h> 51 52 #include "siphash.h" 53 54 static void SipHash_Rounds(SIPHASH_CTX *ctx, i 55 { 56 while (rounds--) { 57 ctx->v[0] += ctx->v[1]; 58 ctx->v[2] += ctx->v[3]; 59 ctx->v[1] = rol64(ctx->v[1], 1 60 ctx->v[3] = rol64(ctx->v[3], 1 61 62 ctx->v[1] ^= ctx->v[0]; 63 ctx->v[3] ^= ctx->v[2]; 64 ctx->v[0] = rol64(ctx->v[0], 3 65 66 ctx->v[2] += ctx->v[1]; 67 ctx->v[0] += ctx->v[3]; 68 ctx->v[1] = rol64(ctx->v[1], 1 69 ctx->v[3] = rol64(ctx->v[3], 2 70 71 ctx->v[1] ^= ctx->v[2]; 72 ctx->v[3] ^= ctx->v[0]; 73 ctx->v[2] = rol64(ctx->v[2], 3 74 } 75 } 76 77 static void SipHash_CRounds(SIPHASH_CTX *ctx, 78 { 79 u64 m = get_unaligned_le64(ptr); 80 81 ctx->v[3] ^= m; 82 SipHash_Rounds(ctx, rounds); 83 ctx->v[0] ^= m; 84 } 85 86 void SipHash_Init(SIPHASH_CTX *ctx, const SIPH 87 { 88 u64 k0, k1; 89 90 k0 = le64_to_cpu(key->k0); 91 k1 = le64_to_cpu(key->k1); 92 93 ctx->v[0] = 0x736f6d6570736575ULL ^ k0 94 ctx->v[1] = 0x646f72616e646f6dULL ^ k1 95 ctx->v[2] = 0x6c7967656e657261ULL ^ k0 96 ctx->v[3] = 0x7465646279746573ULL ^ k1 97 98 memset(ctx->buf, 0, sizeof(ctx->buf)); 99 ctx->bytes = 0; 100 } 101 102 void SipHash_Update(SIPHASH_CTX *ctx, int rc, 103 const void *src, size_t le 104 { 105 const u8 *ptr = src; 106 size_t left, used; 107 108 if (len == 0) 109 return; 110 111 used = ctx->bytes % sizeof(ctx->buf); 112 ctx->bytes += len; 113 114 if (used > 0) { 115 left = sizeof(ctx->buf) - used 116 117 if (len >= left) { 118 memcpy(&ctx->buf[used] 119 SipHash_CRounds(ctx, c 120 len -= left; 121 ptr += left; 122 } else { 123 memcpy(&ctx->buf[used] 124 return; 125 } 126 } 127 128 while (len >= sizeof(ctx->buf)) { 129 SipHash_CRounds(ctx, ptr, rc); 130 len -= sizeof(ctx->buf); 131 ptr += sizeof(ctx->buf); 132 } 133 134 if (len > 0) 135 memcpy(&ctx->buf[used], ptr, l 136 } 137 138 void SipHash_Final(void *dst, SIPHASH_CTX *ctx 139 { 140 u64 r; 141 142 r = SipHash_End(ctx, rc, rf); 143 144 *((__le64 *) dst) = cpu_to_le64(r); 145 } 146 147 u64 SipHash_End(SIPHASH_CTX *ctx, int rc, int 148 { 149 u64 r; 150 size_t left, used; 151 152 used = ctx->bytes % sizeof(ctx->buf); 153 left = sizeof(ctx->buf) - used; 154 memset(&ctx->buf[used], 0, left - 1); 155 ctx->buf[7] = ctx->bytes; 156 157 SipHash_CRounds(ctx, ctx->buf, rc); 158 ctx->v[2] ^= 0xff; 159 SipHash_Rounds(ctx, rf); 160 161 r = (ctx->v[0] ^ ctx->v[1]) ^ (ctx->v[ 162 memset(ctx, 0, sizeof(*ctx)); 163 return r; 164 } 165 166 u64 SipHash(const SIPHASH_KEY *key, int rc, in 167 { 168 SIPHASH_CTX ctx; 169 170 SipHash_Init(&ctx, key); 171 SipHash_Update(&ctx, rc, rf, src, len) 172 return SipHash_End(&ctx, rc, rf); 173 } 174
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.