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 231455 : struct blk *blk_alloc(void)
11 : {
12 231474 : 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 231502 : if(!blk) return;
29 231488 : free_w(&blk->data);
30 : }
31 :
32 231484 : void blk_free(struct blk **blk)
33 : {
34 462968 : if(!blk || !*blk) return;
35 231474 : blk_free_content(*blk);
36 231474 : 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 29154 : int blk_is_zero_length(struct blk *blk)
58 : {
59 29154 : return !blk->fingerprint // All zeroes.
60 29154 : && !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 0xF000000000000000ULL
81 :
82 39542 : int blk_fingerprint_is_hook(struct blk *blk)
83 : {
84 39542 : 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 76912 : blk->fingerprint=ETOH(*(uint64_t *)iobuf->buf);
97 : }
98 :
99 151232 : static void set_sig(struct blk *blk, struct iobuf *iobuf)
100 : {
101 151232 : set_fingerprint(blk, iobuf);
102 75616 : memcpy(blk->md5sum, iobuf->buf+8, 8);
103 75616 : memcpy(blk->md5sum+8, iobuf->buf+16, 8);
104 75616 : }
105 :
106 : static void set_savepath(struct blk *blk, struct iobuf *iobuf, size_t offset)
107 : {
108 58373 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+offset));
109 : }
110 :
111 29155 : int blk_set_from_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
112 : {
113 29155 : if(iobuf->len!=24)
114 : {
115 : logp("Signature wrong length: %lu!=24\n",
116 1 : (unsigned long)iobuf->len);
117 1 : return -1;
118 : }
119 29154 : set_sig(blk, iobuf);
120 29154 : return 0;
121 : }
122 :
123 92924 : int blk_set_from_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
124 : {
125 46462 : if(iobuf->len!=32)
126 : {
127 : logp("Signature with save_path wrong length: %lu!=32\n",
128 0 : (unsigned long)iobuf->len);
129 0 : return -1;
130 : }
131 46462 : set_sig(blk, iobuf);
132 92924 : set_savepath(blk, iobuf, 24 /* offset */);
133 46462 : return 0;
134 : }
135 :
136 2592 : int blk_set_from_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
137 : {
138 1296 : if(iobuf->len!=sizeof(blk->fingerprint))
139 : {
140 : logp("Fingerprint wrong length: %lu!=%lu\n",
141 : (unsigned long)iobuf->len,
142 0 : (unsigned long)sizeof(blk->fingerprint));
143 0 : return -1;
144 : }
145 2592 : set_fingerprint(blk, iobuf);
146 1296 : return 0;
147 : }
148 :
149 23822 : int blk_set_from_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
150 : {
151 11911 : if(iobuf->len!=sizeof(blk->savepath))
152 : {
153 : logp("Save path wrong length: %lu!=%lu\n",
154 : (unsigned long)iobuf->len,
155 0 : (unsigned long)sizeof(blk->savepath));
156 0 : return -1;
157 : }
158 23822 : set_savepath(blk, iobuf, 0 /* offset */);
159 11911 : return 0;
160 : }
161 :
162 12524 : int blk_set_from_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
163 : {
164 12524 : if(iobuf->len!=16)
165 : {
166 : logp("File number and savepath with wrong length: %lu!=16\n",
167 0 : (unsigned long)iobuf->len);
168 0 : return -1;
169 : }
170 12524 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
171 12524 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+8));
172 12524 : return 0;
173 : }
174 :
175 12534 : int blk_set_from_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
176 : {
177 12534 : if(iobuf->len!=sizeof(blk->index))
178 : {
179 : logp("Wrap up with wrong length: %lu!=%lu\n",
180 : (unsigned long)iobuf->len,
181 0 : (unsigned long)sizeof(blk->index));
182 0 : return -1;
183 : }
184 12534 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
185 12534 : return 0;
186 : }
187 :
188 67687 : void blk_to_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
189 : {
190 : static union { char c[24]; uint64_t v[3]; } buf;
191 67687 : buf.v[0]=HTOE(blk->fingerprint);
192 67687 : memcpy(&buf.c[8], blk->md5sum, 8);
193 67687 : memcpy(&buf.c[16], blk->md5sum+8, 8);
194 67687 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
195 67687 : }
196 :
197 187558 : void blk_to_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
198 : {
199 : static union { char c[32]; uint64_t v[4]; } buf;
200 187558 : buf.v[0]=HTOE(blk->fingerprint);
201 187558 : memcpy(&buf.c[8], blk->md5sum, 8);
202 187558 : memcpy(&buf.c[16], blk->md5sum+8, 8);
203 187558 : buf.v[3]=HTOE(blk->savepath);
204 187558 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
205 187558 : }
206 :
207 : static void to_iobuf_uint64(struct iobuf *iobuf, enum cmd cmd, uint64_t val)
208 : {
209 : static union { char c[8]; uint64_t v; } buf;
210 50353 : buf.v=HTOE(val);
211 50353 : iobuf_set(iobuf, cmd, buf.c, sizeof(buf));
212 : }
213 :
214 0 : void blk_to_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
215 : {
216 0 : to_iobuf_uint64(iobuf, CMD_FINGERPRINT, blk->fingerprint);
217 0 : }
218 :
219 35054 : void blk_to_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
220 : {
221 35054 : to_iobuf_uint64(iobuf, CMD_SAVE_PATH, blk->savepath);
222 35054 : }
223 :
224 12524 : void blk_to_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
225 : {
226 : static union { char c[16]; uint64_t v[2]; } buf;
227 12524 : buf.v[0]=HTOE(blk->index);
228 12524 : buf.v[1]=HTOE(blk->savepath);
229 12524 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
230 12524 : }
231 :
232 12534 : void blk_to_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
233 : {
234 12534 : to_iobuf_uint64(iobuf, CMD_WRAP_UP, blk->index);
235 12534 : }
236 :
237 2765 : int to_fzp_fingerprint(struct fzp *fzp, uint64_t fingerprint)
238 : {
239 : static struct iobuf wbuf;
240 : to_iobuf_uint64(&wbuf, CMD_FINGERPRINT, fingerprint);
241 2765 : return iobuf_send_msg_fzp(&wbuf, fzp);
242 : }
|