1//===--- SipHash.cpp - An ABI-stable string hash --------------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file implements an ABI-stable string hash based on SipHash, used to 10// compute ptrauth discriminators. 12//===----------------------------------------------------------------------===// 24using namespacesupport;
26#define DEBUG_TYPE "llvm-siphash" 28// Lightly adapted from the SipHash reference C implementation: 29// https://github.com/veorq/SipHash 30// by Jean-Philippe Aumasson and Daniel J. Bernstein 32#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) 54/// Computes a SipHash value 56/// \param in: pointer to input data (read-only) 57/// \param inlen: input data length in bytes (any size_t value) 58/// \param k: reference to the key data 16-byte array (read-only) 59/// \returns output data, must be 8 or 16 bytes 61template <
int cROUNDS,
int dROUNDS,
size_t outlen>
62void siphash(
constunsignedchar *in,
uint64_t inlen,
63constunsignedchar (&k)[16],
unsignedchar (&out)[outlen]) {
65constunsignedchar *ni = (
constunsignedchar *)in;
66constunsignedchar *kk = (
constunsignedchar *)k;
68static_assert(outlen == 8 || outlen == 16,
"result should be 8 or 16 bytes");
70uint64_t v0 = UINT64_C(0x736f6d6570736575);
71uint64_t v1 = UINT64_C(0x646f72616e646f6d);
72uint64_t v2 = UINT64_C(0x6c7967656e657261);
73uint64_t v3 = UINT64_C(0x7465646279746573);
78constunsignedchar *end = ni + inlen - (inlen %
sizeof(
uint64_t));
79constint left = inlen & 7;
89for (; ni != end; ni += 8) {
93for (i = 0; i < cROUNDS; ++i)
127for (i = 0; i < cROUNDS; ++i)
137for (i = 0; i < dROUNDS; ++i)
140 b = v0 ^ v1 ^ v2 ^ v3;
148for (i = 0; i < dROUNDS; ++i)
151 b = v0 ^ v1 ^ v2 ^ v3;
155}
// end anonymous namespace 159 siphash<2, 4>(In.data(), In.size(), K, Out);
164 siphash<2, 4>(In.data(), In.size(), K, Out);
167/// Compute an ABI-stable 16-bit hash of the given string. 169staticconstuint8_t K[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10, 0x4a, 0x79,
170 0x6f, 0xec, 0x8b, 0x1b, 0x42, 0x87, 0x81, 0xd4};
176// Produce a non-zero 16-bit discriminator. 177uint16_t Discriminator = (RawHash % 0xFFFF) + 1;
179dbgs() <<
"ptrauth stable hash discriminator: " << utostr(Discriminator)
181 << utohexstr(Discriminator,
/*Lowercase=*/false,
/*Width=*/4)
183 <<
" of: " << Str <<
"\n");
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef - Represent a constant reference to a string, i.e.
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
This is an optimization pass for GlobalISel generic memory operations.
void getSipHash_2_4_64(ArrayRef< uint8_t > In, const uint8_t(&K)[16], uint8_t(&Out)[8])
Computes a SipHash-2-4 64-bit result.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint16_t getPointerAuthStableSipHash(StringRef S)
Compute a stable non-zero 16-bit hash of the given string.
void getSipHash_2_4_128(ArrayRef< uint8_t > In, const uint8_t(&K)[16], uint8_t(&Out)[16])
Computes a SipHash-2-4 128-bit result.