Browse Source

add siphash from the kernel to libc

OPENBSD_5_7
tedu 10 years ago
parent
commit
10f5d66e90
3 changed files with 298 additions and 3 deletions
  1. +6
    -3
      src/lib/libc/hash/Makefile.inc
  2. +109
    -0
      src/lib/libc/hash/SipHash24.3
  3. +183
    -0
      src/lib/libc/hash/siphash.c

+ 6
- 3
src/lib/libc/hash/Makefile.inc View File

@ -1,11 +1,11 @@
# $OpenBSD: Makefile.inc,v 1.20 2014/03/23 23:27:22 naddy Exp $
# $OpenBSD: Makefile.inc,v 1.21 2014/12/08 20:37:11 tedu Exp $
# hash functions
.PATH: ${LIBCSRCDIR}/hash
HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c
SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER}
MAN+= md5.3 rmd160.3 sha1.3 sha2.3
SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER} siphash.c
MAN+= md5.3 rmd160.3 sha1.3 sha2.3 SipHash.3
MLINKS+=md5.3 MD5Transform.3 md5.3 MD5Init.3 md5.3 MD5Final.3
MLINKS+=md5.3 MD5Update.3 md5.3 MD5End.3 md5.3 MD5File.3
@ -28,6 +28,9 @@ MLINKS+=sha2.3 SHA384File.3 sha2.3 SHA384FileChunk.3 sha2.3 SHA384Data.3
MLINKS+=sha2.3 SHA512Init.3 sha2.3 SHA512Update.3 sha2.3 SHA512Pad.3
MLINKS+=sha2.3 SHA512Final.3 sha2.3 SHA512Transform.3 sha2.3 SHA512End.3
MLINKS+=sha2.3 SHA512File.3 sha2.3 SHA512FileChunk.3 sha2.3 SHA512Data.3
MLINKS+=SipHash24.3 SipHash24_Init.3 SipHash24.3 SipHash24_Update.3
MLINKS+=SipHash24.3 SipHash24_End.3 SipHash24.3 SipHash24_Final.3
CLEANFILES+= ${HELPER}
md5hl.c: helper.c


+ 109
- 0
src/lib/libc/hash/SipHash24.3 View File

@ -0,0 +1,109 @@
.\" $OpenBSD: SipHash24.3,v 1.1 2014/12/08 20:37:11 tedu Exp $
.\"
.\" Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: December 8 2014 $
.Dt SIPHASH24 9
.Os
.Sh NAME
.Nm SipHash24_Init ,
.Nm SipHash24_Update ,
.Nm SipHash24_End ,
.Nm SipHash24_Final ,
.Nm SipHash24
.Nd calculate SipHash24 hashes
.Sh SYNOPSIS
.In siphash.h
.Ft void
.Fn "SipHash24_Init" "SIPHASH_CTX *ctx" "const SIPHASH_KEY *key"
.Ft void
.Fn "SipHash24_Update" "SIPHASH_CTX *ctx" "const void *data" "size_t len"
.Ft u_int64_t
.Fn "SipHash24_End" "SIPHASH_CTX *ctx"
.Ft void
.Fn "SipHash24_Final" "void *digest" "SIPHASH_CTX *ctx"
.Ft u_int64_t
.Fn "SipHash24" "const SIPHASH_KEY *key" "const void *data" "size_t len"
.Sh DESCRIPTION
The SipHash algorithm is a keyed hash algorithm optimised for short
inputs which produces a 64-bit digest of data.
The SipHash24 functions implement the algorithm with 2 compression
rounds and 4 finalisation rounds.
.Pp
.Fn SipHash24_Init
initialises a
.Vt SIPHASH_CTX
context
.Fa ctx
with the secret
.Fa key .
.Pp
.Fn SipHash24_Update
adds
.Fa data
of length
.Fa len
to the context
.Fa ctx .
.Pp
.Fn SipHash24_End
is called after all data has been added to
.Fa ctx
via
.Fn SipHash24_Update
and returns a message digest in the host's native endian.
.Pp
.Fn SipHash24_Final
is called after all data has been added to
.Fa ctx
via
.Fn SipHash24_Update
and stores the message digest at the address specified by the
.Fa digest
parameter.
The buffer at
.Fa digest
must be
.Dv SIPHASH_DIGEST_LENGTH
bytes long.
.Pp
.Fn SipHash24
calculates the digest of
.Fa data
of length
.Fa len
with the secret
.Fa key .
.Pp
If SipHash is being used to mitigate against hash-table flooding
attacks, it is recommended that the
.Vt SIPHASH_KEY
key be generated with
.Xr arc4random_buf 9 .
.Sh CONTEXT
.Fn SipHash24_Init ,
.Fn SipHash24_Update ,
.Fn SipHash24_End ,
.Fn SipHash24_Final
and
.Fn SipHash24
can be called during autoconf, from process context, or from interrupt context.
.Sh RETURN VALUES
.Fn SipHash24_End
and
.Fn SipHash24
return the 64-bit message digest in the host's native endian representation.
.Sh SEE ALSO
.Xr arc4random_buf 9

+ 183
- 0
src/lib/libc/hash/siphash.c View File

@ -0,0 +1,183 @@
/* $OpenBSD: siphash.c,v 1.1 2014/12/08 20:37:11 tedu Exp $ */
/*-
* Copyright (c) 2013 Andre Oppermann <andre@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d
* are the number of compression rounds and the number of finalization rounds.
* A compression round is identical to a finalization round and this round
* function is called SipRound. Given a 128-bit key k and a (possibly empty)
* byte string m, SipHash-c-d returns a 64-bit value SipHash-c-d(k; m).
*
* Implemented from the paper "SipHash: a fast short-input PRF", 2012.09.18,
* by Jean-Philippe Aumasson and Daniel J. Bernstein,
* Permanent Document ID b9a943a805fbfc6fde808af9fc0ecdfa
* https://131002.net/siphash/siphash.pdf
* https://131002.net/siphash/
*/
#include <sys/param.h>
#include <sys/endian.h>
#include <string.h>
#include <siphash.h>
void SipHash_CRounds(SIPHASH_CTX *, int);
void SipHash_Rounds(SIPHASH_CTX *, int);
void
SipHash_Init(SIPHASH_CTX *ctx, const SIPHASH_KEY *key)
{
uint64_t k0, k1;
k0 = le64toh(key->k0);
k1 = le64toh(key->k1);
ctx->v[0] = 0x736f6d6570736575ULL ^ k0;
ctx->v[1] = 0x646f72616e646f6dULL ^ k1;
ctx->v[2] = 0x6c7967656e657261ULL ^ k0;
ctx->v[3] = 0x7465646279746573ULL ^ k1;
memset(ctx->buf, 0, sizeof(ctx->buf));
ctx->bytes = 0;
}
void
SipHash_Update(SIPHASH_CTX *ctx, int rc, int rf, const void *src, size_t len)
{
const u_int8_t *ptr = src;
size_t free, used;
if (len == 0)
return;
used = ctx->bytes % sizeof(ctx->buf);
ctx->bytes += len;
if (used > 0) {
free = sizeof(ctx->buf) - used;
if (len >= free) {
memcpy(&ctx->buf[used], ptr, free);
SipHash_CRounds(ctx, rc);
len -= free;
ptr += free;
} else {
memcpy(&ctx->buf[used], ptr, len);
return;
}
}
while (len >= sizeof(ctx->buf)) {
memcpy(ctx->buf, ptr, sizeof(ctx->buf));
SipHash_CRounds(ctx, rc);
len -= sizeof(ctx->buf);
ptr += sizeof(ctx->buf);
}
if (len > 0)
memcpy(&ctx->buf[used], ptr, len);
}
void
SipHash_Final(void *dst, SIPHASH_CTX *ctx, int rc, int rf)
{
u_int64_t r;
r = SipHash_End(ctx, rc, rf);
*(u_int64_t *)dst = htole64(r);
}
u_int64_t
SipHash_End(SIPHASH_CTX *ctx, int rc, int rf)
{
u_int64_t r;
size_t free, used;
used = ctx->bytes % sizeof(ctx->buf);
free = sizeof(ctx->buf) - used;
memset(&ctx->buf[used], 0, free - 1);
ctx->buf[7] = ctx->bytes;
SipHash_CRounds(ctx, rc);
ctx->v[2] ^= 0xff;
SipHash_Rounds(ctx, rf);
r = (ctx->v[0] ^ ctx->v[1]) ^ (ctx->v[2] ^ ctx->v[3]);
explicit_bzero(ctx, sizeof(*ctx));
return (r);
}
u_int64_t
SipHash(const SIPHASH_KEY *key, int rc, int rf, const void *src, size_t len)
{
SIPHASH_CTX ctx;
SipHash_Init(&ctx, key);
SipHash_Update(&ctx, rc, rf, src, len);
return (SipHash_End(&ctx, rc, rf));
}
#define SIP_ROTL(x, b) ((x) << (b)) | ( (x) >> (64 - (b)))
void
SipHash_Rounds(SIPHASH_CTX *ctx, int rounds)
{
while (rounds--) {
ctx->v[0] += ctx->v[1];
ctx->v[2] += ctx->v[3];
ctx->v[1] = SIP_ROTL(ctx->v[1], 13);
ctx->v[3] = SIP_ROTL(ctx->v[3], 16);
ctx->v[1] ^= ctx->v[0];
ctx->v[3] ^= ctx->v[2];
ctx->v[0] = SIP_ROTL(ctx->v[0], 32);
ctx->v[2] += ctx->v[1];
ctx->v[0] += ctx->v[3];
ctx->v[1] = SIP_ROTL(ctx->v[1], 17);
ctx->v[3] = SIP_ROTL(ctx->v[3], 21);
ctx->v[1] ^= ctx->v[2];
ctx->v[3] ^= ctx->v[0];
ctx->v[2] = SIP_ROTL(ctx->v[2], 32);
}
}
void
SipHash_CRounds(SIPHASH_CTX *ctx, int rounds)
{
u_int64_t m = letoh64(*(u_int64_t *)ctx->buf);
ctx->v[3] ^= m;
SipHash_Rounds(ctx, rounds);
ctx->v[0] ^= m;
}

Loading…
Cancel
Save