FIPS & pkg-static

I am trying to get a FreeBSD 14 system working with openssl in FIPS mode. Most of the applications I've used work fine, but I'm having a problem with pkg and was wondering if anyone else has run into this. I have a system that I installed from 14.0-RC1, and have upgraded to 14.0p5-RELEASE using freebsd-upgrade. I've switched the files in /etc/pkg/ to use https instead of http so that pkg is actually exercising OpenSSL. pkg works fine, but pkg-static (with --debug) produces "Insufficient randomness" messages and exits with an error. I see this with both the FreeBSD-shipped fips provider, and with a properly built 3.0.9 provider. I ran openssl fipsinstall -module /usr/lib/ossl-modules/fips.so -out /etc/ssl/fipsmodule.cnf with each provider before using it, and tested it with pkg-static fetch pkg.

Can anyone confirm they do or don't see this behaviour in FreeBSD 14? Thanks.

Here are the relevant parts of my /etc/ssl/openssl.cnf
INI:
openssl_conf = openssl_init

.include /etc/ssl/fipsmodule.cnf

[openssl_init]
providers = provider_sect
alg_section = algorithm_sect

[provider_sect]
#default = default_sect
fips = fips_sect
base = base_sect

[algorithm_sect]
default_properties = fips=yes

[base_sect]
activate = 1

[default_sect]
#activate = 1
 
I've switched the files in /etc/pkg/ to use https instead of http
Don't edit those files, your changes might get undone after an update. Create a /usr/local/etc/pkg/repos/FreeBSD.conf and only set the URL (don't have to copy any of the other values.

Code:
FreeBSD: { 
  url: https://....
}

I see this with both the FreeBSD-shipped fips provider, and with a properly built 3.0.9 provider.
pkg-static(8) is a statically compiled version of pkg(8), which means the OpenSSL library is linked in the executable, it is not dynamically loaded.
 
Thanks, I changed /etc/pkg/FreeBSD.conf just for testing pkg(8), upgrades aren't a concern.

I understand pkg-static(8) uses libcrypto.a instead of libcrypto.so. fips.so is not pulled in at link time, libcrypto(.so/.a) loads it at run time based on the contents of /etc/ssl/openssl.cnf.

I think pkg-static(8) is unique among the applications I've been using in being statically linked, I should put out a query to an OpenSSL mailing list about that.
 
The source code is compiled once, and the resulting object files are used for both pkg and pkg-static, so theoretically the OpenSSL initialization should be the same.
 
I understand pkg-static(8) uses libcrypto.a instead of libcrypto.so. fips.so is not pulled in at link time, libcrypto(.so/.a) loads it at run time
Statically linked executables cannot use dlopen(3).

Code:
$ cat dltest.c
#include <stdio.h>
#include <dlfcn.h>

int main()
{
    void *lib = dlopen("/lib/libz.so.6", RTLD_LAZY);
    puts(lib ? "success" : "error");
}

$ cc -odltest -static dltest.c
$ ./dltest
error
$ cc -odltest dltest.c
$ ./dltest
success
$
 
This is not documented in the dlopen(3) man page. Is this intentional?
It's inevitable. These functions instruct the dynamic linker (aka program interpreter) to do something, like, load/map a new module. For this to work, the dynamic linker must be present in the process.

(edit: In the name section, it reads "programmatic interface to the dynamic linker", which certainly implies there must be a dynamic linker present in the address space. But sure, it could be explicitly explained ...)

Does this mean all the static libraries in /usr/lib that use dlopen are broken?
They aren't. Static libraries are just archives of object code. The only thing that matters is whether the binary (that could certainly pull in static libraries as well) is dynamically linked, IOW, requests a program interpreter:
Code:
$ readelf -e test | grep interpreter
      [Requesting program interpreter: /libexec/ld-elf.so.1]
 
OK, so the `.a` libs aren't themselves broken, but they can't be used in a statically linked application, which I think most engineers would find surprising for a `.a` archive. So any application that supports loadable modules must be dynamically linked. E.g. apache, php, rsyslog, python, collectd, postgresql, etc. etc. (Yes, that's normal, but the embedded world is often not normal.)

Is there any way to force a statically linked program to load ld-elf.so.1? Or perhaps to link dynamically, but only with static libraries? (effectively equivalent to replacing all the "-lblah"s with "/usr/lib/libblah.a") Currently digging through the clang ld man page....
 
Is there any way to force a statically linked program to load ld-elf.so.1?
Well, don't link it statically.
Or perhaps to link dynamically, but only with static libraries?
Kind of. I have to correct myself, requesting a program interpreter isn't enough, in my tests it seems libc must be linked dynamically. Maybe the program interpreter otherwise doesn't stay in the address space because it has nothing to do (just guessing here) ....

So any application that supports loadable modules must be dynamically linked. E.g. apache, php, rsyslog, python, collectd, postgresql, etc. etc. (Yes, that's normal, but the embedded world is often not normal.)
Plugins are shared libraries, so ... static linking and plugins are a contradiction in itself. If you want to link statically, this means you ALSO link these parts statically. At least that's the typical approach, I've used this with Qt when building statically linked Windows binaries.
 
Lol, not linking pkg-static(8) statically isn't really an option. And trying to load fips.so statically would invalidate the FIPS certification. I played around with -Wl,-Bstatic and -Wl,-Bdynamic to see if I could force -lblah options to be static, but ldd still showed libc as a dynamic library. I think I'll bring this up with the OpenSSSL folks. Meantime, I'll see if I can disable FIPS just while running pkg-static.

Thanks, both of you, for your help.
 
Lol, not linking pkg-static(8) statically isn't really an option.
And the reason for that is that it should "just work", no matter how broken the system is. Which conflicts with needing to load some shared library at runtime, that's conceptually the same as having the program interpreter do it on startup....

I think I'll bring this up with the OpenSSSL folks.
I wouldn't expect them being able to tell you anything else, you can't use that with a fully statically linked executable. :oops:
 
Since the packages downloaded from the site are signed (and verified against) with the pkg key, do you need to use https? I have a feeling this is why it is disabled by default (less load on the server; payloads already signed.)
 
Back
Top