<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>T540p on dKade's notes</title><link>https://dkade.com/tags/t540p/</link><description>Recent content in T540p on dKade's notes</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>dkade@dkade.com (Daniel Loureiro)</managingEditor><webMaster>dkade@dkade.com (Daniel Loureiro)</webMaster><lastBuildDate>Fri, 21 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://dkade.com/tags/t540p/index.xml" rel="self" type="application/rss+xml"/><item><title>Removing a Lenovo ThinkPad T540p Supervisor Password with a CH341A Programmer</title><link>https://dkade.com/posts/lenovo_t540p_bios_unlock/</link><pubDate>Fri, 21 Aug 2026 00:00:00 +0000</pubDate><author>dkade@dkade.com (Daniel Loureiro)</author><guid>https://dkade.com/posts/lenovo_t540p_bios_unlock/</guid><description>A complete walkthrough of dumping, patching and re-signing a Lenovo T540p BIOS with a CH341A clip programmer to remove a &amp;#34;forgotten&amp;#34; supervisor password — including the Insyde H2O RSA signature pitfall</description><content:encoded><![CDATA[<p>My ThinkPad T540p ended up with a supervisor (BIOS) password after a Lenovo BIOS update&hellip; The machine still powered on, but the BIOS setup was locked and the hard drive was SVP-locked. Rather than replacing the mainboard or sending it to a repair shop, I and AI removed the password by dumping the BIOS flash chip, patching it, and re-flashing — using a cheap CH341A USB programmer and a SOIC-8 test clip.</p>
<p>I was following the process from <a href="https://www.badcaps.net/forum/troubleshooting-hardware-devices-and-electronics-theory/troubleshooting-laptops-tablets-and-mobile-devices/bios-requests-only/78215-lenovo-bios-auto-patcher-for-supervisor-password-removal">BADCAPS</a> but it turned out to be more involved than the usual &ldquo;run the auto-patcher and flash&rdquo; recipe, because this particular BIOS (GMET91WW, a 2021 build) enforces an <strong>RSA signature check</strong> on the patched image and refuses to boot otherwise. This post documents the full procedure that worked.</p>
<h2 id="the-hardware">The hardware</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Lenovo ThinkPad T540p
</span></span><span class="line"><span class="cl">└── BIOS flash: MX25L3273E  (4 MiB, SOIC-8 SPI NOR)
</span></span><span class="line"><span class="cl">        └── CH341A USB SPI programmer + SOIC-8 clip
</span></span></code></pre></div><p>The board connection CH341A and the SOIC-8 clip</p>
<p><img loading="lazy" src="/assets/board_connections.jpeg" type="" alt=""  /></p>
<p>The T540p is a Haswell-era machine, it carries an 8 MiB chip (MX25L6405 family) and the proper BIOS one 4 MiB MX25L3273E. Either way, the procedure is the same — you just need the right chip definition.</p>
<p>Chips on board, the BIOS is the right one</p>
<p><img loading="lazy" src="/assets/chips_board.jpeg" type="" alt=""  /></p>
<h2 id="the-plan">The plan</h2>
<ol>
<li>Dump the BIOS chip with <code>flashrom</code></li>
<li>Verify the dump (multiple reads, identical hashes)</li>
<li>Patch the dump with the Lenovo BIOS auto-patcher (injects two DXE drivers)</li>
<li><strong>Re-sign the modified BIOS</strong> so the machine actually boots it</li>
<li>Flash the signed image and trigger the unlock challenge</li>
<li>Restore the original BIOS</li>
</ol>
<p>Most guides stop at step 3 and 5. The signature step in between is what makes the difference on newer BIOS builds.</p>
<h2 id="dumping-the-chip">Dumping the chip</h2>
<p>A SOIC-8 clip sits on top of the chip without desoldering. The CH341A talks to it over SPI, and <code>flashrom</code> drives the whole thing:</p>
<p>Listing chips found</p>
<p><img loading="lazy" src="/assets/1_found_chips.png" type="" alt=""  /></p>
<p>Check if we identified the correct chip</p>
<p><img loading="lazy" src="/assets/2_check_chip.png" type="" alt=""  /></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi -r t540p_original.bin
</span></span></code></pre></div><p><img loading="lazy" src="/assets/3_dump_bios.png" type="" alt=""  /></p>
<p>The chip is small enough that the clip is finicky. Read it three times and confirm the hashes match before touching anything:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi -r t540p_original_b2.bin
</span></span><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi -r t540p_original_b3.bin
</span></span><span class="line"><span class="cl">sha256sum t540p_original*.bin
</span></span></code></pre></div><p>That verified dump is the single recovery path if anything goes wrong later — keep it somewhere safe.</p>
<h2 id="patching-the-bios">Patching the BIOS</h2>
<p>The Lenovo auto-patcher from the Badcaps forum community (<code>lenovo-bios-autopatcher</code>) does the heavy lifting: it replaces two DXE drivers in the firmware image (<code>BootOption.ffs</code> and <code>LenovoTranslateService.ffs</code>). On boot, the modified translation service presents a password challenge instead of a hard lock, which lets you generate a one-time unlock code.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="nb">cd</span> lenovo-bios-autopatcher
</span></span><span class="line"><span class="cl">./autopatch /path/to/t540p_original.bin
</span></span></code></pre></div><p>This produces <code>t540p_original_PATCHED.bin</code>. On its own, though, this image would not boot on my machine — it black-screened every time.</p>
<p><img loading="lazy" src="/assets/5_patch_bios.png" type="" alt=""  /></p>
<h2 id="the-black-screen-trap-insyde-h2o-rsa-signature">The black-screen trap: Insyde H2O RSA signature</h2>
<p>ThinkPads of this era use an Insyde H2O firmware. Starting around certain BIOS builds, the firmware carries an RSA-signed block called <code>TCPABIOS</code> that stores a SHA1 checksum for the main firmware volume. When the auto-patcher injects the two DXE drivers, the volume bytes change, the SHA1 no longer matches what <code>TCPABIOS</code> records, and the BIOS treats the image as tampered.</p>
<p>On older BIOS builds the machine just beeps five times and continues. On the newer GMET91WW build it <strong>hard-stops with a black screen</strong>.</p>
<p>This is where the AI just simplifies so much our life, if I had to do this manually it would have taken ages, lots of trial and error. So lets use AI for what it is really usefull I started this with a local model (Qwen3.6-35B-A3B) running on my Mac M1, it worked really well, but has there was a lot of trial and error even on AI side, I switched to deepseek-flash-v4 and it went fast and smooth.</p>
<p>The fix is to re-sign the modified image with a new RSA key and swap the corresponding public key into the image. The signature scheme is:</p>
<ul>
<li><code>TCPABIOS</code> block stores the volume checksum and is itself RSA-signed (<code>e = 3</code>, 1024-bit)</li>
<li>The signing input is <code>0x00 * 108 + SHA1(block_data)</code></li>
<li>The 128-byte signature follows a <code>FF FF 83</code> separator</li>
<li>The public key lives at a fixed offset in the same NVRAM region</li>
</ul>
<p>It wrote a small tool (<code>resign_bios.py</code>) that does all of this automatically:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">python3 resign_bios.py t540p_original_PATCHED.bin
</span></span></code></pre></div><p>This generates a fresh RSA keypair, updates the volume checksum in <code>TCPABIOS</code>, re-signs both <code>TCPABIOS</code> and <code>TCPABBLK</code>, and replaces the public key in the image. The output is <code>t540p_original_PATCHED_SIGNED.bin</code>, which boots cleanly.</p>
<h2 id="flashing-and-triggering-the-unlock">Flashing and triggering the unlock</h2>
<p>Flash the signed image:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi -w t540p_original_PATCHED_SIGNED.bin
</span></span></code></pre></div><p>Disconnect the programmer completely, then boot.</p>
<ol>
<li>At the Lenovo splash, press <strong>F1</strong> to enter BIOS setup</li>
<li>At the supervisor password prompt, type any character and press <strong>Enter</strong></li>
<li>Reboot, enter BIOS again, type the same character</li>
<li>The screen shows a <strong>Hardware ID</strong></li>
<li>Press <strong>Enter</strong>, then press <strong>Spacebar twice</strong></li>
</ol>
<p>On many guides, this is where an unlock code appears. On GMET91WW the machine instead reported <strong>&ldquo;TPM written&rdquo;</strong> — meaning the password was cleared directly without issuing a code. Either way, write down whatever the BIOS displays.</p>
<h2 id="restoring-the-original-bios">Restoring the original BIOS</h2>
<p>Once the unlock routine is done, flash the verified original dump back:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi -w t540p_original.bin
</span></span><span class="line"><span class="cl">sudo flashrom -c <span class="s2">&#34;MX25L3233F/MX25L3273E&#34;</span> -p ch341a_spi --verify t540p_original.bin
</span></span></code></pre></div><p>Then power on. If an unlock code was issued, enter BIOS and press <strong>F9</strong> to restore factory defaults, entering the code when prompted. On my unit the password was simply gone after the &ldquo;TPM written&rdquo; pass.</p>
<p><img loading="lazy" src="/assets/6_restore_original.png" type="" alt=""  /></p>
<h2 id="gotchas">Gotchas</h2>
<ul>
<li><strong>The clip is the weak link.</strong> Erase failures at a fixed sector almost always mean marginal contact on one of the address lines — reads still work, but writes fail. Reseat the clip firmly and clean the pads.</li>
<li><strong>Chip auto-detection lies.</strong> Running <code>flashrom</code> without <code>-c</code> sometimes reported an 8 MiB MX25L6405-family chip (a neighbouring part or marginal contact). Always pass <code>-c &quot;MX25L3233F/MX25L3273E&quot;</code> explicitly.</li>
<li><strong>The NVRAM volume patch is not needed here.</strong> The auto-patcher ships a 1 MiB NVRAM volume file; this BIOS uses a 408 KiB NVRAM, so that step correctly reports &ldquo;not found&rdquo;. Leave the NVRAM alone — the DXE injection plus re-sign is what does the work.</li>
<li><strong>Backup first.</strong> The original dump is the only way back. I kept three verified copies before patching.</li>
</ul>
<h2 id="summary">Summary</h2>
<p>Removing a forgotten supervisor password from a ThinkPad T540p is very doable with a CH341A programmer and a SOIC-8 clip.</p>
<p>The straightforward recipe is: dump → verify → auto-patch → flash → unlock → restore. On newer BIOS builds you additionally have to re-sign the patched image, because the Insyde H2O firmware verifies an RSA signature over the firmware volumes. Once I added that step, the machine booted, presented the unlock challenge, and the password was gone in one pass.</p>
<p>The whole procedure, including the re-signing tool and step-by-step workflow, is available in my <a href="https://codeberg.org/dkade/lenovo-bios-unlock"><code>lenovo-bios-unlock</code></a> repository.</p>
<hr>
<p><em>Disclaimer: This work was done purely for research and to recover from a problem caused by an official Lenovo BIOS update, on my own hardware. It is not intended to facilitate bypassing security on equipment you do not own, and it should not be used for any illegal purpose.</em></p>
<p><em>Disclaimer: I use AI as a productivity tool. For a senior engineer, AI is incredibly powerful as one can focus on the solution design and conceptualization and leave the boring part that is implementation to the AI.</em></p>
]]></content:encoded></item></channel></rss>