gcry_create_nonce after a snapshot or checkpoint restore
Yuxiang Ji
kurath0307 at icloud.com
Tue Oct 27 02:37:05 CET 2026
Hello,
Our reply of 21 October to your three questions does not appear in the
list archive, so here it is in short, with one more case.
1. Yes: the cases are those in which getpid() returns the same value
after the duplication. Two are restores: a virtual machine restored
twice from one snapshot (QEMU and Firecracker), and a process restored
twice from one CRIU checkpoint. The third is a fork, below. After an
ordinary fork(), where the pid changes, the nonce generator reseeds its
private part as designed.
2. The library measured is Fedora 44's libgcrypt-1.12.2-1.fc44 (x86_64),
built from libgcrypt-1.12.2.tar.bz2 (sha256
7ce33c2492221a0436f96a8500215e9f3e3dcb5fd26a757cd415e7a843babd5e) with
two Fedora patches, neither of which touches random/. The commit we
named, 1ff517245292, was the master head of the github.com/gpg/libgcrypt
mirror on 2026-10-17; _gcry_create_nonce is the same there and in 1.12.2
(random/random.c 485 to 570).
3. The measurements ran outside FIPS mode: /proc/sys/crypto/fips_enabled
is 0, /etc/gcrypt holds no fips_enabled file, gcry_fips_mode_active()
returns 0 with the measured library, and the guests boot without fips=1.
The fork: a process that is pid 1 of its pid namespace calls
unshare(CLONE_NEWPID) and then fork(). The child is pid 1 of the new
namespace, so getpid() returns 1 in both parent and child, and the
private part of the nonce buffer is not re-randomised (random/random.c
545 to 553). Two children made this way, 32 blocks each from
gcry_create_nonce, compared at equal sequence numbers, are 32 of 32
identical. From an ordinary parent, where the child's pid changes, they
are 0 of 32. gcry_randomize at GCRY_STRONG_RANDOM is distinct in both.
The program below shows the same in a parent and its child: run as
`unshare -Urpf ./repro-gcrypt`, both print the same nonce after the
fork; run without `unshare`, the nonces differ. It needs no root.
If the same-pid case is out of scope, would a sentence in the manual's
description of the nonce generator be welcome? For example: "The nonce
generator detects a fork by a change of the process ID. A child that
keeps its parent's process ID, as after unshare(CLONE_NEWPID) and fork()
in a process that is pid 1 of its namespace, and two copies of a process
or virtual machine restored from one snapshot continue from the same
nonce state." We are glad to send it as a patch.
The repeated blocks are the generator's own output; we have not looked
at anything downstream.
Best regards,
Yuxiang Ji
On 10/21/26 10:00 AM, NIIBE Yutaka wrote:
> Hello,
>
> Thank you for your report. Firstly, let us confirm the source code we
> look.
>
> Yuxiang Ji wrote:
>> We measure how userspace random generators behave when a process or a
>> machine is duplicated, and would like to know where libgcrypt places one
>> case before we write it up.
> Please clarify the term "duplicated", do you mean a situation where
> getpid returns same value? (If so, I'm afraid it's out of scope.)
>
>> libgcrypt 1.12.2 as shipped by Fedora 44, source read at 1ff517245292;
>> Linux 7.2.11, glibc 2.43; the harness and every log are available.
> We don't have any git commit of 1ff517245292 in our repo. So, I think
> that it refers one of Fedora versions? Please tell us the specific
> source code.
>
> And IIUC, RedHat has a practice to use/enforce FIPS mode for a system.
> If it is the case, in _gcry_create_nonce, it goes through the different
> path in the function.
>
> Please try with non-FIPS mode to see how it goes.
More information about the Gcrypt-devel
mailing list