1 // SPDX-License-Identifier: GPL-2.0 2 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 4 //! FSP is a hardware unit that runs FMC firmware. 5 6 use kernel::{ 7 device, 8 dma::Coherent, 9 firmware::Firmware, 10 prelude::*, // 11 }; 12 13 use crate::{ 14 firmware::elf, 15 gpu::Chipset, // 16 }; 17 18 /// Size of the FSP SHA-384 hash, in bytes. 19 const FSP_HASH_SIZE: usize = 48; 20 /// Maximum size of the FSP public key (RSA-3072), in bytes. 21 /// 22 /// The FMC ELF `publickey` section may be shorter, so the remaining bytes are zero-padded. 23 const FSP_PKEY_SIZE: usize = 384; 24 /// Maximum size of the FSP signature (RSA-3072), in bytes. 25 /// 26 /// The FMC ELF `signature` section may be shorter, so the remaining bytes are zero-padded. 27 const FSP_SIG_SIZE: usize = 384; 28 29 /// Structure to hold FMC signatures. 30 /// 31 /// C representation is used because this type is used for communication with the FSP. 32 #[derive(Debug, Clone, Copy, Zeroable)] 33 #[repr(C)] 34 pub(crate) struct FmcSignatures { 35 pub(crate) hash384: [u8; FSP_HASH_SIZE], 36 pub(crate) public_key: [u8; FSP_PKEY_SIZE], 37 pub(crate) signature: [u8; FSP_SIG_SIZE], 38 } 39 40 pub(crate) struct FspFirmware { 41 /// FMC firmware image data (only the "image" ELF section). 42 #[expect(dead_code)] 43 pub(crate) fmc_image: Coherent<[u8]>, 44 /// FMC firmware signatures. 45 #[expect(dead_code)] 46 pub(crate) fmc_sigs: KBox<FmcSignatures>, 47 } 48 49 impl FspFirmware { 50 pub(crate) fn new( 51 dev: &device::Device<device::Bound>, 52 chipset: Chipset, 53 ver: &str, 54 ) -> Result<Self> { 55 let fw = super::request_firmware(dev, chipset, "fmc", ver)?; 56 57 // FSP expects only the "image" section, not the entire ELF file. 58 let fmc_image_data = elf::elf_section(fw.data(), "image").ok_or_else(|| { 59 dev_err!(dev, "FMC ELF file missing 'image' section\n"); 60 EINVAL 61 })?; 62 let fmc_image = Coherent::from_slice(dev, fmc_image_data, GFP_KERNEL)?; 63 64 Ok(Self { 65 fmc_image, 66 fmc_sigs: Self::extract_fmc_signatures(&fw, dev)?, 67 }) 68 } 69 70 /// Extract FMC firmware signatures for Chain of Trust verification. 71 /// 72 /// Extracts real cryptographic signatures from FMC ELF32 firmware sections. 73 /// Returns signatures in a heap-allocated structure to prevent stack overflow. 74 fn extract_fmc_signatures( 75 fmc_fw: &Firmware, 76 dev: &device::Device, 77 ) -> Result<KBox<FmcSignatures>> { 78 let get_section = |name: &str, max_len: usize| { 79 elf::elf_section(fmc_fw.data(), name) 80 .ok_or(EINVAL) 81 .inspect_err(|_| dev_err!(dev, "FMC firmware missing '{}' section\n", name)) 82 .and_then(|section| { 83 if section.len() > max_len { 84 dev_err!( 85 dev, 86 "FMC {} section size {} > maximum {}\n", 87 name, 88 section.len(), 89 max_len 90 ); 91 Err(EINVAL) 92 } else { 93 Ok(section) 94 } 95 }) 96 }; 97 98 let hash_section = get_section("hash", FSP_HASH_SIZE)?; 99 let pkey_section = get_section("publickey", FSP_PKEY_SIZE)?; 100 let sig_section = get_section("signature", FSP_SIG_SIZE)?; 101 102 // The hash section is a SHA-384 output: it must be exactly FSP_HASH_SIZE bytes. 103 if hash_section.len() != FSP_HASH_SIZE { 104 dev_err!( 105 dev, 106 "FMC hash section size {} != expected {}\n", 107 hash_section.len(), 108 FSP_HASH_SIZE 109 ); 110 return Err(EINVAL); 111 } 112 113 // Initialize the signatures in place to avoid building the large `FmcSignatures` on the 114 // stack, then fill each section from the firmware. 115 let signatures = KBox::init( 116 pin_init::init_zeroed::<FmcSignatures>().chain(|sigs| { 117 // PANIC: src and dst lengths are both FSP_HASH_SIZE (verified above). 118 sigs.hash384.copy_from_slice(hash_section); 119 // PANIC: dst is sliced to src.len(); src.len() <= FSP_PKEY_SIZE per `get_section`. 120 sigs.public_key[..pkey_section.len()].copy_from_slice(pkey_section); 121 // PANIC: dst is sliced to src.len(); src.len() <= FSP_SIG_SIZE per `get_section`. 122 sigs.signature[..sig_section.len()].copy_from_slice(sig_section); 123 Ok(()) 124 }), 125 GFP_KERNEL, 126 )?; 127 128 Ok(signatures) 129 } 130 } 131