/*
 * 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 TPL_CALLBACK */
	bs->RaiseTPL ( TPL_CALLBACK );
}

/**
 * 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 );
