Message ID | 20230214080034.3828-3-marcan@marcan.st |
---|---|
State | New |
Headers | show |
Series | Apple T2 platform support | expand |
Hi Hector, On Tue, Feb 14, 2023 at 8:08 PM Hector Martin <marcan@marcan.st> wrote: > > On 14/02/2023 18.00, Julian Calaby wrote: > > Hi Arend, > > > > On Tue, Feb 14, 2023 at 7:04 PM Hector Martin <marcan@marcan.st> wrote: > >> > >> Newer Apple firmwares on chipsets without a hardware RNG require the > >> host to provide a buffer of 256 random bytes to the device on > >> initialization. This buffer is present immediately before NVRAM, > >> suffixed by a footer containing a magic number and the buffer length. > >> > >> This won't affect chips/firmwares that do not use this feature, so do it > >> unconditionally for all Apple platforms (those with an Apple OTP). > > > > Following on from the conversation a year ago, is there a way to > > detect chipsets that need these random bytes? While I'm sure Apple is > > doing their own special thing for special Apple reasons, it seems > > relatively sensible to omit a RNG on lower-cost chipsets, so would > > other chipsets need it? > > I think we could include a list of chips known not to have the RNG (I > think it's only the ones shipped on T2 machines). The main issue is I > don't have access to those machines so it's hard for me to test exactly > which ones need it. IIRC Apple's driver unconditionally provides the > randomness. I could at least test the newer chips on AS platforms and > figure out if they need it to exclude them... but then again, all I can > do is test whether they work without the blob, but they might still want > it (and simply become less secure without it). > > So I guess the answer is "maybe, I don't know, and it's kind of hard to > know for sure"... the joys of reverse engineering hardware without > vendor documentation. > > If you mean whether other chips with non-apple firmware can use this, I > have no idea. That's probably something for Arend to answer. My gut > feeling is Apple added this as part of a hardening mechanism and > non-Apple firmware does not use it (and Broadcom then probably started > shipping chips with a hardware RNG and firmware that uses it directly > across all vendors), in which case the answer is no. Sorry, I should have been more clear, I wasn't expecting you to know, I was asking Arend if he knew. Thanks,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index f320b6ce8bff..a7b88ab609c2 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -15,6 +15,7 @@ #include <linux/sched/signal.h> #include <linux/kthread.h> #include <linux/io.h> +#include <linux/random.h> #include <asm/unaligned.h> #include <soc.h> @@ -1653,6 +1654,13 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, return 0; } +struct brcmf_random_seed_footer { + __le32 length; + __le32 magic; +}; + +#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de +#define BRCMF_RANDOM_SEED_LENGTH 0x100 static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, const struct firmware *fw, void *nvram, @@ -1689,6 +1697,30 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, nvram_len; memcpy_toio(devinfo->tcm + address, nvram, nvram_len); brcmf_fw_nvram_free(nvram); + + if (devinfo->otp.valid) { + size_t rand_len = BRCMF_RANDOM_SEED_LENGTH; + struct brcmf_random_seed_footer footer = { + .length = cpu_to_le32(rand_len), + .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), + }; + void *randbuf; + + /* Some Apple chips/firmwares expect a buffer of random + * data to be present before NVRAM + */ + brcmf_dbg(PCIE, "Download random seed\n"); + + address -= sizeof(footer); + memcpy_toio(devinfo->tcm + address, &footer, + sizeof(footer)); + + address -= rand_len; + randbuf = kzalloc(rand_len, GFP_KERNEL); + get_random_bytes(randbuf, rand_len); + memcpy_toio(devinfo->tcm + address, randbuf, rand_len); + kfree(randbuf); + } } else { brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", devinfo->nvram_name);