Menu
Cart

GoPro HEROBus 2 Research

Posted by Mark Kirschenbaum on

Introduction

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

Pair Usage
A2 i2c Clock
A3 i2c Data
A5 CC1 
A6 IRQ / REQ for herobus /D+
A7 48khz sample rate H5 sourced
GPIO others / D-
B5 VCONN 3.8v
B6

I2S audio
GPIO-IN
D+ -USB/MTP

B7 I2S 3.06Mhz clock out
D- -USB/MTP

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

Addresses

Device 

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

0x4a

 

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
GCCB over USB-CDC
0x4
Macaw Some display port item 0x5
Generic Accessory


Generic BacPac

0x1001
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. 

Setup

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. 

Tests

Output of the MAC on the below test sequence. 

Challenge
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

Response
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

Scan

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

LastKeyUse: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

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

Pin

Use

1 MCU PA16 via 1.5k - MCU Booted
2
3 RTC Battery
4
5
6
7
8
9 GND
10 MCU RESET
11 SYS RESET MCU PA24 direct
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 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