物聯網(IoT)是指由產生和/或使用資料的連網裝置、元件或服務所組成的系統。物聯網應用逐漸成為人們生活中不可或缺的一部份:從工業機器人和手術器械,到自動駕駛車和自主飛行的無人機等。今天,很多這一類裝置已經對使用者的安全、隱私和防護產生影響,有一些甚至是致命的。因此,為物聯網裝置制定通用標準至關重要。

如果軟體設計一開始就能符合規範當然是最好的,但眾所周知,嚴格的開發流程,特別是在未能實現自動化的情況下,可能會影響產品的上市時間。沒有幾個開發人員願意加班完成額外的測試工作並記錄可追溯性,因此,如果耗時費力地建立合規性只是出於將來「可能需要」,那麼,並不值得讓務實、敏捷和快速的開發團隊為此傷元氣。相反地,許多團隊相信「船到橋頭自然直」。

然而,沒有什麼魔法可以讓時光倒流而使得程式碼從一開始就符合規範。這些團隊最後得到的教訓是,等專案結束時再考慮合規性所需的成本,比開發之初就考慮的成本要高出好幾倍。

所以,為了滿足未來嚴格的規範要求,現在可以採取哪些措施以有效減少衝擊呢?

措施1:清楚瞭解自己的技術負債

瞭解開發專案當前的狀況非常重要。由於程式碼太複雜,加上程式碼中存在任何原本的編碼標準與安全違規,因而需要重新編寫程式碼的代價即為「技術負債」(technical debt)。技術負債來自隨後要完成的程式碼清理、修復和測試。靜態程式碼自動分析是掌握專案當前狀況的一種方法,它可以對程式碼基礎的品質和安全性進行深入分析,並列出編碼標準的違規(如果有的話)事件。

然而,許多採用C和C++語言開發嵌入式應用的團隊並未採用靜態分析法,而是依賴編譯器或透過手動檢查程式碼來查找問題。有些團隊因為各種原因而難以決定是否使用靜態分析工具,例如他們發現靜態分析工具雜訊太多且很難使用,或者由於緊急的日常事務而無法將其納入日常開發流程。一種常見的誤解是,確定哪些違規值得修復所花的時間,遠超過實際修復的價值。

但我們發現,如果團隊在專案的前期就強制地採用一小部份重要規則,那麼當專案後期面臨功能安全審查時,重新編寫程式碼花費的時間就少得多。如果從一開始就將安全性植入其中,例如實施CERT C安全編碼規則(Secure Coding Guidelines),則更容易打造出安全可靠的系統。我們可以從簡單的規則開始。CERT擁有複雜的優先順序系統(包含嚴重性、可能性和補救成本三個指標,每個指標分為3個等級,總共27個級別),如果使用自動化測試工具,通常很容易在預先配置好的控制台查看合規狀態。

靜態分析透過採集資料點,協助管理安全與防護合規性,使公司能夠瞭解其技術負債。管理人員可以輕鬆評估一些重要的問題,例如:

  • 底線是什麼?程式庫中不嚴重的編碼違規有多少?
  • 趨向資料:是否每個新版本都回報了新出現和已修復的違規?情況好轉還是更糟了?
  • 目前的程式碼複雜度如何?持續增加嗎?

有些標準要求測量循環複雜度(cyclomatic complexity;由Thomas J. McCabe提出),以使其保持低於某個閾值。複雜度指標也可用於估算測試工作量──例如,證明100%分支級覆蓋率以符合IEC 61508 SIL 2標準所需要的測試案例數,將會與一項功能的McCabe循環複雜度成正比。

圖1的例子來自一個控制台,顯示某專案的MISRA合規性。

MISRA-compliance

圖1:專案的MISRA合規性。

圖2顯示的是CERT合規性。

CERT-C

圖2:專案的CERT合規性。

查看程式碼指標的價值可能有助於暴露出更複雜的區域,從而進行更多的程式碼檢查,並監控測試是否足以涵蓋這些區域。圖3是Metrics控制台示例。

Metrics-Dashboard

圖2:Metrics控制台示例。

首先從基本的開始。一旦開發團隊能夠輕鬆地管理最嚴重的錯誤,就可以增加管理標準違規的範圍。並非所有規則都是「一成不變」的,因此決定將哪些規則納入專案編碼標準非常重要。在一些關鍵編碼標準中至少採用一組強制性的規則(例如MISRA強制性規範或CERT C規則),將使連網裝置未來的安全與防護論證變得更容易。

措施2:建立合格的單元測試架構並測量程式碼覆蓋率

大多數務實的工程師都會認同,盲目地為所有功能設置單元測試並不能獲得良好的投資報酬率(ROI)。但是,如果開發團隊可以存取的單元測試架構是專案Sandbox安全機制的一部份,那麼這就是一項有價值的投資。當需要單獨測試某些複雜的演算法或資料操作時,可以根據實際情況來選擇進行單元測試。開發單元測試這個過程本身也很有價值——從組織的角度來看,僅僅是編寫和執行單元測試就可以使程式碼更加穩健且設計得更好。

當安全與防護的合規要求增加時,組織只需臨時增加測試人員,就可加快單元測試作業。但要快速地擴展測試任務,就需要在整個專案進程中瞭解並記錄單元測試架構和流程。一個考慮未來合規性的可擴展單元測試架構應該具有以下特性:

  • 適合特定安全標準的應用(例如通過TÜV認證)
  • 整合於自動建置系統(build system)中
  • 報告所需的程式碼覆蓋率指標(例如MC/DC)
  • 按時間記錄每次建置完成的測試結果和覆蓋範圍
  • 適用於多個專案和開發團隊**

最重要的是,要以最小的規模來部署未來安全標準需要的所有測試技術。這樣的話,如果需要認證時就更容易擴展,而不用從頭開始。

措施3:隔離關鍵功能

架構嵌入式系統需要考慮大量的「非功能需求」,如簡單性、可攜式、可維護性、可擴展性和可靠度,同時還要綜合考慮延遲、輸送量、功耗和尺寸限制等因素。在設計可能與大型物聯網生態系統互連的系統架構時,許多團隊優先考慮的是一些與品質相關因素,而不只是安全與防護。

如果將元件在時間和空間上分離出來,未來它們便更容易符合安全規範(並具有良好的架構)。例如,在設計系統時,可以將所有的關鍵操作都放在單獨的專用CPU上執行,所有的非關鍵操作放在另一個CPU上執行,從而實現實體的隔離。另一種方法是採用分離核心的管理程式(Separation Kernel Hypervisor)和微核心(Microkernel)的概念。當然還有其它方法,但重點是要儘早採用關鍵架構方法,如關注點分離、深度防禦和混合關鍵性分離。這些方法不僅減少了遵守安全與防標護準所需的工作量,還提高了應用的品質與彈性。例如,以下是隔離關鍵程式碼的一些方法:

例如,以下是隔離關鍵程式碼的一些方法:

  • 空間域:檔案、模組、目錄、工具庫
  • 執行域:執行緒、RTOS任務、虛擬機器監控程式、 CPU核心、獨立CPU

將關鍵功能與非關鍵功能隔離開來,等到未來檢查合規性時,驗證範圍就可以縮小。

結語

物聯網生態系統中的許多邊緣裝置提供關鍵性服務,它們可能需要符合未來的安全與防護標準。努力滿足標準要求卻不管是否真正需要,顯然並不是一種划算的方法。但我們還是應該為未來做好準備,例如採用關鍵設計技術、單元測試方法和靜態分析工具,同時收集各項指標資料來支援未來的需求。如果儘早啟動,軟體開發團隊就可以將這些方法無縫導入現有流程中。同時也應儘早採用具有可擴展性的正確方法,以避免在開發、測試和部署軟體時必須花費更大的力氣來讓程式碼符合規範。

(參考原文:3 Practical Ways to Future-Proof Your IoT Devices,by Andrey Madan)

本文同步刊登於電子技術設計雜誌2019年11月號