📄 loop_serpent.c
字号:
/* 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. * * Adapted to normal loop device transfer interface. * Jari Ruusu, March 5 2002 * * Fixed endianness bug. * Jari Ruusu, December 26 2002 * * Added support for MD5 IV computation and multi-key operation. * Jari Ruusu, October 22 2003 */#include <linux/version.h>#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/string.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/slab.h>#if LINUX_VERSION_CODE >= 0x20600# include <linux/bio.h># include <linux/blkdev.h>#endif#include <linux/loop.h>#include <asm/uaccess.h>#include <asm/byteorder.h>#define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))#define rotr(reg, val) ((reg >> val) | (reg << (32 - val)))#define io_swap_be(x) __cpu_to_be32(x) /* incorrect byte order */#define io_swap_le(x) __cpu_to_le32(x) /* correct byte order *//* 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(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(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(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 void serpent_set_key(u32 *l_key, unsigned char *key, int key_len, int wrongByteOrder){ u32 *in_key = (u32 *)key; u32 i,lk,r0,r1,r2,r3,r4; if (key_len != 16 && key_len != 24 && key_len != 32) key_len = 16; key_len *= 8; i = 0; lk = (key_len + 31) / 32; while(i < lk) { if (wrongByteOrder) { /* incorrect byte order */ l_key[i] = io_swap_be(in_key[lk - i - 1]); } else { /* correct byte order */ l_key[i] = io_swap_le(in_key[i]); } i++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -