Kerberos V 加密 API¶
概述¶
此 API 提供 Kerberos 5 風格的加密功能,用於金鑰派生、加密和校驗,可用於網路檔案系統,也可用於實現 GSSAPI 所需的低階加密。
支援以下加密型別
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192
KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC
KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC
KRB5_CKSUMTYPE_HMAC_SHA1_96_AES128
KRB5_CKSUMTYPE_HMAC_SHA1_96_AES256
KRB5_CKSUMTYPE_CMAC_CAMELLIA128
KRB5_CKSUMTYPE_CMAC_CAMELLIA256
KRB5_CKSUMTYPE_HMAC_SHA256_128_AES128
KRB5_CKSUMTYPE_HMAC_SHA384_192_AES256
API 可透過以下方式包含
#include <crypto/krb5.h>
小型緩衝區¶
為了傳遞小塊資料(如金鑰),定義了一個緩衝區結構,提供資料指標和資料大小。
struct krb5_buffer {
unsigned int len;
void *data;
};
編碼型別¶
編碼型別由以下結構定義
struct krb5_enctype {
int etype;
int ctype;
const char *name;
u16 key_bytes;
u16 key_len;
u16 Kc_len;
u16 Ke_len;
u16 Ki_len;
u16 prf_len;
u16 block_len;
u16 conf_len;
u16 cksum_len;
...
};
對 API 使用者感興趣的欄位如下
etype和ctype分別表示此編碼型別用於加密和校驗的協議號。它們包含KRB5_ENCTYPE_*和KRB5_CKSUMTYPE_*常量。
name是編碼的正式名稱。
key_len和key_bytes是輸入金鑰長度和派生金鑰長度。(我認為它們只對 DES 不同,這裡不支援 DES)。
Kc_len、Ke_len和Ki_len是派生 Kc、Ke 和 Ki 金鑰的大小。Kc 用於校驗模式;Ke 和 Ki 用於加密模式。
prf_len是 PRF+ 函式計算結果的大小。
block_len、conf_len和cksum_len分別是加密塊長度、混淆器長度和校驗和長度。這三者都用於加密模式,但只有校驗和長度用於校驗模式。
編碼型別透過以下函式按編號查詢
const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype);
金鑰派生¶
一旦應用程式選擇了加密型別,用於實際加密的金鑰就可以從傳輸金鑰派生出來。
PRF+ 計算¶
為幫助金鑰派生,提供了一個計算 Kerberos GSSAPI 機制的 PRF+ 函式
int crypto_krb5_calc_PRFplus(const struct krb5_enctype *krb5,
const struct krb5_buffer *K,
unsigned int L,
const struct krb5_buffer *S,
struct krb5_buffer *result,
gfp_t gfp);
這可用於從源金鑰加上額外資料來派生傳輸金鑰,以限制其使用。
加密函式¶
一旦金鑰派生完成,就可以對資料執行加密操作。呼叫者在準備要傳輸的訊息時,必須在緩衝區中為混淆器(如果需要)和校驗和的儲存留出間隙。為此提供了一個列舉和一對函式
enum krb5_crypto_mode {
KRB5_CHECKSUM_MODE,
KRB5_ENCRYPT_MODE,
};
size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t data_size, size_t *_offset);
size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_buffer_size, size_t *_offset);
所有這些函式都接受編碼型別和加密模式指示(僅校驗和或完全加密)。
第一個函式返回容納給定資料量所需的緩衝區大小;第二個函式返回特定大小的緩衝區可容納多少資料,並相應地調整所需緩衝區的大小。在這兩種情況下,資料在緩衝區內的偏移量也會返回。
當收到訊息時,可以透過呼叫以下函式確定訊息中資料的位置和大小
void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_offset, size_t *_len);
呼叫者向函式提供訊息的偏移量和長度,然後函式會更改這些值以指示包含資料的區域(加上任何填充)。由呼叫者確定有多少填充。
準備函式¶
提供了兩個函式來分配和準備加密物件,以便供動作函式使用
struct crypto_aead *
crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
u32 usage, gfp_t gfp);
struct crypto_shash *
crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
u32 usage, gfp_t gfp);
這兩個函式都接受編碼型別、傳輸金鑰以及用於派生適當子金鑰的使用值。它們建立一個適當的加密物件,一個用於加密的 AEAD 模板和一個用於校驗和的同步雜湊,並在其上設定金鑰並進行配置。呼叫者應將這些控制代碼傳遞給下面的動作函式。
加密模式¶
提供一對函式來加密和解密訊息
ssize_t crypto_krb5_encrypt(const struct krb5_enctype *krb5,
struct crypto_aead *aead,
struct scatterlist *sg, unsigned int nr_sg,
size_t sg_len,
size_t data_offset, size_t data_len,
bool preconfounded);
int crypto_krb5_decrypt(const struct krb5_enctype *krb5,
struct crypto_aead *aead,
struct scatterlist *sg, unsigned int nr_sg,
size_t *_offset, size_t *_len);
在這兩種情況下,輸入和輸出緩衝區都由相同的雜湊列表指示。
對於加密函式,輸出緩衝區可能大於所需(返回生成的輸出量),並且指示了資料的位置和大小(必須與編碼匹配)。如果未設定混淆器,函式將插入一個。
對於解密函式,提供訊息在緩衝區中的偏移量和長度,並將其縮小以適應資料。解密函式將驗證訊息中的任何校驗和,如果不匹配則返回錯誤。
校驗和模式¶
提供一對函式來生成訊息的校驗和並驗證該校驗和
ssize_t crypto_krb5_get_mic(const struct krb5_enctype *krb5,
struct crypto_shash *shash,
const struct krb5_buffer *metadata,
struct scatterlist *sg, unsigned int nr_sg,
size_t sg_len,
size_t data_offset, size_t data_len);
int crypto_krb5_verify_mic(const struct krb5_enctype *krb5,
struct crypto_shash *shash,
const struct krb5_buffer *metadata,
struct scatterlist *sg, unsigned int nr_sg,
size_t *_offset, size_t *_len);
在這兩種情況下,輸入和輸出緩衝區都由相同的雜湊列表指示。可以傳入額外的元資料,這些元資料將在資料之前新增到雜湊中。
對於 get_mic 函式,輸出緩衝區可能大於所需(返回生成的輸出量),並且指示了資料的位置和大小(必須與編碼匹配)。
對於驗證函式,提供訊息在緩衝區中的偏移量和長度,並將其縮小以適應資料。如果校驗和不匹配,將返回錯誤。
krb5enc AEAD 演算法¶
提供了一個名為“krb5enc”的模板 AEAD 加密演算法,它在加密明文之前對其進行雜湊處理(與 authenc 相反)。crypto_krb5_prepare_encryption() 返回的控制代碼可能是其中之一,但此 API 的使用者沒有直接與其互動的要求。
作為參考,其金鑰格式以格式號的 BE32 開始。只提供了格式 1,其後是 Ke 金鑰長度的 BE32,然後是 Ki 金鑰長度的 BE32,接著是 Ke 金鑰的位元組,然後是 Ki 金鑰。
使用特定順序的單詞意味著靜態測試資料不需要位元組序轉換。