Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have CRNG avail early on boot and maximize ligcrypt entropy sources/efficiency #1478

Conversation

tlaurion
Copy link
Collaborator

@tlaurion tlaurion commented Aug 24, 2023

This PR at time of merging:

  • unifies linux configs and make sure HW entropy is on
  • unified coreboot kernel options to set log default to loglevel=2
  • Output of warn/die/DEBUG/TRACE are now under kernel log if DEBUG is enabled
  • crng is ready early giving weight to HW provided entropy source, removing errors on dmesg and console

Older traces of history:

  • Have CRNG avail early on boot and maximize ligcrypt entropy sources/efficiency #1478 (comment) clarifies what trust cpu is really about. In short, it is about giving weight to RDRAND RDSEED and not giving warning about crng and accessing random pools prior of them having enough entropy collected.
  • Have CRNG avail early on boot and maximize ligcrypt entropy sources/efficiency #1478 (comment) shows that HOTP/TOTP boards have differences in crng init being ready at different times (4s-30 seconds) depending of if USB stacks related modules loaded and IO linked to all of those operations. We could duplicate linux configs to trustcpu on TOTP boards only, but that doesn't make sense following Have CRNG avail early on boot and maximize ligcrypt entropy sources/efficiency #1478 (comment) analysis.
  • It is thought that enabling TRUSTCPU is better then nothing, while it is to be reminded that even if trustcpu is not enabled, CPU RDRAND/RDSEED are used where available to fill the pool. It is also noted that we would need to have rng-tools to mix entropy sources under /dev/urandom.
  • As of now, /dev/urandom is used directly, even if pool entropy is available or not by: shred, tpm cryptsetup and others. But, those calls are made when the pool is having enough entropy anyway.
  • libgcrypt by this PR makes available all available CPU optimizations for gnupg calls. If jitter was enabled in the kernel, libgcrypt would use it.

So basically, next steps for future work are:

  • Add rng-tools to mix entropy sources and make that avail under /dev/urandom which is used by most tools
  • Enable jitter in all kernel configuration so that IO/cpu + RDRAND/RDSEED+Jitter is used at time of generating keys

But as of now, simply trusting CPU is good enough and if not, shred and tpm calls made prior of crng being ready are also good, while not easthetic.

Note: 00e7156#diff-a890ddf36ae7dca110b70df101c97525a4d8265212ebed3f92562d47162af3a2 enabled trustcpu on most older boards.

Consequence as this PR goes through is that

  • cryptsetup reads through /dev/urandom which is not blocking if pool is not ready
  • shred and tpm are using /dev/urandom as well which is unblocking as opposed to /dev/random
  • gnupg currently uses kernel entropy and sets base for additional entropy sources and accelerations per removal --disable-asm under libgcrypt

Older:

This is PoC to fix #1476

  • Does rely on trust CPU. CPU RAND is first source to fill entropy pool early on boot. coreboot's linux command line turns it "on" explicitly edit: not needed on qemu with virtio supported in kernel and qemu/kvm existing command line options reusing host's available entropy as source.
  • Jitter is added into kernel configs, and coreboot's linux command line option sets basic values to configure jitter Tpm is now turned off since not aggregated by kernel alone
  • TPM was already configured to be a source of randomness in kernel config, but weight was not adjusted in coreboot's kernel config to ponder properly. This is done now Jitter and TPM hardware source of entropy are now turned off since not aggregated by kernel alone.
  • libgcrypt is now compiled to take advantage of available CPU enhancements, including jitter and RDRAND if available, where jitter is used by libgrypt in gnupg operations. This is to be tested, but master was disabling all of those by configuring libgcrypt with --disable-asm
  • qemu now turn on virtio "HW" entropy source (virtio, so host's provided /dev/urandom). ~Comparable to RDRAND
  • Not clear what is available out of the box for PPC

Tested in QEMU (TCG, not KVM, sloooooooow)

  • crng init=0 to readiness takes less then a second. with virtio, crng on qemu is ready under 6s, prior of first entropy pool access.
  • DIFFERENT for ivy bridge+ (xx30: x230/t430/t530/w530/t440p and comparable). crng is ready between 16s-30s.
  • Sandy bridge- (xx20: x20/t420/others) will continue to be slow to have crng ready at boot: RDRAND was added to ivy, not sandy: so xx20 Lenovo will rely on jitter from libgcrypt here even more. Thanks to libgcrypt 1.10+ this is on by default.

TODO:

  • Validate that the sources of entropy are available, selected and used
  • Adapt linux config to make sure CPU features are exposed (AMD/Qemu) Edit: virtio only here, amd cpu is older family and needed RDSEED nor RDRAND is available on q35.
  • Give traces and testing paths for reproducibility and auditability of change. Edit: gpg --benchmark not available. Edit: even if availabe, not su useful.
  • Validate that libgcrypt uses additional entropy source when generating keys in memory: edit: this is sufficient AFAIK without need to trust CPU to have crng and with libgcrypt enabling and mixing all available platform enhancements.
  • check what is available to PPC

@tlaurion tlaurion marked this pull request as draft August 24, 2023 15:13
@tlaurion
Copy link
Collaborator Author

No. Won't fly without rngd. Kernel doesn't aggregate multiple sources. Hopefully, rngd that depends on libgrypt we already use for gpg2 can be used and found resources stipulate that it could be as small as 18k when compiled with -Os. Let's see.

@tlaurion
Copy link
Collaborator Author

rngd-tools have dependencies on libcap which hardcodes cross compilation assumptions under Makefile and Make.Rules... Not successful as of now.

Can we remove libcap dependencies? Seems like another subproject.

As in current state

  • qemu depends on virtio which is fed by host. Good enough.
  • other physical platforms could depend on either jitter, cpu trust or TPM, where tpm seems to require additional tooling.

We could probably trust libgcrypt + cpu extension here as a start.

@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from ba265a1 to 94370b6 Compare August 29, 2023 14:58
@tlaurion
Copy link
Collaborator Author

tlaurion commented Aug 29, 2023

Ok so after having looked into this deeper:

  • Heads taps into /dev/urandom so not locking if not enough entropy. Requires pool to be ready prior of generating key material and such, or locking by switching use of /dev/urandom to /dev/random so that we lock until we have enough entropy to shread files or do totp unseal ops with tpm toolstacks.
  • Kernel does not aggregate multiple sources of entropy, offloading the task to userland (rng-tool would be fit here if we wanted to enable jitter+tpm+cpu)
    • My past attempt to integrate libcap was not libcap-ng but I think we should take gradual steps here. Reminder that openwrt patches and build recipes are good source of info for Heads
  • tpm hw needs toolstack to read into it, but source is slow (10-20 bits second)
  • jitter needs toolstack to read into it, could be alternative
  • cpu hw (AMD/INTEL) is fast enough.

I added sysctl fs in kernel for all boards. Enabled CPU HW for all boards. Qemu uses virtio of host.
So as of now, crng is ready prior of doing anything early )shred of secrets, tpm operations) which is better then before.

I have not digged into libgcrypt entropy sourcing, but I also think that it will be better then before. Would need testing here, but I think the PR is an improvement prior of before with next commits.

Will clean after review.

@JonathonHall-Purism Haven't touched librems outside of putting librem_l1um2 to oldconfig (linux.save_in_old_config would require a lot of review, you are activating a bunch of unneeded stuff right now). Let me know if you want me to enable comparative configs for librems in this PR.

This is needed prior of in-memory key gen PR to be testable.

@tlaurion
Copy link
Collaborator Author

tlaurion commented Aug 30, 2023

By disabling --disable-asm in libgcrypt 1.10.1:

config.status: executing gcrypt-conf commands
         
        Libgcrypt v1.10.1 has been configured as follows:
         
        Platform:                  GNU/Linux (x86_64-pc-linux-musl)
        Hardware detection module: libgcrypt_la-hwf-x86
        Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish
                                   serpent rfc2268 seed camellia idea salsa20
                                   gost28147 chacha20 sm4
        Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
                                   sha256 sha512 sha3 tiger whirlpool stribog
                                   blake2 sm3
        Enabled kdf algorithms:    s2k pkdf2 scrypt
        Enabled pubkey algorithms: dsa elgamal rsa ecc
        Random number generator:   default
        Try using jitter entropy:  yes
        Using linux capabilities:  no
        FIPS module version:       
        Try using Padlock crypto:  yes
        Try using AES-NI crypto:   yes
        Try using Intel SHAEXT:    yes
        Try using Intel PCLMUL:    yes
        Try using Intel SSE4.1:    yes
        Try using DRNG (RDRAND):   yes
        Try using Intel AVX:       yes
        Try using Intel AVX2:      yes
        Try using ARM NEON:        n/a
        Try using ARMv8 crypto:    n/a
        Try using PPC crypto:      n/a
  • To support PPC crypto, it seems we will need yasm.
  • To support linux capabilities, libcap would be required as well later on. :/ another point for rng-tools (which also depends on libcap-ng)

As on master otherwise with --disable-asm:

config.status: executing gcrypt-conf commands
         
        Libgcrypt v1.10.1 has been configured as follows:
         
        Platform:                  GNU/Linux (x86_64-pc-linux-musl)
        Hardware detection module: none
        Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish
                                   serpent rfc2268 seed camellia idea salsa20
                                   gost28147 chacha20 sm4
        Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
                                   sha256 sha512 sha3 tiger whirlpool stribog
                                   blake2 sm3
        Enabled kdf algorithms:    s2k pkdf2 scrypt
        Enabled pubkey algorithms: dsa elgamal rsa ecc
        Random number generator:   default
        Try using jitter entropy:  yes
        Using linux capabilities:  no
        FIPS module version:       
        Try using Padlock crypto:  n/a
        Try using AES-NI crypto:   n/a
        Try using Intel SHAEXT:    n/a
        Try using Intel PCLMUL:    n/a
        Try using Intel SSE4.1:    n/a
        Try using DRNG (RDRAND):   n/a
        Try using Intel AVX:       n/a
        Try using Intel AVX2:      n/a
        Try using ARM NEON:        n/a
        Try using ARMv8 crypto:    n/a
        Try using PPC crypto:      n/a

@tlaurion
Copy link
Collaborator Author

Todo

  • check output of configure for Talos and validate detection are enabled

@tlaurion tlaurion changed the title Stenghten entropy sources with jitter and tpm Have CRNG avail early on boot and maximize ligcrypt entropy sources/efficiency Aug 30, 2023
@tlaurion
Copy link
Collaborator Author

tlaurion commented Aug 31, 2023

@saper @JonathonHall-Purism @daringer On second thoughts, i'm not even convinced that --disable-asm should be removed from libgcrypt. I mean it's an improvement for sure, but its not needed. Let me explain why.

I mean as shown at #1478 (comment), with or without asm code to detect CPU enabled acceleration for different CPUs extensions (which speedups in memory keygen) I want to bring your attention there on the important fact: what we really wanted here, which is Try using jitter entropy: yes is already enabled by default on libgcrypt 1.10.1 as we currently use it (is new on 1.10).

So my reasoning here is that by trusting the CPU for crng init (early boot entropy pool made ready for use), calling gnupg already takes advantage of jitter to not only use flimsy entropy as in master (the poolk was not ready) or now trusted HW provided RDRAND cpu extension enforced entropy (and also virtio under QEMU/KVM to simulate tests, which rely on host's entropy availability, AMD emulated CPU not recent enough to enable and use AMD HW CPU RDRAND there anyway).

Note that we have the space to enable all of that. Question is if --disable-asm was put in place early under Heads libgcrypt module for reproducibility reason (I would doubt so but maybe) which is not a problem for a while now AFAIK.

Thoughts? I think that in current state, this PR is a massive improvement where next steps would be to attack rng-tools inclusion (meaning libcap-ng inclusion) if we want to enable jitter in kernel + tpm hw entropy backend and have rng-tool feed /dev/random and /dev/urandom with proper entropy, mixing all of the above.

But in my opinion, this is not needed here and now and can be enabled later on in future PR. This PR in current state fits the bill and improves current master's situation.

Putting PR as ready for review. Will clean commits/squash prior of merging, I think those are important to see what was tested where and how for willing reviewers in its current state.

@tlaurion tlaurion marked this pull request as ready for review August 31, 2023 16:39
@tlaurion
Copy link
Collaborator Author

Ok, after some challenging discussions with @JonathonHall-Purism :

New facts:

  • cryptsetup uses /dev/urandom by default, meaning it trusts totally entropy provided by RDRAND without mixing it in with anything else. To change behavior, one would have to call cryptsetup with --use-random to generate long-term volume key, use at both luksFormat and by cryptsetup-reencrypt.
  • libgcrypt 1.10+ changed their defaults to mix in jitter in kernel provided source, so in memory keygen is ok currently on master, no need to trust cpu.
  • Need is to review current crng status on x230, observations from qemu are not valid
  • qemu will keep trust cpu, since virtio "hw" source is actually tapping into the host's entropy pool which delegates to the host managing proper entropy pool (where deamons are normally present)
  • Heads taps into /dev/urandom for shred and tpm calls early on boot. It is ok if crng is ready, would be better is not /dev/urandom but that would block.
  • Kernel has its own basic entropy gen under crng. Read comments for crng and entropy collection routines at https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/random.c

Get homes messages:

  • We are better without HW RDRAND if crng is ready on boot
  • gpg in memory keygen is already injecting entropy whike using libgcrypt 1.10+ by default
  • removing --disable-asm is permitting libgcrypt to use what is available to mix what is available on the host without trusting completely the CPU HW rand

So next commits will

  • disable trusting CPU completely from coreboot command line to Heads payload, making the hw source availabile but not enforcing it
  • qemu board will keep trust cpu since it trusts virtio, hence the host's source of entropy as being "hw"

@JonathonHall-Purism
Copy link
Collaborator

Thanks for summing that up @tlaurion. For context, I did some quick checks on my 15v4 and it appeared that crng was already initialized before it was needed on that device from kernel sources, so there is no issue there. I suspect this is only an issue on qemu, but we need to confirm on other devices as well.

We observed as you noted that cryptsetup uses the kernel random number generator; we need this to be a good source of entropy. While our sources of entropy at this point are limited, I would prefer not to trust RDRAND if we do not have to. It appears to me from initial tests that we are getting enough entropy from existing sources outside of qemu, so if there are some devices where we aren't getting that entropy soon enough, maybe there is another solution.

For qemu I am totally fine with adding the necessary bits to get initial entropy from the host, including trust_cpu if needed.

cryptsetup [...] trusts totally entropy provided by RDRAND without mixing it in with anything else. To change behavior, one would have to call cryptsetup with --use-random [...]

Nitpick, --use-random does not affect cryptsetup's trust of kernel RNG, it trusts it either way. The difference is only that /dev/random will block before crng is ready, while /dev/urandom just returns low-entropy numbers immediately. It looks like cryptsetup in Heads is configured to use urandom by default (from cryptsetup --help).

@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from d4134dc to 94dc35e Compare October 2, 2023 19:58
@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 2, 2023

@JonathonHall-Purism forced push to only change qemu linux config. crng is ready within 5s and before entropy is expected to be ready and sued. No more error on qemu side.

libgrcypt now enforces asm code and platforms specific cpu extensions are used where available, see commit log (same output as above for libgcrypt).

Please review, this will be smaller steps and will extensively test this as base for forthcoming PRs.

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 3, 2023

Bad news here. TRUST CPU was enabled for a while which is why crng was not complaining on crng for a lot of platforms on which that change was reverted under f59a63a

@JonathonHall-Purism can you verify that builds for that commit (without trust on CPU) has a crng ready before tpm and shred calls?

on x230 without TRUST CPU:
signal-2023-10-03-140301

We can see TPM and shred calls happening on empty pool prior of crng being ready.

So I guess I will revert this for xx20/xx30 so that TRUST CPU is on and state it clearly on board configs?

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 3, 2023

Letting the build finish prior of pushing more commit.

The following needs to be added to fix mounting devpts over /dev/pts:

diff --git a/config/linux-c216.config b/config/linux-c216.config
index 7bccfba021a..662125a49a5 100644
--- a/config/linux-c216.config
+++ b/config/linux-c216.config
@@ -1375,7 +1375,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_LDISC_AUTOLOAD is not set
 
diff --git a/config/linux-librem_common-6.1.8.config b/config/linux-librem_common-6.1.8.config
index 59ffef787b4..b7e7c76130e 100644
--- a/config/linux-librem_common-6.1.8.config
+++ b/config/linux-librem_common-6.1.8.config
@@ -141,7 +141,6 @@ CONFIG_E1000E=m
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO_SERPORT is not set
-# CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
diff --git a/config/linux-librem_common.config b/config/linux-librem_common.config
index c7a0d2175b5..d718ce5370a 100644
--- a/config/linux-librem_common.config
+++ b/config/linux-librem_common.config
@@ -1385,7 +1385,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_LDISC_AUTOLOAD=y
 
diff --git a/config/linux-nitropad-x.config b/config/linux-nitropad-x.config
index 7f3fbbf3617..c82992c8dc0 100644
--- a/config/linux-nitropad-x.config
+++ b/config/linux-nitropad-x.config
@@ -1483,7 +1483,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_LDISC_AUTOLOAD=y
 
diff --git a/config/linux-t440p.config b/config/linux-t440p.config
index c8b0fbe9398..74ff2fe57b1 100644
--- a/config/linux-t440p.config
+++ b/config/linux-t440p.config
@@ -1405,7 +1405,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_LDISC_AUTOLOAD=y
 
diff --git a/config/linux-x230-flash.config b/config/linux-x230-flash.config
index dc64463ff13..f3d1fb0e863 100644
--- a/config/linux-x230-flash.config
+++ b/config/linux-x230-flash.config
@@ -1071,7 +1071,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_LDISC_AUTOLOAD is not set
 
diff --git a/config/linux-x230-legacy.config b/config/linux-x230-legacy.config
index f90e983d699..54b9cdc2886 100644
--- a/config/linux-x230-legacy.config
+++ b/config/linux-x230-legacy.config
@@ -1181,7 +1181,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_LDISC_AUTOLOAD is not set
 
diff --git a/config/linux-x230-maximized.config b/config/linux-x230-maximized.config
index cd46aad1e24..b932b05b5b8 100644
--- a/config/linux-x230-maximized.config
+++ b/config/linux-x230-maximized.config
@@ -1372,7 +1372,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_LDISC_AUTOLOAD is not set

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 3, 2023

Freezing this PR for the moment, continuing tests under https://github.com/tlaurion/heads/tree/stenghten_entropy_sources_with_jitter_and_TPM-withTrustCPU which trustcpu is enabled as in master because of 00e7156#diff-a890ddf36ae7dca110b70df101c97525a4d8265212ebed3f92562d47162af3a2R1472 but when disabled, sandy/ivy and probably other older architectures read entropy through an empty crng pool....

@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from a64ad39 to 0ad2b72 Compare October 4, 2023 13:54
@JonathonHall-Purism
Copy link
Collaborator

@tlaurion and I both researched this and discussed.

In practice, TRUST_CPU essentially only controls whether the warning about the pool not being fully initialized is printed. Linux uses RDRAND/RDSEED either way, the only difference is whether it credits any entropy. With TRUST_CPU=n it uses them but credits no entropy, the assumption being that a bad entropy source could not be worse than not using it at all.

Currently in Heads I feel that this warning has little value. It's currently caused by shred most of the time, and since we are operating on tmpfs, overwriting the data with any value is sufficient. Key generation occurs after plenty of I/O and user input and there appears to be sufficient entropy at that point regardless of TRUST_CPU.

There is room for debate and improvement, but I think the status quo is improved just by enabling TRUST_CPU to remove a warning that isn't useful in this context.

Some thoughts for future work (will open issues):

  • Re-examine our usage of shred - perhaps overwrite data a different way that doesn't use CRNG
  • Add additional sources of entropy (CPU jitter, etc.), which requires an RNG daemon
  • Question the assumption that a bad RDRAND/RDSEED isn't worse than not using it at all (if it is malicious instead of just bad)

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 4, 2023

Ok. Further testing shows a big difference in CNRG readiness on booy, depending of if the board is HOTP/TOTP only.
The reasoning is that early on boot, if HOTP is used, USB stack kernel modules are loaded early, same for USB keyboard, and then unseal-hotp is called and some related additional IO are being made (USB stack modules measured and loaded) which are taken into consideration for entropy pool.

Testings shows that even on TOTP boards (non-HOTP), doing factory-reset or manual gpg operations on command line will have crng ready prior of important operations.

It is also to be noted that errors given by shred call is benign, since those calls are wiping files in ramfs which blocks would be rewritten with not so random bytes, still overwiting secret intended to be wiped.

The only warning i'm still worry-ish about is tpm calls when crng is not ready (staying in recovery shell without any IO or anything USB related):
signal-2023-10-04-103922

When going from menus to recovery shell and then doing factory-reset and grepping for random after ctrl-c after the output of provisioned secrets:
signal-2023-10-04-105445

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

@JonathonHall-Purism that was harder then I thought.

Some notes:

  • config/linux-librem_common-6.1.8.config is still in defconfig, which hides that "CONFIG_RANDOM_TRUST_CPU=y" is set. You can check for yourself with make BOARD=librem_14 linux.modify_and_save_oldconfig_in_place. Note that a lot of modules are compiled even if unused, that CPU support is generic and does not turn on CPU optimizations as per other boards that were tuned in oldconfig format. I would suggest to compare and put in oldconfig asap. I also added CONFIG_UNIX98_PTYS=y to get rid of warning on pts early on boot (was also missing under qemu linux config).

As of now, this PR is a bit messy, adds cttyhack to call BOOTSCRIPT otherwise, dual console setups (qemu) was reporting to not have proper tty when tty is called. Thoughs on that welcome.

Last changes add preoper DEBUG/TRACING output under dmesg and in console. Reason why those were intertwined by default under qemu is because coreboot config's kernel command line was passing "debug". To have this enabled to have Heads DEBUG/TRACE/die/warn messages intertwined under console output, dmesg -n 8 is needed. But detection of if CONSIF_DEBUT_OUTPUT is setuped either on board config or through config.user on-demand config requires changes under init and proper different output under init.

All of this to permit to detect tpm call on qemu setup, which is the changes coming next if VIRTIO HW source is not enabled in kernel and have all rand calls from unready pool.

To accomplish the same on real hw, the board config needs to enable DEBUG_CONSOLE_OUTPUT in board config otherwise early debug messages are not intertwined since the checks for DEBUG_CONSOLE_OUTPUT are not positive until combine_configs happens.

All unneeded commits will be squashed, of course....

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

This is output of dmesg from dabdc58 for non-HOTP

dmesg_no_hw_trust.txt
@JonathonHall-Purism so there it is the tpm unseal operation that consumes the 20 bytes:

[    1.925706] TRACE: Under /bin/tpmr:tpm1_unseal
[    1.981054] random: tpm: uninitialized urandom read (20 bytes read)
[    2.425558] DEBUG: Running at_exit handlers

@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from dabdc58 to 7a08474 Compare October 6, 2023 16:52
@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

@JonathonHall-Purism This is the output of 7a08474 for HOTP without HW entropy nor CPU trust

dmesg_hotp_no_hw_trust.txt

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

This is the output of f50c296 with hw entropy, no CPU trust resealing TOTP/HOTP
dmesg_hotp-with_hw-no_trust.txt

@JonathonHall-Purism The sealing still happens without pool being ready:

[   16.902833] TRACE: Under /bin/seal-hotpkey
[   16.907165] DEBUG: Sealing HOTP secret reuses TOTP sealed secret...
[   16.910764] TRACE: Under /bin/tpmr
[   16.913220] TRACE: Under /bin/tpmr:tpm1_unseal
[   17.449469] DEBUG: Running at_exit handlers
[   17.450584] TRACE: Under /bin/tpmr:cleanup_shred
[   17.452184] TRACE: Under /bin/seal-hotpkey:mount_boot
[   17.453725] TRACE: Under /etc/ash_functions:enable_usb
[   19.692988] _warn_unseeded_randomness: 138 callbacks suppressed
[   19.692989] random: get_random_u32 called from 0xffffffff8120b902 with crng_init=1
[   19.693341] random: get_random_u64 called from 0xffffffff8102992e with crng_init=1
[   19.693342] random: get_random_u64 called from 0xffffffff811067cf with crng_init=1
[   19.696675] DEBUG: Signature key was created at Mon Dec 30 23:34:16 UTC 2019
[   19.701377] DEBUG: Admin PIN retry counter is 3
[   23.682556] random: crng init done

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

@JonathonHall-Purism with adb5808 we add CPU trust to intel HW entropy source which gives this at totp+hotp sealing
dmesg_hotp-with_hw-with_trust.txt

Of course this changes the output since really early simply because:
[ 0.100727] random: crng done (trusting CPU's manufacturer)

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

@JonathonHall-Purism 9cdf085 adds libgcrypt benchmark app which is ~50k uncompressed but not really useful.

I have not found an easy way of testing different libcrypt supported cpu optimizations as of now, which might be subject to further issues and PR. Let's remember that ofiginal issue is at #1476. From above comments, i'm not convinced still now of state of pool when tpm does stuff, but removing warning is best we can do as of now.

@JonathonHall-Purism Can you review changes of librem configs?

@tlaurion
Copy link
Collaborator Author

tlaurion commented Oct 6, 2023

Basically, I think I will stage this pr and only keep in here

  • Keep linux config changes
  • Keep init changes
  • Keep ash_functions change

Opinion on cttyhack needed in init, can also be separated from here.


And move the rest to other PRs.
@JonathonHall-Purism good with you?

  • gnupg toolstack version bump was required to correct bugs under yubikey, but dirmngr is more tightly bound and gpg doesn't work as expected as of now.
  • board config changes and coreboot files changes are required to remove igfx related stuff that don't matter anymore (where dgpu boards still depend on it and most are UNTESTED now) while unifying log level.

@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from 894c7da to 53ade6b Compare October 10, 2023 15:33
@tlaurion
Copy link
Collaborator Author

Squashing

…CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set, CONFIG_RANDOM_TRUST_CPU=y, CONFIG_PROC_SYSCTL is not set
As on master otherwise with --disable-asm:

    config.status: executing gcrypt-conf commands

            Libgcrypt v1.10.1 has been configured as follows:

            Platform:                  GNU/Linux (x86_64-pc-linux-musl)
            Hardware detection module: none
            Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish
                                       serpent rfc2268 seed camellia idea salsa20
                                       gost28147 chacha20 sm4
            Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
                                       sha256 sha512 sha3 tiger whirlpool stribog
                                       blake2 sm3
            Enabled kdf algorithms:    s2k pkdf2 scrypt
            Enabled pubkey algorithms: dsa elgamal rsa ecc
            Random number generator:   default
            Try using jitter entropy:  yes
            Using linux capabilities:  no
            FIPS module version:
            Try using Padlock crypto:  n/a
            Try using AES-NI crypto:   n/a
            Try using Intel SHAEXT:    n/a
            Try using Intel PCLMUL:    n/a
            Try using Intel SSE4.1:    n/a
            Try using DRNG (RDRAND):   n/a
            Try using Intel AVX:       n/a
            Try using Intel AVX2:      n/a
            Try using ARM NEON:        n/a
            Try using ARMv8 crypto:    n/a
            Try using PPC crypto:      n/a

By disabling --disable-asm in libgcrypt 1.10.1:

    config.status: executing gcrypt-conf commands

            Libgcrypt v1.10.1 has been configured as follows:

            Platform:                  GNU/Linux (x86_64-pc-linux-musl)
            Hardware detection module: libgcrypt_la-hwf-x86
            Enabled cipher algorithms: arcfour blowfish cast5 des aes twofish
                                       serpent rfc2268 seed camellia idea salsa20
                                       gost28147 chacha20 sm4
            Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
                                       sha256 sha512 sha3 tiger whirlpool stribog
                                       blake2 sm3
            Enabled kdf algorithms:    s2k pkdf2 scrypt
            Enabled pubkey algorithms: dsa elgamal rsa ecc
            Random number generator:   default
            Enabled digest algorithms: crc gostr3411-94 md4 md5 rmd160 sha1
                                       sha256 sha512 sha3 tiger whirlpool stribog
                                       blake2 sm3
            Enabled kdf algorithms:    s2k pkdf2 scrypt
            Enabled pubkey algorithms: dsa elgamal rsa ecc
            Random number generator:   default
            Try using jitter entropy:  yes
            Using linux capabilities:  no
            FIPS module version:
            Try using Padlock crypto:  yes
            Try using AES-NI crypto:   yes
            Try using Intel SHAEXT:    yes
            Try using Intel PCLMUL:    yes
            Try using Intel SSE4.1:    yes
            Try using DRNG (RDRAND):   yes
            Try using Intel AVX:       yes
            Try using Intel AVX2:      yes
            Try using ARM NEON:        n/a
            Try using ARMv8 crypto:    n/a
            Try using PPC crypto:      n/a

To support PPC crypto, it seems we will need yasm.
To support linux capabilities, libcap would be required as well later on. :/ another point for rng-tools (which also depends on libcap-ng)
Enabling DEBUG/TRACE options from board config vs from configuration menu is different.

When enabled in board config, /etc/config is from ROM, and sourced early and make TRACE/DEBUG calls appear early.
If added through configuration menu, those are /etc/config.user overrides extracted from CBFS and then sourced after combine_configs call

If for whatever reason early DEBUG is needed on a platform, enabling in board config is needed.
For runtime debugging, enabling Debug output from configuration menu is enough
…d terminal. DEBUG/TRACE now output on /dev/kmsg and console.
@tlaurion tlaurion force-pushed the stenghten_entropy_sources_with_jitter_and_TPM branch from 53ade6b to 9addb3b Compare October 10, 2023 16:31
Comment on lines 6 to 23
die() {
echo >&2 " !!! ERROR: $* !!!";
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
echo " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg > /dev/null;
else
echo >&2 "!!! ERROR: $* !!!";
fi
sleep 2;
exit 1;
}

warn() {
echo >&2 " *** WARNING: $* ***";
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
echo " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg > /dev/null;
else
echo >&2 " *** WARNING: $* ***";
fi
sleep 1;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense for die/warn to disappear from stderr when enabling CONFIG_DEBUG_OUTPUT. I wouldn't expect CONFIG_DEBUG_OUTPUT=y to produce less output in any context.

I think these are pretty reasonable to keep on stderr; I don't think they're too noisy. If they occur in the field I think these are better than nothing (and rarely a false warning). Based on that, I'd say continue printing to stderr regardless of CONFIG_DEBUG_OUTPUT, but I'm willing to consider any alternative 😁

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, @tlaurion clarified to me that this is due to the interaction with enabling kernel messages to console (dmesg -n 8). If we do both, then these messages show up on the console twice, which is pointless.

@@ -14,7 +14,6 @@ libgcrypt_configure := \
--prefix "/" \
--disable-static \
--with-gpg-error-prefix="$(INSTALL)" \
--disable-asm \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summarizing a discussion via DM - I'm good with this change.

And odd thing sticking out to me was that libgcrypt has code to use RDRAND directly for up to 25% of its entropy, which would have been prevented in the past with --disable-asm. That doesn't make much sense with the kernel already including RDSEED in its CRNG, and it doesn't even know about things like the broken Ryzen microcode, etc. But this code is no longer active by default, that code is for USE_RNDOLDLINUX, default is now USE_RNDGETENTROPY.

So no issues here, let's keep this change.

@JonathonHall-Purism
Copy link
Collaborator

@tlaurion Thanks for clarifying both of those last discussions with me, let's merge 👍 🚢

@tlaurion tlaurion merged commit bd2a8eb into linuxboot:master Oct 10, 2023
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CRNG not ready and entropy used early at boot
2 participants