/*
 * libcryptsetup - cryptsetup library, cipher bechmark
 *
 * Copyright (C) 2012-2017, Red Hat, Inc. All rights reserved.
 * Copyright (C) 2012-2017, Milan Broz
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdlib.h>
#include <errno.h>
#include <time.h>

#include "internal.h"

/*
 * This is not simulating storage, so using disk block causes extreme overhead.
 * Let's use some fixed block size where results are more reliable...
 */
#define CIPHER_BLOCK_BYTES 65536

/*
 * If the measured value is lower, encrypted buffer is probably too small
 * and calculated values are not reliable.
 */
#define CIPHER_TIME_MIN_MS 0.001

/*
 * The whole test depends on Linux kernel usermode crypto API for now.
 * (The same implementations are used in dm-crypt though.)
 */

struct cipher_perf {
	char name[32];
	char mode[32];
	char *key;
	size_t key_length;
	char *iv;
	size_t iv_length;
	size_t buffer_size;
};

static int time_ms(struct timespec *start, struct timespec *end, double *ms)
{
	double start_ms, end_ms;

	start_ms = start->tv_sec * 1000.0 + start->tv_nsec / (1000.0 * 1000);
	end_ms   = end->tv_sec * 1000.0 + end->tv_nsec / (1000.0 * 1000);

	*ms = end_ms - start_ms;
	return 0;
}

static int cipher_perf_one(struct cipher_perf *cp, char *buf,
			   size_t buf_size, int enc)
{
	struct crypt_cipher *cipher = NULL;
	size_t done = 0, block = CIPHER_BLOCK_BYTES;
	int r;

	if (buf_size < block)
		block = buf_size;

	r = crypt_cipher_init(&cipher, cp->name, cp->mode, cp->key, cp->key_length);
	if (r < 0) {
		log_dbg("Cannot initialise cipher %s, mode %s.", cp->name, cp->mode);
		return r;
	}

	while (done < buf_size) {
		if ((done + block) > buf_size)
			block = buf_size - done;

		if (enc)
			r = crypt_cipher_encrypt(cipher, &buf[done], &buf[done],
						 block, cp->iv, cp->iv_length);
		else
			r = crypt_cipher_decrypt(cipher, &buf[done], &buf[done],
						 block, cp->iv, cp->iv_length);
		if (r < 0)
			break;

		done += block;
	}

	crypt_cipher_destroy(cipher);

	return r;
}
static int cipher_measure(struct cipher_perf *cp, char *buf,
			  size_t buf_size, int encrypt, double *ms)
{
	struct timespec start, end;
	int r;

	/*
	 * Using getrusage would be better here but the precision
	 * is not adequate, so better stick with CLOCK_MONOTONIC
	 */
	if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
		return -EINVAL;

	r = cipher_perf_one(cp, buf, buf_size, encrypt);
	if (r < 0)
		return r;

	if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
		return -EINVAL;

	r = time_ms(&start, &end, ms);
	if (r < 0)
		return r;

	if (*ms < CIPHER_TIME_MIN_MS) {
		log_dbg("Measured cipher runtime (%1.6f) is too low.", *ms);
		return -ERANGE;
	}

	return 0;
}

static double speed_mbs(unsigned long bytes, double ms)
{
	double speed = bytes, s = ms / 1000.;

	return speed / (1024 * 1024) / s;
}

static int cipher_perf(struct cipher_perf *cp,
	double *encryption_mbs, double *decryption_mbs)
{
	double ms_enc, ms_dec, ms;
	int r, repeat_enc, repeat_dec;
	void *buf = NULL;

	if (posix_memalign(&buf, crypt_getpagesize(), cp->buffer_size))
		return -ENOMEM;

	ms_enc = 0.0;
	repeat_enc = 1;
	while (ms_enc < 1000.0) {
		r = cipher_measure(cp, buf, cp->buffer_size, 1, &ms);
		if (r < 0) {
			free(buf);
			return r;
		}
		ms_enc += ms;
		repeat_enc++;
	}

	ms_dec = 0.0;
	repeat_dec = 1;
	while (ms_dec < 1000.0) {
		r = cipher_measure(cp, buf, cp->buffer_size, 0, &ms);
		if (r < 0) {
			free(buf);
			return r;
		}
		ms_dec += ms;
		repeat_dec++;
	}

	free(buf);

	*encryption_mbs = speed_mbs(cp->buffer_size * repeat_enc, ms_enc);
	*decryption_mbs = speed_mbs(cp->buffer_size * repeat_dec, ms_dec);

	return  0;
}

int crypt_benchmark(struct crypt_device *cd,
	const char *cipher,
	const char *cipher_mode,
	size_t volume_key_size,
	size_t iv_size,
	size_t buffer_size,
	double *encryption_mbs,
	double *decryption_mbs)
{
	struct cipher_perf cp = {
		.key_length = volume_key_size,
		.iv_length = iv_size,
		.buffer_size = buffer_size,
	};
	char *c;
	int r;

	if (!cipher || !cipher_mode || !volume_key_size)
		return -EINVAL;

	r = init_crypto(cd);
	if (r < 0)
		return r;

	r = -ENOMEM;
	if (iv_size) {
		cp.iv = malloc(iv_size);
		if (!cp.iv)
			goto out;
		crypt_random_get(cd, cp.iv, iv_size, CRYPT_RND_NORMAL);
	}

	cp.key = malloc(volume_key_size);
	if (!cp.key)
		goto out;

	crypt_random_get(cd, cp.key, volume_key_size, CRYPT_RND_NORMAL);
	strncpy(cp.name, cipher, sizeof(cp.name)-1);
	strncpy(cp.mode, cipher_mode, sizeof(cp.mode)-1);

	/* Ignore IV generator */
	if ((c  = strchr(cp.mode, '-')))
		*c = '\0';

	r = cipher_perf(&cp, encryption_mbs, decryption_mbs);
out:
	free(cp.key);
	free(cp.iv);
	return r;
}

int crypt_benchmark_kdf(struct crypt_device *cd,
	const char *kdf,
	const char *hash,
	const char *password,
	size_t password_size,
	const char *salt,
	size_t salt_size,
	uint64_t *iterations_sec)
{
	int r, key_length = 0;

	if (!iterations_sec)
		return -EINVAL;

	r = init_crypto(cd);
	if (r < 0)
		return r;

	// FIXME: this should be in KDF check API parameters later
	if (cd)
		key_length = crypt_get_volume_key_size(cd);

	if (key_length == 0)
		key_length = DEFAULT_LUKS1_KEYBITS / 8;

	if (!strncmp(kdf, "pbkdf2", 6))
		r = crypt_pbkdf_check(kdf, hash, password, password_size,
				      salt, salt_size, key_length, iterations_sec);
	else
		r = -EINVAL;

	if (!r)
		log_dbg("KDF %s, hash %s: %" PRIu64 " iterations per second (%d-bits key).",
			kdf, hash, *iterations_sec, key_length * 8);
	return r;
}
