Skip to content

Commit 1024340

Browse files
sameopalmer-dabbelt
authored andcommitted
RISC-V: Implement archrandom when Zkr is available
The Zkr extension is ratified and provides 16 bits of entropy seed when reading the SEED CSR. We can implement arch_get_random_seed_longs() by doing multiple csrrw to that CSR and filling an unsigned long with valid entropy bits. Acked-by: Conor Dooley <conor.dooley@microchip.com> Signed-off-by: Samuel Ortiz <sameo@rivosinc.com> Signed-off-by: Clément Léger <cleger@rivosinc.com> Link: https://lore.kernel.org/r/20231130111704.1319081-1-cleger@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 55ca8d7 commit 1024340

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

arch/riscv/include/asm/archrandom.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Kernel interface for the RISCV arch_random_* functions
4+
*
5+
* Copyright (c) 2023 Rivos Inc.
6+
*
7+
*/
8+
9+
#ifndef ASM_RISCV_ARCHRANDOM_H
10+
#define ASM_RISCV_ARCHRANDOM_H
11+
12+
#include <asm/csr.h>
13+
#include <asm/processor.h>
14+
15+
#define SEED_RETRY_LOOPS 100
16+
17+
static inline bool __must_check csr_seed_long(unsigned long *v)
18+
{
19+
unsigned int retry = SEED_RETRY_LOOPS, valid_seeds = 0;
20+
const int needed_seeds = sizeof(long) / sizeof(u16);
21+
u16 *entropy = (u16 *)v;
22+
23+
do {
24+
/*
25+
* The SEED CSR must be accessed with a read-write instruction.
26+
*/
27+
unsigned long csr_seed = csr_swap(CSR_SEED, 0);
28+
unsigned long opst = csr_seed & SEED_OPST_MASK;
29+
30+
switch (opst) {
31+
case SEED_OPST_ES16:
32+
entropy[valid_seeds++] = csr_seed & SEED_ENTROPY_MASK;
33+
if (valid_seeds == needed_seeds)
34+
return true;
35+
break;
36+
37+
case SEED_OPST_DEAD:
38+
pr_err_once("archrandom: Unrecoverable error\n");
39+
return false;
40+
41+
case SEED_OPST_BIST:
42+
case SEED_OPST_WAIT:
43+
default:
44+
cpu_relax();
45+
continue;
46+
}
47+
} while (--retry);
48+
49+
return false;
50+
}
51+
52+
static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
53+
{
54+
return 0;
55+
}
56+
57+
static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs)
58+
{
59+
if (!max_longs)
60+
return 0;
61+
62+
/*
63+
* If Zkr is supported and csr_seed_long succeeds, we return one long
64+
* worth of entropy.
65+
*/
66+
if (riscv_has_extension_likely(RISCV_ISA_EXT_ZKR) && csr_seed_long(v))
67+
return 1;
68+
69+
return 0;
70+
}
71+
72+
#endif /* ASM_RISCV_ARCHRANDOM_H */

arch/riscv/include/asm/csr.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,15 @@
411411
#define CSR_VTYPE 0xc21
412412
#define CSR_VLENB 0xc22
413413

414+
/* Scalar Crypto Extension - Entropy */
415+
#define CSR_SEED 0x015
416+
#define SEED_OPST_MASK _AC(0xC0000000, UL)
417+
#define SEED_OPST_BIST _AC(0x00000000, UL)
418+
#define SEED_OPST_WAIT _AC(0x40000000, UL)
419+
#define SEED_OPST_ES16 _AC(0x80000000, UL)
420+
#define SEED_OPST_DEAD _AC(0xC0000000, UL)
421+
#define SEED_ENTROPY_MASK _AC(0xFFFF, UL)
422+
414423
#ifdef CONFIG_RISCV_M_MODE
415424
# define CSR_STATUS CSR_MSTATUS
416425
# define CSR_IE CSR_MIE

0 commit comments

Comments
 (0)