From 8cfe0607a9a9d7d68b4949e3c4de85a5d57bc7c0 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/OtpMemImg.py | 2 +- util/design/lib/OtpMemMap.py | 4 ++-- util/design/lib/common.py | 15 +-------------- util/topgen.py | 4 ++-- util/topgen/secure_prng.py | 16 +++++++++------- 6 files changed, 18 insertions(+), 30 deletions(-) diff --git a/util/design/lib/LcStEnc.py b/util/design/lib/LcStEnc.py index 7f9e5bb80fbf9..4e992cefc6869 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/OtpMemImg.py b/util/design/lib/OtpMemImg.py index 2973c3efbd869..057915f4898d2 100644 --- a/util/design/lib/OtpMemImg.py +++ b/util/design/lib/OtpMemImg.py @@ -224,7 +224,7 @@ def __init__(self, lc_state_config, otp_mmap_config, img_config, log.info('') # Re-initialize with seed to make results reproducible. - sp.reseed(common.expand_seed(OTP_IMG_SEED_DIVERSIFIER + int(img_config['seed']))) + sp.reseed(OTP_IMG_SEED_DIVERSIFIER + int(img_config['seed'])) if 'partitions' not in img_config: raise RuntimeError('Missing partitions key in configuration.') diff --git a/util/design/lib/OtpMemMap.py b/util/design/lib/OtpMemMap.py index 0f9d8976fb8ca..cec5baadf15a7 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 820ce0f6b1abe..73167ab8f9fee 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 df4534447c2c3..51c52eb4ed2cb 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 f036b5fcc9a31..ce025f1d34f46 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 = []