1 /**********************************************************************
2 Copyright(c) 2011-2017 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include "rolling_hashx.h"
33 #include "rolling_hashx_internal.h"
34 #include "rolling_hash2_table.h"
35 #include "isal_crypto_api.h"
36
37 extern uint64_t
38 _rolling_hash2_run_until(uint32_t *idx, int max_idx, uint64_t *t1, uint64_t *t2, uint8_t *b1,
39 uint8_t *b2, uint64_t h, uint64_t mask, uint64_t trigger);
40
41 int
_rolling_hash2_init(struct isal_rh_state2 * state,uint32_t w)42 _rolling_hash2_init(struct isal_rh_state2 *state, uint32_t w)
43 {
44 uint32_t i;
45 uint64_t v;
46
47 if (w > ISAL_FINGERPRINT_MAX_WINDOW)
48 return -1;
49
50 for (i = 0; i < 256; i++) {
51 v = rolling_hash2_table1[i];
52 state->table1[i] = v;
53 state->table2[i] = (v << w) | (v >> (64 - w));
54 }
55 state->w = w;
56 return 0;
57 }
58
59 void
_rolling_hash2_reset(struct isal_rh_state2 * state,uint8_t * init_bytes)60 _rolling_hash2_reset(struct isal_rh_state2 *state, uint8_t *init_bytes)
61 {
62 uint64_t hash;
63 uint32_t i, w;
64
65 hash = 0;
66 w = state->w;
67 for (i = 0; i < w; i++) {
68 hash = (hash << 1) | (hash >> (64 - 1));
69 hash ^= state->table1[init_bytes[i]];
70 }
71 state->hash = hash;
72 memcpy(state->history, init_bytes, w);
73 }
74
75 static uint64_t
hash_fn(struct isal_rh_state2 * state,uint64_t h,uint8_t new_char,uint8_t old_char)76 hash_fn(struct isal_rh_state2 *state, uint64_t h, uint8_t new_char, uint8_t old_char)
77 {
78 h = (h << 1) | (h >> (64 - 1));
79 h ^= state->table1[new_char] ^ state->table2[old_char];
80 return h;
81 }
82
83 uint64_t
_rolling_hash2_run_until_base(uint32_t * idx,int max_idx,uint64_t * t1,uint64_t * t2,uint8_t * b1,uint8_t * b2,uint64_t h,uint64_t mask,uint64_t trigger)84 _rolling_hash2_run_until_base(uint32_t *idx, int max_idx, uint64_t *t1, uint64_t *t2, uint8_t *b1,
85 uint8_t *b2, uint64_t h, uint64_t mask, uint64_t trigger)
86 {
87 int i = *idx;
88
89 if (trigger == 0) {
90 for (; i < max_idx; i++) {
91 h = (h << 1) | (h >> (64 - 1));
92 h ^= t1[b1[i]] ^ t2[b2[i]];
93 if ((h & mask) == 0) {
94 *idx = i;
95 return h;
96 }
97 }
98 } else {
99 for (; i < max_idx; i++) {
100 h = (h << 1) | (h >> (64 - 1));
101 h ^= t1[b1[i]] ^ t2[b2[i]];
102 if ((h & mask) == trigger) {
103 *idx = i;
104 return h;
105 }
106 }
107 }
108 *idx = i;
109 return h;
110 }
111
112 int
_rolling_hash2_run(struct isal_rh_state2 * state,uint8_t * buffer,uint32_t buffer_length,uint32_t mask,uint32_t trigger,uint32_t * offset)113 _rolling_hash2_run(struct isal_rh_state2 *state, uint8_t *buffer, uint32_t buffer_length,
114 uint32_t mask, uint32_t trigger, uint32_t *offset)
115 {
116
117 uint32_t i;
118 uint32_t w = state->w;
119 uint64_t hash = state->hash;
120
121 for (i = 0; i < w; i++) {
122 if (i == buffer_length) {
123 *offset = i;
124 // update history
125 memmove(state->history, state->history + i, w - i);
126 memcpy(state->history + w - i, buffer, i);
127 state->hash = hash;
128 return ISAL_FINGERPRINT_RET_MAX;
129 }
130 hash = hash_fn(state, hash, buffer[i], state->history[i]);
131
132 if ((hash & mask) == trigger) {
133 // found hit
134 i++;
135 *offset = i;
136 memmove(state->history, state->history + i, w - i);
137 memcpy(state->history + w - i, buffer, i);
138 state->hash = hash;
139 return ISAL_FINGERPRINT_RET_HIT;
140 }
141 }
142
143 hash = _rolling_hash2_run_until(&i, buffer_length, state->table1, state->table2, buffer,
144 buffer - w, hash, mask, trigger);
145 if ((hash & mask) == trigger) {
146 // found hit
147 i++;
148 *offset = i;
149 memcpy(state->history, buffer + i - w, w);
150 state->hash = hash;
151 return ISAL_FINGERPRINT_RET_HIT;
152 }
153 // no hit
154 *offset = i;
155 memcpy(state->history, buffer + i - w, w);
156 state->hash = hash;
157 return ISAL_FINGERPRINT_RET_MAX;
158 }
159
160 int
isal_rolling_hash2_init(struct isal_rh_state2 * state,const uint32_t w)161 isal_rolling_hash2_init(struct isal_rh_state2 *state, const uint32_t w)
162 {
163 #ifdef FIPS_MODE
164 return ISAL_CRYPTO_ERR_FIPS_INVALID_ALGO;
165 #else
166 #ifdef SAFE_PARAM
167 if (state == NULL)
168 return ISAL_CRYPTO_ERR_NULL_CTX;
169 #endif
170 if (_rolling_hash2_init(state, w) < 0)
171 return ISAL_CRYPTO_ERR_WINDOW_SIZE;
172
173 return 0;
174 #endif
175 }
176
177 int
isal_rolling_hash2_reset(struct isal_rh_state2 * state,const uint8_t * init_bytes)178 isal_rolling_hash2_reset(struct isal_rh_state2 *state, const uint8_t *init_bytes)
179 {
180 #ifdef FIPS_MODE
181 return ISAL_CRYPTO_ERR_FIPS_INVALID_ALGO;
182 #else
183 #ifdef SAFE_PARAM
184 if (state == NULL)
185 return ISAL_CRYPTO_ERR_NULL_CTX;
186 if (init_bytes == NULL)
187 return ISAL_CRYPTO_ERR_NULL_INIT_VAL;
188 #endif
189 _rolling_hash2_reset(state, (uint8_t *) init_bytes);
190
191 return 0;
192 #endif
193 }
194
195 int
isal_rolling_hash2_run(struct isal_rh_state2 * state,const uint8_t * buffer,const uint32_t max_len,const uint32_t mask,const uint32_t trigger,uint32_t * offset,int * match)196 isal_rolling_hash2_run(struct isal_rh_state2 *state, const uint8_t *buffer, const uint32_t max_len,
197 const uint32_t mask, const uint32_t trigger, uint32_t *offset, int *match)
198 {
199 #ifdef FIPS_MODE
200 return ISAL_CRYPTO_ERR_FIPS_INVALID_ALGO;
201 #else
202 #ifdef SAFE_PARAM
203 if (state == NULL)
204 return ISAL_CRYPTO_ERR_NULL_CTX;
205 if (buffer == NULL)
206 return ISAL_CRYPTO_ERR_NULL_SRC;
207 if (offset == NULL)
208 return ISAL_CRYPTO_ERR_NULL_OFFSET;
209 if (match == NULL)
210 return ISAL_CRYPTO_ERR_NULL_MATCH;
211 #endif
212 *match = _rolling_hash2_run(state, (uint8_t *) buffer, max_len, mask, trigger, offset);
213
214 return 0;
215 #endif
216 }
217
218 int
isal_rolling_hashx_mask_gen(const uint32_t mean,const uint32_t shift,uint32_t * mask)219 isal_rolling_hashx_mask_gen(const uint32_t mean, const uint32_t shift, uint32_t *mask)
220 {
221 #ifdef FIPS_MODE
222 return ISAL_CRYPTO_ERR_FIPS_INVALID_ALGO;
223 #else
224 #ifdef SAFE_PARAM
225 if (mask == NULL)
226 return ISAL_CRYPTO_ERR_NULL_MASK;
227 #endif
228 *mask = _rolling_hashx_mask_gen((long) mean, (int) shift);
229
230 return 0;
231 #endif
232 }
233
234 /*
235 * =============================================================================
236 * LEGACY / DEPRECATED API
237 * =============================================================================
238 */
239
240 int
rolling_hash2_init(struct isal_rh_state2 * state,uint32_t w)241 rolling_hash2_init(struct isal_rh_state2 *state, uint32_t w)
242 {
243 return _rolling_hash2_init(state, w);
244 }
245
246 void
rolling_hash2_reset(struct isal_rh_state2 * state,uint8_t * init_bytes)247 rolling_hash2_reset(struct isal_rh_state2 *state, uint8_t *init_bytes)
248 {
249 _rolling_hash2_reset(state, init_bytes);
250 }
251
252 int
rolling_hash2_run(struct isal_rh_state2 * state,uint8_t * buffer,uint32_t max_len,uint32_t mask,uint32_t trigger,uint32_t * offset)253 rolling_hash2_run(struct isal_rh_state2 *state, uint8_t *buffer, uint32_t max_len, uint32_t mask,
254 uint32_t trigger, uint32_t *offset)
255 {
256 return _rolling_hash2_run(state, buffer, max_len, mask, trigger, offset);
257 }
258
259 uint32_t
rolling_hashx_mask_gen(long mean,int shift)260 rolling_hashx_mask_gen(long mean, int shift)
261 {
262 return _rolling_hashx_mask_gen(mean, shift);
263 }
264
265 struct slver {
266 uint16_t snum;
267 uint8_t ver;
268 uint8_t core;
269 };
270 struct slver _rolling_hash2_init_slver_00000264;
271 struct slver _rolling_hash2_init_slver = { 0x0264, 0x00, 0x00 };
272
273 struct slver _rolling_hash2_reset_slver_00000265;
274 struct slver _rolling_hash2_reset_slver = { 0x0265, 0x00, 0x00 };
275
276 struct slver _rolling_hash2_run_slver_00000266;
277 struct slver _rolling_hash2_run_slver = { 0x0266, 0x00, 0x00 };
278