GoPro HEROBus™ 2 Research
Posted by Mark Kirschenbaum on
FOR SECURITY RESEARCH / Interoperability with our products.
The good news is the HEROBus™ is alive and well on the GoPro HERO [5-8]. The bad news is its extremely locked down and needs a BGA part and a crypto key to make it work.
The needed parts are:
- Cypress EZ-PD CCG2 - USB type-C Controller - Accessory
- CYPD2104-20FNXI 20 pin $1.79
- CYPD2122-20FNXI 20 pin $1.98
- ATMEL ATSHA204A - Authentication Chip <- Protected!
- ATSHA204A-XHDA-T I2C version TSSOP $0.55
- The HEROBus™ i2c Slave or Vendor commands on MTP via USB
- Generic HEROBus™ Microcontroller for developer program
- Atmel Sam G22 for spherical camera solutions
- CX20812 for A2D solutions (i2c)
- Generic Accessory - Third Party GoPro Developer Program (i2c)
- Karma Grip / Karma - MTP / CDC via USB
HEROBus™ USB-C Pinout
Here are the Mux tables. Aud_SEL is set via i2c for the garter devices. It allows USB's D+/D- to pass through from the USB-C port on the audio adapter.
The Mux gets set via the
MUX = 0; AUD_SEL=1 (Mic Enabled)
Pair | Usage |
A2 | i2c SCL |
A3 | i2c SDA |
A5 | CC1 |
A6 |
IRQ / REQ for herobus™ |
A7 | 48khz sample rate cam sourced |
B5 | VCONN 3.8v |
B6 |
I2S Data |
B7 | I2S Clk 3.06Mhz clock out |
MUX = 0; AUD_SEL=0
Pair | Usage |
A2 | i2c SCL |
A3 | i2c SDA |
A5 | CC1 |
A6 |
IRQ / REQ for herobus™
|
A7 | 48khz sample rate cam sourced |
B5 | VCONN 3.8v |
B6 |
D+ |
B7 | D- |
MUX =1; AUD_SEL=0
Pair | Usage |
B2 | i2c SCL |
B3 | i2c SDA |
A5 | CC1 |
B6 |
IRQ / REQ for herobus™
|
B7 | 48khz sample rate cam sourced |
B5 | VCONN 3.8v |
A6 |
D+ |
A7 | D- |
MUX = 1; AUD_SEL=1
Pair | Usage |
B2 | i2c SCL |
B3 | i2c SDA |
A5 | CC1 |
B6 |
IRQ / REQ for herobus™
|
B7 | 48khz sample rate cam sourced |
B5 | VCONN 3.8v |
A6 |
I2S Data |
A7 | I2S Clk 3.06Mhz clock out |
VBUS: 5V with external power source. negotiating taken care by CCG2.
GND: All tied with frame passthrough
Addresses
Device |
Usage | i2c Address (shifted <<1) [pure] |
ATSHA204A | Crypto | 0xC4 [0x62] |
CX20812 | A2D on Garter | 0x76 |
CX20811 | A2D on Borg | [0x3B] |
Atmel D21 MCU | Encryption micro on GoPro HERO5 | 0x24 [0x12] |
AS3716 PMIC | Power Monitor | 0x80 |
PMIC | Power Management IC H7 | 0x48 [0x24] |
Generic BP | Generic BP | 0xC0 [0x60] |
Colorado3 | USB-C to HDMI converter | 0x1E |
lp5562 | led driver | 0x60 |
PI3USB9281 | BC2.1 Charger detection Comm via i2c to CCG2 on Borg |
0x4a
|
Cypress CCG | Borg registers on USB-C PD chip | [0x77] |
FUSB302 | CC Driver on GoPro | |
Borg EEPROM | Eeprom on Borg device | [0x54] |
Cypress EX-PD CCG2
The EZ-PD's job is to inform the GoPro HERO[5-8] what accessory is on the USB-C bus. This is a super-set of the eeprom of the old GoPro HEROBus™. Cypress makes developing with these devices fairly straight forward.
The Parameters that we care about are:
- USB Vendor ID 0x2672 (GoPro Inc.)
- Product ID: 2 - Garter (3.5mm Pro) See table for other devices
- BCD Device 1
- FW version 1
- HW version 1
- SVID0 (GoPro::0x2672) Alternative mode index 0x10 or 0x12 (parakeet)
- SVID1 (Cypress:04B4) Alternative mode index 1 = Flash Alternative Mode
- Garter / Borg set's Mux state via Structured VDM 0x26728030 0x1 vs 0x26728030 0x0
Product IDs
GoPro Inc's Device Code Name | Usage | Product Id |
Garter | Pro 3.5mm Adapter | 0x2 |
Green Mamba | Some display port item. Defunct. | 0x3 |
Parakeet / Kirkwood | USB-MTP command interface for Karma products. Unlocks array of USB commands and tunnels | 0x4 |
Macaw | Superspeed charger | 0x5 |
Generic Accessory |
|
0x1001 |
Debug Cable | USB-CDC for accessing rtos or linux console. Defunct on GoPro HERO 8 | 0x7 |
Media Mod | Display port & Audio Adapter - Dec 2019 | 0x8 |
Changing USB Product Ids
It's possible to change the product id of an existing accessory and re-purpose it for your own needs. There is only one set of crypto keys for every accessory so any device can be switched to any other. Using Cypress's MiniProg3 we were able to read/modify/write a device and change it to a different accessory. Check out our GitHub Repo (CYPD2_log2hex) for this code. For completeness here is the CCG2 programming spec.
Garter's CCG GPIO C3 and I'm assuming that for the development program are tied to the dongle's mux's. Garter can be self powered via VCONN.
Unfortunately, all devices require the encryption key. Fortunately, they're all the same, including the batteries and drone battery.
Atmel ATSHA204A Encryption
Moved to a new post
Anti Cloning Technology on the GoPro HEROBUS
Next Steps
Brute force encryption will take the rest of all our lives to determine so the next step is to target the ATSAMD21 MCU. The encrypted updates are part of the firmware ROM section but micro's are a lot more vulnerable. Hopefully we will not have to de-cap and fib one of these bad boys, but at least I have access if necessary.
Above is an X-Ray of the GoPro HERO5 used to find the SWD lines of the Crypto MCU. Although we've confirmed it code protected, there are definitely corner cases and internal TMODs with most debugger logic (my old specialty).
You can connect to the pogo pins or the debug header by adding a FPC cable.
MCU runs at 1.8v, UART is 2.2v
Pin |
Use |
1 | 1v8 |
2 | |
3 | RTC Battery |
4 | |
5 | |
6 | |
7 | |
8 | GND |
9 | |
10 | MCU RESET |
11 | MCU24 XRES PMIC |
12 | MCU SWDIO |
13 | MCU SWCLK |
14 | RTOS TX |
15 | RTOS RX |
16 | Linux TX |
17 | Linux RX |
MCU i2c Commands
Here is the raw commands to the mcu i2c address Write 0x24 Read 0x25
R:00 1 mcu_functions__getreg
R:02 3 mcu_get_bldver_
R:05 3 mcu_get_appver_
W:08 (data:1) mcu_bootbld_
W:08 (data:2) mcu_bootapp_
R:09 1 mcu_bootstat_
R:0E 1 mcu_i2c_mux_ctrl_get__
W:0E (1or0) mcu_i2c_mux_ctrl_set_
W:0F mcu_powerdown_ value: 1 - poweroff, 2- wakeonlan?, 3 - reset, 4 -standby
R:10 0x10 mcu_get_uniqueid_
R:0x12 (1000d) mcu_memread
W:0x20 1 mcu_accessory_check_
W:0x21 (data:1) mcu_ferase_
W:0x21 (data:2) mcu_fwrite_
W:0x21 (data:4) mcu_fiforst_
W:0x21 (data:F0) ReadSecurtiy
W:0x21 (data:F1) ReadSecurtiy
0x22 0x1 mcu_fifo_stat_
R:0x23 0x80 mcu_readsec
0x30 1 mcu_get_usb_status_
0x31 1 mcu_battery_cap_
0x3c 2 mcu_battery_volt_
0x3e 2 mcu_battery_cur_
0x40 1 mcu_get_bc1.2_chager_connected_
0x41 1 mcu_battery_temps_
R:0x43 1 mcu_get_mode_
W:0x43 (val) mcu_change_garter_codec_usb_
R:0x44 (1000) mcu_read_fusb
0x46 1 mcu_get_state
W:0x4A 2 mcu_i2c_write_
W:0x4A 3 mcu_i2c_read_
W:0x4A 4 mcu_i2c_read_after_write
0x50 0x1 mcu_getwakeup_reason
0x54 1 IRQ_status
0x60 4 mcu_get_hbver_
0x64 4 mcu_get_product_model_
W:0x64 4 mcu_set_product_model_
0x68 4 mcu_get_camfw_ver_
0x6c 4 mcu_get_capabilities_
0x74 2 mcu_get_prodid_
0x88 1 mcu_get_hbstat_
0x90 0x20 mcu_fixed_challange_
0xB0 1 mcu_get_shmem_lockstate
0xB3 1 mcu_get_shmem_readlen
0xB3 x mcu_atmsamg55_shmem_read
0xF2 1 mcu_get_cc_info_
W:0xF4 (0-bat,1-bacpac) mcu_authenticate_
0xF5 1 mcu_get_authenticate_
Test commands
t gpdrv mcu
pkton
pktoff
regver
bldver
appver
uniqueid
bootbld
bootapp
bootstat
ferase
fwrite
fiforst
fifold
fixed_challenge
trstat
wakeup
wifion
wifioff
powerdown [option]
bton
btoff
hbver
prodmodel [set value]
camfwver
capabilities
auth battery | bacpac
battery [temp|cap|volt|cur]
i2cwrite
i2cread
fusb
memread
send_cam_ready
get_irq_counts
shmempkt_on
shmempkt_off
fake_accessory [none|parakeet|garter|green_mamba| macaw| dpr ]
readsec <-- Not listedt frw mcu fwupdate gt_set_mode usb
t frw mcu fwupdate gt_set_mode aud
NAND Probing (Exhausted)
The NAND is 4GB wide therefore it was possible that they write balanced the array during updates thus leaving the production code up on the device. We assume, due to the lack of the MCU SWD pogo pins, the initial programming is done with an unprotected version to the ATMEL i2c bootloader. Unfortunately the production ROMFS is overwritten with the HD5 1.02 update.
None-the-less, always using the same NAND pages with no "bad block support" is super poor design and can lead to bricked gopros as the product ages.
Possible Next Steps
Not necessary in order.
- Write a fuzzer to test all i2c slots on the mcu. See if a test mode exists.
- Make the RTOS fail the update of the MCU. See if secread or memory read works. play with timings and cause an external reset mid page. May cause run away since jump to bootloader will fail. There may be a "stay-in-bootloader-pin" but doubt this possibility and finding the pin. (Do not try)
- An offshoot of the above is see if memreads work within the bootloader.
- Inject glitches into the MCU's VDDANA to force improper loading of the SSD bit upon bootup. Test on development board first. Perhaps use SWD since BOD33 is ignored with a probe connected according to the datasheet.
- Pass the original update binaries through known secure Atmel bootloader and see if the non _key2 versions are the default key.
- Completely circumvent the MCU or re-write the mcu code without security checks.
- Patch all future FW with the 1.50 or 1.02 Australia / Margaret River binaries. Simple but easily countered. (For Batteries Only)
- Since we know the algorithm and fairly certain the ATSHA204 library was used within the D21 we can build a side band attack. Create a SAM D21 with the ATSHA204 code base. Next create a power or RF mapping of the GENDIG function (generate digest) on our board. Locate and map the hash generation on the GoPro HERO5. Since the first data to hit the MAC is slot1 we can empirically map each byte going through the MAC. One byte at a time we should be able to recreate the key. Worse case is we have a histogram of bit changes per round.
- Circumvent the MCU's logic by patching the host's firmware. Right now we don't see a way of enabling VCONN and allowing i2c to pass through without the MCU connecting properly to an "Accessory." If you're a host, you can simply use undocumented USB commands to control the camera.
- Hijack an accessory and make it your own solution. <-- This is what we have done for our own testing.
If security is broken, I'll inform GoPro before posting online, but then again I don't hear back from them when I sent send bugs so who knows if this will get action.
Post Script
For the past 10 years people like Hypoxic have created solutions incorporating GoPro Cameras into applications never before dreamed about from Nick Woodman. The user base has transformed these cameras from "toys" into powerful cinematic tools.
Products like mounts for drones, the first selfie sticks, and even bullet time arrays weren't dreamt by GoPro, they were made by their customers. All of these, and thousands others, were made by adventurers to immerse the viewer into the action.
GoPro Inc. may not realize it, but it was the MAKER community which transformed it into a household name. GoPro customers are creators in all sense of the word. With the advent of the GoPro HERO5/6 and their horrible "Developer Program," the maker community got abandoned. Everything is now locked down, GoPro Inc's stock has irrecoverably tanked, and now, as everyone within GoPro has realized, the adventure is gone. Makers have moved to other platforms such as the Yi, Sony, and even the Raspberry Pi which enable innovation. Even Sony has realized the maker movement is mutualistic to their success and opened up their camera API.
Hypoxic used to work tightly with GoPro Inc. We would feed them vulnerabilities and let them know when they accidentally disclosed products within their software. After seeing the mess they've built into the HERO5/6 it has become our mission to open these cameras up to the community.
With GoPro Inc failing miserably, perhaps they will finally open it up and remove their idiotic encryption keys.
Nick Woodman, locking down this interface is detrimental to your business. I urge your team to open it up and let the community create solutions for your hardware.
LEGAL: This product and/or service is not affiliated with, endorsed by, or in any way associated with GoPro Inc. or its products and services. GoPro, HERO, and their respective logos are trademarks or registered trademarks of GoPro, Inc. HEROBUS and BACPAC are trademarks of GoPro Inc.