atsha204a加密芯片使用攻略——配置篇

大家好,這是接上一篇使用篇的博客,本篇文章主講atsha204a加密芯片的配置方式,前面講到,atsha204a加密芯片內部rom分三個區域,一個是config zone,一個是slot zone,還有一個是OTP zone,本篇不只講解config zone的配置,還講解slot 和 OTP區域的配置方法,並且結合官方的庫來演示一下代碼。
首先約定一下,本文所有的通信接口均使用I2C協議,但所有的功能都能在單總線上實現。
開始,我想先講幾個細節,這是剛開始對於接觸這款芯片的我的一些困擾。
1、芯片的config區和data區一旦鎖定,沒有辦法解鎖,鎖的方法只能通過lock command來進行鎖定。
2、config區在沒鎖定的時候,可以使用write command來進行寫操作,但注意,0x00-0x03地址(word地址,詳情請參考手冊)不能被寫,0x15word地址不能使用write command來寫。
3、在config鎖定前,data區(包括slot區和OTP區)既不能寫也不能讀。而在config鎖定後,data區鎖定前,data區只能寫不能讀,在data區鎖定後,可以根據config中的配置來進行讀寫。
我之所以總結出這幾點,是能讓大家好理解這些區的讀寫屬性,接下來進入正題。

1、通信包的格式

atsha204a的所有發送的數據包均是以下格式.
通信包格式

word address 指示這個數據包是爲何作用,有如下值
word address values
最常用的就是0x03 命令數據包了

count是數據包的長度,包括count本身,data和CRC16。

data是數據內容,根據命令的不同而不同。

CRC16是數據包的校驗碼,校驗內容從count到data。

再來看看配置區config的內容
config zone
對atsha204a的所有地址操作都是基於word地址進行的,如上圖所示。

好了,現在我們先來看下讀命令格式(也就是數據包data域裏面的具體內容)
read command
第一個字節是操作碼,read command 的操作碼是0x02,
第二個字節的最高位bit7指示是讀取32字節還是4字節,1爲讀取32字節。bit0指示讀哪個區。
第三個字節是Address地址。
關於這裏的地址,datasheet手冊上寫着如下
Address
讀寫命令中Param2的這個Address如上,高8位爲0,低8位的前3位是偏移量,高5位是block,一個block爲32字節,所以config 分3個block(0-3),slot分16個block(0-15),otp分2個block(0-1),如果是使用32字節進行讀寫的話,則忽略前3位offset。我們舉個例子,比如說,我們要讀config區的word地址0x09那4個字節,因爲0x09是屬於block1的,偏移是1(config的block劃分是,word 0x00 -0x07是block,0,0x08-0x0F爲block1,0x10-0x15是block2,反正就是32個字節爲1個block,slot和otp相同)
Address[4:3] = 1;
如果是4字節讀取,那麼
Address[2:0] = 1;
如果是32字節讀取
則忽略Address[2:0] 。

現在我們來舉個例子,說說通信的數據包。
假設我們要讀取config的word0地址那4個字節,那麼數據包格式如下:
發送數據

如果通信正常,那麼芯片就會返回數據,返回的數據包格式如下
返回數據格式
各數據域的意思與發送的數據一樣。
根據剛纔的例子,返回的數據就是如下:
返回數據
因我們讀的是芯片序列號,xx是每塊芯片的唯一序列號一部分。

這裏僅僅是演示了讀的命令,如果是其他命令,則數據域會更加複雜,所幸ATMEL有專門的庫來封裝這些操作,官方庫文件如下列表:
官方庫文件
sha204_comm_marshling.h和sha204_comm_marshling.c這兩個文件裏面的
uint8_t sha204m_execute(
uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2,
uint8_t *data2, uint8_t datalen3, uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size,
uint8_t *rx_buffer);
這個函數封裝了所有命令,使用起來非常方面,具體實現的話可以去下載庫的源碼進行查看,而移植性的文件則是sha204_i2c.c、sha204_physical.h、sha_timer_utilities.h和sha_timer_utilities.c這幾個文件,做移植只需要簡單修改裏面幾個關於i2c通信和延時的函數即可。

本節以一個簡單的例子來講述了命令的基本格式,並簡單的介紹了官方庫文件的結構,有問題的可以私信。

config區的配置

這節是這篇博客的重點,只有正確配置了config,atsha204a芯片才能按自己的意圖辦事。
我再放一下config zone的配置表
config zone
以下我講的地址全部是word地址
配置區地址0x00-0x03是不允許寫的,只能讀。
從0x04開始講起,首先是I2C Address,可以設置I2C的器件地址,如果I2C總線上掛了好幾個atsha204a,可以修改一下這個地址,然後是CheckMacConfig,文檔介紹如下
這裏寫圖片描述
這個字節理解起來挺費勁的,這個字節隻影響讀寫命令和CheckMac命令,對於Read和Write命令,在進行加密讀\寫的時候要匹配TempKey中的SourceFlag相應的位,否則加密讀\寫將會失敗,什麼是加密讀寫?在後面會介紹到,而對於CheckMac命令也是類似,可以參照一下文檔具體使用。
接下來是OTP Mode
文檔描述如下
OTP Mode
OTP Mode = 0xAA 只讀模式,在OTP鎖定後,只能讀取OTP區中的內容
OTP Mode = 0x55 消耗模式,在OTP鎖定後,寫操作只能使位1變0,不能再變爲1,比如原先的內容是0xFF,寫入0xFC,就變爲0xFC,再寫0xFF,則仍然是0xFC,寫入0x00則立即清零並且不能再寫其他值(這個過程有點像flash的燒寫)。
OTP Mode = 0x00 傳統模式,在OTP鎖定後,不能讀OTP0和OTP1,也不能以32字節讀取。
其他值不被允許。
Selector Mode,這個字節定義0x15地址上的Selector更新方式,
Selector Mode = 0x00 ,使用UpdateExtra 命令可以隨意更新Selector中的值,
Selector Mode = 其他值,只有當Selector中的值爲0時,才能被UpdateExtra 命令命令更新。
這裏順便說一下Selector,當執行Pause Command命令的時候,Pause Command命令參數中指定的selector與配置中的selector相等時,器件將不會進入空閒模式。
對於一般用戶,0x04地址的4個配置按默認值設置即可。

接下來是地址0x05-0x0C關於slot 的配置了,這裏纔是這節的重點,也是需要注意最多的地方。
每個slot config佔用2個字節,每個位具體配置如下
slot config 1

slot config 2
一位一位的說
bit0-3:指定加密讀的slot區,這裏的意思是,如果你把slotX設置成可以加密讀取,則這裏要指定加密讀取的密鑰存放的slot,簡單來說,你要讀一個slotX,而slot config[X]已經被配置成可以加密讀,但是需要知道slot config[X].ReadKey中指定的slot區的密鑰。
bit4:0:這個slot區可以用於所有加密命令,1:這個slot只能用於CheckMac命令和GenDig命令。
bit5:0:此slot中存放的密鑰可以無限使用,1:此slot存放的密鑰有限使用,次數根據UseFlag或LastKeyFlag指定。
bit6 : 0:可以明文讀取,1:必須加密讀取。
bit7:0:此slot不是密鑰區,可以隨意讀寫,1:此slot作爲密鑰區,如果能讀寫則必須是加密進行。
說到這裏大家先看一張表格
加密配置
可以清楚看到IsSecret和EncryptRead位的配置對slot讀操作的影響。
IsSecret = 1;EncryptRead = 0;slot不能被讀。
IsSecret = 1;EncryptRead = 1;slot能被加密讀。
IsSecret = 0;EncryptRead = 0;隨意讀。
說回slot config配置,bit8-bit11,指定加密寫操作的slot區密鑰,跟bit0-3類似,只不過這裏是寫操作,使用write command命令。
bit12-15 Write Config表,上述Write Config 那張表看起來有點費勁,bit12-15對於DeriveKey Command 和 Write command命令有不同的意思,對於DeriveKey Command,就是決定生成的新的密鑰要通過什麼途徑來獲取(Target?,Parent?),具體大家可以看我上一篇使用篇中對於DeriveKey Command的描述。而對於Write Command,定義如下
bit15 = 0;bit14 = 0;bit13 =0; 隨意寫
bit15 = x;bit14 = 0;bit13 =1; 不能寫
bit15 = 1;bit14 = 0;bit13 =x; 不能寫
bit15 = x;bit14 = 1;bit13 =x; 加密寫

到此大致介紹完了slot區的配置,這裏舉個最簡單的例子,如下
現在要把slot0和slot1設置成密鑰區,不能進行任何讀寫,可以執行所有加密命令,無限次使用,則地址word0x04的配置應該是0x80 0xA0 0x80 0xA0,
根據手冊,得知write command命令如下
write command
我們要寫config zone,地址是0x04,4字節寫入,所以填充如下
opcode = 0x12,
zone = 0x00,
address = 0x04,
value = 0x80,0xA0,0x80,0xA0
數據包爲如下格式
寫命令數據包格式

Data_2的MAC域在進行加密寫操作的時候纔會有內容,這裏不進行加密寫操作,所以上述數據包沒有這個字段,大家如果使用官方封裝的庫,可以使用sha204m_execute函數

函數原型如下:
uint8_t sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);

這個函數參數很多,主要是考慮到各種命令的各種不同內容,按上面的描述則調用這個函數時,具體內容爲:
state = sha204m_execute(
0x12,
0x00,
0x05,
4,*yourbuffer,
0,0,0,0,
SHA204_CMD_SIZE_MIN,
txbuf,
WRITE_RSP_SIZE,
rxbuf
);
當然這是一段僞代碼, yourbuffer是data_1:value的存放地方,SHA204_CMD_SIZE_MIN和READ_32_RSP_SIZE在庫中都有定義,實際上在這個函數實現內部SHA204_CMD_SIZE_MIN和WRITE_RSP_SIZE指定的大小均不起作用,在函數內部自動根據命令來調節收發數據包的大小,而用戶只需要給定足夠大的txbuf和rxbuf即可。

接下來是UseFlag,這裏UseFlag裏面的值指明瞭對應的slot區(只限slot0-7)中的key還能使用多少次,但前提是slot config.SingleUse = 1,UseFlag纔會有用。在原datasheet的78頁裏面詳細介紹了single-use key的用法,我截個圖給大家看一下
single-use key
大概的意思就是,slot0-7纔有useflag這功能,slot8-14沒有(slot15比較特殊)。如果相應slot config.singleuse = 1,那麼當執行一些需要用到此slot的加密命令時而UseFlag[SlotID] = 0x00,那麼這些命令就會返回錯誤。UseFlag的計數方式簡單的說就是這個8位數位爲1的個數,比如0xFF是八次,0x7F是7次,0x01是1次,如此類推。
當執行了一些加密命令時,UseFlag就會從最高位開始置零,DeriveKey命令可以更新UseFlag中的值,關於DeriveKey命令,大家可以看一下我上一篇使用篇的博客,因篇幅問題,不再討論。
UpdateCount是對應的slot使用DeriveKey更新了多少次,到了0xFF就回滾至0x00。

然後是LastKeyUse0-15,首先注意,這個”Last”不是上一個的意思,而是最後一個的意思,也就是說,這LastKeyUse0-15都是爲slot15服務的,真是厲害,其實LastKeyUse使用起來和UseFlag差不多,也是要slot15 config.singleuse = 1纔有效,而計算剩餘使用次數的方法是,所有LastKeyUse位1的個數加起來,那麼總共就有16*8 = 128次了,不過用完後,slot15就徹底完了,不能再使用,無法被DeriveKey更新,這也是slot15比較特殊的地方。

地址0x15不能被write command寫,只能通過其他命令,關於UserExtra,官方源文檔中說了這個可以被UpdateExtra Command更新,它的用途主要是給用戶使用的,其他用途不明,如果有其他人知道這個字節有什麼用,也希望告知,謝謝。
Selector前文中提了一下:執行Pause Command命令的時候,Pause Command命令參數中指定的selector與配置中的selector相等時,器件將不會進入空閒模式。也可以被
UpdateExtra Command更新,
UpdateExtra Command命令格式如下:
UpdateExtra Command
參數一目瞭然,不再多說,這裏只需要注意,
1、Mode.bit1 = 1時,這條命令做的操作是,減少NewValue中指定的SlotID的使用次數。
2、UserExtra中的值不爲0,那麼此條命令如果更新UserExtra的話將會返回失敗。
3、如果SelectorMode不爲0,而且Selector不爲0,那麼那麼此條命令如果更新Selector的話將會返回失敗。

Lock Data 和Lock Config是控制鎖定數據區和配置區的兩個字節,
LockData = 0x55,data區沒有鎖定可以進行寫操作。
LockData = 0x00,data區進行鎖定,讀寫需要根據配置來進行。

LockConfig =0x55,config區沒有鎖定可以進行讀寫操作。
LockConfig = 0x00,config區不能寫。
這兩個字節必須使用LockCommand來設置,LockCommand如下:
Lock Command
Zone.bit0決定的是鎖config還是OTP區,Zone.bit7 = 1,則不計算需要鎖定區域的CRC16值,否則需要輸入一個CRC16值來校驗。
Summary如果Zone.bit7=0,那麼就這裏就需要填入相應鎖定區域的CRC16值,否則填0x0000。如果命令成功就返回0。

本節介紹了config zone的配置,用戶可以根據自己的需要來對config 進行配置,強烈建議用戶去多次閱讀datasheet才能深刻理解。

slot區的配置

此區的配置沒那麼複雜,slot主要意圖是存放密鑰,當然也可以設置成eeprom來使用,但一般用戶都不會這麼做。

slot區一共分16部分,slot0-15,每部分可以存放32字節密鑰,相信足夠使用。
對slot區的配置無外乎讀寫內容,在config區鎖定前,所有對slot區的讀寫操作均返回錯誤。在config區鎖定後,data區鎖定前,只能寫slot區而不能讀取,在二者都鎖定後,可以根據上節所講的slot config來進行讀寫。
假設我們配置完了config區,現在我們來寫slot區,很簡單,在data區鎖定前可以隨意讀寫,但強烈建議使用32字節來寫操作,採用4字節寫操作,會有很多的限制條件。
假如我們對slot0寫入0x11,0x11,…..0x11(共32個0x11),使用write command,參數如下(這裏我們暫時先不考慮各種加密讀寫,會在本文最後介紹加密讀寫)
opcode = 0x12,
zone = 0x80|0x02; //32字節寫,寫slot區。
address = 0x00;
data_1 = 32個字節 0x11;
data_2 不填
如果寫入成功,atsha204a將會返回0。

OTP區配置

OTP區和slot區配置類似,在atsha204a裏,OTP分16部分,每部分4字節,默認值都是0xffffffff,OTP區在config區鎖定前無法進行任何讀寫操作,在config鎖定後,data區鎖定前,不能讀,只能寫,與slot區不同的是,OTP區並沒有加密讀寫這一概念,另外也強烈建議使用32字節寫,4字節寫入會有很多限制,在data區鎖定後,OTP區的讀寫操作由OTP Mode決定,在config區那節已經進行描述,這裏不再論述。
關於OTP區的作用,一是用戶可以自定義用途,二是OTP區要參與一些加密命令的MAC摘要計算,如果還有其他用途,歡迎讀者補充。

加密讀寫

本人覺得加密讀寫是高級用戶需要的功能,既然atsha204a提供這個功能,那想必此功能也十分有用,廢話不多說,進入正題。
加密讀,只有當slot config.EncryptRead = 1和slot config.IsSecret = 1時才能進行。
加密讀是爲了防止別人在總線上嗅探到密鑰,這裏我借用官方文檔Atmel-8981的一幅圖,
標準加密讀過程
這個流程圖其實非常明瞭,主要步驟如下:
1、首先發送Nonce Command命令,更新TempKey中的值,主機這邊根據命令返回的randout來使用SHA-256算法計算出TempKey中的值。
2、發送GenDig Command,Gen Dig 命令中的參數KeyID ,就是slot config.ReadKey,比如說,我們要讀取slot1的密鑰,而slot config[0].ReadKey 設置爲0,那麼我們就需要知道slot0中存放的密鑰才能讀取slot1的密鑰,發送完這個命令後如果執行正確,TempKey中的值會被重新計算,而主機需要根據Read Key等一些列參數計算TempKey中的值。
3、執行讀命令,讀取slot區中的值,這時候返回來的內容是經過異或加密的,密鑰是第2步計算出來的摘要,也就是說:讀回來的值^第二步計算出來的摘要 = 原文。

這裏說下GenDig Command,這個命令在我上一篇使用篇的博客中沒有提到,這裏說一下,這條命令作用如下(datasheet 原文):
GenDig Command

GenDig command 使用SHA-256算法結合TempKey中的值去更新TempKey,在執行這條命令前,TempKey中的值必須是合法的。
因爲一些加密命令如MAC,HMAC命令都需要用到TempKey值,使用這條命令可以多增加一些slot區的使用驗證,從而達到更加安全的驗證。而在加密讀的過程中,這條命令必須被正確執行,相應的區才能被正確的加密讀取。
關於Nonce 命令和Read 命令,分別在我上一篇配置篇和上文中都提到了,這裏不再討論。

加密寫,加密寫稍微複雜一點,這裏還是放Atmel-8981文檔的圖
加密寫過程

同樣,加密寫也是爲了防止別人在總線上獲取密鑰。與加密讀過程類似,不過主機這裏還要計算一個MAC發送給atsha204a。
1、發送Nonce Command命令,更新TempKey中的值,主機這邊根據命令返回的randout來使用SHA-256算法計算出TempKey中的值。
2、發送GenDig command,KeyID 是所要寫的slot config.writekey中指定的ID,比如我們要寫slot1,而slot config[1].writekey 設置爲0,那這個keyID就是0。然後主機這邊根據Slot0中的密鑰和其他參數計算出一個摘要(Session Key),當然atsha204a那邊也會進行同樣的計算並存在TempKey中。
3、我們要寫的密鑰和第二步計算出來的摘要進行異或運算等到加密文。
4、再根據第二步生成的摘要和明文還有其他參數(參照流程圖中指示)計算出一個Host MAC。
5、執行寫命令,寫命令中參數value是加密文,而參數MAC是Host MAC(關於Write command的格式請回看上文)。
6、atsha204a收到這個命令後,會對value解密(就是和自己的TempKey做異或運算),然後再執行類似第4步的計算過程得到Client MAC,比較Host MAC和Client MAC就知道寫入的數據是否正確了。

這樣,整個加密寫過程就是如此,在這整個過程中,無論是密鑰,還是Write Key,都沒有明文在總線上傳輸,嗅探者也就不能截獲我們設置的密鑰了。

總結

本文介紹了atsha204a這款芯片的一系列配置方法,這是本人多日來研究所得,不過總結的最全的還是原datasheet,本人寫的博客可能沒有徹徹底底的把這款芯片的所有功能以及用途介紹清楚,開發者根據這麼多的配置項,完全可以配置成自己所要的功能(如防抄板、產品匹對,密鑰驗證等)。另外本文中的不足之處,懇請指正。

附錄

因個人工作原因,本人制作的燒錄器已不再賣,如果任何使用的問題均可以聯繫我。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章