大家好,這是接上一篇使用篇的部落格,本篇文章主講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 指示這個資料包是為何作用,有如下值
最常用的就是0x03 命令資料包了
count是資料包的長度,包括count本身,data和CRC16。
data是資料內容,根據命令的不同而不同。
CRC16是資料包的校正碼,校正內容從count到data。
再來看看配置區config的內容
對atsha204a的所有地址操作都是基於word地址進行的,如上圖所示。
好了,現在我們先來看下讀命令格式(也就是資料包data域裡面的具體內容)
第一個位元組是作業碼,read command 的作業碼是0x02,
第二個位元組的最高位bit7指示是讀取32位元組還是4位元組,1為讀取32位元組。bit0指示讀哪個區。
第三個位元組是Address地址。
關於這裡的地址,datasheet手冊上寫著如下
讀寫命令中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的配置表
以下我講的地址全部是word地址
配置區地址0x00-0x03是不允許寫的,只能讀。
從0x04開始講起,首先是I2C Address,可以設定I2C的器件地址,如果I2C匯流排上掛了好幾個atsha204a,可以修改一下這個地址,然後是CheckMacConfig,文檔介紹如下
這個位元組理解起來挺費勁的,這個位元組隻影響讀寫命令和CheckMac命令,對於Read和Write命令,在進行加密讀\寫的時候要匹配TempKey中的SourceFlag相應的位,否則加密讀\寫將會失敗,什麼是加密讀寫。在後面會介紹到,而對於CheckMac命令也是類似,可以參照一下文檔具體使用。
接下來是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個位元組,每個位具體配置如下
一位一位的說
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命令如下
我們要寫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的用法,我截個圖給大家看一下
大概的意思就是,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命令格式如下:
參數一目瞭然,不再多說,這裡只需要注意,
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如下:
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 使用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,本人寫的部落格可能沒有徹徹底底的把這款晶片的所有功能以及用途介紹清楚,開發人員根據這麼多的配置項,完全可以配置成自己所要的功能(如防抄板、產品匹對,密鑰驗證等)。另外本文中的不足之處,懇請指正。 附錄
因個人工作原因,本人製作的燒錄器已不再賣,如果任何使用的問題均可以聯絡我。