配置加密芯片atsha204a驱动
说明
一个i2c接口的加密芯片,适配到linux RK3576 上。
步骤
注意i2c的速率要100K,太高通讯不上的,然后唤醒就话需要SDA长时间的拉低,时钟太快的话就会唤不醒芯片的。
QY:配置加密芯片 未完成只是probe上了
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-qiyang.dts b/arch/arm64/boot/dts/rockchip/rk3576-qiyang.dts
index c457ca39a9d4..f88958347093 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-qiyang.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-qiyang.dts
@@ -415,6 +415,7 @@ rgmii_phy1: phy@7 {
&i2c0 {
status = "okay";
+ clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0m1_xfer>;
@@ -425,6 +426,13 @@ rtc_sd3078: sd30783@32 {
status = "okay";
};
+ atsha204a: atsha204a@64 {
+ compatible = "atmel,atsha204a";
+ clock-frequency = <100000>;
+ reg = <0x64>;
+ status = "okay";
+ };
+
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig
index cf7f3c0cc844..7fa639e06768 100644
--- a/arch/arm64/configs/rockchip_linux_defconfig
+++ b/arch/arm64/configs/rockchip_linux_defconfig
@@ -286,7 +286,6 @@ CONFIG_SERIAL_8250_NR_UARTS=32
CONFIG_SERIAL_8250_RUNTIME_UARTS=15
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_ROCKCHIP=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_I2C_INFINEON=y
@@ -690,6 +689,7 @@ CONFIG_CRYPTO_SHA1_ARM64_CE=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA204A=y
CONFIG_CRYPTO_DEV_ROCKCHIP=y
CONFIG_CRYPTO_DEV_ROCKCHIP_DEV=y
CONFIG_CRC_CCITT=y
diff --git a/drivers/crypto/atmel-i2c.c b/drivers/crypto/atmel-i2c.c
index 81ce09bedda8..87dab61c4605 100644
--- a/drivers/crypto/atmel-i2c.c
+++ b/drivers/crypto/atmel-i2c.c
@@ -315,7 +315,7 @@ static int device_sanity_check(struct i2c_client *client)
*/
if (cmd->data[LOCK_CONFIG_IDX] || cmd->data[LOCK_VALUE_IDX]) {
dev_err(&client->dev, "Configuration or Data and OTP zones are unlocked!\n");
- ret = -ENOTSUPP;
+ // ret = -ENOTSUPP;
}
/* fall through */
应用测试
基于对称密钥的挑战-响应认证.
先设备树上不要配置OKAY,然后配置i2c的总线为100K,使用C程序直接操作加密芯片。
当总线上有多个 ATSHA204 设备且 I2C 接口以 133KHz 或更慢的速度运行时,某些数据模式 (如 0x00) 的传输将导致总线上的所有 ATSHA204 设备被唤醒。
由于沿总线传输的后续设备地址只会匹配所需的设备,未使用的设备将保持非活动状态,不会引起任何总线冲突。
在 I2C 模式下,当设备已经处于清醒状态时,设备将忽略发送的唤醒序列。
在解析参数和随后执行正确接收的命令期间,设备将处于忙碌状态,不会响应引脚上的转换。
唤醒
发送 0x00
回复 0x04 0x11 0x33 0x43
0x04 总数
0x11 唤醒回复的状态码
0x33 CRC[7:0] – 对前两个字节(0x04 0x11)计算出的 CRC‑16 校验值的低字节。
0x43 CRC[15:8] – CRC 校验值的高字节。
手册上的:

加密芯片使用的CRC16算法

demo里面的实现:
void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) {
uint8_t counter;
uint16_t crc_register = 0;
uint16_t polynom = 0x8005;
uint8_t shift_register;
uint8_t data_bit, crc_bit;
for (counter = 0; counter < length; counter++) {
for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
data_bit = (data[counter] & shift_register) ? 1 : 0;
crc_bit = crc_register >> 15;
crc_register <<= 1;
if (data_bit != crc_bit)
crc_register ^= polynom;
}
}
crc[0] = (uint8_t) (crc_register & 0x00FF);
crc[1] = (uint8_t) (crc_register >> 8);
}
写
大致发送的格式:
字节位置 内容 说明
0 0x03 command flag
1 len 总长度
2 op_code 操作码
3 param1 参数1
4 param2低 参数2低8位
5 param2高 参数2高8位
6-... data1 数据块1(如果有)
... data2 数据块2(如果有)
... data3 数据块3(如果有)
最后2字节 CRC 校验码
返回的是写的状态码。

现在一直返回0xFF 一般是格式或者参数错误。
测试代码,读取SN码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <stdint.h>
/* ========== 根据自己的硬件修改以下定义 ========== */
#define I2C_BUS "/dev/i2c-0" // I2C 设备节点
#define DEVICE_ADDR 0x64 // 芯片 7 位地址,默认 0x60
#define WAIT_WAKE_US 3400 // 唤醒后等待时间 (us)
#define WAIT_CMD_MS 3 // 命令执行等待时间 (ms)
/* ============================================== */
#define SHA204_WRITE 0x01
#define SHA204_READ 0x03
static int atsha_wake(int fd) {
uint8_t dummy;
struct i2c_msg msg = {
.addr = DEVICE_ADDR,
.flags = I2C_M_IGNORE_NAK, // 忽略 NACK 以确保总线释放
.len = 0,
.buf = &dummy
};
struct i2c_rdwr_ioctl_data ioctl_data = {
.msgs = &msg,
.nmsgs = 1
};
if (ioctl(fd, I2C_RDWR, &ioctl_data) < 0) {
perror("Wake ioctl failed");
return -1;
}
usleep(WAIT_WAKE_US);
printf("Wake-up sequence sent.\n");
unsigned char buf[4] = {0};
struct i2c_msg msg1 = {
.addr = DEVICE_ADDR,
.flags = I2C_M_RD, // 这次是读操作,不忽略 NAK
.len = 4,
.buf = buf
};
struct i2c_rdwr_ioctl_data ioctl_data1 = {
.msgs = &msg1,
.nmsgs = 1
};
if (ioctl(fd, I2C_RDWR, &ioctl_data1) < 0) {
perror("Read after wake failed - check wiring / address");
close(fd);
return 1;
}
printf("Chip response: 0x%02X 0x%02X 0x%02X 0x%02X\n",
buf[0], buf[1], buf[2], buf[3]);
if (buf[0] == 0x04 && buf[1] == 0x11 &&
buf[2] == 0x33 && buf[3] == 0x43) {
printf("ATSHA204A woke up successfully.\n");
// close(fd);
} else {
printf("Unexpected response, wake may have failed.\n");
}
return 0;
}
// struct my_i2c_msg packet;
int main()
{
int fd;
uint8_t packet[8];
fd = open("/dev/i2c-0", O_RDWR);
if(fd < 0){
printf("sha204 open failed!");
}
atsha_wake(fd);
packet[0] = 0x03; //0x03, 0x07, 0x02, 0x00, 0x00, 0x00
packet[1] = 0x07;
packet[2] = 0x02;
packet[3] = 0x00;
packet[4] = 0x00;
packet[5] = 0x00;
packet[6] = 0x1e;
packet[7] = 0x2d;
for(int i = 0; i < 8; i++) {
printf("0x%02X ", packet[i]);
}
printf("\n");
// 通过 I2C 发送命令包
struct i2c_msg msg_wr = {
.addr = DEVICE_ADDR,
.flags = 0, // 写操作
.len = 8,
.buf = (uint8_t *)packet
};
struct i2c_rdwr_ioctl_data ioctl_wr = {
.msgs = &msg_wr,
.nmsgs = 1
};
if (ioctl(fd, I2C_RDWR, &ioctl_wr) < 0) {
perror("Send command failed");
return -1;
}
usleep(3000);
// //4.read data
uint8_t count_buf[7] = {0};
struct i2c_msg msg_rd = {
.addr = DEVICE_ADDR,
.flags = I2C_M_RD,
.len = 7,
.buf = count_buf
};
struct i2c_rdwr_ioctl_data ioctl_rd = {
.msgs = &msg_rd,
.nmsgs = 1
};
if (ioctl(fd, I2C_RDWR, &ioctl_rd) < 0) {
perror("Read response failed-----yx");
return -1;
}
for(int i = 0; i < 7; i++) {
printf("0x%02X ", count_buf[i]);
}
printf("\n");
close(fd);
return 0;

参考:
https://www.cnblogs.com/iotrookie/articles/6043170.html
https://blog.csdn.net/lijunyan797/article/details/53584345
https://blog.csdn.net/liuxd3000/article/details/105822086
https://blog.csdn.net/qq_30624591/article/details/85251307
https://blog.csdn.net/qq_30624591/article/details/85251307
https://blog.wudilabs.com/entry/c4a0811d/
https://www.microchip.com/en-us/products/security/trust-platform
https://microchiptech.github.io/cryptoauthlib/
官方库:
本文来自博客园,作者:杨旭0324,转载请注明原文链接:https://www.cnblogs.com/allalonewithyou/p/19632997,个人邮箱:yaonie4444@foxmail.com

浙公网安备 33010602011771号