summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-devtools/mtd-util')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0001-Firmware-update-fix-for-mis-aligned-sectors.patch82
-rw-r--r--meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0002-Add-fix-for-possible-freeing-of-mismatched-memory.patch39
-rw-r--r--meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0003-Fix-Key-Cancellation-Update-Capsule-Flow.patch224
-rw-r--r--meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/mtd-util.bb5
4 files changed, 350 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0001-Firmware-update-fix-for-mis-aligned-sectors.patch b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0001-Firmware-update-fix-for-mis-aligned-sectors.patch
new file mode 100644
index 000000000..aebd776d4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0001-Firmware-update-fix-for-mis-aligned-sectors.patch
@@ -0,0 +1,82 @@
+From d58245421fec0ac212382164bd5cc0e881bc389f Mon Sep 17 00:00:00 2001
+From: Snehalatha Venkatesh <snehalathax.v@intel.com>
+Date: Fri, 27 May 2022 04:23:21 +0000
+Subject: [PATCH] Firmware update fix for mis-aligned sectors
+
+Firmware update breaks due to mis-aligned calculations bug in
+erase and write sector boundaries, which was corrupting the
+next sectors though it wasn't part of erase bit-map (in case of
+increased u-boot image size, its region update is corrupting the
+neighbouring other fw region). This fix validates the erase and
+write boundaries properly now and allows the erase of needed sectors.
+
+Tested: Tested firmware update on platform.
+
+Signed-off-by: Vikram Bodireddy <vikram.bodireddy@intel.com>
+Signed-off-by: Snehalatha Venkatesh <snehalathax.v@intel.com>
+Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+---
+ pfr.hpp | 26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/pfr.hpp b/pfr.hpp
+index 23a73b3..efe737a 100644
+--- a/pfr.hpp
++++ b/pfr.hpp
+@@ -412,6 +412,7 @@ bool pfr_write(mtd<deviceClassT>& dev, const std::string& filename,
+ uint32_t wr_count = 1;
+ uint32_t er_count = 1;
+ uint32_t erase_end_addr = 0;
++ uint32_t write_end_addr = 0;
+ for (uint32_t blk = 0; blk < pbc_hdr->bitmap_size; blk += wr_count)
+ {
+ if ((blk % 8) == 0)
+@@ -504,28 +505,37 @@ bool pfr_write(mtd<deviceClassT>& dev, const std::string& filename,
+ FWDEBUG("erase(" << std::hex << pfr_blk_size * blk << ", "
+ << pfr_blk_size * er_count + dev_offset << ")");
+ dev.erase(pfr_blk_size * blk + dev_offset, pfr_blk_size * er_count);
+- erase_end_addr = (pfr_blk_size * (blk + er_count));
++ erase_end_addr = (pfr_blk_size * (blk + er_count)) - 1;
++ FWDEBUG("erase_end_addr: " << std::hex << erase_end_addr);
+ }
+
+ if (copy)
+ {
+ cbspan data(offset, offset + pfr_blk_size * wr_count);
+- // DUMP(PRINT_ERROR, data);
+- FWDEBUG("write(" << std::hex << pfr_blk_size * blk << ", "
+- << pfr_blk_size * wr_count << "), offset = 0x"
+- << (offset - map_base) + dev_offset);
++ write_end_addr = (pfr_blk_size * (blk + wr_count)) - 1;
++ FWDEBUG("write_end_addr: " << std::hex << write_end_addr);
++
+ // Check if current write address wasn't part of previous 64K sector
+ // erase. and erase it here.
+- if (((pfr_blk_size * (blk + wr_count)) >= erase_end_addr) ||
+- ((pfr_blk_size * blk) >= erase_end_addr))
++ if ((write_end_addr > erase_end_addr) ||
++ ((pfr_blk_size * blk) > erase_end_addr))
+ {
+ // Currently 4K erases are not working hence making it always
+ // 64K erase.
+ // TODO: Fix 4K erase issue and fix the below logic to do
+ // incremental 4K erases.
+- dev.erase(erase_end_addr + dev_offset, pfr_blk_size * 16);
++ FWDEBUG("erase(" << std::hex
++ << (erase_end_addr + 1) + dev_offset << ", "
++ << pfr_blk_size * 16 << ")");
++
++ dev.erase((erase_end_addr + 1) + dev_offset, pfr_blk_size * 16);
+ erase_end_addr += pfr_blk_size * 16;
++ FWDEBUG("erase_end_addr: " << std::hex << erase_end_addr);
+ }
++ // DUMP(PRINT_ERROR, data);
++ FWDEBUG("write(" << std::hex << pfr_blk_size * blk << ", "
++ << pfr_blk_size * wr_count << "), offset = 0x"
++ << (offset - map_base) + dev_offset);
+ dev.write_raw(pfr_blk_size * blk + dev_offset, data);
+
+ offset += pfr_blk_size * wr_count;
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0002-Add-fix-for-possible-freeing-of-mismatched-memory.patch b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0002-Add-fix-for-possible-freeing-of-mismatched-memory.patch
new file mode 100644
index 000000000..1c5bc5843
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0002-Add-fix-for-possible-freeing-of-mismatched-memory.patch
@@ -0,0 +1,39 @@
+From 5606cfc0857dc6fe1071c14f6906d866048f6c18 Mon Sep 17 00:00:00 2001
+From: AkshayRav <akshay.raveendran.k@intel.com>
+Date: Thu, 28 Apr 2022 13:57:32 +0530
+Subject: [PATCH] Add fix for possible freeing of mismatched memory (#8)
+
+* Add fix for possible freeing of mismatched memory
+
+Memory referenced by "buf" was allocated through function
+"new[]" and released through function "delete". The fix changes the
+release function to "delete[]" to remove the possible freeing of
+mismatched memory.
+
+Signed-off-by: AKSHAY RAVEENDRAN K <akshay.raveendran.k@intel.com>
+---
+ mtd-util.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mtd-util.cpp b/mtd-util.cpp
+index 7f2f98d..d6136f0 100644
+--- a/mtd-util.cpp
++++ b/mtd-util.cpp
+@@ -391,7 +391,7 @@ int main(int argc, char* argv[])
+ {
+ std::cerr << "failed to parse '" << argv[optind]
+ << "' as integer" << std::endl;
+- delete buf;
++ delete[] buf;
+ return 1;
+ }
+ optind++;
+@@ -473,7 +473,7 @@ int main(int argc, char* argv[])
+ break;
+ case ACTION_WRITE_TO_FLASH:
+ ret = buf_to_flash(dev, buf, start, len);
+- delete buf;
++ delete[] buf;
+ break;
+ #endif /* DEVELOPER_OPTIONS */
+ case ACTION_CP_TO_FILE:
diff --git a/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0003-Fix-Key-Cancellation-Update-Capsule-Flow.patch b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0003-Fix-Key-Cancellation-Update-Capsule-Flow.patch
new file mode 100644
index 000000000..ca6402ed2
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/files/0003-Fix-Key-Cancellation-Update-Capsule-Flow.patch
@@ -0,0 +1,224 @@
+From a3eba12b5c85add20a248bb95d1b9e884a1f6262 Mon Sep 17 00:00:00 2001
+From: Ankita Vilas Gawade <ankita.gawade@intel.com>
+Date: Tue, 26 Jul 2022 20:22:10 +0000
+Subject: [PATCH] Fix Key Cancellation Update Capsule Flow
+
+In the current code flow, the block 1 component of key cancellation
+capsule is not being mapped to the correct structure which results
+in failure of key cancellation update as improper value would be picked up.
+
+This commit fixes the above issue by introducing an union, using which
+the correct block 1 strcuture can be picked up depending on the type of
+capsule.
+
+This commit also fixes the check on contents of cancellation payload and
+corrects the payload length.
+
+Tested
+1.Posted a key cancellation capsule to cancel CSK ID 2(For BMC and PFM)
+2.Performed BMC Firmware update with the image signed with CSK ID 2.
+3.Firmware Update failed succesfully implying CSK key being cancelled.
+
+Signed-off-by: Ankita Vilas Gawade <ankita.gawade@intel.com>
+---
+ pfr.cpp | 33 ++++++++++++++++-----------------
+ pfr.hpp | 27 +++++++++++++++++----------
+ 2 files changed, 33 insertions(+), 27 deletions(-)
+
+diff --git a/pfr.cpp b/pfr.cpp
+index 4ec9638..b74c166 100644
+--- a/pfr.cpp
++++ b/pfr.cpp
+@@ -599,18 +599,18 @@ static bool is_block0_sig_entry_valid(uint32_t curve, const uint8_t* root_key_x,
+ *
+ * @return bool true if this Block 1 is valid; false, otherwise
+ */
+-static bool is_block1_valid(const blk0* b0, const blk1* b1,
++static bool is_block1_valid(const blk0* b0, const sig_blk1* sig,
+ bool is_key_cancellation_cert, bool check_root_key)
+ {
+ // Verify magic number
+- if (b1->magic != blk1_magic)
++ if (sig->b1.magic != blk1_magic)
+ {
+ FWERROR("b1 magic invalid");
+ return false;
+ }
+
+ // Validate Block1 Root Entry
+- const key_entry* root_entry = &b1->root_key;
++ const key_entry* root_entry = &sig->b1.root_key;
+ if (!is_root_entry_valid(root_entry, check_root_key))
+ {
+ FWERROR("root_entry invalid");
+@@ -621,7 +621,7 @@ static bool is_block1_valid(const blk0* b0, const blk1* b1,
+ {
+ // In the signature of the Key Cancellation Certificate, there's no CSK
+ // entry
+- const block0_sig_entry* b0_entry = &b1->block0_sig;
++ const block0_sig_entry* b0_entry = &sig->cncl_b1.block0_sig;
+
+ // Validate Block 0 Entry in Block 1
+ return is_block0_sig_entry_valid(root_entry->curve, root_entry->key_x,
+@@ -629,7 +629,7 @@ static bool is_block1_valid(const blk0* b0, const blk1* b1,
+ }
+
+ // Validate Block1 CSK Entry
+- const csk_entry* csk = &b1->csk;
++ const csk_entry* csk = &sig->b1.csk;
+ if (!is_csk_entry_valid(root_entry, csk, b0->pc_type))
+ {
+ FWERROR("csk_entry invalid");
+@@ -637,7 +637,7 @@ static bool is_block1_valid(const blk0* b0, const blk1* b1,
+ }
+
+ // Validate Block 0 Entry in Block 1
+- const block0_sig_entry* block0_sig = &b1->block0_sig;
++ const block0_sig_entry* block0_sig = &sig->b1.block0_sig;
+ if (is_block0_sig_entry_valid(root_entry->curve, csk->key.key_x,
+ csk->key.key_y, block0_sig, b0))
+ {
+@@ -657,23 +657,21 @@ static bool is_block1_valid(const blk0* b0, const blk1* b1,
+ * @return uint32_t 1 if this key cancellation certificate is valid; 0,
+ * otherwise
+ */
+-static uint32_t is_key_can_cert_valid(const cancel_cert* cert)
++static uint32_t is_key_can_cert_valid(const cancel_payload* cert)
+ {
+ // Check for the 0s in the reserved field
+ // This reduces the degree of freedom for attackers
+- const uint32_t* key_can_cert_reserved = cert->rsvd;
+- for (uint32_t word_i = 0; word_i < cancel_pad_size / 4; word_i++)
++ const uint32_t* key_can_cert_reserved = cert->padding;
++ for (uint32_t word_i = 0; word_i < cancel_payload_pad_size; word_i++)
+ {
+ if (key_can_cert_reserved[word_i] != 0)
+ {
+ return 0;
+ }
+ }
+- const cancel_payload* cancel =
+- reinterpret_cast<const cancel_payload*>(cert + 1);
+
+ // If the key ID is within 0-127 (inclusive), return 1
+- return cancel->csk_id <= pfr_max_key_id;
++ return cert->csk_id <= pfr_max_key_id;
+ }
+
+ /**
+@@ -692,11 +690,11 @@ static uint32_t is_key_can_cert_valid(const cancel_cert* cert)
+ static bool is_signature_valid(const b0b1_signature* sig, bool check_root_key)
+ {
+ const blk0* b0 = &sig->b0;
+- const blk1* b1 = &sig->b1;
+ bool is_key_cancellation_cert = b0->pc_type & pfr_pc_type_cancel_cert;
+
+ // Get pointer to protected content
+ const uint8_t* pc = reinterpret_cast<const uint8_t*>(sig + 1);
++
+ if (is_key_cancellation_cert)
+ {
+ // Check the size of the cancellation certificate
+@@ -706,7 +704,7 @@ static bool is_signature_valid(const b0b1_signature* sig, bool check_root_key)
+ }
+
+ // Validate the cancellation certificate content
+- if (!is_key_can_cert_valid(reinterpret_cast<const cancel_cert*>(pc)))
++ if (!is_key_can_cert_valid(reinterpret_cast<const cancel_payload*>(pc)))
+ {
+ FWERROR("cancel cert invalid");
+ return false;
+@@ -717,7 +715,8 @@ static bool is_signature_valid(const b0b1_signature* sig, bool check_root_key)
+ if (is_block0_valid(b0, pc))
+ {
+ // Validate block1 (contains the signature chain used to sign block0)
+- if (is_block1_valid(b0, b1, is_key_cancellation_cert, check_root_key))
++ if (is_block1_valid(b0, &sig->b1_sig, is_key_cancellation_cert,
++ check_root_key))
+ {
+ return true;
+ }
+@@ -753,7 +752,7 @@ static bool fvm_authenticate(const b0b1_signature* img_sig)
+ // but it is authenticated as follows:
+ const b0b1_signature* sig = img_sig + 1;
+ const blk0* b0 = &sig->b0;
+- const blk1* b1 = &sig->b1;
++ const blk1* b1 = &sig->b1_sig.b1;
+ const uint8_t* pc = reinterpret_cast<const uint8_t*>(sig + 1);
+
+ if (!is_block0_valid(b0, pc))
+@@ -762,7 +761,7 @@ static bool fvm_authenticate(const b0b1_signature* img_sig)
+ return false;
+ }
+ // Validate block1 (contains the signature chain used to sign block0)
+- if (!is_block1_valid(b0, b1, false, false))
++ if (!is_block1_valid(b0, &sig->b1_sig, false, false))
+ {
+ FWERROR("block1 failed authentication");
+ return false;
+diff --git a/pfr.hpp b/pfr.hpp
+index efe737a..94b7e45 100644
+--- a/pfr.hpp
++++ b/pfr.hpp
+@@ -62,7 +62,7 @@ constexpr size_t pfr_cpld_update_size = 1 * 1024 * 1024; // 1 MB
+ constexpr size_t pfr_pch_max_size = 24 * 1024 * 1024; // 24 MB
+ constexpr size_t pfr_bmc_max_size = 32 * 1024 * 1024; // 32 MB
+ constexpr size_t pfr_afm_max_size = 128 * 1024; // 128KB
+-constexpr size_t pfr_cancel_cert_size = 8;
++constexpr size_t pfr_cancel_cert_size = 128;
+ constexpr uint32_t pfr_max_key_id = 127;
+
+ constexpr uint32_t curve_secp256r1 = 0xc7b88c74;
+@@ -179,14 +179,6 @@ struct blk1
+ uint32_t rsvd[blk1_pad_size];
+ } __attribute__((packed));
+
+-struct b0b1_signature
+-{
+- blk0 b0;
+- blk1 b1;
+-} __attribute__((packed));
+-static_assert(sizeof(b0b1_signature) == 1024,
+- "block0 + block1 size is not 1024 bytes");
+-
+ constexpr size_t cancel_pad_size = 9;
+ struct cancel_cert
+ {
+@@ -200,11 +192,12 @@ struct cancel_cert
+
+ constexpr size_t cancel_sig_pad_size =
+ (blk0blk1_size - sizeof(cancel_cert) - sizeof(uint32_t) -
+- sizeof(key_entry) - sizeof(block0_sig_entry)) /
++ (3 * sizeof(uint32_t)) - sizeof(key_entry) - sizeof(block0_sig_entry)) /
+ sizeof(uint32_t);
+ struct cancel_sig
+ {
+ uint32_t magic;
++ uint32_t pad[3];
+ key_entry root_key;
+ block0_sig_entry block0_sig;
+ uint32_t rsvd[cancel_sig_pad_size];
+@@ -219,6 +212,20 @@ struct cancel_payload
+ uint32_t padding[cancel_payload_pad_size];
+ } __attribute__((packed));
+
++union sig_blk1
++{
++ blk1 b1;
++ cancel_sig cncl_b1;
++};
++
++struct b0b1_signature
++{
++ blk0 b0;
++ sig_blk1 b1_sig;
++} __attribute__((packed));
++static_assert(sizeof(b0b1_signature) == 1024,
++ "block0 + block1 size is not 1024 bytes");
++
+ constexpr uint32_t pfm_magic = 0x02b3ce1d;
+ constexpr uint32_t afm_magic = 0x8883ce1d;
+ constexpr size_t pfm_block_size = 128;
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/mtd-util.bb b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/mtd-util.bb
index c925c522d..b3472d765 100644
--- a/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/mtd-util.bb
+++ b/meta-openbmc-mods/meta-common/recipes-devtools/mtd-util/mtd-util.bb
@@ -8,6 +8,11 @@ SRC_URI = "git://git@github.com/Intel-BMC/mtd-util.git;protocol=ssh"
PV = "1.0+git${SRCPV}"
SRCREV = "708072b62a3cecb520eeaacac88b4f2c2e101fe4"
+SRC_URI += " \
+ file://0001-Firmware-update-fix-for-mis-aligned-sectors.patch \
+ file://0002-Add-fix-for-possible-freeing-of-mismatched-memory.patch \
+ file://0003-Fix-Key-Cancellation-Update-Capsule-Flow.patch \
+ "
S = "${WORKDIR}/git"