??? 摘? 要: 根據(jù)涉密存儲介質(zhì)保密管理的要求,以U盤為例,提出一種新穎的、以USB協(xié)議和大容量存儲類協(xié)議為基礎(chǔ)的移動存儲介質(zhì)管理架構(gòu)。存儲介質(zhì)的唯一性標(biāo)識由VID、PID和硬件序列號組成。同時還提出了基于CY7C67300嵌入式主機(jī)控制器的USB總線介質(zhì)管理方案。通過USB總線枚舉方式,逐一識別介質(zhì)唯一性標(biāo)識并通過超級終端顯示。測試結(jié)果證明,該標(biāo)識和識別方法可以用于移動存儲介質(zhì)安全管理系統(tǒng),從而使涉密移動存儲介質(zhì)處于實(shí)時監(jiān)控狀態(tài)下,大大減少了泄密風(fēng)險。?
??? 關(guān)鍵詞: 信息安全; 移動存儲介質(zhì); 唯一性標(biāo)識; 嵌入式USB主機(jī)控制器; USB總線枚舉
?
??? 按照保密管理規(guī)定,涉密單位職工使用完U盤等移動存儲介質(zhì)必須當(dāng)天按時歸還保密員,并存儲在密碼文件柜中(如部隊的槍支入架)。保密文件柜由保密員人工管理,涉及借出、歸還、監(jiān)督、提醒等事項(xiàng),難免疏漏。若個別人員違規(guī)(未經(jīng)審批許可)攜帶涉密U盤外出,可能導(dǎo)致涉密U盤丟失或涉密數(shù)據(jù)失竊,泄漏國家或商業(yè)秘密,造成巨大的損失。因此,涉密U盤的保密管理,需要依靠創(chuàng)新的技術(shù)手段,保障保密管理規(guī)章制度的貫徹落實(shí)。為了實(shí)現(xiàn)涉密U盤保密管理的智能化“機(jī)控”,需要為每個U盤定義一個可查詢、不易修改的唯一性標(biāo)識(Unique identifier),且該標(biāo)識應(yīng)很容易與使用者綁定,從而使涉密U盤的保密管理責(zé)任到人,以減少泄密隱患。?
??? 本文以通用串行總線USB1.0、USB2.0協(xié)議為基礎(chǔ),采用CY7C67300單芯片實(shí)現(xiàn)嵌入式USB主機(jī)控制器,完成該控制器對U盤的控制以及讀取U盤唯一性標(biāo)識信息的功能。?
1 工作原理?
1.1 唯一性標(biāo)識的構(gòu)建?
??? USB控制/批量/中斷CBI(Control/Bulk/Interrupt)傳輸協(xié)議和USB Bulk-Only協(xié)議中規(guī)定,U盤等符合大容量存儲類MSC(Mass Storage Class)協(xié)議的設(shè)備,如果其序列號索引值不為0,則U盤內(nèi)必定含有一個唯一的序列號與之匹配[1-2]。如表1所示,在其設(shè)備描述符中偏移值為16的字段只規(guī)定了其序列號的索引值,如果其索引值為0,則說明此設(shè)備不含序列號,反之,設(shè)備必定含有一個唯一的序列號。序列號的格式如表2所示,表中,第一項(xiàng)為序列號的長度,其最小值為26;第二項(xiàng)為序列號的類型,其值為3,說明序列號為字符串描述符;第三至第n×2項(xiàng)為序列號的內(nèi)容。USB CBI 和Bulk-Only協(xié)議中規(guī)定序列號至少由12個有效的數(shù)字字符組成,這些數(shù)字字符的有效范圍為:數(shù)字0~9,字符A~F。?
?
?
?
??? 本文采用16 bit VID(設(shè)備描述符偏移量為8)+16 bit PID(設(shè)備描述符偏移量為10)+序列號構(gòu)成GUID(全球唯一ID)作為U盤的唯一性標(biāo)識。?
1.2 唯一性標(biāo)識的識別?
??? 如前所述,獲取U盤唯一性標(biāo)識就是獲取設(shè)備描述符中的VID、PID和字符串描述符中的序列號。本文采用USB總線枚舉方式獲得U盤的唯一性標(biāo)識。?
??? 總線枚舉是指對總線上接入的USB設(shè)備進(jìn)行識別和尋址操作。當(dāng)USB主機(jī)發(fā)現(xiàn)有設(shè)備連接時,立刻通過默認(rèn)的地址0發(fā)送讀取設(shè)備描述符的命令,然后利用控制傳輸?shù)臉?biāo)準(zhǔn)命令為其動態(tài)配置設(shè)備地址,再通過該地址繼續(xù)讀取有關(guān)設(shè)備、配置、接口以及字符串描述符,并建立有關(guān)信息的資料區(qū)[3]。這些信息主要包括VID、PID和端點(diǎn)信息等。其中,VID、PID的獲取是通過Get_descriptor( )標(biāo)準(zhǔn)請求命令實(shí)現(xiàn)的。字符串描述符信息的獲取沒有明確的定義,需要開發(fā)一種用于獲取字符串信息的命令請求。?
??? 本文利用嵌入式控制器完成USB主機(jī)功能,通過USB主機(jī)實(shí)現(xiàn)總線枚舉、控制傳輸以及獲取設(shè)備描述符的標(biāo)準(zhǔn)請求命令和獲取字符串描述符的請求命令,從而實(shí)現(xiàn)U盤唯一性標(biāo)識信息識別裝置的設(shè)計。?
2? 裝置設(shè)計?
2.1 硬件結(jié)構(gòu)?
??? U盤唯一性標(biāo)識識別裝置的硬件結(jié)構(gòu)框圖如圖1所示。采用CY7C67300作為核心處理器,CY16工作在獨(dú)立模式下,控制CY7C67300芯片內(nèi)部的USB串行接口引擎SIE(Serial Interface Engine)完成USB主機(jī)的功能,控制LTC3186芯片進(jìn)行電平轉(zhuǎn)換,完成異步串行收發(fā)器UART可以用來調(diào)試。通過I2C接口控制EEPROM以下載程序。通過外部存儲器接口控制外部存儲器以擴(kuò)展代碼和數(shù)據(jù)存儲空間。?
?
?
??? 核心處理芯片CY7C67300是CYPRESS公司的嵌入式主機(jī)/外設(shè)控制器,其內(nèi)部結(jié)構(gòu)如圖2所示。主機(jī)部分包括高性能16位48 MHz RISC微處理器CY16,該處理器可以獨(dú)立工作(獨(dú)立模式),也可以與其他處理器協(xié)同工作(協(xié)處理器模式);2個SIE,每個可單獨(dú)配置,有2個端口USB-A、USB-B;可配置的I/O電路模塊能連接眾多標(biāo)準(zhǔn)接口,高達(dá)16位可編雙向數(shù)據(jù)I/O,多達(dá)32位通用I/O;4 K×16 bit內(nèi)部掩模板ROM,內(nèi)有基本輸入輸出系統(tǒng)BIOS,支持I2C、EEPROM,外部ROM、UART、USB等外設(shè)端口通信就緒狀態(tài);8 K×16 bit內(nèi)部RAM能由用戶配置;具有外接SRAM,DRAM和ROM存儲器接口,芯片外部可以擴(kuò)展512 KB存儲空間;芯片內(nèi)部集成有定時器和看門狗電路;工作電壓3.3 V,100引腳TQFP封裝。?
?
?
2.2 嵌入式USB主機(jī)設(shè)計?
??? 采用CY7C67300芯片實(shí)現(xiàn)嵌入式USB主機(jī),嵌入式主機(jī)結(jié)構(gòu)如圖3所示。?
?
?
??? 嵌入式主機(jī)由BIOS、框架結(jié)構(gòu)(Frameworks)和應(yīng)用驅(qū)動層(AppDrive)三部分組成。其工作原理為:Frameworks發(fā)現(xiàn)有新的設(shè)備連接時,創(chuàng)建一個device object(設(shè)備列表)并查詢是否與USB大容量存儲類驅(qū)動USB MSC Driver匹配,如果匹配,F(xiàn)rameworks則調(diào)用設(shè)備驅(qū)動程序中的start-device()函數(shù);如果不匹配,則返回繼續(xù)監(jiān)測是否有新的設(shè)備連接。在嵌入式主機(jī)結(jié)構(gòu)中,應(yīng)用程序和設(shè)備驅(qū)動程序并未完全分開,而是集成在一起稱之為AppDrive,當(dāng)AppDrive開始運(yùn)行時,它會創(chuàng)建USB請求塊URBs(USB Requst Block)給Frameworks去處理。當(dāng)URB處理完成后,F(xiàn)rameworks調(diào)用由AppDrive指定的回調(diào)函數(shù)。Frameworks利用在通用主機(jī)控制器接口UHCI(Universal Host Controller Interface)標(biāo)準(zhǔn)中定義的調(diào)度算法建立傳輸描述列表TD-List(Transfer Descriptor List)并將TD-List傳輸給EZ-HOST的BIOS去處理,BIOS返回一個新的TD-List狀態(tài)信息給Frameworks,并將TD-List內(nèi)容傳給USB總線。Frameworks開始創(chuàng)建下一幀的TD-List,TD_List結(jié)構(gòu)體定義[4]如下:?
??? typedef struct TD?
{ ? void??? *address;? ?
??? uint16? length;???? ?
??? uint16? port_num;?? ?
??? uint16? ep;????????? ?
??? uint16? pid;?????? ?
??? uint16? dev_address ; ?
??? uint8?? control;?
??? uint8?? status;?
??? uint16? retry_cnt; ?
??? uint16? retry_xfer_type;?
??? uint16? retry_active;?
??? uint16? unused_3;?
??? uint16? residue;? ?
??? struct TD?? *next_TD;?????????? ?
??? } TD;?
??? 該結(jié)構(gòu)體包含數(shù)據(jù)緩存的基地址、數(shù)據(jù)長度和端口號以及傳輸?shù)陌鼧?biāo)識pid(packet identifier)、主機(jī)給設(shè)備分配的地址、控制位和狀態(tài)位、重傳次數(shù)、傳輸類型以及傳輸是否有效等成員變量。?
2.2.1 嵌入式USB主機(jī) BIOS?
??? USB主機(jī)BIOS包含HUSB-SIE1-INIT-INT, HUSB-SIE2-INIT-INT和HUSB-RESET-INT3個軟件中斷,其中,HUSB-SIEx-INIT-INT(x=1,2)用于執(zhí)行TD-List,主要實(shí)現(xiàn)以下功能:設(shè)置SIE為主機(jī)并執(zhí)行初始化,檢測是否有等待傳輸?shù)腡D-List,如果有,繼續(xù)進(jìn)行TD-List的傳輸;通過USB傳輸所有的TD 數(shù)據(jù);更新TD狀態(tài)并對錯誤進(jìn)行處理。HUSB-RESET-INT執(zhí)行以下3個功能:USB 復(fù)位;速度檢測;幀開始SOF(Start of Frame)和包結(jié)束EOP(End of Packet)產(chǎn)生。?
2.2.2 USB主機(jī)控制器 Frameworks?
??? 自主開發(fā)USB主機(jī)固件任務(wù)相當(dāng)艱巨,而CYPRESS公司提供了大量的USB主機(jī)固件程序,系統(tǒng)在此基礎(chǔ)上可進(jìn)行修改,節(jié)約了大量的開發(fā)時間,提高了系統(tǒng)完成的效率。?
??? 當(dāng)系統(tǒng)上電時,F(xiàn)rameworks會不斷地查詢是否有新的設(shè)備連接,如果發(fā)現(xiàn)有新的設(shè)備,F(xiàn)rameworks會建立如下所示的設(shè)備對象。?
??? typedef struct USB_DEVICE?
??? {???uint8??? sie;?
????uint8??? port;?
????uint8??? address;?
??? uint8??? hub_port;?
??? uint8??? speed;?
??? uint8??? EP0_max_pkt;?
??? uint8??? enum_state;?
??? uint8??? otg_attributes;? ?
??? USB_DEVICE_DESCRIPTOR?? dev_descr;?
??? STRING_DESCRIPTOR_NODE?? dev_string_descr;?
??? uint8??? cfg_descr[];?
??? uint8??? setup_packet_buffer[]?
??? USB_INTERFACE_DESCRIPTOR? *inf_descr;?
??? USB_HUB_DESCRIPTOR????? hub_descr;?
??? void??????????????????? *hub_context;?
??? void??????????????????? *msc_context;?
??? bool??? ???????????????????? idleCheck;?
??? } USB_DEVICE;?
??? 如果該設(shè)備對象與設(shè)備驅(qū)動程序匹配,則開始填充該設(shè)備對象的信息,包括設(shè)備所在的端口、地址或集線器接口、速度、設(shè)備描述符、字符串描述符等[4]。Frameworks利用URB獲取新設(shè)備的信息,通過URB建立1個或多個TD,通過BIOS與USB總線交換信息。?
2.2.3 MSC驅(qū)動?
??? Frameworks發(fā)現(xiàn)有設(shè)備連接時,根據(jù)應(yīng)用驅(qū)動程序發(fā)出的URB獲得設(shè)備信息。U盤屬于MSC(Mass Storage Class)設(shè)備,所以必須開發(fā)MSC驅(qū)動。驅(qū)動實(shí)現(xiàn)結(jié)構(gòu)圖如圖4所示,分三層任務(wù):初始化任務(wù)Init_Task,閑置任務(wù)Idle_Task,回調(diào)任務(wù)CallBack_Tasks。其中,Init_Task負(fù)責(zé)設(shè)置Idle_Task和任何一個CallBack_Tasks、Init_Task只運(yùn)行一次,執(zhí)行完Init_Task后必須釋放其占用的內(nèi)存,把控制權(quán)交還給調(diào)用者。?
??? 每個Idle_Task建立一個Idle_Chain與上一層即應(yīng)用層(Applycation)的Idle_Task相連接,負(fù)責(zé)尋找要做的工作。?
??? CallBack_Tasks負(fù)責(zé)執(zhí)行Idle_Task尋找的工作,執(zhí)行后導(dǎo)致某些事件發(fā)生,這些事件包括硬件中斷、軟件中斷或在Idle_Task中建立的處理過程。?
??? MSC驅(qū)動是通過實(shí)現(xiàn)CLASS-DRIVE結(jié)構(gòu)體定義的成員變量函數(shù):mscdrvr_init( )、mscdrvr_start( )、mscdrvr_stop( )、mscdrvr_run( )、mscdrvr_ioctl( )實(shí)現(xiàn)的。其中CLASS_DRIVER類型mscdrvr_driver結(jié)構(gòu)體成員賦值如下:?
??? CLASS_DRIVER??? mscdrvr_driver =?
??? {?
??? 0x08,????????? /* uint8?? class;?????? */?
??? 0x00,????????? /* uint8?? subclass;??? */?
??? 0x50,????????? /* uint8? ?protocol;??? */?
??? 0x0000,??????? /* uint16? vendor_ID;?? */?
??? 0x0000,??????? /* uint16? product_ID;? */?
??? mscdrvr_init,? /* void?? (*init)( void ); */ mscdrvr_start,?
?????????????????? /*uint16 (*start)( USB_DEVICE *dev ); */?
??? mscdrvr_stop,? /* uint16 (*stop)(void);? */?
??? mscdrvr_run,???/* void?? (*run)(void);? ?
??? mscdrvr_ioctl, /* uint16 (*ioctl)( USB_DEVICE *, uint16,uint16, uint16 ); */?
??? };?
2.3 USB主機(jī)對設(shè)備的總線枚舉以及請求命令實(shí)現(xiàn)?
??? 在以CY7C67300芯片為核心實(shí)現(xiàn)的USB主機(jī)控制器中,USB總線枚舉過程如下:Frameworks通過一系列的URBs枚舉設(shè)備:包括GetDescriptor()、UsbSetConfig()、UsbSetInterface()等USB標(biāo)準(zhǔn)請求命令,建立TD_List,實(shí)現(xiàn)控制傳輸,利用控制傳輸把請求命令傳給BIOS,通過BIOS與USB總線進(jìn)行通信,取得設(shè)備一系列信息。?
2.3.1 控制傳輸?shù)膶?shí)現(xiàn)?
??? 控制傳輸較為復(fù)雜,分為 3 個步驟:初始設(shè)置、可選數(shù)據(jù)和狀態(tài)信息步驟[5]。在初始設(shè)置中需要發(fā)送 8 字節(jié)的請求命令,創(chuàng)建請求命令的結(jié)構(gòu)體如下:
??? typedef struct USB_DEVICE_REQUEST?
??? {?
??????? uint8?? bmRequestType;?
??? uint8?? bRequest??????? ?
??? uint16? wValue????????? ?
??? ??? uint16? wIndex????????? ?
??? ??? uint16? wLength???????? ?
??? } USB_DEVICE_REQUEST;?
??? 請求命令的各個字段分別為請求類型、請求命令、數(shù)值和索引以及獲取的數(shù)據(jù)長度。?
??? (1) 初始設(shè)置的實(shí)現(xiàn)?
??? 初始設(shè)置的任務(wù)就是要發(fā)送建立的 8 字節(jié)請求命令,控制傳輸?shù)脑O(shè)置信息通過端點(diǎn)0進(jìn)行傳輸。因此,設(shè)置USB_DEVICE_REQUEST指向USB_DEVICE結(jié)構(gòu)體中的setup_packet_buffer[0],設(shè)置TD結(jié)構(gòu)體的PID為PID_SETUP,端點(diǎn)號為端點(diǎn)0,TD地址為&setup_packet_buffer[0],發(fā)送內(nèi)容即為setup_packet_buffer[0]中的請求命令。?
??? (2) 可選數(shù)據(jù)的實(shí)現(xiàn)?
??? 請求命令的 wLength 字段指明了需要交換的數(shù)據(jù)長度,當(dāng)值為0時表示沒有可選數(shù)據(jù);當(dāng)值不為0時,設(shè)置TD結(jié)構(gòu)體中的pid為PID_IN(數(shù)據(jù)傳輸方向?yàn)樵O(shè)備到主機(jī))及PID_OUT(主機(jī)到設(shè)備)。length為傳輸數(shù)據(jù)的長度,address為&setup_packet_buffer[0],發(fā)送的內(nèi)容即為setup_packet_buffer[0]中的數(shù)據(jù)。?
??? (3) 狀態(tài)信息的實(shí)現(xiàn)?
??? 在這個步驟中,主機(jī)發(fā)送控制傳輸?shù)臓顟B(tài)信息,實(shí)現(xiàn)過程如下:設(shè)置TD結(jié)構(gòu)體中的PID為PID_OUT,端點(diǎn)地址為0,發(fā)送setup_packet_buffer[0]中的狀態(tài)信息。?
2.3.2請求命令實(shí)現(xiàn)?
??? 表3為獲取設(shè)備描述符和字符串描述符的設(shè)備請求命令封裝,其中設(shè)備描述符、語言ID和字符串描述符請求命令的bmRequestType字段為1 000 000,其D7=1說明數(shù)據(jù)傳輸?shù)姆较蚴窃O(shè)備至主機(jī),D6..5=00表示為標(biāo)準(zhǔn)請求,D4..0=00 000表示為請求命令的接收端為設(shè)備。bRequest字段的內(nèi)容都為Get_Descriptor,因?yàn)樵O(shè)備描述符中含有語言ID和字符串描述符的索引,所以字符串描述符和語言ID的獲取都是通過獲取設(shè)備描述符實(shí)現(xiàn)的。Get_Descriptor命令的wValue字段為0100,01代表描述符類型為設(shè)備描述符,00為描述符索引。wIndex字段為0,wLength為設(shè)備描述符結(jié)構(gòu)體的長度。Get_LanguageID命令的wValue為0300,03代表描述符類型為字符串描述符,00為描述符索引;wIndex為0,wLength為字符串描述符長度。這個命令是獲取U盤的語言ID,使語言ID作為獲取字符串描述符命令的wIndex字段值,Get_Str_Descriptor命令的wValue為0303,descriptor_type為03代表該描述符為字符串描述符,descriptor_index為03說明獲取U盤序列號的索引值為03,獲取的字符串描述符的長度wLength為字符串描述符長度。?
?
?
???? 系統(tǒng)根據(jù)請求命令封裝,分別實(shí)現(xiàn)Get_Descriptor()、Get_LanguageID()、Get_Str_Descriptor()函數(shù),利用這些函數(shù)的返回值得到U盤的唯一性標(biāo)識信息。?
3 調(diào)試結(jié)果?
??? 采用CYPRESS公司提供的軟件工具GNUPro作為調(diào)試工具。UART串口與PC主機(jī)的超級終端連接,當(dāng)U盤插入系統(tǒng)時,超級終端上會自動輸出該U盤的VID、PID和iSerialNumber。?
??? 獲取U盤的唯一性標(biāo)識的4個示例結(jié)果如下:?
??? vid=0x066f?
??? pid=0x8000?
??? Serialn==3?
??? LanguageID=0x0409?
??? descriptorlength=0x0022?
??? iserialnumber=0002F68C2AC54D98?
??? ?
??? vid=0x0204?
??? pid=0x6025?
??? serialn==3?
??? LanguageID | =0x0409?
??? descriptorlength=0x0022?
??? iserialnumber=05185200BA923502?
??? vid=0x0951?
??? pid=0x160b?
??? serialn==3?
??? LanguageID = 0x0409?
??? descriptorlength=0x0032?
??? iserialnumber=0014780F99515C8718080051?
??? vid=0x090c?
??? pid=0x1000?
??? serialn==3?
??? LanguageID = 0x0409?
??? descriptorlength=0x0022?
??? iserialnumber=AA04012700007705?
??? 本文提出了一種U盤唯一性標(biāo)識的構(gòu)建和識別方法;設(shè)計了以CY7C67300為核心芯片的USB主機(jī)控制器,利用該主機(jī)控制器可完成USB總線枚舉、控制傳輸和請求命令,根據(jù)請求命令對U盤唯一性標(biāo)識進(jìn)行識別。利用U盤的唯一性標(biāo)識,可以實(shí)現(xiàn)涉密存儲介質(zhì)的網(wǎng)絡(luò)化管理,遠(yuǎn)程監(jiān)控中心可實(shí)時監(jiān)控U盤的狀態(tài)(借出、歸還),結(jié)合相關(guān)的保密管理規(guī)定,就可以及時發(fā)現(xiàn)涉密U盤管理、使用的違規(guī)行為后及時報警。這種新穎的U盤唯一性標(biāo)識信息的構(gòu)建與識別方法,為涉密U盤的網(wǎng)絡(luò)化、智能化保密管理奠定了基礎(chǔ)。?
參考文獻(xiàn)?
[1] Universal serial bus mass storage class control/bulk/interrupt (CBI) transport revision 1.1[S]. 2003-06-23. ?
[2] Universal serial bus mass storage class bulk-only transport specification revision1.0[S].http://www.usb.org/developers/docs, 1999-09-31.?
[3] 劉思久,李文文,段天明.嵌入式通用USB-Host控制器[J].電測與儀表,2006,43(7):63-66.?
[4] HYDE J. USB multi-role device design by example[M].CYPRESS, 2003.?
[5] 譚剛. 基于MCF5249的USB主機(jī)的設(shè)計與實(shí)現(xiàn)[D].成都:電子科技大學(xué),2005.