Line data Source code
1 : #include "../burp.h"
2 : #include "blk.h"
3 : #include "../alloc.h"
4 : #include "../hexmap.h"
5 : #include "../iobuf.h"
6 : #include "../log.h"
7 : #include "../protocol2/rabin/rabin.h"
8 : #include "rabin/rconf.h"
9 :
10 226364 : struct blk *blk_alloc(void)
11 : {
12 226383 : return (struct blk *)calloc_w(1, sizeof(struct blk), __func__);
13 : }
14 :
15 19 : struct blk *blk_alloc_with_data(uint32_t max_data_length)
16 : {
17 19 : struct blk *blk=NULL;
18 19 : if(!(blk=blk_alloc())) return NULL;
19 19 : if((blk->data=(char *)
20 19 : calloc_w(1, sizeof(char)*max_data_length, __func__)))
21 19 : return blk;
22 0 : blk_free(&blk);
23 0 : return NULL;
24 : }
25 :
26 14 : void blk_free_content(struct blk *blk)
27 : {
28 226411 : if(!blk) return;
29 226397 : free_w(&blk->data);
30 : }
31 :
32 226390 : void blk_free(struct blk **blk)
33 : {
34 452780 : if(!blk || !*blk) return;
35 226383 : blk_free_content(*blk);
36 226383 : free_v((void **)blk);
37 : }
38 :
39 19 : static int md5_generation(uint8_t md5sum[], const char *data, uint32_t length)
40 : {
41 : MD5_CTX md5;
42 38 : if(!MD5_Init(&md5)
43 19 : || !MD5_Update(&md5, data, length)
44 38 : || !MD5_Final(md5sum, &md5))
45 : {
46 0 : logp("MD5 generation failed.\n");
47 0 : return -1;
48 : }
49 : return 0;
50 : }
51 :
52 19 : int blk_md5_update(struct blk *blk)
53 : {
54 19 : return md5_generation(blk->md5sum, blk->data, blk->length);
55 : }
56 :
57 24072 : int blk_is_zero_length(struct blk *blk)
58 : {
59 24072 : return !blk->fingerprint // All zeroes.
60 24072 : && !memcmp(blk->md5sum, md5sum_of_empty_string, MD5_DIGEST_LENGTH);
61 : }
62 :
63 0 : int blk_verify(struct blk *blk)
64 : {
65 : uint8_t md5sum[MD5_DIGEST_LENGTH];
66 : // Check rabin fingerprint.
67 0 : switch(blk_read_verify(blk))
68 : {
69 : case 1: break; // Match.
70 : case 0: return 0; // Did not match.
71 0 : default: return -1;
72 : }
73 : // Check md5sum.
74 0 : if(md5_generation(md5sum, blk->data, blk->length))
75 : return -1;
76 0 : if(!memcmp(md5sum, blk->md5sum, MD5_DIGEST_LENGTH)) return 1;
77 0 : return 0;
78 : }
79 :
80 : #define HOOK_MASK 0xF000000000000000
81 :
82 39022 : int blk_fingerprint_is_hook(struct blk *blk)
83 : {
84 39022 : return (blk->fingerprint&HOOK_MASK)==HOOK_MASK;
85 : }
86 :
87 : #define ETOH le64toh
88 : #define HTOE htole64
89 : // Can set it the other way round to test that endian logic works, but for
90 : // real use we will always be going host->little little->host.
91 : //#define ETOH be64toh
92 : //#define HTOE htobe64
93 :
94 : static void set_fingerprint(struct blk *blk, struct iobuf *iobuf)
95 : {
96 71320 : blk->fingerprint=ETOH(*(uint64_t *)iobuf->buf);
97 : }
98 :
99 141048 : static void set_sig(struct blk *blk, struct iobuf *iobuf)
100 : {
101 141048 : set_fingerprint(blk, iobuf);
102 70524 : memcpy(blk->md5sum, iobuf->buf+8, 8);
103 70524 : memcpy(blk->md5sum+8, iobuf->buf+16, 8);
104 70524 : }
105 :
106 : static void set_savepath(struct blk *blk, struct iobuf *iobuf, size_t offset)
107 : {
108 58048 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+offset));
109 : }
110 :
111 24073 : int blk_set_from_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
112 : {
113 24073 : if(iobuf->len!=24)
114 : {
115 1 : logp("Signature wrong length: %u!=24\n", iobuf->len);
116 1 : return -1;
117 : }
118 24072 : set_sig(blk, iobuf);
119 24072 : return 0;
120 : }
121 :
122 92904 : int blk_set_from_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
123 : {
124 46452 : if(iobuf->len!=32)
125 : {
126 : logp("Signature with save_path wrong length: %u!=32\n",
127 0 : iobuf->len);
128 0 : return -1;
129 : }
130 46452 : set_sig(blk, iobuf);
131 92904 : set_savepath(blk, iobuf, 24 /* offset */);
132 46452 : return 0;
133 : }
134 :
135 1592 : int blk_set_from_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
136 : {
137 796 : if(iobuf->len!=sizeof(blk->fingerprint))
138 : {
139 : logp("Fingerprint wrong length: %u!=%u\n",
140 0 : iobuf->len, sizeof(blk->fingerprint));
141 0 : return -1;
142 : }
143 1592 : set_fingerprint(blk, iobuf);
144 796 : return 0;
145 : }
146 :
147 23192 : int blk_set_from_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
148 : {
149 11596 : if(iobuf->len!=sizeof(blk->savepath))
150 : {
151 : logp("Save path wrong length: %u!=%u\n",
152 0 : iobuf->len, sizeof(blk->savepath));
153 0 : return -1;
154 : }
155 23192 : set_savepath(blk, iobuf, 0 /* offset */);
156 11596 : return 0;
157 : }
158 :
159 9984 : int blk_set_from_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
160 : {
161 9984 : if(iobuf->len!=16)
162 : {
163 : logp("File number and savepath with wrong length: %u!=%u\n",
164 0 : iobuf->len, 16);
165 0 : return -1;
166 : }
167 9984 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
168 9984 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+8));
169 9984 : return 0;
170 : }
171 :
172 9992 : int blk_set_from_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
173 : {
174 9992 : if(iobuf->len!=sizeof(blk->index))
175 : {
176 : logp("Wrap up with wrong length: %u!=%u\n",
177 0 : iobuf->len, sizeof(blk->index));
178 0 : return -1;
179 : }
180 9992 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
181 9992 : return 0;
182 : }
183 :
184 54009 : void blk_to_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
185 : {
186 : static union { char c[24]; uint64_t v[3]; } buf;
187 54009 : buf.v[0]=HTOE(blk->fingerprint);
188 54009 : memcpy(&buf.c[8], blk->md5sum, 8);
189 54009 : memcpy(&buf.c[16], blk->md5sum+8, 8);
190 54009 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
191 54009 : }
192 :
193 182466 : void blk_to_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
194 : {
195 : static union { char c[32]; uint64_t v[4]; } buf;
196 182466 : buf.v[0]=HTOE(blk->fingerprint);
197 182466 : memcpy(&buf.c[8], blk->md5sum, 8);
198 182466 : memcpy(&buf.c[16], blk->md5sum+8, 8);
199 182466 : buf.v[3]=HTOE(blk->savepath);
200 182466 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
201 182466 : }
202 :
203 : static void to_iobuf_uint64(struct iobuf *iobuf, enum cmd cmd, uint64_t val)
204 : {
205 : static union { char c[8]; uint64_t v; } buf;
206 46963 : buf.v=HTOE(val);
207 46963 : iobuf_set(iobuf, cmd, buf.c, sizeof(buf));
208 : }
209 :
210 0 : void blk_to_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
211 : {
212 0 : to_iobuf_uint64(iobuf, CMD_FINGERPRINT, blk->fingerprint);
213 0 : }
214 :
215 34706 : void blk_to_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
216 : {
217 34706 : to_iobuf_uint64(iobuf, CMD_SAVE_PATH, blk->savepath);
218 34706 : }
219 :
220 9984 : void blk_to_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
221 : {
222 : static union { char c[16]; uint64_t v[2]; } buf;
223 9984 : buf.v[0]=HTOE(blk->index);
224 9984 : buf.v[1]=HTOE(blk->savepath);
225 9984 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
226 9984 : }
227 :
228 9992 : void blk_to_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
229 : {
230 9992 : to_iobuf_uint64(iobuf, CMD_WRAP_UP, blk->index);
231 9992 : }
232 :
233 2265 : int to_fzp_fingerprint(struct fzp *fzp, uint64_t fingerprint)
234 : {
235 : static struct iobuf wbuf;
236 : to_iobuf_uint64(&wbuf, CMD_FINGERPRINT, fingerprint);
237 2265 : return iobuf_send_msg_fzp(&wbuf, fzp);
238 : }
|