diff mbox series

[7/9] meson: make the CSPRNG backend configurable

Message ID 20250113-b4-pks-meson-additions-v1-7-97f6a93f691d@pks.im (mailing list archive)
State Superseded
Headers show
Series meson: a couple of additions | expand

Commit Message

Patrick Steinhardt Jan. 13, 2025, 8:33 a.m. UTC
The CSPRNG backend is not configurable in Meson and isn't quite
discoverable, either. Make it configurable and add the actual backend
used to the summary.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 meson.build       | 26 +++++++++++++++++++-------
 meson_options.txt |  2 ++
 2 files changed, 21 insertions(+), 7 deletions(-)

Comments

Patrick Steinhardt Jan. 13, 2025, 9:25 a.m. UTC | #1
On Mon, Jan 13, 2025 at 09:33:40AM +0100, Patrick Steinhardt wrote:
> diff --git a/meson.build b/meson.build
> index 5e1373f6a52a91beb527d00d8fd5c55d377c718b..cb352ce6fd50616e3281a776104692c5b2bfa5b2 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1325,6 +1325,7 @@ if not meson.is_cross_build() and fs.exists('/dev/tty')
> @@ -1421,18 +1422,28 @@ else
>    error('Unhandled SHA256 backend ' + sha256_backend)
>  endif
>  
> -if compiler.has_header_symbol('stdlib.h', 'arc4random_buf')
> +if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random')
>    libgit_c_args += '-DHAVE_ARC4RANDOM'
> -elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf')
> +  csprng_backend = 'arc4random'
> +elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd')
>    libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
> -elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>')
> +  csprng_backend = 'arc4random_bsd'
> +elif csprng_backend in ['auto', 'getrandom'] and compiler.has_function('getrandom', prefix: '#include <sys/random.h>', required: csprng_backend == 'getrandom')
>    libgit_c_args += '-DHAVE_GETRANDOM'
> -elif compiler.has_function('getentropy', prefix: '#include <unistd.h>')
> +  csprng_backend = 'getrandom'
> +elif csprng_backend in ['auto', 'getentropy'] and compiler.has_function('getentropy', prefix: '#include <unistd.h>', required: csprng_backend == 'getentropy')
>    libgit_c_args += '-DHAVE_GETENTROPY'
> -elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>')
> +  csprng_backend = 'getentropy'
> +elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>', required: csprng_backend == 'rtlgenrandom')
>    libgit_c_args += '-DHAVE_RTLGENRANDOM'
> -elif openssl.found()
> +  csprng_backend = 'rtlgenrandom'
> +elif csprng_backend in ['auto', 'openssl'] and openssl.found()
>    libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
> +  csprng_backend = 'openssl'
> +elif csprng_backend in ['auto', 'urandom']
> +  csprng_backend = 'urandom'
> +else
> +  error('Unsupported CSPRNG backend: ' + csprng_backend)
>  endif
>  
>  if get_option('runtime_prefix')

I just noticed that this generates warnings because we use features not
yet in Meson v0.61.0, which is our minimum required version. I'll convert
these to instead use `compiler.has_header_symbol()` consistently, which
is nicer to read anyway, and will add another patch on top that makes us
use `--fatal-meson-warnings` in CI so that warnings will cause us to
abort the build.

Patrick
Junio C Hamano Jan. 13, 2025, 5:59 p.m. UTC | #2
Patrick Steinhardt <ps@pks.im> writes:

> The CSPRNG backend is not configurable in Meson and isn't quite
> discoverable, either. Make it configurable and add the actual backend
> used to the summary.

Makes sense.  Thanks.

> +if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random')
>    libgit_c_args += '-DHAVE_ARC4RANDOM'
> -elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf')
> +  csprng_backend = 'arc4random'
> +elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd')
>    libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
> -elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>')
> +  csprng_backend = 'arc4random_bsd'
> +elif csprng_backend in ['auto', 'getrandom'] and compiler.has_function('getrandom', prefix: '#include <sys/random.h>', required: csprng_backend == 'getrandom')
>    libgit_c_args += '-DHAVE_GETRANDOM'
> -elif compiler.has_function('getentropy', prefix: '#include <unistd.h>')
> +  csprng_backend = 'getrandom'
> +elif csprng_backend in ['auto', 'getentropy'] and compiler.has_function('getentropy', prefix: '#include <unistd.h>', required: csprng_backend == 'getentropy')
>    libgit_c_args += '-DHAVE_GETENTROPY'
> -elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>')
> +  csprng_backend = 'getentropy'
> +elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>', required: csprng_backend == 'rtlgenrandom')
>    libgit_c_args += '-DHAVE_RTLGENRANDOM'
> -elif openssl.found()
> +  csprng_backend = 'rtlgenrandom'
> +elif csprng_backend in ['auto', 'openssl'] and openssl.found()
>    libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
> +  csprng_backend = 'openssl'
> +elif csprng_backend in ['auto', 'urandom']
> +  csprng_backend = 'urandom'
> +else
> +  error('Unsupported CSPRNG backend: ' + csprng_backend)
>  endif

IIRC, the precedence order of CPP macros related to csprng backends
were chosen to reflect our preference for more secure and faster
ones over the ones that are less so.  Does the above list recreate
the same order, and do we want to somehow make sure future
developers would not break that order without knowing our intention,
saying "when all things are equal, we should sort in alphabetical
order" or something?

Thanks.
Patrick Steinhardt Jan. 14, 2025, 9:13 a.m. UTC | #3
On Mon, Jan 13, 2025 at 09:59:53AM -0800, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
> > +if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random')
> >    libgit_c_args += '-DHAVE_ARC4RANDOM'
> > -elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf')
> > +  csprng_backend = 'arc4random'
> > +elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd')
> >    libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
> > -elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>')
> > +  csprng_backend = 'arc4random_bsd'
> > +elif csprng_backend in ['auto', 'getrandom'] and compiler.has_function('getrandom', prefix: '#include <sys/random.h>', required: csprng_backend == 'getrandom')
> >    libgit_c_args += '-DHAVE_GETRANDOM'
> > -elif compiler.has_function('getentropy', prefix: '#include <unistd.h>')
> > +  csprng_backend = 'getrandom'
> > +elif csprng_backend in ['auto', 'getentropy'] and compiler.has_function('getentropy', prefix: '#include <unistd.h>', required: csprng_backend == 'getentropy')
> >    libgit_c_args += '-DHAVE_GETENTROPY'
> > -elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>')
> > +  csprng_backend = 'getentropy'
> > +elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>', required: csprng_backend == 'rtlgenrandom')
> >    libgit_c_args += '-DHAVE_RTLGENRANDOM'
> > -elif openssl.found()
> > +  csprng_backend = 'rtlgenrandom'
> > +elif csprng_backend in ['auto', 'openssl'] and openssl.found()
> >    libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
> > +  csprng_backend = 'openssl'
> > +elif csprng_backend in ['auto', 'urandom']
> > +  csprng_backend = 'urandom'
> > +else
> > +  error('Unsupported CSPRNG backend: ' + csprng_backend)
> >  endif
> 
> IIRC, the precedence order of CPP macros related to csprng backends
> were chosen to reflect our preference for more secure and faster
> ones over the ones that are less so.  Does the above list recreate
> the same order, and do we want to somehow make sure future
> developers would not break that order without knowing our intention,
> saying "when all things are equal, we should sort in alphabetical
> order" or something?

Yup, it's the exact same order as we have in our Makefile and as in
"wrapper.c". And yes, good idea, I'll add a comment.

Patrick
Junio C Hamano Jan. 14, 2025, 7:13 p.m. UTC | #4
Patrick Steinhardt <ps@pks.im> writes:

> Yup, it's the exact same order as we have in our Makefile and as in
> "wrapper.c". And yes, good idea, I'll add a comment.

Yeah, a comment is a good starting point.  We should say something
along the lines of "if you are tempted to change this, change the
other one to match" or something.

If we can keep a single source of truth and derive these two places
that should stay in sync, that would be ideal, but that can be left
outside the topic for now, I think.

Thanks.
diff mbox series

Patch

diff --git a/meson.build b/meson.build
index 5e1373f6a52a91beb527d00d8fd5c55d377c718b..cb352ce6fd50616e3281a776104692c5b2bfa5b2 100644
--- a/meson.build
+++ b/meson.build
@@ -1325,6 +1325,7 @@  if not meson.is_cross_build() and fs.exists('/dev/tty')
   libgit_c_args += '-DHAVE_DEV_TTY'
 endif
 
+csprng_backend = get_option('csprng_backend')
 https_backend = get_option('https_backend')
 sha1_backend = get_option('sha1_backend')
 sha1_unsafe_backend = get_option('sha1_unsafe_backend')
@@ -1336,7 +1337,7 @@  if https_backend == 'auto' and security_framework.found()
   https_backend = 'CommonCrypto'
 endif
 
-openssl_required = 'openssl' in [https_backend, sha1_backend, sha1_unsafe_backend, sha256_backend]
+openssl_required = 'openssl' in [csprng_backend, https_backend, sha1_backend, sha1_unsafe_backend, sha256_backend]
 openssl = dependency('openssl', required: openssl_required, default_options: ['default_library=static'])
 if https_backend == 'auto' and openssl.found()
   https_backend = 'openssl'
@@ -1421,18 +1422,28 @@  else
   error('Unhandled SHA256 backend ' + sha256_backend)
 endif
 
-if compiler.has_header_symbol('stdlib.h', 'arc4random_buf')
+if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random')
   libgit_c_args += '-DHAVE_ARC4RANDOM'
-elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf')
+  csprng_backend = 'arc4random'
+elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd')
   libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
-elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>')
+  csprng_backend = 'arc4random_bsd'
+elif csprng_backend in ['auto', 'getrandom'] and compiler.has_function('getrandom', prefix: '#include <sys/random.h>', required: csprng_backend == 'getrandom')
   libgit_c_args += '-DHAVE_GETRANDOM'
-elif compiler.has_function('getentropy', prefix: '#include <unistd.h>')
+  csprng_backend = 'getrandom'
+elif csprng_backend in ['auto', 'getentropy'] and compiler.has_function('getentropy', prefix: '#include <unistd.h>', required: csprng_backend == 'getentropy')
   libgit_c_args += '-DHAVE_GETENTROPY'
-elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>')
+  csprng_backend = 'getentropy'
+elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>', required: csprng_backend == 'rtlgenrandom')
   libgit_c_args += '-DHAVE_RTLGENRANDOM'
-elif openssl.found()
+  csprng_backend = 'rtlgenrandom'
+elif csprng_backend in ['auto', 'openssl'] and openssl.found()
   libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
+  csprng_backend = 'openssl'
+elif csprng_backend in ['auto', 'urandom']
+  csprng_backend = 'urandom'
+else
+  error('Unsupported CSPRNG backend: ' + csprng_backend)
 endif
 
 if get_option('runtime_prefix')
@@ -1969,6 +1980,7 @@  summary({
 }, section: 'Auto-detected features')
 
 summary({
+  'csprng': csprng_backend,
   'https': https_backend,
   'sha1': sha1_backend,
   'sha1_unsafe': sha1_unsafe_backend,
diff --git a/meson_options.txt b/meson_options.txt
index 34ba679cf931b67a794a9bb7e765bfb22106381e..5429022f30621105cd6974e4260cca60e5f24324 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -47,6 +47,8 @@  option('regex', type: 'feature', value: 'auto',
   description: 'Use the system-provided regex library instead of the bundled one.')
 
 # Backends.
+option('csprng_backend', type: 'combo', value: 'auto', choices: ['auto', 'arc4random', 'arc4random_bsd', 'getrandom', 'getentropy', 'rtlgenrandom', 'openssl', 'urandom'],
+  description: 'The backend to use for generating cryptographically-secure pseudo-random numbers.')
 option('https_backend', type: 'combo', value: 'auto', choices: ['auto', 'openssl', 'CommonCrypto', 'none'],
   description: 'The HTTPS backend to use when connecting to remotes.')
 option('sha1_backend', type: 'combo', choices: ['openssl', 'block', 'sha1dc', 'CommonCrypto'], value: 'sha1dc',