Exemplo n.º 1
0
static void
_test_chacha(chacha_func *crypt,
	      const struct tstring *key,
	      const struct tstring *iv,
	      const struct tstring *cleartext,
	      const struct tstring *ciphertext)
{
  struct chacha_ctx ctx;
  uint8_t *data;
  size_t length;

  ASSERT (cleartext->length == ciphertext->length);
  length = cleartext->length;

  ASSERT (iv->length == CHACHA_IV_SIZE);

  data = xalloc(length + 1);

  chacha_set_key(&ctx, key->length, key->data);
  chacha_set_iv(&ctx, iv->data);
  data[length] = 17;
  crypt(&ctx, length, data, cleartext->data);
  if (data[length] != 17)
    {
      fprintf(stderr, "Encrypt of %lu bytes wrote too much!\nInput:",
	      (unsigned long) length);
      tstring_print_hex(cleartext);
      fprintf(stderr, "\n");
      FAIL();
    }
  if (!MEMEQ(length, data, ciphertext->data))
    {
      fprintf(stderr, "Encrypt failed:\nInput:");
      tstring_print_hex(cleartext);
      fprintf(stderr, "\nOutput: ");
      print_hex(length, data);
      fprintf(stderr, "\nExpected:");
      tstring_print_hex(ciphertext);
      fprintf(stderr, "\n");
      FAIL();
    }
  chacha_set_key(&ctx, key->length, key->data);
  chacha_set_iv(&ctx, iv->data);
  crypt(&ctx, length, data, data);

  if (!MEMEQ(length, data, cleartext->data))
    {
      fprintf(stderr, "Decrypt failed:\nInput:");
      tstring_print_hex(ciphertext);
      fprintf(stderr, "\nOutput: ");
      print_hex(length, data);
      fprintf(stderr, "\nExpected:");
      tstring_print_hex(cleartext);
      fprintf(stderr, "\n");
      FAIL();
    }

  free(data);
}
Exemplo n.º 2
0
/* Initializes the nonce level random generator.
 *
 * the @new_key must be provided.
 *
 * @init must be non zero on first initialization, and
 * zero on any subsequent reinitializations.
 */
static int single_prng_init(struct prng_ctx_st *ctx,
			    uint8_t new_key[PRNG_KEY_SIZE],
			    unsigned new_key_size,
			    unsigned init)
{
	uint8_t nonce[CHACHA_NONCE_SIZE];

	memset(nonce, 0, sizeof(nonce)); /* to prevent valgrind from whinning */

	if (init == 0) {
		/* use the previous key to generate IV as well */
		chacha_crypt(&ctx->ctx, sizeof(nonce), nonce, nonce);

		/* Add key continuity by XORing the new key with data generated
		 * from the old key */
		chacha_crypt(&ctx->ctx, new_key_size, new_key, new_key);
	} else {
		struct timespec now; /* current time */

		ctx->forkid = _gnutls_get_forkid();

		gettime(&now);
		memcpy(nonce, &now, MIN(sizeof(nonce), sizeof(now)));
		ctx->last_reseed = now.tv_sec;
	}

	chacha_set_key(&ctx->ctx, new_key);
	chacha_set_nonce(&ctx->ctx, nonce);

	zeroize_key(new_key, new_key_size);

	ctx->counter = 0;

	return 0;
}
Exemplo n.º 3
0
void test_chacha(const uint8_t *key, const uint8_t *iv, uint8_t *expected, 
                uint8_t keylength, uint8_t rounds) {
    uint8_t cipher_data[64] =  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    uint8_t cipher_result[64] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    struct chacha_ctx cipher_ctx;

    uint8_t errors;
    
    chacha_set_key(&cipher_ctx, keylength, key);
    chacha_set_iv(&cipher_ctx, iv);
    chacha_crypt(&cipher_ctx, 64, rounds, &cipher_result[0], &cipher_data[0]);

    if (DEBUG) {
        printf("Result after encryption:\n");
        print_block(cipher_result);
      }

    errors = 0;
    for (uint8_t i = 0 ; i < 64 ; i++) {
      if (cipher_result[i] != expected[i]) {
        errors++;
      }
    }
    
    if (errors > 0) {
      printf("Error, expected:\n");
      print_block(&expected[0]);
      printf("Got:\n");
      print_block(cipher_result);
    }
    else {
      printf("Success, result matched expected.\n");
    }
}
Exemplo n.º 4
0
/* FIXME: Also set nonce to zero, and implement nonce
   auto-increment? */
void
chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx,
			 const uint8_t *key)
{
  chacha_set_key (&ctx->chacha, key);
}
Exemplo n.º 5
0
static void
test_chacha_stream(const struct tstring *key,
		    const struct tstring *iv,
		    const struct tstring *ciphertext,
		    const struct tstring *xor_ref)
{
  struct chacha_ctx ctx;
  uint8_t data[STREAM_LENGTH + 1];
  uint8_t stream[STREAM_LENGTH + 1];
  uint8_t xor[CHACHA_BLOCK_SIZE];
  size_t j;

  ASSERT (iv->length == CHACHA_IV_SIZE);
  ASSERT (ciphertext->length == 4*CHACHA_BLOCK_SIZE);
  ASSERT (xor_ref->length == CHACHA_BLOCK_SIZE);

  chacha_set_key(&ctx, key->length, key->data);
  chacha_set_iv(&ctx, iv->data);
  memset(stream, 0, STREAM_LENGTH + 1);
  chacha_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 + CHACHA_BLOCK_SIZE, CHACHA_BLOCK_SIZE);
  for (j = 2*CHACHA_BLOCK_SIZE; j < STREAM_LENGTH; j += CHACHA_BLOCK_SIZE)
    memxor (xor, stream + j, CHACHA_BLOCK_SIZE);

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

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

      if (!MEMEQ(j, data, stream))
	{
	  fprintf(stderr, "Encrypt failed for length %lu:\n",
		  (unsigned long) 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 %lu, wrote too much:\n",
		  (unsigned long) j);
	  fprintf(stderr, "\nOutput: ");
	  print_hex(STREAM_LENGTH + 1 - j, data + j);
	  fprintf(stderr, "\n");
	  FAIL();
	}
    }
}