More Related Content Similar to Multi-signed Kernel Module (20) More from SUSE Labs Taipei (19) Multi-signed Kernel Module2. 2 Copyright © SUSE 2020
Agenda
01 Structure of kernel
module signature
02 Producing a CMS
message
03 Producing a multiple
signer CMS message
04 Re-signing a CMS
05 Conclusion
06 Q&A
LINUX KERNEL
4. Copyright © SUSE 20204
Kernel module signature verification
LINUX KERNEL
* The kernel module signing facility cryptographically signs modules during
installation and then checks the signature upon loading the module. [1]
CONFIG_MODULE_SIG
* History in Kernel
- v3.7: Kernel module signature verification be introduced
- Using a specific structure for module signature
- v3.17: PKCS#7 parser be introduced
CONFIG_PKCS7_MESSAGE_PARSER
- v4.3: The format of module signature be switched to PKCS#7/CMS message
5. 5 Copyright © SUSE 2020
Signature of
Kernel Module
LINUX KERNEL
Module Data
ms->sig_len
struct module_signature
u8 id_type;
__be32 sig_len;
PKCS#7 / CMS
message
MODULE_SIG_STRING
12 bytes
markerlen
ModuleSignature
6. 6 Copyright © SUSE 2020
Structure of
module signature
LINUX KERNEL
7. 7 Copyright © SUSE 2020
Example of module signature
LINUX KERNEL
PKCS#7 type sig_len = 0x1ea = 0x1e6 + 4
0x10b31 – 0x1ea + 1 = 0x10948
CMS message
ASN.1 tag:
Type: 30 = _tag(UNIV, CONS, SEQ)
0x82 = 10000002 = 2 subsequent octet
Length = 0x1e6
8. Copyright © SUSE 20208
Cryptographic Message Syntax (CMS)
LINUX KERNEL
* ietf.org RFC 5652
* The CMS is derived from PKCS #7 version 1.5, which is documented in RFC 2315
[PKCS#7].
* The CMS describes an encapsulation syntax for data protection. It supports digital
signatures and encryption. [2]
* The CMS values are generated using ASN.1 [X.208-88], using BER-encoding (Basic
Encoding Rules) [X.209-88]. Values are typically represented as octet strings. [2]
* CMS be supported by openssl-1.0.0 or newer. [1]
9. Copyright © SUSE 20209
Signed-data Content Type
LINUX KERNEL
* The CMS is general enough to support many different content types. [2]
* An implementation that conforms to this specification MUST implement the
protection content, ContentInfo, and MUST implement the data, signed-data, and
enveloped-data content types. [2]
* Kernel module signature uses signed-data conent type.
* openssl cms -sign command can generate signed-data content type.
10. 10 Copyright © SUSE 2020
CMS message
LINUX KERNEL
ContentType
SignedData (a.k.a content)
version
digestAlgorithms
EncapsulatedContentInfo
eContentType
eContent
certificates
crls
SignerInfos
SignerInfo
version
signerIdentifier
digestAlgorithm
signedAttrs (a.k.a. authAttrs)
contentType
messageDigest
signatureAlgorithm
signature (a.k.a. encryptedDigest)
unsignedAttrs
CMSmessage(a.k.a.ContentInfo)
SignerInfo
Module Data
struct module_signature
PKCS#7 / CMS
message
MODULE_SIG_STRING
12. Copyright © SUSE 202012
scripts/sign-file.c
LINUX KERNEL
* A tool in kernel for signing a module file using the given key. [1]
* It relies on openssl
- Before openssl-1.0.0: old PKCS#7
- openssl-1.0.0 or newer: CMS message
* Signing a module:
scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]
* Attaching a raw signature on module:
scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]
13. 13 Copyright © SUSE 2020
Example for using sign-file tool
LINUX KERNEL
* Signing a kernel module
- Using the key automatically generated by the kernel:
../scripts/sign-file sha256 ../certs/signing_key.pem ../certs/signing_key.x509
./acer-wmi.ko ./acer-wmi-signed.ko
* Generating .p7s signature file of a kernel module
- A acer-wmi.ko.p7s file be generated:
../scripts/sign-file -dp sha256 ../certs/signing_key.pem
../certs/signing_key.x509 ./acer-wmi.ko
- openSSL can dump .p7s signature file:
openssl asn1parse -i -dump -inform der -in acer-wmi.ko.p7s | less
14. 14 Copyright © SUSE 2020
ContentType
SignedData
SignerInfos
version
digestAlgorithms
encapContentInfo:eContentType
SignerInfo:version
1: SignerIdentifier = issuerAndSerialNumber
3: SignerIdentifier = subjectKeyIdentifier
sid:issuer
15. 15 Copyright © SUSE 2020
SignedData
SignerInfos
sid:issuer
sid:serialNumber
SignerInfo:digestAlgorithm
SignerInfo:signatureAlgorithm
SignerInfo:signature
(aka encryptedDigest)
SignerInfo:version
1: SignerIdentifier = issuerAndSerialNumber
3: SignerIdentifier = subjectKeyIdentifier
16. 16 Copyright © SUSE 2020
Generating CMS by openssl command
LINUX KERNEL
* Target: Create a CMS by openssl command that the result is the same with sign-file
tool.
* Looking at the CMS code in sign-file.c
- Looks that those flags are for reducing the size of signature.
* Add corresponding options to openssl command for generating CMS message:
openssl cms -sign -signer ../certs/signing_key.pem -binary -in ./acer-wmi.ko
-outform DER -out acer-wmi.ko.cms -nocerts -noattr -nosmimecap
17. 17 Copyright © SUSE 2020
Attach raw CMS message by sign-file
LINUX KERNEL
* Use sign-file to attach a raw CMS message on a kernel module:
../scripts/sign-file -s ./acer-wmi.ko.cms sha256 ../certs/signing_key.x509
acer-wmi.ko acer-wmi-signed.ko
* Loading signed kernel module for testing:
- Kernel should be tainted when verification failed:
[ 57.394922] acer_wmi: module verification failed: signature and/or required
key missing - tainting kernel
- Or enabling lock-down mode for testing:
# echo integrity > /sys/kernel/security/lockdown
# insmod acer-wmi-signed.ko
insmod: ERROR: could not insert module acer-wmi-signed.ko: Operation not
permitted
19. Copyright © SUSE 202019
Add multiple signer by openssl
LINUX KERNEL
* Target: Create a multiple signer CMS message by openssl command.
* Add two signer keys in openssl command for generating two signers CMS message:
openssl cms -sign -signer ../certs/signing_key.pem –signer
../certs/signing_key1.pem -binary -in ./acer-wmi.ko -outform DER -out
acer-wmi.ko.cms -nocerts -noattr -nosmimecap
* The sign-file tool can still be used to attach the multi-signer CMS message on
kernel module.
* Result: The multi-signed kernel module can pass the verification on both two
kernels. And third kernel (SLE kernel) rejected it.
20. 20 Copyright © SUSE 2020
SignerInfo 2
SignerInfo2:signature
SignerInfo2:serialNumber
21. 21 Copyright © SUSE 2020
SignerInfo 1
SignerInfo2:signature
SignerInfo1:signature
SignerInfo1:serialNumber
23. Copyright © SUSE 202023
Re-signing a CMS message
LINUX KERNEL
* The openssl cms -sign command can be used to generate a multiple signers CMS
message. But it also means that the signer should hosts multiple private keys.
* Target: Is it possible that we can re-sign a signed CMS message?
24. Copyright © SUSE 202024
Try openssl cms -resign
LINUX KERNEL
* Using -sign command generates a single signer CMS message:
openssl cms -sign -signer ../certs/signing_key.pem -binary -in ./acer-wmi.ko
-outform DER -out acer-wmi.ko.cms -nocerts -noattr -nosmimecap
* Then using -resign command re-signs the single signer CMS message:
openssl cms -resign -signer ../certs/signing_key1.pem -inform DER
-in ./acer- wmi.ko.cms -outform DER -out acer-wmi.ko.cms2 -nocerts -noattr
-nosmimecap
* Result: The second signature is lost.
25. 25 Copyright © SUSE 2020
SignerInfo 2
SignerInfo 1
SignerInfo1:signature
SignerInfo2:signature is Lost!
26. 26 Copyright © SUSE 2020
LINUX KERNEL
The openssl cms -resign uses signedAttrs
* -resign
- resign a message: take an existing message and one or more new signers.
- The -resign option uses an existing message digest when adding a new signer.
This means that attributes must be present in at least one existing signer using
the same message digest or this operation will fail. [3]
* -noattr
- normally when a message is signed a set of attributes are included which include
the signing time and supported symmetric algorithms. With this option they are
not included. [3]
* The openssl cms -resign command follows signedAttrs approach
The -noattr option can not be used with -resign
27. 27 Copyright © SUSE 2020
LINUX KERNEL
Message Digest Calculation for CMS
* The message digest calculation process computes a message digest on either the
content being signed or the content together with the signed attributes. [2]
* Content together with the signed attributes:
- The complete DER encoding of the SignedAttrs value contained in the signedAttrs
field. it MUST contain:
- content-type
- message-digest
* Content being signed:
- encapContentInfo eContent OCTEST STRING
* External signatures (when no signedAttrs, no eContent):
- SingerInfo:signature SignatureValue
increased size of CMS
28. 28 Copyright © SUSE 2020
Content,
Digest and
Signature
in CMS
LINUX KERNEL
ContentType
SignedData (a.k.a content)
version
digestAlgorithms
EncapsulatedContentInfo
eContentType
eContent
certificates
crls
SignerInfos
SignerInfo
version
signerIdentifier
digestAlgorithm
signedAttrs (a.k.a. authAttrs)
contentType
messageDigest
signatureAlgorithm
signature (a.k.a. encryptedDigest)
unsignedAttrs
CMSmessage(a.k.a.ContentInfo)
SignerInfo
a. RSA encrypted digest of
signedAttrs or eContent
b. External signature when
no signedAttrs, no eContent
OPTIONAL
OPTIONAL
29. 29 Copyright © SUSE 2020
LINUX KERNEL
Removed -noattr when re-signing
* Using -sign command generates a single signer CMS message:
openssl cms -sign -signer ../certs/signing_key.pem -binary -in ./acer-wmi.ko
-outform DER -out acer-wmi.ko.cms -nocerts -nosmimecap
* Then using -resign command re-signs the single signer CMS message:
openssl cms -resign -signer ../certs/signing_key1.pem -inform DER
-in ./acer-wmi.ko.cms -outform DER -out acer-wmi.ko.cms2 -nocerts
-nosmimecap
* Result:
- Kernel raised: [200547.294895] PKCS7: Missing required AuthAttr
- CMS: Adding signers should gen a content type attribute
https://github.com/openssl/openssl/pull/8944
30. 30 Copyright © SUSE 2020
SignerInfo 2
SignerInfo2:contentType is Lost!
patch: openssl#8944
SignerInfo 1
SignerInfo1:contentType
31. 31 Copyright © SUSE 2020
Update openssl
to 1.1.1g
LINUX KERNEL
* The openssl 1.1.1g includes #8944
patches.
- The contentType in second
SignerInfo be generated.
* Kernel raised: [ 249.579675] PKCS7:
Invalid module sig (has authattrs)
* The authattrs can not be used in kernel
module signature.
33. Copyright © SUSE 202033
Conclusion
LINUX KERNEL
* The kernel module signature verification does support multi-signed modules
, but authAttrs can not be used in CMS message. Kernel can only work with
a multiple external signature CMS message.
* The openssl cms -sign function can be used to generate an available multiple
signerinfo CMS message for kernel module verification. The premise is that the
signer hosts multiple private keys.
* Current openssl cms -resign function can not produce an available multiple
signerinfo CMS message for kernel module verification. Because kernel doesn’t
support authAttrs approach.
34. Copyright © SUSE 202034
TODO
LINUX KERNEL
* Use Cases?
* Improve sing-file tool to support multiple private keys?
* Find a way to produce multiple external signatures CMS message for re-signing a
CMS message?
- RFC 5652 does not define re-signing process for CMS message.
36. Copyright © SUSE 202036
References
LINUX KERNEL
* [1] Linux Kernel v5.9-rc6
* [2] RFC5652 Cryptographic Message Syntax (CMS), September 2009
* [3] man page of openssl-cms command
37. Thank you.
© 2020 SUSE LLC. All Rights Reserved. SUSE and the
SUSE logo are registered trademarks of SUSE LLC in the
United States and other countries. All third-party
trademarks are the property of their respective owners.
For more information, contact SUSE at:
+1 800 796 3700 (U.S./Canada)
+49 (0)911-740 53-0 (Worldwide)
SUSE
Maxfeldstrasse 5
90409 Nuremberg
www.suse.com