Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mkosi: use cryptography instead of openssl #4

Open
wants to merge 4 commits into
base: signed-gpt
Choose a base branch
from

Conversation

behrmann
Copy link

No description provided.

poettering and others added 4 commits September 10, 2021 21:58
This adds support for creating signed GPT disk images. If Verity=signed
is set this will not only generate and insert Verity data into the
image, but then use the resulting root hash, sign it and include it in
an additional partition. It will also write the resulting PKCS7
signature out into a new .roothash.p7s file.

This scheme is compatible with kernel 5.4's PKCS7 signature logic for
dm-verity: the resulting .p7s file can be passed as-is to the kernel (or
systemd's RootHashSignature= setting).

The partition this embedds contains a simple JSON object containing
three fields. The verity root hash, the PKCS7 data (i.e. the same data
as in the .p7s file, but in base64), and SHA256 fingerprint of the
signing key. This partition is supposed to be read by the image
dissection logic of systemd, to implement signed single-file images.
(The corresponding PR for systemd I am still working on).

This opens up two avenues for image verification:

1. Everything in one file: the single, "unified" GPT disk image contains
   three partitions, for payload data, verity data and verity signature.

2. Split out: root hash and its signature are stored in two "sidecar"
   files.

(Of course I'd personally always go the "unified" way, but given the
RootHashSignature= logic exists already, and it's easy to support, let's
support it.)

This uses the key already used for doing secureboot image signing.
Conceptually this makes a ton of sense: we sign the same stuff here
after all: the contents of the image, supporting two different
entrypoints to the image: one via UEFI booting the image, and once for
attaching directly to an image from a running system. Admittedly, the
"mkosi.secure-boot.key" and "mkosi.secure-boot.certificate" monikers for
this key pair might be a bit suprising though.

Corresponding PR in systemd is:

systemd/systemd#20691

b64encoded = base64.b64encode(sigbytes).decode("ascii")
# Remove -----BEGIN PKCS7----- and -----END PKCS7----- from beginning and end
b64encoded = "".join(signature.decode("ascii").splitlines()[1:-1])
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably also includes newlines? we don't want those either... i.e. i think we really should just do the base64 encoding ourselves, after all we want a base64-encoded DER, and not a PEM file if you so will, i.e. the base64 need is because that's kinda how things are done with embedding binary data in json, it's not because we actually wanted PEM...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this includes newlines, which the .splitlines() and "".join remove.

cryptography's general approach is trying to cushion off sharp edges and make all things cryptography hard to misuse. The PKCS7SignatureBuilder() only returns things with their valid encodings (serialization.Encoding) and I haven't gone looking for more primitive primitives, but just hacked this together quickly.

I did compare both the current version and this one with the same input root hash and the base64 encoded blobs came out the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants