brintos

brintos / linux-shallow public Read only

0
0
Text · 19.6 KiB · f6ef187 Raw
610 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Cryptographic API.4 *5 * Serpent Cipher Algorithm.6 *7 * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>8 */9 10#include <crypto/algapi.h>11#include <linux/init.h>12#include <linux/module.h>13#include <linux/errno.h>14#include <linux/unaligned.h>15#include <linux/types.h>16#include <crypto/serpent.h>17 18/* Key is padded to the maximum of 256 bits before round key generation.19 * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.20 */21 22#define PHI 0x9e3779b9UL23 24#define keyiter(a, b, c, d, i, j) \25	({ b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b, 11); k[j] = b; })26 27#define loadkeys(x0, x1, x2, x3, i) \28	({ x0 = k[i]; x1 = k[i+1]; x2 = k[i+2]; x3 = k[i+3]; })29 30#define storekeys(x0, x1, x2, x3, i) \31	({ k[i] = x0; k[i+1] = x1; k[i+2] = x2; k[i+3] = x3; })32 33#define store_and_load_keys(x0, x1, x2, x3, s, l) \34	({ storekeys(x0, x1, x2, x3, s); loadkeys(x0, x1, x2, x3, l); })35 36#define K(x0, x1, x2, x3, i) ({				\37	x3 ^= k[4*(i)+3];        x2 ^= k[4*(i)+2];	\38	x1 ^= k[4*(i)+1];        x0 ^= k[4*(i)+0];	\39	})40 41#define LK(x0, x1, x2, x3, x4, i) ({					   \42							x0 = rol32(x0, 13);\43	x2 = rol32(x2, 3);	x1 ^= x0;		x4  = x0 << 3;	   \44	x3 ^= x2;		x1 ^= x2;				   \45	x1 = rol32(x1, 1);	x3 ^= x4;				   \46	x3 = rol32(x3, 7);	x4  = x1;				   \47	x0 ^= x1;		x4 <<= 7;		x2 ^= x3;	   \48	x0 ^= x3;		x2 ^= x4;		x3 ^= k[4*i+3];	   \49	x1 ^= k[4*i+1];		x0 = rol32(x0, 5);	x2 = rol32(x2, 22);\50	x0 ^= k[4*i+0];		x2 ^= k[4*i+2];				   \51	})52 53#define KL(x0, x1, x2, x3, x4, i) ({					   \54	x0 ^= k[4*i+0];		x1 ^= k[4*i+1];		x2 ^= k[4*i+2];	   \55	x3 ^= k[4*i+3];		x0 = ror32(x0, 5);	x2 = ror32(x2, 22);\56	x4 =  x1;		x2 ^= x3;		x0 ^= x3;	   \57	x4 <<= 7;		x0 ^= x1;		x1 = ror32(x1, 1); \58	x2 ^= x4;		x3 = ror32(x3, 7);	x4 = x0 << 3;	   \59	x1 ^= x0;		x3 ^= x4;		x0 = ror32(x0, 13);\60	x1 ^= x2;		x3 ^= x2;		x2 = ror32(x2, 3); \61	})62 63#define S0(x0, x1, x2, x3, x4) ({			\64					x4  = x3;	\65	x3 |= x0;	x0 ^= x4;	x4 ^= x2;	\66	x4 = ~x4;	x3 ^= x1;	x1 &= x0;	\67	x1 ^= x4;	x2 ^= x0;	x0 ^= x3;	\68	x4 |= x0;	x0 ^= x2;	x2 &= x1;	\69	x3 ^= x2;	x1 = ~x1;	x2 ^= x4;	\70	x1 ^= x2;					\71	})72 73#define S1(x0, x1, x2, x3, x4) ({			\74					x4  = x1;	\75	x1 ^= x0;	x0 ^= x3;	x3 = ~x3;	\76	x4 &= x1;	x0 |= x1;	x3 ^= x2;	\77	x0 ^= x3;	x1 ^= x3;	x3 ^= x4;	\78	x1 |= x4;	x4 ^= x2;	x2 &= x0;	\79	x2 ^= x1;	x1 |= x0;	x0 = ~x0;	\80	x0 ^= x2;	x4 ^= x1;			\81	})82 83#define S2(x0, x1, x2, x3, x4) ({			\84					x3 = ~x3;	\85	x1 ^= x0;	x4  = x0;	x0 &= x2;	\86	x0 ^= x3;	x3 |= x4;	x2 ^= x1;	\87	x3 ^= x1;	x1 &= x0;	x0 ^= x2;	\88	x2 &= x3;	x3 |= x1;	x0 = ~x0;	\89	x3 ^= x0;	x4 ^= x0;	x0 ^= x2;	\90	x1 |= x2;					\91	})92 93#define S3(x0, x1, x2, x3, x4) ({			\94					x4  = x1;	\95	x1 ^= x3;	x3 |= x0;	x4 &= x0;	\96	x0 ^= x2;	x2 ^= x1;	x1 &= x3;	\97	x2 ^= x3;	x0 |= x4;	x4 ^= x3;	\98	x1 ^= x0;	x0 &= x3;	x3 &= x4;	\99	x3 ^= x2;	x4 |= x1;	x2 &= x1;	\100	x4 ^= x3;	x0 ^= x3;	x3 ^= x2;	\101	})102 103#define S4(x0, x1, x2, x3, x4) ({			\104					x4  = x3;	\105	x3 &= x0;	x0 ^= x4;			\106	x3 ^= x2;	x2 |= x4;	x0 ^= x1;	\107	x4 ^= x3;	x2 |= x0;			\108	x2 ^= x1;	x1 &= x0;			\109	x1 ^= x4;	x4 &= x2;	x2 ^= x3;	\110	x4 ^= x0;	x3 |= x1;	x1 = ~x1;	\111	x3 ^= x0;					\112	})113 114#define S5(x0, x1, x2, x3, x4) ({			\115	x4  = x1;	x1 |= x0;			\116	x2 ^= x1;	x3 = ~x3;	x4 ^= x0;	\117	x0 ^= x2;	x1 &= x4;	x4 |= x3;	\118	x4 ^= x0;	x0 &= x3;	x1 ^= x3;	\119	x3 ^= x2;	x0 ^= x1;	x2 &= x4;	\120	x1 ^= x2;	x2 &= x0;			\121	x3 ^= x2;					\122	})123 124#define S6(x0, x1, x2, x3, x4) ({			\125					x4  = x1;	\126	x3 ^= x0;	x1 ^= x2;	x2 ^= x0;	\127	x0 &= x3;	x1 |= x3;	x4 = ~x4;	\128	x0 ^= x1;	x1 ^= x2;			\129	x3 ^= x4;	x4 ^= x0;	x2 &= x0;	\130	x4 ^= x1;	x2 ^= x3;	x3 &= x1;	\131	x3 ^= x0;	x1 ^= x2;			\132	})133 134#define S7(x0, x1, x2, x3, x4) ({			\135					x1 = ~x1;	\136	x4  = x1;	x0 = ~x0;	x1 &= x2;	\137	x1 ^= x3;	x3 |= x4;	x4 ^= x2;	\138	x2 ^= x3;	x3 ^= x0;	x0 |= x1;	\139	x2 &= x0;	x0 ^= x4;	x4 ^= x3;	\140	x3 &= x0;	x4 ^= x1;			\141	x2 ^= x4;	x3 ^= x1;	x4 |= x0;	\142	x4 ^= x1;					\143	})144 145#define SI0(x0, x1, x2, x3, x4) ({			\146			x4  = x3;	x1 ^= x0;	\147	x3 |= x1;	x4 ^= x1;	x0 = ~x0;	\148	x2 ^= x3;	x3 ^= x0;	x0 &= x1;	\149	x0 ^= x2;	x2 &= x3;	x3 ^= x4;	\150	x2 ^= x3;	x1 ^= x3;	x3 &= x0;	\151	x1 ^= x0;	x0 ^= x2;	x4 ^= x3;	\152	})153 154#define SI1(x0, x1, x2, x3, x4) ({			\155	x1 ^= x3;	x4  = x0;			\156	x0 ^= x2;	x2 = ~x2;	x4 |= x1;	\157	x4 ^= x3;	x3 &= x1;	x1 ^= x2;	\158	x2 &= x4;	x4 ^= x1;	x1 |= x3;	\159	x3 ^= x0;	x2 ^= x0;	x0 |= x4;	\160	x2 ^= x4;	x1 ^= x0;			\161	x4 ^= x1;					\162	})163 164#define SI2(x0, x1, x2, x3, x4) ({			\165	x2 ^= x1;	x4  = x3;	x3 = ~x3;	\166	x3 |= x2;	x2 ^= x4;	x4 ^= x0;	\167	x3 ^= x1;	x1 |= x2;	x2 ^= x0;	\168	x1 ^= x4;	x4 |= x3;	x2 ^= x3;	\169	x4 ^= x2;	x2 &= x1;			\170	x2 ^= x3;	x3 ^= x4;	x4 ^= x0;	\171	})172 173#define SI3(x0, x1, x2, x3, x4) ({			\174					x2 ^= x1;	\175	x4  = x1;	x1 &= x2;			\176	x1 ^= x0;	x0 |= x4;	x4 ^= x3;	\177	x0 ^= x3;	x3 |= x1;	x1 ^= x2;	\178	x1 ^= x3;	x0 ^= x2;	x2 ^= x3;	\179	x3 &= x1;	x1 ^= x0;	x0 &= x2;	\180	x4 ^= x3;	x3 ^= x0;	x0 ^= x1;	\181	})182 183#define SI4(x0, x1, x2, x3, x4) ({			\184	x2 ^= x3;	x4  = x0;	x0 &= x1;	\185	x0 ^= x2;	x2 |= x3;	x4 = ~x4;	\186	x1 ^= x0;	x0 ^= x2;	x2 &= x4;	\187	x2 ^= x0;	x0 |= x4;			\188	x0 ^= x3;	x3 &= x2;			\189	x4 ^= x3;	x3 ^= x1;	x1 &= x0;	\190	x4 ^= x1;	x0 ^= x3;			\191	})192 193#define SI5(x0, x1, x2, x3, x4) ({			\194			x4  = x1;	x1 |= x2;	\195	x2 ^= x4;	x1 ^= x3;	x3 &= x4;	\196	x2 ^= x3;	x3 |= x0;	x0 = ~x0;	\197	x3 ^= x2;	x2 |= x0;	x4 ^= x1;	\198	x2 ^= x4;	x4 &= x0;	x0 ^= x1;	\199	x1 ^= x3;	x0 &= x2;	x2 ^= x3;	\200	x0 ^= x2;	x2 ^= x4;	x4 ^= x3;	\201	})202 203#define SI6(x0, x1, x2, x3, x4) ({			\204			x0 ^= x2;			\205	x4  = x0;	x0 &= x3;	x2 ^= x3;	\206	x0 ^= x2;	x3 ^= x1;	x2 |= x4;	\207	x2 ^= x3;	x3 &= x0;	x0 = ~x0;	\208	x3 ^= x1;	x1 &= x2;	x4 ^= x0;	\209	x3 ^= x4;	x4 ^= x2;	x0 ^= x1;	\210	x2 ^= x0;					\211	})212 213#define SI7(x0, x1, x2, x3, x4) ({			\214	x4  = x3;	x3 &= x0;	x0 ^= x2;	\215	x2 |= x4;	x4 ^= x1;	x0 = ~x0;	\216	x1 |= x3;	x4 ^= x0;	x0 &= x2;	\217	x0 ^= x1;	x1 &= x2;	x3 ^= x2;	\218	x4 ^= x3;	x2 &= x3;	x3 |= x0;	\219	x1 ^= x4;	x3 ^= x4;	x4 &= x0;	\220	x4 ^= x2;					\221	})222 223/*224 * both gcc and clang have misoptimized this function in the past,225 * producing horrible object code from spilling temporary variables226 * on the stack. Forcing this part out of line avoids that.227 */228static noinline void __serpent_setkey_sbox(u32 r0, u32 r1, u32 r2,229					   u32 r3, u32 r4, u32 *k)230{231	k += 100;232	S3(r3, r4, r0, r1, r2); store_and_load_keys(r1, r2, r4, r3, 28, 24);233	S4(r1, r2, r4, r3, r0); store_and_load_keys(r2, r4, r3, r0, 24, 20);234	S5(r2, r4, r3, r0, r1); store_and_load_keys(r1, r2, r4, r0, 20, 16);235	S6(r1, r2, r4, r0, r3); store_and_load_keys(r4, r3, r2, r0, 16, 12);236	S7(r4, r3, r2, r0, r1); store_and_load_keys(r1, r2, r0, r4, 12, 8);237	S0(r1, r2, r0, r4, r3); store_and_load_keys(r0, r2, r4, r1, 8, 4);238	S1(r0, r2, r4, r1, r3); store_and_load_keys(r3, r4, r1, r0, 4, 0);239	S2(r3, r4, r1, r0, r2); store_and_load_keys(r2, r4, r3, r0, 0, -4);240	S3(r2, r4, r3, r0, r1); store_and_load_keys(r0, r1, r4, r2, -4, -8);241	S4(r0, r1, r4, r2, r3); store_and_load_keys(r1, r4, r2, r3, -8, -12);242	S5(r1, r4, r2, r3, r0); store_and_load_keys(r0, r1, r4, r3, -12, -16);243	S6(r0, r1, r4, r3, r2); store_and_load_keys(r4, r2, r1, r3, -16, -20);244	S7(r4, r2, r1, r3, r0); store_and_load_keys(r0, r1, r3, r4, -20, -24);245	S0(r0, r1, r3, r4, r2); store_and_load_keys(r3, r1, r4, r0, -24, -28);246	k -= 50;247	S1(r3, r1, r4, r0, r2); store_and_load_keys(r2, r4, r0, r3, 22, 18);248	S2(r2, r4, r0, r3, r1); store_and_load_keys(r1, r4, r2, r3, 18, 14);249	S3(r1, r4, r2, r3, r0); store_and_load_keys(r3, r0, r4, r1, 14, 10);250	S4(r3, r0, r4, r1, r2); store_and_load_keys(r0, r4, r1, r2, 10, 6);251	S5(r0, r4, r1, r2, r3); store_and_load_keys(r3, r0, r4, r2, 6, 2);252	S6(r3, r0, r4, r2, r1); store_and_load_keys(r4, r1, r0, r2, 2, -2);253	S7(r4, r1, r0, r2, r3); store_and_load_keys(r3, r0, r2, r4, -2, -6);254	S0(r3, r0, r2, r4, r1); store_and_load_keys(r2, r0, r4, r3, -6, -10);255	S1(r2, r0, r4, r3, r1); store_and_load_keys(r1, r4, r3, r2, -10, -14);256	S2(r1, r4, r3, r2, r0); store_and_load_keys(r0, r4, r1, r2, -14, -18);257	S3(r0, r4, r1, r2, r3); store_and_load_keys(r2, r3, r4, r0, -18, -22);258	k -= 50;259	S4(r2, r3, r4, r0, r1); store_and_load_keys(r3, r4, r0, r1, 28, 24);260	S5(r3, r4, r0, r1, r2); store_and_load_keys(r2, r3, r4, r1, 24, 20);261	S6(r2, r3, r4, r1, r0); store_and_load_keys(r4, r0, r3, r1, 20, 16);262	S7(r4, r0, r3, r1, r2); store_and_load_keys(r2, r3, r1, r4, 16, 12);263	S0(r2, r3, r1, r4, r0); store_and_load_keys(r1, r3, r4, r2, 12, 8);264	S1(r1, r3, r4, r2, r0); store_and_load_keys(r0, r4, r2, r1, 8, 4);265	S2(r0, r4, r2, r1, r3); store_and_load_keys(r3, r4, r0, r1, 4, 0);266	S3(r3, r4, r0, r1, r2); storekeys(r1, r2, r4, r3, 0);267}268 269int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,270		     unsigned int keylen)271{272	u32 *k = ctx->expkey;273	u8  *k8 = (u8 *)k;274	u32 r0, r1, r2, r3, r4;275	__le32 *lk;276	int i;277 278	/* Copy key, add padding */279 280	for (i = 0; i < keylen; ++i)281		k8[i] = key[i];282	if (i < SERPENT_MAX_KEY_SIZE)283		k8[i++] = 1;284	while (i < SERPENT_MAX_KEY_SIZE)285		k8[i++] = 0;286 287	lk = (__le32 *)k;288	k[0] = le32_to_cpu(lk[0]);289	k[1] = le32_to_cpu(lk[1]);290	k[2] = le32_to_cpu(lk[2]);291	k[3] = le32_to_cpu(lk[3]);292	k[4] = le32_to_cpu(lk[4]);293	k[5] = le32_to_cpu(lk[5]);294	k[6] = le32_to_cpu(lk[6]);295	k[7] = le32_to_cpu(lk[7]);296 297	/* Expand key using polynomial */298 299	r0 = k[3];300	r1 = k[4];301	r2 = k[5];302	r3 = k[6];303	r4 = k[7];304 305	keyiter(k[0], r0, r4, r2, 0, 0);306	keyiter(k[1], r1, r0, r3, 1, 1);307	keyiter(k[2], r2, r1, r4, 2, 2);308	keyiter(k[3], r3, r2, r0, 3, 3);309	keyiter(k[4], r4, r3, r1, 4, 4);310	keyiter(k[5], r0, r4, r2, 5, 5);311	keyiter(k[6], r1, r0, r3, 6, 6);312	keyiter(k[7], r2, r1, r4, 7, 7);313 314	keyiter(k[0], r3, r2, r0, 8, 8);315	keyiter(k[1], r4, r3, r1, 9, 9);316	keyiter(k[2], r0, r4, r2, 10, 10);317	keyiter(k[3], r1, r0, r3, 11, 11);318	keyiter(k[4], r2, r1, r4, 12, 12);319	keyiter(k[5], r3, r2, r0, 13, 13);320	keyiter(k[6], r4, r3, r1, 14, 14);321	keyiter(k[7], r0, r4, r2, 15, 15);322	keyiter(k[8], r1, r0, r3, 16, 16);323	keyiter(k[9], r2, r1, r4, 17, 17);324	keyiter(k[10], r3, r2, r0, 18, 18);325	keyiter(k[11], r4, r3, r1, 19, 19);326	keyiter(k[12], r0, r4, r2, 20, 20);327	keyiter(k[13], r1, r0, r3, 21, 21);328	keyiter(k[14], r2, r1, r4, 22, 22);329	keyiter(k[15], r3, r2, r0, 23, 23);330	keyiter(k[16], r4, r3, r1, 24, 24);331	keyiter(k[17], r0, r4, r2, 25, 25);332	keyiter(k[18], r1, r0, r3, 26, 26);333	keyiter(k[19], r2, r1, r4, 27, 27);334	keyiter(k[20], r3, r2, r0, 28, 28);335	keyiter(k[21], r4, r3, r1, 29, 29);336	keyiter(k[22], r0, r4, r2, 30, 30);337	keyiter(k[23], r1, r0, r3, 31, 31);338 339	k += 50;340 341	keyiter(k[-26], r2, r1, r4, 32, -18);342	keyiter(k[-25], r3, r2, r0, 33, -17);343	keyiter(k[-24], r4, r3, r1, 34, -16);344	keyiter(k[-23], r0, r4, r2, 35, -15);345	keyiter(k[-22], r1, r0, r3, 36, -14);346	keyiter(k[-21], r2, r1, r4, 37, -13);347	keyiter(k[-20], r3, r2, r0, 38, -12);348	keyiter(k[-19], r4, r3, r1, 39, -11);349	keyiter(k[-18], r0, r4, r2, 40, -10);350	keyiter(k[-17], r1, r0, r3, 41, -9);351	keyiter(k[-16], r2, r1, r4, 42, -8);352	keyiter(k[-15], r3, r2, r0, 43, -7);353	keyiter(k[-14], r4, r3, r1, 44, -6);354	keyiter(k[-13], r0, r4, r2, 45, -5);355	keyiter(k[-12], r1, r0, r3, 46, -4);356	keyiter(k[-11], r2, r1, r4, 47, -3);357	keyiter(k[-10], r3, r2, r0, 48, -2);358	keyiter(k[-9], r4, r3, r1, 49, -1);359	keyiter(k[-8], r0, r4, r2, 50, 0);360	keyiter(k[-7], r1, r0, r3, 51, 1);361	keyiter(k[-6], r2, r1, r4, 52, 2);362	keyiter(k[-5], r3, r2, r0, 53, 3);363	keyiter(k[-4], r4, r3, r1, 54, 4);364	keyiter(k[-3], r0, r4, r2, 55, 5);365	keyiter(k[-2], r1, r0, r3, 56, 6);366	keyiter(k[-1], r2, r1, r4, 57, 7);367	keyiter(k[0], r3, r2, r0, 58, 8);368	keyiter(k[1], r4, r3, r1, 59, 9);369	keyiter(k[2], r0, r4, r2, 60, 10);370	keyiter(k[3], r1, r0, r3, 61, 11);371	keyiter(k[4], r2, r1, r4, 62, 12);372	keyiter(k[5], r3, r2, r0, 63, 13);373	keyiter(k[6], r4, r3, r1, 64, 14);374	keyiter(k[7], r0, r4, r2, 65, 15);375	keyiter(k[8], r1, r0, r3, 66, 16);376	keyiter(k[9], r2, r1, r4, 67, 17);377	keyiter(k[10], r3, r2, r0, 68, 18);378	keyiter(k[11], r4, r3, r1, 69, 19);379	keyiter(k[12], r0, r4, r2, 70, 20);380	keyiter(k[13], r1, r0, r3, 71, 21);381	keyiter(k[14], r2, r1, r4, 72, 22);382	keyiter(k[15], r3, r2, r0, 73, 23);383	keyiter(k[16], r4, r3, r1, 74, 24);384	keyiter(k[17], r0, r4, r2, 75, 25);385	keyiter(k[18], r1, r0, r3, 76, 26);386	keyiter(k[19], r2, r1, r4, 77, 27);387	keyiter(k[20], r3, r2, r0, 78, 28);388	keyiter(k[21], r4, r3, r1, 79, 29);389	keyiter(k[22], r0, r4, r2, 80, 30);390	keyiter(k[23], r1, r0, r3, 81, 31);391 392	k += 50;393 394	keyiter(k[-26], r2, r1, r4, 82, -18);395	keyiter(k[-25], r3, r2, r0, 83, -17);396	keyiter(k[-24], r4, r3, r1, 84, -16);397	keyiter(k[-23], r0, r4, r2, 85, -15);398	keyiter(k[-22], r1, r0, r3, 86, -14);399	keyiter(k[-21], r2, r1, r4, 87, -13);400	keyiter(k[-20], r3, r2, r0, 88, -12);401	keyiter(k[-19], r4, r3, r1, 89, -11);402	keyiter(k[-18], r0, r4, r2, 90, -10);403	keyiter(k[-17], r1, r0, r3, 91, -9);404	keyiter(k[-16], r2, r1, r4, 92, -8);405	keyiter(k[-15], r3, r2, r0, 93, -7);406	keyiter(k[-14], r4, r3, r1, 94, -6);407	keyiter(k[-13], r0, r4, r2, 95, -5);408	keyiter(k[-12], r1, r0, r3, 96, -4);409	keyiter(k[-11], r2, r1, r4, 97, -3);410	keyiter(k[-10], r3, r2, r0, 98, -2);411	keyiter(k[-9], r4, r3, r1, 99, -1);412	keyiter(k[-8], r0, r4, r2, 100, 0);413	keyiter(k[-7], r1, r0, r3, 101, 1);414	keyiter(k[-6], r2, r1, r4, 102, 2);415	keyiter(k[-5], r3, r2, r0, 103, 3);416	keyiter(k[-4], r4, r3, r1, 104, 4);417	keyiter(k[-3], r0, r4, r2, 105, 5);418	keyiter(k[-2], r1, r0, r3, 106, 6);419	keyiter(k[-1], r2, r1, r4, 107, 7);420	keyiter(k[0], r3, r2, r0, 108, 8);421	keyiter(k[1], r4, r3, r1, 109, 9);422	keyiter(k[2], r0, r4, r2, 110, 10);423	keyiter(k[3], r1, r0, r3, 111, 11);424	keyiter(k[4], r2, r1, r4, 112, 12);425	keyiter(k[5], r3, r2, r0, 113, 13);426	keyiter(k[6], r4, r3, r1, 114, 14);427	keyiter(k[7], r0, r4, r2, 115, 15);428	keyiter(k[8], r1, r0, r3, 116, 16);429	keyiter(k[9], r2, r1, r4, 117, 17);430	keyiter(k[10], r3, r2, r0, 118, 18);431	keyiter(k[11], r4, r3, r1, 119, 19);432	keyiter(k[12], r0, r4, r2, 120, 20);433	keyiter(k[13], r1, r0, r3, 121, 21);434	keyiter(k[14], r2, r1, r4, 122, 22);435	keyiter(k[15], r3, r2, r0, 123, 23);436	keyiter(k[16], r4, r3, r1, 124, 24);437	keyiter(k[17], r0, r4, r2, 125, 25);438	keyiter(k[18], r1, r0, r3, 126, 26);439	keyiter(k[19], r2, r1, r4, 127, 27);440	keyiter(k[20], r3, r2, r0, 128, 28);441	keyiter(k[21], r4, r3, r1, 129, 29);442	keyiter(k[22], r0, r4, r2, 130, 30);443	keyiter(k[23], r1, r0, r3, 131, 31);444 445	/* Apply S-boxes */446	__serpent_setkey_sbox(r0, r1, r2, r3, r4, ctx->expkey);447 448	return 0;449}450EXPORT_SYMBOL_GPL(__serpent_setkey);451 452int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)453{454	return __serpent_setkey(crypto_tfm_ctx(tfm), key, keylen);455}456EXPORT_SYMBOL_GPL(serpent_setkey);457 458void __serpent_encrypt(const void *c, u8 *dst, const u8 *src)459{460	const struct serpent_ctx *ctx = c;461	const u32 *k = ctx->expkey;462	u32	r0, r1, r2, r3, r4;463 464	r0 = get_unaligned_le32(src);465	r1 = get_unaligned_le32(src + 4);466	r2 = get_unaligned_le32(src + 8);467	r3 = get_unaligned_le32(src + 12);468 469					K(r0, r1, r2, r3, 0);470	S0(r0, r1, r2, r3, r4);		LK(r2, r1, r3, r0, r4, 1);471	S1(r2, r1, r3, r0, r4);		LK(r4, r3, r0, r2, r1, 2);472	S2(r4, r3, r0, r2, r1);		LK(r1, r3, r4, r2, r0, 3);473	S3(r1, r3, r4, r2, r0);		LK(r2, r0, r3, r1, r4, 4);474	S4(r2, r0, r3, r1, r4);		LK(r0, r3, r1, r4, r2, 5);475	S5(r0, r3, r1, r4, r2);		LK(r2, r0, r3, r4, r1, 6);476	S6(r2, r0, r3, r4, r1);		LK(r3, r1, r0, r4, r2, 7);477	S7(r3, r1, r0, r4, r2);		LK(r2, r0, r4, r3, r1, 8);478	S0(r2, r0, r4, r3, r1);		LK(r4, r0, r3, r2, r1, 9);479	S1(r4, r0, r3, r2, r1);		LK(r1, r3, r2, r4, r0, 10);480	S2(r1, r3, r2, r4, r0);		LK(r0, r3, r1, r4, r2, 11);481	S3(r0, r3, r1, r4, r2);		LK(r4, r2, r3, r0, r1, 12);482	S4(r4, r2, r3, r0, r1);		LK(r2, r3, r0, r1, r4, 13);483	S5(r2, r3, r0, r1, r4);		LK(r4, r2, r3, r1, r0, 14);484	S6(r4, r2, r3, r1, r0);		LK(r3, r0, r2, r1, r4, 15);485	S7(r3, r0, r2, r1, r4);		LK(r4, r2, r1, r3, r0, 16);486	S0(r4, r2, r1, r3, r0);		LK(r1, r2, r3, r4, r0, 17);487	S1(r1, r2, r3, r4, r0);		LK(r0, r3, r4, r1, r2, 18);488	S2(r0, r3, r4, r1, r2);		LK(r2, r3, r0, r1, r4, 19);489	S3(r2, r3, r0, r1, r4);		LK(r1, r4, r3, r2, r0, 20);490	S4(r1, r4, r3, r2, r0);		LK(r4, r3, r2, r0, r1, 21);491	S5(r4, r3, r2, r0, r1);		LK(r1, r4, r3, r0, r2, 22);492	S6(r1, r4, r3, r0, r2);		LK(r3, r2, r4, r0, r1, 23);493	S7(r3, r2, r4, r0, r1);		LK(r1, r4, r0, r3, r2, 24);494	S0(r1, r4, r0, r3, r2);		LK(r0, r4, r3, r1, r2, 25);495	S1(r0, r4, r3, r1, r2);		LK(r2, r3, r1, r0, r4, 26);496	S2(r2, r3, r1, r0, r4);		LK(r4, r3, r2, r0, r1, 27);497	S3(r4, r3, r2, r0, r1);		LK(r0, r1, r3, r4, r2, 28);498	S4(r0, r1, r3, r4, r2);		LK(r1, r3, r4, r2, r0, 29);499	S5(r1, r3, r4, r2, r0);		LK(r0, r1, r3, r2, r4, 30);500	S6(r0, r1, r3, r2, r4);		LK(r3, r4, r1, r2, r0, 31);501	S7(r3, r4, r1, r2, r0);		K(r0, r1, r2, r3, 32);502 503	put_unaligned_le32(r0, dst);504	put_unaligned_le32(r1, dst + 4);505	put_unaligned_le32(r2, dst + 8);506	put_unaligned_le32(r3, dst + 12);507}508EXPORT_SYMBOL_GPL(__serpent_encrypt);509 510static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)511{512	struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);513 514	__serpent_encrypt(ctx, dst, src);515}516 517void __serpent_decrypt(const void *c, u8 *dst, const u8 *src)518{519	const struct serpent_ctx *ctx = c;520	const u32 *k = ctx->expkey;521	u32	r0, r1, r2, r3, r4;522 523	r0 = get_unaligned_le32(src);524	r1 = get_unaligned_le32(src + 4);525	r2 = get_unaligned_le32(src + 8);526	r3 = get_unaligned_le32(src + 12);527 528					K(r0, r1, r2, r3, 32);529	SI7(r0, r1, r2, r3, r4);	KL(r1, r3, r0, r4, r2, 31);530	SI6(r1, r3, r0, r4, r2);	KL(r0, r2, r4, r1, r3, 30);531	SI5(r0, r2, r4, r1, r3);	KL(r2, r3, r0, r4, r1, 29);532	SI4(r2, r3, r0, r4, r1);	KL(r2, r0, r1, r4, r3, 28);533	SI3(r2, r0, r1, r4, r3);	KL(r1, r2, r3, r4, r0, 27);534	SI2(r1, r2, r3, r4, r0);	KL(r2, r0, r4, r3, r1, 26);535	SI1(r2, r0, r4, r3, r1);	KL(r1, r0, r4, r3, r2, 25);536	SI0(r1, r0, r4, r3, r2);	KL(r4, r2, r0, r1, r3, 24);537	SI7(r4, r2, r0, r1, r3);	KL(r2, r1, r4, r3, r0, 23);538	SI6(r2, r1, r4, r3, r0);	KL(r4, r0, r3, r2, r1, 22);539	SI5(r4, r0, r3, r2, r1);	KL(r0, r1, r4, r3, r2, 21);540	SI4(r0, r1, r4, r3, r2);	KL(r0, r4, r2, r3, r1, 20);541	SI3(r0, r4, r2, r3, r1);	KL(r2, r0, r1, r3, r4, 19);542	SI2(r2, r0, r1, r3, r4);	KL(r0, r4, r3, r1, r2, 18);543	SI1(r0, r4, r3, r1, r2);	KL(r2, r4, r3, r1, r0, 17);544	SI0(r2, r4, r3, r1, r0);	KL(r3, r0, r4, r2, r1, 16);545	SI7(r3, r0, r4, r2, r1);	KL(r0, r2, r3, r1, r4, 15);546	SI6(r0, r2, r3, r1, r4);	KL(r3, r4, r1, r0, r2, 14);547	SI5(r3, r4, r1, r0, r2);	KL(r4, r2, r3, r1, r0, 13);548	SI4(r4, r2, r3, r1, r0);	KL(r4, r3, r0, r1, r2, 12);549	SI3(r4, r3, r0, r1, r2);	KL(r0, r4, r2, r1, r3, 11);550	SI2(r0, r4, r2, r1, r3);	KL(r4, r3, r1, r2, r0, 10);551	SI1(r4, r3, r1, r2, r0);	KL(r0, r3, r1, r2, r4, 9);552	SI0(r0, r3, r1, r2, r4);	KL(r1, r4, r3, r0, r2, 8);553	SI7(r1, r4, r3, r0, r2);	KL(r4, r0, r1, r2, r3, 7);554	SI6(r4, r0, r1, r2, r3);	KL(r1, r3, r2, r4, r0, 6);555	SI5(r1, r3, r2, r4, r0);	KL(r3, r0, r1, r2, r4, 5);556	SI4(r3, r0, r1, r2, r4);	KL(r3, r1, r4, r2, r0, 4);557	SI3(r3, r1, r4, r2, r0);	KL(r4, r3, r0, r2, r1, 3);558	SI2(r4, r3, r0, r2, r1);	KL(r3, r1, r2, r0, r4, 2);559	SI1(r3, r1, r2, r0, r4);	KL(r4, r1, r2, r0, r3, 1);560	SI0(r4, r1, r2, r0, r3);	K(r2, r3, r1, r4, 0);561 562	put_unaligned_le32(r2, dst);563	put_unaligned_le32(r3, dst + 4);564	put_unaligned_le32(r1, dst + 8);565	put_unaligned_le32(r4, dst + 12);566}567EXPORT_SYMBOL_GPL(__serpent_decrypt);568 569static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)570{571	struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);572 573	__serpent_decrypt(ctx, dst, src);574}575 576static struct crypto_alg srp_alg = {577	.cra_name		=	"serpent",578	.cra_driver_name	=	"serpent-generic",579	.cra_priority		=	100,580	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,581	.cra_blocksize		=	SERPENT_BLOCK_SIZE,582	.cra_ctxsize		=	sizeof(struct serpent_ctx),583	.cra_module		=	THIS_MODULE,584	.cra_u			=	{ .cipher = {585	.cia_min_keysize	=	SERPENT_MIN_KEY_SIZE,586	.cia_max_keysize	=	SERPENT_MAX_KEY_SIZE,587	.cia_setkey		=	serpent_setkey,588	.cia_encrypt		=	serpent_encrypt,589	.cia_decrypt		=	serpent_decrypt } }590};591 592static int __init serpent_mod_init(void)593{594	return crypto_register_alg(&srp_alg);595}596 597static void __exit serpent_mod_fini(void)598{599	crypto_unregister_alg(&srp_alg);600}601 602subsys_initcall(serpent_mod_init);603module_exit(serpent_mod_fini);604 605MODULE_LICENSE("GPL");606MODULE_DESCRIPTION("Serpent Cipher Algorithm");607MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");608MODULE_ALIAS_CRYPTO("serpent");609MODULE_ALIAS_CRYPTO("serpent-generic");610