OpenSSL3.0.1中SM4算法分析

这篇具有很好参考价值的文章主要介绍了OpenSSL3.0.1中SM4算法分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SM4分组对称密码算法

简介

SM4分组密码算法是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。要保证一个对称密码算法的安全性的基本条件是其具备足够的密钥长度,SM4算法与AES算法具有相同的密钥长度分组长度128比特,因此在安全性上高于3DES算法。
SM4分组加密算法的每个分组大小是128bit(16字节),所用的密钥长度也是128bit(16字节),最后生成的密文长度也是128bit(16字节),如果未满16字节需要填充特定字符串至满16字节为止。

头文件分析

头文件路径:/include/crypto/sm4.h
源代码路径:/crypto/sm4/sm4.c
由头文件可知主要进行了以下定义:
1、 宏定义
2、 轮密钥的结构体SM4_KEY_st
3、 生成轮密钥函数ossl_sm4_set_key
4、 加密函数ossl_sm4_encrypt
5、 解密函数ossl_sm4_decrypt

# define SM4_ENCRYPT     1
# define SM4_DECRYPT     0

# define SM4_BLOCK_SIZE    16
# define SM4_KEY_SCHEDULE  32

typedef struct SM4_KEY_st {
    uint32_t rk[SM4_KEY_SCHEDULE];
} SM4_KEY;

int ossl_sm4_set_key(const uint8_t *key, SM4_KEY *ks);

void ossl_sm4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);

void ossl_sm4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);

源代码分析

非线性变换 τ \tau τ

τ \tau τ由4个并行的S盒构成,S盒是一个固定的8比特输入8比特输出的置换。
设输入为 A = ( a 0 , a 1 , a 2 , a 3 ) A=(a_{0},a_{1},a_{2},a_{3}) A=(a0,a1,a2,a3),其中 a 0 a_{0} a0- a 3 a_{3} a3均为8bit,A为32bit;输出为B, B = ( b 0 , b 1 , b 2 , b 3 ) B=(b_{0},b_{1},b_{2},b_{3}) B=(b0,b1,b2,b3), 其中 b 0 b_{0} b0- b 3 b_{3} b3均为8bit,B为32bit。
关系如下:
( b 0 , b 1 , b 2 , b 3 ) = τ ( A ) = ( S b o x ( a 0 ) , S b o x ( a 1 ) , S b o x ( a 2 ) , S b o x ( a 3 ) ) (b_{0},b_{1},b_{2},b_{3})=\tau(A)=(\mathrm{Sbox}(\mathrm{a_{0}}), \mathrm{Sbox}(\mathrm{a_{1}}), \mathrm{Sbox}(\mathrm{a_{2}}), \mathrm{Sbox}(\mathrm{a_{3}})) (b0,b1,b2,b3)=τ(A)=(Sbox(a0),Sbox(a1),Sbox(a2),Sbox(a3))
OpenSSL3.0.1中SM4算法分析

对应源码如下:

static const uint8_t SM4_S[256] = {
    0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2,
    0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3,
    0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4,
    0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
    0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA,
    0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA,
    0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2,
    0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
    0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B,
    0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52,
    0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2,
    0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1,
    0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30,
    0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60,
    0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45,
    0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51,
    0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41,
    0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD,
    0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A,
    0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84,
    0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E,
    0xD7, 0xCB, 0x39, 0x48
};

补充示例:

例:输入01100101,取前4位0110转换成16进制为6,也就是对应的x轴为6。后4位的0101转换成16进制为5,对应的y轴也就为5。综合x,y找到S盒输出的值为58,即01011000

线性变换部件L

以字来作为处理单位的线性变换部件,输入输出的字都是32位。非线性变换 τ \tau τ的输出是线性变换L的输入。设输入为B,则
C = L ( B ) = B ⊕ ( B < < < 2 ) ⊕ ( B < < 10 ) ⊕ ( B < < < 18 ) ⊕ ( B < < < 24 ) C=L(B)=B\oplus(B<<<2)\oplus(B<<10)\oplus(B<<<18)\oplus(B<<<24) C=L(B)=B(B<<<2)(B<<10)(B<<<18)(B<<<24)
源码中已经提前做好线性变换
S M 4 _ S B O X _ T [ j ] = L ( S M 4 _ S B O X [ j ] ) SM4\text\_SBOX\text\_T[j]=L(SM4\text\_SBOX[j]) SM4_SBOX_T[j]=L(SM4_SBOX[j])
对应源码为:

static const uint32_t SM4_SBOX_T[256] = {
    0x8ED55B5B, 0xD0924242, 0x4DEAA7A7, 0x06FDFBFB, 0xFCCF3333, 0x65E28787,
    0xC93DF4F4, 0x6BB5DEDE, 0x4E165858, 0x6EB4DADA, 0x44145050, 0xCAC10B0B,
    0x8828A0A0, 0x17F8EFEF, 0x9C2CB0B0, 0x11051414, 0x872BACAC, 0xFB669D9D,
    0xF2986A6A, 0xAE77D9D9, 0x822AA8A8, 0x46BCFAFA, 0x14041010, 0xCFC00F0F,
    0x02A8AAAA, 0x54451111, 0x5F134C4C, 0xBE269898, 0x6D482525, 0x9E841A1A,
    0x1E061818, 0xFD9B6666, 0xEC9E7272, 0x4A430909, 0x10514141, 0x24F7D3D3,
    0xD5934646, 0x53ECBFBF, 0xF89A6262, 0x927BE9E9, 0xFF33CCCC, 0x04555151,
    0x270B2C2C, 0x4F420D0D, 0x59EEB7B7, 0xF3CC3F3F, 0x1CAEB2B2, 0xEA638989,
    0x74E79393, 0x7FB1CECE, 0x6C1C7070, 0x0DABA6A6, 0xEDCA2727, 0x28082020,
    0x48EBA3A3, 0xC1975656, 0x80820202, 0xA3DC7F7F, 0xC4965252, 0x12F9EBEB,
    0xA174D5D5, 0xB38D3E3E, 0xC33FFCFC, 0x3EA49A9A, 0x5B461D1D, 0x1B071C1C,
    0x3BA59E9E, 0x0CFFF3F3, 0x3FF0CFCF, 0xBF72CDCD, 0x4B175C5C, 0x52B8EAEA,
    0x8F810E0E, 0x3D586565, 0xCC3CF0F0, 0x7D196464, 0x7EE59B9B, 0x91871616,
    0x734E3D3D, 0x08AAA2A2, 0xC869A1A1, 0xC76AADAD, 0x85830606, 0x7AB0CACA,
    0xB570C5C5, 0xF4659191, 0xB2D96B6B, 0xA7892E2E, 0x18FBE3E3, 0x47E8AFAF,
    0x330F3C3C, 0x674A2D2D, 0xB071C1C1, 0x0E575959, 0xE99F7676, 0xE135D4D4,
    0x661E7878, 0xB4249090, 0x360E3838, 0x265F7979, 0xEF628D8D, 0x38596161,
    0x95D24747, 0x2AA08A8A, 0xB1259494, 0xAA228888, 0x8C7DF1F1, 0xD73BECEC,
    0x05010404, 0xA5218484, 0x9879E1E1, 0x9B851E1E, 0x84D75353, 0x00000000,
    0x5E471919, 0x0B565D5D, 0xE39D7E7E, 0x9FD04F4F, 0xBB279C9C, 0x1A534949,
    0x7C4D3131, 0xEE36D8D8, 0x0A020808, 0x7BE49F9F, 0x20A28282, 0xD4C71313,
    0xE8CB2323, 0xE69C7A7A, 0x42E9ABAB, 0x43BDFEFE, 0xA2882A2A, 0x9AD14B4B,
    0x40410101, 0xDBC41F1F, 0xD838E0E0, 0x61B7D6D6, 0x2FA18E8E, 0x2BF4DFDF,
    0x3AF1CBCB, 0xF6CD3B3B, 0x1DFAE7E7, 0xE5608585, 0x41155454, 0x25A38686,
    0x60E38383, 0x16ACBABA, 0x295C7575, 0x34A69292, 0xF7996E6E, 0xE434D0D0,
    0x721A6868, 0x01545555, 0x19AFB6B6, 0xDF914E4E, 0xFA32C8C8, 0xF030C0C0,
    0x21F6D7D7, 0xBC8E3232, 0x75B3C6C6, 0x6FE08F8F, 0x691D7474, 0x2EF5DBDB,
    0x6AE18B8B, 0x962EB8B8, 0x8A800A0A, 0xFE679999, 0xE2C92B2B, 0xE0618181,
    0xC0C30303, 0x8D29A4A4, 0xAF238C8C, 0x07A9AEAE, 0x390D3434, 0x1F524D4D,
    0x764F3939, 0xD36EBDBD, 0x81D65757, 0xB7D86F6F, 0xEB37DCDC, 0x51441515,
    0xA6DD7B7B, 0x09FEF7F7, 0xB68C3A3A, 0x932FBCBC, 0x0F030C0C, 0x03FCFFFF,
    0xC26BA9A9, 0xBA73C9C9, 0xD96CB5B5, 0xDC6DB1B1, 0x375A6D6D, 0x15504545,
    0xB98F3636, 0x771B6C6C, 0x13ADBEBE, 0xDA904A4A, 0x57B9EEEE, 0xA9DE7777,
    0x4CBEF2F2, 0x837EFDFD, 0x55114444, 0xBDDA6767, 0x2C5D7171, 0x45400505,
    0x631F7C7C, 0x50104040, 0x325B6969, 0xB8DB6363, 0x220A2828, 0xC5C20707,
    0xF531C4C4, 0xA88A2222, 0x31A79696, 0xF9CE3737, 0x977AEDED, 0x49BFF6F6,
    0x992DB4B4, 0xA475D1D1, 0x90D34343, 0x5A124848, 0x58BAE2E2, 0x71E69797,
    0x64B6D2D2, 0x70B2C2C2, 0xAD8B2626, 0xCD68A5A5, 0xCB955E5E, 0x624B2929,
    0x3C0C3030, 0xCE945A5A, 0xAB76DDDD, 0x867FF9F9, 0xF1649595, 0x5DBBE6E6,
    0x35F2C7C7, 0x2D092424, 0xD1C61717, 0xD66FB9B9, 0xDEC51B1B, 0x94861212,
    0x78186060, 0x30F3C3C3, 0x897CF5F5, 0x5CEFB3B3, 0xD23AE8E8, 0xACDF7373,
    0x794C3535, 0xA0208080, 0x9D78E5E5, 0x56EDBBBB, 0x235E7D7D, 0xC63EF8F8,
    0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121 };

合成置换T

T是一个可逆变换,由非线性变换 τ \tau τ和线性变换L复合而成,即
T ( ⋅ ) = L ( τ ( ⋅ ) ) T(·)=L(\tau(·)) T()=L(τ())
源码中分别定义了两种方式实现合成置换T:
第一种为SM4_T_slow,源码定义如下:

static ossl_inline uint32_t SM4_T_slow(uint32_t X)
{
    uint32_t t = 0;

    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24;
    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16;
    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
    t |= SM4_S[(uint8_t)X];

    /*
     * L linear transform
     */
    return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24);
}

实现了:
B = ( b 0 , b 1 , b 2 , b 3 ) = τ ( A ) = ( S b o x ( a 0 ) , S b o x ( a 1 ) , S b o x ( a 2 ) , S b o x ( a 3 ) ) B=(b_{0},b_{1},b_{2},b_{3})=\tau(A)=(\mathrm{Sbox}(\mathrm{a_{0}}), \mathrm{Sbox}(\mathrm{a_{1}}), \mathrm{Sbox}(\mathrm{a_{2}}), \mathrm{Sbox}(\mathrm{a_{3}})) B=(b0,b1,b2,b3)=τ(A)=(Sbox(a0),Sbox(a1),Sbox(a2),Sbox(a3))
C = L ( B ) = B ⊕ ( B < < < 2 ) ⊕ ( B < < 10 ) ⊕ ( B < < < 18 ) ⊕ ( B < < < 24 ) C=L(B)=B\oplus(B<<<2)\oplus(B<<10)\oplus(B<<<18)\oplus(B<<<24) C=L(B)=B(B<<<2)(B<<10)(B<<<18)(B<<<24)
第二种为SM4_T:

static ossl_inline uint32_t SM4_T(uint32_t X)
{
    return SM4_SBOX_T[(uint8_t)(X >> 24)] ^
           rotl(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^
           rotl(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^
           rotl(SM4_SBOX_T[(uint8_t)X], 8);
}

运用线性变换表SM4_SBOX_T提高了合成置换T的效率

循环位移

源码实现如下:

static ossl_inline uint32_t rotl(uint32_t a, uint8_t n)
{
    return (a << n) | (a >> (32 - n));
}

轮密钥合成置换T’

T’与合成置换T基本类似,只是换了线性置换L为L’
C = L ’ ( B ) = B ⊕ ( B < < < 13 ) ⊕ ( B < < < 23 ) C=L’(B)=B\oplus (B<<<13) \oplus(B<<<23) C=L(B)=B(B<<<13)(B<<<23)
32bit存储源码实现如下:
将4字节的内容分别存储到4个长度为1字节的数组中

static ossl_inline void store_u32_be(uint32_t v, uint8_t *b)
{
    b[0] = (uint8_t)(v >> 24);
    b[1] = (uint8_t)(v >> 16);
    b[2] = (uint8_t)(v >> 8);
    b[3] = (uint8_t)(v);
}

32bit加载源码实现如下:
4字节的内容由4个长度为1字节的数组拼接而成

static ossl_inline uint32_t load_u32_be(const uint8_t *b, uint32_t n)
{
    return ((uint32_t)b[4 * n] << 24) |
           ((uint32_t)b[4 * n + 1] << 16) |
           ((uint32_t)b[4 * n + 2] << 8) |
           ((uint32_t)b[4 * n + 3]);
}

主要流程

密钥扩展

密钥扩展主要是为了得到轮密钥,整个加解密过程使用轮密钥,由头文件中的结构体定义可知轮密钥是 r k [ 32 ] rk_{[32]} rk[32]数组的形式,每一个元素为32bit(4字节)。
加解密算法的轮密钥由加密密钥通过密钥扩展算法生成:
设加密密钥 M K = ( M K 0 , M K 1 , M K 2 , M K 3 ) MK=(MK_{0},MK_{1},MK_{2},MK_{3}) MK=(MK0,MK1,MK2,MK3),其中 M K i MK_i MKi为字
轮密钥为 ( r k 0 , r k 1 , . . . , r k 31 ) (rk_{0},rk_{1},...,rk_{31}) (rk0,rk1,...,rk31)
轮密钥的生成方法具体为:
( K 0 , K 1 , K 2 , K 3 ) = ( M K 0 ⊕ F K 0 , M K 1 ⊕ F K 1 , M K 2 ⊕ F K 2 , M K 3 ⊕ F K 3 ) (K_{0},K_{1},K_{2},K_{3})=(MK_{0} \oplus FK_{0},MK_{1} \oplus FK_{1},MK_{2} \oplus FK_{2},MK_{3} \oplus FK_{3}) (K0,K1,K2,K3)=(MK0FK0,MK1FK1,MK2FK2,MK3FK3)
r k i = K i + 4 = K i ⊕ T ′ ( K i + 1 ⊕ K i + 2 ⊕ K i + 3 ⊕ C K i ) rk_i=K_{i+4}=K_{i}\oplus T'(K_{i+1}\oplus K_{i+2} \oplus K_{i+3}\oplus CK_i ) rki=Ki+4=KiT(Ki+1Ki+2Ki+3CKi)
SM4算法的加密密钥长度为128比特,将其分为四组,其中每一组都为32位,即 M K = ( M K 0 , M K 1 , M K 2 , M K 3 ) MK=(MK_{0},MK_{1},MK_{2},MK_{3}) MK=(MK0,MK1,MK2,MK3)
系统参数FK的取值为:
F K 0 = ( a 3 b 1 b a c 6 ) , F K 1 = ( 56 a a 3350 ) , F K 2 = ( 677 d 9197 ) , F K 3 = ( b 27022 d c ) FK_0 = (a3b1bac6) ,FK_1 = (56aa3350) ,FK_2 = (677d9197) ,FK_3 = (b27022dc) FK0=(a3b1bac6)FK1=(56aa3350)FK2=(677d9197)FK3=(b27022dc)
源代码如下:

static const uint32_t FK[4] =
        { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };

固定参数 C K i CK_i CKi(i=0,1,2,···,31)的具体值为:
00070E15,1C232A31,383F464D,545B6269,
70777E85,8C939AA1,A8AFB6BD,C4CBD2D9,
E0E7EEF5,FC030A11,181F262D,343B4249,
50575E65,6C737A81,888F969D,A4ABB2B9,
C0C7CED5,DCE3EAF1,F8FF060D,141B2229,
30373E45,4C535A61,686F767D,848B9299,
A0A7AEB5,BCC3CAD1,D8DFE6ED,F4FB0209,
10171E25,2C333A41,484F565D,646B7279
源代码如下:

static const uint32_t CK[32] = {
        0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
        0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
        0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
        0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
        0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
        0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
        0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
        0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
    };

创建一个 K [ 4 ] K_{[4]} K[4]数组(单个元素长度为32bit),K数组的0-3下标元素直接从对应下标的MK与对应下标的FK异或得到
源代码实现如下:

uint32_t K[4];
int i;
K[0] = load_u32_be(key, 0) ^ FK[0];
K[1] = load_u32_be(key, 1) ^ FK[1];
K[2] = load_u32_be(key, 2) ^ FK[2];
K[3] = load_u32_be(key, 3) ^ FK[3];

生成子密钥的源代码如下:

for (i = 0; i != SM4_KEY_SCHEDULE; ++i) {
    uint32_t X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i];
    uint32_t t = 0;

    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24;
    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16;
    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
    t |= SM4_S[(uint8_t)X];
    
   
    t = t ^ rotl(t, 13) ^ rotl(t, 23);
    K[i % 4] ^= t;
    ks->rk[i] = K[i % 4];
	}

加密过程

加密过程中,明文数据长度为128bit即16字节;在加密过程中首先要创建一个 X [ 36 ] X_{[36]} X[36]的数组,每个元素32bit。和密钥扩展过程类似,真实数据填充到 X 0 − X 3 X_{0}-X_{3} X0X3
加密轮函数为:
X i + 4 = F ( X i , X i + 1 , X i + 2 , X i + 3 , r k i ) = X i ⊕ T ( X i + 1 ⊕ X i + 2 ⊕ X i + 3 ⊕ r k i ) , i = 0 , 1 , . . . , 31 X_{i+4}=F(X_{i},X_{i+1},X_{i+2},X_{i+3},rk_{i})=X_{i}\oplus T(X_{i+1}\oplus X_{i+2}\oplus X_{i+3}\oplus rk_{i}),i=0,1,...,31 Xi+4=F(Xi,Xi+1,Xi+2,Xi+3,rki)=XiT(Xi+1Xi+2Xi+3rki),i=0,1,...,31
OpenSSL3.0.1中SM4算法分析
代码实现如下:

#define SM4_RNDS(k0, k1, k2, k3, F)          \
      do {                                   \
         B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \
         B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \
         B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \
         B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \
      } while(0)

加密整体流程如下:
OpenSSL3.0.1中SM4算法分析
真实数据填充到 X 0 − X 3 X_{0}-X_{3} X0X3中,代码中为填充到 B 0 − B 3 B0-B3 B0B3数组中

    uint32_t B0 = load_u32_be(in, 0);
    uint32_t B1 = load_u32_be(in, 1);
    uint32_t B2 = load_u32_be(in, 2);
    uint32_t B3 = load_u32_be(in, 3);

32轮迭代计算代码实现如下:

    /*
     * Uses byte-wise sbox in the first and last rounds to provide some
     * protection from cache based side channels.
     */
    SM4_RNDS( 0,  1,  2,  3, SM4_T_slow);
    SM4_RNDS( 4,  5,  6,  7, SM4_T);
    SM4_RNDS( 8,  9, 10, 11, SM4_T);
    SM4_RNDS(12, 13, 14, 15, SM4_T);
    SM4_RNDS(16, 17, 18, 19, SM4_T);
    SM4_RNDS(20, 21, 22, 23, SM4_T);
    SM4_RNDS(24, 25, 26, 27, SM4_T);
    SM4_RNDS(28, 29, 30, 31, SM4_T_slow);

反序变换输出:
( Y 0 , Y 1 , Y 2 , Y 3 ) = R ( X 32 , X 33 , X 34 , X 35 ) = ( X 35 , X 34 , X 33 , X 32 ) = ( B 3 , B 2 , B 1 , B 0 ) (Y_{0},Y_{1},Y_{2},Y_{3})=R(X_{32},X_{33},X_{34},X_{35})=(X_{35},X_{34},X_{33},X_{32})=(B_{3},B_{2},B_{1},B_{0}) (Y0,Y1,Y2,Y3)=R(X32,X33,X34,X35)=(X35,X34,X33,X32)=(B3,B2,B1,B0)
代码实现如下:

    store_u32_be(B3, out);
    store_u32_be(B2, out + 4);
    store_u32_be(B1, out + 8);
    store_u32_be(B0, out + 12);

解密过程

解密变换与加密变换的结构相同,不同的是轮密钥的使用顺序,解密时使用轮密钥序 ( r k 31 , r k 30 … r k 0 ) (rk_{31},rk_{30}…rk_{0}) (rk31,rk30rk0)
将密文填充到 Y 0 − Y 3 Y_{0}-Y_{3} Y0Y3中,代码中为填充到 B 0 − B 3 B0-B3 B0B3数组中:

    uint32_t B0 = load_u32_be(in, 0);
    uint32_t B1 = load_u32_be(in, 1);
    uint32_t B2 = load_u32_be(in, 2);
    uint32_t B3 = load_u32_be(in, 3);

解密轮函数为:
X = F ( X i + 4 , X i + 3 , X i + 2 , X i + 1 , r k i ) X=F(X_{i+4},X_{i+3},X_{i+2},X_{i+1},rk_{i}) X=F(Xi+4,Xi+3,Xi+2,Xi+1,rki)
使用轮密钥序 ( r k 31 , r k 30 … r k 0 ) (rk_{31},rk_{30}…rk_{0}) (rk31,rk30rk0)进行32轮迭代代码实现如下:

    SM4_RNDS(31, 30, 29, 28, SM4_T_slow);
    SM4_RNDS(27, 26, 25, 24, SM4_T);
    SM4_RNDS(23, 22, 21, 20, SM4_T);
    SM4_RNDS(19, 18, 17, 16, SM4_T);
    SM4_RNDS(15, 14, 13, 12, SM4_T);
    SM4_RNDS(11, 10,  9,  8, SM4_T);
    SM4_RNDS( 7,  6,  5,  4, SM4_T);
    SM4_RNDS( 3,  2,  1,  0, SM4_T_slow);

解密证明:
X i + 4 = F ( X i , X i + 1 , X i + 2 , X i + 3 , r k i ) = X i ⊕ T ( X i + 1 ⊕ X i + 2 ⊕ X i + 3 ⊕ r k i ) , i = 0 , 1 , . . . , 31 X_{i+4}=F(X_{i},X_{i+1},X_{i+2},X_{i+3},rk_{i})=X_{i}\oplus T(X_{i+1}\oplus X_{i+2}\oplus X_{i+3}\oplus rk_{i}),i=0,1,...,31 Xi+4=F(Xi,Xi+1,Xi+2,Xi+3,rki)=XiT(Xi+1Xi+2Xi+3rki),i=0,1,...,31
( Y 0 , Y 1 , Y 2 , Y 3 ) = ( X 35 , X 34 , X 33 , X 32 ) (Y_{0},Y_{1},Y_{2},Y_{3})=(X_{35},X_{34},X_{33},X_{32}) (Y0,Y1,Y2,Y3)=(X35,X34,X33,X32)
由此推出:
X 35 = X 31 ⊕ T ( X 34 ⊕ X 33 ⊕ X 32 ⊕ r k 31 ) X_{35}=X_{31}\oplus T(X_{34}\oplus X_{33}\oplus X_{32}\oplus rk_{31}) X35=X31T(X34X33X32rk31)
Y 4 = F ( Y 0 , Y 1 , Y 2 , Y 3 , r k 31 ) = Y 0 ⊕ T ( Y 1 ⊕ Y 2 ⊕ Y 3 ⊕ r k 31 ) = X 35 ⊕ T ( X 34 ⊕ X 33 ⊕ X 32 ⊕ r k 31 ) = X 31 ⊕ T ( X 34 ⊕ X 33 ⊕ X 32 ⊕ r k 31 ) ⊕ T ( X 34 ⊕ X 33 ⊕ X 32 ⊕ r k 31 ) = X 31 Y_{4}=F(Y_{0},Y_{1},Y_{2},Y_{3},rk_{31})=Y_{0}\oplus T(Y_{1}\oplus Y_{2}\oplus Y_{3}\oplus rk_{31})=X_{35}\oplus T(X_{34}\oplus X_{33}\oplus X_{32}\oplus rk_{31})=X_{31}\oplus T(X_{34}\oplus X_{33}\oplus X_{32}\oplus rk_{31})\oplus T(X_{34}\oplus X_{33}\oplus X_{32}\oplus rk_{31})=X_{31} Y4=F(Y0,Y1,Y2,Y3,rk31)=Y0T(Y1Y2Y3rk31)=X35T(X34X33X32rk31)=X31T(X34X33X32rk31)T(X34X33X32rk31)=X31
反序变换输出原文的实现如下:

    store_u32_be(B3, out);
    store_u32_be(B2, out + 4);
    store_u32_be(B1, out + 8);
    store_u32_be(B0, out + 12);

具体细节有待进一步研究,欢迎讨论文章来源地址https://www.toymoban.com/news/detail-457084.html

到了这里,关于OpenSSL3.0.1中SM4算法分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 新手入门 | 掌握国密算法:新手指南: SM2 / SM3 / SM4密码算法详解

    在密码学领域,有多种加密与签名算法,它们在信息安全领域发挥着举足轻重的作用。如今,随着互联网的快速发展,网络安全已经成为各类信息系统完整性、可用性、保密性的重要保障,越来越多的国产密码算法得到了广泛的应用与关注。在本文中,我们将重点介绍三个经

    2024年02月12日
    浏览(145)
  • Python实现国家商用密码算法sm2/sm3/sm4/sm9(国密)

    2010 年开始,我国国家密码管理局就已经开始陆续发布了一系列国产加密算法,这其中就包括 SM1、SM2、SM3 、SM4、SM7、SM9、ZUC(祖冲之加密算法)等,SM 代表商密,即商业密码,是指用于商业的、不涉及国家秘密的密码技术。SM1 和 SM7 的算法不公开,其余算法都已成为 ISO/IEC

    2024年02月15日
    浏览(47)
  • 商用密码应用与安全性评估要点笔记(SM4算法)

    1、SM4算法简介         SM4是我国发布的分组密码算法,属于对称密码的一种。SM4在2006年公开发布,2012年成为行业标准(GMT 0002-2012 SM4分组密码算法),并于2021年成为国际标准。         SM2分组长度为128bit、密钥长度为128bit、采用32轮非线性迭代结构(非平衡Feistel结构)。

    2024年02月12日
    浏览(42)
  • 密码算法(SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算)

    SM1、SM2、SM3和SM4 为了保障商用密码的安全性,国家密码局制定了一系列密码标准,包括:SM1(SCB2)、SM2、SM3、SM4、SM7、SM9、祖冲之密码算法(ZUC) 等。 SM1、SM4、SM7、祖冲之密码(ZUC)是对称算法。 SM2、SM9是非对称算法。 SM3是哈希算法。 SM1、SM7算法不公开,调用该算法时,

    2024年02月03日
    浏览(43)
  • 国密SM4对称加密Java加解密

    提示:国密SM4对称加密Java加解密 国家密码管理局 参考博文 SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。 SM4 代码如下(示例): 在密码学中

    2024年02月11日
    浏览(48)
  • 【密码算法 之十四】非对称算法,ECC椭圆曲线算法 之 ECDSA、ECDH、SM2、SM9等

      ECC(Elliptic Curve Cryptography),就是椭圆曲线密码算法,它是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全,RSA加密算法也是一种非对称加密算法,在公开密钥加密和电子商业中RSA被广泛使用。据

    2024年02月13日
    浏览(34)
  • Openssl+sm4开发实例(含源码)

    SM4(国密算法)是由中国国家密码管理局(State Cryptography Administration,SCA)提出的分组密码算法,是一种对称加密算法。它是中国国家商用密码算法,也是 ISO/IEC 标准(ISO/IEC 18033-3:2010)中的一部分。SM4 算法被广泛用于中国国内的商用加密应用中。 以下是 SM4 算法的主要特点

    2024年02月06日
    浏览(43)
  • C# 实现 国密SM4/ECB/PKCS7Padding对称加密解密

    C# 实现 国密SM4/ECB/PKCS7Padding对称加密解密,为了演示方便本问使用的是Visual Studio 2022 来构建代码的 1、新建项目,之后选择 项目 鼠标右键选择  管理NuGet程序包管理,输入  BouncyCastle 回车 添加BouncyCastle程序包 2、代码如下:CBC模式 代码如下:ECB模式 3、运行 4、SM4密码算法

    2024年02月11日
    浏览(58)
  • SM4算法简介

      SM4为分组对称密码算法,明文、密文以及密钥长度均为 128 128 128 bits。SM4算法主要包括加解密算法和密钥扩展算法,采用 32 32 32 轮非线性迭代的数学结构,其中算法中每一次迭代运算为一轮非线性变换。主要操作包括异或、合成置换、非线性迭代、反序变换、循环移位以

    2024年02月03日
    浏览(25)
  • 探索密码学的未来:SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算

    密码算法在现代通信与信息安全中发挥着至关重要的作用,SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算等密码算法被广泛应用于各种信息安全领域。本篇博客将会为大家介绍这些密码算法,以及它们在信息安全中的作用和应用。 SM1、SM2、SM3、SM4是中国国

    2024年02月08日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包