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