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 206001 : struct blk *blk_alloc(void)
11 : {
12 206001 : return (struct blk *)calloc_w(1, sizeof(struct blk), __func__);
13 : }
14 :
15 0 : struct blk *blk_alloc_with_data(uint32_t max_data_length)
16 : {
17 0 : struct blk *blk=NULL;
18 0 : if(!(blk=blk_alloc())) return NULL;
19 0 : if((blk->data=(char *)
20 0 : calloc_w(1, sizeof(char)*max_data_length, __func__)))
21 0 : return blk;
22 0 : blk_free(&blk);
23 0 : return NULL;
24 : }
25 :
26 206001 : void blk_free_content(struct blk *blk)
27 : {
28 412002 : if(!blk) return;
29 206001 : free_w(&blk->data);
30 : }
31 :
32 206001 : void blk_free(struct blk **blk)
33 : {
34 412002 : if(!blk || !*blk) return;
35 206001 : blk_free_content(*blk);
36 206001 : free_v((void **)blk);
37 : }
38 :
39 0 : static int md5_generation(uint8_t md5sum[], const char *data, uint32_t length)
40 : {
41 : MD5_CTX md5;
42 0 : if(!MD5_Init(&md5)
43 0 : || !MD5_Update(&md5, data, length)
44 0 : || !MD5_Final(md5sum, &md5))
45 : {
46 0 : logp("MD5 generation failed.\n");
47 0 : return -1;
48 : }
49 0 : return 0;
50 : }
51 :
52 0 : int blk_md5_update(struct blk *blk)
53 : {
54 0 : return md5_generation(blk->md5sum, blk->data, blk->length);
55 : }
56 :
57 0 : int blk_is_zero_length(struct blk *blk)
58 : {
59 0 : return !blk->fingerprint // All zeroes.
60 0 : && !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 0 : case 1: break; // Match.
70 0 : 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 0 : 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 34578 : int blk_fingerprint_is_hook(struct blk *blk)
83 : {
84 34578 : 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 46900 : static void set_fingerprint(struct blk *blk, struct iobuf *iobuf)
95 : {
96 46900 : blk->fingerprint=ETOH(*(uint64_t *)iobuf->buf);
97 46900 : }
98 :
99 46104 : static void set_sig(struct blk *blk, struct iobuf *iobuf)
100 : {
101 46104 : set_fingerprint(blk, iobuf);
102 46104 : memcpy(blk->md5sum, iobuf->buf+8, 8);
103 46104 : memcpy(blk->md5sum+8, iobuf->buf+16, 8);
104 46104 : }
105 :
106 57700 : static void set_savepath(struct blk *blk, struct iobuf *iobuf, size_t offset)
107 : {
108 57700 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+offset));
109 57700 : }
110 :
111 0 : int blk_set_from_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
112 : {
113 0 : if(iobuf->len!=24)
114 : {
115 0 : logp("Signature wrong length: %u!=24\n", iobuf->len);
116 0 : return -1;
117 : }
118 0 : set_sig(blk, iobuf);
119 0 : return 0;
120 : }
121 :
122 46104 : int blk_set_from_iobuf_sig_and_savepath(struct blk *blk, struct iobuf *iobuf)
123 : {
124 46104 : 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 46104 : set_sig(blk, iobuf);
131 46104 : set_savepath(blk, iobuf, 24 /* offset */);
132 46104 : return 0;
133 : }
134 :
135 796 : 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 796 : set_fingerprint(blk, iobuf);
144 796 : return 0;
145 : }
146 :
147 11596 : 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 11596 : set_savepath(blk, iobuf, 0 /* offset */);
156 11596 : return 0;
157 : }
158 :
159 0 : int blk_set_from_iobuf_index_and_savepath(struct blk *blk, struct iobuf *iobuf)
160 : {
161 0 : 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 0 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
168 0 : blk->savepath=ETOH(*(uint64_t *)(iobuf->buf+8));
169 0 : return 0;
170 : }
171 :
172 0 : int blk_set_from_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
173 : {
174 0 : 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 0 : blk->index=ETOH(*(uint64_t *)iobuf->buf);
181 0 : return 0;
182 : }
183 :
184 0 : void blk_to_iobuf_sig(struct blk *blk, struct iobuf *iobuf)
185 : {
186 : static union { char c[24]; uint64_t v[3]; } buf;
187 0 : buf.v[0]=HTOE(blk->fingerprint);
188 0 : memcpy(&buf.c[8], blk->md5sum, 8);
189 0 : memcpy(&buf.c[16], blk->md5sum+8, 8);
190 0 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
191 0 : }
192 :
193 162142 : 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 162142 : buf.v[0]=HTOE(blk->fingerprint);
197 162142 : memcpy(&buf.c[8], blk->md5sum, 8);
198 162142 : memcpy(&buf.c[16], blk->md5sum+8, 8);
199 162142 : buf.v[3]=HTOE(blk->savepath);
200 162142 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
201 162142 : }
202 :
203 36900 : 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 36900 : buf.v=HTOE(val);
207 36900 : iobuf_set(iobuf, cmd, buf.c, sizeof(buf));
208 36900 : }
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 34650 : void blk_to_iobuf_savepath(struct blk *blk, struct iobuf *iobuf)
216 : {
217 34650 : to_iobuf_uint64(iobuf, CMD_SAVE_PATH, blk->savepath);
218 34650 : }
219 :
220 0 : 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 0 : buf.v[0]=HTOE(blk->index);
224 0 : buf.v[1]=HTOE(blk->savepath);
225 0 : iobuf_set(iobuf, CMD_SIG, buf.c, sizeof(buf));
226 0 : }
227 :
228 0 : void blk_to_iobuf_wrap_up(struct blk *blk, struct iobuf *iobuf)
229 : {
230 0 : to_iobuf_uint64(iobuf, CMD_WRAP_UP, blk->index);
231 0 : }
232 :
233 2250 : int to_fzp_fingerprint(struct fzp *fzp, uint64_t fingerprint)
234 : {
235 : static struct iobuf wbuf;
236 2250 : to_iobuf_uint64(&wbuf, CMD_FINGERPRINT, fingerprint);
237 2250 : return iobuf_send_msg_fzp(&wbuf, fzp);
238 : }
|