/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* SM4 , as specified in
* https : //tools.ietf.org/id/draft-ribose-cfrg-sm4-10.html
*
* Copyright ( C ) 2018 ARM Limited or its affiliates .
* Copyright ( c ) 2021 Tianjia Zhang < tianjia . zhang @ linux . alibaba . com >
*/
#include <linux/module.h>
#include <linux/unaligned.h>
#include <crypto/sm4.h>
static const u32 ____cacheline_aligned fk[4 ] = {
0 xa3b1bac6, 0 x56aa3350, 0 x677d9197, 0 xb27022dc
};
static const u32 ____cacheline_aligned ck[32 ] = {
0 x00070e15, 0 x1c232a31, 0 x383f464d, 0 x545b6269,
0 x70777e85, 0 x8c939aa1, 0 xa8afb6bd, 0 xc4cbd2d9,
0 xe0e7eef5, 0 xfc030a11, 0 x181f262d, 0 x343b4249,
0 x50575e65, 0 x6c737a81, 0 x888f969d, 0 xa4abb2b9,
0 xc0c7ced5, 0 xdce3eaf1, 0 xf8ff060d, 0 x141b2229,
0 x30373e45, 0 x4c535a61, 0 x686f767d, 0 x848b9299,
0 xa0a7aeb5, 0 xbcc3cad1, 0 xd8dfe6ed, 0 xf4fb0209,
0 x10171e25, 0 x2c333a41, 0 x484f565d, 0 x646b7279
};
static const u8 ____cacheline_aligned sbox[256 ] = {
0 xd6, 0 x90, 0 xe9, 0 xfe, 0 xcc, 0 xe1, 0 x3d, 0 xb7,
0 x16, 0 xb6, 0 x14, 0 xc2, 0 x28, 0 xfb, 0 x2c, 0 x05,
0 x2b, 0 x67, 0 x9a, 0 x76, 0 x2a, 0 xbe, 0 x04, 0 xc3,
0 xaa, 0 x44, 0 x13, 0 x26, 0 x49, 0 x86, 0 x06, 0 x99,
0 x9c, 0 x42, 0 x50, 0 xf4, 0 x91, 0 xef, 0 x98, 0 x7a,
0 x33, 0 x54, 0 x0b, 0 x43, 0 xed, 0 xcf, 0 xac, 0 x62,
0 xe4, 0 xb3, 0 x1c, 0 xa9, 0 xc9, 0 x08, 0 xe8, 0 x95,
0 x80, 0 xdf, 0 x94, 0 xfa, 0 x75, 0 x8f, 0 x3f, 0 xa6,
0 x47, 0 x07, 0 xa7, 0 xfc, 0 xf3, 0 x73, 0 x17, 0 xba,
0 x83, 0 x59, 0 x3c, 0 x19, 0 xe6, 0 x85, 0 x4f, 0 xa8,
0 x68, 0 x6b, 0 x81, 0 xb2, 0 x71, 0 x64, 0 xda, 0 x8b,
0 xf8, 0 xeb, 0 x0f, 0 x4b, 0 x70, 0 x56, 0 x9d, 0 x35,
0 x1e, 0 x24, 0 x0e, 0 x5e, 0 x63, 0 x58, 0 xd1, 0 xa2,
0 x25, 0 x22, 0 x7c, 0 x3b, 0 x01, 0 x21, 0 x78, 0 x87,
0 xd4, 0 x00, 0 x46, 0 x57, 0 x9f, 0 xd3, 0 x27, 0 x52,
0 x4c, 0 x36, 0 x02, 0 xe7, 0 xa0, 0 xc4, 0 xc8, 0 x9e,
0 xea, 0 xbf, 0 x8a, 0 xd2, 0 x40, 0 xc7, 0 x38, 0 xb5,
0 xa3, 0 xf7, 0 xf2, 0 xce, 0 xf9, 0 x61, 0 x15, 0 xa1,
0 xe0, 0 xae, 0 x5d, 0 xa4, 0 x9b, 0 x34, 0 x1a, 0 x55,
0 xad, 0 x93, 0 x32, 0 x30, 0 xf5, 0 x8c, 0 xb1, 0 xe3,
0 x1d, 0 xf6, 0 xe2, 0 x2e, 0 x82, 0 x66, 0 xca, 0 x60,
0 xc0, 0 x29, 0 x23, 0 xab, 0 x0d, 0 x53, 0 x4e, 0 x6f,
0 xd5, 0 xdb, 0 x37, 0 x45, 0 xde, 0 xfd, 0 x8e, 0 x2f,
0 x03, 0 xff, 0 x6a, 0 x72, 0 x6d, 0 x6c, 0 x5b, 0 x51,
0 x8d, 0 x1b, 0 xaf, 0 x92, 0 xbb, 0 xdd, 0 xbc, 0 x7f,
0 x11, 0 xd9, 0 x5c, 0 x41, 0 x1f, 0 x10, 0 x5a, 0 xd8,
0 x0a, 0 xc1, 0 x31, 0 x88, 0 xa5, 0 xcd, 0 x7b, 0 xbd,
0 x2d, 0 x74, 0 xd0, 0 x12, 0 xb8, 0 xe5, 0 xb4, 0 xb0,
0 x89, 0 x69, 0 x97, 0 x4a, 0 x0c, 0 x96, 0 x77, 0 x7e,
0 x65, 0 xb9, 0 xf1, 0 x09, 0 xc5, 0 x6e, 0 xc6, 0 x84,
0 x18, 0 xf0, 0 x7d, 0 xec, 0 x3a, 0 xdc, 0 x4d, 0 x20,
0 x79, 0 xee, 0 x5f, 0 x3e, 0 xd7, 0 xcb, 0 x39, 0 x48
};
extern const u32 crypto_sm4_fk[4 ] __alias(fk);
extern const u32 crypto_sm4_ck[32 ] __alias(ck);
extern const u8 crypto_sm4_sbox[256 ] __alias(sbox);
EXPORT_SYMBOL(crypto_sm4_fk);
EXPORT_SYMBOL(crypto_sm4_ck);
EXPORT_SYMBOL(crypto_sm4_sbox);
static inline u32 sm4_t_non_lin_sub(u32 x)
{
u32 out;
out = (u32)sbox[x & 0 xff];
out |= (u32)sbox[(x >> 8 ) & 0 xff] << 8 ;
out |= (u32)sbox[(x >> 16 ) & 0 xff] << 16 ;
out |= (u32)sbox[(x >> 24 ) & 0 xff] << 24 ;
return out;
}
static inline u32 sm4_key_lin_sub(u32 x)
{
return x ^ rol32(x, 13 ) ^ rol32(x, 23 );
}
static inline u32 sm4_enc_lin_sub(u32 x)
{
return x ^ rol32(x, 2 ) ^ rol32(x, 10 ) ^ rol32(x, 18 ) ^ rol32(x, 24 );
}
static inline u32 sm4_key_sub(u32 x)
{
return sm4_key_lin_sub(sm4_t_non_lin_sub(x));
}
static inline u32 sm4_enc_sub(u32 x)
{
return sm4_enc_lin_sub(sm4_t_non_lin_sub(x));
}
static inline u32 sm4_round(u32 x0, u32 x1, u32 x2, u32 x3, u32 rk)
{
return x0 ^ sm4_enc_sub(x1 ^ x2 ^ x3 ^ rk);
}
/**
* sm4_expandkey - Expands the SM4 key as described in GB / T 32907 - 2016
* @ ctx : The location where the computed key will be stored .
* @ in_key : The supplied key .
* @ key_len : The length of the supplied key .
*
* Returns 0 on success . The function fails only if an invalid key size ( or
* pointer ) is supplied .
*/
int sm4_expandkey(struct sm4_ctx *ctx, const u8 *in_key,
unsigned int key_len)
{
u32 rk[4 ];
const u32 *key = (u32 *)in_key;
int i;
if (key_len != SM4_KEY_SIZE)
return -EINVAL;
rk[0 ] = get_unaligned_be32(&key[0 ]) ^ fk[0 ];
rk[1 ] = get_unaligned_be32(&key[1 ]) ^ fk[1 ];
rk[2 ] = get_unaligned_be32(&key[2 ]) ^ fk[2 ];
rk[3 ] = get_unaligned_be32(&key[3 ]) ^ fk[3 ];
for (i = 0 ; i < 32 ; i += 4 ) {
rk[0 ] ^= sm4_key_sub(rk[1 ] ^ rk[2 ] ^ rk[3 ] ^ ck[i + 0 ]);
rk[1 ] ^= sm4_key_sub(rk[2 ] ^ rk[3 ] ^ rk[0 ] ^ ck[i + 1 ]);
rk[2 ] ^= sm4_key_sub(rk[3 ] ^ rk[0 ] ^ rk[1 ] ^ ck[i + 2 ]);
rk[3 ] ^= sm4_key_sub(rk[0 ] ^ rk[1 ] ^ rk[2 ] ^ ck[i + 3 ]);
ctx->rkey_enc[i + 0 ] = rk[0 ];
ctx->rkey_enc[i + 1 ] = rk[1 ];
ctx->rkey_enc[i + 2 ] = rk[2 ];
ctx->rkey_enc[i + 3 ] = rk[3 ];
ctx->rkey_dec[31 - 0 - i] = rk[0 ];
ctx->rkey_dec[31 - 1 - i] = rk[1 ];
ctx->rkey_dec[31 - 2 - i] = rk[2 ];
ctx->rkey_dec[31 - 3 - i] = rk[3 ];
}
return 0 ;
}
EXPORT_SYMBOL_GPL(sm4_expandkey);
/**
* sm4_crypt_block - Encrypt or decrypt a single SM4 block
* @ rk : The rkey_enc for encrypt or rkey_dec for decrypt
* @ out : Buffer to store output data
* @ in : Buffer containing the input data
*/
void sm4_crypt_block(const u32 *rk, u8 *out, const u8 *in)
{
u32 x[4 ], i;
x[0 ] = get_unaligned_be32(in + 0 * 4 );
x[1 ] = get_unaligned_be32(in + 1 * 4 );
x[2 ] = get_unaligned_be32(in + 2 * 4 );
x[3 ] = get_unaligned_be32(in + 3 * 4 );
for (i = 0 ; i < 32 ; i += 4 ) {
x[0 ] = sm4_round(x[0 ], x[1 ], x[2 ], x[3 ], rk[i + 0 ]);
x[1 ] = sm4_round(x[1 ], x[2 ], x[3 ], x[0 ], rk[i + 1 ]);
x[2 ] = sm4_round(x[2 ], x[3 ], x[0 ], x[1 ], rk[i + 2 ]);
x[3 ] = sm4_round(x[3 ], x[0 ], x[1 ], x[2 ], rk[i + 3 ]);
}
put_unaligned_be32(x[3 - 0 ], out + 0 * 4 );
put_unaligned_be32(x[3 - 1 ], out + 1 * 4 );
put_unaligned_be32(x[3 - 2 ], out + 2 * 4 );
put_unaligned_be32(x[3 - 3 ], out + 3 * 4 );
}
EXPORT_SYMBOL_GPL(sm4_crypt_block);
MODULE_DESCRIPTION("Generic SM4 library" );
MODULE_LICENSE("GPL v2" );
Messung V0.5 in Prozent C=98 H=92 G=94
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland