1*7c356e86SAndroid Build Coastguard Worker /*- 2*7c356e86SAndroid Build Coastguard Worker * Copyright © 2011, 2014, 2015 3*7c356e86SAndroid Build Coastguard Worker * mirabilos <[email protected]> 4*7c356e86SAndroid Build Coastguard Worker * 5*7c356e86SAndroid Build Coastguard Worker * Provided that these terms and disclaimer and all copyright notices 6*7c356e86SAndroid Build Coastguard Worker * are retained or reproduced in an accompanying document, permission 7*7c356e86SAndroid Build Coastguard Worker * is granted to deal in this work without restriction, including un‐ 8*7c356e86SAndroid Build Coastguard Worker * limited rights to use, publicly perform, distribute, sell, modify, 9*7c356e86SAndroid Build Coastguard Worker * merge, give away, or sublicence. 10*7c356e86SAndroid Build Coastguard Worker * 11*7c356e86SAndroid Build Coastguard Worker * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to 12*7c356e86SAndroid Build Coastguard Worker * the utmost extent permitted by applicable law, neither express nor 13*7c356e86SAndroid Build Coastguard Worker * implied; without malicious intent or gross negligence. In no event 14*7c356e86SAndroid Build Coastguard Worker * may a licensor, author or contributor be held liable for indirect, 15*7c356e86SAndroid Build Coastguard Worker * direct, other damage, loss, or other issues arising in any way out 16*7c356e86SAndroid Build Coastguard Worker * of dealing in the work, even if advised of the possibility of such 17*7c356e86SAndroid Build Coastguard Worker * damage or existence of a defect, except proven that it results out 18*7c356e86SAndroid Build Coastguard Worker * of said person’s immediate fault when using the work as intended. 19*7c356e86SAndroid Build Coastguard Worker *- 20*7c356e86SAndroid Build Coastguard Worker * This file provides BAFH (Better Avalanche for the Jenkins Hash) as 21*7c356e86SAndroid Build Coastguard Worker * inline macro bodies that operate on “register uint32_t” variables, 22*7c356e86SAndroid Build Coastguard Worker * with variants that use their local intermediate registers. 23*7c356e86SAndroid Build Coastguard Worker * 24*7c356e86SAndroid Build Coastguard Worker * Usage note for BAFH with entropy distribution: input up to 4 bytes 25*7c356e86SAndroid Build Coastguard Worker * is best combined into a 32-bit unsigned integer, which is then run 26*7c356e86SAndroid Build Coastguard Worker * through BAFHFinish_reg for mixing and then used as context instead 27*7c356e86SAndroid Build Coastguard Worker * of 0. Longer input should be handled the same: take the first four 28*7c356e86SAndroid Build Coastguard Worker * bytes as IV after mixing then add subsequent bytes the same way. 29*7c356e86SAndroid Build Coastguard Worker * This needs counting input bytes and is endian-dependent, thus not, 30*7c356e86SAndroid Build Coastguard Worker * for speed reasons, specified for the regular stable hash, but very 31*7c356e86SAndroid Build Coastguard Worker * much recommended if the actual output value may differ across runs 32*7c356e86SAndroid Build Coastguard Worker * (so is using a random value instead of 0 for the IV). 33*7c356e86SAndroid Build Coastguard Worker *- 34*7c356e86SAndroid Build Coastguard Worker * Little quote gem: 35*7c356e86SAndroid Build Coastguard Worker * We are looking into it. Changing the core 36*7c356e86SAndroid Build Coastguard Worker * hash function in PHP isn't a trivial change 37*7c356e86SAndroid Build Coastguard Worker * and will take us some time. 38*7c356e86SAndroid Build Coastguard Worker * -- Rasmus Lerdorf 39*7c356e86SAndroid Build Coastguard Worker */ 40*7c356e86SAndroid Build Coastguard Worker 41*7c356e86SAndroid Build Coastguard Worker #ifndef SYSKERN_MIRHASH_H 42*7c356e86SAndroid Build Coastguard Worker #define SYSKERN_MIRHASH_H 1 43*7c356e86SAndroid Build Coastguard Worker #define SYSKERN_MIRHASH_BAFH 44*7c356e86SAndroid Build Coastguard Worker 45*7c356e86SAndroid Build Coastguard Worker #include <sys/types.h> 46*7c356e86SAndroid Build Coastguard Worker 47*7c356e86SAndroid Build Coastguard Worker __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.6 2015/11/29 17:05:02 tg Exp $"); 48*7c356e86SAndroid Build Coastguard Worker 49*7c356e86SAndroid Build Coastguard Worker /*- 50*7c356e86SAndroid Build Coastguard Worker * BAFH itself is defined by the following primitives: 51*7c356e86SAndroid Build Coastguard Worker * 52*7c356e86SAndroid Build Coastguard Worker * • BAFHInit(ctx) initialises the hash context, which consists of a 53*7c356e86SAndroid Build Coastguard Worker * sole 32-bit unsigned integer (ideally in a register), to 0. 54*7c356e86SAndroid Build Coastguard Worker * It is possible to use any initial value out of [0; 2³²[ – which 55*7c356e86SAndroid Build Coastguard Worker * is, in fact, recommended if using BAFH for entropy distribution 56*7c356e86SAndroid Build Coastguard Worker * – but for a regular stable hash, the IV 0 is needed. 57*7c356e86SAndroid Build Coastguard Worker * 58*7c356e86SAndroid Build Coastguard Worker * • BAFHUpdateOctet(ctx,val) compresses the unsigned 8-bit quantity 59*7c356e86SAndroid Build Coastguard Worker * into the hash context. The algorithm used is Jenkins’ one-at-a- 60*7c356e86SAndroid Build Coastguard Worker * time, except that an additional constant 1 is added so that, if 61*7c356e86SAndroid Build Coastguard Worker * the context is (still) zero, adding a NUL byte is not ignored. 62*7c356e86SAndroid Build Coastguard Worker * 63*7c356e86SAndroid Build Coastguard Worker * • BAFHror(eax,cl) evaluates to the unsigned 32-bit integer “eax”, 64*7c356e86SAndroid Build Coastguard Worker * rotated right by “cl” ∈ [0; 31] (no casting, be careful!) where 65*7c356e86SAndroid Build Coastguard Worker * “eax” must be uint32_t and “cl” an in-range integer. 66*7c356e86SAndroid Build Coastguard Worker * 67*7c356e86SAndroid Build Coastguard Worker * • BAFHFinish(ctx) avalanches the context around so every sub-byte 68*7c356e86SAndroid Build Coastguard Worker * depends on all input octets; afterwards, the context variable’s 69*7c356e86SAndroid Build Coastguard Worker * value is the hash output. BAFH does not use any padding, nor is 70*7c356e86SAndroid Build Coastguard Worker * the input length added; this is due to the common use case (for 71*7c356e86SAndroid Build Coastguard Worker * quick entropy distribution and use with a hashtable). 72*7c356e86SAndroid Build Coastguard Worker * Warning: BAFHFinish uses the MixColumn algorithm of AES – which 73*7c356e86SAndroid Build Coastguard Worker * is reversible (to avoid introducing funnels and reducing entro‐ 74*7c356e86SAndroid Build Coastguard Worker * py), so blinding may need to be employed for some uses, e.g. in 75*7c356e86SAndroid Build Coastguard Worker * mksh, after a fork. 76*7c356e86SAndroid Build Coastguard Worker * 77*7c356e86SAndroid Build Coastguard Worker * The BAFHUpdateOctet and BAFHFinish are available in two flavours: 78*7c356e86SAndroid Build Coastguard Worker * suffixed with _reg (assumes the context is in a register) or _mem 79*7c356e86SAndroid Build Coastguard Worker * (which doesn’t). 80*7c356e86SAndroid Build Coastguard Worker * 81*7c356e86SAndroid Build Coastguard Worker * The following high-level macros (with _reg and _mem variants) are 82*7c356e86SAndroid Build Coastguard Worker * available: 83*7c356e86SAndroid Build Coastguard Worker * 84*7c356e86SAndroid Build Coastguard Worker * • BAFHUpdateMem(ctx,buf,len) adds a memory block to a context. 85*7c356e86SAndroid Build Coastguard Worker * • BAFHUpdateStr(ctx,buf) is equivalent to using len=strlen(buf). 86*7c356e86SAndroid Build Coastguard Worker * • BAFHHostMem(ctx,buf,len) calculates the hash of the memory buf‐ 87*7c356e86SAndroid Build Coastguard Worker * fer using the first 4 octets (mixed) for IV, as outlined above; 88*7c356e86SAndroid Build Coastguard Worker * the result is endian-dependent; “ctx” assumed to be a register. 89*7c356e86SAndroid Build Coastguard Worker * • BAFHHostStr(ctx,buf) does the same for C strings. 90*7c356e86SAndroid Build Coastguard Worker * 91*7c356e86SAndroid Build Coastguard Worker * All macros may use ctx multiple times in their expansion, but all 92*7c356e86SAndroid Build Coastguard Worker * other arguments are always evaluated at most once except BAFHror. 93*7c356e86SAndroid Build Coastguard Worker * 94*7c356e86SAndroid Build Coastguard Worker * To stay portable, never use the BAFHHost*() macros (these are for 95*7c356e86SAndroid Build Coastguard Worker * host-local entropy shuffling), and encode numbers using ULEB128. 96*7c356e86SAndroid Build Coastguard Worker */ 97*7c356e86SAndroid Build Coastguard Worker 98*7c356e86SAndroid Build Coastguard Worker #define BAFHInit(h) do { \ 99*7c356e86SAndroid Build Coastguard Worker (h) = 0; \ 100*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 101*7c356e86SAndroid Build Coastguard Worker 102*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateOctet_reg(h,b) do { \ 103*7c356e86SAndroid Build Coastguard Worker (h) += (uint8_t)(b); \ 104*7c356e86SAndroid Build Coastguard Worker ++(h); \ 105*7c356e86SAndroid Build Coastguard Worker (h) += (h) << 10; \ 106*7c356e86SAndroid Build Coastguard Worker (h) ^= (h) >> 6; \ 107*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 108*7c356e86SAndroid Build Coastguard Worker 109*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateOctet_mem(m,b) do { \ 110*7c356e86SAndroid Build Coastguard Worker register uint32_t BAFH_h = (m); \ 111*7c356e86SAndroid Build Coastguard Worker \ 112*7c356e86SAndroid Build Coastguard Worker BAFHUpdateOctet_reg(BAFH_h, (b)); \ 113*7c356e86SAndroid Build Coastguard Worker (m) = BAFH_h; \ 114*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 115*7c356e86SAndroid Build Coastguard Worker 116*7c356e86SAndroid Build Coastguard Worker #define BAFHror(eax,cl) (((eax) >> (cl)) | ((eax) << (32 - (cl)))) 117*7c356e86SAndroid Build Coastguard Worker 118*7c356e86SAndroid Build Coastguard Worker #define BAFHFinish_reg(h) do { \ 119*7c356e86SAndroid Build Coastguard Worker register uint32_t BAFHFinish_v; \ 120*7c356e86SAndroid Build Coastguard Worker \ 121*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v = ((h) >> 7) & 0x01010101U; \ 122*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v += BAFHFinish_v << 1; \ 123*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v += BAFHFinish_v << 3; \ 124*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= ((h) << 1) & 0xFEFEFEFEU; \ 125*7c356e86SAndroid Build Coastguard Worker \ 126*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8); \ 127*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= ((h) = BAFHror((h), 8)); \ 128*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= ((h) = BAFHror((h), 8)); \ 129*7c356e86SAndroid Build Coastguard Worker (h) = BAFHror((h), 8) ^ BAFHFinish_v; \ 130*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 131*7c356e86SAndroid Build Coastguard Worker 132*7c356e86SAndroid Build Coastguard Worker #define BAFHFinish_mem(m) do { \ 133*7c356e86SAndroid Build Coastguard Worker register uint32_t BAFHFinish_v, BAFH_h = (m); \ 134*7c356e86SAndroid Build Coastguard Worker \ 135*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v = (BAFH_h >> 7) & 0x01010101U; \ 136*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v += BAFHFinish_v << 1; \ 137*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v += BAFHFinish_v << 3; \ 138*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= (BAFH_h << 1) & 0xFEFEFEFEU; \ 139*7c356e86SAndroid Build Coastguard Worker \ 140*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8); \ 141*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8)); \ 142*7c356e86SAndroid Build Coastguard Worker BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8)); \ 143*7c356e86SAndroid Build Coastguard Worker (m) = BAFHror(BAFH_h, 8) ^ BAFHFinish_v; \ 144*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 145*7c356e86SAndroid Build Coastguard Worker 146*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateMem_reg(h,p,z) do { \ 147*7c356e86SAndroid Build Coastguard Worker register const uint8_t *BAFHUpdate_p; \ 148*7c356e86SAndroid Build Coastguard Worker register size_t BAFHUpdate_z = (z); \ 149*7c356e86SAndroid Build Coastguard Worker \ 150*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_p = (const void *)(p); \ 151*7c356e86SAndroid Build Coastguard Worker while (BAFHUpdate_z--) \ 152*7c356e86SAndroid Build Coastguard Worker BAFHUpdateOctet_reg((h), *BAFHUpdate_p++); \ 153*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 154*7c356e86SAndroid Build Coastguard Worker 155*7c356e86SAndroid Build Coastguard Worker /* meh should have named them _r/m but that’s not valid C */ 156*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateMem_mem(m,p,z) do { \ 157*7c356e86SAndroid Build Coastguard Worker register uint32_t BAFH_h = (m); \ 158*7c356e86SAndroid Build Coastguard Worker \ 159*7c356e86SAndroid Build Coastguard Worker BAFHUpdateMem_reg(BAFH_h, (p), (z)); \ 160*7c356e86SAndroid Build Coastguard Worker (m) = BAFH_h; \ 161*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 162*7c356e86SAndroid Build Coastguard Worker 163*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateStr_reg(h,s) do { \ 164*7c356e86SAndroid Build Coastguard Worker register const uint8_t *BAFHUpdate_s; \ 165*7c356e86SAndroid Build Coastguard Worker register uint8_t BAFHUpdate_c; \ 166*7c356e86SAndroid Build Coastguard Worker \ 167*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_s = (const void *)(s); \ 168*7c356e86SAndroid Build Coastguard Worker while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0) \ 169*7c356e86SAndroid Build Coastguard Worker BAFHUpdateOctet_reg((h), BAFHUpdate_c); \ 170*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 171*7c356e86SAndroid Build Coastguard Worker 172*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateStr_mem(m,s) do { \ 173*7c356e86SAndroid Build Coastguard Worker register uint32_t BAFH_h = (m); \ 174*7c356e86SAndroid Build Coastguard Worker \ 175*7c356e86SAndroid Build Coastguard Worker BAFHUpdateStr_reg(BAFH_h, (s)); \ 176*7c356e86SAndroid Build Coastguard Worker (m) = BAFH_h; \ 177*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 178*7c356e86SAndroid Build Coastguard Worker 179*7c356e86SAndroid Build Coastguard Worker #define BAFHHostMem(h,p,z) do { \ 180*7c356e86SAndroid Build Coastguard Worker register const uint8_t *BAFHUpdate_p; \ 181*7c356e86SAndroid Build Coastguard Worker register size_t BAFHUpdate_z = (z); \ 182*7c356e86SAndroid Build Coastguard Worker size_t BAFHHost_z; \ 183*7c356e86SAndroid Build Coastguard Worker union { \ 184*7c356e86SAndroid Build Coastguard Worker uint8_t as_u8[4]; \ 185*7c356e86SAndroid Build Coastguard Worker uint32_t as_u32; \ 186*7c356e86SAndroid Build Coastguard Worker } BAFHHost_v; \ 187*7c356e86SAndroid Build Coastguard Worker \ 188*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_p = (const void *)(p); \ 189*7c356e86SAndroid Build Coastguard Worker BAFHHost_v.as_u32 = 0; \ 190*7c356e86SAndroid Build Coastguard Worker BAFHHost_z = BAFHUpdate_z < 4 ? BAFHUpdate_z : 4; \ 191*7c356e86SAndroid Build Coastguard Worker memcpy(BAFHHost_v.as_u8, BAFHUpdate_p, BAFHHost_z); \ 192*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_p += BAFHHost_z; \ 193*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_z -= BAFHHost_z; \ 194*7c356e86SAndroid Build Coastguard Worker (h) = BAFHHost_v.as_u32; \ 195*7c356e86SAndroid Build Coastguard Worker BAFHFinish_reg(h); \ 196*7c356e86SAndroid Build Coastguard Worker while (BAFHUpdate_z--) \ 197*7c356e86SAndroid Build Coastguard Worker BAFHUpdateOctet_reg((h), *BAFHUpdate_p++); \ 198*7c356e86SAndroid Build Coastguard Worker BAFHFinish_reg(h); \ 199*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 200*7c356e86SAndroid Build Coastguard Worker 201*7c356e86SAndroid Build Coastguard Worker #define BAFHHostStr(h,s) do { \ 202*7c356e86SAndroid Build Coastguard Worker register const uint8_t *BAFHUpdate_s; \ 203*7c356e86SAndroid Build Coastguard Worker register uint8_t BAFHUpdate_c; \ 204*7c356e86SAndroid Build Coastguard Worker union { \ 205*7c356e86SAndroid Build Coastguard Worker uint8_t as_u8[4]; \ 206*7c356e86SAndroid Build Coastguard Worker uint32_t as_u32; \ 207*7c356e86SAndroid Build Coastguard Worker } BAFHHost_v; \ 208*7c356e86SAndroid Build Coastguard Worker \ 209*7c356e86SAndroid Build Coastguard Worker BAFHUpdate_s = (const void *)(s); \ 210*7c356e86SAndroid Build Coastguard Worker BAFHHost_v.as_u32 = 0; \ 211*7c356e86SAndroid Build Coastguard Worker if ((BAFHHost_v.as_u8[0] = *BAFHUpdate_s) != 0) \ 212*7c356e86SAndroid Build Coastguard Worker ++BAFHUpdate_s; \ 213*7c356e86SAndroid Build Coastguard Worker if ((BAFHHost_v.as_u8[1] = *BAFHUpdate_s) != 0) \ 214*7c356e86SAndroid Build Coastguard Worker ++BAFHUpdate_s; \ 215*7c356e86SAndroid Build Coastguard Worker if ((BAFHHost_v.as_u8[2] = *BAFHUpdate_s) != 0) \ 216*7c356e86SAndroid Build Coastguard Worker ++BAFHUpdate_s; \ 217*7c356e86SAndroid Build Coastguard Worker if ((BAFHHost_v.as_u8[3] = *BAFHUpdate_s) != 0) \ 218*7c356e86SAndroid Build Coastguard Worker ++BAFHUpdate_s; \ 219*7c356e86SAndroid Build Coastguard Worker (h) = BAFHHost_v.as_u32; \ 220*7c356e86SAndroid Build Coastguard Worker BAFHFinish_reg(h); \ 221*7c356e86SAndroid Build Coastguard Worker while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0) \ 222*7c356e86SAndroid Build Coastguard Worker BAFHUpdateOctet_reg((h), BAFHUpdate_c); \ 223*7c356e86SAndroid Build Coastguard Worker BAFHFinish_reg(h); \ 224*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0) 225*7c356e86SAndroid Build Coastguard Worker 226*7c356e86SAndroid Build Coastguard Worker #endif 227