A Hardware Abstraction Layer (HAL) implementation for Microchip's CryptoAuthLib library, enabling I2C communication with ATECC608A/ATECC608B secure elements on Raspberry Pi Pico (RP2040/RP2350) boards.
If you use this HAL in your project, I'd love to hear about it! Please consider reaching out at lucasleeeeeeeee@gmail.com or opening an issue to let me know how you're using it.
- Full I2C HAL implementation for CryptoAuthLib
- Support for ATECC608A and ATECC608B secure elements
- Compatible with RP2040 (Pico/Pico W) and RP2350 (Pico 2/Pico 2 W)
- Implements all required HAL functions (init, send, receive, wake, idle, sleep)
- Configurable I2C pins and baud rate
- MIT licensed
- Microcontroller: Raspberry Pi Pico, Pico W, Pico 2, or Pico 2 W
- Secure Element: Microchip ATECC608A or ATECC608B
- Connection: I2C (default: GPIO 0 = SDA, GPIO 1 = SCL)
Copy these files to your project:
hal_pico_i2c.chal_pico_i2c.h
Add the HAL to your CMakeLists.txt:
# Add CryptoAuthLib dependency
include(FetchContent)
FetchContent_Declare(
cryptoauthlib
GIT_REPOSITORY https://github.com/MicrochipTech/cryptoauthlib.git
GIT_TAG v3.7.9
)
FetchContent_MakeAvailable(cryptoauthlib)
# Create your executable
add_executable(your_project
src/main.c
src/hal/hal_pico_i2c.c
)
# Link libraries
target_link_libraries(your_project
pico_stdlib
hardware_i2c
cryptoauth
)
# Include directories
target_include_directories(your_project PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/hal
${cryptoauthlib_SOURCE_DIR}/lib
)
# Compiler definitions
target_compile_definitions(your_project PRIVATE
ATCA_HAL_I2C
ATCA_ATECC608A_SUPPORT
ATCA_CA_SUPPORT
)Create include/atca_config.h:
#ifndef ATCA_CONFIG_H
#define ATCA_CONFIG_H
// HAL Configuration
#define ATCA_HAL_I2C
// Device Support
#define ATCA_ATECC608A_SUPPORT
#define ATCA_CA_SUPPORT
// Disable unused features
#define ATCA_NO_HEAP
#define ATCA_NO_POLL
#endif // ATCA_CONFIG_H#include "cryptoauthlib.h"
#include "hal_pico_i2c.h"
int main() {
stdio_init_all();
// Configure ATECC608B
ATCAIfaceCfg cfg = {
.iface_type = ATCA_I2C_IFACE,
.devtype = ATECC608B,
.atcai2c.address = 0xC0, // ATECC608B default (0x60 << 1)
.atcai2c.bus = 0,
.atcai2c.baud = 100000,
.wake_delay = 1500,
.rx_retries = 20
};
// Initialize CryptoAuthLib
ATCA_STATUS status = atcab_init(&cfg);
if (status != ATCA_SUCCESS) {
printf("Failed to initialize ATECC608B: 0x%02X\n", status);
return -1;
}
// Test: Read serial number
uint8_t serial[9];
status = atcab_read_serial_number(serial);
if (status == ATCA_SUCCESS) {
printf("Serial Number: ");
for (int i = 0; i < 9; i++) {
printf("%02X", serial[i]);
}
printf("\n");
}
// Your code here...
// Release resources
atcab_release();
return 0;
}The default pins are defined in hal_pico_i2c.c:
#define I2C_SDA_PIN 0 // GPIO 0
#define I2C_SCL_PIN 1 // GPIO 1You can modify these values to match your hardware setup. Just edit the defines before building.
The ATECC608B typically uses one of these addresses:
- 0xC0 (0x60 << 1) - Default for most modules
- 0x6A - Alternative address (some Trust&GO modules)
Note that CryptoAuthLib uses 8-bit I2C addresses, so use the format shown above in cfg.atcai2c.address.
The default baud rate is 100 kHz, which works well for most setups and is recommended for initial testing.
For shorter cables and stable connections, you can increase the speed to 400 kHz:
cfg.atcai2c.baud = 400000;Higher speeds work well when your setup is solid, but start with 100 kHz if you're troubleshooting communication issues.
// Read 4 bytes from Config Zone at offset 0
uint8_t config[4];
ATCA_STATUS status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, config, 4);uint8_t random[32];
ATCA_STATUS status = atcab_random(random);// Generate ephemeral key in Slot 2
uint8_t public_key[64];
ATCA_STATUS status = atcab_genkey(2, public_key);
// Perform ECDH
uint8_t peer_public_key[64]; // From other party
uint8_t shared_secret[32];
status = atcab_ecdh(2, peer_public_key, shared_secret);Check your wiring first. Verify that SDA and SCL are connected properly and that you have pullup resistors (2.2kΩ to 10kΩ) on both lines. The ATECC608 requires a 3.3V supply, so double-check your power connections.
Try different I2C addresses. Some modules use 0xC0 (the default for most ATECC608B modules), while others like Trust&GO use 0x6A. If you're not sure which address your module uses, you can scan the I2C bus to detect devices.
I2C requires pullup resistors on both SDA and SCL lines. Use values between 2.2kΩ and 10kΩ. Without these resistors, communication will be unreliable or fail completely.
If you're still having issues, try reducing the baud rate to 100 kHz. While 400 kHz works well for most setups, slower speeds are more forgiving of longer cables and breadboard connections.
Keep your I2C wires short. For reliable communication, try to keep the total wire length under 30cm. Longer cables can introduce noise and signal degradation.
Make sure CryptoAuthLib is properly fetched by CMake during the build process. Check your CMakeLists.txt and ensure the FetchContent configuration is correct.
Verify that all required libraries are linked. Your target should link against pico_stdlib, hardware_i2c, and cryptoauth.
If you see redefinition warnings for ATCA_HAL_I2C or similar macros, don't worry. These warnings are harmless and occur when the macro is defined in both CMake and your atca_config.h header. The code will compile and run correctly.
See the CryptoAuthLib documentation for the complete API reference.
Here are some of the most commonly used functions:
atcab_init()- Initialize the libraryatcab_release()- Release resources when you're doneatcab_random()- Generate a random numberatcab_genkey()- Generate an ECC keypairatcab_ecdh()- Perform ECDH key exchangeatcab_sign()- Generate an ECDSA signatureatcab_verify_extern()- Verify an ECDSA signatureatcab_read_zone()- Read from data or config zonesatcab_write_zone()- Write to the data zone
The CryptoAuthLib API is well-documented in the upstream repository, and the examples there should work with this HAL without modification.
This project is licensed under the MIT License. See the LICENSE file for the full legal text.
Contributions are welcome! Please open an issue or pull request if you find bugs, want to add features (like SPI support or additional device support), have improvements or optimizations to share, or want to contribute examples.
This HAL builds on excellent work from the community:
- Microchip CryptoAuthLib - The cryptographic library that makes this all possible
- Raspberry Pi Pico SDK - A comprehensive and well-designed embedded SDK
- Adafruit_CircuitPython_ATECC - a reference implementation of the ATECC by Adafruit, very helpful in the initial stages.