What changed, and why it matters
This commit adds a new user-facing 'Nuke Device' feature to the COLDCARD hardware wallet. It lets the owner deliberately wipe the seed and permanently brick the secure element, rendering the device unusable. The change also removes some unreachable cleanup code from the existing seed-clearing routine. There is no evidence in the commit of a hidden or malicious trigger; it appears to be an intentional, user-initiated self-destruct function.
Treat as a feature addition rather than a vulnerability. Review whether 'Nuke Device' should require PIN/seed verification or a longer confirmation chain to reduce risk of accidental or coerced use. Verify that `callgate.fast_brick()` behaves exactly as documented and cannot be triggered by other code paths.
Security signals we found
New destructive capability added: permanent bricking of secure element
Requires two explicit user confirmations with scary wording
Removes unreachable reboot code after fast_wipe, reducing attack surface slightly
No authentication gating beyond existing menu access controls visible in diff
Feature is exposed in an advanced menu, not hidden
Evidence from the diff
The patch introduces nuke_device() in shared/actions.py, wired into the ‘Advanced/Tools’ menu via shared/flow.py. It shows two confirmation prompts and then calls callgate.fast_brick(), which is described as making the secure element’s contents forever inaccessible. In shared/seed.py, the clear_seed() function has its post-fast_wipe(True) dead code removed (utime.sleep(1) and machine.reset()), because fast_wipe is marked ‘# NOT REACHED’. The changelog frames this as a new feature, not a security fix.
Changed components
shared/actions.pyshared/flow.pyshared/seed.pyCOLDCARD firmware user interface / menu systemsecure element / callgate bricking routineInspect captured patch +16 / −6
diff --git a/releases/Next-ChangeLog.md b/releases/Next-ChangeLog.md
index 060520e..294622e 100644
--- a/releases/Next-ChangeLog.md
+++ b/releases/Next-ChangeLog.md
@@ -10,6 +10,7 @@ This lists the new changes that have not yet been published in a normal release.
transaction to enter Transaction Explorer.
- New Feature: Support for v3 transactions
- New Feature: Send keystrokes with all derived BIP-85 secrets
+- New Feature: Nuke Device. Purge device data and make it an e-waste.
- Enhancement: CCC allow to reset block height
- Bugfix: Replace `/` with `-` in exported file names of multisig wallet export artifacts
diff --git a/shared/actions.py b/shared/actions.py
index 1c035c1..c2da101 100644
--- a/shared/actions.py
+++ b/shared/actions.py
@@ -1539,6 +1539,20 @@ Does not affect MicroSD card, if any.''', confirm_key="4"):
from files import wipe_flash_filesystem
wipe_flash_filesystem()
+async def nuke_device(*a):
+ if not await ux_confirm("Wipe Seed & Brick device? This will wipe the seed, purge"
+ "all related settings, and makes ewaste from this device."):
+ return
+
+ if not await ux_confirm("Brick device?\n\nBy design, there is no way to reset or recover"
+ " the secure element, and its contents become forever inaccessible.",
+ confirm_key="1"):
+ return
+
+ import callgate
+ callgate.fast_brick()
+ # NOT REACHED
+
async def wipe_vdisk(*A):
if not await ux_confirm('''\
Erases and reformats shared RAM disk. This is a secure erase that blanks every byte.'''):
diff --git a/shared/flow.py b/shared/flow.py
index 45392d3..8aae273 100644
--- a/shared/flow.py
+++ b/shared/flow.py
@@ -365,6 +365,7 @@ correctly- crafted transactions signed on Testnet could be broadcast on Mainnet.
MenuItem('MCU Key Slots', f=show_mcu_keys_left),
MenuItem('Bless Firmware', f=bless_flash), # no need for this anymore?
MenuItem("Wipe LFS", f=wipe_filesystem), # kills other-seed settings, HSM stuff, addr cache
+ MenuItem("Nuke Device", f=nuke_device),
]
BackupStuffMenu = [
diff --git a/shared/seed.py b/shared/seed.py
index d1667e2..1b1426a 100644
--- a/shared/seed.py
+++ b/shared/seed.py
@@ -815,12 +815,6 @@ def clear_seed():
callgate.fast_wipe(True)
# NOT REACHED
- utime.sleep(1)
-
- # security: need to reboot to really be sure to clear the secrets from main memory.
- from machine import reset
- reset()
-
async def word_quiz(words, limited=None, title='Word %d is?'):
# Perform a test, to check they wrote them down
# Return X if they cancel early.
Why this scored 33/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.