From 2ff4983af96892443afce159e77037c5058b15be Mon Sep 17 00:00:00 2001 From: Jade Philipoom Date: Fri, 13 Sep 2024 14:22:23 +0200 Subject: [PATCH] [util] Remove expand_seed routine. This routine wasn't currently affecting the logic, but would have weakened certain seeds that happened to have low values. Ideally this should all be refactored to use byte strings so it's clearer what range the value is sampled from, but for now just removing the harmful logic should suffice. Signed-off-by: Jade Philipoom --- util/design/lib/LcStEnc.py | 7 +++---- util/design/lib/OtpMemMap.py | 4 ++-- util/design/lib/common.py | 15 +-------------- util/topgen.py | 4 ++-- util/topgen/secure_prng.py | 16 +++++++++------- 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/util/design/lib/LcStEnc.py b/util/design/lib/LcStEnc.py index 7f9e5bb80fbf91..4e992cefc6869d 100644 --- a/util/design/lib/LcStEnc.py +++ b/util/design/lib/LcStEnc.py @@ -8,9 +8,8 @@ from collections import OrderedDict from Crypto.Hash import cSHAKE128 -from lib.common import (check_int, ecc_encode, expand_seed, get_hd, - hd_histogram, is_valid_codeword, random_or_hexvalue, - scatter_bits) +from lib.common import (check_int, ecc_encode, get_hd, hd_histogram, + is_valid_codeword, random_or_hexvalue, scatter_bits) from topgen import secure_prng as sp # Seed diversification constant for LcStEnc (this enables to use @@ -288,7 +287,7 @@ def __init__(self, config): log.info('Seed: {0:x}'.format(config['seed'])) log.info('') - sp.reseed(expand_seed(LC_SEED_DIVERSIFIER + int(config['seed']))) + sp.reseed(LC_SEED_DIVERSIFIER + int(config['seed'])) log.info('Checking SECDED.') _validate_secded(config) diff --git a/util/design/lib/OtpMemMap.py b/util/design/lib/OtpMemMap.py index 0f9d8976fb8ca2..cec5baadf15a76 100644 --- a/util/design/lib/OtpMemMap.py +++ b/util/design/lib/OtpMemMap.py @@ -8,7 +8,7 @@ import logging as log from math import ceil, log2 -from lib.common import check_bool, check_int, expand_seed, random_or_hexvalue +from lib.common import check_bool, check_int, random_or_hexvalue from mubi.prim_mubi import is_width_valid, mubi_value_as_int from tabulate import tabulate from topgen import secure_prng as sp @@ -405,7 +405,7 @@ def __init__(self, config): config["seed"] = check_int(config["seed"]) # Initialize RNG. - sp.reseed(expand_seed(OTP_SEED_DIVERSIFIER + int(config['seed']))) + sp.reseed(OTP_SEED_DIVERSIFIER + int(config['seed'])) log.info('Seed: {0:x}'.format(config['seed'])) log.info('') diff --git a/util/design/lib/common.py b/util/design/lib/common.py index 820ce0f6b1abe9..73167ab8f9fee5 100644 --- a/util/design/lib/common.py +++ b/util/design/lib/common.py @@ -7,7 +7,7 @@ import re import sys import textwrap -from math import ceil, log, log2 +from math import ceil, log2 from pathlib import Path sys.path.append(os.path.join(os.path.dirname(__file__), '../../')) @@ -116,19 +116,6 @@ def blockify(s, size, limit): return (",\n ".join(s_list)) -def expand_seed(seed): - '''Checks if the input seed is shorter than 256 bits and expands it if - it's not. - ''' - new_seed = seed - seed_bytes = ceil(log(seed + 1, 256)) - while new_seed < (1 << 256): - new_seed <<= seed_bytes * 8 - new_seed += seed - new_seed %= (1 << 256) - return new_seed - - def get_random_perm_hex_literal(numel): '''Compute a random permutation of 'numel' elements and return as packed hex literal.''' diff --git a/util/topgen.py b/util/topgen.py index df4534447c2c3a..51c52eb4ed2cb3 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -19,7 +19,6 @@ import hjson import tlgen import version_file -from design.lib.common import expand_seed from ipgen import (IpBlockRenderer, IpConfig, IpDescriptionOnlyRenderer, IpTemplate, TemplateRenderError) from mako import exceptions @@ -1081,7 +1080,8 @@ def main(): elif "rnd_cnst_seed" not in topcfg: log.error('Seed "rnd_cnst_seed" not found in configuration HJSON.') exit(1) - secure_prng.reseed(expand_seed(topcfg["rnd_cnst_seed"])) + + secure_prng.reseed(topcfg["rnd_cnst_seed"]) # TODO, long term, the levels of dependency should be automatically # determined instead of hardcoded. The following are a few examples: diff --git a/util/topgen/secure_prng.py b/util/topgen/secure_prng.py index f036b5fcc9a317..ce025f1d34f46b 100644 --- a/util/topgen/secure_prng.py +++ b/util/topgen/secure_prng.py @@ -173,23 +173,25 @@ def reseed(self, seed): from previous instantiation. """ if seed == 0: - entropy_input = seed.to_bytes(32, 'big') log.error("ERROR: PRNG seeded with 0.") sys.exit(1) - # Check if the provided seed is at least 32 bytes long. - elif sys.getsizeof(seed) < sys.getsizeof(1 << 255): - # Error out if seed is shorter than 256 bits. - log.error("ERROR: Seed shorter than 256 bits.") - sys.exit(1) + + if seed.bit_length() < 250: + # Warn, but don't fail, because the DV logic always passes in 32-bit + # seeds and this can naturally happen about 1% of the time. + log.warn('PRNG seed is only {seed.bit_length()} bits long, which is ' + 'unlikely for a sample from a 256-bit distribution. Please ' + 'double-check the logic.') # Check if the seed is longer than 256 bits. Trim the excess bits and # issue a warning if it is. - elif seed > (1 << 256): + if seed.bit_length() > 256: new_seed = seed % (1 << 256) log.warning("Seed longer than 256 bits. CTR_DRBG seeded with: " + hex(new_seed)) entropy_input = new_seed.to_bytes(32, 'big') else: entropy_input = seed.to_bytes(32, 'big') + self.CTR_DRBG_Instantiate(entropy_input) self.returned_bits = []