Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 567dff53 authored by Laura Abbott's avatar Laura Abbott Committed by Divya Sharma
Browse files

soc: qcom: Add better support for early random numbers



The existing support for generating random numbers relied on
a hacked up version of CONFIG_ARCH_RANDOM and was prone to
scheduling while atomic bugs due to needing to take a mutex.
We don't actually need the additional randomness all the time,
the pool just needs to be initialized with some amount of random
data to avoid getting the same result each time. Switch to
this method for initializing the random pool.

Change-Id: I804ec7556cbd18ff2d9869a03069fda1dd519a79
Signed-off-by: default avatarLaura Abbott <lauraa@codeaurora.org>
[ohaugan@codeaurora.org: Fixed trivial merge conflicts]
Signed-off-by: default avatarOlav Haugan <ohaugan@codeaurora.org>
parent 8f4f1328
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -832,6 +832,14 @@ config QCOM_SMCINVOKE
	  Enable SMCInvoke driver which supports capability based secure
	  communication between QSEE and HLOS.

config QCOM_EARLY_RANDOM
	bool "Initialize random pool very early"
	help
	  The standard random pool may not initialize until late in the boot
	  process which means that any calls to get random numbers before then
	  may not be truly random. Select this option to make an early call
	  to get some random data to put in the pool. If unsure, say N.

source "drivers/soc/qcom/memshare/Kconfig"

endif # ARCH_MSM
+1 −0
Original line number Diff line number Diff line
@@ -101,3 +101,4 @@ obj-$(CONFIG_MSM_KERNEL_PROTECT) += kernel_protect.o
obj-$(CONFIG_MSM_RTB) += msm_rtb-hotplug.o
obj-$(CONFIG_MSM_REMOTEQDSS) += remoteqdss.o
obj-$(CONFIG_QCOM_SMCINVOKE) += smcinvoke.o
obj-$(CONFIG_QCOM_EARLY_RANDOM)	+= early_random.o
+7 −37
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -12,8 +12,9 @@
 */

#include <linux/kernel.h>
#include <linux/random.h>

#include <mach/scm.h>
#include <soc/qcom/scm.h>

#include <asm/io.h>
#include <asm/cacheflush.h>
@@ -21,32 +22,24 @@
#define TZ_SVC_CRYPTO	10
#define PRNG_CMD_ID	0x01

static int use_arch_random = 1;
struct tz_prng_data {
	uint8_t		*out_buf;
	uint32_t	out_buf_sz;
} __packed;

DEFINE_SCM_BUFFER(common_scm_buf)
DEFINE_MUTEX(arch_random_lock);
#define RANDOM_BUFFER_SIZE	PAGE_SIZE
char random_buffer[RANDOM_BUFFER_SIZE] __aligned(PAGE_SIZE);

int arch_get_random_common(void *v, size_t size)
void __init init_random_pool(void)
{
	struct tz_prng_data data;
	int ret;
	u32 resp;

	if (!use_arch_random)
		return 0;

	if (size > sizeof(random_buffer))
		return 0;

	mutex_lock(&arch_random_lock);
	data.out_buf = (uint8_t *) virt_to_phys(random_buffer);
	data.out_buf_sz = size;
	data.out_buf_sz = SZ_512;
	dmac_flush_range(random_buffer, random_buffer + RANDOM_BUFFER_SIZE);

	ret = scm_call_noalloc(TZ_SVC_CRYPTO, PRNG_CMD_ID, &data,
			sizeof(data), &resp, sizeof(resp),
@@ -54,30 +47,7 @@ int arch_get_random_common(void *v, size_t size)
	if (!ret) {
		dmac_inv_range(random_buffer, random_buffer +
						RANDOM_BUFFER_SIZE);
		outer_inv_range(
			(unsigned long) virt_to_phys(random_buffer),
			(unsigned long) virt_to_phys(random_buffer) +
						RANDOM_BUFFER_SIZE);
		memcpy(v, random_buffer, size);
	}
	mutex_unlock(&arch_random_lock);
	return !ret;
}

int arch_get_random_long(unsigned long *v)
{
	return arch_get_random_common(v, sizeof(unsigned long));
		add_device_randomness(random_buffer, SZ_512);
	}

int arch_get_random_int(unsigned int *v)
{
	return arch_get_random_common(v, sizeof(unsigned int));
}
int arch_random_init(void)
{
	use_arch_random = 0;

	return 0;
}
module_init(arch_random_init);