xref: /isa-l_crypto/rolling_hash/rolling_hash2.c (revision 37c1320fef459b6ac01a1fae6f17aa16f54f55fb)
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_hash2_table.h"
34 #include "isal_crypto_api.h"
35 
36 extern uint64_t
37 rolling_hash2_run_until(uint32_t *idx, int max_idx, uint64_t *t1, uint64_t *t2, uint8_t *b1,
38                         uint8_t *b2, uint64_t h, uint64_t mask, uint64_t trigger);
39 
40 int
41 rolling_hash2_init(struct rh_state2 *state, uint32_t w)
42 {
43         uint32_t i;
44         uint64_t v;
45 
46         if (w > FINGERPRINT_MAX_WINDOW)
47                 return -1;
48 
49         for (i = 0; i < 256; i++) {
50                 v = rolling_hash2_table1[i];
51                 state->table1[i] = v;
52                 state->table2[i] = (v << w) | (v >> (64 - w));
53         }
54         state->w = w;
55         return 0;
56 }
57 
58 void
59 rolling_hash2_reset(struct rh_state2 *state, uint8_t *init_bytes)
60 {
61         uint64_t hash;
62         uint32_t i, w;
63 
64         hash = 0;
65         w = state->w;
66         for (i = 0; i < w; i++) {
67                 hash = (hash << 1) | (hash >> (64 - 1));
68                 hash ^= state->table1[init_bytes[i]];
69         }
70         state->hash = hash;
71         memcpy(state->history, init_bytes, w);
72 }
73 
74 static uint64_t
75 hash_fn(struct rh_state2 *state, uint64_t h, uint8_t new_char, uint8_t old_char)
76 {
77         h = (h << 1) | (h >> (64 - 1));
78         h ^= state->table1[new_char] ^ state->table2[old_char];
79         return h;
80 }
81 
82 uint64_t
83 rolling_hash2_run_until_base(uint32_t *idx, int max_idx, uint64_t *t1, uint64_t *t2, uint8_t *b1,
84                              uint8_t *b2, uint64_t h, uint64_t mask, uint64_t trigger)
85 {
86         int i = *idx;
87 
88         if (trigger == 0) {
89                 for (; i < max_idx; i++) {
90                         h = (h << 1) | (h >> (64 - 1));
91                         h ^= t1[b1[i]] ^ t2[b2[i]];
92                         if ((h & mask) == 0) {
93                                 *idx = i;
94                                 return h;
95                         }
96                 }
97         } else {
98                 for (; i < max_idx; i++) {
99                         h = (h << 1) | (h >> (64 - 1));
100                         h ^= t1[b1[i]] ^ t2[b2[i]];
101                         if ((h & mask) == trigger) {
102                                 *idx = i;
103                                 return h;
104                         }
105                 }
106         }
107         *idx = i;
108         return h;
109 }
110 
111 int
112 rolling_hash2_run(struct rh_state2 *state, uint8_t *buffer, uint32_t buffer_length, uint32_t mask,
113                   uint32_t trigger, uint32_t *offset)
114 {
115 
116         uint32_t i;
117         uint32_t w = state->w;
118         uint64_t hash = state->hash;
119 
120         for (i = 0; i < w; i++) {
121                 if (i == buffer_length) {
122                         *offset = i;
123                         // update history
124                         memmove(state->history, state->history + i, w - i);
125                         memcpy(state->history + w - i, buffer, i);
126                         state->hash = hash;
127                         return FINGERPRINT_RET_MAX;
128                 }
129                 hash = hash_fn(state, hash, buffer[i], state->history[i]);
130 
131                 if ((hash & mask) == trigger) {
132                         // found hit
133                         i++;
134                         *offset = i;
135                         memmove(state->history, state->history + i, w - i);
136                         memcpy(state->history + w - i, buffer, i);
137                         state->hash = hash;
138                         return FINGERPRINT_RET_HIT;
139                 }
140         }
141 
142         hash = rolling_hash2_run_until(&i, buffer_length, state->table1, state->table2, buffer,
143                                        buffer - w, hash, mask, trigger);
144         if ((hash & mask) == trigger) {
145                 // found hit
146                 i++;
147                 *offset = i;
148                 memcpy(state->history, buffer + i - w, w);
149                 state->hash = hash;
150                 return FINGERPRINT_RET_HIT;
151         }
152         // no hit
153         *offset = i;
154         memcpy(state->history, buffer + i - w, w);
155         state->hash = hash;
156         return FINGERPRINT_RET_MAX;
157 }
158 
159 int
160 isal_rolling_hash2_init(struct rh_state2 *state, const uint32_t w)
161 {
162 #ifdef SAFE_PARAM
163         if (state == NULL)
164                 return ISAL_CRYPTO_ERR_NULL_CTX;
165 #endif
166         if (rolling_hash2_init(state, w) < 0)
167                 return ISAL_CRYPTO_ERR_WINDOW_SIZE;
168 
169         return 0;
170 }
171 
172 int
173 isal_rolling_hash2_reset(struct rh_state2 *state, const uint8_t *init_bytes)
174 {
175 #ifdef SAFE_PARAM
176         if (state == NULL)
177                 return ISAL_CRYPTO_ERR_NULL_CTX;
178         if (init_bytes == NULL)
179                 return ISAL_CRYPTO_ERR_HASH_INIT_VAL;
180 #endif
181         rolling_hash2_reset(state, (uint8_t *) init_bytes);
182 
183         return 0;
184 }
185 
186 int
187 isal_rolling_hash2_run(struct rh_state2 *state, const uint8_t *buffer, const uint32_t max_len,
188                        const uint32_t mask, const uint32_t trigger, uint32_t *offset, int *match)
189 {
190 #ifdef SAFE_PARAM
191         if (state == NULL)
192                 return ISAL_CRYPTO_ERR_NULL_CTX;
193         if (buffer == NULL)
194                 return ISAL_CRYPTO_ERR_NULL_SRC;
195         if (offset == NULL)
196                 return ISAL_CRYPTO_ERR_NULL_OFFSET;
197         if (match == NULL)
198                 return ISAL_CRYPTO_ERR_NULL_MATCH;
199 #endif
200         *match = rolling_hash2_run(state, (uint8_t *) buffer, max_len, mask, trigger, offset);
201 
202         return 0;
203 }
204 
205 int
206 isal_rolling_hashx_mask_gen(const uint32_t mean, const uint32_t shift, uint32_t *mask)
207 {
208 #ifdef SAFE_PARAM
209         if (mask == NULL)
210                 return ISAL_CRYPTO_ERR_NULL_MASK;
211 #endif
212         *mask = rolling_hashx_mask_gen((long) mean, (int) shift);
213 
214         return 0;
215 }
216 
217 struct slver {
218         uint16_t snum;
219         uint8_t ver;
220         uint8_t core;
221 };
222 struct slver rolling_hash2_init_slver_00000264;
223 struct slver rolling_hash2_init_slver = { 0x0264, 0x00, 0x00 };
224 
225 struct slver rolling_hash2_reset_slver_00000265;
226 struct slver rolling_hash2_reset_slver = { 0x0265, 0x00, 0x00 };
227 
228 struct slver rolling_hash2_run_slver_00000266;
229 struct slver rolling_hash2_run_slver = { 0x0266, 0x00, 0x00 };
230