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 235807 : struct blk *blk_alloc(void)
11 : {
12 235831 : return (struct blk *)calloc_w(1, sizeof(struct blk), __func__);
13 : }
14 :
15 24 : struct blk *blk_alloc_with_data(uint32_t max_data_length)
16 : {
17 24 : struct blk *blk=NULL;
18 24 : if(!(blk=blk_alloc())
19 22 : || !(blk->data=(char *)
20 22 : calloc_w(1, sizeof(char)*max_data_length, __func__)))
21 : goto end;
22 22 : return blk;
23 : end:
24 2 : blk_free(&blk);
25 2 : return NULL;
26 : }
27 :
28 14 : void blk_free_content(struct blk *blk)
29 : {
30 235857 : if(!blk) return;
31 235843 : free_w(&blk->data);
32 : }
33 :
34 235879 : void blk_free(struct blk **blk)
35 : {
36 471758 : if(!blk || !*blk) return;
37 235829 : blk_free_content(*blk);
38 235829 : free_v((void **)blk);
39 : }
40 :
41 21 : static int md5_generation(uint8_t md5sum[], const char *data, uint32_t length)
42 : {
43 : MD5_CTX md5;
44 21 : if(!MD5_Init(&md5)
45 21 : || !MD5_Update(&md5, data, length)
46 21 : || !MD5_Final(md5sum, &md5))
47 : {
48 0 : logp("MD5 generation failed.\n");
49 0 : return -1;
50 : }
51 : return 0;
52 : }
53 :
54 19 : int blk_md5_update(struct blk *blk)
55 : {
56 19 : return md5_generation(blk->md5sum, blk->data, blk->length);
57 : }
58 :
59 29154 : int blk_is_zero_length(struct blk *blk)
60 : {
61 58308 : return !blk->fingerprint // All zeroes.
62 29154 : && !memcmp(blk->md5sum, md5sum_of_empty_string, MD5_DIGEST_LENGTH);
63 : }
64 :
65 3 : int blk_verify(uint64_t fingerprint, uint8_t *md5sum,
66 : char *data, size_t length)
67 : {
68 : uint8_t md5sum_new[MD5_DIGEST_LENGTH];
69 :
70 3 : switch(blk_verify_fingerprint(fingerprint, data, length))
71 : {
72 : case 1: break; // Match.
73 : case 0: return 0; // Did not match.
74 0 : default: return -1;
75 : }
76 :
77 2 : if(md5_generation(md5sum_new, data, length))
78 : return -1;
79 2 : if(!memcmp(md5sum_new, md5sum, MD5_DIGEST_LENGTH))
80 : return 1;
81 :
82 1 : return 0;
83 : }
84 :
85 : #define HOOK_MASK 0xF000000000000000ULL
86 :
87 39777 : int blk_fingerprint_is_hook(struct blk *blk)
88 : {
89 39777 : return (blk->fingerprint&HOOK_MASK)==HOOK_MASK;
90 : }
91 :
92 : #define ETOH le64toh
93 : #define HTOE htole64
94 : // Can set it the other way round to test that endian logic works, but for
95 : // real use we will always be going host->little little->host.
96 : //#define ETOH be64toh
97 : //#define HTOE htobe64
98 :
99 : static void set_fingerprint(struct blk *blk, struct iobuf *iobuf)
100 : {
101 77074 : blk->fingerprint=ETOH(*(uint64_t *)iobuf->buf);
102 : }
103 :
104 151232 : static void set_sig(struct blk *blk, struct iobuf *iobuf)
105 : {
106 151232 : set_fingerprint(blk, iobuf);
107 75616 : memcpy(blk->md5sum, iobuf->buf+8, 8);
108 75616 : memcpy(blk->md5sum+8, iobuf->buf+16, 8);
109 75616 : }
110 :
111 : static void set_savepath(struct blk *blk, struct iobuf *iobuf, size_t offset)
112 : {
113 58373 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+offset));
114 : }
115 :
116 29155 : int blk_set_from_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
117 : {
118 29155 : if(iobuf->len!=24)
119 : {
120 1 : logp("Signature wrong length: %lu!=24\n",
121 : (unsigned long)iobuf->len);
122 1 : return -1;
123 : }
124 29154 : set_sig(blk, iobuf);
125 29154 : return 0;
126 : }
127 :
128 92925 : int blk_set_from_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
129 : {
130 46463 : if(iobuf->len!=32)
131 : {
132 1 : logp("Signature with save_path wrong length: %lu!=32\n",
133 : (unsigned long)iobuf->len);
134 1 : return -1;
135 : }
136 46462 : set_sig(blk, iobuf);
137 92924 : set_savepath(blk, iobuf, 24 /* offset */);
138 46462 : return 0;
139 : }
140 :
141 2917 : int blk_set_from_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
142 : {
143 1459 : if(iobuf->len!=sizeof(blk->fingerprint))
144 : {
145 1 : logp("Fingerprint wrong length: %lu!=%lu\n",
146 : (unsigned long)iobuf->len,
147 : (unsigned long)sizeof(blk->fingerprint));
148 1 : return -1;
149 : }
150 2916 : set_fingerprint(blk, iobuf);
151 1458 : return 0;
152 : }
153 :
154 23823 : int blk_set_from_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
155 : {
156 11912 : if(iobuf->len!=sizeof(blk->savepath))
157 : {
158 1 : logp("Save path wrong length: %lu!=%lu\n",
159 : (unsigned long)iobuf->len,
160 : (unsigned long)sizeof(blk->savepath));
161 1 : return -1;
162 : }
163 23822 : set_savepath(blk, iobuf, 0 /* offset */);
164 11911 : return 0;
165 : }
166 :
167 12525 : int blk_set_from_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
168 : {
169 12525 : if(iobuf->len!=16)
170 : {
171 1 : logp("File number and savepath with wrong length: %lu!=16\n",
172 : (unsigned long)iobuf->len);
173 1 : return -1;
174 : }
175 12524 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
176 12524 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+8));
177 12524 : return 0;
178 : }
179 :
180 12535 : int blk_set_from_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
181 : {
182 12535 : if(iobuf->len!=sizeof(blk->index))
183 : {
184 1 : logp("Wrap up with wrong length: %lu!=%lu\n",
185 : (unsigned long)iobuf->len,
186 : (unsigned long)sizeof(blk->index));
187 1 : return -1;
188 : }
189 12534 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
190 12534 : return 0;
191 : }
192 :
193 67687 : void blk_to_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
194 : {
195 : static union { char c[24]; uint64_t v[3]; } buf;
196 67687 : buf.v[0]=HTOE(blk->fingerprint);
197 67687 : memcpy(&buf.c[8], blk->md5sum, 8);
198 67687 : memcpy(&buf.c[16], blk->md5sum+8, 8);
199 67687 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
200 67687 : }
201 :
202 187793 : void blk_to_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
203 : {
204 : static union { char c[32]; uint64_t v[4]; } buf;
205 187793 : buf.v[0]=HTOE(blk->fingerprint);
206 187793 : memcpy(&buf.c[8], blk->md5sum, 8);
207 187793 : memcpy(&buf.c[16], blk->md5sum+8, 8);
208 187793 : buf.v[3]=HTOE(blk->savepath);
209 187793 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
210 187793 : }
211 :
212 : static void to_iobuf_uint64(struct iobuf *iobuf, enum cmd cmd, uint64_t val)
213 : {
214 : static union { char c[8]; uint64_t v; } buf;
215 50762 : buf.v=HTOE(val);
216 50762 : iobuf_set(iobuf, cmd, buf.c, sizeof(buf));
217 : }
218 :
219 0 : void blk_to_iobuf_fingerprint(struct blk *blk, struct iobuf *iobuf)
220 : {
221 0 : to_iobuf_uint64(iobuf, CMD_FINGERPRINT, blk->fingerprint);
222 0 : }
223 :
224 35289 : void blk_to_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
225 : {
226 35289 : to_iobuf_uint64(iobuf, CMD_SAVE_PATH, blk->savepath);
227 35289 : }
228 :
229 12524 : void blk_to_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
230 : {
231 : static union { char c[16]; uint64_t v[2]; } buf;
232 12524 : buf.v[0]=HTOE(blk->index);
233 12524 : buf.v[1]=HTOE(blk->savepath);
234 12524 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
235 12524 : }
236 :
237 12534 : void blk_to_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
238 : {
239 12534 : to_iobuf_uint64(iobuf, CMD_WRAP_UP, blk->index);
240 12534 : }
241 :
242 2939 : int to_fzp_fingerprint(struct fzp *fzp, uint64_t fingerprint)
243 : {
244 : static struct iobuf wbuf;
245 : to_iobuf_uint64(&wbuf, CMD_FINGERPRINT, fingerprint);
246 2939 : return iobuf_send_msg_fzp(&wbuf, fzp);
247 : }
|