예제 #1
0
파일: hmac.c 프로젝트: kzlin129/tt-gpl
void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
                       unsigned int *keylen, u8 *out)
{
	unsigned int i;
	struct scatterlist tmp;
	char *opad = tfm->crt_digest.dit_hmac_block;
	
	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
		hash_key(tfm, key, *keylen);
		*keylen = crypto_tfm_alg_digestsize(tfm);
	}

	crypto_digest_final(tfm, out);

	memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
	memcpy(opad, key, *keylen);
		
	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
		opad[i] ^= 0x5c;

	tmp.page = virt_to_page(opad);
	tmp.offset = offset_in_page(opad);
	tmp.length = crypto_tfm_alg_blocksize(tfm);

	crypto_digest_init(tfm);
	crypto_digest_update(tfm, &tmp, 1);
	
	tmp.page = virt_to_page(out);
	tmp.offset = offset_in_page(out);
	tmp.length = crypto_tfm_alg_digestsize(tfm);
	
	crypto_digest_update(tfm, &tmp, 1);
	crypto_digest_final(tfm, out);
}
예제 #2
0
파일: backup.c 프로젝트: tuxmux/bareos
/**
 * Save OSX specific resource forks and finder info.
 */
static inline bool save_rsrc_and_finder(b_save_ctx &bsctx)
{
   char flags[FOPTS_BYTES];
   int rsrc_stream;
   BSOCK *sd = bsctx.jcr->store_bsock;
   bool retval = false;

   if (bsctx.ff_pkt->hfsinfo.rsrclength > 0) {
      if (bopen_rsrc(&bsctx.ff_pkt->bfd, bsctx.ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
         bsctx.ff_pkt->ff_errno = errno;
         berrno be;
         Jmsg(bsctx.jcr, M_NOTSAVED, -1,
              _("     Cannot open resource fork for \"%s\": ERR=%s.\n"),
              bsctx.ff_pkt->fname, be.bstrerror());
         bsctx.jcr->JobErrors++;
         if (is_bopen(&bsctx.ff_pkt->bfd)) {
            bclose(&bsctx.ff_pkt->bfd);
         }
      } else {
         int status;

         memcpy(flags, bsctx.ff_pkt->flags, sizeof(flags));
         clear_bit(FO_COMPRESS, bsctx.ff_pkt->flags);
         clear_bit(FO_SPARSE, bsctx.ff_pkt->flags);
         clear_bit(FO_OFFSETS, bsctx.ff_pkt->flags);
         rsrc_stream = bit_is_set(FO_ENCRYPT, flags) ? STREAM_ENCRYPTED_MACOS_FORK_DATA :
                                                       STREAM_MACOS_FORK_DATA;

         status = send_data(bsctx.jcr, rsrc_stream, bsctx.ff_pkt,
                            bsctx.digest, bsctx.signing_digest);

         memcpy(bsctx.ff_pkt->flags, flags, sizeof(flags));
         bclose(&bsctx.ff_pkt->bfd);
         if (!status) {
            goto bail_out;
         }
      }
   }

   Dmsg1(300, "Saving Finder Info for \"%s\"\n", bsctx.ff_pkt->fname);
   sd->fsend("%ld %d 0", bsctx.jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
   Dmsg1(300, "filed>stored:header %s", sd->msg);
   pm_memcpy(sd->msg, bsctx.ff_pkt->hfsinfo.fndrinfo, 32);
   sd->msglen = 32;
   if (bsctx.digest) {
      crypto_digest_update(bsctx.digest, (uint8_t *)sd->msg, sd->msglen);
   }
   if (bsctx.signing_digest) {
      crypto_digest_update(bsctx.signing_digest, (uint8_t *)sd->msg, sd->msglen);
   }
   sd->send();
   sd->signal(BNET_EOD);

   retval = true;

bail_out:
   return retval;
}
예제 #3
0
void iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
{
	struct scatterlist tmp;

	sg_init_one(&tmp, buf, len);
	crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1);
}
예제 #4
0
static inline void
partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn,
			 struct scatterlist *sg, int offset, int length)
{
	struct scatterlist temp;

	memcpy(&temp, sg, sizeof(struct scatterlist));
	temp.offset = offset;
	temp.length = length;
	crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1);
}
예제 #5
0
static void digsig_sha1_update(SIGCTX * ctx, char *buf, int buflen)
{
	char *plaintext;

	memcpy(ctx->tvmem, buf, buflen);
	plaintext = (void *) ctx->tvmem;

	ctx->sg[0].page = virt_to_page((unsigned long)plaintext);
	ctx->sg[0].offset = ((long) plaintext & ~PAGE_MASK);
	ctx->sg[0].length = buflen;

	crypto_digest_update(ctx->tfm, ctx->sg, 1);
}
예제 #6
0
파일: verify.c 프로젝트: AlD/bareos
/*
 * Compute message digest for the file specified by ff_pkt.
 * In case of errors we need the job control record and file name.
 */
int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest)
{
   BFILE bfd;

   Dmsg0(50, "=== digest_file\n");
   binit(&bfd);

   if (ff_pkt->statp.st_size > 0 ||
       ff_pkt->type == FT_RAW ||
       ff_pkt->type == FT_FIFO) {
      int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
      if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0, ff_pkt->statp.st_rdev)) < 0) {
         ff_pkt->ff_errno = errno;
         berrno be;
         be.set_errno(bfd.berrno);
         Dmsg2(100, "Cannot open %s: ERR=%s\n", ff_pkt->fname, be.bstrerror());
         Jmsg(jcr, M_ERROR, 1, _("     Cannot open %s: ERR=%s.\n"),
               ff_pkt->fname, be.bstrerror());
         return 1;
      }
      read_digest(&bfd, digest, jcr);
      bclose(&bfd);
   }

   if (have_darwin_os) {
      /*
       * Open resource fork if necessary
       */
      if (ff_pkt->flags & FO_HFSPLUS && ff_pkt->hfsinfo.rsrclength > 0) {
         if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
            ff_pkt->ff_errno = errno;
            berrno be;
            Jmsg(jcr, M_ERROR, -1, _("     Cannot open resource fork for %s: ERR=%s.\n"),
                  ff_pkt->fname, be.bstrerror());
            if (is_bopen(&ff_pkt->bfd)) {
               bclose(&ff_pkt->bfd);
            }
            return 1;
         }
         read_digest(&bfd, digest, jcr);
         bclose(&bfd);
      }

      if (digest && ff_pkt->flags & FO_HFSPLUS) {
         crypto_digest_update(digest, (uint8_t *)ff_pkt->hfsinfo.fndrinfo, 32);
      }
   }
   return 0;
}
예제 #7
0
파일: verify.c 프로젝트: rustyangel/bareos
/*
 * Read message digest of bfd, updating digest
 * In case of errors we need the job control record and file name.
 */
static int read_digest(BFILE *bfd, DIGEST *digest, JCR *jcr)
{
   char buf[DEFAULT_NETWORK_BUFFER_SIZE];
   int64_t n;
   int64_t bufsiz = (int64_t)sizeof(buf);
   FF_PKT *ff_pkt = (FF_PKT *)jcr->ff;
   uint64_t fileAddr = 0;             /* file address */


   Dmsg0(50, "=== read_digest\n");
   while ((n=bread(bfd, buf, bufsiz)) > 0) {
      /* Check for sparse blocks */
      if (ff_pkt->flags & FO_SPARSE) {
         bool allZeros = false;
         if ((n == bufsiz &&
              fileAddr+n < (uint64_t)ff_pkt->statp.st_size) ||
             ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
               (uint64_t)ff_pkt->statp.st_size == 0)) {
            allZeros = is_buf_zero(buf, bufsiz);
         }
         fileAddr += n;               /* update file address */
         /* Skip any block of all zeros */
         if (allZeros) {
            continue;                 /* skip block of zeros */
         }
      }

      crypto_digest_update(digest, (uint8_t *)buf, n);

      /* Can be used by BaseJobs or with accurate, update only for Verify
       * jobs
       */
      if (jcr->getJobType() == JT_VERIFY) {
         jcr->JobBytes += n;
      }
      jcr->ReadBytes += n;
   }
   if (n < 0) {
      berrno be;
      be.set_errno(bfd->berrno);
      Dmsg2(100, "Error reading file %s: ERR=%s\n", jcr->last_fname, be.bstrerror());
      Jmsg(jcr, M_ERROR, 1, _("Error reading file %s: ERR=%s\n"),
            jcr->last_fname, be.bstrerror());
      jcr->JobErrors++;
      return -1;
   }
   return 0;
}
예제 #8
0
/*
 * Digest one segment
 */
int
smb_md5_update(smb_sign_ctx_t ctx, void *buf, size_t len)
{
	crypto_data_t data;
	int rv;

	bzero(&data, sizeof (data));
	data.cd_format = CRYPTO_DATA_RAW;
	data.cd_length = len;
	data.cd_raw.iov_base = buf;
	data.cd_raw.iov_len = len;

	rv = crypto_digest_update(ctx, &data, 0);

	return (rv == CRYPTO_SUCCESS ? 0 : -1);
}
예제 #9
0
파일: hmac.c 프로젝트: chm088/linux-2.6.18
void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
{
	unsigned int i;
	struct scatterlist tmp;
	char *ipad = tfm->crt_digest.dit_hmac_block;
	
	if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
		hash_key(tfm, key, *keylen);
		*keylen = crypto_tfm_alg_digestsize(tfm);
	}

	memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
	memcpy(ipad, key, *keylen);

	for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
		ipad[i] ^= 0x36;

	sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
	
	crypto_digest_init(tfm);
	crypto_digest_update(tfm, &tmp, 1);
}
예제 #10
0
파일: backup.c 프로젝트: tuxmux/bareos
/*
 * Handle the data just read and send it to the SD after doing any postprocessing needed.
 */
static inline bool send_data_to_sd(b_ctx *bctx)
{
   BSOCK *sd = bctx->jcr->store_bsock;
   bool need_more_data;

   /*
    * Check for sparse blocks
    */
   if (bit_is_set(FO_SPARSE, bctx->ff_pkt->flags)) {
      bool allZeros;
      ser_declare;

      allZeros = false;
      if ((sd->msglen == bctx->rsize &&
          (bctx->fileAddr + sd->msglen < (uint64_t)bctx->ff_pkt->statp.st_size)) ||
          ((bctx->ff_pkt->type == FT_RAW ||
            bctx->ff_pkt->type == FT_FIFO) &&
          ((uint64_t)bctx->ff_pkt->statp.st_size == 0))) {
         allZeros = is_buf_zero(bctx->rbuf, bctx->rsize);
      }

      if (!allZeros) {
         /*
          * Put file address as first data in buffer
          */
         ser_begin(bctx->wbuf, OFFSET_FADDR_SIZE);
         ser_uint64(bctx->fileAddr); /* store fileAddr in begin of buffer */
      }

      bctx->fileAddr += sd->msglen; /* update file address */

      /*
       * Skip block of all zeros
       */
      if (allZeros) {
         return true;
      }
   } else if (bit_is_set(FO_OFFSETS, bctx->ff_pkt->flags)) {
      ser_declare;
      ser_begin(bctx->wbuf, OFFSET_FADDR_SIZE);
      ser_uint64(bctx->ff_pkt->bfd.offset); /* store offset in begin of buffer */
   }

   bctx->jcr->ReadBytes += sd->msglen; /* count bytes read */

   /*
    * Uncompressed cipher input length
    */
   bctx->cipher_input_len = sd->msglen;

   /*
    * Update checksum if requested
    */
   if (bctx->digest) {
      crypto_digest_update(bctx->digest, (uint8_t *)bctx->rbuf, sd->msglen);
   }

   /*
    * Update signing digest if requested
    */
   if (bctx->signing_digest) {
      crypto_digest_update(bctx->signing_digest, (uint8_t *)bctx->rbuf, sd->msglen);
   }

   /*
    * Compress the data.
    */
   if (bit_is_set(FO_COMPRESS, bctx->ff_pkt->flags)) {
      if (!compress_data(bctx->jcr, bctx->ff_pkt->Compress_algo, bctx->rbuf,
                         bctx->jcr->store_bsock->msglen, bctx->cbuf,
                         bctx->max_compress_len, &bctx->compress_len)) {
         return false;
      }

      /*
       * See if we need to generate a compression header.
       */
      if (bctx->chead) {
         ser_declare;

         /*
          * Complete header
          */
         ser_begin(bctx->chead, sizeof(comp_stream_header));
         ser_uint32(bctx->ch.magic);
         ser_uint32(bctx->compress_len);
         ser_uint16(bctx->ch.level);
         ser_uint16(bctx->ch.version);
         ser_end(bctx->chead, sizeof(comp_stream_header));

         bctx->compress_len += sizeof(comp_stream_header); /* add size of header */
      }

      bctx->jcr->store_bsock->msglen = bctx->compress_len; /* set compressed length */
      bctx->cipher_input_len = bctx->compress_len;
   }

   /*
    * Encrypt the data.
    */
   need_more_data = false;
   if (bit_is_set(FO_ENCRYPT, bctx->ff_pkt->flags) && !encrypt_data(bctx, &need_more_data)) {
      if (need_more_data) {
         return true;
      }
      return false;
   }

   /*
    * Send the buffer to the Storage daemon
    */
   if (bit_is_set(FO_SPARSE, bctx->ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx->ff_pkt->flags)) {
      sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
   }
   sd->msg = bctx->wbuf; /* set correct write buffer */

   if (!sd->send()) {
      if (!bctx->jcr->is_job_canceled()) {
         Jmsg1(bctx->jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
      }
      return false;
   }

   Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
   bctx->jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
   sd->msg = bctx->msgsave; /* restore read buffer */

   return true;
}
예제 #11
0
파일: backup.c 프로젝트: halgandd/bacula
/*
 * Send data read from an already open file descriptor.
 *
 * We return 1 on sucess and 0 on errors.
 *
 * ***FIXME***
 * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
 *  reading.
 * Currently this is not a problem as the only other stream, resource forks,
 * are not handled as sparse files.
 */
static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, 
                     DIGEST *signing_digest)
{
   BSOCK *sd = jcr->store_bsock;
   uint64_t fileAddr = 0;             /* file address */
   char *rbuf, *wbuf;
   int32_t rsize = jcr->buf_size;      /* read buffer size */
   POOLMEM *msgsave;
   CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
   const uint8_t *cipher_input;
   uint32_t cipher_input_len;
   uint32_t cipher_block_size;
   uint32_t encrypted_len;
#ifdef FD_NO_SEND_TEST
   return 1;
#endif

   msgsave = sd->msg;
   rbuf = sd->msg;                    /* read buffer */
   wbuf = sd->msg;                    /* write buffer */
   cipher_input = (uint8_t *)rbuf;    /* encrypt uncompressed data */

   Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);

#ifdef HAVE_LIBZ
   uLong compress_len = 0;
   uLong max_compress_len = 0;
   const Bytef *cbuf = NULL;
   int zstat;

   if (ff_pkt->flags & FO_GZIP) {
      if (ff_pkt->flags & FO_SPARSE) {
         cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
         max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
      } else {
         cbuf = (Bytef *)jcr->compress_buf;
         max_compress_len = jcr->compress_buf_size; /* set max length */
      }
      wbuf = jcr->compress_buf;    /* compressed output here */
      cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */

      /* 
       * Only change zlib parameters if there is no pending operation.
       * This should never happen as deflatereset is called after each
       * deflate.
       */

      if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
         /* set gzip compression level - must be done per file */
         if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset, 
              ff_pkt->GZIP_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
            Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
            set_jcr_job_status(jcr, JS_ErrorTerminated);
            goto err;
         }
      }
   }
#else
   const uint32_t max_compress_len = 0;
#endif

   if (ff_pkt->flags & FO_ENCRYPT) {
      if (ff_pkt->flags & FO_SPARSE) {
         Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse data not supported.\n"));
         goto err;
      }
      /* Allocate the cipher context */
      if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true, 
           &cipher_block_size)) == NULL) {
         /* Shouldn't happen! */
         Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
         goto err;
      }

      /*
       * Grow the crypto buffer, if necessary.
       * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
       * We grow crypto_buf to the maximum number of blocks that
       * could be returned for the given read buffer size.
       * (Using the larger of either rsize or max_compress_len)
       */
      jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf, 
           (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) + 
            cipher_block_size - 1) / cipher_block_size * cipher_block_size);

      wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
   }

   /*
    * Send Data header to Storage daemon
    *    <file-index> <stream> <info>
    */
   if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
            sd->bstrerror());
      goto err;
   }
   Dmsg1(300, ">stored: datahdr %s\n", sd->msg);

   /*
    * Make space at beginning of buffer for fileAddr because this
    *   same buffer will be used for writing if compression is off.
    */
   if (ff_pkt->flags & FO_SPARSE) {
      rbuf += SPARSE_FADDR_SIZE;
      rsize -= SPARSE_FADDR_SIZE;
#ifdef HAVE_FREEBSD_OS
      /*
       * To read FreeBSD partitions, the read size must be
       *  a multiple of 512.
       */
      rsize = (rsize/512) * 512;
#endif
   }

   /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
#ifdef HAVE_WIN32
   if (S_ISBLK(ff_pkt->statp.st_mode))
      rsize = (rsize/512) * 512;
#endif
   
   /*
    * Read the file data
    */
   while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {

      /* Check for sparse blocks */
      if (ff_pkt->flags & FO_SPARSE) {
         ser_declare;
         bool allZeros = false;
         if ((sd->msglen == rsize &&
              fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
             ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
               (uint64_t)ff_pkt->statp.st_size == 0)) {
            allZeros = is_buf_zero(rbuf, rsize);
         }
         if (!allZeros) {
            /* Put file address as first data in buffer */
            ser_begin(wbuf, SPARSE_FADDR_SIZE);
            ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
         }
         fileAddr += sd->msglen;      /* update file address */
         /* Skip block of all zeros */
         if (allZeros) {
            continue;                 /* skip block of zeros */
         }
      }

      jcr->ReadBytes += sd->msglen;         /* count bytes read */

      /* Uncompressed cipher input length */
      cipher_input_len = sd->msglen;

      /* Update checksum if requested */
      if (digest) {
         crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
      }

      /* Update signing digest if requested */
      if (signing_digest) {
         crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
      }

#ifdef HAVE_LIBZ
      /* Do compression if turned on */
      if (ff_pkt->flags & FO_GZIP && jcr->pZLIB_compress_workset) {
         Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
         
         ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (Bytef *)rbuf;
                ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
         ((z_stream*)jcr->pZLIB_compress_workset)->next_out  = (Bytef *)cbuf;
                ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;

         if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
            Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
            set_jcr_job_status(jcr, JS_ErrorTerminated);
            goto err;
         }
         compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
         /* reset zlib stream to be able to begin from scratch again */
         if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
            Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
            set_jcr_job_status(jcr, JS_ErrorTerminated);
            goto err;
         }

         Dmsg2(400, "compressed len=%d uncompressed len=%d\n", compress_len, 
               sd->msglen);

         sd->msglen = compress_len;      /* set compressed length */
         cipher_input_len = compress_len;
      }
#endif
      /* 
       * Note, here we prepend the current record length to the beginning
       *  of the encrypted data. This is because both sparse and compression
       *  restore handling want records returned to them with exactly the
       *  same number of bytes that were processed in the backup handling.
       *  That is, both are block filters rather than a stream.  When doing
       *  compression, the compression routines may buffer data, so that for
       *  any one record compressed, when it is decompressed the same size
       *  will not be obtained. Of course, the buffered data eventually comes
       *  out in subsequent crypto_cipher_update() calls or at least
       *  when crypto_cipher_finalize() is called.  Unfortunately, this
       *  "feature" of encryption enormously complicates the restore code.
       */
      if (ff_pkt->flags & FO_ENCRYPT) {
         uint32_t initial_len = 0;
         ser_declare;

         if (ff_pkt->flags & FO_SPARSE) {
            cipher_input_len += SPARSE_FADDR_SIZE;
         }

         /* Encrypt the length of the input block */
         uint8_t packet_len[sizeof(uint32_t)];

         ser_begin(packet_len, sizeof(uint32_t));
         ser_uint32(cipher_input_len);    /* store data len in begin of buffer */
         Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);

         if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
             (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
            /* Encryption failed. Shouldn't happen. */
            Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
            goto err;
         }

         /* Encrypt the input block */
         if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len, 
             (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
            if ((initial_len + encrypted_len) == 0) {
               /* No full block of data available, read more data */
               continue;
            }
            Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len, 
                  sd->msglen);
            sd->msglen = initial_len + encrypted_len; /* set encrypted length */
         } else {
            /* Encryption failed. Shouldn't happen. */
            Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
            goto err;
         }
      }

      /* Send the buffer to the Storage daemon */
      if (ff_pkt->flags & FO_SPARSE) {
         sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
      }
      sd->msg = wbuf;              /* set correct write buffer */
      if (!sd->send()) {
         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
               sd->bstrerror());
         goto err;
      }
      Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
      /*          #endif */
      jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed/encrypted */
      sd->msg = msgsave;                /* restore read buffer */

   } /* end while read file data */

   if (sd->msglen < 0) {                 /* error */
      berrno be;
      Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
         ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
      if (jcr->JobErrors++ > 1000) {       /* insanity check */
         Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
      }
   } else if (ff_pkt->flags & FO_ENCRYPT) {
      /* 
       * For encryption, we must call finalize to push out any
       *  buffered data.
       */
      if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf, 
           &encrypted_len)) {
         /* Padding failed. Shouldn't happen. */
         Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
         goto err;
      }

      /* Note, on SSL pre-0.9.7, there is always some output */
      if (encrypted_len > 0) {
         sd->msglen = encrypted_len;      /* set encrypted length */
         sd->msg = jcr->crypto.crypto_buf;       /* set correct write buffer */
         if (!sd->send()) {
            Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
                  sd->bstrerror());
            goto err;
         }
         Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
         jcr->JobBytes += sd->msglen;     /* count bytes saved possibly compressed/encrypted */
         sd->msg = msgsave;               /* restore bnet buffer */
      }
   }

   if (!sd->signal(BNET_EOD)) {        /* indicate end of file data */
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
            sd->bstrerror());
      goto err;
   }

   /* Free the cipher context */
   if (cipher_ctx) {
      crypto_cipher_free(cipher_ctx);
   }
   return 1;

err:
   /* Free the cipher context */
   if (cipher_ctx) {
      crypto_cipher_free(cipher_ctx);
   }

   sd->msg = msgsave; /* restore bnet buffer */
   sd->msglen = 0;
   return 0;
}
예제 #12
0
/**
 * iscsi_tcp_data_recv - TCP receive in sendfile fashion
 * @rd_desc: read descriptor
 * @skb: socket buffer
 * @offset: offset in skb
 * @len: skb->len - offset
 **/
static int
iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
		    unsigned int offset, size_t len)
{
	int rc;
	struct iscsi_conn *conn = rd_desc->arg.data;
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	int processed;
	char pad[ISCSI_PAD_LEN];
	struct scatterlist sg;

	/*
	 * Save current SKB and its offset in the corresponding
	 * connection context.
	 */
	tcp_conn->in.copy = skb->len - offset;
	tcp_conn->in.offset = offset;
	tcp_conn->in.skb = skb;
	tcp_conn->in.len = tcp_conn->in.copy;
	BUG_ON(tcp_conn->in.copy <= 0);
	debug_tcp("in %d bytes\n", tcp_conn->in.copy);

more:
	tcp_conn->in.copied = 0;
	rc = 0;

	if (unlikely(conn->suspend_rx)) {
		debug_tcp("conn %d Rx suspended!\n", conn->id);
		return 0;
	}

	if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER ||
	    tcp_conn->in_progress == IN_PROGRESS_HEADER_GATHER) {
		rc = iscsi_hdr_extract(tcp_conn);
		if (rc) {
		       if (rc == -EAGAIN)
				goto nomore;
		       else {
				iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
				return 0;
		       }
		}

		/*
		 * Verify and process incoming PDU header.
		 */

		rc = tcp_conn->ops->hdr_recv(conn);
		if (!rc && tcp_conn->in.datalen) {
			if (conn->datadgst_en) {
				BUG_ON(!tcp_conn->data_rx_tfm);
				crypto_digest_init(tcp_conn->data_rx_tfm);
			}
			tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
		} else if (rc) {
			iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
			return 0;
		}
	}

	if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
		uint32_t recv_digest;

		debug_tcp("extra data_recv offset %d copy %d\n",
			  tcp_conn->in.offset, tcp_conn->in.copy);
		skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
				&recv_digest, 4);
		tcp_conn->in.offset += 4;
		tcp_conn->in.copy -= 4;
		if (recv_digest != tcp_conn->in.datadgst) {
			debug_tcp("iscsi_tcp: data digest error!"
				  "0x%x != 0x%x\n", recv_digest,
				  tcp_conn->in.datadgst);
			iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
			return 0;
		} else {
			debug_tcp("iscsi_tcp: data digest match!"
				  "0x%x == 0x%x\n", recv_digest,
				  tcp_conn->in.datadgst);
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
		}
	}

	if (unlikely(conn->suspend_rx)) {
		debug_tcp("conn %d Rx suspended!\n", conn->id);
		goto nomore;
	}

	if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV &&
	   tcp_conn->in.copy) {

		debug_tcp("data_recv offset %d copy %d\n",
		       tcp_conn->in.offset, tcp_conn->in.copy);

		rc = tcp_conn->ops->data_recv(conn);
		if (rc) {
			if (rc == -EAGAIN)
				goto again;
			iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
			return 0;
		}
		tcp_conn->in.copy -= tcp_conn->in.padding;
		tcp_conn->in.offset += tcp_conn->in.padding;
		if (conn->datadgst_en) {
			if (tcp_conn->in.padding) {
				debug_tcp("padding -> %d\n",
					  tcp_conn->in.padding);
				memset(pad, 0, tcp_conn->in.padding);
				sg_init_one(&sg, pad, tcp_conn->in.padding);
				crypto_digest_update(tcp_conn->data_rx_tfm,
						     &sg, 1);
			}
			crypto_digest_final(tcp_conn->data_rx_tfm,
					    (u8 *) & tcp_conn->in.datadgst);
			debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
			tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
		} else
			tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
	}

	debug_tcp("f, processed %d from out of %d padding %d\n",
	       tcp_conn->in.offset - offset, (int)len, tcp_conn->in.padding);
	BUG_ON(tcp_conn->in.offset - offset > len);

	if (tcp_conn->in.offset - offset != len) {
		debug_tcp("continue to process %d bytes\n",
		       (int)len - (tcp_conn->in.offset - offset));
		goto more;
	}

nomore:
	processed = tcp_conn->in.offset - offset;
	BUG_ON(processed == 0);
	return processed;

again:
	processed = tcp_conn->in.offset - offset;
	debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",
	          processed, (int)len, (int)rd_desc->count);
	BUG_ON(processed == 0);
	BUG_ON(processed > len);

	conn->rxdata_octets += processed;
	return processed;
}
예제 #13
0
int iscsi_scsi_data_in(struct iscsi_conn *conn)
{
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_cmd_task *ctask = tcp_conn->in.ctask;
	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
	struct scsi_cmnd *sc = ctask->sc;
	struct scatterlist *sg;
	int i, offset, rc = 0;

	BUG_ON((void*)ctask != sc->SCp.ptr);

	/*
	 * copying Data-In into the Scsi_Cmnd
	 */
	if (!sc->use_sg) {
		i = ctask->data_count;
		rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer,
				      sc->request_bufflen,
				      tcp_ctask->data_offset);
		if (rc == -EAGAIN)
			return rc;
		if (conn->datadgst_en)
			iscsi_recv_digest_update(tcp_conn, sc->request_buffer,
						 i);
		return 0;
	}

	offset = tcp_ctask->data_offset;
	sg = sc->request_buffer;

	if (tcp_ctask->data_offset)
		for (i = 0; i < tcp_ctask->sg_count; i++)
			offset -= sg[i].length;
	/* we've passed through partial sg*/
	if (offset < 0)
		offset = 0;

	for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) {
		char *dest;

		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
				      sg[i].length, offset);
		kunmap_atomic(dest, KM_SOFTIRQ0);
		if (rc == -EAGAIN)
			/* continue with the next SKB/PDU */
			return rc;
		if (!rc) {
			if (conn->datadgst_en) {
				if (!offset)
					crypto_digest_update(
							tcp_conn->data_rx_tfm,
							&sg[i], 1);
				else
					partial_sg_digest_update(tcp_conn,
							&sg[i],
							sg[i].offset + offset,
							sg[i].length - offset);
			}
			offset = 0;
			tcp_ctask->sg_count++;
		}

		if (!ctask->data_count) {
			if (rc && conn->datadgst_en)
				/*
				 * data-in is complete, but buffer not...
				 */
				partial_sg_digest_update(tcp_conn, &sg[i],
						sg[i].offset, sg[i].length-rc);
			rc = 0;
			break;
		}

		if (!tcp_conn->in.copy)
			return -EAGAIN;
	}
	BUG_ON(ctask->data_count);

	return rc;
}
예제 #14
0
int
k5_ef_hash(krb5_context context, int icount,
           const krb5_data *input,
           krb5_data *output)
{
    int i;
    int rv = CRYPTO_FAILED;
    iovec_t v1, v2;
    crypto_data_t d1, d2;
    crypto_mechanism_t mech;
    crypto_context_t ctxp;

    KRB5_LOG0(KRB5_INFO, "k5_ef_hash() start");

    bzero(&d1, sizeof (d1));
    bzero(&d2, sizeof (d2));

    v2.iov_base = (void *)output->data;
    v2.iov_len = output->length;

    d2.cd_format = CRYPTO_DATA_RAW;
    d2.cd_offset = 0;
    d2.cd_length = output->length;
    d2.cd_raw = v2;

    mech.cm_type = context->kef_cksum_mt;
    if (mech.cm_type == CRYPTO_MECH_INVALID) {
        KRB5_LOG(KRB5_ERR,
                 "k5_ef_hash() invalid mech specified: 0x%llx",
                 (long long)context->kef_hash_mt);
        return (CRYPTO_FAILED);
    }
    mech.cm_param = 0;
    mech.cm_param_len = 0;

    rv = crypto_digest_init(&mech, &ctxp, NULL);
    if (rv != CRYPTO_SUCCESS) {
        KRB5_LOG(KRB5_ERR, "crypto_digest_init error: %0x", rv);
        return (rv);
    }

    for (i = 0; i < icount; i++) {
        v1.iov_base = (void *)input[i].data;
        v1.iov_len = input[i].length;
        d1.cd_length = input[i].length;
        d1.cd_format = CRYPTO_DATA_RAW;
        d1.cd_offset = 0;
        d1.cd_raw = v1;

        rv = crypto_digest_update(ctxp, &d1, NULL);
        if (rv != CRYPTO_SUCCESS) {
            KRB5_LOG(KRB5_ERR,
                     "crypto_digest_update error: %0x", rv);
            crypto_cancel_ctx(ctxp);
            return (rv);
        }
    }

    rv = crypto_digest_final(ctxp, &d2, NULL);
    /*
     * crypto_digest_final() internally destroys the context. So, we
     * do not use the context any more. This means we do not call
     * crypto_cancel_ctx() for the failure case here unlike the failure
     * case of crypto_digest_update() where we do.
     */
    if (rv != CRYPTO_SUCCESS) {
        KRB5_LOG(KRB5_ERR, "crypto_digest_final error: %0x", rv);
    }

    return (rv);
}
예제 #15
0
파일: backup.c 프로젝트: halgandd/bacula
/*
 * Called here by find() for each file included.
 *   This is a callback. The original is find_files() above.
 *
 *  Send the file and its data to the Storage daemon.
 *
 *  Returns: 1 if OK
 *           0 if error
 *          -1 to ignore file/directory (not used here)
 */
int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
{
   bool do_read = false;
   int stat, data_stream; 
   int rtnstat = 0;
   DIGEST *digest = NULL;
   DIGEST *signing_digest = NULL;
   int digest_stream = STREAM_NONE;
   SIGNATURE *sig = NULL;
   bool has_file_data = false;
   // TODO landonf: Allow the user to specify the digest algorithm
#ifdef HAVE_SHA2
   crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
#else
   crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
#endif
   BSOCK *sd = jcr->store_bsock;

   if (job_canceled(jcr)) {
      return 0;
   }

   jcr->num_files_examined++;         /* bump total file count */

   switch (ff_pkt->type) {
   case FT_LNKSAVED:                  /* Hard linked, file already saved */
      Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
      break;
   case FT_REGE:
      Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
      has_file_data = true;
      break;
   case FT_REG:
      Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
      has_file_data = true;
      break;
   case FT_LNK:
      Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
      break;
   case FT_DIRBEGIN:
      jcr->num_files_examined--;      /* correct file count */
      return 1;                       /* not used */
   case FT_NORECURSE:
      Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend from %s into %s\n"),
           ff_pkt->top_fname, ff_pkt->fname);
      ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
      break;
   case FT_NOFSCHG:
      /* Suppress message for /dev filesystems */
      if (!is_in_fileset(ff_pkt)) {
         Jmsg(jcr, M_INFO, 1, _("     %s is a different filesystem. Will not descend from %s into %s\n"),
              ff_pkt->fname, ff_pkt->top_fname, ff_pkt->fname);
      }
      ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
      break;
   case FT_INVALIDFS:
      Jmsg(jcr, M_INFO, 1, _("     Disallowed filesystem. Will not descend from %s into %s\n"),
           ff_pkt->top_fname, ff_pkt->fname);
      ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
      break;
   case FT_INVALIDDT:
      Jmsg(jcr, M_INFO, 1, _("     Disallowed drive type. Will not descend into %s\n"),
           ff_pkt->fname);
      break;
   case FT_REPARSE:
   case FT_DIREND:
      Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
      break;
   case FT_SPEC:
      Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
      if (S_ISSOCK(ff_pkt->statp.st_mode)) {
        Jmsg(jcr, M_SKIPPED, 1, _("     Socket file skipped: %s\n"), ff_pkt->fname);
        return 1;
      }
      break;
   case FT_RAW:
      Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
      has_file_data = true;
      break;
   case FT_FIFO:
      Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
      break;
   case FT_NOACCESS: {
      berrno be;
      Jmsg(jcr, M_NOTSAVED, 0, _("     Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
         be.bstrerror(ff_pkt->ff_errno));
      jcr->JobErrors++;
      return 1;
   }
   case FT_NOFOLLOW: {
      berrno be;
      Jmsg(jcr, M_NOTSAVED, 0, _("     Could not follow link \"%s\": ERR=%s\n"), 
           ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
      jcr->JobErrors++;
      return 1;
   }
   case FT_NOSTAT: {
      berrno be;
      Jmsg(jcr, M_NOTSAVED, 0, _("     Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
         be.bstrerror(ff_pkt->ff_errno));
      jcr->JobErrors++;
      return 1;
   }
   case FT_DIRNOCHG:
   case FT_NOCHG:
      Jmsg(jcr, M_SKIPPED, 1, _("     Unchanged file skipped: %s\n"), ff_pkt->fname);
      return 1;
   case FT_ISARCH:
      Jmsg(jcr, M_NOTSAVED, 0, _("     Archive file not saved: %s\n"), ff_pkt->fname);
      return 1;
   case FT_NOOPEN: {
      berrno be;
      Jmsg(jcr, M_NOTSAVED, 0, _("     Could not open directory \"%s\": ERR=%s\n"), 
           ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
      jcr->JobErrors++;
      return 1;
   }
   default:
      Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"), 
           ff_pkt->type, ff_pkt->fname);
      jcr->JobErrors++;
      return 1;
   }

   Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);

   /* Digests and encryption are only useful if there's file data */
   if (has_file_data) {
      /*
       * Setup for digest handling. If this fails, the digest will be set to NULL
       * and not used. Note, the digest (file hash) can be any one of the four
       * algorithms below.
       *
       * The signing digest is a single algorithm depending on
       * whether or not we have SHA2.              
       *   ****FIXME****  the signing algoritm should really be
       *   determined a different way!!!!!!  What happens if
       *   sha2 was available during backup but not restore?
       */
      if (ff_pkt->flags & FO_MD5) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
         digest_stream = STREAM_MD5_DIGEST;

      } else if (ff_pkt->flags & FO_SHA1) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
         digest_stream = STREAM_SHA1_DIGEST;

      } else if (ff_pkt->flags & FO_SHA256) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
         digest_stream = STREAM_SHA256_DIGEST;

      } else if (ff_pkt->flags & FO_SHA512) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
         digest_stream = STREAM_SHA512_DIGEST;
      }

      /* Did digest initialization fail? */
      if (digest_stream != STREAM_NONE && digest == NULL) {
         Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
            stream_to_ascii(digest_stream));
      }

      /*
       * Set up signature digest handling. If this fails, the signature digest will be set to
       * NULL and not used.
       */
      // TODO landonf: We should really only calculate the digest once, for both verification and signing.
      if (jcr->crypto.pki_sign) {
         signing_digest = crypto_digest_new(jcr, signing_algorithm);

         /* Full-stop if a failure occurred initializing the signature digest */
         if (signing_digest == NULL) {
            Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
               stream_to_ascii(signing_algorithm));
            jcr->JobErrors++;
            goto good_rtn;
         }
      }

      /* Enable encryption */
      if (jcr->crypto.pki_encrypt) {
         ff_pkt->flags |= FO_ENCRYPT;
      }
   }

   /* Initialize the file descriptor we use for data and other streams. */
   binit(&ff_pkt->bfd);
   if (ff_pkt->flags & FO_PORTABLE) {
      set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
   }
   if (ff_pkt->cmd_plugin) {
      if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
         goto bail_out;
      }
      send_plugin_name(jcr, sd, true);      /* signal start of plugin data */
   }

   /* Send attributes -- must be done after binit() */
   if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
      goto bail_out;
   }

   /* Set up the encryption context and send the session data to the SD */
   if (has_file_data && jcr->crypto.pki_encrypt) {
      if (!crypto_session_send(jcr, sd)) {
         goto bail_out;
      }
   }

   /*
    * Open any file with data that we intend to save, then save it.
    *
    * Note, if is_win32_backup, we must open the Directory so that
    * the BackupRead will save its permissions and ownership streams.
    */
   if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
#ifdef HAVE_WIN32
      do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
#else
      do_read = ff_pkt->statp.st_size > 0;  
#endif
   } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
              ff_pkt->type == FT_REPARSE ||
         (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
      do_read = true;
   }
   if (ff_pkt->cmd_plugin) {
      do_read = true;
   }

   Dmsg1(400, "do_read=%d\n", do_read);
   if (do_read) {
      btimer_t *tid;

      if (ff_pkt->type == FT_FIFO) {
         tid = start_thread_timer(jcr, pthread_self(), 60);
      } else {
         tid = NULL;
      }
      int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
      ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE;
      if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
         ff_pkt->ff_errno = errno;
         berrno be;
         Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
              be.bstrerror());
         jcr->JobErrors++;
         if (tid) {
            stop_thread_timer(tid);
            tid = NULL;
         }
         goto good_rtn;
      }
      if (tid) {
         stop_thread_timer(tid);
         tid = NULL;
      }

      stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);

      if (ff_pkt->flags & FO_CHKCHANGES) {
         has_file_changed(jcr, ff_pkt);
      }

      bclose(&ff_pkt->bfd);
      
      if (!stat) {
         goto bail_out;
      }
   }

#ifdef HAVE_DARWIN_OS
   /* Regular files can have resource forks and Finder Info */
   if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
            ff_pkt->flags & FO_HFSPLUS)) {
      if (ff_pkt->hfsinfo.rsrclength > 0) {
         int flags;
         int rsrc_stream;
         if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
            ff_pkt->ff_errno = errno;
            berrno be;
            Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"), 
                 ff_pkt->fname, be.bstrerror());
            jcr->JobErrors++;
            if (is_bopen(&ff_pkt->bfd)) {
               bclose(&ff_pkt->bfd);
            }
            goto good_rtn;
         }
         flags = ff_pkt->flags;
         ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
         if (flags & FO_ENCRYPT) {
            rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
         } else {
            rsrc_stream = STREAM_MACOS_FORK_DATA;
         }
         stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
         ff_pkt->flags = flags;
         bclose(&ff_pkt->bfd);
         if (!stat) {
            goto bail_out;
         }
      }

      Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
      sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
      Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
      pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
      sd->msglen = 32;
      if (digest) {
         crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
      }
      if (signing_digest) {
         crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
      }
      sd->send();
      sd->signal(BNET_EOD);
   }
#endif

   /*
    * Save ACLs for anything not being a symlink and not being a plugin.
    */
   if (!ff_pkt->cmd_plugin) {
      if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK) {
         if (!build_acl_streams(jcr, ff_pkt))
            goto bail_out;
      }
   }

   /*
    * Save Extended Attributes for all files not being a plugin.
    */
   if (!ff_pkt->cmd_plugin) {
      if (ff_pkt->flags & FO_XATTR) {
         if (!build_xattr_streams(jcr, ff_pkt))
            goto bail_out;
      }
   }

   /* Terminate the signing digest and send it to the Storage daemon */
   if (signing_digest) {
      uint32_t size = 0;

      if ((sig = crypto_sign_new(jcr)) == NULL) {
         Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
         goto bail_out;
      }

      if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
         Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
         goto bail_out;
      }

      /* Get signature size */
      if (!crypto_sign_encode(sig, NULL, &size)) {
         Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
         goto bail_out;
      }

      /* Grow the bsock buffer to fit our message if necessary */
      if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
         sd->msg = realloc_pool_memory(sd->msg, size);
      }

      /* Send our header */
      sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
      Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);

      /* Encode signature data */
      if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
         Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
         goto bail_out;
      }

      sd->msglen = size;
      sd->send();
      sd->signal(BNET_EOD);              /* end of checksum */
   }

   /* Terminate any digest and send it to Storage daemon */
   if (digest) {
      uint32_t size;

      sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
      Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);

      size = CRYPTO_DIGEST_MAX_SIZE;

      /* Grow the bsock buffer to fit our message if necessary */
      if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
         sd->msg = realloc_pool_memory(sd->msg, size);
      }

      if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
         Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
         goto bail_out;
      }

      sd->msglen = size;
      sd->send();
      sd->signal(BNET_EOD);              /* end of checksum */
   }
   if (ff_pkt->cmd_plugin) {
      send_plugin_name(jcr, sd, false); /* signal end of plugin data */
   }

good_rtn:
   rtnstat = 1;                       /* good return */

bail_out:
   if (digest) {
      crypto_digest_free(digest);
   }
   if (signing_digest) {
      crypto_digest_free(signing_digest);
   }
   if (sig) {
      crypto_sign_free(sig);        
   }
   return rtnstat;
}
예제 #16
0
파일: hmac.c 프로젝트: kzlin129/tt-gpl
void crypto_hmac_update(struct crypto_tfm *tfm,
                        struct scatterlist *sg, unsigned int nsg)
{
	crypto_digest_update(tfm, sg, nsg);
}
예제 #17
0
파일: sha2.c 프로젝트: aeppert/km
int plaintext_to_sha1(unsigned char *hash,
		const char *plaintext, unsigned int len)
{
	struct page *page = NULL;
	char *data = NULL;
	int offset = 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)

	struct crypto_hash *tfm = NULL;
	struct scatterlist sg = {0};
	struct hash_desc desc = {0};

	page = alloc_page(GFP_KERNEL);
	if (!page) {
		return -ENOMEM;
	}
	data = (char *)page_address(page);

	tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		__free_page(page);
		return -EINVAL;
	}

	desc.tfm = tfm;
	desc.flags = 0;

	crypto_hash_init(&desc);
	sg_init_one(&sg, (void *)data, PAGE_SIZE);

	for (offset = 0; offset < len; offset += PAGE_SIZE) {
		memset(data, 0x00, PAGE_SIZE);
		/* Check if the data is page size or part of page */
		if ((len - offset) >= PAGE_SIZE) {
			memcpy(data, plaintext + offset, PAGE_SIZE);
			crypto_hash_update(&desc, &sg, PAGE_SIZE);
		} else {
			memcpy(data, plaintext + offset, (len - offset));
			sg_init_one(&sg, (void *)data, (len - offset));
			crypto_hash_update(&desc, &sg, (len - offset));
		}
	}

	crypto_hash_final(&desc, hash);

	crypto_free_hash(tfm);

#else

	struct crypto_tfm *tfm;
	struct scatterlist sg;

	page = alloc_page(GFP_KERNEL);
	if (!page) {
		return -ENOMEM;
	}
	data = (char *)page_address(page);

	tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP);
	if (tfm == NULL) {
		__free_page(page);
		return -EINVAL;
	}

	crypto_digest_init(tfm);
	sg_init_one(&sg, (u8 *)data, PAGE_SIZE);

	for (offset = 0; offset < len; offset += PAGE_SIZE) {
		memset(data, 0x00, PAGE_SIZE);
		if ((len - offset) >= PAGE_SIZE) {
			memcpy(data, plaintext + offset, PAGE_SIZE);
			crypto_digest_update(tfm, &sg, 1);
		} else {
			memcpy(data, plaintext + offset, (len - offset));
			sg_init_one(&sg, (u8 *)data, (len - offset));
			crypto_digest_update(tfm, &sg, 1);
		}
	}

	crypto_digest_final(tfm, hash);

	crypto_free_tfm(tfm);

#endif

	__free_page(page);
	return 0;

}