xref: /openbsd/gnu/usr.bin/perl/hv_func.h (revision 4bdff4be)
1 /* hash a key
2  *--------------------------------------------------------------------------------------
3  * The "hash seed" feature was added in Perl 5.8.1 to perturb the results
4  * to avoid "algorithmic complexity attacks".
5  *
6  * If USE_HASH_SEED is defined, hash randomisation is done by default
7  * (see also perl.c:perl_parse() and S_init_tls_and_interp() and util.c:get_hash_seed())
8  */
9 #ifndef PERL_SEEN_HV_FUNC_H_ /* compile once */
10 #define PERL_SEEN_HV_FUNC_H_
11 #include "hv_macro.h"
12 
13 #if !( 0 \
14         || defined(PERL_HASH_FUNC_SIPHASH) \
15         || defined(PERL_HASH_FUNC_SIPHASH13) \
16         || defined(PERL_HASH_FUNC_ZAPHOD32) \
17     )
18 #   ifdef CAN64BITHASH
19 #       define PERL_HASH_FUNC_SIPHASH13
20 #   else
21 #       define PERL_HASH_FUNC_ZAPHOD32
22 #   endif
23 #endif
24 
25 #ifndef PERL_HASH_USE_SBOX32_ALSO
26 #define PERL_HASH_USE_SBOX32_ALSO 1
27 #endif
28 
29 #ifndef SBOX32_MAX_LEN
30 #define SBOX32_MAX_LEN 24
31 #endif
32 
33 /* this must be after the SBOX32_MAX_LEN define */
34 #include "sbox32_hash.h"
35 
36 #if defined(PERL_HASH_FUNC_SIPHASH)
37 # define __PERL_HASH_FUNC "SIPHASH_2_4"
38 # define __PERL_HASH_WORD_TYPE U64
39 # define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE)
40 # define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 2)
41 # define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 4)
42 # define __PERL_HASH_SEED_STATE(seed,state) S_perl_siphash_seed_state(seed,state)
43 # define __PERL_HASH_WITH_STATE(state,str,len) S_perl_hash_siphash_2_4_with_state((state),(U8*)(str),(len))
44 #elif defined(PERL_HASH_FUNC_SIPHASH13)
45 # define __PERL_HASH_FUNC "SIPHASH_1_3"
46 # define __PERL_HASH_WORD_TYPE U64
47 # define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE)
48 # define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 2)
49 # define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 4)
50 # define __PERL_HASH_SEED_STATE(seed,state) S_perl_siphash_seed_state(seed,state)
51 # define __PERL_HASH_WITH_STATE(state,str,len) S_perl_hash_siphash_1_3_with_state((state),(U8*)(str),(len))
52 #elif defined(PERL_HASH_FUNC_ZAPHOD32)
53 # define __PERL_HASH_FUNC "ZAPHOD32"
54 # define __PERL_HASH_WORD_TYPE U32
55 # define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE)
56 # define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 3)
57 # define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 3)
58 # define __PERL_HASH_SEED_STATE(seed,state) zaphod32_seed_state(seed,state)
59 # define __PERL_HASH_WITH_STATE(state,str,len) (U32)zaphod32_hash_with_state((state),(U8*)(str),(len))
60 # include "zaphod32_hash.h"
61 #endif
62 
63 #ifndef __PERL_HASH_WITH_STATE
64 #error "No hash function defined!"
65 #endif
66 #ifndef __PERL_HASH_SEED_BYTES
67 #error "__PERL_HASH_SEED_BYTES not defined"
68 #endif
69 #ifndef __PERL_HASH_FUNC
70 #error "__PERL_HASH_FUNC not defined"
71 #endif
72 
73 /* Some siphash static functions are needed by XS::APItest even when
74    siphash isn't the current hash.  For SipHash builds this needs to
75    be before the S_perl_hash_with_seed() definition.
76 */
77 #include "perl_siphash.h"
78 
79 #define __PERL_HASH_SEED_roundup(x, y)   ( ( ( (x) + ( (y) - 1 ) ) / (y) ) * (y) )
80 #define _PERL_HASH_SEED_roundup(x) __PERL_HASH_SEED_roundup(x,__PERL_HASH_WORD_SIZE)
81 
82 #define PL_hash_seed ((U8 *)PL_hash_seed_w)
83 #define PL_hash_state ((U8 *)PL_hash_state_w)
84 
85 #if PERL_HASH_USE_SBOX32_ALSO != 1
86 # define _PERL_HASH_FUNC                        __PERL_HASH_FUNC
87 # define _PERL_HASH_SEED_BYTES                  __PERL_HASH_SEED_BYTES
88 # define _PERL_HASH_STATE_BYTES                 __PERL_HASH_STATE_BYTES
89 # define _PERL_HASH_SEED_STATE(seed,state)      __PERL_HASH_SEED_STATE(seed,state)
90 # define _PERL_HASH_WITH_STATE(state,str,len)   __PERL_HASH_WITH_STATE(state,str,len)
91 #else
92 
93 #define _PERL_HASH_FUNC         "SBOX32_WITH_" __PERL_HASH_FUNC
94 /* note the 4 in the below code comes from the fact the seed to initialize the SBOX is 128 bits */
95 #define _PERL_HASH_SEED_BYTES   ( __PERL_HASH_SEED_BYTES + (int)( 4 * sizeof(U32)) )
96 
97 #define _PERL_HASH_STATE_BYTES  \
98     ( __PERL_HASH_STATE_BYTES + ( ( 1 + ( 256 * SBOX32_MAX_LEN ) ) * sizeof(U32) ) )
99 
100 #define _PERL_HASH_SEED_STATE(seed,state) STMT_START {                                      \
101     __PERL_HASH_SEED_STATE(seed,state);                                                     \
102     sbox32_seed_state128(seed + __PERL_HASH_SEED_BYTES, state + __PERL_HASH_STATE_BYTES);    \
103 } STMT_END
104 
105 #define _PERL_HASH_WITH_STATE(state,str,len)                                            \
106     (LIKELY(len <= SBOX32_MAX_LEN)                                                      \
107         ? sbox32_hash_with_state((state + __PERL_HASH_STATE_BYTES),(U8*)(str),(len))    \
108         : __PERL_HASH_WITH_STATE((state),(str),(len)))
109 
110 #endif
111 
112 #define PERL_HASH_WITH_SEED(seed,hash,str,len) \
113     (hash) = S_perl_hash_with_seed((const U8 *) seed, (const U8 *) str,len)
114 #define PERL_HASH_WITH_STATE(state,hash,str,len) \
115     (hash) = _PERL_HASH_WITH_STATE((state),(U8*)(str),(len))
116 
117 #define PERL_HASH_SEED_STATE(seed,state) _PERL_HASH_SEED_STATE(seed,state)
118 #define PERL_HASH_SEED_BYTES _PERL_HASH_SEED_roundup(_PERL_HASH_SEED_BYTES)
119 #define PERL_HASH_STATE_BYTES _PERL_HASH_SEED_roundup(_PERL_HASH_STATE_BYTES)
120 #define PERL_HASH_FUNC        _PERL_HASH_FUNC
121 
122 #define PERL_HASH_SEED_WORDS (PERL_HASH_SEED_BYTES/__PERL_HASH_WORD_SIZE)
123 #define PERL_HASH_STATE_WORDS (PERL_HASH_STATE_BYTES/__PERL_HASH_WORD_SIZE)
124 
125 #ifdef PERL_USE_SINGLE_CHAR_HASH_CACHE
126 #define PERL_HASH(state,str,len) \
127     (hash) = ((len) < 2 ? ( (len) == 0 ? PL_hash_chars[256] : PL_hash_chars[(U8)(str)[0]] ) \
128                        : _PERL_HASH_WITH_STATE(PL_hash_state,(U8*)(str),(len)))
129 #else
130 #define PERL_HASH(hash,str,len) \
131     PERL_HASH_WITH_STATE(PL_hash_state,hash,(U8*)(str),(len))
132 #endif
133 
134 /* Setup the hash seed, either we do things dynamically at start up,
135  * including reading from the environment, or we randomly setup the
136  * seed. The seed will be passed into the PERL_HASH_SEED_STATE() function
137  * defined for the configuration defined for this perl, which will then
138  * initialize whatever state it might need later in hashing. */
139 
140 #ifndef PERL_HASH_SEED
141 #   if defined(USE_HASH_SEED)
142 #       define PERL_HASH_SEED PL_hash_seed
143 #   else
144        /* this is a 512 bit seed, which should be more than enough for the
145         * configuration of any of our hash functions (with or without sbox).
146         * If you actually use a hard coded seed, you are strongly encouraged
147         * to replace this with something else of the correct length
148         * for the hash function you are using (24-32 bytes depending on build
149         * options). Repeat, you are *STRONGLY* encouraged not to use the value
150         * provided here.
151         */
152 #       define PERL_HASH_SEED \
153            ((const U8 *)"A long string of pseudorandomly "  \
154                         "chosen bytes for hashing in Perl")
155 #   endif
156 #endif
157 
158 /* legacy - only mod_perl should be doing this.  */
159 #ifdef PERL_HASH_INTERNAL_ACCESS
160 #define PERL_HASH_INTERNAL(hash,str,len) PERL_HASH(hash,str,len)
161 #endif
162 
163 PERL_STATIC_INLINE U32
164 S_perl_hash_with_seed(const U8 * seed, const U8 *str, STRLEN len) {
165     __PERL_HASH_WORD_TYPE state[PERL_HASH_STATE_WORDS];
166     _PERL_HASH_SEED_STATE(seed,(U8*)state);
167     return _PERL_HASH_WITH_STATE((U8*)state,str,len);
168 }
169 
170 #endif /*compile once*/
171 
172 /*
173  * ex: set ts=8 sts=4 sw=4 et:
174  */
175