/*
 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <errno.h>
#include <ipxe/entropy.h>
#include <ipxe/crc32.h>
#include <ipxe/profile.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/Rng.h>

/** @file
 *
 * EFI entropy source
 *
 */

/** Random number generator protocol */
static EFI_RNG_PROTOCOL *efirng;
EFI_REQUEST_PROTOCOL ( EFI_RNG_PROTOCOL, &efirng );

/** Minimum number of bytes to request from RNG
 *
 * The UEFI spec states (for no apparently good reason) that "When a
 * Deterministic Random Bit Generator (DRBG) is used on the output of
 * a (raw) entropy source, its security level must be at least 256
 * bits."  The EDK2 codebase (mis)interprets this to mean that the
 * call to GetRNG() should fail if given a buffer less than 32 bytes.
 *
 * Incidentally, nothing in the EFI RNG protocol provides any way to
 * report the actual amount of entropy returned by GetRNG().
 */
#define EFI_ENTROPY_RNG_LEN 32

/** Time (in 100ns units) to delay waiting for timer tick
 *
 * In theory, UEFI allows us to specify a trigger time of zero to
 * simply wait for the next timer tick.  In practice, specifying zero
 * seems to often return immediately, which produces almost no
 * entropy.  Specify a delay of 1000ns to try to force an existent
 * delay.
 */
#define EFI_ENTROPY_TRIGGER_TIME 10

/** Event used to wait for timer tick */
static EFI_EVENT tick;

/**
 * Enable entropy gathering
 *
 * @ret rc		Return status code
 */
static int efi_entropy_enable ( void ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_STATUS efirc;
	int rc;

	DBGC ( &tick, "ENTROPY %s RNG protocol\n",
	       ( efirng ? "has" : "has no" ) );

	/* Drop to external TPL to allow timer tick event to take place */
	bs->RestoreTPL ( efi_external_tpl );

	/* Create timer tick event */
	if ( ( efirc = bs->CreateEvent ( EVT_TIMER, TPL_NOTIFY, NULL, NULL,
					 &tick ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( &tick, "ENTROPY could not create event: %s\n",
		       strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Disable entropy gathering
 *
 */
static void efi_entropy_disable ( void ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;

	/* Close timer tick event */
	bs->CloseEvent ( tick );

	/* Return to internal TPL */
	bs->RaiseTPL ( efi_internal_tpl );
}

/**
 * Wait for a timer tick
 *
 * @ret low		CPU profiling low-order bits, or negative error
 */
static int efi_entropy_tick ( void ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	UINTN index;
	uint16_t low;
	EFI_STATUS efirc;
	int rc;

	/* Wait for next timer tick */
	if ( ( efirc = bs->SetTimer ( tick, TimerRelative,
				      EFI_ENTROPY_TRIGGER_TIME ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( &tick, "ENTROPY could not set timer: %s\n",
		       strerror ( rc ) );
		return rc;
	}
	if ( ( efirc = bs->WaitForEvent ( 1, &tick, &index ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( &tick, "ENTROPY could not wait for timer tick: %s\n",
		       strerror ( rc ) );
		return rc;
	}

	/* Get current CPU profiling timestamp low-order bits */
	low = profile_timestamp();

	return low;
}

/**
 * Get noise sample from timer ticks
 *
 * @ret noise		Noise sample
 * @ret rc		Return status code
 */
static int efi_get_noise_ticks ( noise_sample_t *noise ) {
	int before;
	int after;
	int rc;

	/* Wait for a timer tick */
	before = efi_entropy_tick();
	if ( before < 0 ) {
		rc = before;
		return rc;
	}

	/* Wait for another timer tick */
	after = efi_entropy_tick();
	if ( after < 0 ) {
		rc = after;
		return rc;
	}

	/* Use TSC delta as noise sample */
	*noise = ( after - before );

	return 0;
}

/**
 * Get noise sample from RNG protocol
 *
 * @ret noise		Noise sample
 * @ret rc		Return status code
 */
static int efi_get_noise_rng ( noise_sample_t *noise ) {
	static uint8_t prev[EFI_ENTROPY_RNG_LEN];
	uint8_t buf[EFI_ENTROPY_RNG_LEN];
	EFI_STATUS efirc;
	int rc;

	/* Fail if we have no EFI RNG protocol */
	if ( ! efirng )
		return -ENOTSUP;

	/* Get the minimum allowed number of random bytes */
	if ( ( efirc = efirng->GetRNG ( efirng, NULL, EFI_ENTROPY_RNG_LEN,
					buf ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( &tick, "ENTROPY could not read from RNG: %s\n",
		       strerror ( rc ) );
		return rc;
	}

	/* Fail (and permanently disable the EFI RNG) if we get
	 * consecutive identical results.
	 */
	if ( memcmp ( buf, prev, sizeof ( buf ) ) == 0 ) {
		DBGC ( &tick, "ENTROPY detected broken EFI RNG:\n" );
		DBGC_HDA ( &tick, 0, buf, sizeof ( buf ) );
		efirng = NULL;
		return -EIO;
	}
	memcpy ( prev, buf, sizeof ( prev ) );

	/* Reduce random bytes to a single noise sample.  This seems
	 * like overkill, but we have no way of knowing how much
	 * entropy is actually present in the bytes returned by the
	 * RNG protocol.
	 */
	*noise = crc32_le ( 0, buf, sizeof ( buf ) );

	return 0;
}

/**
 * Get noise sample
 *
 * @ret noise		Noise sample
 * @ret rc		Return status code
 */
static int efi_get_noise ( noise_sample_t *noise ) {
	int rc;

	/* Try RNG first, falling back to timer ticks */
	if ( ( ( rc = efi_get_noise_rng ( noise ) ) != 0 ) &&
	     ( ( rc = efi_get_noise_ticks ( noise ) ) != 0 ) )
		return rc;

	return 0;
}

PROVIDE_ENTROPY_INLINE ( efi, min_entropy_per_sample );
PROVIDE_ENTROPY ( efi, entropy_enable, efi_entropy_enable );
PROVIDE_ENTROPY ( efi, entropy_disable, efi_entropy_disable );
PROVIDE_ENTROPY ( efi, get_noise, efi_get_noise );
