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