674baa3c4f
changes. MFC after: 2 weeks X-MFC-With: r361677
197 lines
5.5 KiB
C
197 lines
5.5 KiB
C
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*
|
|
* SipHash (C reference implementation, APR-ized), originating from:
|
|
* https://131002.net/siphash/siphash24.c.
|
|
*/
|
|
|
|
#include "apr_siphash.h"
|
|
|
|
#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
|
|
|
#define U8TO64_LE(p) \
|
|
(((apr_uint64_t)((p)[0]) ) | \
|
|
((apr_uint64_t)((p)[1]) << 8) | \
|
|
((apr_uint64_t)((p)[2]) << 16) | \
|
|
((apr_uint64_t)((p)[3]) << 24) | \
|
|
((apr_uint64_t)((p)[4]) << 32) | \
|
|
((apr_uint64_t)((p)[5]) << 40) | \
|
|
((apr_uint64_t)((p)[6]) << 48) | \
|
|
((apr_uint64_t)((p)[7]) << 56))
|
|
|
|
#define U64TO8_LE(p, v) \
|
|
do { \
|
|
(p)[0] = (unsigned char)((v) ); \
|
|
(p)[1] = (unsigned char)((v) >> 8); \
|
|
(p)[2] = (unsigned char)((v) >> 16); \
|
|
(p)[3] = (unsigned char)((v) >> 24); \
|
|
(p)[4] = (unsigned char)((v) >> 32); \
|
|
(p)[5] = (unsigned char)((v) >> 40); \
|
|
(p)[6] = (unsigned char)((v) >> 48); \
|
|
(p)[7] = (unsigned char)((v) >> 56); \
|
|
} while (0)
|
|
|
|
#define SIPROUND() \
|
|
do { \
|
|
v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
|
|
v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
|
|
v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
|
|
v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
|
|
} while(0)
|
|
|
|
#define SIPHASH(r, s, n, k) \
|
|
do { \
|
|
const unsigned char *ptr, *end; \
|
|
apr_uint64_t v0, v1, v2, v3, m; \
|
|
apr_uint64_t k0, k1; \
|
|
unsigned int rem; \
|
|
\
|
|
k0 = U8TO64_LE(k + 0); \
|
|
k1 = U8TO64_LE(k + 8); \
|
|
v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL; \
|
|
v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL; \
|
|
v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL; \
|
|
v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL; \
|
|
\
|
|
rem = (unsigned int)(n & 0x7); \
|
|
for (ptr = s, end = ptr + n - rem; ptr < end; ptr += 8) { \
|
|
m = U8TO64_LE(ptr); \
|
|
v3 ^= m; \
|
|
cROUNDS \
|
|
v0 ^= m; \
|
|
} \
|
|
m = (apr_uint64_t)(n & 0xff) << 56; \
|
|
switch (rem) { \
|
|
case 7: m |= (apr_uint64_t)ptr[6] << 48; \
|
|
case 6: m |= (apr_uint64_t)ptr[5] << 40; \
|
|
case 5: m |= (apr_uint64_t)ptr[4] << 32; \
|
|
case 4: m |= (apr_uint64_t)ptr[3] << 24; \
|
|
case 3: m |= (apr_uint64_t)ptr[2] << 16; \
|
|
case 2: m |= (apr_uint64_t)ptr[1] << 8; \
|
|
case 1: m |= (apr_uint64_t)ptr[0]; \
|
|
case 0: break; \
|
|
} \
|
|
v3 ^= m; \
|
|
cROUNDS \
|
|
v0 ^= m; \
|
|
\
|
|
v2 ^= 0xff; \
|
|
dROUNDS \
|
|
\
|
|
r = v0 ^ v1 ^ v2 ^ v3; \
|
|
} while (0)
|
|
|
|
APU_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE],
|
|
unsigned int c, unsigned int d)
|
|
{
|
|
apr_uint64_t h;
|
|
unsigned int i;
|
|
|
|
#undef cROUNDS
|
|
#define cROUNDS \
|
|
for (i = 0; i < c; ++i) { \
|
|
SIPROUND(); \
|
|
}
|
|
|
|
#undef dROUNDS
|
|
#define dROUNDS \
|
|
for (i = 0; i < d; ++i) { \
|
|
SIPROUND(); \
|
|
}
|
|
|
|
SIPHASH(h, src, len, key);
|
|
return h;
|
|
}
|
|
|
|
APU_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE],
|
|
const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE],
|
|
unsigned int c, unsigned int d)
|
|
{
|
|
apr_uint64_t h;
|
|
h = apr_siphash(src, len, key, c, d);
|
|
U64TO8_LE(out, h);
|
|
}
|
|
|
|
APU_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE])
|
|
{
|
|
apr_uint64_t h;
|
|
|
|
#undef cROUNDS
|
|
#define cROUNDS \
|
|
SIPROUND(); \
|
|
SIPROUND();
|
|
|
|
#undef dROUNDS
|
|
#define dROUNDS \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND();
|
|
|
|
SIPHASH(h, src, len, key);
|
|
return h;
|
|
}
|
|
|
|
APU_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE],
|
|
const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE])
|
|
{
|
|
apr_uint64_t h;
|
|
h = apr_siphash24(src, len, key);
|
|
U64TO8_LE(out, h);
|
|
}
|
|
|
|
APU_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE])
|
|
{
|
|
apr_uint64_t h;
|
|
|
|
#undef cROUNDS
|
|
#define cROUNDS \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND();
|
|
|
|
#undef dROUNDS
|
|
#define dROUNDS \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND(); \
|
|
SIPROUND();
|
|
|
|
SIPHASH(h, src, len, key);
|
|
return h;
|
|
}
|
|
|
|
APU_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE],
|
|
const void *src, apr_size_t len,
|
|
const unsigned char key[APR_SIPHASH_KSIZE])
|
|
{
|
|
apr_uint64_t h;
|
|
h = apr_siphash48(src, len, key);
|
|
U64TO8_LE(out, h);
|
|
}
|
|
|