1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2011-2012 Planets Communications B.V.
6    Copyright (C) 2013-2016 Bareos GmbH & Co. KG
7 
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    Affero General Public License for more details.
17 
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23 /*
24  * Kern Sibbald, March MM
25  * Extracted from other source files by Marco van Wieringen, June 2011
26  */
27 /**
28  * @file
29  * Functions to handle cryptology
30  */
31 
32 #include "include/bareos.h"
33 #include "filed/filed.h"
34 #include "filed/jcr_private.h"
35 #include "filed/restore.h"
36 #include "findlib/find_one.h"
37 #include "lib/bsock.h"
38 #include "lib/edit.h"
39 
40 namespace filedaemon {
41 
42 #ifdef HAVE_SHA2
43 const bool have_sha2 = true;
44 #else
45 const bool have_sha2 = false;
46 #endif
47 
UnserCryptoPacketLen(RestoreCipherContext * ctx)48 static void UnserCryptoPacketLen(RestoreCipherContext* ctx)
49 {
50   unser_declare;
51   if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
52     UnserBegin(&ctx->buf[0], CRYPTO_LEN_SIZE);
53     unser_uint32(ctx->packet_len);
54     ctx->packet_len += CRYPTO_LEN_SIZE;
55   }
56 }
57 
CryptoSessionStart(JobControlRecord * jcr,crypto_cipher_t cipher)58 bool CryptoSessionStart(JobControlRecord* jcr, crypto_cipher_t cipher)
59 {
60   /**
61    * Create encryption session data and a cached, DER-encoded session data
62    * structure. We use a single session key for each backup, so we'll encode
63    * the session data only once.
64    */
65   if (jcr->impl->crypto.pki_encrypt) {
66     uint32_t size = 0;
67 
68     /**
69      * Create per-job session encryption context
70      */
71     jcr->impl->crypto.pki_session =
72         crypto_session_new(cipher, jcr->impl->crypto.pki_recipients);
73     if (!jcr->impl->crypto.pki_session) {
74       Jmsg(jcr, M_FATAL, 0,
75            _("Cannot create a new crypto session probably unsupported cipher "
76              "configured.\n"));
77       return false;
78     }
79 
80     /**
81      * Get the session data size
82      */
83     if (!CryptoSessionEncode(jcr->impl->crypto.pki_session, (uint8_t*)0,
84                              &size)) {
85       Jmsg(jcr, M_FATAL, 0,
86            _("An error occurred while encrypting the stream.\n"));
87       return false;
88     }
89 
90     /**
91      * Allocate buffer
92      */
93     jcr->impl->crypto.pki_session_encoded = GetMemory(size);
94 
95     /**
96      * Encode session data
97      */
98     if (!CryptoSessionEncode(jcr->impl->crypto.pki_session,
99                              (uint8_t*)jcr->impl->crypto.pki_session_encoded,
100                              &size)) {
101       Jmsg(jcr, M_FATAL, 0,
102            _("An error occurred while encrypting the stream.\n"));
103       return false;
104     }
105 
106     /**
107      * ... and store the encoded size
108      */
109     jcr->impl->crypto.pki_session_encoded_size = size;
110 
111     /**
112      * Allocate the encryption/decryption buffer
113      */
114     jcr->impl->crypto.crypto_buf = GetMemory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
115   }
116 
117   return true;
118 }
119 
CryptoSessionEnd(JobControlRecord * jcr)120 void CryptoSessionEnd(JobControlRecord* jcr)
121 {
122   if (jcr->impl->crypto.crypto_buf) {
123     FreePoolMemory(jcr->impl->crypto.crypto_buf);
124     jcr->impl->crypto.crypto_buf = NULL;
125   }
126   if (jcr->impl->crypto.pki_session) {
127     CryptoSessionFree(jcr->impl->crypto.pki_session);
128   }
129   if (jcr->impl->crypto.pki_session_encoded) {
130     FreePoolMemory(jcr->impl->crypto.pki_session_encoded);
131     jcr->impl->crypto.pki_session_encoded = NULL;
132   }
133 }
134 
CryptoSessionSend(JobControlRecord * jcr,BareosSocket * sd)135 bool CryptoSessionSend(JobControlRecord* jcr, BareosSocket* sd)
136 {
137   POOLMEM* msgsave;
138 
139   /** Send our header */
140   Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles,
141         STREAM_ENCRYPTED_SESSION_DATA);
142   sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
143 
144   msgsave = sd->msg;
145   sd->msg = jcr->impl->crypto.pki_session_encoded;
146   sd->message_length = jcr->impl->crypto.pki_session_encoded_size;
147   jcr->JobBytes += sd->message_length;
148 
149   Dmsg1(100, "Send data len=%d\n", sd->message_length);
150   sd->send();
151   sd->msg = msgsave;
152   sd->signal(BNET_EOD);
153   return true;
154 }
155 
156 /**
157  * Verify the signature for the last restored file
158  * Return value is either true (signature correct)
159  * or false (signature could not be verified).
160  * TODO landonf: Implement without using FindOneFile and
161  * without re-reading the file.
162  */
VerifySignature(JobControlRecord * jcr,r_ctx & rctx)163 bool VerifySignature(JobControlRecord* jcr, r_ctx& rctx)
164 {
165   X509_KEYPAIR* keypair = nullptr;
166   DIGEST* digest = NULL;
167   crypto_error_t err;
168   uint64_t saved_bytes;
169   crypto_digest_t signing_algorithm =
170       have_sha2 ? CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1;
171   crypto_digest_t algorithm;
172   SIGNATURE* sig = rctx.sig;
173 
174   if (!jcr->impl->crypto.pki_sign) {
175     /*
176      * no signature OK
177      */
178     return true;
179   }
180   if (!sig) {
181     if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) {
182       Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"),
183             jcr->impl->last_fname);
184       goto bail_out;
185     }
186     return true;
187   }
188 
189   /*
190    * Iterate through the trusted signers
191    */
192   foreach_alist (keypair, jcr->impl->crypto.pki_signers) {
193     err = CryptoSignGetDigest(sig, jcr->impl->crypto.pki_keypair, algorithm,
194                               &digest);
195     switch (err) {
196       case CRYPTO_ERROR_NONE:
197         Dmsg0(50, "== Got digest\n");
198         /*
199          * We computed jcr->impl_->crypto.digest using signing_algorithm while
200          * writing the file. If it is not the same as the algorithm used for
201          * this file, punt by releasing the computed algorithm and
202          * computing by re-reading the file.
203          */
204         if (algorithm != signing_algorithm) {
205           if (jcr->impl->crypto.digest) {
206             CryptoDigestFree(jcr->impl->crypto.digest);
207             jcr->impl->crypto.digest = NULL;
208           }
209         }
210         if (jcr->impl->crypto.digest) {
211           /*
212            * Use digest computed while writing the file to verify the signature
213            */
214           if ((err =
215                    CryptoSignVerify(sig, keypair, jcr->impl->crypto.digest)) !=
216               CRYPTO_ERROR_NONE) {
217             Dmsg1(50, "Bad signature on %s\n", jcr->impl->last_fname);
218             Jmsg2(jcr, M_ERROR, 0,
219                   _("Signature validation failed for file %s: ERR=%s\n"),
220                   jcr->impl->last_fname, crypto_strerror(err));
221             goto bail_out;
222           }
223         } else {
224           /*
225            * Signature found, digest allocated.  Old method,
226            * re-read the file and compute the digest
227            */
228           jcr->impl->crypto.digest = digest;
229 
230           /*
231            * Checksum the entire file
232            * Make sure we don't modify JobBytes by saving and restoring it
233            */
234           saved_bytes = jcr->JobBytes;
235           if (FindOneFile(jcr, jcr->impl->ff, DoFileDigest,
236                           jcr->impl->last_fname, (dev_t)-1, 1) != 0) {
237             Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"),
238                  jcr->impl->last_fname);
239             jcr->JobBytes = saved_bytes;
240             goto bail_out;
241           }
242           jcr->JobBytes = saved_bytes;
243 
244           /*
245            * Verify the signature
246            */
247           if ((err = CryptoSignVerify(sig, keypair, digest)) !=
248               CRYPTO_ERROR_NONE) {
249             Dmsg1(50, "Bad signature on %s\n", jcr->impl->last_fname);
250             Jmsg2(jcr, M_ERROR, 0,
251                   _("Signature validation failed for file %s: ERR=%s\n"),
252                   jcr->impl->last_fname, crypto_strerror(err));
253             goto bail_out;
254           }
255           jcr->impl->crypto.digest = NULL;
256         }
257 
258         /*
259          * Valid signature
260          */
261         Dmsg1(50, "Signature good on %s\n", jcr->impl->last_fname);
262         CryptoDigestFree(digest);
263         return true;
264 
265       case CRYPTO_ERROR_NOSIGNER:
266         /*
267          * Signature not found, try again
268          */
269         if (digest) {
270           CryptoDigestFree(digest);
271           digest = NULL;
272         }
273         continue;
274       default:
275         /*
276          * Something strange happened (that shouldn't happen!)...
277          */
278         Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"),
279               jcr->impl->last_fname, crypto_strerror(err));
280         goto bail_out;
281     }
282   }
283 
284   /*
285    * No signer
286    */
287   Dmsg1(50, "Could not find a valid public key for signature on %s\n",
288         jcr->impl->last_fname);
289 
290 bail_out:
291   if (digest) { CryptoDigestFree(digest); }
292   return false;
293 }
294 
295 /**
296  * In the context of jcr, flush any remaining data from the cipher context,
297  * writing it to bfd.
298  * Return value is true on success, false on failure.
299  */
FlushCipher(JobControlRecord * jcr,BareosWinFilePacket * bfd,uint64_t * addr,char * flags,int32_t stream,RestoreCipherContext * cipher_ctx)300 bool FlushCipher(JobControlRecord* jcr,
301                  BareosWinFilePacket* bfd,
302                  uint64_t* addr,
303                  char* flags,
304                  int32_t stream,
305                  RestoreCipherContext* cipher_ctx)
306 {
307   uint32_t decrypted_len = 0;
308   char* wbuf;     /* write buffer */
309   uint32_t wsize; /* write size */
310   char ec1[50];   /* Buffer printing huge values */
311   bool second_pass = false;
312 
313 again:
314   /*
315    * Write out the remaining block and free the cipher context
316    */
317   cipher_ctx->buf = CheckPoolMemorySize(
318       cipher_ctx->buf, cipher_ctx->buf_len + cipher_ctx->block_size);
319 
320   if (!CryptoCipherFinalize(cipher_ctx->cipher,
321                             (uint8_t*)&cipher_ctx->buf[cipher_ctx->buf_len],
322                             &decrypted_len)) {
323     /*
324      * Writing out the final, buffered block failed. Shouldn't happen.
325      */
326     Jmsg3(jcr, M_ERROR, 0,
327           _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"),
328           cipher_ctx->buf_len, decrypted_len, jcr->impl->last_fname);
329   }
330 
331   Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len,
332         cipher_ctx->buf_len);
333   /*
334    * If nothing new was decrypted, and our output buffer is empty, return
335    */
336   if (decrypted_len == 0 && cipher_ctx->buf_len == 0) { return true; }
337 
338   cipher_ctx->buf_len += decrypted_len;
339 
340   UnserCryptoPacketLen(cipher_ctx);
341   Dmsg1(500, "Crypto unser block size=%d\n",
342         cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
343   wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
344   /*
345    * Decrypted, possibly decompressed output here.
346    */
347   wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE];
348   cipher_ctx->buf_len -= cipher_ctx->packet_len;
349   Dmsg2(
350       130,
351       "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n",
352       wsize, cipher_ctx->buf_len);
353 
354   if (BitIsSet(FO_SPARSE, flags) || BitIsSet(FO_OFFSETS, flags)) {
355     if (!SparseData(jcr, bfd, addr, &wbuf, &wsize)) { return false; }
356   }
357 
358   if (BitIsSet(FO_COMPRESS, flags)) {
359     if (!DecompressData(jcr, jcr->impl->last_fname, stream, &wbuf, &wsize,
360                         false)) {
361       return false;
362     }
363   }
364 
365   Dmsg0(130, "Call StoreData\n");
366   if (!StoreData(jcr, bfd, wbuf, wsize, BitIsSet(FO_WIN32DECOMP, flags))) {
367     return false;
368   }
369   jcr->JobBytes += wsize;
370   Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize,
371         edit_uint64(jcr->JobBytes, ec1));
372 
373   /*
374    * Move any remaining data to start of buffer
375    */
376   if (cipher_ctx->buf_len > 0) {
377     Dmsg1(130, "Moving %u buffered bytes to start of buffer\n",
378           cipher_ctx->buf_len);
379     memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
380             cipher_ctx->buf_len);
381   }
382   /*
383    * The packet was successfully written, reset the length so that the next
384    * packet length may be re-read by UnserCryptoPacketLen()
385    */
386   cipher_ctx->packet_len = 0;
387 
388   if (cipher_ctx->buf_len > 0 && !second_pass) {
389     second_pass = true;
390     goto again;
391   }
392 
393   /*
394    * Stop decryption
395    */
396   cipher_ctx->buf_len = 0;
397   cipher_ctx->packet_len = 0;
398 
399   return true;
400 }
401 
DeallocateCipher(r_ctx & rctx)402 void DeallocateCipher(r_ctx& rctx)
403 {
404   /*
405    * Flush and deallocate previous stream's cipher context
406    */
407   if (rctx.cipher_ctx.cipher) {
408     FlushCipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags,
409                 rctx.comp_stream, &rctx.cipher_ctx);
410     CryptoCipherFree(rctx.cipher_ctx.cipher);
411     rctx.cipher_ctx.cipher = NULL;
412   }
413 }
414 
DeallocateForkCipher(r_ctx & rctx)415 void DeallocateForkCipher(r_ctx& rctx)
416 {
417   /*
418    * Flush and deallocate previous stream's fork cipher context
419    */
420   if (rctx.fork_cipher_ctx.cipher) {
421     FlushCipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags,
422                 rctx.comp_stream, &rctx.fork_cipher_ctx);
423     CryptoCipherFree(rctx.fork_cipher_ctx.cipher);
424     rctx.fork_cipher_ctx.cipher = NULL;
425   }
426 }
427 
428 /**
429  * Setup a encryption context
430  */
SetupEncryptionContext(b_ctx & bctx)431 bool SetupEncryptionContext(b_ctx& bctx)
432 {
433   uint32_t cipher_block_size;
434   bool retval = false;
435 
436   if (BitIsSet(FO_ENCRYPT, bctx.ff_pkt->flags)) {
437     if (BitIsSet(FO_SPARSE, bctx.ff_pkt->flags) ||
438         BitIsSet(FO_OFFSETS, bctx.ff_pkt->flags)) {
439       Jmsg0(bctx.jcr, M_FATAL, 0,
440             _("Encrypting sparse or offset data not supported.\n"));
441       goto bail_out;
442     }
443     /*
444      * Allocate the cipher context
445      */
446     if ((bctx.cipher_ctx = crypto_cipher_new(
447              bctx.jcr->impl->crypto.pki_session, true, &cipher_block_size)) ==
448         NULL) {
449       /*
450        * Shouldn't happen!
451        */
452       Jmsg0(bctx.jcr, M_FATAL, 0,
453             _("Failed to initialize encryption context.\n"));
454       goto bail_out;
455     }
456 
457     /*
458      * Grow the crypto buffer, if necessary.
459      * CryptoCipherUpdate() will buffer up to (cipher_block_size - 1).
460      * We grow crypto_buf to the maximum number of blocks that
461      * could be returned for the given read buffer size.
462      * (Using the larger of either rsize or max_compress_len)
463      */
464     bctx.jcr->impl->crypto.crypto_buf =
465         CheckPoolMemorySize(bctx.jcr->impl->crypto.crypto_buf,
466                             (MAX(bctx.jcr->buf_size + (int)sizeof(uint32_t),
467                                  (int32_t)bctx.max_compress_len) +
468                              cipher_block_size - 1) /
469                                 cipher_block_size * cipher_block_size);
470 
471     bctx.wbuf =
472         bctx.jcr->impl->crypto
473             .crypto_buf; /* Encrypted, possibly compressed output here. */
474   }
475 
476   retval = true;
477 
478 bail_out:
479   return retval;
480 }
481 
482 /**
483  * Setup a decryption context
484  */
SetupDecryptionContext(r_ctx & rctx,RestoreCipherContext & rcctx)485 bool SetupDecryptionContext(r_ctx& rctx, RestoreCipherContext& rcctx)
486 {
487   if (!rctx.cs) {
488     Jmsg1(rctx.jcr, M_ERROR, 0,
489           _("Missing encryption session data stream for %s\n"),
490           rctx.jcr->impl->last_fname);
491     return false;
492   }
493 
494   if ((rcctx.cipher = crypto_cipher_new(rctx.cs, false, &rcctx.block_size)) ==
495       NULL) {
496     Jmsg1(rctx.jcr, M_ERROR, 0,
497           _("Failed to initialize decryption context for %s\n"),
498           rctx.jcr->impl->last_fname);
499     FreeSession(rctx);
500     return false;
501   }
502 
503   return true;
504 }
505 
EncryptData(b_ctx * bctx,bool * need_more_data)506 bool EncryptData(b_ctx* bctx, bool* need_more_data)
507 {
508   bool retval = false;
509   uint32_t initial_len = 0;
510 
511   /*
512    * Note, here we prepend the current record length to the beginning
513    *  of the encrypted data. This is because both sparse and compression
514    *  restore handling want records returned to them with exactly the
515    *  same number of bytes that were processed in the backup handling.
516    *  That is, both are block filters rather than a stream.  When doing
517    *  compression, the compression routines may buffer data, so that for
518    *  any one record compressed, when it is decompressed the same size
519    *  will not be obtained. Of course, the buffered data eventually comes
520    *  out in subsequent CryptoCipherUpdate() calls or at least
521    *  when CryptoCipherFinalize() is called.  Unfortunately, this
522    *  "feature" of encryption enormously complicates the restore code.
523    */
524   ser_declare;
525 
526   if (BitIsSet(FO_SPARSE, bctx->ff_pkt->flags) ||
527       BitIsSet(FO_OFFSETS, bctx->ff_pkt->flags)) {
528     bctx->cipher_input_len += OFFSET_FADDR_SIZE;
529   }
530 
531   /*
532    * Encrypt the length of the input block
533    */
534   uint8_t packet_len[sizeof(uint32_t)];
535 
536   SerBegin(packet_len, sizeof(uint32_t));
537   ser_uint32(bctx->cipher_input_len); /* store data len in begin of buffer */
538   Dmsg1(20, "Encrypt len=%d\n", bctx->cipher_input_len);
539 
540   if (!CryptoCipherUpdate(bctx->cipher_ctx, packet_len, sizeof(packet_len),
541                           (uint8_t*)bctx->jcr->impl->crypto.crypto_buf,
542                           &initial_len)) {
543     /*
544      * Encryption failed. Shouldn't happen.
545      */
546     Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n"));
547     goto bail_out;
548   }
549 
550   /*
551    * Encrypt the input block
552    */
553   if (CryptoCipherUpdate(
554           bctx->cipher_ctx, bctx->cipher_input, bctx->cipher_input_len,
555           (uint8_t*)&bctx->jcr->impl->crypto.crypto_buf[initial_len],
556           &bctx->encrypted_len)) {
557     if ((initial_len + bctx->encrypted_len) == 0) {
558       /*
559        * No full block of data available, read more data
560        */
561       *need_more_data = true;
562       goto bail_out;
563     }
564 
565     Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", bctx->encrypted_len,
566           bctx->jcr->store_bsock->message_length);
567 
568     bctx->jcr->store_bsock->message_length =
569         initial_len + bctx->encrypted_len; /* set encrypted length */
570   } else {
571     /*
572      * Encryption failed. Shouldn't happen.
573      */
574     Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n"));
575     goto bail_out;
576   }
577 
578   retval = true;
579 
580 bail_out:
581   return retval;
582 }
583 
DecryptData(JobControlRecord * jcr,char ** data,uint32_t * length,RestoreCipherContext * cipher_ctx)584 bool DecryptData(JobControlRecord* jcr,
585                  char** data,
586                  uint32_t* length,
587                  RestoreCipherContext* cipher_ctx)
588 {
589   uint32_t decrypted_len = 0; /* Decryption output length */
590 
591   ASSERT(cipher_ctx->cipher);
592 
593   /*
594    * NOTE: We must implement block preserving semantics for the
595    * non-streaming compression and sparse code.
596    *
597    * Grow the crypto buffer, if necessary.
598    * CryptoCipherUpdate() will process only whole blocks,
599    * buffering the remaining input.
600    */
601   cipher_ctx->buf = CheckPoolMemorySize(
602       cipher_ctx->buf, cipher_ctx->buf_len + *length + cipher_ctx->block_size);
603 
604   /*
605    * Decrypt the input block
606    */
607   if (!CryptoCipherUpdate(cipher_ctx->cipher, (const u_int8_t*)*data, *length,
608                           (u_int8_t*)&cipher_ctx->buf[cipher_ctx->buf_len],
609                           &decrypted_len)) {
610     /*
611      * Decryption failed. Shouldn't happen.
612      */
613     Jmsg(jcr, M_FATAL, 0, _("Decryption error\n"));
614     goto bail_out;
615   }
616 
617   if (decrypted_len == 0) {
618     /*
619      * No full block of encrypted data available, write more data
620      */
621     *length = 0;
622     return true;
623   }
624 
625   Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, *length);
626 
627   cipher_ctx->buf_len += decrypted_len;
628   *data = cipher_ctx->buf;
629 
630   /*
631    * If one full preserved block is available, write it to disk,
632    * and then buffer any remaining data. This should be effecient
633    * as long as Bareos's block size is not significantly smaller than the
634    * encryption block size (extremely unlikely!)
635    */
636   UnserCryptoPacketLen(cipher_ctx);
637   Dmsg1(500, "Crypto unser block size=%d\n",
638         cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
639 
640   if (cipher_ctx->packet_len == 0 ||
641       cipher_ctx->buf_len < cipher_ctx->packet_len) {
642     /*
643      * No full preserved block is available.
644      */
645     *length = 0;
646     return true;
647   }
648 
649   /*
650    * We have one full block, set up the filter input buffers
651    */
652   *length = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
653   *data = &((*data)[CRYPTO_LEN_SIZE]); /* Skip the block length header */
654   cipher_ctx->buf_len -= cipher_ctx->packet_len;
655   Dmsg2(
656       130,
657       "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n",
658       *length, cipher_ctx->buf_len);
659 
660   return true;
661 
662 bail_out:
663   return false;
664 }
665 } /* namespace filedaemon */
666