162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Cryptographic API. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Serpent Cipher Algorithm. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <crypto/algapi.h> 1162306a36Sopenharmony_ci#include <linux/init.h> 1262306a36Sopenharmony_ci#include <linux/module.h> 1362306a36Sopenharmony_ci#include <linux/errno.h> 1462306a36Sopenharmony_ci#include <asm/unaligned.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <crypto/serpent.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Key is padded to the maximum of 256 bits before round key generation. 1962306a36Sopenharmony_ci * Any key length <= 256 bits (32 bytes) is allowed by the algorithm. 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define PHI 0x9e3779b9UL 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define keyiter(a, b, c, d, i, j) \ 2562306a36Sopenharmony_ci ({ b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b, 11); k[j] = b; }) 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define loadkeys(x0, x1, x2, x3, i) \ 2862306a36Sopenharmony_ci ({ x0 = k[i]; x1 = k[i+1]; x2 = k[i+2]; x3 = k[i+3]; }) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define storekeys(x0, x1, x2, x3, i) \ 3162306a36Sopenharmony_ci ({ k[i] = x0; k[i+1] = x1; k[i+2] = x2; k[i+3] = x3; }) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define store_and_load_keys(x0, x1, x2, x3, s, l) \ 3462306a36Sopenharmony_ci ({ storekeys(x0, x1, x2, x3, s); loadkeys(x0, x1, x2, x3, l); }) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define K(x0, x1, x2, x3, i) ({ \ 3762306a36Sopenharmony_ci x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \ 3862306a36Sopenharmony_ci x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0]; \ 3962306a36Sopenharmony_ci }) 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define LK(x0, x1, x2, x3, x4, i) ({ \ 4262306a36Sopenharmony_ci x0 = rol32(x0, 13);\ 4362306a36Sopenharmony_ci x2 = rol32(x2, 3); x1 ^= x0; x4 = x0 << 3; \ 4462306a36Sopenharmony_ci x3 ^= x2; x1 ^= x2; \ 4562306a36Sopenharmony_ci x1 = rol32(x1, 1); x3 ^= x4; \ 4662306a36Sopenharmony_ci x3 = rol32(x3, 7); x4 = x1; \ 4762306a36Sopenharmony_ci x0 ^= x1; x4 <<= 7; x2 ^= x3; \ 4862306a36Sopenharmony_ci x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \ 4962306a36Sopenharmony_ci x1 ^= k[4*i+1]; x0 = rol32(x0, 5); x2 = rol32(x2, 22);\ 5062306a36Sopenharmony_ci x0 ^= k[4*i+0]; x2 ^= k[4*i+2]; \ 5162306a36Sopenharmony_ci }) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define KL(x0, x1, x2, x3, x4, i) ({ \ 5462306a36Sopenharmony_ci x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \ 5562306a36Sopenharmony_ci x3 ^= k[4*i+3]; x0 = ror32(x0, 5); x2 = ror32(x2, 22);\ 5662306a36Sopenharmony_ci x4 = x1; x2 ^= x3; x0 ^= x3; \ 5762306a36Sopenharmony_ci x4 <<= 7; x0 ^= x1; x1 = ror32(x1, 1); \ 5862306a36Sopenharmony_ci x2 ^= x4; x3 = ror32(x3, 7); x4 = x0 << 3; \ 5962306a36Sopenharmony_ci x1 ^= x0; x3 ^= x4; x0 = ror32(x0, 13);\ 6062306a36Sopenharmony_ci x1 ^= x2; x3 ^= x2; x2 = ror32(x2, 3); \ 6162306a36Sopenharmony_ci }) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define S0(x0, x1, x2, x3, x4) ({ \ 6462306a36Sopenharmony_ci x4 = x3; \ 6562306a36Sopenharmony_ci x3 |= x0; x0 ^= x4; x4 ^= x2; \ 6662306a36Sopenharmony_ci x4 = ~x4; x3 ^= x1; x1 &= x0; \ 6762306a36Sopenharmony_ci x1 ^= x4; x2 ^= x0; x0 ^= x3; \ 6862306a36Sopenharmony_ci x4 |= x0; x0 ^= x2; x2 &= x1; \ 6962306a36Sopenharmony_ci x3 ^= x2; x1 = ~x1; x2 ^= x4; \ 7062306a36Sopenharmony_ci x1 ^= x2; \ 7162306a36Sopenharmony_ci }) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define S1(x0, x1, x2, x3, x4) ({ \ 7462306a36Sopenharmony_ci x4 = x1; \ 7562306a36Sopenharmony_ci x1 ^= x0; x0 ^= x3; x3 = ~x3; \ 7662306a36Sopenharmony_ci x4 &= x1; x0 |= x1; x3 ^= x2; \ 7762306a36Sopenharmony_ci x0 ^= x3; x1 ^= x3; x3 ^= x4; \ 7862306a36Sopenharmony_ci x1 |= x4; x4 ^= x2; x2 &= x0; \ 7962306a36Sopenharmony_ci x2 ^= x1; x1 |= x0; x0 = ~x0; \ 8062306a36Sopenharmony_ci x0 ^= x2; x4 ^= x1; \ 8162306a36Sopenharmony_ci }) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define S2(x0, x1, x2, x3, x4) ({ \ 8462306a36Sopenharmony_ci x3 = ~x3; \ 8562306a36Sopenharmony_ci x1 ^= x0; x4 = x0; x0 &= x2; \ 8662306a36Sopenharmony_ci x0 ^= x3; x3 |= x4; x2 ^= x1; \ 8762306a36Sopenharmony_ci x3 ^= x1; x1 &= x0; x0 ^= x2; \ 8862306a36Sopenharmony_ci x2 &= x3; x3 |= x1; x0 = ~x0; \ 8962306a36Sopenharmony_ci x3 ^= x0; x4 ^= x0; x0 ^= x2; \ 9062306a36Sopenharmony_ci x1 |= x2; \ 9162306a36Sopenharmony_ci }) 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci#define S3(x0, x1, x2, x3, x4) ({ \ 9462306a36Sopenharmony_ci x4 = x1; \ 9562306a36Sopenharmony_ci x1 ^= x3; x3 |= x0; x4 &= x0; \ 9662306a36Sopenharmony_ci x0 ^= x2; x2 ^= x1; x1 &= x3; \ 9762306a36Sopenharmony_ci x2 ^= x3; x0 |= x4; x4 ^= x3; \ 9862306a36Sopenharmony_ci x1 ^= x0; x0 &= x3; x3 &= x4; \ 9962306a36Sopenharmony_ci x3 ^= x2; x4 |= x1; x2 &= x1; \ 10062306a36Sopenharmony_ci x4 ^= x3; x0 ^= x3; x3 ^= x2; \ 10162306a36Sopenharmony_ci }) 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define S4(x0, x1, x2, x3, x4) ({ \ 10462306a36Sopenharmony_ci x4 = x3; \ 10562306a36Sopenharmony_ci x3 &= x0; x0 ^= x4; \ 10662306a36Sopenharmony_ci x3 ^= x2; x2 |= x4; x0 ^= x1; \ 10762306a36Sopenharmony_ci x4 ^= x3; x2 |= x0; \ 10862306a36Sopenharmony_ci x2 ^= x1; x1 &= x0; \ 10962306a36Sopenharmony_ci x1 ^= x4; x4 &= x2; x2 ^= x3; \ 11062306a36Sopenharmony_ci x4 ^= x0; x3 |= x1; x1 = ~x1; \ 11162306a36Sopenharmony_ci x3 ^= x0; \ 11262306a36Sopenharmony_ci }) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define S5(x0, x1, x2, x3, x4) ({ \ 11562306a36Sopenharmony_ci x4 = x1; x1 |= x0; \ 11662306a36Sopenharmony_ci x2 ^= x1; x3 = ~x3; x4 ^= x0; \ 11762306a36Sopenharmony_ci x0 ^= x2; x1 &= x4; x4 |= x3; \ 11862306a36Sopenharmony_ci x4 ^= x0; x0 &= x3; x1 ^= x3; \ 11962306a36Sopenharmony_ci x3 ^= x2; x0 ^= x1; x2 &= x4; \ 12062306a36Sopenharmony_ci x1 ^= x2; x2 &= x0; \ 12162306a36Sopenharmony_ci x3 ^= x2; \ 12262306a36Sopenharmony_ci }) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define S6(x0, x1, x2, x3, x4) ({ \ 12562306a36Sopenharmony_ci x4 = x1; \ 12662306a36Sopenharmony_ci x3 ^= x0; x1 ^= x2; x2 ^= x0; \ 12762306a36Sopenharmony_ci x0 &= x3; x1 |= x3; x4 = ~x4; \ 12862306a36Sopenharmony_ci x0 ^= x1; x1 ^= x2; \ 12962306a36Sopenharmony_ci x3 ^= x4; x4 ^= x0; x2 &= x0; \ 13062306a36Sopenharmony_ci x4 ^= x1; x2 ^= x3; x3 &= x1; \ 13162306a36Sopenharmony_ci x3 ^= x0; x1 ^= x2; \ 13262306a36Sopenharmony_ci }) 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#define S7(x0, x1, x2, x3, x4) ({ \ 13562306a36Sopenharmony_ci x1 = ~x1; \ 13662306a36Sopenharmony_ci x4 = x1; x0 = ~x0; x1 &= x2; \ 13762306a36Sopenharmony_ci x1 ^= x3; x3 |= x4; x4 ^= x2; \ 13862306a36Sopenharmony_ci x2 ^= x3; x3 ^= x0; x0 |= x1; \ 13962306a36Sopenharmony_ci x2 &= x0; x0 ^= x4; x4 ^= x3; \ 14062306a36Sopenharmony_ci x3 &= x0; x4 ^= x1; \ 14162306a36Sopenharmony_ci x2 ^= x4; x3 ^= x1; x4 |= x0; \ 14262306a36Sopenharmony_ci x4 ^= x1; \ 14362306a36Sopenharmony_ci }) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci#define SI0(x0, x1, x2, x3, x4) ({ \ 14662306a36Sopenharmony_ci x4 = x3; x1 ^= x0; \ 14762306a36Sopenharmony_ci x3 |= x1; x4 ^= x1; x0 = ~x0; \ 14862306a36Sopenharmony_ci x2 ^= x3; x3 ^= x0; x0 &= x1; \ 14962306a36Sopenharmony_ci x0 ^= x2; x2 &= x3; x3 ^= x4; \ 15062306a36Sopenharmony_ci x2 ^= x3; x1 ^= x3; x3 &= x0; \ 15162306a36Sopenharmony_ci x1 ^= x0; x0 ^= x2; x4 ^= x3; \ 15262306a36Sopenharmony_ci }) 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#define SI1(x0, x1, x2, x3, x4) ({ \ 15562306a36Sopenharmony_ci x1 ^= x3; x4 = x0; \ 15662306a36Sopenharmony_ci x0 ^= x2; x2 = ~x2; x4 |= x1; \ 15762306a36Sopenharmony_ci x4 ^= x3; x3 &= x1; x1 ^= x2; \ 15862306a36Sopenharmony_ci x2 &= x4; x4 ^= x1; x1 |= x3; \ 15962306a36Sopenharmony_ci x3 ^= x0; x2 ^= x0; x0 |= x4; \ 16062306a36Sopenharmony_ci x2 ^= x4; x1 ^= x0; \ 16162306a36Sopenharmony_ci x4 ^= x1; \ 16262306a36Sopenharmony_ci }) 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci#define SI2(x0, x1, x2, x3, x4) ({ \ 16562306a36Sopenharmony_ci x2 ^= x1; x4 = x3; x3 = ~x3; \ 16662306a36Sopenharmony_ci x3 |= x2; x2 ^= x4; x4 ^= x0; \ 16762306a36Sopenharmony_ci x3 ^= x1; x1 |= x2; x2 ^= x0; \ 16862306a36Sopenharmony_ci x1 ^= x4; x4 |= x3; x2 ^= x3; \ 16962306a36Sopenharmony_ci x4 ^= x2; x2 &= x1; \ 17062306a36Sopenharmony_ci x2 ^= x3; x3 ^= x4; x4 ^= x0; \ 17162306a36Sopenharmony_ci }) 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#define SI3(x0, x1, x2, x3, x4) ({ \ 17462306a36Sopenharmony_ci x2 ^= x1; \ 17562306a36Sopenharmony_ci x4 = x1; x1 &= x2; \ 17662306a36Sopenharmony_ci x1 ^= x0; x0 |= x4; x4 ^= x3; \ 17762306a36Sopenharmony_ci x0 ^= x3; x3 |= x1; x1 ^= x2; \ 17862306a36Sopenharmony_ci x1 ^= x3; x0 ^= x2; x2 ^= x3; \ 17962306a36Sopenharmony_ci x3 &= x1; x1 ^= x0; x0 &= x2; \ 18062306a36Sopenharmony_ci x4 ^= x3; x3 ^= x0; x0 ^= x1; \ 18162306a36Sopenharmony_ci }) 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#define SI4(x0, x1, x2, x3, x4) ({ \ 18462306a36Sopenharmony_ci x2 ^= x3; x4 = x0; x0 &= x1; \ 18562306a36Sopenharmony_ci x0 ^= x2; x2 |= x3; x4 = ~x4; \ 18662306a36Sopenharmony_ci x1 ^= x0; x0 ^= x2; x2 &= x4; \ 18762306a36Sopenharmony_ci x2 ^= x0; x0 |= x4; \ 18862306a36Sopenharmony_ci x0 ^= x3; x3 &= x2; \ 18962306a36Sopenharmony_ci x4 ^= x3; x3 ^= x1; x1 &= x0; \ 19062306a36Sopenharmony_ci x4 ^= x1; x0 ^= x3; \ 19162306a36Sopenharmony_ci }) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#define SI5(x0, x1, x2, x3, x4) ({ \ 19462306a36Sopenharmony_ci x4 = x1; x1 |= x2; \ 19562306a36Sopenharmony_ci x2 ^= x4; x1 ^= x3; x3 &= x4; \ 19662306a36Sopenharmony_ci x2 ^= x3; x3 |= x0; x0 = ~x0; \ 19762306a36Sopenharmony_ci x3 ^= x2; x2 |= x0; x4 ^= x1; \ 19862306a36Sopenharmony_ci x2 ^= x4; x4 &= x0; x0 ^= x1; \ 19962306a36Sopenharmony_ci x1 ^= x3; x0 &= x2; x2 ^= x3; \ 20062306a36Sopenharmony_ci x0 ^= x2; x2 ^= x4; x4 ^= x3; \ 20162306a36Sopenharmony_ci }) 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#define SI6(x0, x1, x2, x3, x4) ({ \ 20462306a36Sopenharmony_ci x0 ^= x2; \ 20562306a36Sopenharmony_ci x4 = x0; x0 &= x3; x2 ^= x3; \ 20662306a36Sopenharmony_ci x0 ^= x2; x3 ^= x1; x2 |= x4; \ 20762306a36Sopenharmony_ci x2 ^= x3; x3 &= x0; x0 = ~x0; \ 20862306a36Sopenharmony_ci x3 ^= x1; x1 &= x2; x4 ^= x0; \ 20962306a36Sopenharmony_ci x3 ^= x4; x4 ^= x2; x0 ^= x1; \ 21062306a36Sopenharmony_ci x2 ^= x0; \ 21162306a36Sopenharmony_ci }) 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci#define SI7(x0, x1, x2, x3, x4) ({ \ 21462306a36Sopenharmony_ci x4 = x3; x3 &= x0; x0 ^= x2; \ 21562306a36Sopenharmony_ci x2 |= x4; x4 ^= x1; x0 = ~x0; \ 21662306a36Sopenharmony_ci x1 |= x3; x4 ^= x0; x0 &= x2; \ 21762306a36Sopenharmony_ci x0 ^= x1; x1 &= x2; x3 ^= x2; \ 21862306a36Sopenharmony_ci x4 ^= x3; x2 &= x3; x3 |= x0; \ 21962306a36Sopenharmony_ci x1 ^= x4; x3 ^= x4; x4 &= x0; \ 22062306a36Sopenharmony_ci x4 ^= x2; \ 22162306a36Sopenharmony_ci }) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* 22462306a36Sopenharmony_ci * both gcc and clang have misoptimized this function in the past, 22562306a36Sopenharmony_ci * producing horrible object code from spilling temporary variables 22662306a36Sopenharmony_ci * on the stack. Forcing this part out of line avoids that. 22762306a36Sopenharmony_ci */ 22862306a36Sopenharmony_cistatic noinline void __serpent_setkey_sbox(u32 r0, u32 r1, u32 r2, 22962306a36Sopenharmony_ci u32 r3, u32 r4, u32 *k) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci k += 100; 23262306a36Sopenharmony_ci S3(r3, r4, r0, r1, r2); store_and_load_keys(r1, r2, r4, r3, 28, 24); 23362306a36Sopenharmony_ci S4(r1, r2, r4, r3, r0); store_and_load_keys(r2, r4, r3, r0, 24, 20); 23462306a36Sopenharmony_ci S5(r2, r4, r3, r0, r1); store_and_load_keys(r1, r2, r4, r0, 20, 16); 23562306a36Sopenharmony_ci S6(r1, r2, r4, r0, r3); store_and_load_keys(r4, r3, r2, r0, 16, 12); 23662306a36Sopenharmony_ci S7(r4, r3, r2, r0, r1); store_and_load_keys(r1, r2, r0, r4, 12, 8); 23762306a36Sopenharmony_ci S0(r1, r2, r0, r4, r3); store_and_load_keys(r0, r2, r4, r1, 8, 4); 23862306a36Sopenharmony_ci S1(r0, r2, r4, r1, r3); store_and_load_keys(r3, r4, r1, r0, 4, 0); 23962306a36Sopenharmony_ci S2(r3, r4, r1, r0, r2); store_and_load_keys(r2, r4, r3, r0, 0, -4); 24062306a36Sopenharmony_ci S3(r2, r4, r3, r0, r1); store_and_load_keys(r0, r1, r4, r2, -4, -8); 24162306a36Sopenharmony_ci S4(r0, r1, r4, r2, r3); store_and_load_keys(r1, r4, r2, r3, -8, -12); 24262306a36Sopenharmony_ci S5(r1, r4, r2, r3, r0); store_and_load_keys(r0, r1, r4, r3, -12, -16); 24362306a36Sopenharmony_ci S6(r0, r1, r4, r3, r2); store_and_load_keys(r4, r2, r1, r3, -16, -20); 24462306a36Sopenharmony_ci S7(r4, r2, r1, r3, r0); store_and_load_keys(r0, r1, r3, r4, -20, -24); 24562306a36Sopenharmony_ci S0(r0, r1, r3, r4, r2); store_and_load_keys(r3, r1, r4, r0, -24, -28); 24662306a36Sopenharmony_ci k -= 50; 24762306a36Sopenharmony_ci S1(r3, r1, r4, r0, r2); store_and_load_keys(r2, r4, r0, r3, 22, 18); 24862306a36Sopenharmony_ci S2(r2, r4, r0, r3, r1); store_and_load_keys(r1, r4, r2, r3, 18, 14); 24962306a36Sopenharmony_ci S3(r1, r4, r2, r3, r0); store_and_load_keys(r3, r0, r4, r1, 14, 10); 25062306a36Sopenharmony_ci S4(r3, r0, r4, r1, r2); store_and_load_keys(r0, r4, r1, r2, 10, 6); 25162306a36Sopenharmony_ci S5(r0, r4, r1, r2, r3); store_and_load_keys(r3, r0, r4, r2, 6, 2); 25262306a36Sopenharmony_ci S6(r3, r0, r4, r2, r1); store_and_load_keys(r4, r1, r0, r2, 2, -2); 25362306a36Sopenharmony_ci S7(r4, r1, r0, r2, r3); store_and_load_keys(r3, r0, r2, r4, -2, -6); 25462306a36Sopenharmony_ci S0(r3, r0, r2, r4, r1); store_and_load_keys(r2, r0, r4, r3, -6, -10); 25562306a36Sopenharmony_ci S1(r2, r0, r4, r3, r1); store_and_load_keys(r1, r4, r3, r2, -10, -14); 25662306a36Sopenharmony_ci S2(r1, r4, r3, r2, r0); store_and_load_keys(r0, r4, r1, r2, -14, -18); 25762306a36Sopenharmony_ci S3(r0, r4, r1, r2, r3); store_and_load_keys(r2, r3, r4, r0, -18, -22); 25862306a36Sopenharmony_ci k -= 50; 25962306a36Sopenharmony_ci S4(r2, r3, r4, r0, r1); store_and_load_keys(r3, r4, r0, r1, 28, 24); 26062306a36Sopenharmony_ci S5(r3, r4, r0, r1, r2); store_and_load_keys(r2, r3, r4, r1, 24, 20); 26162306a36Sopenharmony_ci S6(r2, r3, r4, r1, r0); store_and_load_keys(r4, r0, r3, r1, 20, 16); 26262306a36Sopenharmony_ci S7(r4, r0, r3, r1, r2); store_and_load_keys(r2, r3, r1, r4, 16, 12); 26362306a36Sopenharmony_ci S0(r2, r3, r1, r4, r0); store_and_load_keys(r1, r3, r4, r2, 12, 8); 26462306a36Sopenharmony_ci S1(r1, r3, r4, r2, r0); store_and_load_keys(r0, r4, r2, r1, 8, 4); 26562306a36Sopenharmony_ci S2(r0, r4, r2, r1, r3); store_and_load_keys(r3, r4, r0, r1, 4, 0); 26662306a36Sopenharmony_ci S3(r3, r4, r0, r1, r2); storekeys(r1, r2, r4, r3, 0); 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ciint __serpent_setkey(struct serpent_ctx *ctx, const u8 *key, 27062306a36Sopenharmony_ci unsigned int keylen) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci u32 *k = ctx->expkey; 27362306a36Sopenharmony_ci u8 *k8 = (u8 *)k; 27462306a36Sopenharmony_ci u32 r0, r1, r2, r3, r4; 27562306a36Sopenharmony_ci __le32 *lk; 27662306a36Sopenharmony_ci int i; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci /* Copy key, add padding */ 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci for (i = 0; i < keylen; ++i) 28162306a36Sopenharmony_ci k8[i] = key[i]; 28262306a36Sopenharmony_ci if (i < SERPENT_MAX_KEY_SIZE) 28362306a36Sopenharmony_ci k8[i++] = 1; 28462306a36Sopenharmony_ci while (i < SERPENT_MAX_KEY_SIZE) 28562306a36Sopenharmony_ci k8[i++] = 0; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci lk = (__le32 *)k; 28862306a36Sopenharmony_ci k[0] = le32_to_cpu(lk[0]); 28962306a36Sopenharmony_ci k[1] = le32_to_cpu(lk[1]); 29062306a36Sopenharmony_ci k[2] = le32_to_cpu(lk[2]); 29162306a36Sopenharmony_ci k[3] = le32_to_cpu(lk[3]); 29262306a36Sopenharmony_ci k[4] = le32_to_cpu(lk[4]); 29362306a36Sopenharmony_ci k[5] = le32_to_cpu(lk[5]); 29462306a36Sopenharmony_ci k[6] = le32_to_cpu(lk[6]); 29562306a36Sopenharmony_ci k[7] = le32_to_cpu(lk[7]); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* Expand key using polynomial */ 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci r0 = k[3]; 30062306a36Sopenharmony_ci r1 = k[4]; 30162306a36Sopenharmony_ci r2 = k[5]; 30262306a36Sopenharmony_ci r3 = k[6]; 30362306a36Sopenharmony_ci r4 = k[7]; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci keyiter(k[0], r0, r4, r2, 0, 0); 30662306a36Sopenharmony_ci keyiter(k[1], r1, r0, r3, 1, 1); 30762306a36Sopenharmony_ci keyiter(k[2], r2, r1, r4, 2, 2); 30862306a36Sopenharmony_ci keyiter(k[3], r3, r2, r0, 3, 3); 30962306a36Sopenharmony_ci keyiter(k[4], r4, r3, r1, 4, 4); 31062306a36Sopenharmony_ci keyiter(k[5], r0, r4, r2, 5, 5); 31162306a36Sopenharmony_ci keyiter(k[6], r1, r0, r3, 6, 6); 31262306a36Sopenharmony_ci keyiter(k[7], r2, r1, r4, 7, 7); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci keyiter(k[0], r3, r2, r0, 8, 8); 31562306a36Sopenharmony_ci keyiter(k[1], r4, r3, r1, 9, 9); 31662306a36Sopenharmony_ci keyiter(k[2], r0, r4, r2, 10, 10); 31762306a36Sopenharmony_ci keyiter(k[3], r1, r0, r3, 11, 11); 31862306a36Sopenharmony_ci keyiter(k[4], r2, r1, r4, 12, 12); 31962306a36Sopenharmony_ci keyiter(k[5], r3, r2, r0, 13, 13); 32062306a36Sopenharmony_ci keyiter(k[6], r4, r3, r1, 14, 14); 32162306a36Sopenharmony_ci keyiter(k[7], r0, r4, r2, 15, 15); 32262306a36Sopenharmony_ci keyiter(k[8], r1, r0, r3, 16, 16); 32362306a36Sopenharmony_ci keyiter(k[9], r2, r1, r4, 17, 17); 32462306a36Sopenharmony_ci keyiter(k[10], r3, r2, r0, 18, 18); 32562306a36Sopenharmony_ci keyiter(k[11], r4, r3, r1, 19, 19); 32662306a36Sopenharmony_ci keyiter(k[12], r0, r4, r2, 20, 20); 32762306a36Sopenharmony_ci keyiter(k[13], r1, r0, r3, 21, 21); 32862306a36Sopenharmony_ci keyiter(k[14], r2, r1, r4, 22, 22); 32962306a36Sopenharmony_ci keyiter(k[15], r3, r2, r0, 23, 23); 33062306a36Sopenharmony_ci keyiter(k[16], r4, r3, r1, 24, 24); 33162306a36Sopenharmony_ci keyiter(k[17], r0, r4, r2, 25, 25); 33262306a36Sopenharmony_ci keyiter(k[18], r1, r0, r3, 26, 26); 33362306a36Sopenharmony_ci keyiter(k[19], r2, r1, r4, 27, 27); 33462306a36Sopenharmony_ci keyiter(k[20], r3, r2, r0, 28, 28); 33562306a36Sopenharmony_ci keyiter(k[21], r4, r3, r1, 29, 29); 33662306a36Sopenharmony_ci keyiter(k[22], r0, r4, r2, 30, 30); 33762306a36Sopenharmony_ci keyiter(k[23], r1, r0, r3, 31, 31); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci k += 50; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci keyiter(k[-26], r2, r1, r4, 32, -18); 34262306a36Sopenharmony_ci keyiter(k[-25], r3, r2, r0, 33, -17); 34362306a36Sopenharmony_ci keyiter(k[-24], r4, r3, r1, 34, -16); 34462306a36Sopenharmony_ci keyiter(k[-23], r0, r4, r2, 35, -15); 34562306a36Sopenharmony_ci keyiter(k[-22], r1, r0, r3, 36, -14); 34662306a36Sopenharmony_ci keyiter(k[-21], r2, r1, r4, 37, -13); 34762306a36Sopenharmony_ci keyiter(k[-20], r3, r2, r0, 38, -12); 34862306a36Sopenharmony_ci keyiter(k[-19], r4, r3, r1, 39, -11); 34962306a36Sopenharmony_ci keyiter(k[-18], r0, r4, r2, 40, -10); 35062306a36Sopenharmony_ci keyiter(k[-17], r1, r0, r3, 41, -9); 35162306a36Sopenharmony_ci keyiter(k[-16], r2, r1, r4, 42, -8); 35262306a36Sopenharmony_ci keyiter(k[-15], r3, r2, r0, 43, -7); 35362306a36Sopenharmony_ci keyiter(k[-14], r4, r3, r1, 44, -6); 35462306a36Sopenharmony_ci keyiter(k[-13], r0, r4, r2, 45, -5); 35562306a36Sopenharmony_ci keyiter(k[-12], r1, r0, r3, 46, -4); 35662306a36Sopenharmony_ci keyiter(k[-11], r2, r1, r4, 47, -3); 35762306a36Sopenharmony_ci keyiter(k[-10], r3, r2, r0, 48, -2); 35862306a36Sopenharmony_ci keyiter(k[-9], r4, r3, r1, 49, -1); 35962306a36Sopenharmony_ci keyiter(k[-8], r0, r4, r2, 50, 0); 36062306a36Sopenharmony_ci keyiter(k[-7], r1, r0, r3, 51, 1); 36162306a36Sopenharmony_ci keyiter(k[-6], r2, r1, r4, 52, 2); 36262306a36Sopenharmony_ci keyiter(k[-5], r3, r2, r0, 53, 3); 36362306a36Sopenharmony_ci keyiter(k[-4], r4, r3, r1, 54, 4); 36462306a36Sopenharmony_ci keyiter(k[-3], r0, r4, r2, 55, 5); 36562306a36Sopenharmony_ci keyiter(k[-2], r1, r0, r3, 56, 6); 36662306a36Sopenharmony_ci keyiter(k[-1], r2, r1, r4, 57, 7); 36762306a36Sopenharmony_ci keyiter(k[0], r3, r2, r0, 58, 8); 36862306a36Sopenharmony_ci keyiter(k[1], r4, r3, r1, 59, 9); 36962306a36Sopenharmony_ci keyiter(k[2], r0, r4, r2, 60, 10); 37062306a36Sopenharmony_ci keyiter(k[3], r1, r0, r3, 61, 11); 37162306a36Sopenharmony_ci keyiter(k[4], r2, r1, r4, 62, 12); 37262306a36Sopenharmony_ci keyiter(k[5], r3, r2, r0, 63, 13); 37362306a36Sopenharmony_ci keyiter(k[6], r4, r3, r1, 64, 14); 37462306a36Sopenharmony_ci keyiter(k[7], r0, r4, r2, 65, 15); 37562306a36Sopenharmony_ci keyiter(k[8], r1, r0, r3, 66, 16); 37662306a36Sopenharmony_ci keyiter(k[9], r2, r1, r4, 67, 17); 37762306a36Sopenharmony_ci keyiter(k[10], r3, r2, r0, 68, 18); 37862306a36Sopenharmony_ci keyiter(k[11], r4, r3, r1, 69, 19); 37962306a36Sopenharmony_ci keyiter(k[12], r0, r4, r2, 70, 20); 38062306a36Sopenharmony_ci keyiter(k[13], r1, r0, r3, 71, 21); 38162306a36Sopenharmony_ci keyiter(k[14], r2, r1, r4, 72, 22); 38262306a36Sopenharmony_ci keyiter(k[15], r3, r2, r0, 73, 23); 38362306a36Sopenharmony_ci keyiter(k[16], r4, r3, r1, 74, 24); 38462306a36Sopenharmony_ci keyiter(k[17], r0, r4, r2, 75, 25); 38562306a36Sopenharmony_ci keyiter(k[18], r1, r0, r3, 76, 26); 38662306a36Sopenharmony_ci keyiter(k[19], r2, r1, r4, 77, 27); 38762306a36Sopenharmony_ci keyiter(k[20], r3, r2, r0, 78, 28); 38862306a36Sopenharmony_ci keyiter(k[21], r4, r3, r1, 79, 29); 38962306a36Sopenharmony_ci keyiter(k[22], r0, r4, r2, 80, 30); 39062306a36Sopenharmony_ci keyiter(k[23], r1, r0, r3, 81, 31); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci k += 50; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci keyiter(k[-26], r2, r1, r4, 82, -18); 39562306a36Sopenharmony_ci keyiter(k[-25], r3, r2, r0, 83, -17); 39662306a36Sopenharmony_ci keyiter(k[-24], r4, r3, r1, 84, -16); 39762306a36Sopenharmony_ci keyiter(k[-23], r0, r4, r2, 85, -15); 39862306a36Sopenharmony_ci keyiter(k[-22], r1, r0, r3, 86, -14); 39962306a36Sopenharmony_ci keyiter(k[-21], r2, r1, r4, 87, -13); 40062306a36Sopenharmony_ci keyiter(k[-20], r3, r2, r0, 88, -12); 40162306a36Sopenharmony_ci keyiter(k[-19], r4, r3, r1, 89, -11); 40262306a36Sopenharmony_ci keyiter(k[-18], r0, r4, r2, 90, -10); 40362306a36Sopenharmony_ci keyiter(k[-17], r1, r0, r3, 91, -9); 40462306a36Sopenharmony_ci keyiter(k[-16], r2, r1, r4, 92, -8); 40562306a36Sopenharmony_ci keyiter(k[-15], r3, r2, r0, 93, -7); 40662306a36Sopenharmony_ci keyiter(k[-14], r4, r3, r1, 94, -6); 40762306a36Sopenharmony_ci keyiter(k[-13], r0, r4, r2, 95, -5); 40862306a36Sopenharmony_ci keyiter(k[-12], r1, r0, r3, 96, -4); 40962306a36Sopenharmony_ci keyiter(k[-11], r2, r1, r4, 97, -3); 41062306a36Sopenharmony_ci keyiter(k[-10], r3, r2, r0, 98, -2); 41162306a36Sopenharmony_ci keyiter(k[-9], r4, r3, r1, 99, -1); 41262306a36Sopenharmony_ci keyiter(k[-8], r0, r4, r2, 100, 0); 41362306a36Sopenharmony_ci keyiter(k[-7], r1, r0, r3, 101, 1); 41462306a36Sopenharmony_ci keyiter(k[-6], r2, r1, r4, 102, 2); 41562306a36Sopenharmony_ci keyiter(k[-5], r3, r2, r0, 103, 3); 41662306a36Sopenharmony_ci keyiter(k[-4], r4, r3, r1, 104, 4); 41762306a36Sopenharmony_ci keyiter(k[-3], r0, r4, r2, 105, 5); 41862306a36Sopenharmony_ci keyiter(k[-2], r1, r0, r3, 106, 6); 41962306a36Sopenharmony_ci keyiter(k[-1], r2, r1, r4, 107, 7); 42062306a36Sopenharmony_ci keyiter(k[0], r3, r2, r0, 108, 8); 42162306a36Sopenharmony_ci keyiter(k[1], r4, r3, r1, 109, 9); 42262306a36Sopenharmony_ci keyiter(k[2], r0, r4, r2, 110, 10); 42362306a36Sopenharmony_ci keyiter(k[3], r1, r0, r3, 111, 11); 42462306a36Sopenharmony_ci keyiter(k[4], r2, r1, r4, 112, 12); 42562306a36Sopenharmony_ci keyiter(k[5], r3, r2, r0, 113, 13); 42662306a36Sopenharmony_ci keyiter(k[6], r4, r3, r1, 114, 14); 42762306a36Sopenharmony_ci keyiter(k[7], r0, r4, r2, 115, 15); 42862306a36Sopenharmony_ci keyiter(k[8], r1, r0, r3, 116, 16); 42962306a36Sopenharmony_ci keyiter(k[9], r2, r1, r4, 117, 17); 43062306a36Sopenharmony_ci keyiter(k[10], r3, r2, r0, 118, 18); 43162306a36Sopenharmony_ci keyiter(k[11], r4, r3, r1, 119, 19); 43262306a36Sopenharmony_ci keyiter(k[12], r0, r4, r2, 120, 20); 43362306a36Sopenharmony_ci keyiter(k[13], r1, r0, r3, 121, 21); 43462306a36Sopenharmony_ci keyiter(k[14], r2, r1, r4, 122, 22); 43562306a36Sopenharmony_ci keyiter(k[15], r3, r2, r0, 123, 23); 43662306a36Sopenharmony_ci keyiter(k[16], r4, r3, r1, 124, 24); 43762306a36Sopenharmony_ci keyiter(k[17], r0, r4, r2, 125, 25); 43862306a36Sopenharmony_ci keyiter(k[18], r1, r0, r3, 126, 26); 43962306a36Sopenharmony_ci keyiter(k[19], r2, r1, r4, 127, 27); 44062306a36Sopenharmony_ci keyiter(k[20], r3, r2, r0, 128, 28); 44162306a36Sopenharmony_ci keyiter(k[21], r4, r3, r1, 129, 29); 44262306a36Sopenharmony_ci keyiter(k[22], r0, r4, r2, 130, 30); 44362306a36Sopenharmony_ci keyiter(k[23], r1, r0, r3, 131, 31); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci /* Apply S-boxes */ 44662306a36Sopenharmony_ci __serpent_setkey_sbox(r0, r1, r2, r3, r4, ctx->expkey); 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci return 0; 44962306a36Sopenharmony_ci} 45062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__serpent_setkey); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ciint serpent_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci return __serpent_setkey(crypto_tfm_ctx(tfm), key, keylen); 45562306a36Sopenharmony_ci} 45662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serpent_setkey); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_civoid __serpent_encrypt(const void *c, u8 *dst, const u8 *src) 45962306a36Sopenharmony_ci{ 46062306a36Sopenharmony_ci const struct serpent_ctx *ctx = c; 46162306a36Sopenharmony_ci const u32 *k = ctx->expkey; 46262306a36Sopenharmony_ci u32 r0, r1, r2, r3, r4; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci r0 = get_unaligned_le32(src); 46562306a36Sopenharmony_ci r1 = get_unaligned_le32(src + 4); 46662306a36Sopenharmony_ci r2 = get_unaligned_le32(src + 8); 46762306a36Sopenharmony_ci r3 = get_unaligned_le32(src + 12); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci K(r0, r1, r2, r3, 0); 47062306a36Sopenharmony_ci S0(r0, r1, r2, r3, r4); LK(r2, r1, r3, r0, r4, 1); 47162306a36Sopenharmony_ci S1(r2, r1, r3, r0, r4); LK(r4, r3, r0, r2, r1, 2); 47262306a36Sopenharmony_ci S2(r4, r3, r0, r2, r1); LK(r1, r3, r4, r2, r0, 3); 47362306a36Sopenharmony_ci S3(r1, r3, r4, r2, r0); LK(r2, r0, r3, r1, r4, 4); 47462306a36Sopenharmony_ci S4(r2, r0, r3, r1, r4); LK(r0, r3, r1, r4, r2, 5); 47562306a36Sopenharmony_ci S5(r0, r3, r1, r4, r2); LK(r2, r0, r3, r4, r1, 6); 47662306a36Sopenharmony_ci S6(r2, r0, r3, r4, r1); LK(r3, r1, r0, r4, r2, 7); 47762306a36Sopenharmony_ci S7(r3, r1, r0, r4, r2); LK(r2, r0, r4, r3, r1, 8); 47862306a36Sopenharmony_ci S0(r2, r0, r4, r3, r1); LK(r4, r0, r3, r2, r1, 9); 47962306a36Sopenharmony_ci S1(r4, r0, r3, r2, r1); LK(r1, r3, r2, r4, r0, 10); 48062306a36Sopenharmony_ci S2(r1, r3, r2, r4, r0); LK(r0, r3, r1, r4, r2, 11); 48162306a36Sopenharmony_ci S3(r0, r3, r1, r4, r2); LK(r4, r2, r3, r0, r1, 12); 48262306a36Sopenharmony_ci S4(r4, r2, r3, r0, r1); LK(r2, r3, r0, r1, r4, 13); 48362306a36Sopenharmony_ci S5(r2, r3, r0, r1, r4); LK(r4, r2, r3, r1, r0, 14); 48462306a36Sopenharmony_ci S6(r4, r2, r3, r1, r0); LK(r3, r0, r2, r1, r4, 15); 48562306a36Sopenharmony_ci S7(r3, r0, r2, r1, r4); LK(r4, r2, r1, r3, r0, 16); 48662306a36Sopenharmony_ci S0(r4, r2, r1, r3, r0); LK(r1, r2, r3, r4, r0, 17); 48762306a36Sopenharmony_ci S1(r1, r2, r3, r4, r0); LK(r0, r3, r4, r1, r2, 18); 48862306a36Sopenharmony_ci S2(r0, r3, r4, r1, r2); LK(r2, r3, r0, r1, r4, 19); 48962306a36Sopenharmony_ci S3(r2, r3, r0, r1, r4); LK(r1, r4, r3, r2, r0, 20); 49062306a36Sopenharmony_ci S4(r1, r4, r3, r2, r0); LK(r4, r3, r2, r0, r1, 21); 49162306a36Sopenharmony_ci S5(r4, r3, r2, r0, r1); LK(r1, r4, r3, r0, r2, 22); 49262306a36Sopenharmony_ci S6(r1, r4, r3, r0, r2); LK(r3, r2, r4, r0, r1, 23); 49362306a36Sopenharmony_ci S7(r3, r2, r4, r0, r1); LK(r1, r4, r0, r3, r2, 24); 49462306a36Sopenharmony_ci S0(r1, r4, r0, r3, r2); LK(r0, r4, r3, r1, r2, 25); 49562306a36Sopenharmony_ci S1(r0, r4, r3, r1, r2); LK(r2, r3, r1, r0, r4, 26); 49662306a36Sopenharmony_ci S2(r2, r3, r1, r0, r4); LK(r4, r3, r2, r0, r1, 27); 49762306a36Sopenharmony_ci S3(r4, r3, r2, r0, r1); LK(r0, r1, r3, r4, r2, 28); 49862306a36Sopenharmony_ci S4(r0, r1, r3, r4, r2); LK(r1, r3, r4, r2, r0, 29); 49962306a36Sopenharmony_ci S5(r1, r3, r4, r2, r0); LK(r0, r1, r3, r2, r4, 30); 50062306a36Sopenharmony_ci S6(r0, r1, r3, r2, r4); LK(r3, r4, r1, r2, r0, 31); 50162306a36Sopenharmony_ci S7(r3, r4, r1, r2, r0); K(r0, r1, r2, r3, 32); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci put_unaligned_le32(r0, dst); 50462306a36Sopenharmony_ci put_unaligned_le32(r1, dst + 4); 50562306a36Sopenharmony_ci put_unaligned_le32(r2, dst + 8); 50662306a36Sopenharmony_ci put_unaligned_le32(r3, dst + 12); 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__serpent_encrypt); 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_cistatic void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 51162306a36Sopenharmony_ci{ 51262306a36Sopenharmony_ci struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci __serpent_encrypt(ctx, dst, src); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_civoid __serpent_decrypt(const void *c, u8 *dst, const u8 *src) 51862306a36Sopenharmony_ci{ 51962306a36Sopenharmony_ci const struct serpent_ctx *ctx = c; 52062306a36Sopenharmony_ci const u32 *k = ctx->expkey; 52162306a36Sopenharmony_ci u32 r0, r1, r2, r3, r4; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci r0 = get_unaligned_le32(src); 52462306a36Sopenharmony_ci r1 = get_unaligned_le32(src + 4); 52562306a36Sopenharmony_ci r2 = get_unaligned_le32(src + 8); 52662306a36Sopenharmony_ci r3 = get_unaligned_le32(src + 12); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci K(r0, r1, r2, r3, 32); 52962306a36Sopenharmony_ci SI7(r0, r1, r2, r3, r4); KL(r1, r3, r0, r4, r2, 31); 53062306a36Sopenharmony_ci SI6(r1, r3, r0, r4, r2); KL(r0, r2, r4, r1, r3, 30); 53162306a36Sopenharmony_ci SI5(r0, r2, r4, r1, r3); KL(r2, r3, r0, r4, r1, 29); 53262306a36Sopenharmony_ci SI4(r2, r3, r0, r4, r1); KL(r2, r0, r1, r4, r3, 28); 53362306a36Sopenharmony_ci SI3(r2, r0, r1, r4, r3); KL(r1, r2, r3, r4, r0, 27); 53462306a36Sopenharmony_ci SI2(r1, r2, r3, r4, r0); KL(r2, r0, r4, r3, r1, 26); 53562306a36Sopenharmony_ci SI1(r2, r0, r4, r3, r1); KL(r1, r0, r4, r3, r2, 25); 53662306a36Sopenharmony_ci SI0(r1, r0, r4, r3, r2); KL(r4, r2, r0, r1, r3, 24); 53762306a36Sopenharmony_ci SI7(r4, r2, r0, r1, r3); KL(r2, r1, r4, r3, r0, 23); 53862306a36Sopenharmony_ci SI6(r2, r1, r4, r3, r0); KL(r4, r0, r3, r2, r1, 22); 53962306a36Sopenharmony_ci SI5(r4, r0, r3, r2, r1); KL(r0, r1, r4, r3, r2, 21); 54062306a36Sopenharmony_ci SI4(r0, r1, r4, r3, r2); KL(r0, r4, r2, r3, r1, 20); 54162306a36Sopenharmony_ci SI3(r0, r4, r2, r3, r1); KL(r2, r0, r1, r3, r4, 19); 54262306a36Sopenharmony_ci SI2(r2, r0, r1, r3, r4); KL(r0, r4, r3, r1, r2, 18); 54362306a36Sopenharmony_ci SI1(r0, r4, r3, r1, r2); KL(r2, r4, r3, r1, r0, 17); 54462306a36Sopenharmony_ci SI0(r2, r4, r3, r1, r0); KL(r3, r0, r4, r2, r1, 16); 54562306a36Sopenharmony_ci SI7(r3, r0, r4, r2, r1); KL(r0, r2, r3, r1, r4, 15); 54662306a36Sopenharmony_ci SI6(r0, r2, r3, r1, r4); KL(r3, r4, r1, r0, r2, 14); 54762306a36Sopenharmony_ci SI5(r3, r4, r1, r0, r2); KL(r4, r2, r3, r1, r0, 13); 54862306a36Sopenharmony_ci SI4(r4, r2, r3, r1, r0); KL(r4, r3, r0, r1, r2, 12); 54962306a36Sopenharmony_ci SI3(r4, r3, r0, r1, r2); KL(r0, r4, r2, r1, r3, 11); 55062306a36Sopenharmony_ci SI2(r0, r4, r2, r1, r3); KL(r4, r3, r1, r2, r0, 10); 55162306a36Sopenharmony_ci SI1(r4, r3, r1, r2, r0); KL(r0, r3, r1, r2, r4, 9); 55262306a36Sopenharmony_ci SI0(r0, r3, r1, r2, r4); KL(r1, r4, r3, r0, r2, 8); 55362306a36Sopenharmony_ci SI7(r1, r4, r3, r0, r2); KL(r4, r0, r1, r2, r3, 7); 55462306a36Sopenharmony_ci SI6(r4, r0, r1, r2, r3); KL(r1, r3, r2, r4, r0, 6); 55562306a36Sopenharmony_ci SI5(r1, r3, r2, r4, r0); KL(r3, r0, r1, r2, r4, 5); 55662306a36Sopenharmony_ci SI4(r3, r0, r1, r2, r4); KL(r3, r1, r4, r2, r0, 4); 55762306a36Sopenharmony_ci SI3(r3, r1, r4, r2, r0); KL(r4, r3, r0, r2, r1, 3); 55862306a36Sopenharmony_ci SI2(r4, r3, r0, r2, r1); KL(r3, r1, r2, r0, r4, 2); 55962306a36Sopenharmony_ci SI1(r3, r1, r2, r0, r4); KL(r4, r1, r2, r0, r3, 1); 56062306a36Sopenharmony_ci SI0(r4, r1, r2, r0, r3); K(r2, r3, r1, r4, 0); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci put_unaligned_le32(r2, dst); 56362306a36Sopenharmony_ci put_unaligned_le32(r3, dst + 4); 56462306a36Sopenharmony_ci put_unaligned_le32(r1, dst + 8); 56562306a36Sopenharmony_ci put_unaligned_le32(r4, dst + 12); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__serpent_decrypt); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_cistatic void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci __serpent_decrypt(ctx, dst, src); 57462306a36Sopenharmony_ci} 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_cistatic struct crypto_alg srp_alg = { 57762306a36Sopenharmony_ci .cra_name = "serpent", 57862306a36Sopenharmony_ci .cra_driver_name = "serpent-generic", 57962306a36Sopenharmony_ci .cra_priority = 100, 58062306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 58162306a36Sopenharmony_ci .cra_blocksize = SERPENT_BLOCK_SIZE, 58262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct serpent_ctx), 58362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 58462306a36Sopenharmony_ci .cra_u = { .cipher = { 58562306a36Sopenharmony_ci .cia_min_keysize = SERPENT_MIN_KEY_SIZE, 58662306a36Sopenharmony_ci .cia_max_keysize = SERPENT_MAX_KEY_SIZE, 58762306a36Sopenharmony_ci .cia_setkey = serpent_setkey, 58862306a36Sopenharmony_ci .cia_encrypt = serpent_encrypt, 58962306a36Sopenharmony_ci .cia_decrypt = serpent_decrypt } } 59062306a36Sopenharmony_ci}; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic int __init serpent_mod_init(void) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci return crypto_register_alg(&srp_alg); 59562306a36Sopenharmony_ci} 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_cistatic void __exit serpent_mod_fini(void) 59862306a36Sopenharmony_ci{ 59962306a36Sopenharmony_ci crypto_unregister_alg(&srp_alg); 60062306a36Sopenharmony_ci} 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_cisubsys_initcall(serpent_mod_init); 60362306a36Sopenharmony_cimodule_exit(serpent_mod_fini); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 60662306a36Sopenharmony_ciMODULE_DESCRIPTION("Serpent Cipher Algorithm"); 60762306a36Sopenharmony_ciMODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>"); 60862306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("serpent"); 60962306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("serpent-generic"); 610