mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-05 17:56:10 +00:00
feat(core): Use Optiga as a source of randomness.
This commit is contained in:
parent
8c98015b67
commit
686aa78aa7
1
core/.changelog.d/3256.added
Normal file
1
core/.changelog.d/3256.added
Normal file
@ -0,0 +1 @@
|
||||
Use Optiga as a source of randomness in seed generation for Model R.
|
@ -23,6 +23,10 @@
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
#if USE_OPTIGA
|
||||
#include "optiga.h"
|
||||
#endif
|
||||
|
||||
/// package: trezorcrypto.random
|
||||
|
||||
/// def uniform(n: int) -> int:
|
||||
@ -40,22 +44,52 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_uniform_obj,
|
||||
mod_trezorcrypto_random_uniform);
|
||||
|
||||
/// import builtins
|
||||
/// def bytes(len: int) -> builtins.bytes:
|
||||
/// def bytes(len: int, strong: bool = False) -> builtins.bytes:
|
||||
/// """
|
||||
/// Generate random bytes sequence of length len.
|
||||
/// Generate random bytes sequence of length len. If `strong` is set then
|
||||
/// maximum sources of entropy are used.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorcrypto_random_bytes(mp_obj_t len) {
|
||||
uint32_t l = trezor_obj_get_uint(len);
|
||||
if (l > 1024) {
|
||||
STATIC mp_obj_t mod_trezorcrypto_random_bytes(size_t n_args,
|
||||
const mp_obj_t *args) {
|
||||
uint32_t len = trezor_obj_get_uint(args[0]);
|
||||
if (len > 1024) {
|
||||
mp_raise_ValueError("Maximum requested size is 1024");
|
||||
}
|
||||
vstr_t vstr = {0};
|
||||
vstr_init_len(&vstr, l);
|
||||
random_buffer((uint8_t *)vstr.buf, l);
|
||||
vstr_init_len(&vstr, len);
|
||||
#if USE_OPTIGA
|
||||
if (n_args > 1 && mp_obj_is_true(args[1])) {
|
||||
uint8_t *dest = (uint8_t *)vstr.buf;
|
||||
if (!optiga_random_buffer(dest, len)) {
|
||||
vstr_clear(&vstr);
|
||||
mp_raise_msg(&mp_type_RuntimeError,
|
||||
"Failed to get randomness from Optiga.");
|
||||
}
|
||||
|
||||
uint8_t buffer[4] = {0};
|
||||
while (len > sizeof(buffer)) {
|
||||
random_buffer(buffer, sizeof(buffer));
|
||||
for (int i = 0; i < sizeof(buffer); ++i) {
|
||||
*dest ^= buffer[i];
|
||||
++dest;
|
||||
}
|
||||
len -= sizeof(buffer);
|
||||
}
|
||||
|
||||
random_buffer(buffer, len);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
*dest ^= buffer[i];
|
||||
++dest;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
random_buffer((uint8_t *)vstr.buf, len);
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_bytes_obj,
|
||||
mod_trezorcrypto_random_bytes);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_random_bytes_obj, 1,
|
||||
2, mod_trezorcrypto_random_bytes);
|
||||
|
||||
/// def shuffle(data: list) -> None:
|
||||
/// """
|
||||
|
@ -39,4 +39,6 @@ bool optiga_cert_size(uint8_t index, size_t *cert_size);
|
||||
bool optiga_read_cert(uint8_t index, uint8_t *cert, size_t max_cert_size,
|
||||
size_t *cert_size);
|
||||
|
||||
bool optiga_random_buffer(uint8_t *dest, size_t size);
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "optiga.h"
|
||||
#include <string.h>
|
||||
#include "optiga_commands.h"
|
||||
|
||||
int optiga_sign(uint8_t index, const uint8_t *digest, size_t digest_size,
|
||||
@ -89,3 +90,22 @@ bool optiga_read_cert(uint8_t index, uint8_t *cert, size_t max_cert_size,
|
||||
cert, max_cert_size, cert_size);
|
||||
return OPTIGA_SUCCESS == ret;
|
||||
}
|
||||
|
||||
bool optiga_random_buffer(uint8_t *dest, size_t size) {
|
||||
while (size > OPTIGA_RANDOM_MAX_SIZE) {
|
||||
if (optiga_get_random(dest, OPTIGA_RANDOM_MAX_SIZE) != OPTIGA_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
dest += OPTIGA_RANDOM_MAX_SIZE;
|
||||
size -= OPTIGA_RANDOM_MAX_SIZE;
|
||||
}
|
||||
|
||||
if (size < OPTIGA_RANDOM_MIN_SIZE) {
|
||||
static uint8_t buffer[OPTIGA_RANDOM_MIN_SIZE] = {0};
|
||||
optiga_result ret = optiga_get_random(buffer, OPTIGA_RANDOM_MIN_SIZE);
|
||||
memcpy(dest, buffer, size);
|
||||
return ret == OPTIGA_SUCCESS;
|
||||
}
|
||||
|
||||
return optiga_get_random(dest, size) == OPTIGA_SUCCESS;
|
||||
}
|
||||
|
@ -338,7 +338,8 @@ optiga_result optiga_set_data_object(uint16_t oid, bool set_metadata,
|
||||
* https://github.com/Infineon/optiga-trust-m/blob/develop/documents/OPTIGA%E2%84%A2%20Trust%20M%20Solution%20Reference%20Manual.md#getrandom
|
||||
*/
|
||||
optiga_result optiga_get_random(uint8_t *random, size_t random_size) {
|
||||
if (random_size < 8 || random_size > 256) {
|
||||
if (random_size < OPTIGA_RANDOM_MIN_SIZE ||
|
||||
random_size > OPTIGA_RANDOM_MAX_SIZE) {
|
||||
return OPTIGA_ERR_SIZE;
|
||||
}
|
||||
|
||||
|
@ -125,6 +125,8 @@ typedef struct {
|
||||
#define OPTIGA_ECC_KEY_COUNT 4
|
||||
#define OPTIGA_CERT_COUNT 4
|
||||
#define OPTIGA_MAX_METADATA_SIZE 44
|
||||
#define OPTIGA_RANDOM_MIN_SIZE 8
|
||||
#define OPTIGA_RANDOM_MAX_SIZE 256
|
||||
|
||||
#define OPTIGA_ACCESS_CONDITION(ac_id, oid) \
|
||||
{ (const uint8_t[]){ac_id, oid >> 8, oid & 0xff}, 3 }
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ecdsa.h"
|
||||
#include "nist256p1.h"
|
||||
#include "optiga_common.h"
|
||||
#include "rand.h"
|
||||
|
||||
static const uint8_t DEVICE_CERT_CHAIN[] = {
|
||||
0x30, 0x82, 0x01, 0x90, 0x30, 0x82, 0x01, 0x37, 0xa0, 0x03, 0x02, 0x01,
|
||||
@ -145,3 +146,8 @@ bool optiga_read_cert(uint8_t index, uint8_t *cert, size_t max_cert_size,
|
||||
*cert_size = sizeof(DEVICE_CERT_CHAIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool optiga_random_buffer(uint8_t *dest, size_t size) {
|
||||
random_buffer(dest, size);
|
||||
return true;
|
||||
}
|
||||
|
@ -10,9 +10,10 @@ import builtins
|
||||
|
||||
|
||||
# extmod/modtrezorcrypto/modtrezorcrypto-random.h
|
||||
def bytes(len: int) -> builtins.bytes:
|
||||
def bytes(len: int, strong: bool = False) -> builtins.bytes:
|
||||
"""
|
||||
Generate random bytes sequence of length len.
|
||||
Generate random bytes sequence of length len. If `strong` is set then
|
||||
maximum sources of entropy are used.
|
||||
"""
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ async def reset_device(msg: ResetDevice) -> Success:
|
||||
raise ProcessError("Failed to set PIN")
|
||||
|
||||
# generate and display internal entropy
|
||||
int_entropy = random.bytes(32)
|
||||
int_entropy = random.bytes(32, True)
|
||||
if __debug__:
|
||||
storage.debug.reset_internal_entropy = int_entropy
|
||||
if msg.display_random:
|
||||
|
@ -19,6 +19,6 @@ async def get_entropy(msg: GetEntropy) -> Entropy:
|
||||
)
|
||||
|
||||
size = min(msg.size, 1024)
|
||||
entropy = random.bytes(size)
|
||||
entropy = random.bytes(size, True)
|
||||
|
||||
return Entropy(entropy=entropy)
|
||||
|
@ -443,9 +443,11 @@ def _split_secret(
|
||||
|
||||
random_share_count = threshold - 2
|
||||
|
||||
shares = [(i, random.bytes(len(shared_secret))) for i in range(random_share_count)]
|
||||
shares = [
|
||||
(i, random.bytes(len(shared_secret), True)) for i in range(random_share_count)
|
||||
]
|
||||
|
||||
random_part = random.bytes(len(shared_secret) - _DIGEST_LENGTH_BYTES)
|
||||
random_part = random.bytes(len(shared_secret) - _DIGEST_LENGTH_BYTES, True)
|
||||
digest = _create_digest(random_part, shared_secret)
|
||||
|
||||
base_shares = shares + [
|
||||
|
@ -784,11 +784,11 @@
|
||||
"TR_test_pin.py::test_wipe_code_setup": "2f1d097810aa38ff87acef79133ccc735a9523118a1d83420efb84db21a05d97",
|
||||
"TR_test_recovery.py::test_recovery_bip39": "7f969a6623c767e62e50e246bb67e57fdcc7447b8bdd14155d98a6e6c7675a57",
|
||||
"TR_test_recovery.py::test_recovery_slip39_basic": "c2efcb8016f9fa4771297f535e9eed1dc12d898a07936c9fc047b290705a6def",
|
||||
"TR_test_reset_bip39.py::test_reset_bip39": "57a37b7b0a2c535fafec929bbb15b95b9bb2387b9a64655de9342ce03e03551a",
|
||||
"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced[16of16]": "dda360b15510bf207231d7596a5aaab3082ad9e13cd85624d8c9ee6df40d95ae",
|
||||
"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced[2of2]": "c7f2bf8cf3fb70baaf6d5799cd50641a01c71e231b23a0d8eed3b416126bec83",
|
||||
"TR_test_reset_slip39_basic.py::test_reset_slip39_basic[16of16]": "e0925d33d34b0901ce4794adea1c412f4d073c87606a283b619fc1639973ef9b",
|
||||
"TR_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "18064813219c189a3bc8fd5c1be52929cccc3be58c91e42f1e0fcbd5caf5dcc3",
|
||||
"TR_test_reset_bip39.py::test_reset_bip39": "7dee2da63f3d220b4a1466b59da6c89a623d1a55c3d5300efe37761d064435db",
|
||||
"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced[16of16]": "0442794f3b952b6362d6569eaf15af002e7af5ccd3fedcf5339a9e75a61cb6e7",
|
||||
"TR_test_reset_slip39_advanced.py::test_reset_slip39_advanced[2of2]": "83d29833c99068a474c7b1c841cd0a88c92d3fba0e471d5e10dcd0d58b164d7a",
|
||||
"TR_test_reset_slip39_basic.py::test_reset_slip39_basic[16of16]": "11239923e51327c518bcb6123c8e645b0e34174b1857ff64a2e7cbd49b3bcc21",
|
||||
"TR_test_reset_slip39_basic.py::test_reset_slip39_basic[1of1]": "b51e9c4b3fc6962c128a75676a0ef5a08d72e69abe825707195fcdaf7b114760",
|
||||
"TR_test_tutorial.py::test_tutorial_again_and_skip": "c611a049ccc584fd69abf55bac3b185e370e0680990afb3139b755fd1f41a19e",
|
||||
"TR_test_tutorial.py::test_tutorial_finish": "1ae785e1ff678241aa18a254ae755a002ccd62550cbbd1dd92fa3cbd53d071b0",
|
||||
"TR_test_tutorial.py::test_tutorial_skip": "00a893066c2578f14ae9ab749791f1dde753b43be460d69a304aaae8704cfe8a"
|
||||
@ -1794,24 +1794,24 @@
|
||||
"TR_reset_recovery-test_recovery_slip39_basic.py::test_wrong_nth_word[2]": "92606a46453e87a9c59a89e76568c9aad3009d4f0d15aa53cafd0eeb92885a2a",
|
||||
"TR_reset_recovery-test_recovery_slip39_basic_dryrun.py::test_2of3_dryrun": "95aa55b8fc244bb61c60e602683570711b95f829587e4da469f229cac53a99f7",
|
||||
"TR_reset_recovery-test_recovery_slip39_basic_dryrun.py::test_2of3_invalid_seed_dryrun": "31665a411ee0d7da0f5577a349224ee2a285b34fce5519923bc09e918aed27dc",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Bip39-backup_flow_bip39]": "ce9b32e21af32d0375528c5b4372b42b26e1fbd0228898b054a24bf720c9ceba",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Slip39_Advanced-bac-f67baa1c": "6cd86f6d80aa8fc5d85f1b0f87c6660b1e22f450e406a7c4b5fcb7b6f98f4093",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Slip39_Basic-backup-6348e7fe": "43f81d8e72e41cbeec95cfa35f28637c0af5dd25c51c49239c2d88526a8b3dd6",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Bip39-backup_flow_bip39]": "481ef01eac32b443e93b4ad01cf347b7a6fae23cd7ff4294a96f69038dda4acd",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Slip39_Advanced-backup-dcbda5cf": "892dd4ca104647a7b10a9a7abe25f414a79459a1256d8caa156d88269d199826",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Slip39_Basic-backup_fl-1577de4d": "141bff02439fecde33953519dea921d82e65b580a318800b4062dba4316aebc3",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Bip39-backup_flow_bip39]": "f60a5c63c74cafbfda26817acf3a409e05cb3746b916565f3510569754f579a0",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Slip39_Advanced-bac-f67baa1c": "6d270737f23bd05874d9a7a7234f42fb5e0cec3769dee0186c3337c7c78b79a8",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_manual[BackupType.Slip39_Basic-backup-6348e7fe": "809e150906fc39a019d96c88107032ab36a02796ebe6fb5c05075530a1109f60",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Bip39-backup_flow_bip39]": "fd5655cdfe6e76fd15ef57712c4ba0439ce20ef37f4ce0e540c1109f924e084c",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Slip39_Advanced-backup-dcbda5cf": "a485b1ec23a04252daf716bde35a344984e538b297d86edd85a2ad30ed3e3a0a",
|
||||
"TR_reset_recovery-test_reset_backup.py::test_skip_backup_msg[BackupType.Slip39_Basic-backup_fl-1577de4d": "ce97ecddf443af2f99d4de0403ad83f4db1d9b3db9c0f58cc429d68165785212",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_already_initialized": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_failed_pin": "6b4f02ba25b4199d426a8238bb28fff6bfbeabe1f921352a19b3d651921a4b2b",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device": "c9ae1b520663693155b17be4cc69c45f18026fcaa67934a974852bebe1474019",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device_192": "1c8dc7da58fca6d5e4519ee250517a6263ba46f04c72d496b52b130d80dfddcc",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device_pin": "7d196f117fd495b8b87b65e7181fee3019a7298c79e97fda44c46321ab9919a1",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_failed_check": "95ab7a3593621b7595e7d7945e73e4a7c475d37bafb61410336765dd32b4dc83",
|
||||
"TR_reset_recovery-test_reset_recovery_bip39.py::test_reset_recovery": "7473c5202491021ffc0347665f495a07734c4ab52217058ce744683b96b179dd",
|
||||
"TR_reset_recovery-test_reset_recovery_slip39_advanced.py::test_reset_recovery": "0e127d30feeea33985959bb531174cd5c4e1e59481c11c92bc6a5e97a77811d2",
|
||||
"TR_reset_recovery-test_reset_recovery_slip39_basic.py::test_reset_recovery": "70766853f7bc80d743de6fd1c99ac7111cbb243626379f71539f20efe0f7f8c8",
|
||||
"TR_reset_recovery-test_reset_slip39_advanced.py::test_reset_device_slip39_advanced": "4e9173dd4894e1094e7f121cc898668f2c4f834ac3613e39cf0c3e2a75c3b424",
|
||||
"TR_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic": "02b8ef44d443b557457628c21f4ad0d15d4acc1d65f14efefe889055067053b9",
|
||||
"TR_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic_256": "1cc4431bd4e7ce4851a86fafdcfd75f5acce3fa4a6f18aaaafb3c2906ac364cc",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device": "ca712743e8937bc7db6265810964d20d292f8166315fd9c30c9a3b5ae82ab6c9",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device_192": "189b6effb1666f250bec4813028f8af24407c08e6be14287dca563db1c04afd6",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_device_pin": "b236293539ac37adb87fb07bfa6de5b4079ded32c437eb79f3fa58fd73a781bd",
|
||||
"TR_reset_recovery-test_reset_bip39_t2.py::test_reset_failed_check": "e3f1151b8480d47c00d10073fab067096f252a7982abe828f3208efb2aa6220b",
|
||||
"TR_reset_recovery-test_reset_recovery_bip39.py::test_reset_recovery": "daccf2d9264bd4776a9d2201494e5b41f2960ad7ceaa5090eabe640009af88eb",
|
||||
"TR_reset_recovery-test_reset_recovery_slip39_advanced.py::test_reset_recovery": "29c42c776be9cdba7a47a4df4454480e0fce21131692d4ebdd9d1ac2d343380a",
|
||||
"TR_reset_recovery-test_reset_recovery_slip39_basic.py::test_reset_recovery": "d6c56240ad61f1aeaf28c5de0aafa2970bbb37a7b55d01890a4fcd3dbb1db633",
|
||||
"TR_reset_recovery-test_reset_slip39_advanced.py::test_reset_device_slip39_advanced": "19492556256195acbab3865f663cb3127d1bfb8a7d27b2000b870d082f8575a3",
|
||||
"TR_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic": "e79608b2335fba3da5b52a896e4ce0095acb5305688993617e09329b8220087b",
|
||||
"TR_reset_recovery-test_reset_slip39_basic.py::test_reset_device_slip39_basic_256": "a573066d7bedd8318c412de713743bdf3ac50775a634c7ee55435fd37e3a2987",
|
||||
"TR_ripple-test_get_address.py::test_ripple_get_address": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
|
||||
"TR_ripple-test_get_address.py::test_ripple_get_address_other": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
|
||||
"TR_ripple-test_sign_tx.py::test_ripple_sign_invalid_fee": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
|
||||
@ -1915,9 +1915,9 @@
|
||||
"TR_test_msg_applysettings.py::test_safety_checks": "83080cba06af0a9c47ff0316a38096a17d21fcd7034b7878db9b4e6f9c01ad06",
|
||||
"TR_test_msg_backup_device.py::test_backup_bip39": "a765ee7fbf3e763d7fbfee248d7afe159e1986975e1d94635a50631828e6695b",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_advanced[click_info]": "b6e34f1ccd560f41f3b33b4755e900089797898a66c8fdfd28d9f61274e873f4",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_advanced[no_click_info]": "ef0eaf62ca8e071a696b34b794541930e6a85b7008d3d414406a714e81f93431",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_advanced[no_click_info]": "d03ec76ae176f4a7dfd3f4df83fdecd8dfd1ef29bec85e5c21e3ec97937b970b",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_basic[click_info]": "b6e34f1ccd560f41f3b33b4755e900089797898a66c8fdfd28d9f61274e873f4",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_basic[no_click_info]": "22c4d375b8ac2f7bcc2c65c5260eb3e72e4ee20524fa65d9457ba41fe61f1111",
|
||||
"TR_test_msg_backup_device.py::test_backup_slip39_basic[no_click_info]": "9df6f18e33ff9412f0817dc2f0da2b96b1df4fed0252fbe09e1ee0f521dcba47",
|
||||
"TR_test_msg_backup_device.py::test_interrupt_backup_fails": "1139f673473fbf725b2ee52d4965917c6a72676e69b073707f40b556a48f4b79",
|
||||
"TR_test_msg_backup_device.py::test_no_backup_fails": "60c13acb4f8e40ee32f9d01415cbcbd75ffcd6a4015003d93562e84c3901a62f",
|
||||
"TR_test_msg_backup_device.py::test_no_backup_show_entropy_fails": "f49c8d846c2d56a575f0ad49463845ba641b02656783e4fcfc67d74e8fa671dd",
|
||||
|
Loading…
Reference in New Issue
Block a user