塊密碼演算法定義

這些資料結構定義了模組化加密演算法實現,透過 crypto_register_alg() 和 crypto_unregister_alg() 進行管理。

struct cipher_alg

單塊對稱密碼定義

定義:

struct cipher_alg {
    unsigned int cia_min_keysize;
    unsigned int cia_max_keysize;
    int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen);
    void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
    void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
};

成員

cia_min_keysize

轉換支援的最小金鑰大小。這是此轉換演算法支援的最小金鑰長度。必須將其設定為預定義的值之一,因為它不是硬體特定的。可以透過 git grep “_MIN_KEY_SIZE” include/crypto/ 找到此欄位的可能值

cia_max_keysize

轉換支援的最大金鑰大小。這是此轉換演算法支援的最大金鑰長度。必須將其設定為預定義的值之一,因為它不是硬體特定的。可以透過 git grep “_MAX_KEY_SIZE” include/crypto/ 找到此欄位的可能值

cia_setkey

設定轉換的金鑰。此函式用於將提供的金鑰程式設計到硬體中,或將金鑰儲存在轉換上下文中以供以後程式設計。請注意,此函式會修改轉換上下文。此函式可以在轉換物件的整個生命週期中被多次呼叫,因此必須確保金鑰已正確重新程式設計到硬體中。此函式還負責檢查金鑰長度的有效性。

cia_encrypt

加密單個塊。此函式用於加密單個數據塊,該資料塊必須是 cra_blocksize 大小。此函式始終對完整的 cra_blocksize 進行操作,並且無法加密較小大小的塊。因此,提供的緩衝區也必須至少為 cra_blocksize 大小。輸入和輸出緩衝區始終與 cra_alignmask 對齊。如果加密 API 使用者提供的輸入或輸出緩衝區未與 cra_alignmask 對齊,則加密 API 將重新對齊緩衝區。重新對齊意味著將分配一個新的緩衝區,資料將被複制到新緩衝區中,然後在新的緩衝區上進行處理,然後將資料複製回原始緩衝區,最後釋放新的緩衝區。如果在 cra_init 呼叫中設定了軟體回退,則如果演算法不支援所有金鑰大小,則此函式可能需要使用回退。如果金鑰儲存在轉換上下文中,則可能需要在該函式中將金鑰重新程式設計到硬體中。此函式不應修改轉換上下文,因為可以與同一轉換物件並行呼叫此函式。

cia_decrypt

解密單個塊。這是 cia_encrypt 的反向對應項,並且條件完全相同。

描述

所有欄位都是必需的,必須填寫。

struct crypto_alg

加密密碼演算法的定義

定義:

struct crypto_alg {
    struct list_head cra_list;
    struct list_head cra_users;
    u32 cra_flags;
    unsigned int cra_blocksize;
    unsigned int cra_ctxsize;
    unsigned int cra_alignmask;
    unsigned int cra_reqsize;
    int cra_priority;
    refcount_t cra_refcnt;
    char cra_name[CRYPTO_MAX_ALG_NAME];
    char cra_driver_name[CRYPTO_MAX_ALG_NAME];
    const struct crypto_type *cra_type;
    union {
        struct cipher_alg cipher;
    } cra_u;
    int (*cra_init)(struct crypto_tfm *tfm);
    void (*cra_exit)(struct crypto_tfm *tfm);
    void (*cra_destroy)(struct crypto_alg *alg);
    struct module *cra_module;
};

成員

cra_list

內部使用

cra_users

內部使用

cra_flags

描述此轉換的標誌。請參閱 include/linux/crypto.h CRYPTO_ALG_* 標誌以獲取此處使用的標誌。這些標誌用於微調轉換演算法的描述。

cra_blocksize

此轉換的最小塊大小。可以使用此演算法轉換的最小可能單元的位元組大小。使用者必須遵守此值。對於 HASH 轉換,可以將小於 cra_blocksize 的塊傳遞給加密 API 進行轉換,對於任何其他轉換型別,如果嘗試轉換小於 cra_blocksize 的塊,將返回錯誤。

cra_ctxsize

轉換的操作上下文的大小。此值告知核心加密 API 需要為轉換上下文分配的記憶體大小。

cra_alignmask

對於 cipher、skcipher、lskcipher 和 aead 演算法,此值比演算法實現對輸入和輸出緩衝區要求的對齊方式(以位元組為單位)少 1。當使用未與此對齊方式對齊的緩衝區呼叫加密 API 時,加密 API 會自動使用適當對齊的臨時緩衝區來滿足演算法的需求。(對於 scatterlist,僅當演算法使用 skcipher_walk 輔助函式時才會發生這種情況。)這種未對齊處理會帶來效能損失,因此最好演算法不要設定非零的 alignmask。此外,加密 API 使用者可能希望分配與所使用演算法的 alignmask 對齊的緩衝區,以避免 API 必須重新對齊它們。注意:hash 演算法不支援 alignmask,並且對於它們始終為 0。

cra_reqsize

此演算法的請求上下文的大小。

cra_priority

此轉換實現的優先順序。如果多個具有相同 cra_name 的轉換可用於加密 API,則核心將使用具有最高 cra_priority 的轉換。

cra_refcnt

內部使用

cra_name

轉換演算法的通用名稱(可由多個實現使用)。這是轉換本身的名稱。核心在查詢特定轉換的提供程式時使用此欄位。

cra_driver_name

轉換提供程式的唯一名稱。這是轉換提供程式的名稱。這可以是任何任意值,但在通常情況下,它包含晶片或提供程式的名稱以及轉換演算法的名稱。

cra_type

加密轉換的型別。這是指向 struct crypto_type 的指標,該結構實現所有轉換型別通用的回撥。有多個選項,例如 crypto_skcipher_typecrypto_ahash_typecrypto_rng_type。此欄位可能為空。在這種情況下,沒有通用回撥。這是以下情況:cipher。

cra_u

實現轉換的回撥。這是多個結構的聯合。根據 cra_type 和上面的 cra_flags 選擇的轉換型別,必須使用回撥填充關聯的結構。此欄位可能為空。這是 ahash、shash 的情況。

cra_u.cipher

聯合成員,包含單塊對稱密碼定義。請參閱 struct cipher_alg

cra_init

已棄用,請勿使用。

cra_exit

已棄用,請勿使用。

cra_destroy

內部使用

cra_module

此轉換實現的所有者。設定為 THIS_MODULE

描述

struct crypto_alg 描述了一個通用的加密 API 演算法,並且對於所有轉換都是通用的。此處未記錄的任何變數不應被密碼實現使用,因為它在加密 API 內部使用。

對稱金鑰密碼 API

對稱金鑰密碼 API 與型別為 CRYPTO_ALG_TYPE_SKCIPHER 的密碼一起使用(在 /proc/crypto 中列為 “skcipher” 型別)。

非同步密碼操作意味著密碼請求的函式呼叫在操作完成之前立即返回。密碼請求被排程為一個單獨的核心執行緒,因此透過程序排程程式在不同的 CPU 上進行負載平衡。為了允許核心加密 API 通知呼叫者密碼請求的完成情況,呼叫者必須提供一個回撥函式。當請求完成時,將使用密碼控制代碼呼叫該函式。

為了支援非同步操作,必須向核心加密 API 提供除密碼控制代碼之外的其他資訊。透過填寫 skcipher_request 資料結構來提供該附加資訊。

對於對稱金鑰密碼 API,狀態由 tfm 密碼控制代碼維護。單個 tfm 可以在多個呼叫中並行使用。對於非同步塊密碼呼叫,除了用於密碼請求的 IV 之外,呼叫者提供並僅使用的上下文資料可以在請求資料結構中引用。維護此類狀態資訊對於加密驅動程式實現者來說很重要,因為在密碼操作完成時呼叫回撥函式時,如果並行呼叫了多個密碼操作,則該回調函式可能需要一些有關剛完成的操作的資訊。核心加密 API 不使用此狀態資訊。

struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, u32 type, u32 mask)

分配對稱金鑰密碼控制代碼

引數

const char *alg_name

是 skcipher 密碼的 cra_name / name 或 cra_driver_name / driver name

u32 type

指定密碼的型別

u32 mask

指定密碼的掩碼

描述

為 skcipher 分配密碼控制代碼。返回的 struct crypto_skcipher 是該 skcipher 的任何後續 API 呼叫所需的密碼控制代碼。

返回

成功分配的密碼控制代碼;如果 IS_ERR() 為真,則表示發生

錯誤,PTR_ERR() 返回錯誤程式碼。

void crypto_free_skcipher(struct crypto_skcipher *tfm)

清零並釋放密碼控制代碼

引數

struct crypto_skcipher *tfm

要釋放的密碼控制代碼

描述

如果 tfm 是 NULL 或錯誤指標,則此函式不執行任何操作。

int crypto_has_skcipher(const char *alg_name, u32 type, u32 mask)

搜尋 skcipher 的可用性。

引數

const char *alg_name

是 skcipher 的 cra_name / name 或 cra_driver_name / driver name

u32 type

指定 skcipher 的型別

u32 mask

指定 skcipher 的掩碼

返回

當核心加密 API 知道 skcipher 時為 true;否則為 false

否則為 false

unsigned int crypto_skcipher_ivsize(struct crypto_skcipher *tfm)

獲取 IV 大小

引數

struct crypto_skcipher *tfm

密碼控制代碼

描述

返回由密碼控制代碼引用的 skcipher 的 IV 大小。如果密碼不需要 IV,則此 IV 大小可能為零。

返回

IV 大小(以位元組為單位)

unsigned int crypto_skcipher_blocksize(struct crypto_skcipher *tfm)

獲取密碼的塊大小

引數

struct crypto_skcipher *tfm

密碼控制代碼

描述

返回使用密碼控制代碼引用的 skcipher 的塊大小。呼叫者可以使用該資訊為加密或解密操作返回的資料分配適當的記憶體

返回

密碼的塊大小

int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)

為密碼設定金鑰

引數

struct crypto_skcipher *tfm

密碼控制代碼

const u8 *key

儲存金鑰的緩衝區

unsigned int keylen

金鑰的長度(以位元組為單位)

描述

為密碼控制代碼引用的 skcipher 設定呼叫者提供的金鑰。

請注意,金鑰長度決定密碼型別。許多塊密碼根據金鑰大小實現不同的密碼模式,例如 AES-128 與 AES-192 與 AES-256。當為 AES 密碼控制代碼提供 16 位元組金鑰時,將執行 AES-128。

返回

如果金鑰設定成功,則為 0;如果發生錯誤,則為 < 0

struct crypto_skcipher *crypto_skcipher_reqtfm(struct skcipher_request *req)

從請求中獲取密碼控制代碼

引數

struct skcipher_request *req

要從中獲取密碼控制代碼的 skcipher_request

描述

在提供 skcipher_request 資料結構時返回 crypto_skcipher 控制代碼。

返回

crypto_skcipher 控制代碼

int crypto_skcipher_encrypt(struct skcipher_request *req)

加密明文

引數

struct skcipher_request *req

引用 skcipher_request 控制代碼,該控制代碼儲存執行密碼操作所需的所有資訊

描述

使用 skcipher_request 控制代碼加密明文資料。該資料結構以及如何使用資料填充該結構將在 skcipher_request_* 函式中討論。

返回

如果密碼操作成功,則為 0;如果發生錯誤,則為 < 0

int crypto_skcipher_decrypt(struct skcipher_request *req)

解密密文

引數

struct skcipher_request *req

引用 skcipher_request 控制代碼,該控制代碼儲存執行密碼操作所需的所有資訊

描述

使用 skcipher_request 控制代碼解密密文資料。該資料結構以及如何使用資料填充該結構將在 skcipher_request_* 函式中討論。

返回

如果密碼操作成功,則為 0;如果發生錯誤,則為 < 0

對稱金鑰密碼請求控制代碼

skcipher_request 資料結構包含對稱金鑰密碼操作所需的所有資料指標。這包括密碼控制代碼(可以被多個 skcipher_request 例項使用)、指向明文和密文的指標、非同步回撥函式等。它的作用類似於 skcipher_request_* API 呼叫的控制代碼,類似於 skcipher 控制代碼對 crypto_skcipher_* API 呼叫的作用。

unsigned int crypto_skcipher_reqsize(struct crypto_skcipher *tfm)

獲取請求資料結構的大小

引數

struct crypto_skcipher *tfm

密碼控制代碼

返回

位元組數

void skcipher_request_set_tfm(struct skcipher_request *req, struct crypto_skcipher *tfm)

更新請求中的密碼控制代碼引用

引數

struct skcipher_request *req

要修改的請求控制代碼

struct crypto_skcipher *tfm

應新增到請求控制代碼的密碼控制代碼

描述

允許呼叫者使用不同的 skcipher 控制代碼替換請求資料結構中現有的 skcipher 控制代碼。

struct skcipher_request *skcipher_request_alloc(struct crypto_skcipher *tfm, gfp_t gfp)

分配請求資料結構

引數

struct crypto_skcipher *tfm

要註冊到請求的密碼控制代碼

gfp_t gfp

API 呼叫傳遞給 kmalloc 的記憶體分配標誌。

描述

分配必須與 skcipher 加密和解密 API 呼叫一起使用的請求資料結構。在分配期間,提供的 skcipher 控制代碼已在請求資料結構中註冊。

返回

成功分配的請求控制代碼,如果記憶體不足則為 NULL

void skcipher_request_free(struct skcipher_request *req)

清零並釋放請求資料結構

引數

struct skcipher_request *req

要釋放的請求資料結構密碼控制代碼

void skcipher_request_set_callback(struct skcipher_request *req, u32 flags, crypto_completion_t compl, void *data)

設定非同步回撥函式

引數

struct skcipher_request *req

請求控制代碼

u32 flags

指定零或 ORing 的標誌 CRYPTO_TFM_REQ_MAY_BACKLOG 請求佇列可能會積壓並將等待佇列增加到超出初始最大大小;CRYPTO_TFM_REQ_MAY_SLEEP 請求處理可能會休眠

crypto_completion_t compl

要註冊到請求控制代碼的回撥函式指標

void *data

資料指標引用核心加密 API 未使用的記憶體,而是提供給回撥函式以供使用。在這裡,呼叫者可以提供對回撥函式可以操作的記憶體的引用。由於回撥函式與相關功能非同步呼叫,因此它可能需要訪問相關功能的資料結構,可以使用此指標引用這些資料結構。回撥函式可以透過提供給回撥函式的 crypto_async_request 資料結構中的 “data” 欄位訪問記憶體。

描述

此函式允許設定密碼操作完成後觸發的回撥函式。

回撥函式已在 skcipher_request 控制代碼中註冊,並且必須符合以下模板

void callback_function(struct crypto_async_request *req, int error)
void skcipher_request_set_crypt(struct skcipher_request *req, struct scatterlist *src, struct scatterlist *dst, unsigned int cryptlen, void *iv)

設定資料緩衝區

引數

struct skcipher_request *req

請求控制代碼

struct scatterlist *src

源 scatter / gather 列表

struct scatterlist *dst

目標 scatter / gather 列表

unsigned int cryptlen

要從 src 處理的位元組數

void *iv

密碼操作的 IV,必須符合 crypto_skcipher_ivsize 定義的 IV 大小

描述

此函式允許設定源資料和目標資料 scatter / gather 列表。

對於加密,源被視為明文,目標是密文。對於解密操作,使用方式相反 - 源是密文,目標是明文。

單塊密碼 API

單塊密碼 API 與型別為 CRYPTO_ALG_TYPE_CIPHER 的密碼一起使用(在 /proc/crypto 中列為 “cipher” 型別)。

使用單塊密碼 API 呼叫,可以實現基本密碼原語的操作。這些密碼原語不包括任何塊連結操作,包括 IV 處理。

此單塊密碼 API 的目的是支援模板或其他只需要一次對一個塊執行密碼操作的概念的實現。模板按塊呼叫底層密碼原語,並處理這些密碼操作的輸入或輸出資料。

struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask)

分配單塊密碼控制代碼

引數

const char *alg_name

是單塊密碼的 cra_name / name 或 cra_driver_name / driver name

u32 type

指定密碼的型別

u32 mask

指定密碼的掩碼

描述

為單塊密碼分配密碼控制代碼。返回的 struct crypto_cipher 是該單塊密碼的任何後續 API 呼叫所需的密碼控制代碼。

返回

成功分配的密碼控制代碼;如果 IS_ERR() 為真,則表示發生

錯誤,PTR_ERR() 返回錯誤程式碼。

void crypto_free_cipher(struct crypto_cipher *tfm)

清零並釋放單塊密碼控制代碼

引數

struct crypto_cipher *tfm

要釋放的密碼控制代碼

int crypto_has_cipher(const char *alg_name, u32 type, u32 mask)

搜尋單個分組密碼的可用性

引數

const char *alg_name

是單塊密碼的 cra_name / name 或 cra_driver_name / driver name

u32 type

指定密碼的型別

u32 mask

指定密碼的掩碼

返回

當核心加密API已知單個分組密碼時為true;

否則為false

unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm)

獲取密碼的分組大小

引數

struct crypto_cipher *tfm

密碼控制代碼

描述

返回透過密碼控制代碼tfm引用的單個分組密碼的分組大小。呼叫者可以使用該資訊為加密或解密操作返回的資料分配適當的記憶體

返回

密碼的塊大小

int crypto_cipher_setkey(struct crypto_cipher *tfm, const u8 *key, unsigned int keylen)

為密碼設定金鑰

引數

struct crypto_cipher *tfm

密碼控制代碼

const u8 *key

儲存金鑰的緩衝區

unsigned int keylen

金鑰的長度(以位元組為單位)

描述

為密碼控制代碼引用的單個分組密碼設定呼叫者提供的金鑰。

請注意,金鑰長度決定密碼型別。許多塊密碼根據金鑰大小實現不同的密碼模式,例如 AES-128 與 AES-192 與 AES-256。當為 AES 密碼控制代碼提供 16 位元組金鑰時,將執行 AES-128。

返回

如果金鑰設定成功,則為 0;如果發生錯誤,則為 < 0

void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src)

加密一個明文塊

引數

struct crypto_cipher *tfm

密碼控制代碼

u8 *dst

指向將填充密文的緩衝區

const u8 *src

儲存要加密的明文的緩衝區

描述

呼叫一個塊的加密操作。呼叫者必須確保明文和密文緩衝區的大小至少為一個塊。

void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src)

解密一個密文塊

引數

struct crypto_cipher *tfm

密碼控制代碼

u8 *dst

指向將填充明文的緩衝區

const u8 *src

儲存要解密的密文的緩衝區

描述

呼叫一個塊的解密操作。呼叫者必須確保明文和密文緩衝區的大小至少為一個塊。