[2/2] brcmfmac: pcie: Provide a buffer of random bytes to the device
Commit Message
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).
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Hector Martin <marcan@marcan.st>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
Comments
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?
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Hector Martin <marcan@marcan.st>
Beyond that, it all seems pretty sensible.
Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
> ---
> .../broadcom/brcm80211/brcmfmac/pcie.c | 32 +++++++++++++++++++
> 1 file changed, 32 insertions(+)
Thanks,
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.
- Hector
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,
@@ -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);