1427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/*-
2427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Copyright © 2011, 2014
3427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *	Thorsten Glaser <tg@mirbsd.org>
4427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
5427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Provided that these terms and disclaimer and all copyright notices
6427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * are retained or reproduced in an accompanying document, permission
7427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * is granted to deal in this work without restriction, including un‐
8427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * limited rights to use, publicly perform, distribute, sell, modify,
9427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * merge, give away, or sublicence.
10427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
11427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
12427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * the utmost extent permitted by applicable law, neither express nor
13427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * implied; without malicious intent or gross negligence. In no event
14427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * may a licensor, author or contributor be held liable for indirect,
15427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * direct, other damage, loss, or other issues arising in any way out
16427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * of dealing in the work, even if advised of the possibility of such
17427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * damage or existence of a defect, except proven that it results out
18427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * of said person’s immediate fault when using the work as intended.
19427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *-
20427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * This file provides BAFH (Better Avalanche for the Jenkins Hash) as
21427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * inline macro bodies that operate on “register uint32_t” variables,
22427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * with variants that use their local intermediate registers.
23427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
24427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Usage note for BAFH with entropy distribution: input up to 4 bytes
25427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * is best combined into a 32-bit unsigned integer, which is then run
26427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * through BAFHFinish_reg for mixing and then used as context instead
27427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * of 0. Longer input should be handled the same: take the first four
28427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * bytes as IV after mixing then add subsequent bytes the same way.
29427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * This needs counting input bytes and is endian-dependent, thus not,
30427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * for speed reasons, specified for the regular stable hash, but very
31427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * much recommended if the actual output value may differ across runs
32427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * (so is using a random value instead of 0 for the IV).
33b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes *-
34b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes * Little quote gem:
35b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes *	We are looking into it. Changing the core
36b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes *	hash function in PHP isn't a trivial change
37b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes *	and will take us some time.
38b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes * -- Rasmus Lerdorf
39427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes */
40427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
41427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#ifndef SYSKERN_MIRHASH_H
42427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define SYSKERN_MIRHASH_H 1
43427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define SYSKERN_MIRHASH_BAFH
44427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
45427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#include <sys/types.h>
46427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
47b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $");
48427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
49427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/*-
50427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * BAFH itself is defined by the following primitives:
51427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
52427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHInit(ctx) initialises the hash context, which consists of a
53427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   sole 32-bit unsigned integer (ideally in a register), to 0.
54427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   It is possible to use any initial value out of [0; 2³²[ – which
55427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   is, in fact, recommended if using BAFH for entropy distribution
56427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   – but for a regular stable hash, the IV 0 is needed.
57427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
58427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHUpdateOctet(ctx,val) compresses the unsigned 8-bit quantity
59427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   into the hash context. The algorithm used is Jenkins’ one-at-a-
60427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   time, except that an additional constant 1 is added so that, if
61427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   the context is (still) zero, adding a NUL byte is not ignored.
62427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
63427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHror(eax,cl) evaluates to the unsigned 32-bit integer “eax”,
64427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   rotated right by “cl” ∈ [0;31]; no casting, be careful!
65427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
66427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHFinish(ctx) avalanches the context around so every sub-byte
67427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   depends on all input octets; afterwards, the context variable’s
68427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   value is the hash output. BAFH does not use any padding, nor is
69427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   the input length added; this is due to the common use case (for
70427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   quick entropy distribution and use with a hashtable).
71427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   Warning: BAFHFinish uses the MixColumn algorithm of AES – which
72427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   is reversible (to avoid introducing funnels and reducing entro‐
73427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   py), so blinding may need to be employed for some uses, e.g. in
74427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   mksh, after a fork.
75427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
76427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * The BAFHUpdateOctet and BAFHFinish are available in two flavours:
77427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * suffixed with _reg (assumes the context is in a register) or _mem
78427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * (which doesn’t).
79427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
80427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * The following high-level macros (with _reg and _mem variants) are
81427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * available:
82427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
83427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHUpdateMem(ctx,buf,len) adds a memory block to a context.
84427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHUpdateStr(ctx,buf) is equivalent to using len=strlen(buf).
85427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHHostMem(ctx,buf,len) calculates the hash of the memory buf‐
86427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   fer using the first 4 octets (mixed) for IV, as outlined above;
87427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *   the result is endian-dependent; “ctx” assumed to be a register.
88427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * • BAFHHostStr(ctx,buf) does the same for C strings.
89427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
90427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * All macros may use ctx multiple times in their expansion, but all
91427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * other arguments are always evaluated at most once.
92427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes *
93427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * To stay portable, never use the BAFHHost*() macros (these are for
94427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * host-local entropy shuffling), and encode numbers using ULEB128.
95427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes */
96427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
97427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHInit(h) do {					\
98427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) = 0;						\
99427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
100427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
101427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateOctet_reg(h,b) do {				\
102427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) += (uint8_t)(b);					\
103427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	++(h);							\
104427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) += (h) << 10;					\
105427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) ^= (h) >> 6;					\
106427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
107427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
108427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateOctet_mem(m,b) do {				\
109427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint32_t BAFH_h = (m);				\
110427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
111427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdateOctet_reg(BAFH_h, (b));			\
112427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(m) = BAFH_h;						\
113427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
114427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
115427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHror(eax,cl) (((eax) >> (cl)) | ((eax) << (32 - (cl))))
116427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
117427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHFinish_reg(h) do {					\
118427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint32_t BAFHFinish_v;				\
119427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
120427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v = ((h) >> 7) & 0x01010101U;		\
121427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v += BAFHFinish_v << 1;			\
122427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v += BAFHFinish_v << 3;			\
123427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= ((h) << 1) & 0xFEFEFEFEU;		\
124427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
125427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);		\
126427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= ((h) = BAFHror((h), 8));		\
127427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= ((h) = BAFHror((h), 8));		\
128427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) = BAFHror((h), 8) ^ BAFHFinish_v;			\
129427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
130427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
131427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHFinish_mem(m) do {					\
132427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint32_t BAFHFinish_v, BAFH_h = (m);		\
133427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
134427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v = (BAFH_h >> 7) & 0x01010101U;		\
135427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v += BAFHFinish_v << 1;			\
136427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v += BAFHFinish_v << 3;			\
137427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= (BAFH_h << 1) & 0xFEFEFEFEU;		\
138427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
139427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);		\
140427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));		\
141427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));		\
142427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(m) = BAFHror(BAFH_h, 8) ^ BAFHFinish_v;		\
143427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
144427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
145427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateMem_reg(h,p,z) do {				\
146427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register const uint8_t *BAFHUpdate_p;			\
147427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register size_t BAFHUpdate_z = (z);			\
148427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
149427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_p = (const void *)(p);			\
150427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	while (BAFHUpdate_z--)					\
151427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);	\
152427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
153427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
154427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/* meh should have named them _r/m but that’s not valid C */
155427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateMem_mem(m,p,z) do {				\
156427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint32_t BAFH_h = (m);				\
157427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
158427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdateMem_reg(BAFH_h, (p), (z));			\
159427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(m) = BAFH_h;						\
160427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
161427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
162427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateStr_reg(h,s) do {				\
163427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register const uint8_t *BAFHUpdate_s;			\
164427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint8_t BAFHUpdate_c;				\
165427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
166427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_s = (const void *)(s);			\
167427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)		\
168427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		BAFHUpdateOctet_reg((h), BAFHUpdate_c);		\
169427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
170427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
171427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHUpdateStr_mem(m,s) do {				\
172427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint32_t BAFH_h = (m);				\
173427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
174427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdateStr_reg(BAFH_h, (s));				\
175427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(m) = BAFH_h;						\
176427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
177427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
178427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHHostMem(h,p,z) do {					\
179427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register const uint8_t *BAFHUpdate_p;			\
180427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register size_t BAFHUpdate_z = (z);			\
181427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	size_t BAFHHost_z;					\
182427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	union {							\
183427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		uint8_t as_u8[4];				\
184427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		uint32_t as_u32;				\
185427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	} BAFHHost_v;						\
186427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
187427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_p = (const void *)(p);			\
188427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHHost_v.as_u32 = 0;					\
189427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHHost_z = BAFHUpdate_z < 4 ? BAFHUpdate_z : 4;	\
190427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	memcpy(BAFHHost_v.as_u8, BAFHUpdate_p, BAFHHost_z);	\
191427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_p += BAFHHost_z;				\
192427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_z -= BAFHHost_z;				\
193427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) = BAFHHost_v.as_u32;				\
194427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_reg(h);					\
195427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	while (BAFHUpdate_z--)					\
196427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);	\
197427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_reg(h);					\
198427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
199427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
200427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define BAFHHostStr(h,s) do {					\
201427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register const uint8_t *BAFHUpdate_s;			\
202427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	register uint8_t BAFHUpdate_c;				\
203427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	union {							\
204427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		uint8_t as_u8[4];				\
205427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		uint32_t as_u32;				\
206427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	} BAFHHost_v;						\
207427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes								\
208427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHUpdate_s = (const void *)(s);			\
209427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	if ((BAFHHost_v.as_u8[0] = *BAFHUpdate_s) != 0)		\
210427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		++BAFHUpdate_s;					\
211427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	if ((BAFHHost_v.as_u8[1] = *BAFHUpdate_s) != 0)		\
212427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		++BAFHUpdate_s;					\
213427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	if ((BAFHHost_v.as_u8[2] = *BAFHUpdate_s) != 0)		\
214427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		++BAFHUpdate_s;					\
215427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	if ((BAFHHost_v.as_u8[3] = *BAFHUpdate_s) != 0)		\
216427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		++BAFHUpdate_s;					\
217427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	(h) = BAFHHost_v.as_u32;				\
218427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_reg(h);					\
219427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)		\
220427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes		BAFHUpdateOctet_reg((h), BAFHUpdate_c);		\
221427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes	BAFHFinish_reg(h);					\
222427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} while (/* CONSTCOND */ 0)
223427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes
224427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif
225