/* 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.11 Sekunden
(vorverarbeitet am 2026-06-05)
¤
*© Formatika GbR, Deutschland