With CONFIG_MODULE_SIG the kernel checks module signatures. A signed
module is the unchanged ELF file with the signature simply appended at the end,
outside the ELF container; the whole module, debug information included, is what is
signed, so a signed module must not be stripped afterwards. The marker at the end
shows only that a signature is present, not that it is valid.
Layout of the end of the file
| Part | Size | Contents |
|---|---|---|
| ELF module | — | The module as built. |
| signer’s name | signer_len | Empty (0) for PKCS#7 signatures. |
| key identifier | key_id_len | Empty (0) for PKCS#7 signatures. |
| signature data | sig_len | The signature: a PKCS#7 message when id_type is 2. |
| information block | 12 | struct module_signature, below. |
| marker | 28 | ~Module signature appended~ and a line feed (0A). |
A reader therefore checks the last 28 bytes for the marker, reads the 12 bytes
before it, and finds the signature sig_len bytes (plus the two empty
lengths) before that.
struct module_signature
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 1 | algo | Public-key algorithm; 0 for PKCS#7. |
1 | 1 | hash | Digest algorithm; 0 for PKCS#7. |
2 | 1 | id_type | Key identifier type: 2 MODULE_SIGNATURE_TYPE_PKCS7 (signature in a PKCS#7 message). |
3 | 1 | signer_len | Length of the signer’s name; 0 for PKCS#7. |
4 | 1 | key_id_len | Length of the key identifier; 0 for PKCS#7. |
5 | 3 | __pad | Padding. |
8 | 4 | sig_len | Length of the signature data, big-endian. |
The header marks algo, hash, signer_len and
key_id_len as 0, so the algorithms are not given in these fields. The
kernel’s
documentation lists RSA and ECDSA with SHA-2 or SHA-3 digests of 256, 384 or 512 bits
(configuration options CONFIG_MODULE_SIG_SHA256 to
CONFIG_MODULE_SIG_SHA3_512), and ML-DSA keys.
Example
…signature data (sig_len bytes)…
00 00 02 00 00 00 00 00 algo, hash, id_type 2 (PKCS#7), signer_len, key_id_len, pad
00 00 02 A3 sig_len 675 (big-endian)
7E 4D 6F 64 75 6C 65 20 73 69 67 6E 61 74 75 72 65 20 61 70 70 65 6E 64 65 64 7E 0A
"~Module signature appended~\n"
The signature length is illustrative.
Sources
- include/uapi/linux/module_signature.h – the marker,
struct module_signature,MODULE_SIGNATURE_TYPE_PKCS7and the order of the signature’s parts - Kernel module signing facility – where the signature goes, what is signed, stripping, algorithms and configuration options