總覽
zxcrypt 是區塊裝置篩選器驅動程式庫,會公開加密寫入和 以及從封鎖裝置讀取的資料解密。zxcrypt 裝置的基礎區塊裝置 使用的可能是任何區塊裝置,包括原始磁碟、ramdisks、GPT 分區、FVM 分區 甚至是其他 zxcrypt 裝置唯一的限制是區塊大小必須透過網頁對齊。一次 繫結,zxcrypt 裝置會在裝置樹狀結構中發布另一個區塊裝置,以供使用者 互動。
用量
zxcrypt 同時包含驅動程式和 library
libzxcrypt.so 是管理 zxcrypt 裝置的四種功能。每一步都會
zxcrypt_key_t
索引鍵,可在有多個索引鍵的情況下與索引鍵資料、長度和運算單元建立關聯。
- zxcrypt_format 函式會取用開放區塊裝置,然後寫入必要的加密 將其設定為 zxcrypt 裝置所提供的 zxcrypt 金鑰無法保護 用於保護資料金鑰內容,但可用於保護資料金鑰內容。
zx_status_t zxcrypt_format(int fd, const zxcrypt_key_t* key);
- zxcrypt_bind 函式會指示驅動程式庫讀取加密的中繼資料,並擷取 資料金鑰內容,以公開透明的方式轉換 I/O 資料。
zx_status_t zxcrypt_bind(int fd, const zxcrypt_key_t *key);
- zxcrypt_rekey 函式會使用舊金鑰先行讀取已加密的中繼資料,以及 輸入反轉指令。
zx_status_t zxcrypt_rekey(int fd, const zxcrypt_key_t* old_key, const zxcrypt_key_t* new_key);
- zxcrypt_shred 函式會先驗證呼叫端是否能使用按鍵存取資料 來讀取加密中繼資料。如果連線成功,此規則就會刪除 內含資料金鑰內容的中繼資料這麼做可防止日後再存取資料。
zx_status_t zxcrypt_shred(int fd, const zxcrypt_key_t* key);
技術詳細資料
DDKTL 驅動程式
zxcrypt 是以 DDKTL 裝置驅動程式的形式編寫。src/lib/ddktl 是 C++ 架構 。可讓作者自動提供 src/lib/ddk 函式指標和回呼 (使用範本混合型混合)。
無法使用 DDKTL 和 C++ 編寫的兩小功能:
工作站執行緒
裝置會啟動長時間執行的工作站執行緒 並為所有 I/O 要求建立管道。每個容器都有各自的 I/O 類型 等候處理的傳入要求 I/O 以及資料加密。收到要求後 如果運算碼符合其尋找,它就會使用其密碼來轉換 再傳送要求
整個管道如下所示:
DdkIotxnQueue -+
\ Worker 1: Underlying Worker 2: Original
BlockRead ---+---> Encrypter ---> Block ---> Decrypter ---> Completion
/ Acts on writes Device Acts on reads Callback
BlockWrite -+
「加密者」工作站會先將每個 I/O 寫入要求中的資料加密,再傳送至 基礎區塊裝置與「解密者」工作站會將每個 I/O 讀取回應中的資料解密 來自基礎區塊裝置 cipher 的金鑰長度必須至少為 16 個位元組。 「語意層安全性」(IND-CCA2) 並將區塊偏移納入為 「微調」。AES256-XTS 目前使用中。
戒指和指揮棒
為了讓原始 I/O 要求者保持公開資料的加密與解密作業, 工作站在轉換資料時必須複製資料。透過管道傳送的 I/O 要求 實際要求,而是「影子」可以封裝 請求。
需要影子要求時,系統會按照 VMO。當 工作站需要轉換資料,也就是從已封裝的原始寫入資料中加密資料 直接傳送至影子要求,或是將陰影要求中的資料解密為原始 封裝的讀取要求。原要求可以等回歸原始要求 在要求者提出的情況下,系統就會取消配置該陰影要求,並顯示其頁面「decommit」。 這樣可以確保在待處理的 I/O 要求中,不需使用額外的記憶體。
超級封鎖格式
用來加密及解密資料的金鑰內容稱為「資料金鑰」,
儲存在裝置的保留部分中,名為 superblock
。這個超級區塊的存在
至關重要如果沒有資料,就無法重新建立資料鍵並復原
裝置。因此,超級區塊會複製到裝置上的多個位置以提供備援。
zxcrypt 封鎖裝置使用者無法查看這些位置。每當 zxcrypt 驅動程式庫
成功讀取並驗證某位置的超級區塊後,就會將此程式碼複製到所有其他位置
超封鎖位置方便您「自傷」以免發生毀損的超級區塊
超區塊格式如下,依序描述每個欄位:
+----------------+----------------+----+-----...-----+----...----+------...------+
| Type GUID | Instance GUID |Vers| Sealed Key | Reserved | HMAC |
| 16 bytes | 16 bytes | 4B | Key size | ... | Digest length |
+----------------+----------------+----+-----...-----+----...----+------...------+
- 輸入 GUID:表示這是 zxcrypt 裝置。相容於 GPT。
- 執行個體 GUID:每部裝置 ID,如下所述做為 KDF 鹽。
- 版本:用來指出要使用的密碼編譯演算法。
- 密封金鑰:資料金鑰,由包裝金鑰加密,說明如下。
- 保留:未使用的資料,讓超區塊與區塊邊界對齊。
- HMAC:到目前為止的超區塊金鑰摘要 (包括保留欄位)。
包裝金鑰、包裝 IV 和 HMAC 金鑰衍生自 KDF。這個 KDF 是 RFC 5869 HKDF, 結合所提供的鍵,「salt」執行個體 GUID 和用途標籤,例如「包裝」或 「hmac」。KDF 不會嘗試任何頻率限制。KDF 可降低金鑰重複使用的風險 視為新的隨機例項鹽,就會產生新的衍生金鑰。 HMAC 可防範意外或惡意修改 而不會洩漏任何關於 zxcrypt 金鑰的實用資訊。
_注意:KDF 不會執行任何鍵延展作業。可以假設攻擊者可以 移除裝置並嘗試自行嘗試金鑰衍生,略過 HMAC 檢查與任何 可能的頻率限制為防止這種情況發生,zxcrypt 消費者應在適當的情況下加入速率限制 裝置金鑰,例如來自 TPM,以衍生 zxcrypt 金鑰。_
未來工作
以下列舉幾項應進一步工作或應盡的部分:
途徑隱藏繫結失敗
目前,即使裝置無法初始化,
zxcrypt_bind
可能仍表示成功。 當繫結邏輯發生以下情形時,「不會」同步將裝置新增至裝置樹狀結構中 此程序的第一步 是將程式碼簽入執行所有單元測試的存放區中它必須執行 I/O 且不能禁止傳回對device_bind
的呼叫,因此它會產生 初始化器執行緒,並在完成後新增裝置。自 2017 年 10 月 10 日起,這是 DDK 開發的活躍領域,政策有所異動 並呼叫稍後要發布的裝置。 此時,您可能需要對呼叫端同步呼叫
zxcrypt_bind
區塊 直到裝置準備就緒或無明確的繫結失敗為止。使用 AEAD 而非 AES-XTS
大眾普遍認為 AEAD 藉由驗證憑證提供優異的加密功能 的完整性。這很理想,但需要額外 每個區塊的負擔這表示消費者必須使用未與網頁對齊的區塊 (移除內嵌負擔之後) 或 zxcrypt 需要存放外部的基礎架構 處理非不可部分完成的寫入失敗。
支援多個金鑰
如要促進金鑰託管和/或復原,只要修改超級區塊即可 格式,以便加上一系列的密碼編譯信封。為此,libzxcrypt API 會使用任意數量的索引鍵,但目前只支援 1,且 有效版位為 0。
調整工作站數量
目前有一個加密程式和一個解密工具。這套系統專為任意選用 因此,效能調整可能需要找出最理想的工作站數量。 透過排程器流失平衡 I/O 頻寬。
移除內部檢查
目前,zxcrypt 程式碼會檢查內部邊界的多種錯誤狀況,並傳回 表示錯誤訊息。對於成效範圍來說 程式設計師才會發生錯誤,對於要求者或基礎裝置的資料都不會有 轉換為「debug」在發布模式中略過的斷言。