示例#1
0
static int
process_file(struct rsa_session *ctx,
	     FILE *in, FILE *out)
{
  uint8_t buffer[BLOCK_SIZE + SHA1_DIGEST_SIZE];

  for (;;)
    {
      size_t size = fread(buffer, 1, BLOCK_SIZE, in);
      hmac_sha1_update(&ctx->hmac, size, buffer);

      if (size < BLOCK_SIZE)
	{
	  unsigned leftover;
	  unsigned padding;

	  if (ferror(in))
	    {
	      werror("Reading input failed: %s\n", strerror(errno));
	      return 0;
	    }
	  
	  leftover = size % AES_BLOCK_SIZE;
	  padding = AES_BLOCK_SIZE - leftover;

	  assert (size + padding <= BLOCK_SIZE);
	  
	  if (padding > 1)
	    yarrow256_random(&ctx->yarrow, padding - 1, buffer + size);

	  size += padding;

	  buffer[size - 1] = padding;
	  CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer);

	  assert (size + SHA1_DIGEST_SIZE <= sizeof(buffer));

	  hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + size);
	  size += SHA1_DIGEST_SIZE;

	  if (!write_string(out, size, buffer))
	    {
	      werror("Writing output failed: %s\n", strerror(errno));
	      return 0;
	    }
	  return 1;
	}

      CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer);
      if (!write_string(out, size, buffer))
	{
	  werror("Writing output failed: %s\n", strerror(errno));
	  return 0;
	}
    }
}
示例#2
0
term_t cbif_sha_mac_n3(proc_t *proc, term_t *regs)
{
	term_t Key = regs[0];
	term_t Data = regs[1];
	term_t Size = regs[2];

	if (!is_list(Key) && !is_boxed_binary(Key))
		badarg(Key);
	if (!is_list(Data) && !is_boxed_binary(Data))
		badarg(Data);
	if (!is_int(Size))
		badarg(Size);

	int trunc_size = int_value(Size);
	if (trunc_size < 1 || trunc_size > SHA1_DIGEST_SIZE)
		badarg(Size);

	int key_size = iolist_size(Key);
	if (key_size < 0)
		badarg(Key);
	assert(key_size <= 65536);	// TODO: use heap_tmp_buf for a longer Key
	uint8_t key_buf[key_size];
	iolist_flatten(Key, key_buf);

	int data_size = iolist_size(Data);
	if (data_size < 0)
		badarg(Data);
	assert(data_size <= 65536);	// TODO: use heap_tmp_buf for larger Data
	uint8_t data_buf[data_size];
	iolist_flatten(Data, data_buf);

	struct hmac_sha1_ctx ctx;
	hmac_sha1_set_key(&ctx, key_size, key_buf);
	hmac_sha1_update(&ctx, data_size, data_buf);

	uint8_t *ptr;
	term_t mac = heap_make_bin(&proc->hp, trunc_size, &ptr);
	hmac_sha1_digest(&ctx, trunc_size, ptr);

	return mac;
}
示例#3
0
static void
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
{
	hmac_sha1_digest(ctx, (unsigned)*out_len, out);
}
示例#4
0
static int
process_file(struct rsa_session *ctx,
	     FILE *in, FILE *out)
{
  uint8_t buffer[BUF_SIZE + BUF_FINAL];
  uint8_t digest[SHA1_DIGEST_SIZE];
  size_t size;
  unsigned padding;

  size = fread(buffer, 1, BUF_FINAL, in);
  if (size < BUF_FINAL)
    {
      if (ferror(in))
	werror("Reading input failed: %s\n", strerror(errno));
      else
	werror("Unexpected EOF on input.\n");
      return 0;
    }

  do
    {
      size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in);

      if (size < BUF_SIZE && ferror(in))
	{
	  werror("Reading input failed: %s\n", strerror(errno));
	  return 0;
	}

      if (size % AES_BLOCK_SIZE != 0)
	{
	  werror("Unexpected EOF on input.\n");
	  return 0;
	}

      if (size)
	{
	  CBC_DECRYPT(&ctx->aes, aes256_decrypt, size, buffer, buffer);
	  hmac_sha1_update(&ctx->hmac, size, buffer);
	  if (!write_data(out, size, buffer))
	    {
	      werror("Writing output failed: %s\n", strerror(errno));
	      return 0;
	    }
	  memmove(buffer, buffer + size, BUF_FINAL);
	}
    }
  while (size == BUF_SIZE);

  /* Decrypt final block */
  CBC_DECRYPT(&ctx->aes, aes256_decrypt, AES_BLOCK_SIZE, buffer, buffer);
  padding = buffer[AES_BLOCK_SIZE - 1];
  if (padding > AES_BLOCK_SIZE)
    {
      werror("Decryption failed: Invalid padding.\n");
      return 0;
    }

  if (padding < AES_BLOCK_SIZE)
    {
      unsigned leftover = AES_BLOCK_SIZE - padding;
      hmac_sha1_update(&ctx->hmac, leftover, buffer);
      if (!write_data(out, leftover, buffer))
	{
	  werror("Writing output failed: %s\n", strerror(errno));
	  return 0;
	}
    }
  hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest);
  if (!memeql_sec(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE))
    {
      werror("Decryption failed: Invalid mac.\n");
      return 0;
    }
  
  return 1;
}