Merge lp:~gl-az/percona-xtrabackup/BT23557-bug1185343-2.2 into lp:percona-xtrabackup/2.2

Proposed by George Ormond Lorch III
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 4881
Proposed branch: lp:~gl-az/percona-xtrabackup/BT23557-bug1185343-2.2
Merge into: lp:percona-xtrabackup/2.2
Diff against target: 493 lines (+199/-27)
8 files modified
xtrabackup/src/ds_encrypt.c (+12/-3)
xtrabackup/src/xbcrypt.c (+26/-8)
xtrabackup/src/xbcrypt.h (+12/-7)
xtrabackup/src/xbcrypt_common.c (+22/-1)
xtrabackup/src/xbcrypt_read.c (+81/-5)
xtrabackup/src/xbcrypt_write.c (+13/-3)
xtrabackup/test/inc/decrypt_v1_test_file.txt (+9/-0)
xtrabackup/test/t/xbcrypt.sh (+24/-0)
To merge this branch: bzr merge lp:~gl-az/percona-xtrabackup/BT23557-bug1185343-2.2
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+191677@code.launchpad.net

Description of the change

Merged from 2.1:

Fix for https://bugs.launchpad.net/percona-xtrabackup/+bug/1185343 - Fixed IV used in Xtrabackup encryption

In order to fix this in the safest possible way, followed general advice from various sources but summed up nicely here:
    "An initialization vector has different security requirements than a key, so the IV usually does not need to be secret. However, in most cases, it is important that an initialization vector is never reused under the same key. For CBC and CFB, reusing an IV leaks some information about the first block of plaintext, and about any common prefix shared by the two messages. For OFB and CTR, reusing an IV completely destroys security. This can be seen because both modes effectively create a bitstream that is XORed with the plaintext, and this bitstream is dependent on the password and IV only. Reusing a bitstream destroys security. In CBC mode, the IV must, in addition, be unpredictable at encryption time; in particular, the (previously) common practice of re-using the last ciphertext block of a message as the IV for the next message is insecure (for example, this method was used by SSL 2.0). If an attacker knows the IV (or the previous block of ciphertext) before he specifies the next plaintext, he can check his guess about plaintext of some block that was encrypted with the same key before (this is known as the TLS CBC IV attack)." - http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

This fix advances the XBCRYPT chunk header version and adds an iv field to store the iv that was used to encrypt that block.

On decryption, if the XBCRYPT version is 1 then the original fixed iv is used to decrypt, otherwise the iv in the block header is used.

On encryption, for each block being encrypted, an iv of the correct length is generated by using values returned from random() until the iv has been fully populated. This iv will be written into the XBCRYPT chunk header along with its size.

One new test case added, xbcrypt.sh. Added two files in inc: decrypt_v1_test_file.txt is a simple text file that was then encrypted @ v1 levels and put in decrypt_v1_test_file.xbcrypt. The new test case tests two simple scenarios:
      1 - Tests that a file can go through an encryption/decryption cycle and be 100% identical to the original file.
      2 - Tests that a file previously encrypted with and earlier version can be decrypted with the current version.

http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.2-param/20/

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'xtrabackup/src/ds_encrypt.c'
2--- xtrabackup/src/ds_encrypt.c 2013-08-18 06:54:14 +0000
3+++ xtrabackup/src/ds_encrypt.c 2013-10-17 16:35:32 +0000
4@@ -42,6 +42,7 @@
5 const char *from;
6 size_t from_len;
7 char *to;
8+ char *iv;
9 size_t to_len;
10 gcry_cipher_hd_t cipher_handle;
11 } crypt_thread_ctxt_t;
12@@ -171,6 +172,8 @@
13 xb_a(encrypt_iv_len > 0);
14 xb_a(encrypt_iv_len <= sizeof(encrypt_iv));
15
16+ xb_crypt_init_iv();
17+
18 /* Now set up the key */
19 if (xtrabackup_encrypt_key == NULL &&
20 xtrabackup_encrypt_key_file == NULL) {
21@@ -334,7 +337,9 @@
22 if (xb_crypt_write_chunk(crypt_file->xbcrypt_file,
23 threads[i].to,
24 threads[i].from_len,
25- threads[i].to_len)) {
26+ threads[i].to_len,
27+ threads[i].iv,
28+ encrypt_iv_len)) {
29 msg("encrypt: write to the destination file "
30 "failed.\n");
31 return 1;
32@@ -411,6 +416,9 @@
33 thd->to = (char *) my_malloc(XB_CRYPT_CHUNK_SIZE,
34 MYF(MY_FAE));
35
36+ thd->iv = (char *) my_malloc(encrypt_iv_len,
37+ MYF(MY_FAE));
38+
39 /* Initialize the control mutex and condition var */
40 if (pthread_mutex_init(&thd->ctrl_mutex, NULL) ||
41 pthread_cond_init(&thd->ctrl_cond, NULL)) {
42@@ -501,6 +509,7 @@
43 gcry_cipher_close(thd->cipher_handle);
44
45 MY_FREE(thd->to);
46+ MY_FREE(thd->iv);
47 }
48
49 MY_FREE(threads);
50@@ -521,7 +530,6 @@
51
52 pthread_mutex_unlock(&thd->ctrl_mutex);
53
54-
55 while (1) {
56 thd->data_avail = FALSE;
57 pthread_cond_signal(&thd->data_cond);
58@@ -548,8 +556,9 @@
59 continue;
60 }
61
62+ xb_crypt_create_iv(thd->iv, encrypt_iv_len);
63 gcry_error = gcry_cipher_setiv(thd->cipher_handle,
64- encrypt_iv,
65+ thd->iv,
66 encrypt_iv_len);
67 if (gcry_error) {
68 msg("encrypt: unable to set cipher ctr - "
69
70=== modified file 'xtrabackup/src/xbcrypt.c'
71--- xtrabackup/src/xbcrypt.c 2013-08-18 06:54:14 +0000
72+++ xtrabackup/src/xbcrypt.c 2013-10-17 16:35:32 +0000
73@@ -56,7 +56,7 @@
74 static int encrypt_algo = 0;
75 static int encrypt_mode = GCRY_CIPHER_MODE_CTR;
76 static uint encrypt_key_len = 0;
77-static const unsigned char encrypt_iv[] =
78+static const unsigned char v1_encrypt_iv[] =
79 "Percona Xtrabackup is Awesome!!!";
80 static size_t encrypt_iv_len = 0;
81
82@@ -294,6 +294,8 @@
83 void *chunkbuf = NULL;
84 size_t chunksize;
85 size_t originalsize;
86+ void *ivbuf = NULL;
87+ size_t ivsize;
88 void *decryptbuf = NULL;
89 size_t decryptbufsize = 0;
90 ulonglong ttlchunksread = 0;
91@@ -335,7 +337,8 @@
92
93 /* Walk the encrypted chunks, decrypting them and writing out */
94 while ((result = xb_crypt_read_chunk(xbcrypt_file, &chunkbuf,
95- &originalsize, &chunksize))
96+ &originalsize, &chunksize,
97+ &ivbuf, &ivsize))
98 == XB_CRYPT_READ_CHUNK) {
99
100 if (encrypt_algo != GCRY_CIPHER_NONE) {
101@@ -348,9 +351,15 @@
102 goto err;
103 }
104
105- gcry_error = gcry_cipher_setiv(cipher_handle,
106- encrypt_iv,
107- encrypt_iv_len);
108+ if (ivsize) {
109+ gcry_error = gcry_cipher_setiv(cipher_handle,
110+ ivbuf,
111+ ivsize);
112+ } else {
113+ gcry_error = gcry_cipher_setiv(cipher_handle,
114+ v1_encrypt_iv,
115+ encrypt_iv_len);
116+ }
117 if (gcry_error) {
118 msg("%s:decrypt: unable to set cipher iv - "
119 "%s : %s\n", my_progname,
120@@ -448,6 +457,7 @@
121 size_t bytesread;
122 size_t chunkbuflen;
123 void *chunkbuf = NULL;
124+ void *ivbuf = NULL;
125 size_t encryptbuflen = 0;
126 size_t encryptedlen = 0;
127 void *encryptbuf = NULL;
128@@ -491,7 +501,11 @@
129 goto err;
130 }
131
132- /* now read in data in chunk size, encryptand write out */
133+ ivbuf = my_malloc(encrypt_iv_len, MYF(MY_FAE));
134+
135+ xb_crypt_init_iv();
136+
137+ /* now read in data in chunk size, encrypt and write out */
138 chunkbuflen = opt_encrypt_chunk_size;
139 chunkbuf = my_malloc(chunkbuflen, MYF(MY_FAE));
140 while ((bytesread = my_read(filein, chunkbuf, chunkbuflen,
141@@ -507,8 +521,10 @@
142 gcry_strerror(gcry_error));
143 goto err;
144 }
145+
146+ xb_crypt_create_iv(ivbuf, encrypt_iv_len);
147 gcry_error = gcry_cipher_setiv(cipher_handle,
148- encrypt_iv,
149+ ivbuf,
150 encrypt_iv_len);
151
152 if (gcry_error) {
153@@ -553,7 +569,8 @@
154 encryptbuf = chunkbuf;
155 }
156
157- if (xb_crypt_write_chunk(xbcrypt_file, encryptbuf, bytesread, encryptedlen)) {
158+ if (xb_crypt_write_chunk(xbcrypt_file, encryptbuf, bytesread,
159+ encryptedlen, ivbuf, encrypt_iv_len)) {
160 msg("%s:encrypt: abcrypt_write_chunk() failed.\n",
161 my_progname);
162 goto err;
163@@ -568,6 +585,7 @@
164 ttlbyteswritten);
165 }
166
167+ MY_FREE(ivbuf);
168 MY_FREE(chunkbuf);
169
170 if (encryptbuf && encryptbuflen)
171
172=== modified file 'xtrabackup/src/xbcrypt.h'
173--- xtrabackup/src/xbcrypt.h 2013-08-18 06:54:14 +0000
174+++ xtrabackup/src/xbcrypt.h 2013-10-17 16:35:32 +0000
175@@ -24,8 +24,9 @@
176 #include <my_base.h>
177 #include "common.h"
178
179-#define XB_CRYPT_CHUNK_MAGIC "XBCRYP01"
180-#define XB_CRYPT_CHUNK_MAGIC_SIZE (sizeof(XB_CRYPT_CHUNK_MAGIC)-1)
181+#define XB_CRYPT_CHUNK_MAGIC1 "XBCRYP01"
182+#define XB_CRYPT_CHUNK_MAGIC2 "XBCRYP02" /* must be same size as ^^ */
183+#define XB_CRYPT_CHUNK_MAGIC_SIZE (sizeof(XB_CRYPT_CHUNK_MAGIC1)-1)
184
185 /******************************************************************************
186 Write interface */
187@@ -38,11 +39,11 @@
188 xb_wcrypt_t *xb_crypt_write_open(void *userdata,
189 xb_crypt_write_callback *onwrite);
190
191-/* Takes buffer, original length and encrypted length, formats output buffer
192- and calls write callback.
193+/* Takes buffer, original length, encrypted length iv and iv length, formats
194+ output buffer and calls write callback.
195 Returns 0 on success, 1 on error */
196 int xb_crypt_write_chunk(xb_wcrypt_t *crypt, const void *buf, size_t olen,
197- size_t elen);
198+ size_t elen, const void *iv, size_t ivlen);
199
200 /* Returns 0 on success, 1 on error */
201 int xb_crypt_write_close(xb_wcrypt_t *crypt);
202@@ -51,7 +52,7 @@
203 Read interface */
204 typedef struct xb_rcrypt_struct xb_rcrypt_t;
205
206-/* Callback on write for i/o, must return # of bytes read or -1 on error */
207+/* Callback on read for i/o, must return # of bytes read or -1 on error */
208 typedef ssize_t xb_crypt_read_callback(void *userdata,
209 void *buf, size_t len, int flags);
210
211@@ -65,7 +66,8 @@
212 } xb_rcrypt_result_t;
213
214 xb_rcrypt_result_t xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf,
215- size_t *olen, size_t *elen);
216+ size_t *olen, size_t *elen, void **iv,
217+ size_t *ivlen);
218
219 int xb_crypt_read_close(xb_rcrypt_t *crypt);
220
221@@ -74,4 +76,7 @@
222 my_bool xb_crypt_read_key_file(const char *filename,
223 void** key, uint *keylength);
224
225+void xb_crypt_init_iv();
226+
227+void xb_crypt_create_iv(void* ivbuf, size_t ivlen);
228 #endif
229
230=== modified file 'xtrabackup/src/xbcrypt_common.c'
231--- xtrabackup/src/xbcrypt_common.c 2013-08-18 06:54:14 +0000
232+++ xtrabackup/src/xbcrypt_common.c 2013-10-17 16:35:32 +0000
233@@ -23,7 +23,6 @@
234 #include "xbcrypt.h"
235 #include <gcrypt.h>
236
237-
238 my_bool
239 xb_crypt_read_key_file(const char *filename, void** key, uint *keylength)
240 {
241@@ -43,3 +42,25 @@
242 my_fclose(fp, MYF(0));
243 return TRUE;
244 }
245+
246+
247+void
248+xb_crypt_init_iv()
249+{
250+ uint seed = time(NULL);
251+ srandom(seed);
252+}
253+
254+void
255+xb_crypt_create_iv(void* ivbuf, size_t ivlen)
256+{
257+ size_t i;
258+ ulong rndval;
259+
260+ for (i = 0; i < ivlen; i++) {
261+ if (i % 4 == 0) {
262+ rndval = (ulong) random();
263+ }
264+ ((uchar*)ivbuf)[i] = ((uchar*)&rndval)[i % 4];
265+ }
266+}
267
268=== modified file 'xtrabackup/src/xbcrypt_read.c'
269--- xtrabackup/src/xbcrypt_read.c 2013-08-18 06:54:14 +0000
270+++ xtrabackup/src/xbcrypt_read.c 2013-10-17 16:35:32 +0000
271@@ -25,6 +25,8 @@
272 xb_crypt_read_callback *read;
273 void *buffer;
274 size_t bufsize;
275+ void *ivbuffer;
276+ size_t ivbufsize;
277 ulonglong offset;
278 };
279
280@@ -42,17 +44,20 @@
281 crypt->buffer = NULL;
282 crypt->bufsize = 0;
283 crypt->offset = 0;
284-
285+ crypt->ivbuffer = NULL;
286+ crypt->ivbufsize = 0;
287 return crypt;
288 }
289
290 xb_rcrypt_result_t
291-xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf, size_t *olen, size_t *elen)
292+xb_crypt_read_chunk(xb_rcrypt_t *crypt, void **buf, size_t *olen, size_t *elen,
293+ void **iv, size_t *ivlen)
294+
295 {
296 uchar tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4];
297 uchar *ptr;
298 ulonglong tmp;
299- ulong checksum, checksum_exp;
300+ ulong checksum, checksum_exp, version;
301 ssize_t bytesread;
302 xb_rcrypt_result_t result = XB_CRYPT_READ_CHUNK;
303
304@@ -72,8 +77,11 @@
305
306 ptr = tmpbuf;
307
308- if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC, XB_CRYPT_CHUNK_MAGIC_SIZE)
309- != 0) {
310+ if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC1, XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
311+ version = 1;
312+ } else if (memcmp(ptr, XB_CRYPT_CHUNK_MAGIC2, XB_CRYPT_CHUNK_MAGIC_SIZE) == 0) {
313+ version = 2;
314+ } else {
315 msg("%s:%s: wrong chunk magic at offset 0x%llx.\n",
316 my_progname, __FUNCTION__, crypt->offset);
317 result = XB_CRYPT_READ_ERROR;
318@@ -113,6 +121,72 @@
319 ptr += 4;
320 crypt->offset += 4;
321
322+ /* iv size */
323+ if (version == 1) {
324+ *ivlen = 0;
325+ *iv = 0;
326+ } else {
327+ if ((bytesread = crypt->read(crypt->userdata, tmpbuf, 8,
328+ MYF(MY_WME))) != 8) {
329+ if (bytesread == 0) {
330+ result = XB_CRYPT_READ_EOF;
331+ goto err;
332+ } else {
333+ msg("%s:%s: unable to read chunk iv size at "
334+ "offset 0x%llx.\n",
335+ my_progname, __FUNCTION__, crypt->offset);
336+ result = XB_CRYPT_READ_ERROR;
337+ goto err;
338+ }
339+ }
340+
341+ tmp = uint8korr(tmpbuf);
342+ if (tmp > INT_MAX) {
343+ msg("%s:%s: invalid iv size at offset 0x%llx.\n",
344+ my_progname, __FUNCTION__, crypt->offset);
345+ result = XB_CRYPT_READ_ERROR;
346+ goto err;
347+ }
348+ crypt->offset += 8;
349+ *ivlen = (size_t)tmp;
350+ }
351+
352+ if (*ivlen > crypt->ivbufsize) {
353+ if (crypt->ivbuffer) {
354+ crypt->ivbuffer = my_realloc(crypt->ivbuffer, *ivlen,
355+ MYF(MY_WME));
356+ if (crypt->ivbuffer == NULL) {
357+ msg("%s:%s: failed to increase iv buffer to "
358+ "%llu bytes.\n", my_progname, __FUNCTION__,
359+ (ulonglong)*ivlen);
360+ result = XB_CRYPT_READ_ERROR;
361+ goto err;
362+ }
363+ } else {
364+ crypt->ivbuffer = my_malloc(*ivlen, MYF(MY_WME));
365+ if (crypt->ivbuffer == NULL) {
366+ msg("%s:%s: failed to allocate iv buffer of "
367+ "%llu bytes.\n", my_progname, __FUNCTION__,
368+ (ulonglong)*ivlen);
369+ result = XB_CRYPT_READ_ERROR;
370+ goto err;
371+ }
372+ }
373+ crypt->ivbufsize = *ivlen;
374+ }
375+
376+ if (*ivlen > 0) {
377+ if (crypt->read(crypt->userdata, crypt->ivbuffer, *ivlen, MYF(MY_WME|MY_FULL_IO))
378+ != (ssize_t)*ivlen) {
379+ msg("%s:%s: failed to read %lld bytes for chunk iv "
380+ "at offset 0x%llx.\n", my_progname, __FUNCTION__,
381+ (ulonglong)*ivlen, crypt->offset);
382+ result = XB_CRYPT_READ_ERROR;
383+ goto err;
384+ }
385+ *iv = crypt->ivbuffer;
386+ }
387+
388 if (*olen > crypt->bufsize) {
389 if (crypt->buffer) {
390 crypt->buffer = my_realloc(crypt->buffer, *olen,
391@@ -165,6 +239,8 @@
392 *buf = NULL;
393 *olen = 0;
394 *elen = 0;
395+ *ivlen = 0;
396+ *iv = 0;
397 exit:
398 return result;
399 }
400
401=== modified file 'xtrabackup/src/xbcrypt_write.c'
402--- xtrabackup/src/xbcrypt_write.c 2013-08-18 06:54:14 +0000
403+++ xtrabackup/src/xbcrypt_write.c 2013-10-17 16:35:32 +0000
404@@ -41,9 +41,9 @@
405 }
406
407 int xb_crypt_write_chunk(xb_wcrypt_t *crypt, const void *buf, size_t olen,
408- size_t elen)
409+ size_t elen, const void *iv, size_t ivlen)
410 {
411- uchar tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4];
412+ uchar tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4 + 8];
413 uchar *ptr;
414 ulong checksum;
415
416@@ -55,9 +55,13 @@
417 if (elen > INT_MAX)
418 return 0;
419
420+ xb_ad(ivlen <= INT_MAX);
421+ if (ivlen > INT_MAX)
422+ return 0;
423+
424 ptr = tmpbuf;
425
426- memcpy(ptr, XB_CRYPT_CHUNK_MAGIC, XB_CRYPT_CHUNK_MAGIC_SIZE);
427+ memcpy(ptr, XB_CRYPT_CHUNK_MAGIC2, XB_CRYPT_CHUNK_MAGIC_SIZE);
428 ptr += XB_CRYPT_CHUNK_MAGIC_SIZE;
429
430 int8store(ptr, (ulonglong)0); /* reserved */
431@@ -73,11 +77,17 @@
432 int4store(ptr, checksum); /* checksum */
433 ptr += 4;
434
435+ int8store(ptr, (ulonglong)ivlen); /* iv size */
436+ ptr += 8;
437+
438 xb_ad(ptr <= tmpbuf + sizeof(tmpbuf));
439
440 if (crypt->write(crypt->userdata, tmpbuf, ptr-tmpbuf) == -1)
441 return 1;
442
443+ if (crypt->write(crypt->userdata, iv, ivlen) == -1)
444+ return 1;
445+
446 if (crypt->write(crypt->userdata, buf, elen) == -1)
447 return 1;
448
449
450=== added file 'xtrabackup/test/inc/decrypt_v1_test_file.txt'
451--- xtrabackup/test/inc/decrypt_v1_test_file.txt 1970-01-01 00:00:00 +0000
452+++ xtrabackup/test/inc/decrypt_v1_test_file.txt 2013-10-17 16:35:32 +0000
453@@ -0,0 +1,9 @@
454+*******************************************************************************
455+* This is just a simple text file with enough data to make sure to fill a *
456+* full encryption window. It will be stored in the source tree in both *
457+* encrypted in v1 format and decrypted for comparison after decrypting with *
458+* the xbcrypt utility to validate that newer xbcrypt decryptions can properly *
459+* read and decrypt files encrypted with older versions of xtrabackup. *
460+* The encrypted version of this file will be encrypted with AES256 and the *
461+* key percona_xtrabackup_is_awesome___ *
462+*******************************************************************************
463
464=== added file 'xtrabackup/test/inc/decrypt_v1_test_file.xbcrypt'
465Binary files xtrabackup/test/inc/decrypt_v1_test_file.xbcrypt 1970-01-01 00:00:00 +0000 and xtrabackup/test/inc/decrypt_v1_test_file.xbcrypt 2013-10-17 16:35:32 +0000 differ
466=== added file 'xtrabackup/test/t/xbcrypt.sh'
467--- xtrabackup/test/t/xbcrypt.sh 1970-01-01 00:00:00 +0000
468+++ xtrabackup/test/t/xbcrypt.sh 2013-10-17 16:35:32 +0000
469@@ -0,0 +1,24 @@
470+############################################################################
471+# A few tests for encryption:
472+# 1 - Test that a file that goes through the encrypt/decrypt cycle is
473+# exactly the same after decryption as the original.
474+# 2 - Test that files encrypted with prior versions of xbcrypt can be
475+# correctly decrypted. Introduced when fixing bug 1185343 - Fixed IV
476+# used in Xtrabackup encryption
477+############################################################################
478+
479+encrypt_algo="AES256"
480+encrypt_key="percona_xtrabackup_is_awesome___"
481+
482+# test that decrypted file is identical to original
483+run_cmd xbcrypt -i inc/decrypt_v1_test_file.txt -o ${topdir}/decrypt_v1_test_file.xbcrypt -a ${encrypt_algo} -k ${encrypt_key}
484+run_cmd xbcrypt -d -i ${topdir}/decrypt_v1_test_file.xbcrypt -o ${topdir}/decrypt_v1_test_file.txt -a ${encrypt_algo} -k ${encrypt_key}
485+run_cmd cmp inc/decrypt_v1_test_file.txt ${topdir}/decrypt_v1_test_file.txt
486+rm ${topdir}/decrypt_v1_test_file.xbcrypt
487+rm ${topdir}/decrypt_v1_test_file.txt
488+
489+
490+# test that file encrypted w/ v1 can be decrypted perfectly w/ v2
491+run_cmd xbcrypt -d -i inc/decrypt_v1_test_file.xbcrypt -o ${topdir}/decrypt_v1_test_file.txt -a ${encrypt_algo} -k ${encrypt_key}
492+run_cmd cmp inc/decrypt_v1_test_file.txt ${topdir}/decrypt_v1_test_file.txt
493+rm ${topdir}/decrypt_v1_test_file.txt

Subscribers

People subscribed via source and target branches