GoPro HEROBus 2 Research

Posted by Mark Kirschenbaum on


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.

The Meat

FOR SECURITY RESEARCH / Interoperability with our products.  

The good news is the HEROBus is alive and well on the GoPro HERO5/6. 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
  • ATMEL ATSHA204A - Authentication Chip <- Protected!
  • 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

I2C Over USB-C

GoPro HERO5 USB Pinout

Pin Definition for orientation A. Flip for Reversed. Adapter has muxes. For keyed devices such as the Karma A1 is oriented towards the bottom.

Pair Usage
A2 i2c Clock
A3 i2c Data
A5 CC1 

IRQ / REQ for herobus /D+


A7 48khz sample rate H5 sourced
GPIO others / D-
B5 VCONN 3.8v

I2S audio

B7 I2S 3.06Mhz clock out

VBUS: 5V with external power source. negotiating taken care by CCG2.
GND: All tied with frame passthrough



Usage i2c Address
ATSHA204A Crypto 0xC4
CX20812  A2D on Garter 0x76
Atmel D21 MCU Encryption micro on GoPro HERO5 0x24
AS3716 PMIC Power Monitor 0x80
Generic BP Generic BP 0xC0
ATSAMG55 Multicamera/spherical via ATMEL D21
Colorado3  USB-C to HDMI converter 0x1E
lp5562 led driver 0x60
PI3USB9281? BC2.1 Charger detection



Cypress EX-PD CCG2

The EZ-PD's job is to inform the GoPro HERO5/6 what power supply is connected and which type of accessory exists out on the bus. It negotiates current draw / source as well as notifies the GoPro Camera when external power is applied. 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
  • SVID1 (Cypress:04B4) Alternative mode index 1 = Flash Alternative Mode

GoPro HeroBus PD settings

Possible values for Product ID are 

GoPro Inc's Device Code Name  Usage Product Id
Garter Pro 3.5mm Adapter 0x2
Green Mamba  Some display port item 0x3
Parakeet / Kirkwood Karma
Macaw Some display port item 0x5
Generic Accessory

Generic BacPac

Debug Cable USB-CDC for accessing rtos or linux console 0x7

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.

Unfortunately, all devices require the encryption key. Fortunately, they're all the same, including the batteries and drone battery. 

Atmel ATSHA204A Encryption

The GoPro HERO5's encryption microcontroller (MCU) sends a challenge to the ATSHA204 device to ensure the accessory is authentic. We should note the encryption microcontroller is a SAM D21 code protected with encrypted updates. 


The MCU creates a 256bit FIXED-CHALLENGE and a 256bit session based MCU-ID. It should be noted that the session based MCU-ID changes slightly upon reset. We haven't explored the expiration of the challenge, but it can easily be changed during upgrades or per device.

The ATSHA204A contains an encrypted 256bit key called data.SLOT1. The configured ATSHA204A contains 11 other 'issecret' slots which can be moved to in case one gets compromised.

The steps are: 

  1. Loads a "NONCE" from the "FIXED-CHALLENGE". 
  2. Generate a digest GenDig with the SHA256(data.SLOT1[32] + staticdata + NONCE[32])
  3. Create a MAC from the SHA256(DIGEST[32] + MCU-ID[32]  + staticdata).
  4. Compare digest in MCU's encrypted memory 

ATSHA204 transaction details

  1. ATSHA204 NONCE ::  Command: 0x16, Param1: 3, Param2: 0 
  2. ATSHA204 GENDIG :: Command: 0x15, Param1: 2, Param2: 1 
  3. ATSHA204 MAC       :: Command: 0x08, Param1: 6 Param2: 0 

Psuedo Code (v1.50)

NONCE = fixed-challenge


// GenDig: message = data.SLOT1 + OpCode + Param1 + Param2 + SN[8] + SN[0:1] + padding: x 25 + NONCE


message = data.SLOT1 + 0x15 + 0x02 + 0x01 + 0xC6 + 0x1 + 0x23 + {'0x0'*25} + NONCE


DIGEST = SHA256(message)


//  MAC: full_challenge = digest+ challenge + opcode + mode + param1+ param2 + zeros x 8 + zeros x 3 + SN[8] + zeros x 4 + SN[0:1] + zeros x 2


full_challenge[] = digest[32] + MCU-ID[32] + 08h + 06h + 00h + 00h + {'0x00'*8} + {'0x00'*3} + 0xC6 + {'0x00'*4} + {'0x01,0x23} + {'0x00'*2}


RESULT = SHA256(full_challenge)


Notes: Entropy comes from MCU-ID which has 3 bytes of randomness per boot. Replay attack is possible per camera with 4GB of data. 


Output of the MAC on the below test sequence. 

0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF

0xC4, 0x64, 0xf3, 0x9c, 0x43, 0x02, 0x7c, 0xde, 
0x19, 0x76, 0x35, 0x61, 0x71, 0xed, 0xc3, 0xc6, 
0x37, 0x4a, 0x17, 0x9b, 0xDA, 0x70, 0x1a, 0x07, 
0xcd, 0xa1, 0x8f, 0xe1, 0x2d, 0xa5, 0x47, 0xf2, 

   0xc0, 0x2e <-- CRC


For those looking to explore here is the output from a read of our STSHA204A

wakeup passed
Dev Rev via cmd: 00 09 60 00

Serial number: 01 23 XX XX XX XX XX XX C6 <- Not EE like spec
Revision number: 00 09 04 00
I2C enabled; Address: 0xC4
OTP mode: consumption
Selector: can be updated only if it is 0.
User Extra byte: 00
Selector byte: 00

Data and OTP zones are locked!

Config zone is locked!

Configurations of slots:

Slot:0 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:1 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:2 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:3 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:4 ReadKey:F CheckOnly:1 SingleUse:1 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:5 ReadKey:F CheckOnly:1 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:6 ReadKey:F CheckOnly:1 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:7 ReadKey:F CheckOnly:1 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8
  UseFlag:FF UpdateCount:00

Slot:8 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:0
  WriteKey:F WriteConfig:8
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00

Slot:9 ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:0
  WriteKey:4 WriteConfig:C
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00

Slot:A ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:0
WriteKey:5 WriteConfig:C
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00

Slot:B ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:0
WriteKey:F WriteConfig:0
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00

Slot:C ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8

Slot:D ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:D WriteConfig:2

Slot:E ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:6 WriteConfig:C

Slot:F ReadKey:F CheckOnly:0 SingleUse:0 EncryptRead:0 IsSecret:1
  WriteKey:F WriteConfig:8


Next Steps

Brute force encryption will take the rest of all our lives to determine so the next step is to target the D21 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. 

GoPro HERO5 Black Xray Hack

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). 

GoPro HERO5 Debug Header

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



1 MCU PA16 via 1.5k - MCU Booted
3 RTC Battery
11 SYS RESET MCU PA24 direct
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
powerdown [option]
prodmodel [set value]
auth battery | bacpac
battery [temp|cap|volt|cur]
fake_accessory [none|parakeet|garter|green_mamba| macaw| dpr ]
readsec <-- Not listed

t frw mcu fwupdate gt_set_mode usb
t frw mcu fwupdate gt_set_mode aud

NAND Probing

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. 

  1. Write a fuzzer to test all i2c slots on the mcu. See if a test mode exists.
  2. 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)
  3. An offshoot of the above is see if memreads work within the bootloader.
  4. 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. 
  5. Pass the original update binaries through known secure Atmel bootloader and see if the non _key2 versions are the default key.
  6. Completely circumvent the MCU or re-write the mcu code without security checks.
  7. Patch all future FW with the 1.50 or 1.02 Australia / Margaret River binaries. Simple but easily countered. (For Batteries Only)
  8. 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.
  9. 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.
  10. 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. 

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.

Share this post

← Older Post Newer Post →

Hypoxic Products