Edit the wireless regdb regulatory.db
Category: Gentoo Tags: wireless regulatory db, kernel
Howto adjust your wireless regdb a.k.a regulatory.db used by linux kernel.
In a former blog post I described how to edit the regulatory.bin used by crda.
Since then a few things have changed. Most important recent linux kernels load the regulatory db themself.
The construct of udev rule and crda has become obsolete.
But for the kernel to load the regulatory db it has, by default, to be signed with a certificate included in the kernel.
You can configure your kernel in expert mode to accept a unsigned regulatory db.
Also wireless-regdb tools now use python3.
So the tasks are:
- sign the db with our private key
- generate a certificate based on our private key
- supply the kernel with our certificate
Sign the db with our private key
The regulatory db is installed via net-wireless/wireless-regdb ebuild. Normally db files and everything else is just copied.
We hook into the emerge process to regenerate the db and sign it with our private key.
Of course first you should extract net-wireless/wireless-regdb adjust db.txt to your needs and create a patch, which is stored in etc/portage/patches/net-wireless/wireless-regdb/.
To hook into the emerge process we supply the script etc/portage/env/net-wireless/wireless-regdb. It will be sourced by emerge and callback functions get executed. Look into the older post for more details.
#!/usr/bin/env bash
export REGDB_PRIVKEY="rapna.key.priv.pem"
export REGDB_PUBKEY="rapna.key.pub.pem"
export REGDB_PUBCERT="rapna.x509.pem"
export REGDB_AUTHOR="rapna"
Almost the same as in the old version, but lets get to it.
Global variables are set with export. I had issues with them not defined so I do it this way ... maybe it is not necessary.
post_src_prepare() {
if [ -f "/etc/wireless-regdb/$REGDB_PRIVKEY" ]; then
einfo "Found private distro key"
cp "/etc/wireless-regdb/$REGDB_PRIVKEY" .
if [ -f "/etc/wireless-regdb/certs/$REGDB_PUBCERT" ]; then
einfo "Found distro certificate"
cp "/etc/wireless-regdb/certs/$REGDB_PUBCERT" .
fi
fi
}
post_src_prepare
is executed after sources are extracted and patches are applied.
If there is already a private key and/or a certificate in the host system we copy it into the build directory.
post_src_compile() {
if [ -f $REGDB_PRIVKEY ]; then
einfo "Using private host key for signing"
else
einfo "Generate private host key for signing"
make $REGDB_PRIVKEY
fi
if [ -f $REGDB_PUBCERT ]; then
einfo "Using distro certificate for signing"
else
einfo "Generate distro certficiate host key for signing"
openssl req -new -key "$REGDB_PRIVKEY" -days 36500 -utf8 -nodes -batch \
-x509 -outform PEM -out "$REGDB_PUBCERT" \
-config <(cat <<-EOF
[ req ]
distinguished_name = req_distinguished_name
string_mask = utf8only
prompt = no
[ req_distinguished_name ]
commonName = $REGDB_AUTHOR
EOF
)
fi
make sha1sum.txt
make regulatory.bin
make regulatory.db
make regulatory.db.p7s
}
post_src_compile
is executed after regular compiling, which doesn't happen in this ebuild.
If there is a private key use it otherwise create it. Same goes for the certificate.
The generation of the certificate is a bit more complex. It is vital to generate a pem encoded x509 certificate based on the private key.
Finally use the make file and generate the checksum, the obsolete regulatory.bin, regulatory.db for the kernel and regulatory.db.p7s,
the signature of regulatory.db.
In opposite to the old post there is no need to patch the tools as python3 is supported.
post_src_install() {
if [ -f $REGDB_PUBKEY ]; then
einfo "Install public key for signed regulatory.bin"
insinto /etc/wireless-regdb/pubkeys
doins $REGDB_PUBKEY
fi
if [ -f $REGDB_PRIVKEY ]; then
einfo "Install private distro key"
insinto "/etc/wireless-regdb"
doins $REGDB_PRIVKEY
fi
if [ -f $REGDB_PUBCERT ]; then
einfo "Install distro certificate"
insinto "/etc/wireless-regdb/certs"
doins $REGDB_PUBCERT
fi
}
Finally in post_src_install
install the generated public key, the private key and the certificate. The public key is obsolete.
regulatory.db and regulatory.db.p7s have been installed in lib/firmware, that's where the kernel will look for them.
So far so good
- adjusted regulatory.db ... check
- signed with private key ... check
- put everything in place ... check
Download wireless-regdb script
The Kernel
The kernel sources ship with certificates and when the kernel is compiled they are statically included.
To include our own certificate, we have to hook into the emerge process.
As I use sys-kernel/gentoo-sources, I have to supply etc/portage/env/sys-kernel/gentoo-sources.
I already have the file by that name, cause I compress the kernel sources as squashfs as described here.
Anyway I will discuss only what is needed for the certificate.
#!/usr/bin/env bash
# /etc/portage/env/sys-kernel/gentoo-sources
pre_src_install() {
for cert in "${EROOT}"/etc/wireless-regdb/certs/*.x509.pem ; do
if [ -e "$cert" ]; then
openssl x509 -in "$cert" -inform PEM &>/dev/null;
if [ $? -eq 0 ]; then
file=`basename "$cert"`
einfo "Adding wireless certificate to kernel sources ($file)"
inc=${file%.x509.pem}
openssl x509 -in "$cert" -inform PEM -outform DER | xxd -i -c 8 > "${WORKDIR}/linux-${KV_FULL}/net/wireless/certs/${inc}".hex
fi
fi
done
}
pre_src_install
hook is used. All files in etc/wireless-regdb/certs/ ending with x509.pem are checked and if they are pem encoded x509 certificates they will
recoded in DER binary format and hexdumped for use in header files. This is how the kernel needs the certificate.
I use xxd for hexdumping. xxd belongs to vim, which is not everyones favourite. Be sure to check if you got xxd or use an alternative!
Finally the certificates are copied into the kernel sources. Whether you compress the sources afterwards or not, the certificates will be installed alongside the kernel sources and included when the kernel is compiled.
That's it for the kernel.
When you build your kernel and boot it, you should see something similar to this in your log:
notice kernel: cfg80211: Loaded X.509 cert 'rapna: 00ff63db13b1b338bd'
With the certificate included in the kernel, the kernel will now load and accept your self signed regulatory.db.