Skip to content

Commit

Permalink
[riscv] Add support for the seed CSR as an entropy source
Browse files Browse the repository at this point in the history
The Zkr entropy source extension defines a potentially unprivileged
seed CSR that can be read to obtain 16 bits of entropy input, with a
mandated requirement that 256 entropy input bits read from the seed
CSR will contain at least 128 bits of min-entropy.

Signed-off-by: Michael Brown <[email protected]>
  • Loading branch information
mcb30 committed Oct 28, 2024
1 parent cd54e7c commit be0c978
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
110 changes: 110 additions & 0 deletions src/arch/riscv/core/zkr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2024 Michael Brown <[email protected]>.
*
* 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 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 );

/** @file
*
* Entropy source extension (Zkr)
*
*/

#include <errno.h>
#include <ipxe/hart.h>
#include <ipxe/entropy.h>
#include <ipxe/drbg.h>

struct entropy_source zkr_entropy __entropy_source ( ENTROPY_PREFERRED );

/** Seed CSR operational state */
#define ZKR_SEED_OPST_MASK 0xc0000000UL
#define ZKR_SEED_OPST_ES16 0x80000000UL /**< 16 bits of entropy available */

/** Number of times to retry reading from seed CSR */
#define ZKR_SEED_MAX_RETRY 1024

/** Colour for debug messages */
#define colour &zkr_entropy

/**
* Enable entropy gathering
*
* @ret rc Return status code
*/
static int zkr_entropy_enable ( void ) {
int rc;

/* Check if Zkr extension is supported */
if ( ( rc = hart_supported ( "_zkr" ) ) != 0 ) {
DBGC ( colour, "ZKR not supported: %s\n", strerror ( rc ) );
return rc;
}

/* RISC-V ISA mandates that 128 bits of full entropy shall be
* obtained from 256 entropy bits read from the seed CSR.
*
* Each 16-bit sample therefore contains 8 bits of
* min-entropy.
*/
entropy_init ( &zkr_entropy, MIN_ENTROPY ( 8.0 ) );

return 0;
}

/**
* Get noise sample
*
* @ret noise Noise sample
* @ret rc Return status code
*/
static int zkr_get_noise ( noise_sample_t *noise ) {
unsigned long seed;
unsigned int i;

/* Read entropy from seed CSR */
for ( i = 0 ; i < ZKR_SEED_MAX_RETRY ; i++ ) {

/* Read seed CSR */
__asm__ ( "csrrw %0, seed, zero" : "=r" ( seed ) );

/* Check operationsl state */
if ( ( seed & ZKR_SEED_OPST_MASK ) == ZKR_SEED_OPST_ES16 ) {

/* Return entropy from both halves of the
* 16-bit entropy source value.
*/
*noise = ( seed ^ ( seed >> 8 ) );
return 0;
}
}

DBGC ( colour, "ZKR could not source entropy (seed %#08lx)\n", seed );
return -EBUSY;
}

/** Hardware entropy source */
struct entropy_source zkr_entropy __entropy_source ( ENTROPY_PREFERRED ) = {
.name = "zkr",
.enable = zkr_entropy_enable,
.get_noise = zkr_get_noise,
};
1 change: 1 addition & 0 deletions src/arch/riscv/include/bits/errfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_sbi_reboot ( ERRFILE_ARCH | ERRFILE_CORE | 0x00000000 )
#define ERRFILE_hart ( ERRFILE_ARCH | ERRFILE_CORE | 0x00010000 )
#define ERRFILE_zicntr ( ERRFILE_ARCH | ERRFILE_CORE | 0x00020000 )
#define ERRFILE_zkr ( ERRFILE_ARCH | ERRFILE_CORE | 0x00030000 )

/** @} */

Expand Down
3 changes: 3 additions & 0 deletions src/config/config_entropy.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ REQUIRE_OBJECT ( linux_entropy );
#ifdef ENTROPY_RDRAND
REQUIRE_OBJECT ( rdrand );
#endif
#ifdef ENTROPY_ZKR
REQUIRE_OBJECT ( zkr );
#endif

0 comments on commit be0c978

Please sign in to comment.