Skip to content

Instantly share code, notes, and snippets.

@jj1bdx
Forked from rrottmann/atecc608a-i2c-notes.md
Created January 10, 2024 06:16
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 jj1bdx/ad2dedcbacb9198bd4e1667008e9dbe5 to your computer and use it in GitHub Desktop.
Save jj1bdx/ad2dedcbacb9198bd4e1667008e9dbe5 to your computer and use it in GitHub Desktop.
ATECC608A I2C Notes

ATECC608A I2C Notes

Here be dragons

WARNING: AS THE DEVICE CAN BE CONFIGURED ONLY ONCE, PLEASE BE WARNED THAT YOU MIGHT EASILY BRICK THE CHIP! USE AT YOUR OWN RISK!

Circuit

Please make sure to use proper circuit for ATECC608A with pullups and decoupling capacitors when hooked to a MCU. A Raspberry Pi might also work without external components just using internal pullups.

Defaults

Besides SPI only ATECC608A, there are different versions available. As a hobbyist the sourcing might be difficult and it is not always clear which device you will get (e.g. from China vendors). Overall default is 0xC0 programmed code which will translate to 0x60. Besides that, you might have gotten an ATECC508A chip listening to the same addresses but with less features. The chips are not marked so you have to trust the vendor. It is somewhat confusing that the I2C address is being read from a configuration byte. Cryptoauthlib reads embedded configuration blobs during initialization. So when there is 0xC0 in the configuration byte 16, it expects the ATECC608A at 0x60. This needs to be changed when you want to interact with a device that has a different I2C address. Then there are also ATECC608B which might introduce more changes. The following list is not complete:

Device Default 7-bit I2C Address 8-bit Programmed I2C Address Value
ATECC608A-TNGTLS 0x35 0x6A
ATECC608A-TFLXTLS 0x36 x6C
ATECC608A-MAHDA 0x60 0xC0

Personalization with sample config

The following procedure can be used to personalize an ATECC608A for personal experiments with a sample config. This is now my goto procedure for testing purposes.

# ubuntu 20.04
apt update
apt install -y i2c-tools python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
mkdir ~/git
cd ~/git
git clone https://github.com/MicrochipTech/cryptoauthtools.git
cd cryptauthrools/python/examples
python3 -m venv venv
source venv/bin/activate
pip3 install cryptoauthlib==20190517 --no-cache-dir
pip3 install -r requirements.txt
# needed as i use a pc with only one i2c bus:
cat > config.patch <<"PATCH"
git diff config.py
diff --git a/python/examples/config.py b/python/examples/config.py
index 9579cf4..6d13f37 100644
--- a/python/examples/config.py
+++ b/python/examples/config.py
@@ -79,6 +79,7 @@ def configure_device(iface='hid', device='ecc', i2c_addr=None, keygen=True, **kw
             icfg = getattr(cfg.cfg, 'atca{}'.format(iface))
             setattr(icfg, k, int(v, 16))
 
+    cfg.cfg.atcai2c.bus = 0
     # Basic Raspberry Pi I2C check
     if 'i2c' == iface and check_if_rpi():
         cfg.cfg.atcai2c.bus = 1

PATCH
git apply config.patch
i2cdetect -y 0
# this should yield an i2c device at 0x60 - the default before personalization
# THE FOLLOWING COMMAND IS DANGEROUS AND CAN ONLY BE EXECUTED ONCE!
# I WANT NO COMPLAINTS. ALL AT YOUR OWN RISKS. I BURNED SOME ATECC608 DURING EXPERIMENTING!
# MOST LIKELY YOU CAN STILL USE THE CHIP BUT WITH A NON-DEFAULT I2C ADDRESS ONLY SOME TOOLS/LIBS WORK!
# FOR NON-COMMERCIAL TINKERING, ALL ATECC608 WE CAN SOURCE CAN BE DIFFERENT! THE CHIP IS NOT MARKED!
python3 config.py -i i2c --i2c 0xC0 # this will set the i2c address to 0x60 even when using other ATECC608A chip

Changing I2C Value

Using atecc-util one can easily interact with ATECC608A devices attached to I2C bus on Linux. Even when it is configured to use a different I2C address.

Setup atecc-util to use a different I2C address

# ubuntu 20.04
apt install -y python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
mkdir ~/git
cd ~/git
git clone https://github.com/wirenboard/atecc-util.git
cd atecc-util
git submodule init
git submodule update
# patch the configuration byte to use a different i2c address
cat > atecc.patch <<"PATCH"
diff --git a/config.h b/config.h
index 6fa7f00..5d1e24e 100644
--- a/config.h
+++ b/config.h
@@ -1,6 +1,6 @@
 #pragma once
 
 #define DEFAULT_I2C_BUS 9
-#define DEFAULT_I2C_SLAVE 0xC0
+#define DEFAULT_I2C_SLAVE 0x6A
 
 #define MAX_CMDS 32
PATCH
git apply atecc.patch
make
dpkg-buildpackage
dpkg -i atecc-util*

Change i2c address with atecc-util

Use i2cdetect -y 0 to scan bus 0 in order to detect the used i2c address of your device.

You should use the atecc command first to grab some valuable information about your device for any troubleshooting needs. This also makes sure that you can interact with the device.

modprobe i2c_dev # make sure the i2c bus gets enumerated in /dev/i2c-*
# -b 0 is the first bus. on newer raspberry pi you need -b 1, on a pc you could have many!
# get the serial of the device
./atecc -b 0 -c "serial" > serial.txt
# save configuration bytes and decoded information to file
touch config.dump
./atecc -b 0 -c "dump-config config.dump"
# see whether device is already locked
./atecc -b 0 -c "config-is-locked" > lock.status

Then the following command can be executed ONCE in order to permanent change the address for i2c A SINGLE TIME:

./atecc -b 0 -c "extra-set 85 0xC0"
# power down/up i2c device; i2c is not hotplugable!

However it seems that not all ATECC608A allow to have the I2C reset once the configuration is locked. Without locking the configuration, you could not interact with the device and execute cryptographic functions.

Test with Raspberry Pi Zero

Connect device according to the following schematic (header is the same on Pi Zero):

Schematic

# raspbian buster lite
sudo apt update
sudo apt install -y i2c-tools python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
cd
mkdir git
cd git
git clone https://github.com/adafruit/Adafruit_CircuitPython_ATECC.git
cd Adafruit_CircuitPython_ATECC/
python3 -m venv venv
source venv/bin/activate
pip3 install wheel
pip3 install -r requirements.txt
i2cdetect -y 1
#     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
#00:          -- -- -- -- -- -- -- -- -- -- -- -- --
#10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- --
#40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#70: -- -- -- -- -- -- -- --
pip3 freeze
#Adafruit-Blinka==6.3.0
#adafruit-circuitpython-binascii==1.2.5
#adafruit-circuitpython-busdevice==5.0.6
#Adafruit-PlatformDetect==3.2.0
#Adafruit-PureIO==1.1.8
#pkg-resources==0.0.0
#pyftdi==0.52.9
#pyserial==3.5
#pyusb==1.1.1
#rpi-ws281x==4.2.5
#RPi.GPIO==0.7.0
#sysv-ipc==1.1.0
python3 setup.py bdist_wheel
# patch the i2c address if yours is different to 0x60 (in this case 0x35)
cat > atecc.patch <<"PATCH"
--- atecc.patch 2021-03-04 21:21:07.229852937 +0000
+++ atecc.patch2        2021-03-04 21:20:52.339761410 +0000
@@ -3,13 +3,13 @@
 --- a/adafruit_atecc/adafruit_atecc.py
 +++ b/adafruit_atecc/adafruit_atecc.py
 @@ -59,7 +59,7 @@ def _convert_i2c_addr_to_atecc_addr(i2c_addr=0x60):
-
-
+
+
  # Device Address
 -_I2C_ADDR = 0x60
 +_I2C_ADDR = 0x35
  _REG_ATECC_ADDR = _convert_i2c_addr_to_atecc_addr(i2c_addr=_I2C_ADDR)
-
+
  _REG_ATECC_DEVICE_ADDR = _REG_ATECC_ADDR >> 1
 diff --git a/examples/atecc_simpletest.py b/examples/atecc_simpletest.py
 index 088f48e..403e179 100644
@@ -17,10 +17,10 @@
 +++ b/examples/atecc_simpletest.py
 @@ -9,7 +9,7 @@ from adafruit_atecc.adafruit_atecc import ATECC, _WAKE_CLK_FREQ
  i2c = busio.I2C(board.SCL, board.SDA, frequency=_WAKE_CLK_FREQ)
-
+
  # Initialize a new atecc object
 -atecc = ATECC(i2c)
 +atecc = ATECC(i2c, address=0x35, debug=False)
-
+
  print("ATECC Serial: ", atecc.serial_number)
-
+
PATCH

# force reinstall in case original wheel already installed during testing
pip3 install --upgrade --force-reinstall dist/adafruit_circuitpython_atecc-1.2.6-py3-none-any.whl
python3 examples/atecc_simpletest.py
#ATECC Serial:  0123E*************
#Random Value:  525
#ATECC Counter #1 Value:  bytearray(b'\t\x00\x00\x00')
#Appending to the digest...
#Appending to the digest...
#SHA Digest:  bytearray(b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment