Skip to content

Instantly share code, notes, and snippets.

Last active March 31, 2024 22:35
Show Gist options
  • Save achow101/3604bf50aa622b33ad2160cc77075a8c to your computer and use it in GitHub Desktop.
Save achow101/3604bf50aa622b33ad2160cc77075a8c to your computer and use it in GitHub Desktop.

Notes on updating Ledger Nano S Firmware

Update process steps

  1. Read device information from device. Get the SE version (we will denote this as se_version), MCU version (we will denote this as mcu_version), version, targetId, and provider
  2. Using HTTP GET, a list of MCU version information from Find the MCU JSON object for your mcu_version, the name field will match the mcu_version from your device. Extract the id (we will denote this as mcu_id).
  3. Using HTTP POST, get information from In the POST body, send:

From the response, extract id.

  1. Using HTTP POST, get information about the current firmware version from In the POST body:

From the response, extract id, we will denote this as id2.

  1. Using HTTP POST, get the information about the latest firmware version from (note that for some reason the URL parameter is required). In the POST Body:

From the response, extract next_se_firmware_final_version (denoted as new_id), firmware (we will denote as firmware_osu), firmware_key (we will denote as firmware_key_osu), and perso (we will denote as perso_osu).

  1. Using HTTP GET, get the information for the latest firmware version from<new_id>. From the response, extract mcu_versions, firmware, firmware_key, and perso.

  2. Install the OSU firmware by connecting to the Websocket Server wss://<targetId>&firmware=<firmware_osu>&firmwareKey=<firmware_key_osu>&perso=<perso_osu>. Extract the data from each server response as a hex encoded APDU command and forward those to the device. From the device, receive APDU responses, wrap them in a similar way to how the server sent data, and return to the server the APDU responses.

  3. If mcu_id is in mcu_versions, skip to step 10. Otherwise, unplug the device and replug it holding the left button in order to start it in bootloader mode.

  4. Extract the first item of mcu_versions (we denote this item as new_mcu) and get the MCU version information using HTTP GET from<new_mcu>. From the response, extract the name which we will denote as new_mcu_name

  5. Install the MCU using the same websockets thing done earlier except with the URL wss://<targetId>&version=<new_mcu_name>.

  6. Lastly, install the final firmware using the websockets method with the URL wss://<targetId>&firmware=<firmware>&firmwareKey=<firmware_key>&perso=<perso>

Python updater script

An all-in-one Python 3 script that does everything and updates a ledger:


  • OSU = OS Update application
  • SE = Secure Element
  • MCU = MicroController Unit
Copy link

2024 version (for now only supports genuine check and installing the Bitcoin app, but could be made to upgrade the firmware too): Thanks for your investigation it was helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment