Summary: | gptboot fails to read the encrypted rootfs if geli authentication (geli -a) is used | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | no@spam <nospam> | ||||
Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
Status: | Open --- | ||||||
Severity: | Affects Some People | CC: | allanjude, jhb, markj, pat | ||||
Priority: | --- | ||||||
Version: | 14.1-STABLE | ||||||
Hardware: | amd64 | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
no@spam
2024-11-29 20:10:24 UTC
Is this a regression relative to an older release? There is some code in the loader to handle authenticated GELI providers, but we're not sure how well it's tested. The installer doesn't appear to enable authentication when configuring boot from GELI. Hmm, I think we aren't deriving the encryption key correctly when auth is configured. The code in the kernel for this case in sys/geom/eli/g_eli_key.c: /* * Find and decrypt Master Key encrypted with 'key' at slot 'nkey'. * Return 0 on success, > 0 on failure, -1 on bad key. */ int g_eli_mkey_decrypt(const struct g_eli_metadata *md, const unsigned char *key, unsigned char *mkey, unsigned nkey) { unsigned char tmpmkey[G_ELI_MKEYLEN]; unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */ const unsigned char *mmkey; int bit, error; if (nkey > G_ELI_MKEYLEN) return (-1); /* * The key for encryption is: enckey = HMAC_SHA512(Derived-Key, 1) */ g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x01", 1, enckey, 0); ... but in geliboot.c we have: if ((gdev->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) { bcopy(mkp, gdev->sc.sc_ekey, G_ELI_DATAKEYLEN); } else { /* * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10) */ g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, (const uint8_t *)"\x10", 1, gdev->sc.sc_ekey, 0); } Try this change to see if it works: diff --git a/stand/libsa/geli/geliboot.c b/stand/libsa/geli/geliboot.c index 04c53e73b29a..bdb288d2733c 100644 --- a/stand/libsa/geli/geliboot.c +++ b/stand/libsa/geli/geliboot.c @@ -286,9 +286,9 @@ geli_probe(struct geli_dev *gdev, const char *passphrase, u_char *mkeyp) bcopy(mkp, gdev->sc.sc_ekey, G_ELI_DATAKEYLEN); } else { /* - * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10) + * The encryption key is: ekey = HMAC_SHA512(Derived-Key, 1) */ - g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, (const uint8_t *)"\x10", 1, + g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, (const uint8_t *)"\x01", 1, gdev->sc.sc_ekey, 0); } explicit_bzero(mkey, sizeof(mkey)); BTW, we don't perform any MAC on data read from a GELI volume, this patch would just ensure we get the right key to decrypt the data. This is not fully ideal but is "ok" for a read-only boot loader. However, GELI has gained write support in the boot loader at some point and we need to reject writes on a volume with auth support unless we implement proper auth support in geliboot. Created attachment 255669 [details]
geliboot_auth.patch
Better patch that also disables writes
|