本文基於以下軟硬體假定:
架構:AARCH64
內核版本:5.14.0-rc5
內核對加解密演算法的管理
加解密演算法可分為對稱演算法、非對稱演算法、hash演算法、mac演算法以及aead演算法等不同的種類。對稱演算法包括aes、des、3des、sm4、rc4、blowfish等,hash演算法包括md5、sha1、sha256、sha512、sha3、sm3等。
同一種演算法可以有多種不同的實現,如aes演算法可以由純軟體實現,可以由cpu架構的加解密指令加速,還可以通過獨立的加解密硬體加速等。此外,有些演算法還有不同的加解密模式,基礎加解密演算法可以與相關的模式進一步組合,形成新的演算法實例。
為了支持以上需求,內核分別為其抽象出了演算法類型、普通演算法、基礎演算法以及演算法模板。其中演算法類型用於表示某一類演算法,如對稱演算法使用crypto_skcipher結構體表示,hash演算法用crypto_ahash表示等。內核統一使用crypto_alg結構體表示所有的演算法實現,並用一個全局鏈表來管理所有注冊到crypto core中的crypto_alg,以下為其示例結構:
內核使用演算法名(cra_name)來表示某一特定的演算法,而使用演算法驅動名(cra_driver_name)來表示演算法的特定實現。不同的crypto_alg可以含有相同的cra_name,但其cra_driver_name是唯一的。用戶可以使用cra_name或cra_driver_name來調用相關演算法,為了在用戶使用cra_name參數時選擇最優的演算法實現,內核對每種crypto_alg都定義了一個優先順序。當給定cra_name還有多種不同實現時,則選擇其中優先順序最高的演算法實現。
內核還支持基礎對稱加解密演算法(指該演算法在加解密時只操作單個block,而不涉及與block數據組合相關的加解密模式)。它們可通過演算法模板(template),與不同的演算法模式組合成完整的加解密演算法。如aes演算法可與ecb、cbc、ctr模式分別組合成ecb(aes)、cbc(aes)和ctr(aes)演算法,des演算法也可與ecb、cbc、ctr模式組合為ecb(des)、cbc(des)和ctr(des)演算法等。內核通過特定的標志CRYPTO_ALG_TYPE_CIPHER來標識這類演算法。
最後,為了保證注冊演算法的正確性,當新演算法被注冊到crypto core之前,內核會先對其進行自測。為此在自測成功之前,這些演算法會由crypto_larval管理,它包含了larval演算法和alt演算法,當自測成功後,才將alt演算法標記為tested,並銷毀其對應的larval演算法。
數據結構
2.1 crypto_alg結構體
該結構體是加解密演算法的基礎結構體,主要用於描述演算法的通用屬性,如演算法名稱、演算法驅動名稱、分組大小、數據對齊值等。當一個演算法被注冊到加解密核心中時,crypto_alg將會通過該節點掛到全局的演算法鏈表crypto_alg_list上。此後,加解密核心就可以通過遍歷該鏈表查找該演算法。
2.2 skcipher_alg結構體
以下為該結構體的定義:
設置密鑰回調函數、加密回調函數、解密回調函數、演算法初始化回調函數、演算法退出回調函數、演算法支持的最短密鑰長度、演算法支持的最長密鑰長度、演算法支持的iv長度、對於塊密碼演算法,該值等於block size、若演算法在並行處理多個塊時效率更高,則為chunksize的整數倍,否則等於chunksize、基礎演算法結構體。
2.3 crypto_larval結構體
該結構體在演算法注冊時用於其自測流程,其結構體定義如下:
演算法注冊時的臨時演算法結構體、演算法注冊時最終使用的實際演算法結構體、用於演算法自測同步操作的完成量。
加解密演算法注冊流程
加解密演算法注冊的主要工作為將對應演算法加入全局演算法鏈表中,並觸發演算法自測流程。由於在自測完成之前,該演算法還不能被調用,因此會為其分配一個crypto_larval結構體,用於其在自測時的管理。
3.1 演算法校驗
crypto_check_alg函數用於校驗待注冊演算法的合法性,如其對齊值、block size等是否位於合理范圍。
3.2 __crypto_register_alg實現
該函數首先檢查該演算法是否已注冊,且已注冊演算法鏈表中是否有重名的演算法,若檢查通過則為其分配並初始化一個演算法自測使用的crypto_larval結構體。然後將該演算法與larval臨時演算法都添加到全局演算法鏈表中。
3.3 crypto_wait_for_test流程
該函數會通過通知方式觸發該演算法的自測流程,然後等待自測完成。
3.4 演算法自測流程
加解密核心通過cryptomgr_init函數注冊加解密演算法相關的通知,該通知主要用於觸發演算法自測和模板示例創建工作。
4 特定演算法類型的注冊介面
由於不同演算法類型會在crypto_alg基礎上封裝其自身的演算法結構體,因此它們也相應地封裝了其對應的演算法注冊介面,我們在注冊某特定演算法時,通常都是使用該演算法類型對應的注冊介面完成。
5 基礎對稱加解密演算法注冊
基礎對稱加解密演算法指單次加密或解密操作固定為一個block的加解密演算法,該演算法一般會通過加解密模板,與特定的加解密模式功能生成組合演算法。
以內核中的通用aes加解密基礎演算法aes-generic為例,其注冊流程如下:
指示該演算法為基礎cipher演算法、設置基礎cipher演算法的屬性和回調函數。其中crypto_aes_encrypt和crypto_aes_decrypt在單次調用中只能加解密一個block。