cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

siphash.c (11845B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2/* Copyright (C) 2016-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
      3 *
      4 * SipHash: a fast short-input PRF
      5 * https://131002.net/siphash/
      6 *
      7 * This implementation is specifically for SipHash2-4 for a secure PRF
      8 * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
      9 * hashtables.
     10 */
     11
     12#include <linux/siphash.h>
     13#include <asm/unaligned.h>
     14
     15#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
     16#include <linux/dcache.h>
     17#include <asm/word-at-a-time.h>
     18#endif
     19
     20#define SIPROUND SIPHASH_PERMUTATION(v0, v1, v2, v3)
     21
     22#define PREAMBLE(len) \
     23	u64 v0 = SIPHASH_CONST_0; \
     24	u64 v1 = SIPHASH_CONST_1; \
     25	u64 v2 = SIPHASH_CONST_2; \
     26	u64 v3 = SIPHASH_CONST_3; \
     27	u64 b = ((u64)(len)) << 56; \
     28	v3 ^= key->key[1]; \
     29	v2 ^= key->key[0]; \
     30	v1 ^= key->key[1]; \
     31	v0 ^= key->key[0];
     32
     33#define POSTAMBLE \
     34	v3 ^= b; \
     35	SIPROUND; \
     36	SIPROUND; \
     37	v0 ^= b; \
     38	v2 ^= 0xff; \
     39	SIPROUND; \
     40	SIPROUND; \
     41	SIPROUND; \
     42	SIPROUND; \
     43	return (v0 ^ v1) ^ (v2 ^ v3);
     44
     45#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
     46u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key)
     47{
     48	const u8 *end = data + len - (len % sizeof(u64));
     49	const u8 left = len & (sizeof(u64) - 1);
     50	u64 m;
     51	PREAMBLE(len)
     52	for (; data != end; data += sizeof(u64)) {
     53		m = le64_to_cpup(data);
     54		v3 ^= m;
     55		SIPROUND;
     56		SIPROUND;
     57		v0 ^= m;
     58	}
     59#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
     60	if (left)
     61		b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
     62						  bytemask_from_count(left)));
     63#else
     64	switch (left) {
     65	case 7: b |= ((u64)end[6]) << 48; fallthrough;
     66	case 6: b |= ((u64)end[5]) << 40; fallthrough;
     67	case 5: b |= ((u64)end[4]) << 32; fallthrough;
     68	case 4: b |= le32_to_cpup(data); break;
     69	case 3: b |= ((u64)end[2]) << 16; fallthrough;
     70	case 2: b |= le16_to_cpup(data); break;
     71	case 1: b |= end[0];
     72	}
     73#endif
     74	POSTAMBLE
     75}
     76EXPORT_SYMBOL(__siphash_aligned);
     77#endif
     78
     79u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key)
     80{
     81	const u8 *end = data + len - (len % sizeof(u64));
     82	const u8 left = len & (sizeof(u64) - 1);
     83	u64 m;
     84	PREAMBLE(len)
     85	for (; data != end; data += sizeof(u64)) {
     86		m = get_unaligned_le64(data);
     87		v3 ^= m;
     88		SIPROUND;
     89		SIPROUND;
     90		v0 ^= m;
     91	}
     92#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
     93	if (left)
     94		b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
     95						  bytemask_from_count(left)));
     96#else
     97	switch (left) {
     98	case 7: b |= ((u64)end[6]) << 48; fallthrough;
     99	case 6: b |= ((u64)end[5]) << 40; fallthrough;
    100	case 5: b |= ((u64)end[4]) << 32; fallthrough;
    101	case 4: b |= get_unaligned_le32(end); break;
    102	case 3: b |= ((u64)end[2]) << 16; fallthrough;
    103	case 2: b |= get_unaligned_le16(end); break;
    104	case 1: b |= end[0];
    105	}
    106#endif
    107	POSTAMBLE
    108}
    109EXPORT_SYMBOL(__siphash_unaligned);
    110
    111/**
    112 * siphash_1u64 - compute 64-bit siphash PRF value of a u64
    113 * @first: first u64
    114 * @key: the siphash key
    115 */
    116u64 siphash_1u64(const u64 first, const siphash_key_t *key)
    117{
    118	PREAMBLE(8)
    119	v3 ^= first;
    120	SIPROUND;
    121	SIPROUND;
    122	v0 ^= first;
    123	POSTAMBLE
    124}
    125EXPORT_SYMBOL(siphash_1u64);
    126
    127/**
    128 * siphash_2u64 - compute 64-bit siphash PRF value of 2 u64
    129 * @first: first u64
    130 * @second: second u64
    131 * @key: the siphash key
    132 */
    133u64 siphash_2u64(const u64 first, const u64 second, const siphash_key_t *key)
    134{
    135	PREAMBLE(16)
    136	v3 ^= first;
    137	SIPROUND;
    138	SIPROUND;
    139	v0 ^= first;
    140	v3 ^= second;
    141	SIPROUND;
    142	SIPROUND;
    143	v0 ^= second;
    144	POSTAMBLE
    145}
    146EXPORT_SYMBOL(siphash_2u64);
    147
    148/**
    149 * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64
    150 * @first: first u64
    151 * @second: second u64
    152 * @third: third u64
    153 * @key: the siphash key
    154 */
    155u64 siphash_3u64(const u64 first, const u64 second, const u64 third,
    156		 const siphash_key_t *key)
    157{
    158	PREAMBLE(24)
    159	v3 ^= first;
    160	SIPROUND;
    161	SIPROUND;
    162	v0 ^= first;
    163	v3 ^= second;
    164	SIPROUND;
    165	SIPROUND;
    166	v0 ^= second;
    167	v3 ^= third;
    168	SIPROUND;
    169	SIPROUND;
    170	v0 ^= third;
    171	POSTAMBLE
    172}
    173EXPORT_SYMBOL(siphash_3u64);
    174
    175/**
    176 * siphash_4u64 - compute 64-bit siphash PRF value of 4 u64
    177 * @first: first u64
    178 * @second: second u64
    179 * @third: third u64
    180 * @forth: forth u64
    181 * @key: the siphash key
    182 */
    183u64 siphash_4u64(const u64 first, const u64 second, const u64 third,
    184		 const u64 forth, const siphash_key_t *key)
    185{
    186	PREAMBLE(32)
    187	v3 ^= first;
    188	SIPROUND;
    189	SIPROUND;
    190	v0 ^= first;
    191	v3 ^= second;
    192	SIPROUND;
    193	SIPROUND;
    194	v0 ^= second;
    195	v3 ^= third;
    196	SIPROUND;
    197	SIPROUND;
    198	v0 ^= third;
    199	v3 ^= forth;
    200	SIPROUND;
    201	SIPROUND;
    202	v0 ^= forth;
    203	POSTAMBLE
    204}
    205EXPORT_SYMBOL(siphash_4u64);
    206
    207u64 siphash_1u32(const u32 first, const siphash_key_t *key)
    208{
    209	PREAMBLE(4)
    210	b |= first;
    211	POSTAMBLE
    212}
    213EXPORT_SYMBOL(siphash_1u32);
    214
    215u64 siphash_3u32(const u32 first, const u32 second, const u32 third,
    216		 const siphash_key_t *key)
    217{
    218	u64 combined = (u64)second << 32 | first;
    219	PREAMBLE(12)
    220	v3 ^= combined;
    221	SIPROUND;
    222	SIPROUND;
    223	v0 ^= combined;
    224	b |= third;
    225	POSTAMBLE
    226}
    227EXPORT_SYMBOL(siphash_3u32);
    228
    229#if BITS_PER_LONG == 64
    230/* Note that on 64-bit, we make HalfSipHash1-3 actually be SipHash1-3, for
    231 * performance reasons. On 32-bit, below, we actually implement HalfSipHash1-3.
    232 */
    233
    234#define HSIPROUND SIPROUND
    235#define HPREAMBLE(len) PREAMBLE(len)
    236#define HPOSTAMBLE \
    237	v3 ^= b; \
    238	HSIPROUND; \
    239	v0 ^= b; \
    240	v2 ^= 0xff; \
    241	HSIPROUND; \
    242	HSIPROUND; \
    243	HSIPROUND; \
    244	return (v0 ^ v1) ^ (v2 ^ v3);
    245
    246#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
    247u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
    248{
    249	const u8 *end = data + len - (len % sizeof(u64));
    250	const u8 left = len & (sizeof(u64) - 1);
    251	u64 m;
    252	HPREAMBLE(len)
    253	for (; data != end; data += sizeof(u64)) {
    254		m = le64_to_cpup(data);
    255		v3 ^= m;
    256		HSIPROUND;
    257		v0 ^= m;
    258	}
    259#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
    260	if (left)
    261		b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
    262						  bytemask_from_count(left)));
    263#else
    264	switch (left) {
    265	case 7: b |= ((u64)end[6]) << 48; fallthrough;
    266	case 6: b |= ((u64)end[5]) << 40; fallthrough;
    267	case 5: b |= ((u64)end[4]) << 32; fallthrough;
    268	case 4: b |= le32_to_cpup(data); break;
    269	case 3: b |= ((u64)end[2]) << 16; fallthrough;
    270	case 2: b |= le16_to_cpup(data); break;
    271	case 1: b |= end[0];
    272	}
    273#endif
    274	HPOSTAMBLE
    275}
    276EXPORT_SYMBOL(__hsiphash_aligned);
    277#endif
    278
    279u32 __hsiphash_unaligned(const void *data, size_t len,
    280			 const hsiphash_key_t *key)
    281{
    282	const u8 *end = data + len - (len % sizeof(u64));
    283	const u8 left = len & (sizeof(u64) - 1);
    284	u64 m;
    285	HPREAMBLE(len)
    286	for (; data != end; data += sizeof(u64)) {
    287		m = get_unaligned_le64(data);
    288		v3 ^= m;
    289		HSIPROUND;
    290		v0 ^= m;
    291	}
    292#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
    293	if (left)
    294		b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
    295						  bytemask_from_count(left)));
    296#else
    297	switch (left) {
    298	case 7: b |= ((u64)end[6]) << 48; fallthrough;
    299	case 6: b |= ((u64)end[5]) << 40; fallthrough;
    300	case 5: b |= ((u64)end[4]) << 32; fallthrough;
    301	case 4: b |= get_unaligned_le32(end); break;
    302	case 3: b |= ((u64)end[2]) << 16; fallthrough;
    303	case 2: b |= get_unaligned_le16(end); break;
    304	case 1: b |= end[0];
    305	}
    306#endif
    307	HPOSTAMBLE
    308}
    309EXPORT_SYMBOL(__hsiphash_unaligned);
    310
    311/**
    312 * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32
    313 * @first: first u32
    314 * @key: the hsiphash key
    315 */
    316u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
    317{
    318	HPREAMBLE(4)
    319	b |= first;
    320	HPOSTAMBLE
    321}
    322EXPORT_SYMBOL(hsiphash_1u32);
    323
    324/**
    325 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
    326 * @first: first u32
    327 * @second: second u32
    328 * @key: the hsiphash key
    329 */
    330u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
    331{
    332	u64 combined = (u64)second << 32 | first;
    333	HPREAMBLE(8)
    334	v3 ^= combined;
    335	HSIPROUND;
    336	v0 ^= combined;
    337	HPOSTAMBLE
    338}
    339EXPORT_SYMBOL(hsiphash_2u32);
    340
    341/**
    342 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
    343 * @first: first u32
    344 * @second: second u32
    345 * @third: third u32
    346 * @key: the hsiphash key
    347 */
    348u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
    349		  const hsiphash_key_t *key)
    350{
    351	u64 combined = (u64)second << 32 | first;
    352	HPREAMBLE(12)
    353	v3 ^= combined;
    354	HSIPROUND;
    355	v0 ^= combined;
    356	b |= third;
    357	HPOSTAMBLE
    358}
    359EXPORT_SYMBOL(hsiphash_3u32);
    360
    361/**
    362 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
    363 * @first: first u32
    364 * @second: second u32
    365 * @third: third u32
    366 * @forth: forth u32
    367 * @key: the hsiphash key
    368 */
    369u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
    370		  const u32 forth, const hsiphash_key_t *key)
    371{
    372	u64 combined = (u64)second << 32 | first;
    373	HPREAMBLE(16)
    374	v3 ^= combined;
    375	HSIPROUND;
    376	v0 ^= combined;
    377	combined = (u64)forth << 32 | third;
    378	v3 ^= combined;
    379	HSIPROUND;
    380	v0 ^= combined;
    381	HPOSTAMBLE
    382}
    383EXPORT_SYMBOL(hsiphash_4u32);
    384#else
    385#define HSIPROUND HSIPHASH_PERMUTATION(v0, v1, v2, v3)
    386
    387#define HPREAMBLE(len) \
    388	u32 v0 = HSIPHASH_CONST_0; \
    389	u32 v1 = HSIPHASH_CONST_1; \
    390	u32 v2 = HSIPHASH_CONST_2; \
    391	u32 v3 = HSIPHASH_CONST_3; \
    392	u32 b = ((u32)(len)) << 24; \
    393	v3 ^= key->key[1]; \
    394	v2 ^= key->key[0]; \
    395	v1 ^= key->key[1]; \
    396	v0 ^= key->key[0];
    397
    398#define HPOSTAMBLE \
    399	v3 ^= b; \
    400	HSIPROUND; \
    401	v0 ^= b; \
    402	v2 ^= 0xff; \
    403	HSIPROUND; \
    404	HSIPROUND; \
    405	HSIPROUND; \
    406	return v1 ^ v3;
    407
    408#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
    409u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
    410{
    411	const u8 *end = data + len - (len % sizeof(u32));
    412	const u8 left = len & (sizeof(u32) - 1);
    413	u32 m;
    414	HPREAMBLE(len)
    415	for (; data != end; data += sizeof(u32)) {
    416		m = le32_to_cpup(data);
    417		v3 ^= m;
    418		HSIPROUND;
    419		v0 ^= m;
    420	}
    421	switch (left) {
    422	case 3: b |= ((u32)end[2]) << 16; fallthrough;
    423	case 2: b |= le16_to_cpup(data); break;
    424	case 1: b |= end[0];
    425	}
    426	HPOSTAMBLE
    427}
    428EXPORT_SYMBOL(__hsiphash_aligned);
    429#endif
    430
    431u32 __hsiphash_unaligned(const void *data, size_t len,
    432			 const hsiphash_key_t *key)
    433{
    434	const u8 *end = data + len - (len % sizeof(u32));
    435	const u8 left = len & (sizeof(u32) - 1);
    436	u32 m;
    437	HPREAMBLE(len)
    438	for (; data != end; data += sizeof(u32)) {
    439		m = get_unaligned_le32(data);
    440		v3 ^= m;
    441		HSIPROUND;
    442		v0 ^= m;
    443	}
    444	switch (left) {
    445	case 3: b |= ((u32)end[2]) << 16; fallthrough;
    446	case 2: b |= get_unaligned_le16(end); break;
    447	case 1: b |= end[0];
    448	}
    449	HPOSTAMBLE
    450}
    451EXPORT_SYMBOL(__hsiphash_unaligned);
    452
    453/**
    454 * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32
    455 * @first: first u32
    456 * @key: the hsiphash key
    457 */
    458u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
    459{
    460	HPREAMBLE(4)
    461	v3 ^= first;
    462	HSIPROUND;
    463	v0 ^= first;
    464	HPOSTAMBLE
    465}
    466EXPORT_SYMBOL(hsiphash_1u32);
    467
    468/**
    469 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
    470 * @first: first u32
    471 * @second: second u32
    472 * @key: the hsiphash key
    473 */
    474u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
    475{
    476	HPREAMBLE(8)
    477	v3 ^= first;
    478	HSIPROUND;
    479	v0 ^= first;
    480	v3 ^= second;
    481	HSIPROUND;
    482	v0 ^= second;
    483	HPOSTAMBLE
    484}
    485EXPORT_SYMBOL(hsiphash_2u32);
    486
    487/**
    488 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
    489 * @first: first u32
    490 * @second: second u32
    491 * @third: third u32
    492 * @key: the hsiphash key
    493 */
    494u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
    495		  const hsiphash_key_t *key)
    496{
    497	HPREAMBLE(12)
    498	v3 ^= first;
    499	HSIPROUND;
    500	v0 ^= first;
    501	v3 ^= second;
    502	HSIPROUND;
    503	v0 ^= second;
    504	v3 ^= third;
    505	HSIPROUND;
    506	v0 ^= third;
    507	HPOSTAMBLE
    508}
    509EXPORT_SYMBOL(hsiphash_3u32);
    510
    511/**
    512 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
    513 * @first: first u32
    514 * @second: second u32
    515 * @third: third u32
    516 * @forth: forth u32
    517 * @key: the hsiphash key
    518 */
    519u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
    520		  const u32 forth, const hsiphash_key_t *key)
    521{
    522	HPREAMBLE(16)
    523	v3 ^= first;
    524	HSIPROUND;
    525	v0 ^= first;
    526	v3 ^= second;
    527	HSIPROUND;
    528	v0 ^= second;
    529	v3 ^= third;
    530	HSIPROUND;
    531	v0 ^= third;
    532	v3 ^= forth;
    533	HSIPROUND;
    534	v0 ^= forth;
    535	HPOSTAMBLE
    536}
    537EXPORT_SYMBOL(hsiphash_4u32);
    538#endif