I'm new to writing Linux modules (drivers) and digital signatures, so please correct me if any of my understanding is incorrect.
When I run
make modules_install on my module, I get the following error (veikk is the module name):
At main.c:160: - SSL error:02001002:system library:fopen:No such file or directory: ../crypto/bio/bss_file.c:72 - SSL error:2006D080:BIO routines:BIO_new_file:no such file: ../crypto/bio/bss_file.c:79 sign-file: certs/signing_key.pem: No such file or directory
I was looking up tutorials on signing modules, but I was very confused about how to distribute a signed module. There are tutorials for manually signing modules (e.g., this, this, this), but these all seem to be post-installation and involve generating and registering a key with the kernel. It seems that the kernel wants to automatically sign the module on installation using
certs/signing_key.pem (hence the error).
Using the advice provided by this Unix Stack Exchange question, I was able to get rid of the error. This generates the
x509.genkey file, and then creates the
signing_key.x509 files in the
certs directory in the kernel directory.
printf "[ req ]\ndefault_bits = 4096\ndistinguished_name = req_distinguished_name\nprompt = no\nstring_mask = utf8only\nx509_extensions = myexts\n\n[ req_distinguished_name ]\nCN = Modules\n\n[ myexts ]\nbasicConstraints=critical,CA:FALSE\nkeyUsage=digitalSignature\nsubjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid" > x509.genkey openssl req -new -nodes -utf8 -sha512 -days 36500 -batch -x509 -config x509.genkey -outform DER -out $(BUILD_DIR)/certs/signing_key.x509 -keyout $(BUILD_DIR)/certs/signing_key.pem
After running this and
make modules_install, the module seems to install correctly. The output of
modinfo veikk seems to show a valid signature:
filename: /lib/modules/5.1.5-arch1-2-ARCH/extra/veikk.ko.xz license: GPL srcversion: A82263B16A25C763382D8B9 alias: hid:b0003g*v00002FEBp00000003 alias: hid:b0003g*v00002FEBp00000002 alias: hid:b0003g*v00002FEBp00000001 depends: hid retpoline: Y name: veikk vermagic: 5.1.5-arch1-2-ARCH SMP preempt mod_unload sig_id: PKCS#7 signer: Modules sig_key: 27:E8:FC:4A:4E:15:0C:AF:40:D5:A1:A4:10:E5:B5:55:BF:AF:EB:66 sig_hashalgo: sha512 signature: AC:AF:49:16:D4:AD:D9:7B:C5:52:A5:9F:F8:46:1C:DF:93:71:05:00: 4D:BF:96:96:3C:D1:11:19:6F:AC:D5:27:7D:E3:EE:8D:6C:BB:17:F4: 53:D3:FD:EE:85:22:97:57:BB:27:23:9C:8A:04:79:75:99:C4:A0:E6: 29:AF:20:15:87:EA:41:D2:26:00:2B:A1:39:68:28:FE:05:F5:F1:B1: 42:F8:FF:66:C0:6C:B5:17:A1:E7:F4:65:0A:17:64:99:9E:11:86:C0: 94:E7:D5:83:59:50:BE:0D:33:B8:A2:64:66:4F:70:A3:EB:E4:FB:B4: 52:D9:26:9C:57:CC:0D:D6:53:51:C2:90:D6:51:13:83:B6:22:EC:C9: DF:15:1D:1E:34:BD:7A:2D:8F:13:2D:78:8C:D3:EA:43:0B:6C:8D:DA: 9A:DA:A1:74:03:FC:D8:72:D0:96:54:52:60:AB:7A:BB:3C:D0:F4:8C: B7:92:21:B1:D8:02:01:6B:9B:AD:11:1A:90:5B:21:94:12:B7:5A:15: 10:6B:92:FA:74:F5:49:A2:4A:65:FF:4E:B6:9B:08:7B:BD:E5:85:9D: 98:52:A2:E4:D7:B4:0D:90:0D:62:7E:CE:6B:F8:8B:0C:33:76:1E:01: C7:0D:29:8C:97:BC:E1:35:58:2B:55:3F:6E:D9:36:46:50:76:74:67: 1F:B2:F6:C3:6B:24:4D:C1:7E:8D:14:4D:10:2D:1D:80:3C:82:02:1C: A6:87:14:8B:A0:3C:21:EA:DD:A7:CD:9C:D0:1B:DF:84:53:BF:0A:B6: DA:50:C4:AA:FF:90:44:47:4B:9F:8A:1C:C3:14:5D:A3:B5:A4:5F:6F: E1:E0:E2:51:B1:1E:5C:7E:95:70:72:76:3A:9D:53:10:F5:F0:3F:CD: E5:2B:EF:E4:3D:DB:64:65:9B:AE:E6:23:6E:4E:F1:4B:94:17:FF:FF: 06:A0:79:84:E1:BE:24:9D:93:B9:D4:94:41:76:92:D5:5B:8F:F6:4F: 98:B9:24:6F:01:CD:4F:49:52:15:48:79:4A:F3:46:CF:8A:AC:21:A9: 64:81:AC:01:15:80:06:F4:C3:9D:8A:C0:48:A6:53:C5:81:C2:DD:B1: C6:B9:80:B8:A9:C2:89:B8:20:C5:89:81:90:15:86:78:F7:09:3F:FD: F6:AC:54:57:8C:E0:B4:62:E0:78:CB:59:63:FA:E6:E2:8C:78:59:31: 92:E5:B5:E3:75:FE:F6:8F:82:3B:D6:5B:B1:84:E9:A8:9E:A4:B0:03: 99:8D:41:55:FF:11:A8:B6:A3:B9:EA:1D:5C:58:F7:D2:A6:F4:3A:C9: B1:E6:83:10:B7:E5:E4:15:28:2C:62:96
My question: Is this a recommended (and safe) way to sign a driver? Preferably, I would like to have end users not have to worry about the hassle of signing the drivers themselves when installing.
Because my understanding is a little muddy, here are a few questions I don't understand:
- Is this automatic signing on build as secure as the tutorials above for manually signing a driver after installation? I.e., I'm generating a key to sign it with, but that key never (at least explicitly) is loaded into the kernel.
- How are drivers normally distributed and signed? I would expect large companies with proprietary drivers for Linux to have their modules signed some way, such as Nvidia.
- Is there a way to pre-sign a module (on my end)? This seems unlikely because the module should be built for any system it's to be used on.
I would like to keep Secure Boot on (disabling it allows the unsigned module to load, but clients would prefer to have Secure Boot on).