Add SipHash algorithm

This commit is contained in:
Sean Parkinson
2022-01-14 13:56:23 +10:00
parent f81e15f342
commit a6485a228d
11 changed files with 1578 additions and 0 deletions

View File

@ -683,6 +683,7 @@ then
test "$enable_psk" = "" && enable_psk=yes
test "$enable_idea" = "" && enable_idea=yes
test "$enable_cmac" = "" && enable_cmac=yes
test "$enable_siphash" = "" && enable_siphash=yes
test "$enable_xts" = "" && enable_xts=yes
test "$enable_hc128" = "" && enable_hc128=yes
test "$enable_rabbit" = "" && enable_rabbit=yes
@ -3354,6 +3355,17 @@ else
fi
# SipHash
AC_ARG_ENABLE([siphash],
[AS_HELP_STRING([--enable-siphash],[Enable SipHash (default: disabled)])],
[ ENABLED_SIPHASH=$enableval ],
[ ENABLED_SIPHASH=no ]
)
AS_IF([test "x$ENABLED_SIPHASH" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SIPHASH"])
# CMAC
AC_ARG_ENABLE([cmac],
[AS_HELP_STRING([--enable-cmac],[Enable CMAC (default: disabled)])],
@ -7394,6 +7406,7 @@ AM_CONDITIONAL([BUILD_FIPS_RAND],[test "x$FIPS_VERSION" = "xrand"])
AM_CONDITIONAL([BUILD_FIPS_V3],[test "$HAVE_FIPS_VERSION" = 3])
AM_CONDITIONAL([BUILD_FIPS_V5],[test "$HAVE_FIPS_VERSION" = 5])
AM_CONDITIONAL([BUILD_FIPS_CURRENT],[test "$HAVE_FIPS_VERSION" -ge 2 ])
AM_CONDITIONAL([BUILD_SIPHASH],[test "x$ENABLED_SIPHASH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_CMAC],[test "x$ENABLED_CMAC" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
AM_CONDITIONAL([BUILD_SELFTEST],[test "x$ENABLED_SELFTEST" = "xyes"])
AM_CONDITIONAL([BUILD_SHA224],[test "x$ENABLED_SHA224" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
@ -7713,6 +7726,7 @@ echo " * SHA3: $ENABLED_SHA3"
echo " * SHAKE256: $ENABLED_SHAKE256"
echo " * BLAKE2: $ENABLED_BLAKE2"
echo " * BLAKE2S: $ENABLED_BLAKE2S"
echo " * SipHash: $ENABLED_SIPHASH"
echo " * CMAC: $ENABLED_CMAC"
echo " * keygen: $ENABLED_KEYGEN"
echo " * certgen: $ENABLED_CERTGEN"

View File

@ -207,6 +207,7 @@
\defgroup RSA Algorithms - RSA
\defgroup Rabbit Algorithms - Rabbit
\defgroup SHA Algorithms - SHA 128/224/256/384/512
\defgroup SipHash Algorithm - SipHash
\defgroup SRP Algorithms - SRP
\defgroup ASN ASN.1

View File

@ -57,6 +57,7 @@
<li>\ref RIPEMD</li>
<li>\ref RSA</li>
<li>\ref SHA</li>
<li>\ref SipHash</li>
<li>\ref SRP</li>
</ul>
*/

View File

@ -0,0 +1,151 @@
/*!
\ingroup SipHash
\brief This function initializes SipHash with a key for a MAC size.
\return 0 Returned upon successfully initializing
\return BAD_FUNC_ARG Returned when siphash or key is NULL
\return BAD_FUNC_ARG Returned when outSz is neither 8 nor 16
\param siphash pointer to the SipHash structure to use for MACing
\param key pointer to the 16-byte array
\param outSz number of bytes to output as MAC
_Example_
\code
SipHash siphash[1];
unsigned char key[16] = { ... };
byte macSz = 8; // 8 or 16
if ((ret = wc_InitSipHash(siphash, key, macSz)) != 0) {
WOLFSSL_MSG("wc_InitSipHash failed");
}
else if ((ret = wc_SipHashUpdate(siphash, data, len)) != 0) {
WOLFSSL_MSG("wc_SipHashUpdate failed");
}
else if ((ret = wc_SipHashFinal(siphash, mac, macSz)) != 0) {
WOLFSSL_MSG("wc_SipHashFinal failed");
}
\endcode
\sa wc_SipHash
\sa wc_SipHashUpdate
\sa wc_SipHashFinal
*/
WOLFSSL_API int wc_InitSipHash(SipHash* siphash, const unsigned char* key,
unsigned char outSz);
/*!
\ingroup SipHash
\brief Can be called to continually hash the provided byte
array of length len.
\return 0 Returned upon successfully adding the data to the MAC
\return BAD_FUNC_ARG Returned when siphash is NULL
\return BAD_FUNC_ARG Returned when in is NULL and inSz is not zero
\param siphash pointer to the SipHash structure to use for MACing
\param in the data to be MACed
\param inSz size of data to be MACed
_Example_
\code
SipHash siphash[1];
byte data[] = { Data to be MACed };
word32 len = sizeof(data);
if ((ret = wc_InitSipHash(siphash, key, macSz)) != 0) {
WOLFSSL_MSG("wc_InitSipHash failed");
}
else if ((ret = wc_SipHashUpdate(siphash, data, len)) != 0) {
WOLFSSL_MSG("wc_SipHashUpdate failed");
}
else if ((ret = wc_SipHashFinal(siphash, mac, macSz)) != 0) {
WOLFSSL_MSG("wc_SipHashFinal failed");
}
\endcode
\sa wc_SipHash
\sa wc_InitSipHash
\sa wc_SipHashFinal
*/
WOLFSSL_API int wc_SipHashUpdate(SipHash* siphash, const unsigned char* in,
word32 inSz);
/*!
\ingroup SipHash
\brief Finalizes MACing of data. Result is placed into out.
\return 0 Returned upon successfully finalizing.
\return BAD_FUNC_ARG Returned when siphash of out is NULL
\return BAD_FUNC_ARG Returned when outSz is not the same as the initialized
value
\param siphash pointer to the SipHash structure to use for MACing
\param out Byte array to hold MAC value
\param outSz number of bytes to output as MAC
_Example_
\code
SipHash siphash[1];
byte mac[8] = { ... }; // 8 or 16 bytes
byte macSz = sizeof(mac);
if ((ret = wc_InitSipHash(siphash, key, macSz)) != 0) {
WOLFSSL_MSG("wc_InitSipHash failed");
}
else if ((ret = wc_SipHashUpdate(siphash, data, len)) != 0) {
WOLFSSL_MSG("wc_SipHashUpdate failed");
}
else if ((ret = wc_SipHashFinal(siphash, mac, macSz)) != 0) {
WOLFSSL_MSG("wc_SipHashFinal failed");
}
\endcode
\sa wc_SipHash
\sa wc_InitSipHash
\sa wc_SipHashUpdate
*/
WOLFSSL_API int wc_SipHashFinal(SipHash* siphash, unsigned char* out,
unsigned char outSz);
/*!
\ingroup SipHash
\brief This function one-shots the data using SipHash to calculate a MAC
based on the key.
\return 0 Returned upon successfully MACing
\return BAD_FUNC_ARG Returned when key or out is NULL
\return BAD_FUNC_ARG Returned when in is NULL and inSz is not zero
\return BAD_FUNC_ARG Returned when outSz is neither 8 nor 16
\param key pointer to the 16-byte array
\param in the data to be MACed
\param inSz size of data to be MACed
\param out Byte array to hold MAC value
\param outSz number of bytes to output as MAC
_Example_
\code
unsigned char key[16] = { ... };
byte data[] = { Data to be MACed };
word32 len = sizeof(data);
byte mac[8] = { ... }; // 8 or 16 bytes
byte macSz = sizeof(mac);
if ((ret = wc_SipHash(key, data, len, mac, macSz)) != 0) {
WOLFSSL_MSG("wc_SipHash failed");
}
\endcode
\sa wc_InitSipHash
\sa wc_SipHashUpdate
\sa wc_SipHashFinal
*/
WOLFSSL_API int wc_SipHash(const unsigned char* key, const unsigned char* in,
word32 inSz, unsigned char* out, unsigned char outSz);

View File

@ -487,6 +487,10 @@ endif !BUILD_FIPS_CURRENT
endif !BUILD_FIPS_RAND
if BUILD_SIPHASH
src_libwolfssl_la_SOURCES += wolfcrypt/src/siphash.c
endif
src_libwolfssl_la_SOURCES += \
wolfcrypt/src/logging.c \
wolfcrypt/src/wc_port.c \

View File

@ -171,6 +171,9 @@
#ifndef NO_HMAC
#include <wolfssl/wolfcrypt/hmac.h>
#endif
#ifdef WOLFSSL_SIPHASH
#include <wolfssl/wolfcrypt/siphash.h>
#endif
#ifndef NO_PWDBASED
#include <wolfssl/wolfcrypt/pwdbased.h>
#endif
@ -316,6 +319,7 @@
BENCH_HMAC_SHA224 | BENCH_HMAC_SHA256 | \
BENCH_HMAC_SHA384 | BENCH_HMAC_SHA512)
#define BENCH_PBKDF2 0x00000100
#define BENCH_SIPHASH 0x00000200
/* Asymmetric algorithms. */
#define BENCH_RSA_KEYGEN 0x00000001
@ -547,6 +551,9 @@ static const bench_alg bench_mac_opt[] = {
#ifndef NO_PWDBASED
{ "-pbkdf2", BENCH_PBKDF2 },
#endif
#ifdef WOLFSSL_SIPHASH
{ "-siphash", BENCH_SIPHASH },
#endif
#endif
{ NULL, 0 }
};
@ -1990,6 +1997,11 @@ static void* benchmarks_do(void* args)
bench_pbkdf2();
}
#endif
#ifdef WOLFSSL_SIPHASH
if (bench_all || (bench_mac_algs & BENCH_SIPHASH)) {
bench_siphash();
}
#endif
#endif /* NO_HMAC */
#ifdef HAVE_SCRYPT
@ -4752,6 +4764,37 @@ void bench_pbkdf2(void)
#endif /* NO_HMAC */
#ifdef WOLFSSL_SIPHASH
void bench_siphash(void)
{
double start;
int ret = 0, count;
const char* passwd16 = "passwordpassword";
byte out[16];
int i;
bench_stats_start(&count, &start);
do {
for (i = 0; i < numBlocks; i++) {
ret = wc_SipHash((const byte*)passwd16, bench_plain, BENCH_SIZE,
out, 8);
}
count += i;
} while (bench_stats_sym_check(start));
bench_stats_sym_finish("SipHash-8", 1, count, BENCH_SIZE, start, ret);
bench_stats_start(&count, &start);
do {
for (i = 0; i < numBlocks; i++) {
ret = wc_SipHash((const byte*)passwd16, bench_plain, BENCH_SIZE,
out, 16);
}
count += i;
} while (bench_stats_sym_check(start));
bench_stats_sym_finish("SipHash-16", 1, count, BENCH_SIZE, start, ret);
}
#endif
#ifndef NO_RSA
#if defined(WOLFSSL_KEY_GEN)

View File

@ -77,6 +77,7 @@ void bench_hmac_sha224(int);
void bench_hmac_sha256(int);
void bench_hmac_sha384(int);
void bench_hmac_sha512(int);
void bench_siphash(void);
void bench_rsaKeyGen(int);
void bench_rsaKeyGen_size(int, int);
void bench_rsa(int);

930
wolfcrypt/src/siphash.c Normal file
View File

@ -0,0 +1,930 @@
/* siphash.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/siphash.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
/* DESCRIPTION
*
* SipHash is a PseudoRandom Function (PRF) that can be used with small
* messages (less than 256 bytes).
* SipHash can be used for Message Authentication Codes (MACs) and as such must
* be passed a secret key.
* https://eprint.iacr.org/2012/351.pdf
*
* SipHash is commonly used in hash tables.
* Do not use this as a hash not as a general purpose MAC.
*
* WOLFSSL_SIPHASH_CROUNDS and WOLFSSL_SIPHASH_DROUNDS can be defined at build
* time to change the algorithm.
* Default is SipHash-2-4:
* WOLFSSL_SIPHASH_CROUNDS = 2
* WOLFSSL_SIPHASH_DROUNDS = 4
*
* Inline assembly implementations of wc_SipHash() written for:
* - GCC for Intel x86_64
* - GCC for Aarch64.
*/
#ifdef WOLFSSL_SIPHASH
#ifdef LITTLE_ENDIAN_ORDER
/**
* Decode little-endian byte array to 64-bit number.
*
* @param [in] a Little-endian byte array.
* @return 64-bit number.
*/
#define GET_U64(a) (*(word64*)(a))
/**
* Decode little-endian byte array to 32-bit number.
*
* @param [in] a Little-endian byte array.
* @return 32-bit number.
*/
#define GET_U32(a) (*(word32*)(a))
/**
* Decode little-endian byte array to 16-bit number.
*
* @param [in] a Little-endian byte array.
* @return 16-bit number.
*/
#define GET_U16(a) (*(word16*)(a))
/**
* Encode 64-bit nuumber to a little-endian byte array.
*
* @param [out] a Byte array to write into.
* @param [in] n Number to encode.
*/
#define SET_U64(a, n) ((*(word64*)(a)) = n)
#else
/**
* Decode little-endian byte array to 64-bit number.
*
* @param [in] a Little-endian byte array.
* @return 64-bit number.
*/
#define GET_U64(a) (((word64)((a)[7]) << 56) | \
((word64)((a)[6]) << 48) | \
((word64)((a)[5]) << 40) | \
((word64)((a)[4]) << 32) | \
((word64)((a)[3]) << 24) | \
((word64)((a)[2]) << 16) | \
((word64)((a)[1]) << 8) | \
((word64)((a)[0]) ))
/**
* Decode little-endian byte array to 32-bit number.
*
* @param [in] a Little-endian byte array.
* @return 32-bit number.
*/
#define GET_U32(a) (((word64)((a)[3]) << 24) | \
((word32)((a)[2]) << 16) | \
((word32)((a)[1]) << 8) | \
((word32)((a)[0]) ))
/**
* Decode little-endian byte array to 16-bit number.
*
* @param [in] a Little-endian byte array.
* @return 16-bit number.
*/
#define GET_U16(a) (((word16)((a)[1]) << 8) | \
((word16)((a)[0]) ))
/**
* Encode 64-bit nuumber to a little-endian byte array.
*
* @param [out] a Byte array to write into.
* @param [in] n Number to encode.
*/
#define SET_U64(a, n) (a)[0] = (byte)((n) ); \
(a)[1] = (byte)((n) >> 8); \
(a)[2] = (byte)((n) >> 16); \
(a)[3] = (byte)((n) >> 24); \
(a)[4] = (byte)((n) >> 32); \
(a)[5] = (byte)((n) >> 40); \
(a)[6] = (byte)((n) >> 48); \
(a)[7] = (byte)((n) >> 56)
#endif
/**
* Initialize SipHash operation with a key.
*
* @param [out] sipHash SipHash object.
* @param [in] key 16 byte array - little endian.
* @return BAD_FUNC_ARG when sipHash or key is NULL.
* @return BAD_FUNC_ARG when outSz is neither 8 nor 16.
* @return 0 on success.
*/
int wc_InitSipHash(SipHash* sipHash, const unsigned char* key,
unsigned char outSz)
{
int ret = 0;
/* Validate parameters. */
if ((sipHash == NULL) || (key == NULL) ||
((outSz != SIPHASH_MAC_SIZE_8) && (outSz != SIPHASH_MAC_SIZE_16))) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
word64 k0 = GET_U64(key + 0);
word64 k1 = GET_U64(key + 8);
/* Initialize state with key. */
sipHash->v[0] = 0x736f6d6570736575UL;
if (outSz == SIPHASH_MAC_SIZE_8) {
sipHash->v[1] = 0x646f72616e646f6dUL;
}
else {
sipHash->v[1] = 0x646f72616e646f83UL;
}
sipHash->v[2] = 0x6c7967656e657261UL;
sipHash->v[3] = 0x7465646279746573UL;
sipHash->v[0] ^= k0;
sipHash->v[1] ^= k1;
sipHash->v[2] ^= k0;
sipHash->v[3] ^= k1;
/* No cached message bytes. */
sipHash->cacheCnt = 0;
/* No message bytes compressed yet. */
sipHash->inCnt = 0;
/* Keep the output size to check against final call. */
sipHash->outSz = outSz;
}
return ret;
}
/**
* One round of SipHash.
*
* @param [in, out] sipHash SipHash object.
*/
static WC_INLINE void SipRound(SipHash *sipHash)
{
word64* v = sipHash->v;
v[0] += v[1];
v[2] += v[3];
v[1] = rotlFixed64(v[1], 13);
v[3] = rotlFixed64(v[3], 16);
v[1] ^= v[0];
v[3] ^= v[2];
v[0] = rotlFixed64(v[0], 32);
v[2] += v[1];
v[0] += v[3];
v[1] = rotlFixed64(v[1], 17);
v[3] = rotlFixed64(v[3], 21);
v[1] ^= v[2];
v[3] ^= v[0];
v[2] = rotlFixed64(v[2], 32);
}
/**
* One step of the compression operation.
*
* @param [in, out] sipHash SipHash object.
* @param [in] m Message to compress.
*/
static WC_INLINE void SipHashCompress(SipHash* sipHash, const byte* m)
{
int i;
sipHash->v[3] ^= GET_U64(m);
for (i = 0; i < WOLFSSL_SIPHASH_CROUNDS; i++) {
SipRound(sipHash);
}
sipHash->v[0] ^= GET_U64(m);
}
/**
* Update the SipHash operation with more data.
*
* @param [in, out] sipHash SipHash object.
* @param [in] in Input message.
* @param [in] inSz Size of input message.
* @return BAD_FUNC_ARG when sipHash is NULL.
* @return BAD_FUNC_ARG when in is NULL and inSz is not zero.
* @return 0 on success.
*/
int wc_SipHashUpdate(SipHash* sipHash, const unsigned char* in, word32 inSz)
{
int ret = 0;
/* Validate parameters. */
if ((sipHash == NULL) || ((in == NULL) && (inSz != 0))) {
ret = BAD_FUNC_ARG;
}
/* Process any message bytes. */
if ((ret == 0) && (inSz > 0)) {
/* Add to cache if already started. */
if (sipHash->cacheCnt > 0) {
byte len = SIPHASH_BLOCK_SIZE - sipHash->cacheCnt;
if (len > inSz) {
len = inSz;
}
XMEMCPY(sipHash->cache + sipHash->cacheCnt, in, len);
in += len;
inSz -= len;
sipHash->cacheCnt += len;
if (sipHash->cacheCnt == SIPHASH_BLOCK_SIZE) {
/* Compress the block from the cache. */
SipHashCompress(sipHash, sipHash->cache);
sipHash->cacheCnt = 0;
}
}
/* Process more blocks from message. */
while (inSz >= SIPHASH_BLOCK_SIZE) {
/* Compress the next block from the message data. */
SipHashCompress(sipHash, in);
in += SIPHASH_BLOCK_SIZE;
inSz -= SIPHASH_BLOCK_SIZE;
sipHash->inCnt += SIPHASH_BLOCK_SIZE;
}
if (inSz > 0) {
/* Cache remaining message bytes less than a block. */
XMEMCPY(sipHash->cache, in, inSz);
sipHash->cacheCnt = inSz;
}
}
return ret;
}
/**
* Calculate 8-bytes of output.
*
* @param [in, out] sipHash SipHash object.
* @param [out] out Buffer to place 8-bytes of MAC into.
*/
static WC_INLINE void SipHashOut(SipHash* sipHash, byte* out)
{
word64 n;
int i;
for (i = 0; i < WOLFSSL_SIPHASH_DROUNDS; i++) {
SipRound(sipHash);
}
n = sipHash->v[0] ^ sipHash->v[1] ^ sipHash->v[2] ^ sipHash->v[3];
SET_U64(out, n);
}
/**
* Finalize SipHash operation.
*
* @param [in, out] sipHash SipHash object.
* @param [out] out Buffer to place MAC into.
* @param [in] outSz Size of ouput MAC. 8 or 16 only.
* @return BAD_FUNC_ARG when sipHash or out is NULL.
* @return BAD_FUNC_ARG when outSz is not the same as initialized value.
* @return 0 on success.
*/
int wc_SipHashFinal(SipHash* sipHash, unsigned char* out, unsigned char outSz)
{
int ret = 0;
/* Validate parameters. */
if ((sipHash == NULL) || (out == NULL) || (outSz != sipHash->outSz)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
/* Put int remaining cached message bytes. */
XMEMSET(sipHash->cache + sipHash->cacheCnt, 0, 7 - sipHash->cacheCnt);
sipHash->cache[7] = (byte)(sipHash->inCnt + sipHash->cacheCnt);
SipHashCompress(sipHash, sipHash->cache);
sipHash->cacheCnt = 0;
/* Output either 8 or 16 bytes. */
if (outSz == SIPHASH_MAC_SIZE_8) {
sipHash->v[2] ^= (word64)0xff;
SipHashOut(sipHash, out);
}
else {
sipHash->v[2] ^= (word64)0xee;
SipHashOut(sipHash, out);
sipHash->v[1] ^= (word64)0xdd;
SipHashOut(sipHash, out + 8);
}
}
return ret;
}
#if defined(__GNUC__) && defined(__x86_64__) && \
(WOLFSSL_SIPHASH_CROUNDS == 1 || WOLFSSL_SIPHASH_CROUNDS == 2) && \
(WOLFSSL_SIPHASH_DROUNDS == 2 || WOLFSSL_SIPHASH_DROUNDS == 4)
#define SIPHASH_ROUND(v0, v1, v2, v3) \
"addq " #v1 ", " #v0 "\n\t" \
"addq " #v3 ", " #v2 "\n\t" \
"rolq $13, " #v1 "\n\t" \
"rolq $16, " #v3 "\n\t" \
"xorq " #v0 ", " #v1 "\n\t" \
"xorq " #v2 ", " #v3 "\n\t" \
"rolq $32, " #v0 "\n\t" \
"addq " #v1 ", " #v2 "\n\t" \
"addq " #v3 ", " #v0 "\n\t" \
"rolq $17, " #v1 "\n\t" \
"rolq $21, " #v3 "\n\t" \
"xorq " #v2 ", " #v1 "\n\t" \
"xorq " #v0 ", " #v3 "\n\t" \
"rolq $32, " #v2 "\n\t"
#define SIPHASH_LAST_ROUND(v0, v1, v2, v3) \
"addq " #v1 ", " #v0 "\n\t" \
"addq " #v3 ", " #v2 "\n\t" \
"rolq $13, " #v1 "\n\t" \
"rolq $16, " #v3 "\n\t" \
"xorq " #v0 ", " #v1 "\n\t" \
"xorq " #v2 ", " #v3 "\n\t" \
"addq " #v1 ", " #v2 "\n\t" \
"rolq $17, " #v1 "\n\t" \
"rolq $21, " #v3 "\n\t" \
"xorq " #v2 ", " #v1 "\n\t" \
"rolq $32, " #v2 "\n\t"
/**
* Perform SipHash operation on input with key.
*
* @param [in] key 16 byte array - little endian.
* @param [in] in Input message.
* @param [in] inSz Size of input message.
* @param [out] out Buffer to place MAC into.
* @param [in] outSz Size of ouput MAC. 8 or 16 only.
* @return BAD_FUNC_ARG when key or out is NULL.
* @return BAD_FUNC_ARG when in is NULL and inSz is not zero.
* @return BAD_FUNC_ARG when outSz is neither 8 nor 16.
* @return 0 on success.
*/
int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz,
unsigned char* out, unsigned char outSz)
{
if ((key == NULL) || ((in == NULL) && (inSz != 0)) || (out == NULL) ||
((outSz != SIPHASH_MAC_SIZE_8) && (outSz != SIPHASH_MAC_SIZE_16))) {
return BAD_FUNC_ARG;
}
/* v0=%r8, v1=%r9, v2=%r10, v3=%r11 */
__asm__ __volatile__ (
"movq (%[key]), %%r12\n\t"
"movq 8(%[key]), %%r13\n\t"
"movabsq $0x736f6d6570736575, %%r8\n\t"
"movabsq $0x646f72616e646f6d, %%r9\n\t"
"movabsq $0x6c7967656e657261, %%r10\n\t"
"movabsq $0x7465646279746573, %%r11\n\t"
"xorq %%r12, %%r8\n\t"
"xorq %%r13, %%r9\n\t"
"xorq %%r12, %%r10\n\t"
"xorq %%r13, %%r11\n\t"
"cmp $8, %[outSz]\n\t"
"mov %[inSz], %%r13d\n\t"
"je L_siphash_8_top\n\t"
"xorq $0xee, %%r9\n\t"
"L_siphash_8_top:\n\t"
"sub $8, %[inSz]\n\t"
"jb L_siphash_done_input_8\n\t"
"L_siphash_input:\n\t"
"movq (%[in]), %%r12\n\t"
"addq $8, %[in]\n\t"
"xorq %%r12, %%r11\n\t"
#if WOLFSSL_SIPHASH_CROUNDS == 1
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#elif WOLFSSL_SIPHASH_CROUNDS == 2
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#endif
"xorq %%r12, %%r8\n\t"
"sub $8, %[inSz]\n\t"
"jge L_siphash_input\n\t"
"L_siphash_done_input_8:\n\t"
"add $8, %[inSz]\n\t"
"shlq $56, %%r13\n\t"
"cmp $0, %[inSz]\n\t"
"je L_siphash_last_done\n\t"
"cmp $4, %[inSz]\n\t"
"jl L_siphash_last_lt4\n\t"
"cmp $7, %[inSz]\n\t"
"jl L_siphash_n7\n\t"
"movzxb 6(%[in]), %%r12\n\t"
"shlq $48, %%r12\n\t"
"orq %%r12, %%r13\n\t"
"L_siphash_n7:\n\t"
"cmp $6, %[inSz]\n\t"
"jl L_siphash_n6\n\t"
"movzxb 5(%[in]), %%r12\n\t"
"shlq $40, %%r12\n\t"
"orq %%r12, %%r13\n\t"
"L_siphash_n6:\n\t"
"cmp $5, %[inSz]\n\t"
"jl L_siphash_n5\n\t"
"movzxb 4(%[in]), %%r12\n\t"
"shlq $32, %%r12\n\t"
"orq %%r12, %%r13\n\t"
"L_siphash_n5:\n\t"
"mov (%[in]), %%r12d\n\t"
"orq %%r12, %%r13\n\t"
"jmp L_siphash_last_done\n\t"
"L_siphash_last_lt4:\n\t"
"cmp $1, %[inSz]\n\t"
"je L_siphash_last_1\n\t"
"cmp $3, %[inSz]\n\t"
"jl L_siphash_n3\n\t"
"movzxb 2(%[in]), %%r12\n\t"
"shlq $16, %%r12\n\t"
"orq %%r12, %%r13\n\t"
"L_siphash_n3:\n\t"
"movw (%[in]), %%r12w\n\t"
"or %%r12w, %%r13w\n\t"
"jmp L_siphash_last_done\n\t"
"L_siphash_last_1:\n\t"
"movb (%[in]), %%r12b\n\t"
"or %%r12b, %%r13b\n\t"
"L_siphash_last_done:\n\t"
"xorq %%r13, %%r11\n\t"
#if WOLFSSL_SIPHASH_CROUNDS == 1
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#elif WOLFSSL_SIPHASH_CROUNDS == 2
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#endif
"xorq %%r13, %%r8\n\t"
"cmp $8, %[outSz]\n\t"
"je L_siphash_8_end\n\t"
"xor $0xee, %%r10b\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
#endif
"movq %%r8, %%r12\n\t"
"xorq %%r9, %%r12\n\t"
"xorq %%r10, %%r12\n\t"
"xorq %%r11, %%r12\n\t"
"movq %%r12, (%[out])\n\t"
"xor $0xdd, %%r9b\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_LAST_ROUND(%%r8, %%r9, %%r10, %%r11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_LAST_ROUND(%%r8, %%r9, %%r10, %%r11)
#endif
"xorq %%r11, %%r9\n\t"
"xorq %%r10, %%r9\n\t"
"movq %%r9, 8(%[out])\n\t"
"jmp L_siphash_done\n\t"
"L_siphash_8_end:\n\t"
"xor $0xff, %%r10b\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_LAST_ROUND(%%r8, %%r9, %%r10, %%r11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_ROUND(%%r8, %%r9, %%r10, %%r11)
SIPHASH_LAST_ROUND(%%r8, %%r9, %%r10, %%r11)
#endif
"xorq %%r11, %%r9\n\t"
"xorq %%r10, %%r9\n\t"
"movq %%r9, (%[out])\n\t"
"L_siphash_done:\n\t"
: [in] "+r" (in), [inSz] "+r" (inSz)
: [key] "r" (key), [out] "r" (out) , [outSz] "r" (outSz)
: "memory", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13"
);
return 0;
}
#elif defined(__GNUC__) && defined(__aarch64__) && \
(WOLFSSL_SIPHASH_CROUNDS == 1 || WOLFSSL_SIPHASH_CROUNDS == 2) && \
(WOLFSSL_SIPHASH_DROUNDS == 2 || WOLFSSL_SIPHASH_DROUNDS == 4)
#define SIPHASH_ROUND(v0, v1, v2, v3) \
"add " #v0 ", " #v0 ", " #v1 "\n\t" \
"add " #v2 ", " #v2 ", " #v3 "\n\t" \
"ror " #v1 ", " #v1 ", #51\n\t" \
"ror " #v3 ", " #v3 ", #48\n\t" \
"eor " #v1 ", " #v1 ", " #v0 "\n\t" \
"eor " #v3 ", " #v3 ", " #v2 "\n\t" \
"ror " #v0 ", " #v0 ", #32\n\t" \
"add " #v2 ", " #v2 ", " #v1 "\n\t" \
"add " #v0 ", " #v0 ", " #v3 "\n\t" \
"ror " #v1 ", " #v1 ", #47\n\t" \
"ror " #v3 ", " #v3 ", #43\n\t" \
"eor " #v1 ", " #v1 ", " #v2 "\n\t" \
"eor " #v3 ", " #v3 ", " #v0 "\n\t" \
"ror " #v2 ", " #v2 ", #32\n\t"
#define SIPHASH_LAST_ROUND(v0, v1, v2, v3) \
"add " #v0 ", " #v0 ", " #v1 "\n\t" \
"add " #v2 ", " #v2 ", " #v3 "\n\t" \
"ror " #v1 ", " #v1 ", #51\n\t" \
"ror " #v3 ", " #v3 ", #48\n\t" \
"eor " #v1 ", " #v1 ", " #v0 "\n\t" \
"eor " #v3 ", " #v3 ", " #v2 "\n\t" \
"add " #v2 ", " #v2 ", " #v1 "\n\t" \
"ror " #v1 ", " #v1 ", #47\n\t" \
"ror " #v3 ", " #v3 ", #43\n\t" \
"eor " #v1 ", " #v1 ", " #v2 "\n\t" \
"ror " #v2 ", " #v2 ", #32\n\t"
/**
* Perform SipHash operation on input with key.
*
* @param [in] key 16 byte array - little endian.
* @param [in] in Input message.
* @param [in] inSz Size of input message.
* @param [out] out Buffer to place MAC into.
* @param [in] outSz Size of ouput MAC. 8 or 16 only.
* @return BAD_FUNC_ARG when key or out is NULL.
* @return BAD_FUNC_ARG when in is NULL and inSz is not zero.
* @return BAD_FUNC_ARG when outSz is not 8 nor 16.
* @return 0 on success.
*/
int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz,
unsigned char* out, unsigned char outSz)
{
if ((key == NULL) || ((in == NULL) && (inSz != 0)) || (out == NULL) ||
((outSz != SIPHASH_MAC_SIZE_8) && (outSz != SIPHASH_MAC_SIZE_16))) {
return BAD_FUNC_ARG;
}
/* v0=x8, v1=x9, v2=x10, v3=x11 */
__asm__ __volatile__ (
"ldp x12, x13, [%[key]]\n\t"
"mov x8, #0x6575\n\t"
"movk x8, #0x7073, lsl #16\n\t"
"movk x8, #0x6d65, lsl #32\n\t"
"movk x8, #0x736f, lsl #48\n\t"
"mov x9, #0x6f6d\n\t"
"movk x9, #0x6e64, lsl #16\n\t"
"movk x9, #0x7261, lsl #32\n\t"
"movk x9, #0x646f, lsl #48\n\t"
"mov x10, #0x7261\n\t"
"movk x10, #0x6e65, lsl #16\n\t"
"movk x10, #0x6765, lsl #32\n\t"
"movk x10, #0x6c79, lsl #48\n\t"
"mov x11, #0x6573\n\t"
"movk x11, #0x7974, lsl #16\n\t"
"movk x11, #0x6462, lsl #32\n\t"
"movk x11, #0x7465, lsl #48\n\t"
"eor x8, x8, x12\n\t"
"eor x9, x9, x13\n\t"
"eor x10, x10, x12\n\t"
"eor x11, x11, x13\n\t"
"mov w13, %w[inSz]\n\t"
"cmp %w[outSz], #8\n\t"
"b.eq L_siphash_8_top\n\t"
"mov w12, #0xee\n\t"
"eor x9, x9, x12\n\t"
"L_siphash_8_top:\n\t"
"subs %w[inSz], %w[inSz], #8\n\t"
"b.mi L_siphash_done_input_8\n\t"
"L_siphash_input:\n\t"
"ldr x12, [%[in]], #8\n\t"
"eor x11, x11, x12\n\t"
#if WOLFSSL_SIPHASH_CROUNDS == 1
SIPHASH_ROUND(x8, x9, x10, x11)
#elif WOLFSSL_SIPHASH_CROUNDS == 2
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
#endif
"eor x8, x8, x12\n\t"
"subs %w[inSz], %w[inSz], #8\n\t"
"b.ge L_siphash_input\n\t"
"L_siphash_done_input_8:\n\t"
"add %w[inSz], %w[inSz], #8\n\t"
"lsl x13, x13, #56\n\t"
"cmp %w[inSz], #0\n\t"
"b.eq L_siphash_last_done\n\t"
"cmp %w[inSz], #4\n\t"
"b.lt L_siphash_last_lt4\n\t"
"cmp %w[inSz], #7\n\t"
"b.lt L_siphash_n7\n\t"
"ldrb w12, [%[in], 6]\n\t"
"orr x13, x13, x12, lsl 48\n\t"
"L_siphash_n7:\n\t"
"cmp %w[inSz], #6\n\t"
"b.lt L_siphash_n6\n\t"
"ldrb w12, [%[in], 5]\n\t"
"orr x13, x13, x12, lsl 40\n\t"
"L_siphash_n6:\n\t"
"cmp %w[inSz], #5\n\t"
"b.lt L_siphash_n5\n\t"
"ldrb w12, [%[in], 4]\n\t"
"orr x13, x13, x12, lsl 32\n\t"
"L_siphash_n5:\n\t"
"ldr w12, [%[in]]\n\t"
"orr x13, x13, x12\n\t"
"b L_siphash_last_done\n\t"
"L_siphash_last_lt4:\n\t"
"cmp %w[inSz], #1\n\t"
"b.eq L_siphash_last_1\n\t"
"cmp %w[inSz], #3\n\t"
"b.lt L_siphash_n3\n\t"
"ldrb w12, [%[in], 2]\n\t"
"orr x13, x13, x12, lsl 16\n\t"
"L_siphash_n3:\n\t"
"ldrh w12, [%[in]]\n\t"
"orr x13, x13, x12\n\t"
"b L_siphash_last_done\n\t"
"L_siphash_last_1:\n\t"
"ldrb w12, [%[in]]\n\t"
"orr x13, x13, x12\n\t"
"L_siphash_last_done:\n\t"
"eor x11, x11, x13\n\t"
#if WOLFSSL_SIPHASH_CROUNDS == 1
SIPHASH_ROUND(x8, x9, x10, x11)
#elif WOLFSSL_SIPHASH_CROUNDS == 2
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
#endif
"eor x8, x8, x13\n\t"
"cmp %w[outSz], #8\n\t"
"b.eq L_siphash_8_end\n\t"
"mov w13, #0xee\n\t"
"eor x10, x10, x13\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
#endif
"eor x12, x8, x9\n\t"
"eor x13, x10, x11\n\t"
"eor x12, x12, x13\n\t"
"mov w13, #0xdd\n\t"
"eor x9, x9, x13\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_LAST_ROUND(x8, x9, x10, x11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_LAST_ROUND(x8, x9, x10, x11)
#endif
"eor x13, x11, x9\n\t"
"eor x13, x13, x10\n\t"
"stp x12, x13, [%[out]]\n\t"
"b L_siphash_done\n\t"
"L_siphash_8_end:\n\t"
"mov w13, #0xff\n\t"
"eor x10, x10, x13\n\t"
#if WOLFSSL_SIPHASH_DROUNDS == 2
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_LAST_ROUND(x8, x9, x10, x11)
#elif WOLFSSL_SIPHASH_DROUNDS == 4
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_ROUND(x8, x9, x10, x11)
SIPHASH_LAST_ROUND(x8, x9, x10, x11)
#endif
"eor x13, x11, x9\n\t"
"eor x13, x13, x10\n\t"
"str x13, [%[out]]\n\t"
"L_siphash_done:\n\t"
: [in] "+r" (in), [inSz] "+r" (inSz)
: [key] "r" (key), [out] "r" (out) , [outSz] "r" (outSz)
: "memory", "x8", "x9", "x10", "x11", "x12", "x13"
);
return 0;
}
#else
#define SipRoundV(v0, v1, v2, v3) \
v0 += v1; \
v2 += v3; \
v1 = rotlFixed64(v1, 13); \
v3 = rotlFixed64(v3, 16); \
v1 ^= v0; \
v3 ^= v2; \
v0 = rotlFixed64(v0, 32); \
v2 += v1; \
v0 += v3; \
v1 = rotlFixed64(v1, 17); \
v3 = rotlFixed64(v3, 21); \
v1 ^= v2; \
v3 ^= v0; \
v2 = rotlFixed64(v2, 32);
#define SipHashCompressV(v0, v1, v2, v3, m) \
do { \
int i; \
v3 ^= m; \
for (i = 0; i < WOLFSSL_SIPHASH_CROUNDS; i++) { \
SipRoundV(v0, v1, v2, v3); \
} \
v0 ^= m; \
} \
while (0)
#define SipHashOutV(v0, v1, v2, v3, out) \
do { \
word64 n; \
int i; \
\
for (i = 0; i < WOLFSSL_SIPHASH_DROUNDS; i++) { \
SipRoundV(v0, v1, v2, v3); \
} \
n = v0 ^ v1 ^ v2 ^ v3; \
SET_U64(out, n); \
} \
while (0)
/**
* Perform SipHash operation on input with key.
*
* @param [in] key 16 byte array - little endian.
* @param [in] in Input message.
* @param [in] inSz Size of input message.
* @param [out] out Buffer to place MAC into.
* @param [in] outSz Size of ouput MAC. 8 or 16 only.
* @return BAD_FUNC_ARG when key or out is NULL.
* @return BAD_FUNC_ARG when in is NULL and inSz is not zero.
* @return BAD_FUNC_ARG when outSz is not 8 nor 16.
* @return 0 on success.
*/
int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz,
unsigned char* out, unsigned char outSz)
{
int ret = 0;
if ((key == NULL) || ((in == NULL) && (inSz != 0)) || (out == NULL) ||
((outSz != SIPHASH_MAC_SIZE_8) && (outSz != SIPHASH_MAC_SIZE_16))) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
word64 v0, v1, v2, v3;
word64 k0 = GET_U64(key + 0);
word64 k1 = GET_U64(key + 8);
word64 b = (word64)((word64)inSz << 56);
/* Initialize state with key. */
v0 = 0x736f6d6570736575UL;
v1 = 0x646f72616e646f6dUL;
v2 = 0x6c7967656e657261UL;
v3 = 0x7465646279746573UL;
if (outSz == SIPHASH_MAC_SIZE_16) {
v1 ^= 0xee;
}
v0 ^= k0;
v1 ^= k1;
v2 ^= k0;
v3 ^= k1;
/* Process blocks from message. */
while (inSz >= SIPHASH_BLOCK_SIZE) {
word64 m = GET_U64(in);
/* Compress the next block from the message data. */
SipHashCompressV(v0, v1, v2, v3, m);
in += SIPHASH_BLOCK_SIZE;
inSz -= SIPHASH_BLOCK_SIZE;
}
switch (inSz) {
case 7:
b |= (word64)in[6] << 48;
/* fall-through */
case 6:
b |= (word64)in[5] << 40;
/* fall-through */
case 5:
b |= (word64)in[4] << 32;
/* fall-through */
case 4:
b |= (word64)GET_U32(in);
break;
case 3:
b |= (word64)in[2] << 16;
/* fall-through */
case 2:
b |= (word64)GET_U16(in);
break;
case 1:
b |= (word64)in[0];
break;
case 0:
break;
}
SipHashCompressV(v0, v1, v2, v3, b);
/* Output either 8 or 16 bytes. */
if (outSz == SIPHASH_MAC_SIZE_8) {
v2 ^= (word64)0xff;
SipHashOutV(v0, v1, v2, v3, out);
}
else {
v2 ^= (word64)0xee;
SipHashOutV(v0, v1, v2, v3, out);
v1 ^= (word64)0xdd;
SipHashOutV(v0, v1, v2, v3, out + 8);
}
}
return ret;
}
#endif /* !ASM */
#endif /* WOLFSSL_SIPHASH */

View File

@ -235,6 +235,7 @@ _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/wc_encrypt.h>
#include <wolfssl/wolfcrypt/cmac.h>
#include <wolfssl/wolfcrypt/siphash.h>
#include <wolfssl/wolfcrypt/poly1305.h>
#include <wolfssl/wolfcrypt/camellia.h>
#include <wolfssl/wolfcrypt/hmac.h>
@ -426,6 +427,9 @@ WOLFSSL_TEST_SUBROUTINE int aes192_test(void);
WOLFSSL_TEST_SUBROUTINE int aes256_test(void);
WOLFSSL_TEST_SUBROUTINE int aesofb_test(void);
WOLFSSL_TEST_SUBROUTINE int cmac_test(void);
#if defined(WOLFSSL_SIPHASH)
WOLFSSL_TEST_SUBROUTINE int siphash_test(void);
#endif
WOLFSSL_TEST_SUBROUTINE int poly1305_test(void);
WOLFSSL_TEST_SUBROUTINE int aesgcm_test(void);
WOLFSSL_TEST_SUBROUTINE int aesgcm_default_test(void);
@ -1330,6 +1334,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
TEST_PASS("CMAC test passed!\n");
#endif
#if defined(WOLFSSL_SIPHASH)
if ( (ret = siphash_test()) != 0)
return err_sys("SipHash test failed!\n", ret);
else
TEST_PASS("SipHash test passed!\n");
#endif
#ifdef HAVE_LIBZ
if ( (ret = compress_test()) != 0)
return err_sys("COMPRESS test failed!\n", ret);
@ -30334,6 +30345,326 @@ WOLFSSL_TEST_SUBROUTINE int cmac_test(void)
#endif /* NO_AES && WOLFSSL_CMAC */
#if defined(WOLFSSL_SIPHASH)
#if WOLFSSL_SIPHASH_CROUNDS == 2 && WOLFSSL_SIPHASH_DROUNDS == 4
/* Test vectors from:
* https://github.com/veorq/SipHash/blob/master/vectors.h
*/
static const unsigned char siphash_key[SIPHASH_KEY_SIZE] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static const unsigned char siphash_msg[64] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
};
static const unsigned char siphash_r8[64][SIPHASH_MAC_SIZE_8] = {
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, },
};
static const unsigned char siphash_r16[64][SIPHASH_MAC_SIZE_16] = {
{ 0xa3, 0x81, 0x7f, 0x04, 0xba, 0x25, 0xa8, 0xe6,
0x6d, 0xf6, 0x72, 0x14, 0xc7, 0x55, 0x02, 0x93, },
{ 0xda, 0x87, 0xc1, 0xd8, 0x6b, 0x99, 0xaf, 0x44,
0x34, 0x76, 0x59, 0x11, 0x9b, 0x22, 0xfc, 0x45, },
{ 0x81, 0x77, 0x22, 0x8d, 0xa4, 0xa4, 0x5d, 0xc7,
0xfc, 0xa3, 0x8b, 0xde, 0xf6, 0x0a, 0xff, 0xe4, },
{ 0x9c, 0x70, 0xb6, 0x0c, 0x52, 0x67, 0xa9, 0x4e,
0x5f, 0x33, 0xb6, 0xb0, 0x29, 0x85, 0xed, 0x51, },
{ 0xf8, 0x81, 0x64, 0xc1, 0x2d, 0x9c, 0x8f, 0xaf,
0x7d, 0x0f, 0x6e, 0x7c, 0x7b, 0xcd, 0x55, 0x79, },
{ 0x13, 0x68, 0x87, 0x59, 0x80, 0x77, 0x6f, 0x88,
0x54, 0x52, 0x7a, 0x07, 0x69, 0x0e, 0x96, 0x27, },
{ 0x14, 0xee, 0xca, 0x33, 0x8b, 0x20, 0x86, 0x13,
0x48, 0x5e, 0xa0, 0x30, 0x8f, 0xd7, 0xa1, 0x5e, },
{ 0xa1, 0xf1, 0xeb, 0xbe, 0xd8, 0xdb, 0xc1, 0x53,
0xc0, 0xb8, 0x4a, 0xa6, 0x1f, 0xf0, 0x82, 0x39, },
{ 0x3b, 0x62, 0xa9, 0xba, 0x62, 0x58, 0xf5, 0x61,
0x0f, 0x83, 0xe2, 0x64, 0xf3, 0x14, 0x97, 0xb4, },
{ 0x26, 0x44, 0x99, 0x06, 0x0a, 0xd9, 0xba, 0xab,
0xc4, 0x7f, 0x8b, 0x02, 0xbb, 0x6d, 0x71, 0xed, },
{ 0x00, 0x11, 0x0d, 0xc3, 0x78, 0x14, 0x69, 0x56,
0xc9, 0x54, 0x47, 0xd3, 0xf3, 0xd0, 0xfb, 0xba, },
{ 0x01, 0x51, 0xc5, 0x68, 0x38, 0x6b, 0x66, 0x77,
0xa2, 0xb4, 0xdc, 0x6f, 0x81, 0xe5, 0xdc, 0x18, },
{ 0xd6, 0x26, 0xb2, 0x66, 0x90, 0x5e, 0xf3, 0x58,
0x82, 0x63, 0x4d, 0xf6, 0x85, 0x32, 0xc1, 0x25, },
{ 0x98, 0x69, 0xe2, 0x47, 0xe9, 0xc0, 0x8b, 0x10,
0xd0, 0x29, 0x93, 0x4f, 0xc4, 0xb9, 0x52, 0xf7, },
{ 0x31, 0xfc, 0xef, 0xac, 0x66, 0xd7, 0xde, 0x9c,
0x7e, 0xc7, 0x48, 0x5f, 0xe4, 0x49, 0x49, 0x02, },
{ 0x54, 0x93, 0xe9, 0x99, 0x33, 0xb0, 0xa8, 0x11,
0x7e, 0x08, 0xec, 0x0f, 0x97, 0xcf, 0xc3, 0xd9, },
{ 0x6e, 0xe2, 0xa4, 0xca, 0x67, 0xb0, 0x54, 0xbb,
0xfd, 0x33, 0x15, 0xbf, 0x85, 0x23, 0x05, 0x77, },
{ 0x47, 0x3d, 0x06, 0xe8, 0x73, 0x8d, 0xb8, 0x98,
0x54, 0xc0, 0x66, 0xc4, 0x7a, 0xe4, 0x77, 0x40, },
{ 0xa4, 0x26, 0xe5, 0xe4, 0x23, 0xbf, 0x48, 0x85,
0x29, 0x4d, 0xa4, 0x81, 0xfe, 0xae, 0xf7, 0x23, },
{ 0x78, 0x01, 0x77, 0x31, 0xcf, 0x65, 0xfa, 0xb0,
0x74, 0xd5, 0x20, 0x89, 0x52, 0x51, 0x2e, 0xb1, },
{ 0x9e, 0x25, 0xfc, 0x83, 0x3f, 0x22, 0x90, 0x73,
0x3e, 0x93, 0x44, 0xa5, 0xe8, 0x38, 0x39, 0xeb, },
{ 0x56, 0x8e, 0x49, 0x5a, 0xbe, 0x52, 0x5a, 0x21,
0x8a, 0x22, 0x14, 0xcd, 0x3e, 0x07, 0x1d, 0x12, },
{ 0x4a, 0x29, 0xb5, 0x45, 0x52, 0xd1, 0x6b, 0x9a,
0x46, 0x9c, 0x10, 0x52, 0x8e, 0xff, 0x0a, 0xae, },
{ 0xc9, 0xd1, 0x84, 0xdd, 0xd5, 0xa9, 0xf5, 0xe0,
0xcf, 0x8c, 0xe2, 0x9a, 0x9a, 0xbf, 0x69, 0x1c, },
{ 0x2d, 0xb4, 0x79, 0xae, 0x78, 0xbd, 0x50, 0xd8,
0x88, 0x2a, 0x8a, 0x17, 0x8a, 0x61, 0x32, 0xad, },
{ 0x8e, 0xce, 0x5f, 0x04, 0x2d, 0x5e, 0x44, 0x7b,
0x50, 0x51, 0xb9, 0xea, 0xcb, 0x8d, 0x8f, 0x6f, },
{ 0x9c, 0x0b, 0x53, 0xb4, 0xb3, 0xc3, 0x07, 0xe8,
0x7e, 0xae, 0xe0, 0x86, 0x78, 0x14, 0x1f, 0x66, },
{ 0xab, 0xf2, 0x48, 0xaf, 0x69, 0xa6, 0xea, 0xe4,
0xbf, 0xd3, 0xeb, 0x2f, 0x12, 0x9e, 0xeb, 0x94, },
{ 0x06, 0x64, 0xda, 0x16, 0x68, 0x57, 0x4b, 0x88,
0xb9, 0x35, 0xf3, 0x02, 0x73, 0x58, 0xae, 0xf4, },
{ 0xaa, 0x4b, 0x9d, 0xc4, 0xbf, 0x33, 0x7d, 0xe9,
0x0c, 0xd4, 0xfd, 0x3c, 0x46, 0x7c, 0x6a, 0xb7, },
{ 0xea, 0x5c, 0x7f, 0x47, 0x1f, 0xaf, 0x6b, 0xde,
0x2b, 0x1a, 0xd7, 0xd4, 0x68, 0x6d, 0x22, 0x87, },
{ 0x29, 0x39, 0xb0, 0x18, 0x32, 0x23, 0xfa, 0xfc,
0x17, 0x23, 0xde, 0x4f, 0x52, 0xc4, 0x3d, 0x35, },
{ 0x7c, 0x39, 0x56, 0xca, 0x5e, 0xea, 0xfc, 0x3e,
0x36, 0x3e, 0x9d, 0x55, 0x65, 0x46, 0xeb, 0x68, },
{ 0x77, 0xc6, 0x07, 0x71, 0x46, 0xf0, 0x1c, 0x32,
0xb6, 0xb6, 0x9d, 0x5f, 0x4e, 0xa9, 0xff, 0xcf, },
{ 0x37, 0xa6, 0x98, 0x6c, 0xb8, 0x84, 0x7e, 0xdf,
0x09, 0x25, 0xf0, 0xf1, 0x30, 0x9b, 0x54, 0xde, },
{ 0xa7, 0x05, 0xf0, 0xe6, 0x9d, 0xa9, 0xa8, 0xf9,
0x07, 0x24, 0x1a, 0x2e, 0x92, 0x3c, 0x8c, 0xc8, },
{ 0x3d, 0xc4, 0x7d, 0x1f, 0x29, 0xc4, 0x48, 0x46,
0x1e, 0x9e, 0x76, 0xed, 0x90, 0x4f, 0x67, 0x11, },
{ 0x0d, 0x62, 0xbf, 0x01, 0xe6, 0xfc, 0x0e, 0x1a,
0x0d, 0x3c, 0x47, 0x51, 0xc5, 0xd3, 0x69, 0x2b, },
{ 0x8c, 0x03, 0x46, 0x8b, 0xca, 0x7c, 0x66, 0x9e,
0xe4, 0xfd, 0x5e, 0x08, 0x4b, 0xbe, 0xe7, 0xb5, },
{ 0x52, 0x8a, 0x5b, 0xb9, 0x3b, 0xaf, 0x2c, 0x9c,
0x44, 0x73, 0xcc, 0xe5, 0xd0, 0xd2, 0x2b, 0xd9, },
{ 0xdf, 0x6a, 0x30, 0x1e, 0x95, 0xc9, 0x5d, 0xad,
0x97, 0xae, 0x0c, 0xc8, 0xc6, 0x91, 0x3b, 0xd8, },
{ 0x80, 0x11, 0x89, 0x90, 0x2c, 0x85, 0x7f, 0x39,
0xe7, 0x35, 0x91, 0x28, 0x5e, 0x70, 0xb6, 0xdb, },
{ 0xe6, 0x17, 0x34, 0x6a, 0xc9, 0xc2, 0x31, 0xbb,
0x36, 0x50, 0xae, 0x34, 0xcc, 0xca, 0x0c, 0x5b, },
{ 0x27, 0xd9, 0x34, 0x37, 0xef, 0xb7, 0x21, 0xaa,
0x40, 0x18, 0x21, 0xdc, 0xec, 0x5a, 0xdf, 0x89, },
{ 0x89, 0x23, 0x7d, 0x9d, 0xed, 0x9c, 0x5e, 0x78,
0xd8, 0xb1, 0xc9, 0xb1, 0x66, 0xcc, 0x73, 0x42, },
{ 0x4a, 0x6d, 0x80, 0x91, 0xbf, 0x5e, 0x7d, 0x65,
0x11, 0x89, 0xfa, 0x94, 0xa2, 0x50, 0xb1, 0x4c, },
{ 0x0e, 0x33, 0xf9, 0x60, 0x55, 0xe7, 0xae, 0x89,
0x3f, 0xfc, 0x0e, 0x3d, 0xcf, 0x49, 0x29, 0x02, },
{ 0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1,
0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, 0x1b, },
{ 0xf7, 0xe5, 0xae, 0xf5, 0x49, 0xf7, 0x82, 0xcf,
0x37, 0x90, 0x55, 0xa6, 0x08, 0x26, 0x9b, 0x16, },
{ 0x43, 0x8d, 0x03, 0x0f, 0xd0, 0xb7, 0xa5, 0x4f,
0xa8, 0x37, 0xf2, 0xad, 0x20, 0x1a, 0x64, 0x03, },
{ 0xa5, 0x90, 0xd3, 0xee, 0x4f, 0xbf, 0x04, 0xe3,
0x24, 0x7e, 0x0d, 0x27, 0xf2, 0x86, 0x42, 0x3f, },
{ 0x5f, 0xe2, 0xc1, 0xa1, 0x72, 0xfe, 0x93, 0xc4,
0xb1, 0x5c, 0xd3, 0x7c, 0xae, 0xf9, 0xf5, 0x38, },
{ 0x2c, 0x97, 0x32, 0x5c, 0xbd, 0x06, 0xb3, 0x6e,
0xb2, 0x13, 0x3d, 0xd0, 0x8b, 0x3a, 0x01, 0x7c, },
{ 0x92, 0xc8, 0x14, 0x22, 0x7a, 0x6b, 0xca, 0x94,
0x9f, 0xf0, 0x65, 0x9f, 0x00, 0x2a, 0xd3, 0x9e, },
{ 0xdc, 0xe8, 0x50, 0x11, 0x0b, 0xd8, 0x32, 0x8c,
0xfb, 0xd5, 0x08, 0x41, 0xd6, 0x91, 0x1d, 0x87, },
{ 0x67, 0xf1, 0x49, 0x84, 0xc7, 0xda, 0x79, 0x12,
0x48, 0xe3, 0x2b, 0xb5, 0x92, 0x25, 0x83, 0xda, },
{ 0x19, 0x38, 0xf2, 0xcf, 0x72, 0xd5, 0x4e, 0xe9,
0x7e, 0x94, 0x16, 0x6f, 0xa9, 0x1d, 0x2a, 0x36, },
{ 0x74, 0x48, 0x1e, 0x96, 0x46, 0xed, 0x49, 0xfe,
0x0f, 0x62, 0x24, 0x30, 0x16, 0x04, 0x69, 0x8e, },
{ 0x57, 0xfc, 0xa5, 0xde, 0x98, 0xa9, 0xd6, 0xd8,
0x00, 0x64, 0x38, 0xd0, 0x58, 0x3d, 0x8a, 0x1d, },
{ 0x9f, 0xec, 0xde, 0x1c, 0xef, 0xdc, 0x1c, 0xbe,
0xd4, 0x76, 0x36, 0x74, 0xd9, 0x57, 0x53, 0x59, },
{ 0xe3, 0x04, 0x0c, 0x00, 0xeb, 0x28, 0xf1, 0x53,
0x66, 0xca, 0x73, 0xcb, 0xd8, 0x72, 0xe7, 0x40, },
{ 0x76, 0x97, 0x00, 0x9a, 0x6a, 0x83, 0x1d, 0xfe,
0xcc, 0xa9, 0x1c, 0x59, 0x93, 0x67, 0x0f, 0x7a, },
{ 0x58, 0x53, 0x54, 0x23, 0x21, 0xf5, 0x67, 0xa0,
0x05, 0xd5, 0x47, 0xa4, 0xf0, 0x47, 0x59, 0xbd, },
{ 0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a,
0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, 0x7c, },
};
#endif
WOLFSSL_TEST_SUBROUTINE int siphash_test(void)
{
int ret = 0;
int i;
#if WOLFSSL_SIPHASH_CROUNDS == 2 && WOLFSSL_SIPHASH_DROUNDS == 4
unsigned char res[SIPHASH_MAC_SIZE_16];
SipHash siphash;
for (i = 0; i < 64; i++) {
ret = wc_InitSipHash(&siphash, siphash_key, SIPHASH_MAC_SIZE_8);
if (ret != 0)
return -12100 - i;
ret = wc_SipHashUpdate(&siphash, siphash_msg, i);
if (ret != 0)
return -12200 - i;
ret = wc_SipHashFinal(&siphash, res, SIPHASH_MAC_SIZE_8);
if (ret != 0)
return -12300 - i;
if (XMEMCMP(res, siphash_r8[i], SIPHASH_MAC_SIZE_8) != 0)
return -12400 - i;
ret = wc_SipHash(siphash_key, siphash_msg, i, res, SIPHASH_MAC_SIZE_8);
if (ret != 0)
return -12500 - i;
if (XMEMCMP(res, siphash_r8[i], SIPHASH_MAC_SIZE_8) != 0)
return -12600 - i;
}
for (i = 0; i < 64; i++) {
ret = wc_InitSipHash(&siphash, siphash_key, SIPHASH_MAC_SIZE_16);
if (ret != 0)
return -12700 - i;
ret = wc_SipHashUpdate(&siphash, siphash_msg, i);
if (ret != 0)
return -12800 - i;
ret = wc_SipHashFinal(&siphash, res, SIPHASH_MAC_SIZE_16);
if (ret != 0)
return -12900 - i;
if (XMEMCMP(res, siphash_r16[i], SIPHASH_MAC_SIZE_16) != 0)
return -13000 - i;
ret = wc_SipHash(siphash_key, siphash_msg, i, res, SIPHASH_MAC_SIZE_16);
if (ret != 0)
return -13100 - i;
if (XMEMCMP(res, siphash_r16[i], SIPHASH_MAC_SIZE_16) != 0)
return -13200 - i;
}
#endif
/* Testing bad parameters. */
ret = wc_InitSipHash(NULL, NULL, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13300;
ret = wc_InitSipHash(NULL, siphash_key, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13301;
ret = wc_InitSipHash(&siphash, NULL, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13302;
ret = wc_InitSipHash(&siphash, siphash_key, 7);
if (ret != BAD_FUNC_ARG)
return -13303;
ret = wc_InitSipHash(&siphash, siphash_key, SIPHASH_MAC_SIZE_8);
if (ret != 0)
return -13304;
ret = wc_SipHashUpdate(NULL, NULL, 0);
if (ret != BAD_FUNC_ARG)
return -13305;
ret = wc_SipHashUpdate(&siphash, NULL, 1);
if (ret != BAD_FUNC_ARG)
return -13306;
ret = wc_SipHashFinal(NULL, NULL, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13307;
ret = wc_SipHashFinal(&siphash, NULL, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13308;
ret = wc_SipHashFinal(NULL, res, SIPHASH_MAC_SIZE_8);
if (ret != BAD_FUNC_ARG)
return -13309;
ret = wc_SipHashFinal(&siphash, res, SIPHASH_MAC_SIZE_16);
if (ret != BAD_FUNC_ARG)
return -13310;
ret = wc_SipHash(NULL, NULL, 0, NULL, SIPHASH_MAC_SIZE_16);
if (ret != BAD_FUNC_ARG)
return -13311;
ret = wc_SipHash(siphash_key, NULL, 0, NULL, SIPHASH_MAC_SIZE_16);
if (ret != BAD_FUNC_ARG)
return -13312;
ret = wc_SipHash(NULL, NULL, 0, res, SIPHASH_MAC_SIZE_16);
if (ret != BAD_FUNC_ARG)
return -13313;
ret = wc_SipHash(siphash_key, NULL, 0, res, 15);
if (ret != BAD_FUNC_ARG)
return -13314;
ret = wc_SipHash(siphash_key, NULL, 1, res, SIPHASH_MAC_SIZE_16);
if (ret != BAD_FUNC_ARG)
return -13315;
return 0;
}
#endif /* WOLFSSL_SIPHASH */
#ifdef HAVE_LIBZ
static const byte sample_text[] =

View File

@ -70,6 +70,7 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/pkcs12.h \
wolfssl/wolfcrypt/wolfmath.h \
wolfssl/wolfcrypt/sha3.h \
wolfssl/wolfcrypt/siphash.h \
wolfssl/wolfcrypt/cpuid.h \
wolfssl/wolfcrypt/cryptocb.h

101
wolfssl/wolfcrypt/siphash.h Normal file
View File

@ -0,0 +1,101 @@
/* siphash.h
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLF_CRYPT_SIPHASH_H
#define WOLF_CRYPT_SIPHASH_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(WOLFSSL_SIPHASH)
/* DESCRIPTION
*
* SipHash is a PseudoRandom Function (PRF) that can be used with small
* messages (less than 256 bytes).
* SipHash can be used for Message Authentication Codes (MACs) and as such must
* be passed a secret key.
* https://eprint.iacr.org/2012/351.pdf
*
* SipHash is commonly used in hash tables.
* Do not use this as a hash not as a general purpose MAC.
*
* WOLFSSL_SIPHASH_CROUNDS and WOLFSSL_SIPHASH_DROUNDS can be defined at build
* time to change the algorithm.
* Default is SipHash-2-4:
* WOLFSSL_SIPHASH_CROUNDS = 2
* WOLFSSL_SIPHASH_DROUNDS = 4
*/
#ifndef WOLFSSL_SIPHASH_CROUNDS
/* Number of rounds to perform in compression operation. */
#define WOLFSSL_SIPHASH_CROUNDS 2
#endif /* WOLFSSL_SIPHASH_CROUNDS */
#ifndef WOLFSSL_SIPHASH_DROUNDS
/* Number of rounds to perform in final operation. */
#define WOLFSSL_SIPHASH_DROUNDS 4
#endif /* WOLFSSL_SIPHASH_DROUNDS */
enum {
SIPHASH_KEY_SIZE = 16, /* Key size of SipHash. */
SIPHASH_BLOCK_SIZE = 8, /* Block size of SipHash. */
SIPHASH_MAC_SIZE_8 = 8, /* Output an 8 byte MAC. */
SIPHASH_MAC_SIZE_16 = 16, /* Output a 16 byte MAC. */
};
typedef struct SipHash SipHash;
struct SipHash {
/* Internal state. */
word64 v[4];
/* Cached message data. */
byte cache[SIPHASH_BLOCK_SIZE];
/* Number of bytes cached. */
byte cacheCnt;
/* Number of output bytes. */
byte outSz;
/* Number of input bytes processed. */
word32 inCnt;
};
#ifdef __cplusplus
extern "C" {
#endif
WOLFSSL_API int wc_InitSipHash(SipHash* sipHash, const unsigned char* key,
unsigned char outSz);
WOLFSSL_API int wc_SipHashUpdate(SipHash* sipHash, const unsigned char* in,
word32 inSz);
WOLFSSL_API int wc_SipHashFinal(SipHash* sipHash, unsigned char* out,
unsigned char outSz);
WOLFSSL_API int wc_SipHash(const unsigned char* key, const unsigned char* in,
word32 inSz, unsigned char* out, unsigned char outSz);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* NO_AES && WOLFSSL_SIPHASH */
#endif /* WOLF_CRYPT_SIPHASH_H */