📄 cipher-serpent.c
字号:
/* $Id: cipher-serpent.c,v 1.10 2002/09/04 20:39:31 hvr Exp $ * * Optimized implementation of the Serpent AES candidate algorithm * Designed by Anderson, Biham and Knudsen and implemented by * Gisle S鎙ensminde 2000. * * The implementation is based on the pentium optimised sboxes of * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86 * processors they are efficient on other processors as well, but the speedup * isn't so impressive compared to other implementations. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. */#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/crypto.h>#include <linux/wordops.h>#include <asm/byteorder.h>#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif#ifdef MODULE_DESCRIPTIONMODULE_DESCRIPTION ("Serpent Cipher / CryptoAPI");#endif#ifdef MODULE_AUTHORMODULE_AUTHOR ("Gisle S鎙ensminde <gisle@ii.uib.no>");#endif#define XKEY_SIZE 140 /* size of expanded key */struct serpent_ctx { u32 xkey[XKEY_SIZE];};#define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))#define rotr(reg, val) ((reg >> val) | (reg << (32 - val))) #define io_swap(x) __cpu_to_be32(x)/* The sbox functions. The first four parameters is the input bits, and * the last is a tempoary. These parameters are also used for output, but * the bit order is permuted. The output bit order from S0 is * (1 4 2 0 3), where 3 is the (now useless) tempoary. */#define S0(r0, r1, r2, r3, r4) \ r3 = r3 ^ r0; \ r4 = r1; \ r1 = r1 & r3; \ r4 = r4 ^ r2; \ r1 = r1 ^ r0; \ r0 = r0 | r3; \ r0 = r0 ^ r4; \ r4 = r4 ^ r3; \ r3 = r3 ^ r2; \ r2 = r2 | r1; \ r2 = r2 ^ r4; \ r4 = -1 ^ r4; \ r4 = r4 | r1; \ r1 = r1 ^ r3; \ r1 = r1 ^ r4; \ r3 = r3 | r0; \ r1 = r1 ^ r3; \ r4 = r4 ^ r3; #define S1(r0, r1, r2, r3, r4) \ r1 = -1 ^ r1; \ r4 = r0; \ r0 = r0 ^ r1; \ r4 = r4 | r1; \ r4 = r4 ^ r3; \ r3 = r3 & r0; \ r2 = r2 ^ r4; \ r3 = r3 ^ r1; \ r3 = r3 | r2; \ r0 = r0 ^ r4; \ r3 = r3 ^ r0; \ r1 = r1 & r2; \ r0 = r0 | r1; \ r1 = r1 ^ r4; \ r0 = r0 ^ r2; \ r4 = r4 | r3; \ r0 = r0 ^ r4; \ r4 = -1 ^ r4; \ r1 = r1 ^ r3; \ r4 = r4 & r2; \ r1 = -1 ^ r1; \ r4 = r4 ^ r0; \ r1 = r1 ^ r4; #define S2(r0, r1, r2, r3, r4) \ r4 = r0; \ r0 = r0 & r2; \ r0 = r0 ^ r3; \ r2 = r2 ^ r1; \ r2 = r2 ^ r0; \ r3 = r3 | r4; \ r3 = r3 ^ r1; \ r4 = r4 ^ r2; \ r1 = r3; \ r3 = r3 | r4; \ r3 = r3 ^ r0; \ r0 = r0 & r1; \ r4 = r4 ^ r0; \ r1 = r1 ^ r3; \ r1 = r1 ^ r4; \ r4 = -1 ^ r4; #define S3(r0, r1, r2, r3, r4) \ r4 = r0 ; \ r0 = r0 | r3; \ r3 = r3 ^ r1; \ r1 = r1 & r4; \ r4 = r4 ^ r2; \ r2 = r2 ^ r3; \ r3 = r3 & r0; \ r4 = r4 | r1; \ r3 = r3 ^ r4; \ r0 = r0 ^ r1; \ r4 = r4 & r0; \ r1 = r1 ^ r3; \ r4 = r4 ^ r2; \ r1 = r1 | r0; \ r1 = r1 ^ r2; \ r0 = r0 ^ r3; \ r2 = r1; \ r1 = r1 | r3; \ r1 = r1 ^ r0; #define S4(r0, r1, r2, r3, r4) \ r1 = r1 ^ r3; \ r3 = -1 ^ r3; \ r2 = r2 ^ r3; \ r3 = r3 ^ r0; \ r4 = r1; \ r1 = r1 & r3; \ r1 = r1 ^ r2; \ r4 = r4 ^ r3; \ r0 = r0 ^ r4; \ r2 = r2 & r4; \ r2 = r2 ^ r0; \ r0 = r0 & r1; \ r3 = r3 ^ r0; \ r4 = r4 | r1; \ r4 = r4 ^ r0; \ r0 = r0 | r3; \ r0 = r0 ^ r2; \ r2 = r2 & r3; \ r0 = -1 ^ r0; \ r4 = r4 ^ r2; #define S5(r0, r1, r2, r3, r4) \ r0 = r0 ^ r1; \ r1 = r1 ^ r3; \ r3 = -1 ^ r3; \ r4 = r1; \ r1 = r1 & r0; \ r2 = r2 ^ r3; \ r1 = r1 ^ r2; \ r2 = r2 | r4; \ r4 = r4 ^ r3; \ r3 = r3 & r1; \ r3 = r3 ^ r0; \ r4 = r4 ^ r1; \ r4 = r4 ^ r2; \ r2 = r2 ^ r0; \ r0 = r0 & r3; \ r2 = -1 ^ r2; \ r0 = r0 ^ r4; \ r4 = r4 | r3; \ r2 = r2 ^ r4; #define S6(r0, r1, r2, r3, r4) \ r2 = -1 ^ r2; \ r4 = r3; \ r3 = r3 & r0; \ r0 = r0 ^ r4; \ r3 = r3 ^ r2; \ r2 = r2 | r4; \ r1 = r1 ^ r3; \ r2 = r2 ^ r0; \ r0 = r0 | r1; \ r2 = r2 ^ r1; \ r4 = r4 ^ r0; \ r0 = r0 | r3; \ r0 = r0 ^ r2; \ r4 = r4 ^ r3; \ r4 = r4 ^ r0; \ r3 = -1 ^ r3; \ r2 = r2 & r4; \ r2 = r2 ^ r3; #define S7(r0, r1, r2, r3, r4) \ r4 = r2; \ r2 = r2 & r1; \ r2 = r2 ^ r3; \ r3 = r3 & r1; \ r4 = r4 ^ r2; \ r2 = r2 ^ r1; \ r1 = r1 ^ r0; \ r0 = r0 | r4; \ r0 = r0 ^ r2; \ r3 = r3 ^ r1; \ r2 = r2 ^ r3; \ r3 = r3 & r0; \ r3 = r3 ^ r4; \ r4 = r4 ^ r2; \ r2 = r2 & r0; \ r4 = -1 ^ r4; \ r2 = r2 ^ r4; \ r4 = r4 & r0; \ r1 = r1 ^ r3; \ r4 = r4 ^ r1; /* The inverse sboxes */#define I0(r0, r1, r2, r3, r4) \ r2 = r2 ^ -1; \ r4 = r1; \ r1 = r1 | r0; \ r4 = r4 ^ -1; \ r1 = r1 ^ r2; \ r2 = r2 | r4; \ r1 = r1 ^ r3; \ r0 = r0 ^ r4; \ r2 = r2 ^ r0; \ r0 = r0 & r3; \ r4 = r4 ^ r0; \ r0 = r0 | r1; \ r0 = r0 ^ r2; \ r3 = r3 ^ r4; \ r2 = r2 ^ r1; \ r3 = r3 ^ r0; \ r3 = r3 ^ r1; \ r2 = r2 & r3; \ r4 = r4 ^ r2; #define I1(r0, r1, r2, r3, r4) \ r4 = r1; \ r1 = r1 ^ r3; \ r3 = r3 & r1; \ r4 = r4 ^ r2; \ r3 = r3 ^ r0; \ r0 = r0 | r1; \ r2 = r2 ^ r3; \ r0 = r0 ^ r4; \ r0 = r0 | r2; \ r1 = r1 ^ r3; \ r0 = r0 ^ r1; \ r1 = r1 | r3; \ r1 = r1 ^ r0; \ r4 = r4 ^ -1; \ r4 = r4 ^ r1; \ r1 = r1 | r0; \ r1 = r1 ^ r0; \ r1 = r1 | r4; \ r3 = r3 ^ r1; #define I2(r0, r1, r2, r3, r4) \ r2 = r2 ^ r3; \ r3 = r3 ^ r0; \ r4 = r3; \ r3 = r3 & r2; \ r3 = r3 ^ r1; \ r1 = r1 | r2; \ r1 = r1 ^ r4; \ r4 = r4 & r3; \ r2 = r2 ^ r3; \ r4 = r4 & r0; \ r4 = r4 ^ r2; \ r2 = r2 & r1; \ r2 = r2 | r0; \ r3 = r3 ^ -1; \ r2 = r2 ^ r3; \ r0 = r0 ^ r3; \ r0 = r0 & r1; \ r3 = r3 ^ r4; \ r3 = r3 ^ r0; #define I3(r0, r1, r2, r3, r4) \ r4 = r2; \ r2 = r2 ^ r1; \ r0 = r0 ^ r2; \ r4 = r4 & r2; \ r4 = r4 ^ r0; \ r0 = r0 & r1; \ r1 = r1 ^ r3; \ r3 = r3 | r4; \ r2 = r2 ^ r3; \ r0 = r0 ^ r3; \ r1 = r1 ^ r4; \ r3 = r3 & r2; \ r3 = r3 ^ r1; \ r1 = r1 ^ r0; \ r1 = r1 | r2; \ r0 = r0 ^ r3; \ r1 = r1 ^ r4; \ r0 = r0 ^ r1; #define I4(r0, r1, r2, r3, r4) \ r4 = r2; \ r2 = r2 & r3; \ r2 = r2 ^ r1; \ r1 = r1 | r3; \ r1 = r1 & r0; \ r4 = r4 ^ r2; \ r4 = r4 ^ r1; \ r1 = r1 & r2; \ r0 = r0 ^ -1; \ r3 = r3 ^ r4; \ r1 = r1 ^ r3; \ r3 = r3 & r0; \ r3 = r3 ^ r2; \ r0 = r0 ^ r1; \ r2 = r2 & r0; \ r3 = r3 ^ r0; \ r2 = r2 ^ r4; \ r2 = r2 | r3; \ r3 = r3 ^ r0; \ r2 = r2 ^ r1; #define I5(r0, r1, r2, r3, r4) \ r1 = r1 ^ -1; \ r4 = r3; \ r2 = r2 ^ r1; \ r3 = r3 | r0; \ r3 = r3 ^ r2; \ r2 = r2 | r1; \ r2 = r2 & r0; \ r4 = r4 ^ r3; \ r2 = r2 ^ r4; \ r4 = r4 | r0; \ r4 = r4 ^ r1; \ r1 = r1 & r2; \ r1 = r1 ^ r3; \ r4 = r4 ^ r2; \ r3 = r3 & r4; \ r4 = r4 ^ r1; \ r3 = r3 ^ r0; \ r3 = r3 ^ r4; \ r4 = r4 ^ -1; #define I6(r0, r1, r2, r3, r4) \ r0 = r0 ^ r2; \ r4 = r2; \ r2 = r2 & r0; \ r4 = r4 ^ r3; \ r2 = r2 ^ -1; \ r3 = r3 ^ r1; \ r2 = r2 ^ r3; \ r4 = r4 | r0; \ r0 = r0 ^ r2; \ r3 = r3 ^ r4; \ r4 = r4 ^ r1; \ r1 = r1 & r3; \ r1 = r1 ^ r0; \ r0 = r0 ^ r3; \ r0 = r0 | r2; \ r3 = r3 ^ r1; \ r4 = r4 ^ r0; #define I7(r0, r1, r2, r3, r4) \ r4 = r2; \ r2 = r2 ^ r0; \ r0 = r0 & r3; \ r4 = r4 | r3; \ r2 = r2 ^ -1; \ r3 = r3 ^ r1; \ r1 = r1 | r0; \ r0 = r0 ^ r2; \ r2 = r2 & r4; \ r3 = r3 & r4; \ r1 = r1 ^ r2; \ r2 = r2 ^ r0; \ r0 = r0 | r2; \ r4 = r4 ^ r1; \ r0 = r0 ^ r3; \ r3 = r3 ^ r4; \ r4 = r4 | r0; \ r3 = r3 ^ r2; \ r4 = r4 ^ r2; /* forward and inverse linear transformations */#define LINTRANS(r0, r1, r2, r3, r4) \ r0 = rotl(r0, 13); \ r2 = rotl(r2, 3); \ r3 = r3 ^ r2; \ r4 = r0 << 3; \ r1 = r1 ^ r0; \ r3 = r3 ^ r4; \ r1 = r1 ^ r2; \ r3 = rotl(r3, 7); \ r1 = rotl(r1, 1); \ r2 = r2 ^ r3; \ r4 = r1 << 7; \ r0 = r0 ^ r1; \ r2 = r2 ^ r4; \ r0 = r0 ^ r3; \ r2 = rotl(r2, 22); \ r0 = rotl(r0, 5); #define ILINTRANS(r0, r1, r2, r3, r4) \ r2 = rotr(r2, 22); \ r0 = rotr(r0, 5); \ r2 = r2 ^ r3; \ r4 = r1 << 7; \ r0 = r0 ^ r1; \ r2 = r2 ^ r4; \ r0 = r0 ^ r3; \ r3 = rotr(r3, 7); \ r1 = rotr(r1, 1); \ r3 = r3 ^ r2; \ r4 = r0 << 3; \ r1 = r1 ^ r0; \ r3 = r3 ^ r4; \ r1 = r1 ^ r2; \ r2 = rotr(r2, 3); \ r0 = rotr(r0, 13); #define KEYMIX(l_key, r0, r1, r2, r3, r4, IN) \ r0 = r0 ^ l_key[IN+8]; \ r1 = r1 ^ l_key[IN+9]; \ r2 = r2 ^ l_key[IN+10]; \ r3 = r3 ^ l_key[IN+11]; #define GETKEY(l_key, r0, r1, r2, r3, IN) \ r0 = l_key[IN+8]; \ r1 = l_key[IN+9]; \ r2 = l_key[IN+10]; \ r3 = l_key[IN+11]; #define SETKEY(l_key, r0, r1, r2, r3, IN) \ l_key[IN+8] = r0; \ l_key[IN+9] = r1; \ l_key[IN+10] = r2; \ l_key[IN+11] = r3;/* initialise the key schedule from the user supplied key */static int serpent_set_key(struct cipher_context *cx, const u8 *key, int key_len, int atomic){ struct serpent_ctx *ctx; u32 *in_key = (u32 *)key; u32 i, lk, r0, r1, r2, r3, r4; /* serpent_ctx.xkey - storage for the expanded key */ ctx = (struct serpent_ctx *)cx->keyinfo; if (key_len != 16 && key_len != 24 && key_len != 32) return -EINVAL; /* unsupported key length */ cx->key_length = key_len; key_len *= 8; i = 0; lk = (key_len + 31) / 32; while (i < lk) { ctx->xkey[i] = io_swap(in_key[lk - i - 1]); i++; } if (key_len < 256) { while (i < 8) ctx->xkey[i++] = 0; i = key_len / 32; lk = 1 << key_len % 32; ctx->xkey[i] &= lk - 1; ctx->xkey[i] |= lk; } for (i = 0; i < 132; ++i) { lk = ctx->xkey[i] ^ ctx->xkey[i + 3] ^ ctx->xkey[i + 5] \ ^ ctx->xkey[i + 7] ^ 0x9e3779b9 ^ i; ctx->xkey[i + 8] = (lk << 11) | (lk >> 21); } GETKEY(ctx->xkey, r0, r1, r2, r3, 0); S3(r0,r1,r2,r3,r4); SETKEY(ctx->xkey, r1, r2, r3, r4, 0); GETKEY(ctx->xkey, r0, r1, r2, r3, 4); S2(r0,r1,r2,r3,r4); SETKEY(ctx->xkey, r2, r3, r1, r4, 4); GETKEY(ctx->xkey, r0, r1, r2, r3, 8); S1(r0,r1,r2,r3,r4); SETKEY(ctx->xkey, r3, r1, r2, r0, 8); GETKEY(ctx->xkey, r0, r1, r2, r3, 12); S0(r0,r1,r2,r3,r4); SETKEY(ctx->xkey, r1, r4, r2, r0, 12);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -