Skip to content

Instantly share code, notes, and snippets.

@achow101
Last active March 31, 2024 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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 https://manager.api.live.ledger.com/api/mcu_versions. 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 https://manager.api.live.ledger.com/api/get_device_version. In the POST body, send:
provider:<provider>
target_id:<targetId>

From the response, extract id.

  1. Using HTTP POST, get information about the current firmware version from https://manager.api.live.ledger.com/api/get_firmware_version. In the POST body:
device_version:<id>
version_name:<version>
provider:<provider>

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

  1. Using HTTP POST, get the information about the latest firmware version from https://manager.api.live.ledger.com/api/get_latest_firmware?livecommonversion=7.10.0-959cfdaf (note that for some reason the URL parameter is required). In the POST Body:
current_se_firmware_final_version:<id2>
device_version:<id>
provider:<provider>

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 https://manager.api.live.ledger.com/api/firmware_final_versions/<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://api.ledgerwallet.com/update/install?targetId=<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 https://manager.api.live.ledger.com/api/mcu_versions/<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://api.ledgerwallet.com/update/mcu?targetId=<targetId>&version=<new_mcu_name>.

  6. Lastly, install the final firmware using the websockets method with the URL wss://api.ledgerwallet.com/update/install?targetId=<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: https://gist.github.com/achow101/16df88551b4e305eb01b4618f6d24239

Abbreviations

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

2024 version (for now only supports genuine check and installing the Bitcoin app, but could be made to upgrade the firmware too): https://github.com/darosior/ledger_installer. 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