1 #include "common.h"
2 #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER
3 #include "log.h"
4
5 #include "utils.h"
6 #include "block-tx-utils.h"
7
8 /* Utility functions for block transfer protocol. */
9
10 /* Encryption related functions. */
11
12 void
blocktx_generate_encrypt_key(unsigned char * session_key,int sk_len,unsigned char * key,unsigned char * iv)13 blocktx_generate_encrypt_key (unsigned char *session_key, int sk_len,
14 unsigned char *key, unsigned char *iv)
15 {
16 EVP_BytesToKey (EVP_aes_256_cbc(), /* cipher mode */
17 EVP_sha1(), /* message digest */
18 NULL, /* salt */
19 session_key,
20 sk_len,
21 3, /* iteration times */
22 key, /* the derived key */
23 iv); /* IV, initial vector */
24 }
25
26 int
blocktx_encrypt_init(EVP_CIPHER_CTX ** ctx,const unsigned char * key,const unsigned char * iv)27 blocktx_encrypt_init (EVP_CIPHER_CTX **ctx,
28 const unsigned char *key,
29 const unsigned char *iv)
30 {
31 int ret;
32
33 /* Prepare CTX for encryption. */
34 *ctx = EVP_CIPHER_CTX_new ();
35
36 ret = EVP_EncryptInit_ex (*ctx,
37 EVP_aes_256_cbc(), /* cipher mode */
38 NULL, /* engine, NULL for default */
39 key, /* derived key */
40 iv); /* initial vector */
41 if (ret == 0)
42 return -1;
43
44 return 0;
45 }
46
47 int
blocktx_decrypt_init(EVP_CIPHER_CTX ** ctx,const unsigned char * key,const unsigned char * iv)48 blocktx_decrypt_init (EVP_CIPHER_CTX **ctx,
49 const unsigned char *key,
50 const unsigned char *iv)
51 {
52 int ret;
53
54 /* Prepare CTX for decryption. */
55 *ctx = EVP_CIPHER_CTX_new();
56
57 ret = EVP_DecryptInit_ex (*ctx,
58 EVP_aes_256_cbc(), /* cipher mode */
59 NULL, /* engine, NULL for default */
60 key, /* derived key */
61 iv); /* initial vector */
62 if (ret == 0)
63 return -1;
64
65 return 0;
66 }
67
68 /* Sending frame */
69
70 int
send_encrypted_data_frame_begin(evutil_socket_t data_fd,int frame_len)71 send_encrypted_data_frame_begin (evutil_socket_t data_fd,
72 int frame_len)
73 {
74 /* Compute data size after encryption.
75 * Block size is 16 bytes and AES always add one padding block.
76 */
77 int enc_frame_len;
78
79 enc_frame_len = ((frame_len >> 4) + 1) << 4;
80 enc_frame_len = htonl (enc_frame_len);
81
82 if (sendn (data_fd, &enc_frame_len, sizeof(int)) < 0) {
83 seaf_warning ("Failed to send frame length: %s.\n",
84 evutil_socket_error_to_string(evutil_socket_geterror(data_fd)));
85 return -1;
86 }
87
88 return 0;
89 }
90
91 int
send_encrypted_data(EVP_CIPHER_CTX * ctx,evutil_socket_t data_fd,const void * buf,int len)92 send_encrypted_data (EVP_CIPHER_CTX *ctx,
93 evutil_socket_t data_fd,
94 const void *buf, int len)
95 {
96 char out_buf[len + ENC_BLOCK_SIZE];
97 int out_len;
98
99 if (EVP_EncryptUpdate (ctx,
100 (unsigned char *)out_buf, &out_len,
101 (unsigned char *)buf, len) == 0) {
102 seaf_warning ("Failed to encrypt data.\n");
103 return -1;
104 }
105
106 if (sendn (data_fd, out_buf, out_len) < 0) {
107 seaf_warning ("Failed to write data: %s.\n",
108 evutil_socket_error_to_string(evutil_socket_geterror(data_fd)));
109 return -1;
110 }
111
112 return 0;
113 }
114
115 int
send_encrypted_data_frame_end(EVP_CIPHER_CTX * ctx,evutil_socket_t data_fd)116 send_encrypted_data_frame_end (EVP_CIPHER_CTX *ctx,
117 evutil_socket_t data_fd)
118 {
119 char out_buf[ENC_BLOCK_SIZE];
120 int out_len;
121
122 if (EVP_EncryptFinal_ex (ctx, (unsigned char *)out_buf, &out_len) == 0) {
123 seaf_warning ("Failed to encrypt data.\n");
124 return -1;
125 }
126 if (sendn (data_fd, out_buf, out_len) < 0) {
127 seaf_warning ("Failed to write data: %s.\n",
128 evutil_socket_error_to_string(evutil_socket_geterror(data_fd)));
129 return -1;
130 }
131
132 return 0;
133 }
134
135 /* Receiving frame */
136
137 static int
handle_frame_content(struct evbuffer * buf,FrameParser * parser)138 handle_frame_content (struct evbuffer *buf, FrameParser *parser)
139 {
140 char *frame;
141 EVP_CIPHER_CTX *ctx;
142 char *out;
143 int outlen, outlen2;
144 int ret = 0;
145
146 struct evbuffer *input = buf;
147
148 if (evbuffer_get_length (input) < parser->enc_frame_len)
149 return 0;
150
151 if (parser->version == 1)
152 blocktx_decrypt_init (&ctx, parser->key, parser->iv);
153 else if (parser->version == 2)
154 blocktx_decrypt_init (&ctx, parser->key_v2, parser->iv_v2);
155
156 frame = g_malloc (parser->enc_frame_len);
157 out = g_malloc (parser->enc_frame_len + ENC_BLOCK_SIZE);
158
159 evbuffer_remove (input, frame, parser->enc_frame_len);
160
161 if (EVP_DecryptUpdate (ctx,
162 (unsigned char *)out, &outlen,
163 (unsigned char *)frame,
164 parser->enc_frame_len) == 0) {
165 seaf_warning ("Failed to decrypt frame content.\n");
166 ret = -1;
167 goto out;
168 }
169
170 if (EVP_DecryptFinal_ex (ctx, (unsigned char *)(out + outlen), &outlen2) == 0)
171 {
172 seaf_warning ("Failed to decrypt frame content.\n");
173 ret = -1;
174 goto out;
175 }
176
177 ret = parser->content_cb (out, outlen + outlen2, parser->cbarg);
178
179 out:
180 g_free (frame);
181 g_free (out);
182 parser->enc_frame_len = 0;
183 EVP_CIPHER_CTX_free (ctx);
184 return ret;
185 }
186
187 int
handle_one_frame(struct evbuffer * buf,FrameParser * parser)188 handle_one_frame (struct evbuffer *buf, FrameParser *parser)
189 {
190 struct evbuffer *input = buf;
191
192 if (!parser->enc_frame_len) {
193 /* Read the length of the encrypted frame first. */
194 if (evbuffer_get_length (input) < sizeof(int))
195 return 0;
196
197 int frame_len;
198 evbuffer_remove (input, &frame_len, sizeof(int));
199 parser->enc_frame_len = ntohl (frame_len);
200
201 if (evbuffer_get_length (input) > 0)
202 return handle_frame_content (buf, parser);
203
204 return 0;
205 } else {
206 return handle_frame_content (buf, parser);
207 }
208 }
209
210 static int
handle_frame_fragment_content(struct evbuffer * buf,FrameParser * parser)211 handle_frame_fragment_content (struct evbuffer *buf, FrameParser *parser)
212 {
213 char *fragment = NULL, *out = NULL;
214 int fragment_len, outlen;
215 int ret = 0;
216
217 struct evbuffer *input = buf;
218
219 fragment_len = evbuffer_get_length (input);
220 fragment = g_malloc (fragment_len);
221 evbuffer_remove (input, fragment, fragment_len);
222
223 out = g_malloc (fragment_len + ENC_BLOCK_SIZE);
224
225 if (EVP_DecryptUpdate (parser->ctx,
226 (unsigned char *)out, &outlen,
227 (unsigned char *)fragment, fragment_len) == 0) {
228 seaf_warning ("Failed to decrypt frame fragment.\n");
229 ret = -1;
230 goto out;
231 }
232
233 ret = parser->fragment_cb (out, outlen, 0, parser->cbarg);
234 if (ret < 0)
235 goto out;
236
237 parser->remain -= fragment_len;
238
239 if (parser->remain <= 0) {
240 if (EVP_DecryptFinal_ex (parser->ctx,
241 (unsigned char *)out,
242 &outlen) == 0) {
243 seaf_warning ("Failed to decrypt frame fragment.\n");
244 ret = -1;
245 goto out;
246 }
247
248 ret = parser->fragment_cb (out, outlen, 1, parser->cbarg);
249 if (ret < 0)
250 goto out;
251
252 EVP_CIPHER_CTX_free (parser->ctx);
253 parser->enc_init = FALSE;
254 parser->enc_frame_len = 0;
255 }
256
257 out:
258 g_free (fragment);
259 g_free (out);
260 if (ret < 0) {
261 EVP_CIPHER_CTX_free (parser->ctx);
262 parser->enc_init = FALSE;
263 parser->enc_frame_len = 0;
264 }
265 return ret;
266 }
267
268 int
handle_frame_fragments(struct evbuffer * buf,FrameParser * parser)269 handle_frame_fragments (struct evbuffer *buf, FrameParser *parser)
270 {
271 struct evbuffer *input = buf;
272
273 if (!parser->enc_frame_len) {
274 /* Read the length of the encrypted frame first. */
275 if (evbuffer_get_length (input) < sizeof(int))
276 return 0;
277
278 int frame_len;
279 evbuffer_remove (input, &frame_len, sizeof(int));
280 parser->enc_frame_len = ntohl (frame_len);
281 parser->remain = parser->enc_frame_len;
282
283 if (parser->version == 1)
284 blocktx_decrypt_init (&parser->ctx, parser->key, parser->iv);
285 else if (parser->version == 2)
286 blocktx_decrypt_init (&parser->ctx, parser->key_v2, parser->iv_v2);
287 parser->enc_init = TRUE;
288
289 if (evbuffer_get_length (input) > 0)
290 return handle_frame_fragment_content (buf, parser);
291
292 return 0;
293 } else {
294 return handle_frame_fragment_content (buf, parser);
295 }
296 }
297