Zxcrypt

總覽

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++ 編寫的兩小功能:

  • 使用 DDK 的 C 預先處理器巨集編寫的驅動程式繫結邏輯 binding.h
  • ulib/sync 的完成常式,用於同步 I/O 且與 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」在發布模式中略過的斷言。