openssl實現分組加密模式(例如AES128-CBC的CBC部分)的模塊名字叫做modes,源代碼位于
https://gitee.com/gh_mirrors/openssl/tree/master/crypto/modes
博主又打不開github了TT,只能找個gitee鏡像
頭文件是modes.h。
該模塊目前支持12種加密模式,如圖,每一個文件就是一個模式。
加密模式與加密算法并不綁定,你可以使用自定義的加密函數,只要分組長度是128bit即可。理論上可以使用非對稱的加密函數,但必須是128bit等長分組,這種情況并不常見。
以CRYPTO_cbc128_encrypt為例,該函數的最后一個參數是一個函數指針,用于對一個分組進行加密,需要調用者提供。
void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,size_t len, const void *key,unsigned char ivec[16], block128_f block)
{size_t n;const unsigned char *iv = ivec;if (len == 0)return;#if !defined(OPENSSL_SMALL_FOOTPRINT)if (STRICT_ALIGNMENT &&((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {while (len >= 16) {for (n = 0; n < 16; ++n)out[n] = in[n] ^ iv[n];(*block) (out, out, key);iv = out;len -= 16;in += 16;out += 16;}} else {while (len >= 16) {for (n = 0; n < 16; n += sizeof(size_t))*(size_t_aX *)(out + n) =*(size_t_aX *)(in + n) ^ *(size_t_aX *)(iv + n);(*block) (out, out, key);iv = out;len -= 16;in += 16;out += 16;}}
#endifwhile (len) {for (n = 0; n < 16 && n < len; ++n)out[n] = in[n] ^ iv[n];for (; n < 16; ++n)out[n] = iv[n];(*block) (out, out, key);iv = out;if (len <= 16)break;len -= 16;in += 16;out += 16;}if (ivec != iv)memcpy(ivec, iv, 16);
}
注意事項:
1、block參數必須支持前2個參數使用相同的指針,即輸入輸出使用同一塊緩存。
2、key參數沒有長度限制,實際長度取決于block。因此受限制的是分組長度而非密鑰長度,密鑰長度可以不等于分組長度,AES256就是這種情況。
對于GCM這種較為復雜的模式,需要輸入上下文對象指針。