Ejemplo n.º 1
0
void
chacha_crypt(struct chacha_ctx *ctx,
	      size_t length,
	      uint8_t *c,
	      const uint8_t *m)
{
  if (!length)
    return;
  
  for (;;)
    {
      uint32_t x[_CHACHA_STATE_LENGTH];

      _chacha_core (x, ctx->state, CHACHA_ROUNDS);

      ctx->state[13] += (++ctx->state[12] == 0);

      /* stopping at 2^70 length per nonce is user's responsibility */
      
      if (length <= CHACHA_BLOCK_SIZE)
	{
	  memxor3 (c, m, x, length);
	  return;
	}
      memxor3 (c, m, x, CHACHA_BLOCK_SIZE);

      length -= CHACHA_BLOCK_SIZE;
      c += CHACHA_BLOCK_SIZE;
      m += CHACHA_BLOCK_SIZE;
  }
}
Ejemplo n.º 2
0
static void
test_memxor3 (const uint8_t *ain, const uint8_t *bin, const uint8_t *c,
	      size_t size, unsigned align_dst, unsigned align_a, unsigned align_b)
{
  uint8_t dst_buf[MAX_SIZE + ALIGN_SIZE + 1];
  uint8_t a_buf[MAX_SIZE + ALIGN_SIZE + 1];
  uint8_t b_buf[MAX_SIZE + ALIGN_SIZE + 1];

  uint8_t *dst = set_align (dst_buf, align_dst);
  uint8_t *a = set_align (a_buf, align_a);
  uint8_t *b = set_align (b_buf, align_b);

  if (verbose)
    fprintf(stderr, "size = %d, align_dst = %d, align_a = %d, align_b = %d\n",
	    (int) size, align_dst, align_a, align_b);

  memset (dst, 0, size);
  dst[-1] = 17;
  dst[size] = 17;

  memcpy (a, ain, size);
  memcpy (b, bin, size);
  memxor3 (dst, a, b, size);

  ASSERT (MEMEQ (size, dst, c));
  ASSERT (dst[-1] == 17);
  ASSERT (dst[size] == 17);
}
Ejemplo n.º 3
0
static void
ctr32_encrypt_blocks_inplace(const unsigned char *in, unsigned char *out,
			     size_t blocks, const AES_KEY *key,
			     const unsigned char ivec[16])
{
	unsigned i;
	uint8_t ctr[16];
	uint8_t tmp[16];

	memcpy(ctr, ivec, 16);

	for (i=0;i<blocks;i++) {
		aes_v8_encrypt(ctr, tmp, key);
		memxor3(out, tmp, in, 16);

		out += 16;
		in += 16;
		INC32(ctr);
	}
}
Ejemplo n.º 4
0
void
cfb_encrypt(const void *ctx, nettle_cipher_func *f,
	    size_t block_size, uint8_t *iv,
	    size_t length, uint8_t *dst,
	    const uint8_t *src)
{
  uint8_t *p;
  TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);

  TMP_ALLOC(buffer, block_size);

  if (src != dst)
    {
      for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
	{
	  f(ctx, block_size, dst, p);
	  memxor(dst, src, block_size);
	}
    }
  else
    {
      for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
	{
	  f(ctx, block_size, buffer, p);
	  memxor(dst, buffer, block_size);
	}
    }

  if (p != iv)
    memcpy(iv, p, block_size);

  if (length)
    {
      f(ctx, block_size, buffer, iv);
      memxor3(dst, buffer, src, length);
      /* We do not care about updating IV here. This is the last call in
       * message sequence and one has to set IV afterwards anyway */
    }
}
Ejemplo n.º 5
0
Archivo: cfb8.c Proyecto: gnutls/gnutls
void
cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
	     size_t block_size, uint8_t *iv,
	     size_t length, uint8_t *dst,
	     const uint8_t *src)
{
  TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
  TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
  TMP_ALLOC(buffer, block_size * 2);
  TMP_ALLOC(outbuf, block_size * 2);
  uint8_t i = 0;

  memcpy(buffer, iv, block_size);
  memcpy(buffer + block_size, src,
	 length < block_size ? length : block_size);

  while (length)
    {

      for (i = 0; i < length && i < block_size; i++)
	f(ctx, block_size, outbuf + i, buffer + i);

      memxor3(dst, src, outbuf, i);

      length -= i;
      src += i;
      dst += i;

      memcpy(buffer, buffer + block_size, block_size);
      memcpy(buffer + block_size, src,
	     length < block_size ? length : block_size);

    }

  memcpy(iv, buffer + i, block_size);
}
Ejemplo n.º 6
0
static void
test_salsa20_stream(const struct tstring *key,
		    const struct tstring *iv,
		    const struct tstring *ciphertext,
		    const struct tstring *xor_ref)
{
  struct salsa20_ctx ctx;
  uint8_t data[STREAM_LENGTH + 1];
  uint8_t stream[STREAM_LENGTH + 1];
  uint8_t xor[SALSA20_BLOCK_SIZE];
  unsigned j;

  ASSERT (iv->length == SALSA20_IV_SIZE);
  ASSERT (ciphertext->length == 4*SALSA20_BLOCK_SIZE);
  ASSERT (xor_ref->length == SALSA20_BLOCK_SIZE);

  salsa20_set_key(&ctx, key->length, key->data);
  salsa20_set_iv(&ctx, iv->data);
  memset(stream, 0, STREAM_LENGTH + 1);
  salsa20_crypt(&ctx, STREAM_LENGTH, stream, stream);
  if (stream[STREAM_LENGTH])
    {
      fprintf(stderr, "Stream of %d bytes wrote too much!\n", STREAM_LENGTH);
      FAIL();
    }
  if (!MEMEQ (64, stream, ciphertext->data))
    {
      fprintf(stderr, "Error failed, offset 0:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(64, stream);
      fprintf(stderr, "\nExpected:");
      print_hex(64, ciphertext->data);
      fprintf(stderr, "\n");
      FAIL();
    }
  if (!MEMEQ (128, stream + 192, ciphertext->data + 64))
    {
      fprintf(stderr, "Error failed, offset 192:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(128, stream + 192);
      fprintf(stderr, "\nExpected:");
      print_hex(64, ciphertext->data + 64);
      fprintf(stderr, "\n");
      FAIL();
    }
  if (!MEMEQ (64, stream + 448, ciphertext->data + 192))
    {
      fprintf(stderr, "Error failed, offset 448:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(64, stream + 448);
      fprintf(stderr, "\nExpected:");
      print_hex(64, ciphertext->data + 192);
      fprintf(stderr, "\n");
      FAIL();
    }

  memxor3 (xor, stream, stream + SALSA20_BLOCK_SIZE, SALSA20_BLOCK_SIZE);
  for (j = 2*SALSA20_BLOCK_SIZE; j < STREAM_LENGTH; j += SALSA20_BLOCK_SIZE)
    memxor (xor, stream + j, SALSA20_BLOCK_SIZE);

  if (!MEMEQ (SALSA20_BLOCK_SIZE, xor, xor_ref->data))
    {
      fprintf(stderr, "Error failed, bad xor 448:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(SALSA20_BLOCK_SIZE, xor);
      fprintf(stderr, "\nExpected:");
      print_hex(SALSA20_BLOCK_SIZE, xor_ref->data);
      fprintf(stderr, "\n");
      FAIL();
    }

  for (j = 1; j <= STREAM_LENGTH; j++)
    {
      memset(data, 0, STREAM_LENGTH + 1);
      salsa20_set_iv(&ctx, iv->data);
      salsa20_crypt(&ctx, j, data, data);

      if (!MEMEQ(j, data, stream))
	{
	  fprintf(stderr, "Encrypt failed for length %u:\n", j);
	  fprintf(stderr, "\nOutput: ");
	  print_hex(j, data);
	  fprintf(stderr, "\nExpected:");
	  print_hex(j, stream);
	  fprintf(stderr, "\n");
	  FAIL();
	}
      if (!memzero_p (data + j, STREAM_LENGTH + 1 - j))
	{
	  fprintf(stderr, "Encrypt failed for length %u, wrote too much:\n", j);
	  fprintf(stderr, "\nOutput: ");
	  print_hex(STREAM_LENGTH + 1 - j, data + j);
	  fprintf(stderr, "\n");
	  FAIL();
	}
    }
}
Ejemplo n.º 7
0
void
cfb_decrypt(const void *ctx, nettle_cipher_func *f,
	    size_t block_size, uint8_t *iv,
	    size_t length, uint8_t *dst,
	    const uint8_t *src)
{
  if (src != dst)
    {
      size_t left = length % block_size;

      length -= left;
      if (length > 0)
	{
	  /* Decrypt in ECB mode */
	  f(ctx, block_size, dst, iv);
	  f(ctx, length - block_size, dst + block_size, src);
	  memcpy(iv, src + length - block_size, block_size);
	  memxor(dst, src, length);
	}

      if (left > 0)
	{
	  TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
	  TMP_ALLOC(buffer, block_size);

	  f(ctx, block_size, buffer, iv);
	  memxor3(dst + length, src + length, buffer, left);
	}
    }
  else
    {
      /* For in-place CFB, we decrypt into a temporary buffer of size
       * at most CFB_BUFFER_LIMIT, and process that amount of data at
       * a time. */

      /* NOTE: We assume that block_size <= CFB_BUFFER_LIMIT */

      TMP_DECL(buffer, uint8_t, CFB_BUFFER_LIMIT);
      TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);

      size_t buffer_size;
      size_t left;

      buffer_size = CFB_BUFFER_LIMIT - (CFB_BUFFER_LIMIT % block_size);

      TMP_ALLOC(buffer, buffer_size);
      TMP_ALLOC(initial_iv, block_size);

      left = length % block_size;
      length -= left;

      while (length > 0)
	{
	  size_t part = length > buffer_size ? buffer_size : length;

	  /* length is greater that zero and is divided by block_size, so it is
	   * not less than block_size. So does part */

	  f(ctx, block_size, buffer, iv);
	  f(ctx, part - block_size, buffer + block_size, src);
	  memcpy(iv, src + part - block_size, block_size);
	  memxor(dst, buffer, part);

	  length -= part;
	  src += part;
	  dst += part;
	}

      if (left > 0)
	{
	  f(ctx, block_size, buffer, iv);
	  memxor(dst, buffer, left);
	}
    }
}
Ejemplo n.º 8
0
Archivo: cbc.c Proyecto: AllardJ/Tomato
void
cbc_decrypt(void *ctx, nettle_crypt_func *f,
	    unsigned block_size, uint8_t *iv,
	    unsigned length, uint8_t *dst,
	    const uint8_t *src)
{
  assert(!(length % block_size));

  if (!length)
    return;

  if (src != dst)
    {
      /* Decrypt in ECB mode */
      f(ctx, length, dst, src);

      /* XOR the cryptotext, shifted one block */
      memxor(dst, iv, block_size);
      memxor(dst + block_size, src, length - block_size);
      memcpy(iv, src + length - block_size, block_size);
    }

  else
    {
      /* For in-place CBC, we decrypt into a temporary buffer of size
       * at most CBC_BUFFER_LIMIT, and process that amount of data at
       * a time. */
      
      /* NOTE: We assume that block_size <= CBC_BUFFER_LIMIT, and we
	 depend on memxor3 working from the end of the area, allowing
	 certain overlapping operands. */ 

      TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT);
      TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);

      unsigned buffer_size;

      if (length <= CBC_BUFFER_LIMIT)
	buffer_size = length;
      else
	buffer_size
	  = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);

      TMP_ALLOC(buffer, buffer_size);
      TMP_ALLOC(initial_iv, block_size);

      for ( ; length > buffer_size;
	    length -= buffer_size, src += buffer_size, dst += buffer_size)
	{
	  f(ctx, buffer_size, buffer, src);
	  memcpy(initial_iv, iv, block_size);
	  memcpy(iv, src + buffer_size - block_size, block_size);
	  memxor3(dst + block_size, buffer + block_size, src,
		  buffer_size - block_size);
	  memxor3(dst, buffer, initial_iv, block_size);
	}

      f(ctx, length, buffer, src);
      memcpy(initial_iv, iv, block_size);
      /* Copies last block */
      memcpy(iv, src + length - block_size, block_size);
      /* Writes all but first block, reads all but last block. */
      memxor3(dst + block_size, buffer + block_size, src,
	      length - block_size);
      /* Writes first block. */
      memxor3(dst, buffer, initial_iv, block_size);
    }
}