Merge "soc: qcom: Add better support for early random numbers"

This commit is contained in:
Linux Build Service Account 2016-10-19 11:17:58 -07:00 committed by Gerrit - the friendly Code Review server
commit d12a43a23d
4 changed files with 16 additions and 57 deletions

View file

@ -1,20 +0,0 @@
/* Copyright (c) 2013, 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
* only version 2 as published by the Free Software Foundation.
*
* 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.
*
*/
#ifndef ARM_ASM_ARCHRANDOM_H
#define ARM_ASM_ARCHRANDOM_H
extern int arch_get_random_long(unsigned long *v);
extern int arch_get_random_int(unsigned int *v);
#endif

View file

@ -821,4 +821,12 @@ 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"

View file

@ -99,3 +99,4 @@ obj-$(CONFIG_MSM_RPM_LOG) += rpm_log.o
obj-$(CONFIG_QSEE_IPC_IRQ_BRIDGE) += qsee_ipc_irq_bridge.o
obj-$(CONFIG_WCD_DSP_GLINK) += wcd-dsp-glink.o
obj-$(CONFIG_QCOM_SMCINVOKE) += smcinvoke.o
obj-$(CONFIG_QCOM_EARLY_RANDOM) += early_random.o

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, 2016, 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);
add_device_randomness(random_buffer, SZ_512);
}
mutex_unlock(&arch_random_lock);
return !ret;
}
int arch_get_random_long(unsigned long *v)
{
return arch_get_random_common(v, sizeof(unsigned long));
}
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);