Python & CircuitPython

It's easy to use the ATECC608 with CircuitPython and the Adafruit CircuitPython ATECC module.  This module allows you to easily write Python code that can communicate with the ATECC608 module. 

You can use this sensor with any CircuitPython microcontroller board or with a Linux single board computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.

CircuitPython Microcontroller Wiring

Wiring the ATECC608 is easy, since it only requires power and two wires for an I2C connection. Additionally, the STEMMA QT connectors give you additional solderless options for wiring:

  • Board 3V to sensor VIN (red wire)
  • Board GND to sensor GND (black wire)
  • Board SCL to sensor SCL (yellow wire)
  • Board SDA to sensor SDA (blue wire)

Python Computer Wiring

Since there's dozens of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported

Here's the Raspberry Pi wired with I2C:

  • Pi 3V to sensor VIN (red wire)
  • Pi GND to sensor GND (black wire)
  • Pi SCL to sensor SCL (yellow wire)
  • Pi SDA to sensor SDA (blue wire)

CircuitPython Installation of the ATECC Library

You'll need to install the Adafruit CircuitPython ATECC library on your CircuitPython board.

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  Our CircuitPython starter guide has a great page on how to install the library bundle.

For non-express boards like the Trinket M0 or Gemma M0, you'll need to manually install the necessary libraries from the bundle:

  • adafruit_atecc.mpy
  • adafruit_atecc_asn1.mpy
  • adafruit_atecc_cert_util.mpy
  • adafruit_binascii
  • adafruit_bus_device

Before continuing make sure your board's lib folder or root filesystem has the adafruit_atecc.mpy, adafruit_atecc_asn1.mpy, adafruit_atecc_cert_util.mpy, adafruit_binascii and adafruit_bus_device files and folders copied over.

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

Python Installation of ATECC Library

You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!

Once that's done, from your command line run the following command:

  • sudo pip3 install adafruit-circuitpython-atecc

If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!

CircuitPython and Python Usage

To demonstrate the power of the ATECC co-processor, you'll initialize it, generate a random number, print (and increase) one of the co-processor's internal counters, and perform a SHA-256 hash operation.

Copy the following code to the code.py file on your CircuitPython device:

import board
import busio
from adafruit_atecc.adafruit_atecc import ATECC, _WAKE_CLK_FREQ

# Initialize the i2c bus
i2c = busio.I2C(board.SCL, board.SDA,
                frequency=_WAKE_CLK_FREQ)

# Initialize a new atecc object
atecc = ATECC(i2c)

print("ATECC Serial: ", atecc.serial_number)

# Generate a random number with a maximum value of 1024
print("Random Value: ", atecc.random(rnd_max=1024))

# Print out the value from one of the ATECC's counters
# You should see this counter increase on every time the code.py runs.
print("ATECC Counter #1 Value: ", atecc.counter(1, increment_counter=True))

# Initialize the SHA256 calculation engine
atecc.sha_start()

# Append bytes to the SHA digest
print("Appending to the digest...")
atecc.sha_update(b"Nobody inspects")
print("Appending to the digest...")
atecc.sha_update(b" the spammish repetition")

# Return the digest of the data passed to sha_update
message = atecc.sha_digest()
print("SHA Digest: ", message)

Save the file and open the board's REPL. You should see the following output:

The ATECC will output its serial number and a random value to the REPL. You can modify the call to atecc.random() in your code to specify a minimum or maximum integer value to generate.

Download: file
print("ATECC Serial: ", atecc.serial_number)

# Generate a random number with a maximum value of 1024
print("Random Value: ", atecc.random(rnd_max=1024))

The code also writes a value of one of the ATECC's hardware counters to the REPL. This code uses counter #1, there's two hardware counters built into the ATECC chip.

If you run the file again (by saving it), you'll notice the counter value increase. The counter's state is saved, even if the ATECC is powered off. If you're building an IoT project, you can save important state information in here, such as the last frame which was transmitted before the connection was lost.

Download: file
print("ATECC Counter #1 Value: ", atecc.counter(1, increment_counter=True))

The ATECC is capable of performing hashing using the SHA256 algorithm. Instead of using a slow python-based SHA256 hash algorithm (such as the one found within CircuitPython's hashlib module), you can use the ATECC's super-quick hardware to hash data for you!

CircuitPython_ATECC implements a CPython3 hashlib-like interface. First, initialize the SHA256 calculate engine and memory context of the ATECC chip.

Download: file
# Initialize the SHA256 calculation engine
atecc.sha_start()

Then, can append bytes to hash object by passing bytes to sha_update. You can append as many bytes as you'd like before you create a message digest. 

Download: file
# Append bytes to the SHA digest
print("Appending to the digest...")
atecc.sha_update(b"Nobody inspects")

print("Appending to the digest...")
atecc.sha_update(b" the spammish repetition")

The digest of the data passed to the sha_update()  method is then returned and printed to the REPL.

Download: file
# Return the digest of the data passed to sha_update
message = atecc.sha_digest()
print("SHA Digest: ", message)

Self-Signed Certificate Demo

This demo will generate a self signed certificate for a private key generated by your crypto chip. 

Copy the code below to your code.py file. 

import board
import busio
from adafruit_atecc.adafruit_atecc import ATECC, _WAKE_CLK_FREQ, CFG_TLS

import adafruit_atecc.adafruit_atecc_cert_util as cert_utils

# -- Enter your configuration below -- #

# Lock the ATECC module when the code is run?
LOCK_ATECC = False
# 2-letter country code
MY_COUNTRY = "US"
# State or Province Name
MY_STATE = "New York"
# City Name
MY_CITY = "New York"
# Organization Name
MY_ORG = "Adafruit"
# Organizational Unit Name
MY_SECTION = "Crypto"
# Which ATECC slot (0-4) to use
ATECC_SLOT = 0
# Generate new private key, or use existing key
GENERATE_PRIVATE_KEY = True

# -- END Configuration, code below -- #

# Initialize the i2c bus
i2c = busio.I2C(board.SCL, board.SDA,
                frequency=_WAKE_CLK_FREQ)

# Initialize a new atecc object
atecc = ATECC(i2c)

print("ATECC Serial Number: ", atecc.serial_number)

if not atecc.locked:
    if not LOCK_ATECC:
        raise RuntimeError("The ATECC is not locked, set LOCK_ATECC to True in code.py.")
    print("Writing default configuration to the device...")
    atecc.write_config(CFG_TLS)
    print("Wrote configuration, locking ATECC module...")
    # Lock ATECC config, data, and otp zones
    atecc.lock_all_zones()
    print("ATECC locked!")

print("Generating Certificate Signing Request...")
# Initialize a certificate signing request with provided info
csr = cert_utils.CSR(atecc, ATECC_SLOT, GENERATE_PRIVATE_KEY, MY_COUNTRY, MY_STATE,
                     MY_CITY, MY_ORG, MY_SECTION)
# Generate CSR
my_csr = csr.generate_csr()
print("-----BEGIN CERTIFICATE REQUEST-----\n")
print(my_csr.decode('utf-8'))
print("-----END CERTIFICATE REQUEST-----")

Save the file and open the board's REPL. You should see the following output:

Download: file
ATECC Serial Number:  012347A22713EAFCEE
The ATECC is not locked, set LOCK_ATECC to True in code.py.

You'll want to edit the following lines in code.py before generating a certificate signing request.

Download: file
# -- Enter your configuration below -- #

# Lock the ATECC module when the code is run?
LOCK_ATECC = False
# 2-letter country code
MY_COUNTRY = "US"
# State or Province Name
MY_STATE = "New York"
# City Name
MY_CITY = "New York"
# Organization Name
MY_ORG = "Adafruit"
# Organizational Unit Name
MY_SECTION = "Crypto"
# Which ATECC slot (0-4) to use
ATECC_SLOT = 0
# Generate new private key, or use existing key
GENERATE_PRIVATE_KEY = True

# -- END Configuration, code below -- #

Once the configuration in code.py looks correct, change the following line from:

LOCK_ATECC = False 

to

LOCK_ATECC = True 

This will permanently lock your chip. You will only need to set this once.

Save and run your code. You should see the following output:

Download: file
ATECC Serial Number:  012347A22713EAFCEE
Writing default configuration to the device...
Wrote configuration, locking ATECC module...
ATECC locked!

Generating Certificate Signing Request...
-----BEGIN CERTIFICATE REQUEST-----

MIIBMDCB1gIBADB0MQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMREwDwYDVQQKEwhBZGFmcnVpdDEPMA0GA1UECxMGQ3J5cHRvMRswGQYDVQQDExIwMTIzNDdBMjI3MTNFQUZDRUUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARAFWZ0TDXKl0iks2NnMZOhQA3XYG/F6wFUfDIuabu8/nsSW6gtNq2UJi559OpgXsEkNMkUeqkaJLWFvn3hIKQHoAAwCgYIKoZIzj0EAwIDSQAwRgIhAJ6CZ2EQQ/838lD35O3yBoMloNVY4F47xveXF2ccDFCLAiEA8/kFUQXfbjgixSasozi3JsBsT4V03ER5P+zcSTUZ6Ns=

-----END CERTIFICATE REQUEST-----

The ATECC608A will quickly generate a certificate signing request and output it to the REPL.

This guide was first published on Sep 02, 2019. It was last updated on Sep 02, 2019. This page (Python & CircuitPython) was last updated on Dec 05, 2019.