(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1 @@
cmd_crypto/built-in.o := rm -f crypto/built-in.o; ar rcs crypto/built-in.o

View File

@@ -0,0 +1,278 @@
#
# Cryptographic API Configuration
#
menu "Cryptographic options"
config CRYPTO
bool "Cryptographic API"
help
This option provides the core Cryptographic API.
config CRYPTO_HMAC
bool "HMAC support"
depends on CRYPTO
help
HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec.
config CRYPTO_NULL
tristate "Null algorithms"
depends on CRYPTO
help
These are 'Null' algorithms, used by IPsec, which do nothing.
config CRYPTO_MD4
tristate "MD4 digest algorithm"
depends on CRYPTO
help
MD4 message digest algorithm (RFC1320).
config CRYPTO_MD5
tristate "MD5 digest algorithm"
depends on CRYPTO
help
MD5 message digest algorithm (RFC1321).
config CRYPTO_SHA1
tristate "SHA1 digest algorithm"
depends on CRYPTO
help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
config CRYPTO_SHA1_Z990
tristate "SHA1 digest algorithm for IBM zSeries z990"
depends on CRYPTO && ARCH_S390
help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
config CRYPTO_SHA256
tristate "SHA256 digest algorithm"
depends on CRYPTO
help
SHA256 secure hash standard (DFIPS 180-2).
This version of SHA implements a 256 bit hash with 128 bits of
security against collision attacks.
config CRYPTO_SHA512
tristate "SHA384 and SHA512 digest algorithms"
depends on CRYPTO
help
SHA512 secure hash standard (DFIPS 180-2).
This version of SHA implements a 512 bit hash with 256 bits of
security against collision attacks.
This code also includes SHA-384, a 384 bit hash with 192 bits
of security against collision attacks.
config CRYPTO_WP512
tristate "Whirlpool digest algorithms"
depends on CRYPTO
help
Whirlpool hash algorithm 512, 384 and 256-bit hashes
Whirlpool-512 is part of the NESSIE cryptographic primitives.
Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
See also:
http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
config CRYPTO_DES_Z990
tristate "DES and Triple DES cipher algorithms for IBM zSeries z990"
depends on CRYPTO && ARCH_S390
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
config CRYPTO_BLOWFISH
tristate "Blowfish cipher algorithm"
depends on CRYPTO
help
Blowfish cipher algorithm, by Bruce Schneier.
This is a variable key length cipher which can use keys from 32
bits to 448 bits in length. It's fast, simple and specifically
designed for use on "large microprocessors".
See also:
http://www.schneier.com/blowfish.html
config CRYPTO_TWOFISH
tristate "Twofish cipher algorithm"
depends on CRYPTO
help
Twofish cipher algorithm.
Twofish was submitted as an AES (Advanced Encryption Standard)
candidate cipher by researchers at CounterPane Systems. It is a
16 round block cipher supporting key sizes of 128, 192, and 256
bits.
See also:
http://www.schneier.com/twofish.html
config CRYPTO_SERPENT
tristate "Serpent cipher algorithm"
depends on CRYPTO
help
Serpent cipher algorithm, by Anderson, Biham & Knudsen.
Keys are allowed to be from 0 to 256 bits in length, in steps
of 8 bits. Also includes the 'Tnepres' algorithm, a reversed
variant of Serpent for compatibility with old kerneli code.
See also:
http://www.cl.cam.ac.uk/~rja14/serpent.html
config CRYPTO_AES
tristate "AES cipher algorithms"
depends on CRYPTO && !(X86 && !X86_64)
help
AES cipher algorithms (FIPS-197). AES uses the Rijndael
algorithm.
Rijndael appears to be consistently a very good performer in
both hardware and software across a wide range of computing
environments regardless of its use in feedback or non-feedback
modes. Its key setup time is excellent, and its key agility is
good. Rijndael's very low memory requirements make it very well
suited for restricted-space environments, in which it also
demonstrates excellent performance. Rijndael's operations are
among the easiest to defend against power and timing attacks.
The AES specifies three key sizes: 128, 192 and 256 bits
See http://csrc.nist.gov/CryptoToolkit/aes/ for more information.
config CRYPTO_AES_586
tristate "AES cipher algorithms (i586)"
depends on CRYPTO && (X86 && !X86_64)
help
AES cipher algorithms (FIPS-197). AES uses the Rijndael
algorithm.
Rijndael appears to be consistently a very good performer in
both hardware and software across a wide range of computing
environments regardless of its use in feedback or non-feedback
modes. Its key setup time is excellent, and its key agility is
good. Rijndael's very low memory requirements make it very well
suited for restricted-space environments, in which it also
demonstrates excellent performance. Rijndael's operations are
among the easiest to defend against power and timing attacks.
The AES specifies three key sizes: 128, 192 and 256 bits
See http://csrc.nist.gov/encryption/aes/ for more information.
config CRYPTO_CAST5
tristate "CAST5 (CAST-128) cipher algorithm"
depends on CRYPTO
help
The CAST5 encryption algorithm (synonymous with CAST-128) is
described in RFC2144.
config CRYPTO_CAST6
tristate "CAST6 (CAST-256) cipher algorithm"
depends on CRYPTO
help
The CAST6 encryption algorithm (synonymous with CAST-256) is
described in RFC2612.
config CRYPTO_TEA
tristate "TEA and XTEA cipher algorithms"
depends on CRYPTO
help
TEA cipher algorithm.
Tiny Encryption Algorithm is a simple cipher that uses
many rounds for security. It is very fast and uses
little memory.
Xtendend Tiny Encryption Algorithm is a modification to
the TEA algorithm to address a potential key weakness
in the TEA algorithm.
config CRYPTO_ARC4
tristate "ARC4 cipher algorithm"
depends on CRYPTO
help
ARC4 cipher algorithm.
ARC4 is a stream cipher using keys ranging from 8 bits to 2048
bits in length. This algorithm is required for driver-based
WEP, but it should not be for other purposes because of the
weakness of the algorithm.
config CRYPTO_KHAZAD
tristate "Khazad cipher algorithm"
depends on CRYPTO
help
Khazad cipher algorithm.
Khazad was a finalist in the initial NESSIE competition. It is
an algorithm optimized for 64-bit processors with good performance
on 32-bit processors. Khazad uses an 128 bit key size.
See also:
http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html
config CRYPTO_ANUBIS
tristate "Anubis cipher algorithm"
depends on CRYPTO
help
Anubis cipher algorithm.
Anubis is a variable key length cipher which can use keys from
128 bits to 320 bits in length. It was evaluated as a entrant
in the NESSIE competition.
See also:
https://www.cosic.esat.kuleuven.ac.be/nessie/reports/
http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
depends on CRYPTO
select ZLIB_INFLATE
select ZLIB_DEFLATE
help
This is the Deflate algorithm (RFC1951), specified for use in
IPSec with the IPCOMP protocol (RFC3173, RFC2394).
You will most probably want this if using IPSec.
config CRYPTO_MICHAEL_MIC
tristate "Michael MIC keyed digest algorithm"
depends on CRYPTO
help
Michael MIC is used for message integrity protection in TKIP
(IEEE 802.11i). This algorithm is required for TKIP, but it
should not be used for other purposes because of the weakness
of the algorithm.
config CRYPTO_CRC32C
tristate "CRC32c CRC algorithm"
depends on CRYPTO
select LIBCRC32C
help
Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
by iSCSI for header and data digests and by others.
See Castagnoli93. This implementation uses lib/libcrc32c.
Module will be crc32c.
config CRYPTO_TEST
tristate "Testing module"
depends on CRYPTO
help
Quick & dirty crypto test module.
endmenu

View File

@@ -0,0 +1,33 @@
#
# Cryptographic API
#
proc-crypto-$(CONFIG_PROC_FS) = proc.o
obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \
$(proc-crypto-y)
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
obj-$(CONFIG_CRYPTO_MD4) += md4.o
obj-$(CONFIG_CRYPTO_MD5) += md5.o
obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
obj-$(CONFIG_CRYPTO_DES) += des.o
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
obj-$(CONFIG_CRYPTO_AES) += aes.o
obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o

View File

@@ -0,0 +1,468 @@
/*
* Cryptographic API.
*
* AES Cipher Algorithm.
*
* Based on Brian Gladman's code.
*
* Linux developers:
* Alexander Kjeldaas <astor@fast.no>
* Herbert Valerio Riedel <hvr@hvrlab.org>
* Kyle McMartin <kyle@debian.org>
* Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ---------------------------------------------------------------------------
* Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
* All rights reserved.
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
* ---------------------------------------------------------------------------
*/
/* Some changes from the Gladman version:
s/RIJNDAEL(e_key)/E_KEY/g
s/RIJNDAEL(d_key)/D_KEY/g
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/crypto.h>
#include <asm/byteorder.h>
#define AES_MIN_KEY_SIZE 16
#define AES_MAX_KEY_SIZE 32
#define AES_BLOCK_SIZE 16
static inline
u32 generic_rotr32 (const u32 x, const unsigned bits)
{
const unsigned n = bits % 32;
return (x >> n) | (x << (32 - n));
}
static inline
u32 generic_rotl32 (const u32 x, const unsigned bits)
{
const unsigned n = bits % 32;
return (x << n) | (x >> (32 - n));
}
#define rotl generic_rotl32
#define rotr generic_rotr32
/*
* #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
*/
inline static u8
byte(const u32 x, const unsigned n)
{
return x >> (n << 3);
}
#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
struct aes_ctx {
int key_length;
u32 E[60];
u32 D[60];
};
#define E_KEY ctx->E
#define D_KEY ctx->D
static u8 pow_tab[256] __initdata;
static u8 log_tab[256] __initdata;
static u8 sbx_tab[256] __initdata;
static u8 isb_tab[256] __initdata;
static u32 rco_tab[10];
static u32 ft_tab[4][256];
static u32 it_tab[4][256];
static u32 fl_tab[4][256];
static u32 il_tab[4][256];
static inline u8 __init
f_mult (u8 a, u8 b)
{
u8 aa = log_tab[a], cc = aa + log_tab[b];
return pow_tab[cc + (cc < aa ? 1 : 0)];
}
#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0)
#define f_rn(bo, bi, n, k) \
bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rn(bo, bi, n, k) \
bo[n] = it_tab[0][byte(bi[n],0)] ^ \
it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
#define ls_box(x) \
( fl_tab[0][byte(x, 0)] ^ \
fl_tab[1][byte(x, 1)] ^ \
fl_tab[2][byte(x, 2)] ^ \
fl_tab[3][byte(x, 3)] )
#define f_rl(bo, bi, n, k) \
bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rl(bo, bi, n, k) \
bo[n] = il_tab[0][byte(bi[n],0)] ^ \
il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
static void __init
gen_tabs (void)
{
u32 i, t;
u8 p, q;
/* log and power tables for GF(2**8) finite field with
0x011b as modular polynomial - the simplest primitive
root is 0x03, used here to generate the tables */
for (i = 0, p = 1; i < 256; ++i) {
pow_tab[i] = (u8) p;
log_tab[p] = (u8) i;
p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
}
log_tab[1] = 0;
for (i = 0, p = 1; i < 10; ++i) {
rco_tab[i] = p;
p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
}
for (i = 0; i < 256; ++i) {
p = (i ? pow_tab[255 - log_tab[i]] : 0);
q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
sbx_tab[i] = p;
isb_tab[p] = (u8) i;
}
for (i = 0; i < 256; ++i) {
p = sbx_tab[i];
t = p;
fl_tab[0][i] = t;
fl_tab[1][i] = rotl (t, 8);
fl_tab[2][i] = rotl (t, 16);
fl_tab[3][i] = rotl (t, 24);
t = ((u32) ff_mult (2, p)) |
((u32) p << 8) |
((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
ft_tab[0][i] = t;
ft_tab[1][i] = rotl (t, 8);
ft_tab[2][i] = rotl (t, 16);
ft_tab[3][i] = rotl (t, 24);
p = isb_tab[i];
t = p;
il_tab[0][i] = t;
il_tab[1][i] = rotl (t, 8);
il_tab[2][i] = rotl (t, 16);
il_tab[3][i] = rotl (t, 24);
t = ((u32) ff_mult (14, p)) |
((u32) ff_mult (9, p) << 8) |
((u32) ff_mult (13, p) << 16) |
((u32) ff_mult (11, p) << 24);
it_tab[0][i] = t;
it_tab[1][i] = rotl (t, 8);
it_tab[2][i] = rotl (t, 16);
it_tab[3][i] = rotl (t, 24);
}
}
#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
#define imix_col(y,x) \
u = star_x(x); \
v = star_x(u); \
w = star_x(v); \
t = w ^ (x); \
(y) = u ^ v ^ w; \
(y) ^= rotr(u ^ t, 8) ^ \
rotr(v ^ t, 16) ^ \
rotr(t,24)
/* initialise the key schedule from the user supplied key */
#define loop4(i) \
{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \
t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \
t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \
t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \
t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \
}
#define loop6(i) \
{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \
t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \
t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \
t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \
t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \
t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \
t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \
}
#define loop8(i) \
{ t = rotr(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \
t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \
t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \
t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \
t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \
t = E_KEY[8 * i + 4] ^ ls_box(t); \
E_KEY[8 * i + 12] = t; \
t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \
t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \
t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \
}
static int
aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
{
struct aes_ctx *ctx = ctx_arg;
u32 i, t, u, v, w;
if (key_len != 16 && key_len != 24 && key_len != 32) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
ctx->key_length = key_len;
E_KEY[0] = u32_in (in_key);
E_KEY[1] = u32_in (in_key + 4);
E_KEY[2] = u32_in (in_key + 8);
E_KEY[3] = u32_in (in_key + 12);
switch (key_len) {
case 16:
t = E_KEY[3];
for (i = 0; i < 10; ++i)
loop4 (i);
break;
case 24:
E_KEY[4] = u32_in (in_key + 16);
t = E_KEY[5] = u32_in (in_key + 20);
for (i = 0; i < 8; ++i)
loop6 (i);
break;
case 32:
E_KEY[4] = u32_in (in_key + 16);
E_KEY[5] = u32_in (in_key + 20);
E_KEY[6] = u32_in (in_key + 24);
t = E_KEY[7] = u32_in (in_key + 28);
for (i = 0; i < 7; ++i)
loop8 (i);
break;
}
D_KEY[0] = E_KEY[0];
D_KEY[1] = E_KEY[1];
D_KEY[2] = E_KEY[2];
D_KEY[3] = E_KEY[3];
for (i = 4; i < key_len + 24; ++i) {
imix_col (D_KEY[i], E_KEY[i]);
}
return 0;
}
/* encrypt a block of text */
#define f_nround(bo, bi, k) \
f_rn(bo, bi, 0, k); \
f_rn(bo, bi, 1, k); \
f_rn(bo, bi, 2, k); \
f_rn(bo, bi, 3, k); \
k += 4
#define f_lround(bo, bi, k) \
f_rl(bo, bi, 0, k); \
f_rl(bo, bi, 1, k); \
f_rl(bo, bi, 2, k); \
f_rl(bo, bi, 3, k)
static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
{
const struct aes_ctx *ctx = ctx_arg;
u32 b0[4], b1[4];
const u32 *kp = E_KEY + 4;
b0[0] = u32_in (in) ^ E_KEY[0];
b0[1] = u32_in (in + 4) ^ E_KEY[1];
b0[2] = u32_in (in + 8) ^ E_KEY[2];
b0[3] = u32_in (in + 12) ^ E_KEY[3];
if (ctx->key_length > 24) {
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
}
if (ctx->key_length > 16) {
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
}
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
f_nround (b1, b0, kp);
f_nround (b0, b1, kp);
f_nround (b1, b0, kp);
f_lround (b0, b1, kp);
u32_out (out, b0[0]);
u32_out (out + 4, b0[1]);
u32_out (out + 8, b0[2]);
u32_out (out + 12, b0[3]);
}
/* decrypt a block of text */
#define i_nround(bo, bi, k) \
i_rn(bo, bi, 0, k); \
i_rn(bo, bi, 1, k); \
i_rn(bo, bi, 2, k); \
i_rn(bo, bi, 3, k); \
k -= 4
#define i_lround(bo, bi, k) \
i_rl(bo, bi, 0, k); \
i_rl(bo, bi, 1, k); \
i_rl(bo, bi, 2, k); \
i_rl(bo, bi, 3, k)
static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
{
const struct aes_ctx *ctx = ctx_arg;
u32 b0[4], b1[4];
const int key_len = ctx->key_length;
const u32 *kp = D_KEY + key_len + 20;
b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
if (key_len > 24) {
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
}
if (key_len > 16) {
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
}
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
i_nround (b1, b0, kp);
i_nround (b0, b1, kp);
i_nround (b1, b0, kp);
i_lround (b0, b1, kp);
u32_out (out, b0[0]);
u32_out (out + 4, b0[1]);
u32_out (out + 8, b0[2]);
u32_out (out + 12, b0[3]);
}
static struct crypto_alg aes_alg = {
.cra_name = "aes",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct aes_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
.cia_max_keysize = AES_MAX_KEY_SIZE,
.cia_setkey = aes_set_key,
.cia_encrypt = aes_encrypt,
.cia_decrypt = aes_decrypt
}
}
};
static int __init aes_init(void)
{
gen_tabs();
return crypto_register_alg(&aes_alg);
}
static void __exit aes_fini(void)
{
crypto_unregister_alg(&aes_alg);
}
module_init(aes_init);
module_exit(aes_fini);
MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
MODULE_LICENSE("Dual BSD/GPL");

View File

@@ -0,0 +1,719 @@
/*
* Cryptographic API.
*
* Anubis Algorithm
*
* The Anubis algorithm was developed by Paulo S. L. M. Barreto and
* Vincent Rijmen.
*
* See
*
* P.S.L.M. Barreto, V. Rijmen,
* ``The Anubis block cipher,''
* NESSIE submission, 2000.
*
* This software implements the "tweaked" version of Anubis.
* Only the S-box and (consequently) the rounds constants have been
* changed.
*
* The original authors have disclaimed all copyright interest in this
* code and thus put it in the public domain. The subsequent authors
* have put this under the GNU General Public License.
*
* By Aaron Grothe ajgrothe@yahoo.com, October 28, 2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#define ANUBIS_MIN_KEY_SIZE 16
#define ANUBIS_MAX_KEY_SIZE 40
#define ANUBIS_BLOCK_SIZE 16
#define ANUBIS_MAX_N 10
#define ANUBIS_MAX_ROUNDS (8 + ANUBIS_MAX_N)
struct anubis_ctx {
int key_len; // in bits
int R;
u32 E[ANUBIS_MAX_ROUNDS + 1][4];
u32 D[ANUBIS_MAX_ROUNDS + 1][4];
};
static const u32 T0[256] = {
0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U,
0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U,
0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U,
0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U,
0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU,
0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U,
0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U,
0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U,
0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU,
0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U,
0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U,
0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU,
0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U,
0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U,
0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U,
0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U,
0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U,
0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U,
0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U,
0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U,
0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U,
0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U,
0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U,
0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U,
0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU,
0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU,
0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU,
0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U,
0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU,
0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU,
0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U,
0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U,
0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U,
0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U,
0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U,
0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U,
0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU,
0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU,
0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU,
0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU,
0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU,
0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU,
0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU,
0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U,
0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU,
0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U,
0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU,
0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU,
0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U,
0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U,
0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U,
0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU,
0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU,
0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U,
0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U,
0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U,
0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U,
0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU,
0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU,
0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U,
0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU,
0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU,
0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU,
0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U,
};
static const u32 T1[256] = {
0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU,
0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U,
0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U,
0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU,
0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U,
0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U,
0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU,
0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U,
0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U,
0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U,
0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU,
0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U,
0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U,
0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U,
0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U,
0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU,
0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U,
0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U,
0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU,
0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU,
0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U,
0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U,
0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U,
0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U,
0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U,
0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU,
0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U,
0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U,
0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U,
0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU,
0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U,
0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U,
0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU,
0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U,
0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU,
0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU,
0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU,
0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U,
0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU,
0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU,
0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU,
0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U,
0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U,
0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U,
0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U,
0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U,
0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U,
0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU,
0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U,
0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U,
0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U,
0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U,
0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U,
0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU,
0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U,
0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U,
0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U,
0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U,
0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU,
0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU,
0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U,
0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU,
0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U,
0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U,
};
static const u32 T2[256] = {
0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U,
0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU,
0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U,
0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U,
0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU,
0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U,
0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU,
0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U,
0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU,
0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU,
0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U,
0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U,
0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U,
0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU,
0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U,
0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U,
0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U,
0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U,
0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU,
0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU,
0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U,
0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU,
0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU,
0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U,
0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU,
0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U,
0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U,
0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU,
0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U,
0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U,
0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU,
0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U,
0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU,
0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U,
0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU,
0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U,
0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U,
0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U,
0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U,
0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U,
0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U,
0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U,
0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U,
0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU,
0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU,
0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU,
0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU,
0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U,
0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U,
0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U,
0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U,
0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU,
0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU,
0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U,
0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U,
0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU,
0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U,
0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU,
0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U,
0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U,
0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU,
0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U,
0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU,
0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U,
};
static const u32 T3[256] = {
0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U,
0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU,
0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU,
0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU,
0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U,
0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U,
0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U,
0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU,
0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU,
0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU,
0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U,
0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U,
0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U,
0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU,
0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU,
0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU,
0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU,
0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU,
0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U,
0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU,
0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U,
0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U,
0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U,
0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U,
0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U,
0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU,
0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU,
0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U,
0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U,
0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U,
0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U,
0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU,
0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U,
0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU,
0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U,
0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U,
0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU,
0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U,
0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U,
0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU,
0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U,
0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U,
0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU,
0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU,
0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U,
0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU,
0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U,
0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU,
0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U,
0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U,
0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U,
0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U,
0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U,
0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU,
0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU,
0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U,
0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U,
0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U,
0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U,
0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U,
0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU,
0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U,
0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU,
0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U,
};
static const u32 T4[256] = {
0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U,
0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU,
0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU,
0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU,
0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U,
0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U,
0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U,
0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU,
0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU,
0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU,
0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U,
0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U,
0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U,
0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU,
0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU,
0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU,
0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU,
0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU,
0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U,
0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU,
0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U,
0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U,
0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U,
0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U,
0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U,
0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU,
0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU,
0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U,
0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U,
0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U,
0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U,
0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU,
0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U,
0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU,
0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U,
0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U,
0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU,
0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U,
0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U,
0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU,
0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U,
0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U,
0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU,
0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU,
0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U,
0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU,
0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U,
0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU,
0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U,
0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U,
0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U,
0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U,
0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U,
0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU,
0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU,
0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U,
0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U,
0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U,
0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U,
0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U,
0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU,
0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U,
0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU,
0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U,
};
static const u32 T5[256] = {
0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
};
static const u32 rc[] = {
0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU,
0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU,
0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U,
0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU,
0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U,
};
static int anubis_setkey(void *ctx_arg, const u8 *in_key,
unsigned int key_len, u32 *flags)
{
int N, R, i, pos, r;
u32 kappa[ANUBIS_MAX_N];
u32 inter[ANUBIS_MAX_N];
struct anubis_ctx *ctx = ctx_arg;
switch (key_len)
{
case 16: case 20: case 24: case 28:
case 32: case 36: case 40:
break;
default:
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return - EINVAL;
}
ctx->key_len = key_len * 8;
N = ctx->key_len >> 5;
ctx->R = R = 8 + N;
/* * map cipher key to initial key state (mu): */
for (i = 0, pos = 0; i < N; i++, pos += 4) {
kappa[i] =
(in_key[pos ] << 24) ^
(in_key[pos + 1] << 16) ^
(in_key[pos + 2] << 8) ^
(in_key[pos + 3] );
}
/*
* generate R + 1 round keys:
*/
for (r = 0; r <= R; r++) {
u32 K0, K1, K2, K3;
/*
* generate r-th round key K^r:
*/
K0 = T4[(kappa[N - 1] >> 24) ];
K1 = T4[(kappa[N - 1] >> 16) & 0xff];
K2 = T4[(kappa[N - 1] >> 8) & 0xff];
K3 = T4[(kappa[N - 1] ) & 0xff];
for (i = N - 2; i >= 0; i--) {
K0 = T4[(kappa[i] >> 24) ] ^
(T5[(K0 >> 24) ] & 0xff000000U) ^
(T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^
(T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^
(T5[(K0 ) & 0xff] & 0x000000ffU);
K1 = T4[(kappa[i] >> 16) & 0xff] ^
(T5[(K1 >> 24) ] & 0xff000000U) ^
(T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^
(T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^
(T5[(K1 ) & 0xff] & 0x000000ffU);
K2 = T4[(kappa[i] >> 8) & 0xff] ^
(T5[(K2 >> 24) ] & 0xff000000U) ^
(T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^
(T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^
(T5[(K2 ) & 0xff] & 0x000000ffU);
K3 = T4[(kappa[i] ) & 0xff] ^
(T5[(K3 >> 24) ] & 0xff000000U) ^
(T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^
(T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^
(T5[(K3 ) & 0xff] & 0x000000ffU);
}
ctx->E[r][0] = K0;
ctx->E[r][1] = K1;
ctx->E[r][2] = K2;
ctx->E[r][3] = K3;
/*
* compute kappa^{r+1} from kappa^r:
*/
if (r == R) {
break;
}
for (i = 0; i < N; i++) {
int j = i;
inter[i] = T0[(kappa[j--] >> 24) ];
if (j < 0) j = N - 1;
inter[i] ^= T1[(kappa[j--] >> 16) & 0xff];
if (j < 0) j = N - 1;
inter[i] ^= T2[(kappa[j--] >> 8) & 0xff];
if (j < 0) j = N - 1;
inter[i] ^= T3[(kappa[j ] ) & 0xff];
}
kappa[0] = inter[0] ^ rc[r];
for (i = 1; i < N; i++) {
kappa[i] = inter[i];
}
}
/*
* generate inverse key schedule: K'^0 = K^R, K'^R =
* K^0, K'^r = theta(K^{R-r}):
*/
for (i = 0; i < 4; i++) {
ctx->D[0][i] = ctx->E[R][i];
ctx->D[R][i] = ctx->E[0][i];
}
for (r = 1; r < R; r++) {
for (i = 0; i < 4; i++) {
u32 v = ctx->E[R - r][i];
ctx->D[r][i] =
T0[T4[(v >> 24) ] & 0xff] ^
T1[T4[(v >> 16) & 0xff] & 0xff] ^
T2[T4[(v >> 8) & 0xff] & 0xff] ^
T3[T4[(v ) & 0xff] & 0xff];
}
}
return 0;
}
static void anubis_crypt(u32 roundKey[ANUBIS_MAX_ROUNDS + 1][4],
u8 *ciphertext, const u8 *plaintext, const int R)
{
int i, pos, r;
u32 state[4];
u32 inter[4];
/*
* map plaintext block to cipher state (mu)
* and add initial round key (sigma[K^0]):
*/
for (i = 0, pos = 0; i < 4; i++, pos += 4) {
state[i] =
(plaintext[pos ] << 24) ^
(plaintext[pos + 1] << 16) ^
(plaintext[pos + 2] << 8) ^
(plaintext[pos + 3] ) ^
roundKey[0][i];
}
/*
* R - 1 full rounds:
*/
for (r = 1; r < R; r++) {
inter[0] =
T0[(state[0] >> 24) ] ^
T1[(state[1] >> 24) ] ^
T2[(state[2] >> 24) ] ^
T3[(state[3] >> 24) ] ^
roundKey[r][0];
inter[1] =
T0[(state[0] >> 16) & 0xff] ^
T1[(state[1] >> 16) & 0xff] ^
T2[(state[2] >> 16) & 0xff] ^
T3[(state[3] >> 16) & 0xff] ^
roundKey[r][1];
inter[2] =
T0[(state[0] >> 8) & 0xff] ^
T1[(state[1] >> 8) & 0xff] ^
T2[(state[2] >> 8) & 0xff] ^
T3[(state[3] >> 8) & 0xff] ^
roundKey[r][2];
inter[3] =
T0[(state[0] ) & 0xff] ^
T1[(state[1] ) & 0xff] ^
T2[(state[2] ) & 0xff] ^
T3[(state[3] ) & 0xff] ^
roundKey[r][3];
state[0] = inter[0];
state[1] = inter[1];
state[2] = inter[2];
state[3] = inter[3];
}
/*
* last round:
*/
inter[0] =
(T0[(state[0] >> 24) ] & 0xff000000U) ^
(T1[(state[1] >> 24) ] & 0x00ff0000U) ^
(T2[(state[2] >> 24) ] & 0x0000ff00U) ^
(T3[(state[3] >> 24) ] & 0x000000ffU) ^
roundKey[R][0];
inter[1] =
(T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^
(T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^
(T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^
(T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^
roundKey[R][1];
inter[2] =
(T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^
(T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^
(T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^
(T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^
roundKey[R][2];
inter[3] =
(T0[(state[0] ) & 0xff] & 0xff000000U) ^
(T1[(state[1] ) & 0xff] & 0x00ff0000U) ^
(T2[(state[2] ) & 0xff] & 0x0000ff00U) ^
(T3[(state[3] ) & 0xff] & 0x000000ffU) ^
roundKey[R][3];
/*
* map cipher state to ciphertext block (mu^{-1}):
*/
for (i = 0, pos = 0; i < 4; i++, pos += 4) {
u32 w = inter[i];
ciphertext[pos ] = (u8)(w >> 24);
ciphertext[pos + 1] = (u8)(w >> 16);
ciphertext[pos + 2] = (u8)(w >> 8);
ciphertext[pos + 3] = (u8)(w );
}
}
static void anubis_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
struct anubis_ctx *ctx = ctx_arg;
anubis_crypt(ctx->E, dst, src, ctx->R);
}
static void anubis_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
struct anubis_ctx *ctx = ctx_arg;
anubis_crypt(ctx->D, dst, src, ctx->R);
}
static struct crypto_alg anubis_alg = {
.cra_name = "anubis",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = ANUBIS_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct anubis_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(anubis_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = ANUBIS_MIN_KEY_SIZE,
.cia_max_keysize = ANUBIS_MAX_KEY_SIZE,
.cia_setkey = anubis_setkey,
.cia_encrypt = anubis_encrypt,
.cia_decrypt = anubis_decrypt } }
};
static int __init init(void)
{
int ret = 0;
ret = crypto_register_alg(&anubis_alg);
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&anubis_alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Anubis Cryptographic Algorithm");

View File

@@ -0,0 +1,233 @@
/*
* Scatterlist Cryptographic API.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 David S. Miller (davem@redhat.com)
*
* Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
* and Nettle, by Niels Möller.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/crypto.h>
#include <linux/errno.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
#include "internal.h"
LIST_HEAD(crypto_alg_list);
DECLARE_RWSEM(crypto_alg_sem);
static inline int crypto_alg_get(struct crypto_alg *alg)
{
return try_module_get(alg->cra_module);
}
static inline void crypto_alg_put(struct crypto_alg *alg)
{
module_put(alg->cra_module);
}
struct crypto_alg *crypto_alg_lookup(const char *name)
{
struct crypto_alg *q, *alg = NULL;
if (!name)
return NULL;
down_read(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) {
if (!(strcmp(q->cra_name, name))) {
if (crypto_alg_get(q))
alg = q;
break;
}
}
up_read(&crypto_alg_sem);
return alg;
}
static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
{
tfm->crt_flags = 0;
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
return crypto_init_cipher_flags(tfm, flags);
case CRYPTO_ALG_TYPE_DIGEST:
return crypto_init_digest_flags(tfm, flags);
case CRYPTO_ALG_TYPE_COMPRESS:
return crypto_init_compress_flags(tfm, flags);
default:
break;
}
BUG();
return -EINVAL;
}
static int crypto_init_ops(struct crypto_tfm *tfm)
{
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
return crypto_init_cipher_ops(tfm);
case CRYPTO_ALG_TYPE_DIGEST:
return crypto_init_digest_ops(tfm);
case CRYPTO_ALG_TYPE_COMPRESS:
return crypto_init_compress_ops(tfm);
default:
break;
}
BUG();
return -EINVAL;
}
static void crypto_exit_ops(struct crypto_tfm *tfm)
{
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
crypto_exit_cipher_ops(tfm);
break;
case CRYPTO_ALG_TYPE_DIGEST:
crypto_exit_digest_ops(tfm);
break;
case CRYPTO_ALG_TYPE_COMPRESS:
crypto_exit_compress_ops(tfm);
break;
default:
BUG();
}
}
struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
{
struct crypto_tfm *tfm = NULL;
struct crypto_alg *alg;
alg = crypto_alg_mod_lookup(name);
if (alg == NULL)
goto out;
tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
if (tfm == NULL)
goto out_put;
memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
tfm->__crt_alg = alg;
if (crypto_init_flags(tfm, flags))
goto out_free_tfm;
if (crypto_init_ops(tfm)) {
crypto_exit_ops(tfm);
goto out_free_tfm;
}
goto out;
out_free_tfm:
kfree(tfm);
tfm = NULL;
out_put:
crypto_alg_put(alg);
out:
return tfm;
}
void crypto_free_tfm(struct crypto_tfm *tfm)
{
struct crypto_alg *alg = tfm->__crt_alg;
int size = sizeof(*tfm) + alg->cra_ctxsize;
crypto_exit_ops(tfm);
crypto_alg_put(alg);
memset(tfm, 0, size);
kfree(tfm);
}
int crypto_register_alg(struct crypto_alg *alg)
{
int ret = 0;
struct crypto_alg *q;
down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) {
if (!(strcmp(q->cra_name, alg->cra_name))) {
ret = -EEXIST;
goto out;
}
}
list_add_tail(&alg->cra_list, &crypto_alg_list);
out:
up_write(&crypto_alg_sem);
return ret;
}
int crypto_unregister_alg(struct crypto_alg *alg)
{
int ret = -ENOENT;
struct crypto_alg *q;
BUG_ON(!alg->cra_module);
down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) {
if (alg == q) {
list_del(&alg->cra_list);
ret = 0;
goto out;
}
}
out:
up_write(&crypto_alg_sem);
return ret;
}
int crypto_alg_available(const char *name, u32 flags)
{
int ret = 0;
struct crypto_alg *alg = crypto_alg_mod_lookup(name);
if (alg) {
crypto_alg_put(alg);
ret = 1;
}
return ret;
}
static int __init init_crypto(void)
{
printk(KERN_INFO "Initializing Cryptographic API\n");
crypto_init_proc();
return 0;
}
__initcall(init_crypto);
EXPORT_SYMBOL_GPL(crypto_register_alg);
EXPORT_SYMBOL_GPL(crypto_unregister_alg);
EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
EXPORT_SYMBOL_GPL(crypto_free_tfm);
EXPORT_SYMBOL_GPL(crypto_alg_available);

View File

@@ -0,0 +1,103 @@
/*
* Cryptographic API
*
* ARC4 Cipher Algorithm
*
* Jon Oberheide <jon@oberheide.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/crypto.h>
#define ARC4_MIN_KEY_SIZE 1
#define ARC4_MAX_KEY_SIZE 256
#define ARC4_BLOCK_SIZE 1
struct arc4_ctx {
u8 S[256];
u8 x, y;
};
static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
{
struct arc4_ctx *ctx = ctx_arg;
int i, j = 0, k = 0;
ctx->x = 1;
ctx->y = 0;
for(i = 0; i < 256; i++)
ctx->S[i] = i;
for(i = 0; i < 256; i++)
{
u8 a = ctx->S[i];
j = (j + in_key[k] + a) & 0xff;
ctx->S[i] = ctx->S[j];
ctx->S[j] = a;
if(++k >= key_len)
k = 0;
}
return 0;
}
static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
{
struct arc4_ctx *ctx = ctx_arg;
u8 *const S = ctx->S;
u8 x = ctx->x;
u8 y = ctx->y;
u8 a, b;
a = S[x];
y = (y + a) & 0xff;
b = S[y];
S[x] = b;
S[y] = a;
x = (x + 1) & 0xff;
*out++ = *in ^ S[(a + b) & 0xff];
ctx->x = x;
ctx->y = y;
}
static struct crypto_alg arc4_alg = {
.cra_name = "arc4",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = ARC4_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct arc4_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = ARC4_MIN_KEY_SIZE,
.cia_max_keysize = ARC4_MAX_KEY_SIZE,
.cia_setkey = arc4_set_key,
.cia_encrypt = arc4_crypt,
.cia_decrypt = arc4_crypt } }
};
static int __init arc4_init(void)
{
return crypto_register_alg(&arc4_alg);
}
static void __exit arc4_exit(void)
{
crypto_unregister_alg(&arc4_alg);
}
module_init(arc4_init);
module_exit(arc4_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");

View File

@@ -0,0 +1,478 @@
/*
* Cryptographic API.
*
* Blowfish Cipher Algorithm, by Bruce Schneier.
* http://www.counterpane.com/blowfish.html
*
* Adapted from Kerneli implementation.
*
* Copyright (c) Herbert Valerio Riedel <hvr@hvrlab.org>
* Copyright (c) Kyle McMartin <kyle@debian.org>
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#define BF_BLOCK_SIZE 8
#define BF_MIN_KEY_SIZE 4
#define BF_MAX_KEY_SIZE 56
struct bf_ctx {
u32 p[18];
u32 s[1024];
};
static const u32 bf_pbox[16 + 2] = {
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b,
};
static const u32 bf_sbox[256 * 4] = {
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
};
/*
* Round loop unrolling macros, S is a pointer to a S-Box array
* organized in 4 unsigned longs at a row.
*/
#define GET32_3(x) (((x) & 0xff))
#define GET32_2(x) (((x) >> (8)) & (0xff))
#define GET32_1(x) (((x) >> (16)) & (0xff))
#define GET32_0(x) (((x) >> (24)) & (0xff))
#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
#define ROUND(a, b, n) b ^= P[n]; a ^= bf_F (b)
/*
* The blowfish encipher, processes 64-bit blocks.
* NOTE: This function MUSTN'T respect endianess
*/
static void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src)
{
const u32 *P = bctx->p;
const u32 *S = bctx->s;
u32 yl = src[0];
u32 yr = src[1];
ROUND(yr, yl, 0);
ROUND(yl, yr, 1);
ROUND(yr, yl, 2);
ROUND(yl, yr, 3);
ROUND(yr, yl, 4);
ROUND(yl, yr, 5);
ROUND(yr, yl, 6);
ROUND(yl, yr, 7);
ROUND(yr, yl, 8);
ROUND(yl, yr, 9);
ROUND(yr, yl, 10);
ROUND(yl, yr, 11);
ROUND(yr, yl, 12);
ROUND(yl, yr, 13);
ROUND(yr, yl, 14);
ROUND(yl, yr, 15);
yl ^= P[16];
yr ^= P[17];
dst[0] = yr;
dst[1] = yl;
}
static void bf_encrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32 *in_blk = (const u32 *)src;
u32 *const out_blk = (u32 *)dst;
u32 in32[2], out32[2];
in32[0] = be32_to_cpu(in_blk[0]);
in32[1] = be32_to_cpu(in_blk[1]);
encrypt_block(ctx, out32, in32);
out_blk[0] = cpu_to_be32(out32[0]);
out_blk[1] = cpu_to_be32(out32[1]);
}
static void bf_decrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32 *in_blk = (const u32 *)src;
u32 *const out_blk = (u32 *)dst;
const u32 *P = ((struct bf_ctx *)ctx)->p;
const u32 *S = ((struct bf_ctx *)ctx)->s;
u32 yl = be32_to_cpu(in_blk[0]);
u32 yr = be32_to_cpu(in_blk[1]);
ROUND(yr, yl, 17);
ROUND(yl, yr, 16);
ROUND(yr, yl, 15);
ROUND(yl, yr, 14);
ROUND(yr, yl, 13);
ROUND(yl, yr, 12);
ROUND(yr, yl, 11);
ROUND(yl, yr, 10);
ROUND(yr, yl, 9);
ROUND(yl, yr, 8);
ROUND(yr, yl, 7);
ROUND(yl, yr, 6);
ROUND(yr, yl, 5);
ROUND(yl, yr, 4);
ROUND(yr, yl, 3);
ROUND(yl, yr, 2);
yl ^= P[1];
yr ^= P[0];
out_blk[0] = cpu_to_be32(yr);
out_blk[1] = cpu_to_be32(yl);
}
/*
* Calculates the blowfish S and P boxes for encryption and decryption.
*/
static int bf_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
{
short i, j, count;
u32 data[2], temp;
u32 *P = ((struct bf_ctx *)ctx)->p;
u32 *S = ((struct bf_ctx *)ctx)->s;
/* Copy the initialization s-boxes */
for (i = 0, count = 0; i < 256; i++)
for (j = 0; j < 4; j++, count++)
S[count] = bf_sbox[count];
/* Set the p-boxes */
for (i = 0; i < 16 + 2; i++)
P[i] = bf_pbox[i];
/* Actual subkey generation */
for (j = 0, i = 0; i < 16 + 2; i++) {
temp = (((u32 )key[j] << 24) |
((u32 )key[(j + 1) % keylen] << 16) |
((u32 )key[(j + 2) % keylen] << 8) |
((u32 )key[(j + 3) % keylen]));
P[i] = P[i] ^ temp;
j = (j + 4) % keylen;
}
data[0] = 0x00000000;
data[1] = 0x00000000;
for (i = 0; i < 16 + 2; i += 2) {
encrypt_block((struct bf_ctx *)ctx, data, data);
P[i] = data[0];
P[i + 1] = data[1];
}
for (i = 0; i < 4; i++) {
for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
encrypt_block((struct bf_ctx *)ctx, data, data);
S[count] = data[0];
S[count + 1] = data[1];
}
}
/* Bruce says not to bother with the weak key check. */
return 0;
}
static struct crypto_alg alg = {
.cra_name = "blowfish",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = BF_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct bf_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = BF_MIN_KEY_SIZE,
.cia_max_keysize = BF_MAX_KEY_SIZE,
.cia_setkey = bf_setkey,
.cia_encrypt = bf_encrypt,
.cia_decrypt = bf_decrypt } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Blowfish Cipher Algorithm");

View File

@@ -0,0 +1 @@
!<arch>

View File

@@ -0,0 +1,851 @@
/* Kernel cryptographic api.
* cast5.c - Cast5 cipher algorithm (rfc2144).
*
* Derived from GnuPG implementation of cast5.
*
* Major Changes.
* Complete conformance to rfc2144.
* Supports key size from 40 to 128 bits.
*
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
* Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#define CAST5_BLOCK_SIZE 8
#define CAST5_MIN_KEY_SIZE 5
#define CAST5_MAX_KEY_SIZE 16
struct cast5_ctx {
u32 Km[16];
u8 Kr[16];
int rr; /* rr?number of rounds = 16:number of rounds = 12; (rfc 2144) */
};
static const u32 s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
static const u32 s2[256] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
0x73bfbe70, 0x83877605, 0x4523ecf1
};
static const u32 s3[256] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
0xa133c501, 0xe9d3531c, 0xee353783
};
static const u32 s4[256] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
static const u32 s5[256] = {
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff,
0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8,
0x386381cb, 0xacf6243a, 0x69befd7a,
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640,
0x15b0a848, 0xe68b18cb, 0x4caadeff,
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d,
0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7,
0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88,
0x8709e6b0, 0xd7e07156, 0x4e29fea7,
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a,
0x578535f2, 0x2261be02, 0xd642a0c9,
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8,
0xc8adedb3, 0x28a87fc9, 0x3d959981,
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1,
0x4fb96976, 0x90c79505, 0xb0a8a774,
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f,
0x0ec50966, 0xdfdd55bc, 0x29de0655,
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980,
0x524755f4, 0x03b63cc9, 0x0cc844b2,
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449,
0x64ee2d7e, 0xcddbb1da, 0x01c94910,
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6,
0x50f5b616, 0xf24766e3, 0x8eca36c1,
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9,
0x3063fcdf, 0xb6f589de, 0xec2941da,
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401,
0xc1bacb7f, 0xe5ff550f, 0xb6083049,
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd,
0x9e0885f9, 0x68cb3e47, 0x086c010f,
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3,
0xcbb3d550, 0x1793084d, 0xb0d70eba,
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56,
0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280,
0x05687715, 0x646c6bd7, 0x44904db3,
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f,
0x2cb6356a, 0x85808573, 0x4991f840,
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8,
0xc1092910, 0x8bc95fc6, 0x7d869cf4,
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717,
0x7d161bba, 0x9cad9010, 0xaf462ba2,
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e,
0x176d486f, 0x097c13ea, 0x631da5c7,
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72,
0x6e5dd2f3, 0x20936079, 0x459b80a5,
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572,
0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e,
0x75922283, 0x784d6b17, 0x58ebb16e,
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf,
0xaaf47556, 0x5f46b02a, 0x2b092801,
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874,
0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826,
0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9,
0x17e3fe2a, 0x24b79767, 0xf5a96b20,
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a,
0xeeb9491d, 0x34010718, 0xbb30cab8,
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8,
0xb1534546, 0x6d47de08, 0xefe9e7d4
};
static const u32 s6[256] = {
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7,
0x016843b4, 0xeced5cbc, 0x325553ac,
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8,
0xde5ebe39, 0xf38ff732, 0x8989b138,
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99,
0x4e23e33c, 0x79cbd7cc, 0x48a14367,
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d,
0x09a8486f, 0xa888614a, 0x2900af98,
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932,
0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c,
0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01,
0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c,
0xb88153e2, 0x08a19866, 0x1ae2eac8,
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3,
0x9aea3906, 0xefe8c36e, 0xf890cdd9,
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc,
0x221db3a6, 0x9a69a02f, 0x68818a54,
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc,
0xcf222ebf, 0x25ac6f48, 0xa9a99387,
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1,
0xe8a11be9, 0x4980740d, 0xc8087dfc,
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f,
0x9528cd89, 0xfd339fed, 0xb87834bf,
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa,
0x57f55ec5, 0xe2220abe, 0xd2916ebf,
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff,
0xa8dc8af0, 0x7345c106, 0xf41e232f,
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af,
0x692573e4, 0xe9a9d848, 0xf3160289,
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063,
0x4576698d, 0xb6fad407, 0x592af950,
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8,
0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d,
0x48b9d585, 0xdc049441, 0xc8098f9b,
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6,
0x890072d6, 0x28207682, 0xa9a9f7be,
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a,
0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a,
0xb6c85283, 0x3cc2acfb, 0x3fc06976,
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0,
0x513021a5, 0x6c5b68b7, 0x822f8aa0,
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9,
0x0c5ec241, 0x8809286c, 0xf592d891,
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98,
0xb173ecc0, 0xbc60b42a, 0x953498da,
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123,
0x257f0c3d, 0x9348af49, 0x361400bc,
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57,
0xda41e7f9, 0xc25ad33a, 0x54f4a084,
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5,
0xb6f6deaf, 0x3a479c3a, 0x5302da25,
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88,
0x44136c76, 0x0404a8c8, 0xb8e5a121,
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913,
0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1,
0xf544edeb, 0xb0e93524, 0xbebb8fbd,
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905,
0xa65b1db8, 0x851c97bd, 0xd675cf2f
};
static const u32 s7[256] = {
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f,
0xab9bc912, 0xde6008a1, 0x2028da1f,
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11,
0xb232e75c, 0x4b3695f2, 0xb28707de,
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381,
0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be,
0xbaeeadf4, 0x1286becf, 0xb6eacb19,
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66,
0x28136086, 0x0bd8dfa8, 0x356d1cf2,
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a,
0xeb12ff82, 0xe3486911, 0xd34d7516,
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce,
0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa,
0x4437f107, 0xb6e79962, 0x42d2d816,
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7,
0xf9583745, 0xcf19df58, 0xbec3f756,
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511,
0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f,
0xaff60ff4, 0xea2c4e6d, 0x16e39264,
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a,
0xb2856e6e, 0x1aec3ca9, 0xbe838688,
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85,
0x61fe033c, 0x16746233, 0x3c034c28,
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a,
0x1626a49f, 0xeed82b29, 0x1d382fe3,
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c,
0xd45230c7, 0x2bd1408b, 0x60c03eb7,
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32,
0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f,
0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0,
0x79d34217, 0x021a718d, 0x9ac6336a,
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef,
0x4eeb8476, 0x488dcf25, 0x36c9d566,
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6,
0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887,
0x2b9f4fd5, 0x625aba82, 0x6a017962,
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22,
0xe32dbf9a, 0x058745b9, 0x3453dc1e,
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1,
0x19de7eae, 0x053e561a, 0x15ad6f8c,
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0,
0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108,
0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f,
0x3d321c5d, 0xc3f5e194, 0x4b269301,
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e,
0x296693f4, 0x3d1fce6f, 0xc61e45be,
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d,
0xb5229301, 0xcfd2a87f, 0x60aeb767,
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b,
0x589dd390, 0x5479f8e6, 0x1cb8d647,
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad,
0x462e1b78, 0x6580f87e, 0xf3817914,
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc,
0x3d40f021, 0xc3c0bdae, 0x4958c24c,
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7,
0x94e01be8, 0x90716f4b, 0x954b8aa3
};
static const u32 sb8[256] = {
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7,
0xe6c1121b, 0x0e241600, 0x052ce8b5,
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c,
0x76e38111, 0xb12def3a, 0x37ddddfc,
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f,
0xb4d137cf, 0xb44e79f0, 0x049eedfd,
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831,
0x3f8f95e7, 0x72df191b, 0x7580330d,
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a,
0x02e7d1ca, 0x53571dae, 0x7a3182a2,
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022,
0xce949ad4, 0xb84769ad, 0x965bd862,
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f,
0xc28ec4b8, 0x57e8726e, 0x647a78fc,
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3,
0xae63aff2, 0x7e8bd632, 0x70108c0c,
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53,
0x06918548, 0x58cb7e07, 0x3b74ef2e,
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2,
0x19b47a38, 0x424f7618, 0x35856039,
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd,
0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c,
0x3dd00db3, 0x708f8f34, 0x77d51b42,
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e,
0x3e378160, 0x7895cda5, 0x859c15a5,
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e,
0x31842e7b, 0x24259fd7, 0xf8bef472,
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c,
0xe2506d3d, 0x4f9b12ea, 0xf215f225,
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187,
0xea7a6e98, 0x7cd16efc, 0x1436876c,
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899,
0x92ecbae6, 0xdd67016d, 0x151682eb,
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e,
0xe139673b, 0xefa63fb8, 0x71873054,
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d,
0x844a1be5, 0xbae7dfdc, 0x42cbda70,
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428,
0x79d130a4, 0x3486ebfb, 0x33d3cddc,
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4,
0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2,
0x37df932b, 0xc4248289, 0xacf3ebc3,
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e,
0x5e410fab, 0xb48a2465, 0x2eda7fa4,
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b,
0xdb485694, 0x38d7e5b2, 0x57720101,
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282,
0x7523d24a, 0xe0779695, 0xf9c17a8f,
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f,
0xad1163ed, 0xea7b5965, 0x1a00726e,
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0,
0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca,
0x8951570f, 0xdf09822b, 0xbd691a6c,
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f,
0x0d771c2b, 0x67cdb156, 0x350d8384,
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61,
0x8360d87b, 0x1fa98b0c, 0x1149382c,
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82,
0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80,
0xeaee6801, 0x8db2a283, 0xea8bf59e
};
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \
(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static void cast5_encrypt(void *ctx, u8 * outbuf, const u8 * inbuf)
{
struct cast5_ctx *c = (struct cast5_ctx *) ctx;
u32 l, r, t;
u32 I; /* used by the Fx macros */
u32 *Km;
u8 *Kr;
Km = c->Km;
Kr = c->Kr;
/* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
* right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
*/
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
* Li = Ri-1;
* Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
* Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
* Rounds 2, 5, 8, 11, and 14 use f function Type 2.
* Rounds 3, 6, 9, 12, and 15 use f function Type 3.
*/
if (!(c->rr)) {
t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
} else {
t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
}
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
* concatenate to form the ciphertext.) */
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
}
static void cast5_decrypt(void *ctx, u8 * outbuf, const u8 * inbuf)
{
struct cast5_ctx *c = (struct cast5_ctx *) ctx;
u32 l, r, t;
u32 I;
u32 *Km;
u8 *Kr;
Km = c->Km;
Kr = c->Kr;
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
if (!(c->rr)) {
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
} else {
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
}
outbuf[0] = (r >> 24) & 0xff;
outbuf[1] = (r >> 16) & 0xff;
outbuf[2] = (r >> 8) & 0xff;
outbuf[3] = r & 0xff;
outbuf[4] = (l >> 24) & 0xff;
outbuf[5] = (l >> 16) & 0xff;
outbuf[6] = (l >> 8) & 0xff;
outbuf[7] = l & 0xff;
}
static void key_schedule(u32 * x, u32 * z, u32 * k)
{
#define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
#define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
s7[xi(8)];
z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
sb8[xi(10)];
z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
s5[xi(9)];
z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
s6[xi(11)];
k[0] = s5[zi(8)] ^ s6[zi(9)] ^ s7[zi(7)] ^ sb8[zi(6)] ^ s5[zi(2)];
k[1] = s5[zi(10)] ^ s6[zi(11)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
s6[zi(6)];
k[2] = s5[zi(12)] ^ s6[zi(13)] ^ s7[zi(3)] ^ sb8[zi(2)] ^
s7[zi(9)];
k[3] = s5[zi(14)] ^ s6[zi(15)] ^ s7[zi(1)] ^ sb8[zi(0)] ^
sb8[zi(12)];
x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
s7[zi(0)];
x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
sb8[zi(2)];
x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
s5[zi(1)];
x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
s6[zi(3)];
k[4] = s5[xi(3)] ^ s6[xi(2)] ^ s7[xi(12)] ^ sb8[xi(13)] ^
s5[xi(8)];
k[5] = s5[xi(1)] ^ s6[xi(0)] ^ s7[xi(14)] ^ sb8[xi(15)] ^
s6[xi(13)];
k[6] = s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(8)] ^ sb8[xi(9)] ^ s7[xi(3)];
k[7] = s5[xi(5)] ^ s6[xi(4)] ^ s7[xi(10)] ^ sb8[xi(11)] ^
sb8[xi(7)];
z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
s7[xi(8)];
z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
sb8[xi(10)];
z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
s5[xi(9)];
z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
s6[xi(11)];
k[8] = s5[zi(3)] ^ s6[zi(2)] ^ s7[zi(12)] ^ sb8[zi(13)] ^
s5[zi(9)];
k[9] = s5[zi(1)] ^ s6[zi(0)] ^ s7[zi(14)] ^ sb8[zi(15)] ^
s6[zi(12)];
k[10] = s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(8)] ^ sb8[zi(9)] ^ s7[zi(2)];
k[11] = s5[zi(5)] ^ s6[zi(4)] ^ s7[zi(10)] ^ sb8[zi(11)] ^
sb8[zi(6)];
x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
s7[zi(0)];
x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
sb8[zi(2)];
x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
s5[zi(1)];
x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
s6[zi(3)];
k[12] = s5[xi(8)] ^ s6[xi(9)] ^ s7[xi(7)] ^ sb8[xi(6)] ^ s5[xi(3)];
k[13] = s5[xi(10)] ^ s6[xi(11)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
s6[xi(7)];
k[14] = s5[xi(12)] ^ s6[xi(13)] ^ s7[xi(3)] ^ sb8[xi(2)] ^
s7[xi(8)];
k[15] = s5[xi(14)] ^ s6[xi(15)] ^ s7[xi(1)] ^ sb8[xi(0)] ^
sb8[xi(13)];
#undef xi
#undef zi
}
static int
cast5_setkey(void *ctx, const u8 * key, unsigned key_len, u32 * flags)
{
int i;
u32 x[4];
u32 z[4];
u32 k[16];
u8 p_key[16];
struct cast5_ctx *c = (struct cast5_ctx *) ctx;
if (key_len < 5 || key_len > 16) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
c->rr = key_len <= 10 ? 1 : 0;
memset(p_key, 0, 16);
memcpy(p_key, key, key_len);
x[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3];
x[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7];
x[2] =
p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11];
x[3] =
p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15];
key_schedule(x, z, k);
for (i = 0; i < 16; i++)
c->Km[i] = k[i];
key_schedule(x, z, k);
for (i = 0; i < 16; i++)
c->Kr[i] = k[i] & 0x1f;
return 0;
}
static struct crypto_alg alg = {
.cra_name = "cast5",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAST5_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct cast5_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = CAST5_MIN_KEY_SIZE,
.cia_max_keysize = CAST5_MAX_KEY_SIZE,
.cia_setkey = cast5_setkey,
.cia_encrypt = cast5_encrypt,
.cia_decrypt = cast5_decrypt
}
}
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cast5 Cipher Algorithm");

View File

@@ -0,0 +1,562 @@
/* Kernel cryptographic api.
* cast6.c - Cast6 cipher algorithm [rfc2612].
*
* CAST-256 (*cast6*) is a DES like Substitution-Permutation Network (SPN)
* cryptosystem built upon the CAST-128 (*cast5*) [rfc2144] encryption
* algorithm.
*
* Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#define CAST6_BLOCK_SIZE 16
#define CAST6_MIN_KEY_SIZE 16
#define CAST6_MAX_KEY_SIZE 32
struct cast6_ctx {
u32 Km[12][4];
u8 Kr[12][4];
};
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
#define F1(D,r,m) ( (I = ((m) + (D))), (I=rol((r),I)), \
(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
#define F2(D,r,m) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
#define F3(D,r,m) ( (I = ((m) - (D))), (I=rol((r),I)), \
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static const u32 s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
static const u32 s2[256] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
0x73bfbe70, 0x83877605, 0x4523ecf1
};
static const u32 s3[256] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
0xa133c501, 0xe9d3531c, 0xee353783
};
static const u32 s4[256] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
static const u32 Tm[24][8] = {
{ 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
0x84c413be, 0xf39dff5f, 0x6277eb00 } ,
{ 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
{ 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
0x7262cdce, 0xe13cb96f, 0x5016a510 } ,
{ 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35,
0xe9322ad6, 0x580c1677, 0xc6e60218 } ,
{ 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d,
0x600187de, 0xcedb737f, 0x3db55f20 } ,
{ 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945,
0xd6d0e4e6, 0x45aad087, 0xb484bc28 } ,
{ 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d,
0x4da041ee, 0xbc7a2d8f, 0x2b541930 } ,
{ 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355,
0xc46f9ef6, 0x33498a97, 0xa2237638 } ,
{ 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d,
0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } ,
{ 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65,
0xb20e5906, 0x20e844a7, 0x8fc23048 } ,
{ 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d,
0x28ddb60e, 0x97b7a1af, 0x06918d50 } ,
{ 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775,
0x9fad1316, 0x0e86feb7, 0x7d60ea58 } ,
{ 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d,
0x167c701e, 0x85565bbf, 0xf4304760 } ,
{ 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185,
0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } ,
{ 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d,
0x041b2a2e, 0x72f515cf, 0xe1cf0170 } ,
{ 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95,
0x7aea8736, 0xe9c472d7, 0x589e5e78 } ,
{ 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d,
0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } ,
{ 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5,
0x68894146, 0xd7632ce7, 0x463d1888 } ,
{ 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad,
0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } ,
{ 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5,
0x5627fb56, 0xc501e6f7, 0x33dbd298 } ,
{ 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd,
0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } ,
{ 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5,
0x43c6b566, 0xb2a0a107, 0x217a8ca8 } ,
{ 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd,
0xba96126e, 0x296ffe0f, 0x9849e9b0 } ,
{ 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5,
0x31656f76, 0xa03f5b17, 0x0f1946b8 }
};
static const u8 Tr[4][8] = {
{ 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } ,
{ 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } ,
{ 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } ,
{ 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 }
};
/* forward octave */
static inline void W(u32 *key, unsigned int i) {
u32 I;
key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]);
key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);
key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
}
static int
cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags)
{
int i;
u32 key[8];
u8 p_key[32]; /* padded key */
struct cast6_ctx *c = (struct cast6_ctx *) ctx;
if (key_len < 16 || key_len > 32 || key_len % 4 != 0) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
memset (p_key, 0, 32);
memcpy (p_key, in_key, key_len);
key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; /* A */
key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; /* B */
key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; /* C */
key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; /* D */
key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19]; /* E */
key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23]; /* F */
key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27]; /* G */
key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31]; /* H */
for (i = 0; i < 12; i++) {
W (key, 2 * i);
W (key, 2 * i + 1);
c->Kr[i][0] = key[0] & 0x1f;
c->Kr[i][1] = key[2] & 0x1f;
c->Kr[i][2] = key[4] & 0x1f;
c->Kr[i][3] = key[6] & 0x1f;
c->Km[i][0] = key[7];
c->Km[i][1] = key[5];
c->Km[i][2] = key[3];
c->Km[i][3] = key[1];
}
return 0;
}
/*forward quad round*/
static inline void Q (u32 * block, u8 * Kr, u32 * Km) {
u32 I;
block[2] ^= F1(block[3], Kr[0], Km[0]);
block[1] ^= F2(block[2], Kr[1], Km[1]);
block[0] ^= F3(block[1], Kr[2], Km[2]);
block[3] ^= F1(block[0], Kr[3], Km[3]);
}
/*reverse quad round*/
static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) {
u32 I;
block[3] ^= F1(block[0], Kr[3], Km[3]);
block[0] ^= F3(block[1], Kr[2], Km[2]);
block[1] ^= F2(block[2], Kr[1], Km[1]);
block[2] ^= F1(block[3], Kr[0], Km[0]);
}
static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
struct cast6_ctx * c = (struct cast6_ctx *)ctx;
u32 block[4];
u32 * Km;
u8 * Kr;
block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km);
Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km);
Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km);
Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km);
Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km);
Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km);
Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km);
Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
outbuf[0] = (block[0] >> 24) & 0xff;
outbuf[1] = (block[0] >> 16) & 0xff;
outbuf[2] = (block[0] >> 8) & 0xff;
outbuf[3] = block[0] & 0xff;
outbuf[4] = (block[1] >> 24) & 0xff;
outbuf[5] = (block[1] >> 16) & 0xff;
outbuf[6] = (block[1] >> 8) & 0xff;
outbuf[7] = block[1] & 0xff;
outbuf[8] = (block[2] >> 24) & 0xff;
outbuf[9] = (block[2] >> 16) & 0xff;
outbuf[10] = (block[2] >> 8) & 0xff;
outbuf[11] = block[2] & 0xff;
outbuf[12] = (block[3] >> 24) & 0xff;
outbuf[13] = (block[3] >> 16) & 0xff;
outbuf[14] = (block[3] >> 8) & 0xff;
outbuf[15] = block[3] & 0xff;
}
static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
struct cast6_ctx * c = (struct cast6_ctx *)ctx;
u32 block[4];
u32 * Km;
u8 * Kr;
block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km);
Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km);
Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km);
Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km);
Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km);
Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km);
Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km);
Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km);
Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
outbuf[0] = (block[0] >> 24) & 0xff;
outbuf[1] = (block[0] >> 16) & 0xff;
outbuf[2] = (block[0] >> 8) & 0xff;
outbuf[3] = block[0] & 0xff;
outbuf[4] = (block[1] >> 24) & 0xff;
outbuf[5] = (block[1] >> 16) & 0xff;
outbuf[6] = (block[1] >> 8) & 0xff;
outbuf[7] = block[1] & 0xff;
outbuf[8] = (block[2] >> 24) & 0xff;
outbuf[9] = (block[2] >> 16) & 0xff;
outbuf[10] = (block[2] >> 8) & 0xff;
outbuf[11] = block[2] & 0xff;
outbuf[12] = (block[3] >> 24) & 0xff;
outbuf[13] = (block[3] >> 16) & 0xff;
outbuf[14] = (block[3] >> 8) & 0xff;
outbuf[15] = block[3] & 0xff;
}
static struct crypto_alg alg = {
.cra_name = "cast6",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAST6_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct cast6_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = CAST6_MIN_KEY_SIZE,
.cia_max_keysize = CAST6_MAX_KEY_SIZE,
.cia_setkey = cast6_setkey,
.cia_encrypt = cast6_encrypt,
.cia_decrypt = cast6_decrypt}
}
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cast6 Cipher Algorithm");

View File

@@ -0,0 +1,298 @@
/*
* Cryptographic API.
*
* Cipher operations.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/kernel.h>
#include <linux/crypto.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include "internal.h"
#include "scatterwalk.h"
typedef void (cryptfn_t)(void *, u8 *, const u8 *);
typedef void (procfn_t)(struct crypto_tfm *, u8 *,
u8*, cryptfn_t, int enc, void *, int);
static inline void xor_64(u8 *a, const u8 *b)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
}
static inline void xor_128(u8 *a, const u8 *b)
{
((u32 *)a)[0] ^= ((u32 *)b)[0];
((u32 *)a)[1] ^= ((u32 *)b)[1];
((u32 *)a)[2] ^= ((u32 *)b)[2];
((u32 *)a)[3] ^= ((u32 *)b)[3];
}
/*
* Generic encrypt/decrypt wrapper for ciphers, handles operations across
* multiple page boundaries by using temporary blocks. In user context,
* the kernel is given a chance to schedule us once per block.
*/
static int crypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, cryptfn_t crfn,
procfn_t prfn, int enc, void *info)
{
struct scatter_walk walk_in, walk_out;
const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
u8 tmp_src[bsize];
u8 tmp_dst[bsize];
if (!nbytes)
return 0;
if (nbytes % bsize) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
return -EINVAL;
}
scatterwalk_start(&walk_in, src);
scatterwalk_start(&walk_out, dst);
for(;;) {
u8 *src_p, *dst_p;
int in_place;
scatterwalk_map(&walk_in, 0);
scatterwalk_map(&walk_out, 1);
src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
in_place = scatterwalk_samebuf(&walk_in, &walk_out,
src_p, dst_p);
nbytes -= bsize;
scatterwalk_copychunks(src_p, &walk_in, bsize, 0);
prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
scatterwalk_done(&walk_in, 0, nbytes);
scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
scatterwalk_done(&walk_out, 1, nbytes);
if (!nbytes)
return 0;
crypto_yield(tfm);
}
}
static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
cryptfn_t fn, int enc, void *info, int in_place)
{
u8 *iv = info;
/* Null encryption */
if (!iv)
return;
if (enc) {
tfm->crt_u.cipher.cit_xor_block(iv, src);
fn(crypto_tfm_ctx(tfm), dst, iv);
memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
} else {
u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0];
u8 *buf = in_place ? stack : dst;
fn(crypto_tfm_ctx(tfm), buf, src);
tfm->crt_u.cipher.cit_xor_block(buf, iv);
memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
if (buf != dst)
memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
}
}
static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
cryptfn_t fn, int enc, void *info, int in_place)
{
fn(crypto_tfm_ctx(tfm), dst, src);
}
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
{
struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
} else
return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
&tfm->crt_flags);
}
static int ecb_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src, unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_encrypt,
ecb_process, 1, NULL);
}
static int ecb_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_decrypt,
ecb_process, 1, NULL);
}
static int cbc_encrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_encrypt,
cbc_process, 1, tfm->crt_cipher.cit_iv);
}
static int cbc_encrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_encrypt,
cbc_process, 1, iv);
}
static int cbc_decrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_decrypt,
cbc_process, 0, tfm->crt_cipher.cit_iv);
}
static int cbc_decrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
return crypt(tfm, dst, src, nbytes,
tfm->__crt_alg->cra_cipher.cia_decrypt,
cbc_process, 0, iv);
}
static int nocrypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return -ENOSYS;
}
static int nocrypt_iv(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes, u8 *iv)
{
return -ENOSYS;
}
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
{
u32 mode = flags & CRYPTO_TFM_MODE_MASK;
tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
return 0;
}
int crypto_init_cipher_ops(struct crypto_tfm *tfm)
{
int ret = 0;
struct cipher_tfm *ops = &tfm->crt_cipher;
ops->cit_setkey = setkey;
switch (tfm->crt_cipher.cit_mode) {
case CRYPTO_TFM_MODE_ECB:
ops->cit_encrypt = ecb_encrypt;
ops->cit_decrypt = ecb_decrypt;
break;
case CRYPTO_TFM_MODE_CBC:
ops->cit_encrypt = cbc_encrypt;
ops->cit_decrypt = cbc_decrypt;
ops->cit_encrypt_iv = cbc_encrypt_iv;
ops->cit_decrypt_iv = cbc_decrypt_iv;
break;
case CRYPTO_TFM_MODE_CFB:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
ops->cit_encrypt_iv = nocrypt_iv;
ops->cit_decrypt_iv = nocrypt_iv;
break;
case CRYPTO_TFM_MODE_CTR:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
ops->cit_encrypt_iv = nocrypt_iv;
ops->cit_decrypt_iv = nocrypt_iv;
break;
default:
BUG();
}
if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
switch (crypto_tfm_alg_blocksize(tfm)) {
case 8:
ops->cit_xor_block = xor_64;
break;
case 16:
ops->cit_xor_block = xor_128;
break;
default:
printk(KERN_WARNING "%s: block size %u not supported\n",
crypto_tfm_alg_name(tfm),
crypto_tfm_alg_blocksize(tfm));
ret = -EINVAL;
goto out;
}
ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
if (ops->cit_iv == NULL)
ret = -ENOMEM;
}
out:
return ret;
}
void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
{
if (tfm->crt_cipher.cit_iv)
kfree(tfm->crt_cipher.cit_iv);
}

View File

@@ -0,0 +1,63 @@
/*
* Cryptographic API.
*
* Compression operations.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/types.h>
#include <linux/crypto.h>
#include <linux/errno.h>
#include <asm/scatterlist.h>
#include <linux/string.h>
#include "internal.h"
static int crypto_compress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
src, slen, dst,
dlen);
}
static int crypto_decompress(struct crypto_tfm *tfm,
const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
src, slen, dst,
dlen);
}
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
{
return flags ? -EINVAL : 0;
}
int crypto_init_compress_ops(struct crypto_tfm *tfm)
{
int ret = 0;
struct compress_tfm *ops = &tfm->crt_compress;
ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
if (ret)
goto out;
ops->cot_compress = crypto_compress;
ops->cot_decompress = crypto_decompress;
out:
return ret;
}
void crypto_exit_compress_ops(struct crypto_tfm *tfm)
{
tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
}

View File

@@ -0,0 +1,110 @@
/*
* Cryptographic API.
*
* CRC32C chksum
*
* This module file is a wrapper to invoke the lib/crc32c routines.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/crc32c.h>
#include <asm/byteorder.h>
#define CHKSUM_BLOCK_SIZE 32
#define CHKSUM_DIGEST_SIZE 4
struct chksum_ctx {
u32 crc;
};
/*
* Steps through buffer one byte at at time, calculates reflected
* crc using table.
*/
static void chksum_init(void *ctx)
{
struct chksum_ctx *mctx = ctx;
mctx->crc = ~(u32)0; /* common usage */
}
/*
* Setting the seed allows arbitrary accumulators and flexible XOR policy
* If your algorithm starts with ~0, then XOR with ~0 before you set
* the seed.
*/
static int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen,
u32 *flags)
{
struct chksum_ctx *mctx = ctx;
if (keylen != sizeof(mctx->crc)) {
if (flags)
*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
mctx->crc = __cpu_to_le32(*(u32 *)key);
return 0;
}
static void chksum_update(void *ctx, const u8 *data, unsigned int length)
{
struct chksum_ctx *mctx = ctx;
u32 mcrc;
mcrc = crc32c(mctx->crc, data, (size_t)length);
mctx->crc = mcrc;
}
static void chksum_final(void *ctx, u8 *out)
{
struct chksum_ctx *mctx = ctx;
u32 mcrc = (mctx->crc ^ ~(u32)0);
*(u32 *)out = __le32_to_cpu(mcrc);
}
static struct crypto_alg alg = {
.cra_name = "crc32c",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = CHKSUM_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct chksum_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.digest = {
.dia_digestsize= CHKSUM_DIGEST_SIZE,
.dia_setkey = chksum_setkey,
.dia_init = chksum_init,
.dia_update = chksum_update,
.dia_final = chksum_final
}
}
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,137 @@
/*
* Cryptographic API.
*
* Null algorithms, aka Much Ado About Nothing.
*
* These are needed for IPsec, and may be useful in general for
* testing & debugging.
*
* The null cipher is compliant with RFC2410.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#define NULL_KEY_SIZE 0
#define NULL_BLOCK_SIZE 1
#define NULL_DIGEST_SIZE 0
static int null_compress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{ return 0; }
static int null_decompress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{ return 0; }
static void null_init(void *ctx)
{ }
static void null_update(void *ctx, const u8 *data, unsigned int len)
{ }
static void null_final(void *ctx, u8 *out)
{ }
static int null_setkey(void *ctx, const u8 *key,
unsigned int keylen, u32 *flags)
{ return 0; }
static void null_encrypt(void *ctx, u8 *dst, const u8 *src)
{ }
static void null_decrypt(void *ctx, u8 *dst, const u8 *src)
{ }
static struct crypto_alg compress_null = {
.cra_name = "compress_null",
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
.cra_blocksize = NULL_BLOCK_SIZE,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(compress_null.cra_list),
.cra_u = { .compress = {
.coa_compress = null_compress,
.coa_decompress = null_decompress } }
};
static struct crypto_alg digest_null = {
.cra_name = "digest_null",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = NULL_BLOCK_SIZE,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(digest_null.cra_list),
.cra_u = { .digest = {
.dia_digestsize = NULL_DIGEST_SIZE,
.dia_init = null_init,
.dia_update = null_update,
.dia_final = null_final } }
};
static struct crypto_alg cipher_null = {
.cra_name = "cipher_null",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = NULL_BLOCK_SIZE,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(cipher_null.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = NULL_KEY_SIZE,
.cia_max_keysize = NULL_KEY_SIZE,
.cia_setkey = null_setkey,
.cia_encrypt = null_encrypt,
.cia_decrypt = null_decrypt } }
};
MODULE_ALIAS("compress_null");
MODULE_ALIAS("digest_null");
MODULE_ALIAS("cipher_null");
static int __init init(void)
{
int ret = 0;
ret = crypto_register_alg(&cipher_null);
if (ret < 0)
goto out;
ret = crypto_register_alg(&digest_null);
if (ret < 0) {
crypto_unregister_alg(&cipher_null);
goto out;
}
ret = crypto_register_alg(&compress_null);
if (ret < 0) {
crypto_unregister_alg(&digest_null);
crypto_unregister_alg(&cipher_null);
goto out;
}
out:
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&compress_null);
crypto_unregister_alg(&digest_null);
crypto_unregister_alg(&cipher_null);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Null Cryptographic Algorithms");

View File

@@ -0,0 +1,223 @@
/*
* Cryptographic API.
*
* Deflate algorithm (RFC 1951), implemented here primarily for use
* by IPCOMP (RFC 3173 & RFC 2394).
*
* Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* FIXME: deflate transforms will require up to a total of about 436k of kernel
* memory on i386 (390k for compression, the rest for decompression), as the
* current zlib kernel code uses a worst case pre-allocation system by default.
* This needs to be fixed so that the amount of memory required is properly
* related to the winbits and memlevel parameters.
*
* The default winbits of 11 should suit most packets, and it may be something
* to configure on a per-tfm basis in the future.
*
* Currently, compression history is not maintained between tfm calls, as
* it is not needed for IPCOMP and keeps the code simpler. It can be
* implemented if someone wants it.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/zlib.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/slab.h>
#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
#define DEFLATE_DEF_WINBITS 11
#define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
struct deflate_ctx {
struct z_stream_s comp_stream;
struct z_stream_s decomp_stream;
};
static int deflate_comp_init(struct deflate_ctx *ctx)
{
int ret = 0;
struct z_stream_s *stream = &ctx->comp_stream;
stream->workspace = vmalloc(zlib_deflate_workspacesize());
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
memset(stream->workspace, 0, zlib_deflate_workspacesize());
ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK) {
ret = -EINVAL;
goto out_free;
}
out:
return ret;
out_free:
vfree(stream->workspace);
goto out;
}
static int deflate_decomp_init(struct deflate_ctx *ctx)
{
int ret = 0;
struct z_stream_s *stream = &ctx->decomp_stream;
stream->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
memset(stream->workspace, 0, zlib_inflate_workspacesize());
ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
if (ret != Z_OK) {
ret = -EINVAL;
goto out_free;
}
out:
return ret;
out_free:
kfree(stream->workspace);
goto out;
}
static void deflate_comp_exit(struct deflate_ctx *ctx)
{
vfree(ctx->comp_stream.workspace);
}
static void deflate_decomp_exit(struct deflate_ctx *ctx)
{
kfree(ctx->decomp_stream.workspace);
}
static int deflate_init(void *ctx)
{
int ret;
ret = deflate_comp_init(ctx);
if (ret)
goto out;
ret = deflate_decomp_init(ctx);
if (ret)
deflate_comp_exit(ctx);
out:
return ret;
}
static void deflate_exit(void *ctx)
{
deflate_comp_exit(ctx);
deflate_decomp_exit(ctx);
}
static int deflate_compress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
int ret = 0;
struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->comp_stream;
ret = zlib_deflateReset(stream);
if (ret != Z_OK) {
ret = -EINVAL;
goto out;
}
stream->next_in = (u8 *)src;
stream->avail_in = slen;
stream->next_out = (u8 *)dst;
stream->avail_out = *dlen;
ret = zlib_deflate(stream, Z_FINISH);
if (ret != Z_STREAM_END) {
ret = -EINVAL;
goto out;
}
ret = 0;
*dlen = stream->total_out;
out:
return ret;
}
static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen,
u8 *dst, unsigned int *dlen)
{
int ret = 0;
struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->decomp_stream;
ret = zlib_inflateReset(stream);
if (ret != Z_OK) {
ret = -EINVAL;
goto out;
}
stream->next_in = (u8 *)src;
stream->avail_in = slen;
stream->next_out = (u8 *)dst;
stream->avail_out = *dlen;
ret = zlib_inflate(stream, Z_SYNC_FLUSH);
/*
* Work around a bug in zlib, which sometimes wants to taste an extra
* byte when being used in the (undocumented) raw deflate mode.
* (From USAGI).
*/
if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
u8 zerostuff = 0;
stream->next_in = &zerostuff;
stream->avail_in = 1;
ret = zlib_inflate(stream, Z_FINISH);
}
if (ret != Z_STREAM_END) {
ret = -EINVAL;
goto out;
}
ret = 0;
*dlen = stream->total_out;
out:
return ret;
}
static struct crypto_alg alg = {
.cra_name = "deflate",
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
.cra_ctxsize = sizeof(struct deflate_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .compress = {
.coa_init = deflate_init,
.coa_exit = deflate_exit,
.coa_compress = deflate_compress,
.coa_decompress = deflate_decompress } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
/*
* Cryptographic API.
*
* Digest operations.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/crypto.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/highmem.h>
#include <asm/scatterlist.h>
#include "internal.h"
static void init(struct crypto_tfm *tfm)
{
tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
}
static void update(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg)
{
unsigned int i;
for (i = 0; i < nsg; i++) {
struct page *pg = sg[i].page;
unsigned int offset = sg[i].offset;
unsigned int l = sg[i].length;
do {
unsigned int bytes_from_page = min(l, ((unsigned int)
(PAGE_SIZE)) -
offset);
char *p = crypto_kmap(pg, 0) + offset;
tfm->__crt_alg->cra_digest.dia_update
(crypto_tfm_ctx(tfm), p,
bytes_from_page);
crypto_kunmap(p, 0);
crypto_yield(tfm);
offset = 0;
pg++;
l -= bytes_from_page;
} while (l > 0);
}
}
static void final(struct crypto_tfm *tfm, u8 *out)
{
tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
}
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
{
u32 flags;
if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
return -ENOSYS;
return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
key, keylen, &flags);
}
static void digest(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg, u8 *out)
{
unsigned int i;
tfm->crt_digest.dit_init(tfm);
for (i = 0; i < nsg; i++) {
char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
p, sg[i].length);
crypto_kunmap(p, 0);
crypto_yield(tfm);
}
crypto_digest_final(tfm, out);
}
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
{
return flags ? -EINVAL : 0;
}
int crypto_init_digest_ops(struct crypto_tfm *tfm)
{
struct digest_tfm *ops = &tfm->crt_digest;
ops->dit_init = init;
ops->dit_update = update;
ops->dit_final = final;
ops->dit_digest = digest;
ops->dit_setkey = setkey;
return crypto_alloc_hmac_block(tfm);
}
void crypto_exit_digest_ops(struct crypto_tfm *tfm)
{
crypto_free_hmac_block(tfm);
}

View File

@@ -0,0 +1,134 @@
/*
* Cryptographic API.
*
* HMAC: Keyed-Hashing for Message Authentication (RFC2104).
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* The HMAC implementation is derived from USAGI.
* Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/crypto.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include "internal.h"
static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
{
struct scatterlist tmp;
tmp.page = virt_to_page(key);
tmp.offset = offset_in_page(key);
tmp.length = keylen;
crypto_digest_digest(tfm, &tmp, 1, key);
}
int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
{
int ret = 0;
BUG_ON(!crypto_tfm_alg_blocksize(tfm));
tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
GFP_KERNEL);
if (tfm->crt_digest.dit_hmac_block == NULL)
ret = -ENOMEM;
return ret;
}
void crypto_free_hmac_block(struct crypto_tfm *tfm)
{
if (tfm->crt_digest.dit_hmac_block)
kfree(tfm->crt_digest.dit_hmac_block);
}
void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
{
unsigned int i;
struct scatterlist tmp;
char *ipad = tfm->crt_digest.dit_hmac_block;
if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
*keylen = crypto_tfm_alg_digestsize(tfm);
}
memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
memcpy(ipad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
ipad[i] ^= 0x36;
tmp.page = virt_to_page(ipad);
tmp.offset = offset_in_page(ipad);
tmp.length = crypto_tfm_alg_blocksize(tfm);
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
}
void crypto_hmac_update(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg)
{
crypto_digest_update(tfm, sg, nsg);
}
void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
unsigned int *keylen, u8 *out)
{
unsigned int i;
struct scatterlist tmp;
char *opad = tfm->crt_digest.dit_hmac_block;
if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
*keylen = crypto_tfm_alg_digestsize(tfm);
}
crypto_digest_final(tfm, out);
memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
memcpy(opad, key, *keylen);
for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
opad[i] ^= 0x5c;
tmp.page = virt_to_page(opad);
tmp.offset = offset_in_page(opad);
tmp.length = crypto_tfm_alg_blocksize(tfm);
crypto_digest_init(tfm);
crypto_digest_update(tfm, &tmp, 1);
tmp.page = virt_to_page(out);
tmp.offset = offset_in_page(out);
tmp.length = crypto_tfm_alg_digestsize(tfm);
crypto_digest_update(tfm, &tmp, 1);
crypto_digest_final(tfm, out);
}
void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
struct scatterlist *sg, unsigned int nsg, u8 *out)
{
crypto_hmac_init(tfm, key, keylen);
crypto_hmac_update(tfm, sg, nsg);
crypto_hmac_final(tfm, key, keylen, out);
}
EXPORT_SYMBOL_GPL(crypto_hmac_init);
EXPORT_SYMBOL_GPL(crypto_hmac_update);
EXPORT_SYMBOL_GPL(crypto_hmac_final);
EXPORT_SYMBOL_GPL(crypto_hmac);

View File

@@ -0,0 +1,92 @@
/*
* Cryptographic API.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
#ifndef _CRYPTO_INTERNAL_H
#define _CRYPTO_INTERNAL_H
#include <linux/crypto.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <asm/kmap_types.h>
extern enum km_type crypto_km_types[];
static inline enum km_type crypto_kmap_type(int out)
{
return crypto_km_types[(in_softirq() ? 2 : 0) + out];
}
static inline void *crypto_kmap(struct page *page, int out)
{
return kmap_atomic(page, crypto_kmap_type(out));
}
static inline void crypto_kunmap(void *vaddr, int out)
{
kunmap_atomic(vaddr, crypto_kmap_type(out));
}
static inline void crypto_yield(struct crypto_tfm *tfm)
{
if (!in_softirq())
cond_resched();
}
static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
{
return (void *)&tfm[1];
}
struct crypto_alg *crypto_alg_lookup(const char *name);
/* A far more intelligent version of this is planned. For now, just
* try an exact match on the name of the algorithm. */
static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
{
return try_then_request_module(crypto_alg_lookup(name), name);
}
#ifdef CONFIG_CRYPTO_HMAC
int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
void crypto_free_hmac_block(struct crypto_tfm *tfm);
#else
static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
{
return 0;
}
static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
{ }
#endif
#ifdef CONFIG_PROC_FS
void __init crypto_init_proc(void);
#else
static inline void crypto_init_proc(void)
{ }
#endif
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_digest_ops(struct crypto_tfm *tfm);
int crypto_init_cipher_ops(struct crypto_tfm *tfm);
int crypto_init_compress_ops(struct crypto_tfm *tfm);
void crypto_exit_digest_ops(struct crypto_tfm *tfm);
void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
void crypto_exit_compress_ops(struct crypto_tfm *tfm);
#endif /* _CRYPTO_INTERNAL_H */

View File

@@ -0,0 +1,915 @@
/*
* Cryptographic API.
*
* Khazad Algorithm
*
* The Khazad algorithm was developed by Paulo S. L. M. Barreto and
* Vincent Rijmen. It was a finalist in the NESSIE encryption contest.
*
* The original authors have disclaimed all copyright interest in this
* code and thus put it in the public domain. The subsequent authors
* have put this under the GNU General Public License.
*
* By Aaron Grothe ajgrothe@yahoo.com, August 1, 2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#define KHAZAD_KEY_SIZE 16
#define KHAZAD_BLOCK_SIZE 8
#define KHAZAD_ROUNDS 8
struct khazad_ctx {
u64 E[KHAZAD_ROUNDS + 1];
u64 D[KHAZAD_ROUNDS + 1];
};
static const u64 T0[256] = {
0xbad3d268bbb96a01ULL, 0x54fc4d19e59a66b1ULL, 0x2f71bc93e26514cdULL,
0x749ccdb925871b51ULL, 0x53f55102f7a257a4ULL, 0xd3686bb8d0d6be03ULL,
0xd26b6fbdd6deb504ULL, 0x4dd72964b35285feULL, 0x50f05d0dfdba4aadULL,
0xace98a26cf09e063ULL, 0x8d8a0e83091c9684ULL, 0xbfdcc679a5914d1aULL,
0x7090ddad3da7374dULL, 0x52f65507f1aa5ca3ULL, 0x9ab352c87ba417e1ULL,
0x4cd42d61b55a8ef9ULL, 0xea238f65460320acULL, 0xd56273a6c4e68411ULL,
0x97a466f155cc68c2ULL, 0xd16e63b2dcc6a80dULL, 0x3355ccffaa85d099ULL,
0x51f35908fbb241aaULL, 0x5bed712ac7e20f9cULL, 0xa6f7a204f359ae55ULL,
0xde7f5f81febec120ULL, 0x48d83d75ad7aa2e5ULL, 0xa8e59a32d729cc7fULL,
0x99b65ec771bc0ae8ULL, 0xdb704b90e096e63bULL, 0x3256c8faac8ddb9eULL,
0xb7c4e65195d11522ULL, 0xfc19d72b32b3aaceULL, 0xe338ab48704b7393ULL,
0x9ebf42dc63843bfdULL, 0x91ae7eef41fc52d0ULL, 0x9bb056cd7dac1ce6ULL,
0xe23baf4d76437894ULL, 0xbbd0d66dbdb16106ULL, 0x41c319589b32f1daULL,
0x6eb2a5cb7957e517ULL, 0xa5f2ae0bf941b35cULL, 0xcb400bc08016564bULL,
0x6bbdb1da677fc20cULL, 0x95a26efb59dc7eccULL, 0xa1febe1fe1619f40ULL,
0xf308eb1810cbc3e3ULL, 0xb1cefe4f81e12f30ULL, 0x0206080a0c10160eULL,
0xcc4917db922e675eULL, 0xc45137f3a26e3f66ULL, 0x1d2774694ee8cf53ULL,
0x143c504478a09c6cULL, 0xc3582be8b0560e73ULL, 0x63a591f2573f9a34ULL,
0xda734f95e69eed3cULL, 0x5de76934d3d2358eULL, 0x5fe1613edfc22380ULL,
0xdc79578bf2aed72eULL, 0x7d87e99413cf486eULL, 0xcd4a13de94266c59ULL,
0x7f81e19e1fdf5e60ULL, 0x5aee752fc1ea049bULL, 0x6cb4adc17547f319ULL,
0x5ce46d31d5da3e89ULL, 0xf704fb0c08ebefffULL, 0x266a98bed42d47f2ULL,
0xff1cdb2438abb7c7ULL, 0xed2a937e543b11b9ULL, 0xe825876f4a1336a2ULL,
0x9dba4ed3699c26f4ULL, 0x6fb1a1ce7f5fee10ULL, 0x8e8f028c03048b8dULL,
0x192b647d56c8e34fULL, 0xa0fdba1ae7699447ULL, 0xf00de7171ad3deeaULL,
0x89861e97113cba98ULL, 0x0f113c332278692dULL, 0x07091c1b12383115ULL,
0xafec8629c511fd6aULL, 0xfb10cb30208b9bdbULL, 0x0818202830405838ULL,
0x153f54417ea8976bULL, 0x0d1734392e687f23ULL, 0x040c101418202c1cULL,
0x0103040506080b07ULL, 0x64ac8de94507ab21ULL, 0xdf7c5b84f8b6ca27ULL,
0x769ac5b329970d5fULL, 0x798bf9800bef6472ULL, 0xdd7a538ef4a6dc29ULL,
0x3d47f4c98ef5b2b3ULL, 0x163a584e74b08a62ULL, 0x3f41fcc382e5a4bdULL,
0x3759dcebb2a5fc85ULL, 0x6db7a9c4734ff81eULL, 0x3848e0d890dd95a8ULL,
0xb9d6de67b1a17708ULL, 0x7395d1a237bf2a44ULL, 0xe926836a4c1b3da5ULL,
0x355fd4e1beb5ea8bULL, 0x55ff491ce3926db6ULL, 0x7193d9a83baf3c4aULL,
0x7b8df18a07ff727cULL, 0x8c890a860f149d83ULL, 0x7296d5a731b72143ULL,
0x88851a921734b19fULL, 0xf607ff090ee3e4f8ULL, 0x2a7ea882fc4d33d6ULL,
0x3e42f8c684edafbaULL, 0x5ee2653bd9ca2887ULL, 0x27699cbbd2254cf5ULL,
0x46ca0543890ac0cfULL, 0x0c14303c28607424ULL, 0x65af89ec430fa026ULL,
0x68b8bdd56d67df05ULL, 0x61a399f85b2f8c3aULL, 0x03050c0f0a181d09ULL,
0xc15e23e2bc46187dULL, 0x57f94116ef827bb8ULL, 0xd6677fa9cefe9918ULL,
0xd976439aec86f035ULL, 0x58e87d25cdfa1295ULL, 0xd875479fea8efb32ULL,
0x66aa85e34917bd2fULL, 0xd7647bacc8f6921fULL, 0x3a4ee8d29ccd83a6ULL,
0xc84507cf8a0e4b42ULL, 0x3c44f0cc88fdb9b4ULL, 0xfa13cf35268390dcULL,
0x96a762f453c463c5ULL, 0xa7f4a601f551a552ULL, 0x98b55ac277b401efULL,
0xec29977b52331abeULL, 0xb8d5da62b7a97c0fULL, 0xc7543bfca876226fULL,
0xaeef822cc319f66dULL, 0x69bbb9d06b6fd402ULL, 0x4bdd317aa762bfecULL,
0xabe0963ddd31d176ULL, 0xa9e69e37d121c778ULL, 0x67a981e64f1fb628ULL,
0x0a1e28223c504e36ULL, 0x47c901468f02cbc8ULL, 0xf20bef1d16c3c8e4ULL,
0xb5c2ee5b99c1032cULL, 0x226688aacc0d6beeULL, 0xe532b356647b4981ULL,
0xee2f9f715e230cb0ULL, 0xbedfc27ca399461dULL, 0x2b7dac87fa4538d1ULL,
0x819e3ebf217ce2a0ULL, 0x1236485a6c90a67eULL, 0x839836b52d6cf4aeULL,
0x1b2d6c775ad8f541ULL, 0x0e1238362470622aULL, 0x23658cafca0560e9ULL,
0xf502f30604fbf9f1ULL, 0x45cf094c8312ddc6ULL, 0x216384a5c61576e7ULL,
0xce4f1fd19e3e7150ULL, 0x49db3970ab72a9e2ULL, 0x2c74b09ce87d09c4ULL,
0xf916c33a2c9b8dd5ULL, 0xe637bf596e635488ULL, 0xb6c7e25493d91e25ULL,
0x2878a088f05d25d8ULL, 0x17395c4b72b88165ULL, 0x829b32b02b64ffa9ULL,
0x1a2e68725cd0fe46ULL, 0x8b80169d1d2cac96ULL, 0xfe1fdf213ea3bcc0ULL,
0x8a8312981b24a791ULL, 0x091b242d3648533fULL, 0xc94603ca8c064045ULL,
0x879426a1354cd8b2ULL, 0x4ed2256bb94a98f7ULL, 0xe13ea3427c5b659dULL,
0x2e72b896e46d1fcaULL, 0xe431b75362734286ULL, 0xe03da7477a536e9aULL,
0xeb208b60400b2babULL, 0x90ad7aea47f459d7ULL, 0xa4f1aa0eff49b85bULL,
0x1e22786644f0d25aULL, 0x85922eab395ccebcULL, 0x60a09dfd5d27873dULL,
0x0000000000000000ULL, 0x256f94b1de355afbULL, 0xf401f70302f3f2f6ULL,
0xf10ee3121cdbd5edULL, 0x94a16afe5fd475cbULL, 0x0b1d2c273a584531ULL,
0xe734bb5c686b5f8fULL, 0x759fc9bc238f1056ULL, 0xef2c9b74582b07b7ULL,
0x345cd0e4b8bde18cULL, 0x3153c4f5a695c697ULL, 0xd46177a3c2ee8f16ULL,
0xd06d67b7dacea30aULL, 0x869722a43344d3b5ULL, 0x7e82e59b19d75567ULL,
0xadea8e23c901eb64ULL, 0xfd1ad32e34bba1c9ULL, 0x297ba48df6552edfULL,
0x3050c0f0a09dcd90ULL, 0x3b4decd79ac588a1ULL, 0x9fbc46d9658c30faULL,
0xf815c73f2a9386d2ULL, 0xc6573ff9ae7e2968ULL, 0x13354c5f6a98ad79ULL,
0x060a181e14303a12ULL, 0x050f14111e28271bULL, 0xc55233f6a4663461ULL,
0x113344556688bb77ULL, 0x7799c1b62f9f0658ULL, 0x7c84ed9115c74369ULL,
0x7a8ef58f01f7797bULL, 0x7888fd850de76f75ULL, 0x365ad8eeb4adf782ULL,
0x1c24706c48e0c454ULL, 0x394be4dd96d59eafULL, 0x59eb7920cbf21992ULL,
0x1828607850c0e848ULL, 0x56fa4513e98a70bfULL, 0xb3c8f6458df1393eULL,
0xb0cdfa4a87e92437ULL, 0x246c90b4d83d51fcULL, 0x206080a0c01d7de0ULL,
0xb2cbf2408bf93239ULL, 0x92ab72e04be44fd9ULL, 0xa3f8b615ed71894eULL,
0xc05d27e7ba4e137aULL, 0x44cc0d49851ad6c1ULL, 0x62a695f751379133ULL,
0x103040506080b070ULL, 0xb4c1ea5e9fc9082bULL, 0x84912aae3f54c5bbULL,
0x43c511529722e7d4ULL, 0x93a876e54dec44deULL, 0xc25b2fedb65e0574ULL,
0x4ade357fa16ab4ebULL, 0xbddace73a9815b14ULL, 0x8f8c0689050c808aULL,
0x2d77b499ee7502c3ULL, 0xbcd9ca76af895013ULL, 0x9cb94ad66f942df3ULL,
0x6abeb5df6177c90bULL, 0x40c01d5d9d3afaddULL, 0xcf4c1bd498367a57ULL,
0xa2fbb210eb798249ULL, 0x809d3aba2774e9a7ULL, 0x4fd1216ebf4293f0ULL,
0x1f217c6342f8d95dULL, 0xca430fc5861e5d4cULL, 0xaae39238db39da71ULL,
0x42c61557912aecd3ULL
};
static const u64 T1[256] = {
0xd3ba68d2b9bb016aULL, 0xfc54194d9ae5b166ULL, 0x712f93bc65e2cd14ULL,
0x9c74b9cd8725511bULL, 0xf5530251a2f7a457ULL, 0x68d3b86bd6d003beULL,
0x6bd2bd6fded604b5ULL, 0xd74d642952b3fe85ULL, 0xf0500d5dbafdad4aULL,
0xe9ac268a09cf63e0ULL, 0x8a8d830e1c098496ULL, 0xdcbf79c691a51a4dULL,
0x9070addda73d4d37ULL, 0xf6520755aaf1a35cULL, 0xb39ac852a47be117ULL,
0xd44c612d5ab5f98eULL, 0x23ea658f0346ac20ULL, 0x62d5a673e6c41184ULL,
0xa497f166cc55c268ULL, 0x6ed1b263c6dc0da8ULL, 0x5533ffcc85aa99d0ULL,
0xf3510859b2fbaa41ULL, 0xed5b2a71e2c79c0fULL, 0xf7a604a259f355aeULL,
0x7fde815fbefe20c1ULL, 0xd848753d7aade5a2ULL, 0xe5a8329a29d77fccULL,
0xb699c75ebc71e80aULL, 0x70db904b96e03be6ULL, 0x5632fac88dac9edbULL,
0xc4b751e6d1952215ULL, 0x19fc2bd7b332ceaaULL, 0x38e348ab4b709373ULL,
0xbf9edc428463fd3bULL, 0xae91ef7efc41d052ULL, 0xb09bcd56ac7de61cULL,
0x3be24daf43769478ULL, 0xd0bb6dd6b1bd0661ULL, 0xc3415819329bdaf1ULL,
0xb26ecba5577917e5ULL, 0xf2a50bae41f95cb3ULL, 0x40cbc00b16804b56ULL,
0xbd6bdab17f670cc2ULL, 0xa295fb6edc59cc7eULL, 0xfea11fbe61e1409fULL,
0x08f318ebcb10e3c3ULL, 0xceb14ffee181302fULL, 0x06020a08100c0e16ULL,
0x49ccdb172e925e67ULL, 0x51c4f3376ea2663fULL, 0x271d6974e84e53cfULL,
0x3c144450a0786c9cULL, 0x58c3e82b56b0730eULL, 0xa563f2913f57349aULL,
0x73da954f9ee63cedULL, 0xe75d3469d2d38e35ULL, 0xe15f3e61c2df8023ULL,
0x79dc8b57aef22ed7ULL, 0x877d94e9cf136e48ULL, 0x4acdde132694596cULL,
0x817f9ee1df1f605eULL, 0xee5a2f75eac19b04ULL, 0xb46cc1ad477519f3ULL,
0xe45c316ddad5893eULL, 0x04f70cfbeb08ffefULL, 0x6a26be982dd4f247ULL,
0x1cff24dbab38c7b7ULL, 0x2aed7e933b54b911ULL, 0x25e86f87134aa236ULL,
0xba9dd34e9c69f426ULL, 0xb16fcea15f7f10eeULL, 0x8f8e8c0204038d8bULL,
0x2b197d64c8564fe3ULL, 0xfda01aba69e74794ULL, 0x0df017e7d31aeadeULL,
0x8689971e3c1198baULL, 0x110f333c78222d69ULL, 0x09071b1c38121531ULL,
0xecaf298611c56afdULL, 0x10fb30cb8b20db9bULL, 0x1808282040303858ULL,
0x3f154154a87e6b97ULL, 0x170d3934682e237fULL, 0x0c04141020181c2cULL,
0x030105040806070bULL, 0xac64e98d074521abULL, 0x7cdf845bb6f827caULL,
0x9a76b3c597295f0dULL, 0x8b7980f9ef0b7264ULL, 0x7add8e53a6f429dcULL,
0x473dc9f4f58eb3b2ULL, 0x3a164e58b074628aULL, 0x413fc3fce582bda4ULL,
0x5937ebdca5b285fcULL, 0xb76dc4a94f731ef8ULL, 0x4838d8e0dd90a895ULL,
0xd6b967dea1b10877ULL, 0x9573a2d1bf37442aULL, 0x26e96a831b4ca53dULL,
0x5f35e1d4b5be8beaULL, 0xff551c4992e3b66dULL, 0x9371a8d9af3b4a3cULL,
0x8d7b8af1ff077c72ULL, 0x898c860a140f839dULL, 0x9672a7d5b7314321ULL,
0x8588921a34179fb1ULL, 0x07f609ffe30ef8e4ULL, 0x7e2a82a84dfcd633ULL,
0x423ec6f8ed84baafULL, 0xe25e3b65cad98728ULL, 0x6927bb9c25d2f54cULL,
0xca4643050a89cfc0ULL, 0x140c3c3060282474ULL, 0xaf65ec890f4326a0ULL,
0xb868d5bd676d05dfULL, 0xa361f8992f5b3a8cULL, 0x05030f0c180a091dULL,
0x5ec1e22346bc7d18ULL, 0xf957164182efb87bULL, 0x67d6a97ffece1899ULL,
0x76d99a4386ec35f0ULL, 0xe858257dfacd9512ULL, 0x75d89f478eea32fbULL,
0xaa66e38517492fbdULL, 0x64d7ac7bf6c81f92ULL, 0x4e3ad2e8cd9ca683ULL,
0x45c8cf070e8a424bULL, 0x443cccf0fd88b4b9ULL, 0x13fa35cf8326dc90ULL,
0xa796f462c453c563ULL, 0xf4a701a651f552a5ULL, 0xb598c25ab477ef01ULL,
0x29ec7b973352be1aULL, 0xd5b862daa9b70f7cULL, 0x54c7fc3b76a86f22ULL,
0xefae2c8219c36df6ULL, 0xbb69d0b96f6b02d4ULL, 0xdd4b7a3162a7ecbfULL,
0xe0ab3d9631dd76d1ULL, 0xe6a9379e21d178c7ULL, 0xa967e6811f4f28b6ULL,
0x1e0a2228503c364eULL, 0xc9474601028fc8cbULL, 0x0bf21defc316e4c8ULL,
0xc2b55beec1992c03ULL, 0x6622aa880dccee6bULL, 0x32e556b37b648149ULL,
0x2fee719f235eb00cULL, 0xdfbe7cc299a31d46ULL, 0x7d2b87ac45fad138ULL,
0x9e81bf3e7c21a0e2ULL, 0x36125a48906c7ea6ULL, 0x9883b5366c2daef4ULL,
0x2d1b776cd85a41f5ULL, 0x120e363870242a62ULL, 0x6523af8c05cae960ULL,
0x02f506f3fb04f1f9ULL, 0xcf454c091283c6ddULL, 0x6321a58415c6e776ULL,
0x4fced11f3e9e5071ULL, 0xdb49703972abe2a9ULL, 0x742c9cb07de8c409ULL,
0x16f93ac39b2cd58dULL, 0x37e659bf636e8854ULL, 0xc7b654e2d993251eULL,
0x782888a05df0d825ULL, 0x39174b5cb8726581ULL, 0x9b82b032642ba9ffULL,
0x2e1a7268d05c46feULL, 0x808b9d162c1d96acULL, 0x1ffe21dfa33ec0bcULL,
0x838a9812241b91a7ULL, 0x1b092d2448363f53ULL, 0x46c9ca03068c4540ULL,
0x9487a1264c35b2d8ULL, 0xd24e6b254ab9f798ULL, 0x3ee142a35b7c9d65ULL,
0x722e96b86de4ca1fULL, 0x31e453b773628642ULL, 0x3de047a7537a9a6eULL,
0x20eb608b0b40ab2bULL, 0xad90ea7af447d759ULL, 0xf1a40eaa49ff5bb8ULL,
0x221e6678f0445ad2ULL, 0x9285ab2e5c39bcceULL, 0xa060fd9d275d3d87ULL,
0x0000000000000000ULL, 0x6f25b19435defb5aULL, 0x01f403f7f302f6f2ULL,
0x0ef112e3db1cedd5ULL, 0xa194fe6ad45fcb75ULL, 0x1d0b272c583a3145ULL,
0x34e75cbb6b688f5fULL, 0x9f75bcc98f235610ULL, 0x2cef749b2b58b707ULL,
0x5c34e4d0bdb88ce1ULL, 0x5331f5c495a697c6ULL, 0x61d4a377eec2168fULL,
0x6dd0b767ceda0aa3ULL, 0x9786a4224433b5d3ULL, 0x827e9be5d7196755ULL,
0xeaad238e01c964ebULL, 0x1afd2ed3bb34c9a1ULL, 0x7b298da455f6df2eULL,
0x5030f0c09da090cdULL, 0x4d3bd7ecc59aa188ULL, 0xbc9fd9468c65fa30ULL,
0x15f83fc7932ad286ULL, 0x57c6f93f7eae6829ULL, 0x35135f4c986a79adULL,
0x0a061e183014123aULL, 0x0f051114281e1b27ULL, 0x52c5f63366a46134ULL,
0x33115544886677bbULL, 0x9977b6c19f2f5806ULL, 0x847c91edc7156943ULL,
0x8e7a8ff5f7017b79ULL, 0x887885fde70d756fULL, 0x5a36eed8adb482f7ULL,
0x241c6c70e04854c4ULL, 0x4b39dde4d596af9eULL, 0xeb592079f2cb9219ULL,
0x28187860c05048e8ULL, 0xfa5613458ae9bf70ULL, 0xc8b345f6f18d3e39ULL,
0xcdb04afae9873724ULL, 0x6c24b4903dd8fc51ULL, 0x6020a0801dc0e07dULL,
0xcbb240f2f98b3932ULL, 0xab92e072e44bd94fULL, 0xf8a315b671ed4e89ULL,
0x5dc0e7274eba7a13ULL, 0xcc44490d1a85c1d6ULL, 0xa662f79537513391ULL,
0x30105040806070b0ULL, 0xc1b45eeac99f2b08ULL, 0x9184ae2a543fbbc5ULL,
0xc54352112297d4e7ULL, 0xa893e576ec4dde44ULL, 0x5bc2ed2f5eb67405ULL,
0xde4a7f356aa1ebb4ULL, 0xdabd73ce81a9145bULL, 0x8c8f89060c058a80ULL,
0x772d99b475eec302ULL, 0xd9bc76ca89af1350ULL, 0xb99cd64a946ff32dULL,
0xbe6adfb577610bc9ULL, 0xc0405d1d3a9dddfaULL, 0x4ccfd41b3698577aULL,
0xfba210b279eb4982ULL, 0x9d80ba3a7427a7e9ULL, 0xd14f6e2142bff093ULL,
0x211f637cf8425dd9ULL, 0x43cac50f1e864c5dULL, 0xe3aa389239db71daULL,
0xc64257152a91d3ecULL
};
static const u64 T2[256] = {
0xd268bad36a01bbb9ULL, 0x4d1954fc66b1e59aULL, 0xbc932f7114cde265ULL,
0xcdb9749c1b512587ULL, 0x510253f557a4f7a2ULL, 0x6bb8d368be03d0d6ULL,
0x6fbdd26bb504d6deULL, 0x29644dd785feb352ULL, 0x5d0d50f04aadfdbaULL,
0x8a26ace9e063cf09ULL, 0x0e838d8a9684091cULL, 0xc679bfdc4d1aa591ULL,
0xddad7090374d3da7ULL, 0x550752f65ca3f1aaULL, 0x52c89ab317e17ba4ULL,
0x2d614cd48ef9b55aULL, 0x8f65ea2320ac4603ULL, 0x73a6d5628411c4e6ULL,
0x66f197a468c255ccULL, 0x63b2d16ea80ddcc6ULL, 0xccff3355d099aa85ULL,
0x590851f341aafbb2ULL, 0x712a5bed0f9cc7e2ULL, 0xa204a6f7ae55f359ULL,
0x5f81de7fc120febeULL, 0x3d7548d8a2e5ad7aULL, 0x9a32a8e5cc7fd729ULL,
0x5ec799b60ae871bcULL, 0x4b90db70e63be096ULL, 0xc8fa3256db9eac8dULL,
0xe651b7c4152295d1ULL, 0xd72bfc19aace32b3ULL, 0xab48e3387393704bULL,
0x42dc9ebf3bfd6384ULL, 0x7eef91ae52d041fcULL, 0x56cd9bb01ce67dacULL,
0xaf4de23b78947643ULL, 0xd66dbbd06106bdb1ULL, 0x195841c3f1da9b32ULL,
0xa5cb6eb2e5177957ULL, 0xae0ba5f2b35cf941ULL, 0x0bc0cb40564b8016ULL,
0xb1da6bbdc20c677fULL, 0x6efb95a27ecc59dcULL, 0xbe1fa1fe9f40e161ULL,
0xeb18f308c3e310cbULL, 0xfe4fb1ce2f3081e1ULL, 0x080a0206160e0c10ULL,
0x17dbcc49675e922eULL, 0x37f3c4513f66a26eULL, 0x74691d27cf534ee8ULL,
0x5044143c9c6c78a0ULL, 0x2be8c3580e73b056ULL, 0x91f263a59a34573fULL,
0x4f95da73ed3ce69eULL, 0x69345de7358ed3d2ULL, 0x613e5fe12380dfc2ULL,
0x578bdc79d72ef2aeULL, 0xe9947d87486e13cfULL, 0x13decd4a6c599426ULL,
0xe19e7f815e601fdfULL, 0x752f5aee049bc1eaULL, 0xadc16cb4f3197547ULL,
0x6d315ce43e89d5daULL, 0xfb0cf704efff08ebULL, 0x98be266a47f2d42dULL,
0xdb24ff1cb7c738abULL, 0x937eed2a11b9543bULL, 0x876fe82536a24a13ULL,
0x4ed39dba26f4699cULL, 0xa1ce6fb1ee107f5fULL, 0x028c8e8f8b8d0304ULL,
0x647d192be34f56c8ULL, 0xba1aa0fd9447e769ULL, 0xe717f00ddeea1ad3ULL,
0x1e978986ba98113cULL, 0x3c330f11692d2278ULL, 0x1c1b070931151238ULL,
0x8629afecfd6ac511ULL, 0xcb30fb109bdb208bULL, 0x2028081858383040ULL,
0x5441153f976b7ea8ULL, 0x34390d177f232e68ULL, 0x1014040c2c1c1820ULL,
0x040501030b070608ULL, 0x8de964acab214507ULL, 0x5b84df7cca27f8b6ULL,
0xc5b3769a0d5f2997ULL, 0xf980798b64720befULL, 0x538edd7adc29f4a6ULL,
0xf4c93d47b2b38ef5ULL, 0x584e163a8a6274b0ULL, 0xfcc33f41a4bd82e5ULL,
0xdceb3759fc85b2a5ULL, 0xa9c46db7f81e734fULL, 0xe0d8384895a890ddULL,
0xde67b9d67708b1a1ULL, 0xd1a273952a4437bfULL, 0x836ae9263da54c1bULL,
0xd4e1355fea8bbeb5ULL, 0x491c55ff6db6e392ULL, 0xd9a871933c4a3bafULL,
0xf18a7b8d727c07ffULL, 0x0a868c899d830f14ULL, 0xd5a77296214331b7ULL,
0x1a928885b19f1734ULL, 0xff09f607e4f80ee3ULL, 0xa8822a7e33d6fc4dULL,
0xf8c63e42afba84edULL, 0x653b5ee22887d9caULL, 0x9cbb27694cf5d225ULL,
0x054346cac0cf890aULL, 0x303c0c1474242860ULL, 0x89ec65afa026430fULL,
0xbdd568b8df056d67ULL, 0x99f861a38c3a5b2fULL, 0x0c0f03051d090a18ULL,
0x23e2c15e187dbc46ULL, 0x411657f97bb8ef82ULL, 0x7fa9d6679918cefeULL,
0x439ad976f035ec86ULL, 0x7d2558e81295cdfaULL, 0x479fd875fb32ea8eULL,
0x85e366aabd2f4917ULL, 0x7bacd764921fc8f6ULL, 0xe8d23a4e83a69ccdULL,
0x07cfc8454b428a0eULL, 0xf0cc3c44b9b488fdULL, 0xcf35fa1390dc2683ULL,
0x62f496a763c553c4ULL, 0xa601a7f4a552f551ULL, 0x5ac298b501ef77b4ULL,
0x977bec291abe5233ULL, 0xda62b8d57c0fb7a9ULL, 0x3bfcc754226fa876ULL,
0x822caeeff66dc319ULL, 0xb9d069bbd4026b6fULL, 0x317a4bddbfeca762ULL,
0x963dabe0d176dd31ULL, 0x9e37a9e6c778d121ULL, 0x81e667a9b6284f1fULL,
0x28220a1e4e363c50ULL, 0x014647c9cbc88f02ULL, 0xef1df20bc8e416c3ULL,
0xee5bb5c2032c99c1ULL, 0x88aa22666beecc0dULL, 0xb356e5324981647bULL,
0x9f71ee2f0cb05e23ULL, 0xc27cbedf461da399ULL, 0xac872b7d38d1fa45ULL,
0x3ebf819ee2a0217cULL, 0x485a1236a67e6c90ULL, 0x36b58398f4ae2d6cULL,
0x6c771b2df5415ad8ULL, 0x38360e12622a2470ULL, 0x8caf236560e9ca05ULL,
0xf306f502f9f104fbULL, 0x094c45cfddc68312ULL, 0x84a5216376e7c615ULL,
0x1fd1ce4f71509e3eULL, 0x397049dba9e2ab72ULL, 0xb09c2c7409c4e87dULL,
0xc33af9168dd52c9bULL, 0xbf59e63754886e63ULL, 0xe254b6c71e2593d9ULL,
0xa088287825d8f05dULL, 0x5c4b1739816572b8ULL, 0x32b0829bffa92b64ULL,
0x68721a2efe465cd0ULL, 0x169d8b80ac961d2cULL, 0xdf21fe1fbcc03ea3ULL,
0x12988a83a7911b24ULL, 0x242d091b533f3648ULL, 0x03cac94640458c06ULL,
0x26a18794d8b2354cULL, 0x256b4ed298f7b94aULL, 0xa342e13e659d7c5bULL,
0xb8962e721fcae46dULL, 0xb753e43142866273ULL, 0xa747e03d6e9a7a53ULL,
0x8b60eb202bab400bULL, 0x7aea90ad59d747f4ULL, 0xaa0ea4f1b85bff49ULL,
0x78661e22d25a44f0ULL, 0x2eab8592cebc395cULL, 0x9dfd60a0873d5d27ULL,
0x0000000000000000ULL, 0x94b1256f5afbde35ULL, 0xf703f401f2f602f3ULL,
0xe312f10ed5ed1cdbULL, 0x6afe94a175cb5fd4ULL, 0x2c270b1d45313a58ULL,
0xbb5ce7345f8f686bULL, 0xc9bc759f1056238fULL, 0x9b74ef2c07b7582bULL,
0xd0e4345ce18cb8bdULL, 0xc4f53153c697a695ULL, 0x77a3d4618f16c2eeULL,
0x67b7d06da30adaceULL, 0x22a48697d3b53344ULL, 0xe59b7e82556719d7ULL,
0x8e23adeaeb64c901ULL, 0xd32efd1aa1c934bbULL, 0xa48d297b2edff655ULL,
0xc0f03050cd90a09dULL, 0xecd73b4d88a19ac5ULL, 0x46d99fbc30fa658cULL,
0xc73ff81586d22a93ULL, 0x3ff9c6572968ae7eULL, 0x4c5f1335ad796a98ULL,
0x181e060a3a121430ULL, 0x1411050f271b1e28ULL, 0x33f6c5523461a466ULL,
0x44551133bb776688ULL, 0xc1b6779906582f9fULL, 0xed917c84436915c7ULL,
0xf58f7a8e797b01f7ULL, 0xfd8578886f750de7ULL, 0xd8ee365af782b4adULL,
0x706c1c24c45448e0ULL, 0xe4dd394b9eaf96d5ULL, 0x792059eb1992cbf2ULL,
0x60781828e84850c0ULL, 0x451356fa70bfe98aULL, 0xf645b3c8393e8df1ULL,
0xfa4ab0cd243787e9ULL, 0x90b4246c51fcd83dULL, 0x80a020607de0c01dULL,
0xf240b2cb32398bf9ULL, 0x72e092ab4fd94be4ULL, 0xb615a3f8894eed71ULL,
0x27e7c05d137aba4eULL, 0x0d4944ccd6c1851aULL, 0x95f762a691335137ULL,
0x40501030b0706080ULL, 0xea5eb4c1082b9fc9ULL, 0x2aae8491c5bb3f54ULL,
0x115243c5e7d49722ULL, 0x76e593a844de4decULL, 0x2fedc25b0574b65eULL,
0x357f4adeb4eba16aULL, 0xce73bdda5b14a981ULL, 0x06898f8c808a050cULL,
0xb4992d7702c3ee75ULL, 0xca76bcd95013af89ULL, 0x4ad69cb92df36f94ULL,
0xb5df6abec90b6177ULL, 0x1d5d40c0fadd9d3aULL, 0x1bd4cf4c7a579836ULL,
0xb210a2fb8249eb79ULL, 0x3aba809de9a72774ULL, 0x216e4fd193f0bf42ULL,
0x7c631f21d95d42f8ULL, 0x0fc5ca435d4c861eULL, 0x9238aae3da71db39ULL,
0x155742c6ecd3912aULL
};
static const u64 T3[256] = {
0x68d2d3ba016ab9bbULL, 0x194dfc54b1669ae5ULL, 0x93bc712fcd1465e2ULL,
0xb9cd9c74511b8725ULL, 0x0251f553a457a2f7ULL, 0xb86b68d303bed6d0ULL,
0xbd6f6bd204b5ded6ULL, 0x6429d74dfe8552b3ULL, 0x0d5df050ad4abafdULL,
0x268ae9ac63e009cfULL, 0x830e8a8d84961c09ULL, 0x79c6dcbf1a4d91a5ULL,
0xaddd90704d37a73dULL, 0x0755f652a35caaf1ULL, 0xc852b39ae117a47bULL,
0x612dd44cf98e5ab5ULL, 0x658f23eaac200346ULL, 0xa67362d51184e6c4ULL,
0xf166a497c268cc55ULL, 0xb2636ed10da8c6dcULL, 0xffcc553399d085aaULL,
0x0859f351aa41b2fbULL, 0x2a71ed5b9c0fe2c7ULL, 0x04a2f7a655ae59f3ULL,
0x815f7fde20c1befeULL, 0x753dd848e5a27aadULL, 0x329ae5a87fcc29d7ULL,
0xc75eb699e80abc71ULL, 0x904b70db3be696e0ULL, 0xfac856329edb8dacULL,
0x51e6c4b72215d195ULL, 0x2bd719fcceaab332ULL, 0x48ab38e393734b70ULL,
0xdc42bf9efd3b8463ULL, 0xef7eae91d052fc41ULL, 0xcd56b09be61cac7dULL,
0x4daf3be294784376ULL, 0x6dd6d0bb0661b1bdULL, 0x5819c341daf1329bULL,
0xcba5b26e17e55779ULL, 0x0baef2a55cb341f9ULL, 0xc00b40cb4b561680ULL,
0xdab1bd6b0cc27f67ULL, 0xfb6ea295cc7edc59ULL, 0x1fbefea1409f61e1ULL,
0x18eb08f3e3c3cb10ULL, 0x4ffeceb1302fe181ULL, 0x0a0806020e16100cULL,
0xdb1749cc5e672e92ULL, 0xf33751c4663f6ea2ULL, 0x6974271d53cfe84eULL,
0x44503c146c9ca078ULL, 0xe82b58c3730e56b0ULL, 0xf291a563349a3f57ULL,
0x954f73da3ced9ee6ULL, 0x3469e75d8e35d2d3ULL, 0x3e61e15f8023c2dfULL,
0x8b5779dc2ed7aef2ULL, 0x94e9877d6e48cf13ULL, 0xde134acd596c2694ULL,
0x9ee1817f605edf1fULL, 0x2f75ee5a9b04eac1ULL, 0xc1adb46c19f34775ULL,
0x316de45c893edad5ULL, 0x0cfb04f7ffefeb08ULL, 0xbe986a26f2472dd4ULL,
0x24db1cffc7b7ab38ULL, 0x7e932aedb9113b54ULL, 0x6f8725e8a236134aULL,
0xd34eba9df4269c69ULL, 0xcea1b16f10ee5f7fULL, 0x8c028f8e8d8b0403ULL,
0x7d642b194fe3c856ULL, 0x1abafda0479469e7ULL, 0x17e70df0eaded31aULL,
0x971e868998ba3c11ULL, 0x333c110f2d697822ULL, 0x1b1c090715313812ULL,
0x2986ecaf6afd11c5ULL, 0x30cb10fbdb9b8b20ULL, 0x2820180838584030ULL,
0x41543f156b97a87eULL, 0x3934170d237f682eULL, 0x14100c041c2c2018ULL,
0x05040301070b0806ULL, 0xe98dac6421ab0745ULL, 0x845b7cdf27cab6f8ULL,
0xb3c59a765f0d9729ULL, 0x80f98b797264ef0bULL, 0x8e537add29dca6f4ULL,
0xc9f4473db3b2f58eULL, 0x4e583a16628ab074ULL, 0xc3fc413fbda4e582ULL,
0xebdc593785fca5b2ULL, 0xc4a9b76d1ef84f73ULL, 0xd8e04838a895dd90ULL,
0x67ded6b90877a1b1ULL, 0xa2d19573442abf37ULL, 0x6a8326e9a53d1b4cULL,
0xe1d45f358beab5beULL, 0x1c49ff55b66d92e3ULL, 0xa8d993714a3caf3bULL,
0x8af18d7b7c72ff07ULL, 0x860a898c839d140fULL, 0xa7d596724321b731ULL,
0x921a85889fb13417ULL, 0x09ff07f6f8e4e30eULL, 0x82a87e2ad6334dfcULL,
0xc6f8423ebaafed84ULL, 0x3b65e25e8728cad9ULL, 0xbb9c6927f54c25d2ULL,
0x4305ca46cfc00a89ULL, 0x3c30140c24746028ULL, 0xec89af6526a00f43ULL,
0xd5bdb86805df676dULL, 0xf899a3613a8c2f5bULL, 0x0f0c0503091d180aULL,
0xe2235ec17d1846bcULL, 0x1641f957b87b82efULL, 0xa97f67d61899feceULL,
0x9a4376d935f086ecULL, 0x257de8589512facdULL, 0x9f4775d832fb8eeaULL,
0xe385aa662fbd1749ULL, 0xac7b64d71f92f6c8ULL, 0xd2e84e3aa683cd9cULL,
0xcf0745c8424b0e8aULL, 0xccf0443cb4b9fd88ULL, 0x35cf13fadc908326ULL,
0xf462a796c563c453ULL, 0x01a6f4a752a551f5ULL, 0xc25ab598ef01b477ULL,
0x7b9729ecbe1a3352ULL, 0x62dad5b80f7ca9b7ULL, 0xfc3b54c76f2276a8ULL,
0x2c82efae6df619c3ULL, 0xd0b9bb6902d46f6bULL, 0x7a31dd4becbf62a7ULL,
0x3d96e0ab76d131ddULL, 0x379ee6a978c721d1ULL, 0xe681a96728b61f4fULL,
0x22281e0a364e503cULL, 0x4601c947c8cb028fULL, 0x1def0bf2e4c8c316ULL,
0x5beec2b52c03c199ULL, 0xaa886622ee6b0dccULL, 0x56b332e581497b64ULL,
0x719f2feeb00c235eULL, 0x7cc2dfbe1d4699a3ULL, 0x87ac7d2bd13845faULL,
0xbf3e9e81a0e27c21ULL, 0x5a4836127ea6906cULL, 0xb5369883aef46c2dULL,
0x776c2d1b41f5d85aULL, 0x3638120e2a627024ULL, 0xaf8c6523e96005caULL,
0x06f302f5f1f9fb04ULL, 0x4c09cf45c6dd1283ULL, 0xa5846321e77615c6ULL,
0xd11f4fce50713e9eULL, 0x7039db49e2a972abULL, 0x9cb0742cc4097de8ULL,
0x3ac316f9d58d9b2cULL, 0x59bf37e68854636eULL, 0x54e2c7b6251ed993ULL,
0x88a07828d8255df0ULL, 0x4b5c39176581b872ULL, 0xb0329b82a9ff642bULL,
0x72682e1a46fed05cULL, 0x9d16808b96ac2c1dULL, 0x21df1ffec0bca33eULL,
0x9812838a91a7241bULL, 0x2d241b093f534836ULL, 0xca0346c94540068cULL,
0xa1269487b2d84c35ULL, 0x6b25d24ef7984ab9ULL, 0x42a33ee19d655b7cULL,
0x96b8722eca1f6de4ULL, 0x53b731e486427362ULL, 0x47a73de09a6e537aULL,
0x608b20ebab2b0b40ULL, 0xea7aad90d759f447ULL, 0x0eaaf1a45bb849ffULL,
0x6678221e5ad2f044ULL, 0xab2e9285bcce5c39ULL, 0xfd9da0603d87275dULL,
0x0000000000000000ULL, 0xb1946f25fb5a35deULL, 0x03f701f4f6f2f302ULL,
0x12e30ef1edd5db1cULL, 0xfe6aa194cb75d45fULL, 0x272c1d0b3145583aULL,
0x5cbb34e78f5f6b68ULL, 0xbcc99f7556108f23ULL, 0x749b2cefb7072b58ULL,
0xe4d05c348ce1bdb8ULL, 0xf5c4533197c695a6ULL, 0xa37761d4168feec2ULL,
0xb7676dd00aa3cedaULL, 0xa4229786b5d34433ULL, 0x9be5827e6755d719ULL,
0x238eeaad64eb01c9ULL, 0x2ed31afdc9a1bb34ULL, 0x8da47b29df2e55f6ULL,
0xf0c0503090cd9da0ULL, 0xd7ec4d3ba188c59aULL, 0xd946bc9ffa308c65ULL,
0x3fc715f8d286932aULL, 0xf93f57c668297eaeULL, 0x5f4c351379ad986aULL,
0x1e180a06123a3014ULL, 0x11140f051b27281eULL, 0xf63352c5613466a4ULL,
0x5544331177bb8866ULL, 0xb6c1997758069f2fULL, 0x91ed847c6943c715ULL,
0x8ff58e7a7b79f701ULL, 0x85fd8878756fe70dULL, 0xeed85a3682f7adb4ULL,
0x6c70241c54c4e048ULL, 0xdde44b39af9ed596ULL, 0x2079eb599219f2cbULL,
0x7860281848e8c050ULL, 0x1345fa56bf708ae9ULL, 0x45f6c8b33e39f18dULL,
0x4afacdb03724e987ULL, 0xb4906c24fc513dd8ULL, 0xa0806020e07d1dc0ULL,
0x40f2cbb23932f98bULL, 0xe072ab92d94fe44bULL, 0x15b6f8a34e8971edULL,
0xe7275dc07a134ebaULL, 0x490dcc44c1d61a85ULL, 0xf795a66233913751ULL,
0x5040301070b08060ULL, 0x5eeac1b42b08c99fULL, 0xae2a9184bbc5543fULL,
0x5211c543d4e72297ULL, 0xe576a893de44ec4dULL, 0xed2f5bc274055eb6ULL,
0x7f35de4aebb46aa1ULL, 0x73cedabd145b81a9ULL, 0x89068c8f8a800c05ULL,
0x99b4772dc30275eeULL, 0x76cad9bc135089afULL, 0xd64ab99cf32d946fULL,
0xdfb5be6a0bc97761ULL, 0x5d1dc040ddfa3a9dULL, 0xd41b4ccf577a3698ULL,
0x10b2fba2498279ebULL, 0xba3a9d80a7e97427ULL, 0x6e21d14ff09342bfULL,
0x637c211f5dd9f842ULL, 0xc50f43ca4c5d1e86ULL, 0x3892e3aa71da39dbULL,
0x5715c642d3ec2a91ULL
};
static const u64 T4[256] = {
0xbbb96a01bad3d268ULL, 0xe59a66b154fc4d19ULL, 0xe26514cd2f71bc93ULL,
0x25871b51749ccdb9ULL, 0xf7a257a453f55102ULL, 0xd0d6be03d3686bb8ULL,
0xd6deb504d26b6fbdULL, 0xb35285fe4dd72964ULL, 0xfdba4aad50f05d0dULL,
0xcf09e063ace98a26ULL, 0x091c96848d8a0e83ULL, 0xa5914d1abfdcc679ULL,
0x3da7374d7090ddadULL, 0xf1aa5ca352f65507ULL, 0x7ba417e19ab352c8ULL,
0xb55a8ef94cd42d61ULL, 0x460320acea238f65ULL, 0xc4e68411d56273a6ULL,
0x55cc68c297a466f1ULL, 0xdcc6a80dd16e63b2ULL, 0xaa85d0993355ccffULL,
0xfbb241aa51f35908ULL, 0xc7e20f9c5bed712aULL, 0xf359ae55a6f7a204ULL,
0xfebec120de7f5f81ULL, 0xad7aa2e548d83d75ULL, 0xd729cc7fa8e59a32ULL,
0x71bc0ae899b65ec7ULL, 0xe096e63bdb704b90ULL, 0xac8ddb9e3256c8faULL,
0x95d11522b7c4e651ULL, 0x32b3aacefc19d72bULL, 0x704b7393e338ab48ULL,
0x63843bfd9ebf42dcULL, 0x41fc52d091ae7eefULL, 0x7dac1ce69bb056cdULL,
0x76437894e23baf4dULL, 0xbdb16106bbd0d66dULL, 0x9b32f1da41c31958ULL,
0x7957e5176eb2a5cbULL, 0xf941b35ca5f2ae0bULL, 0x8016564bcb400bc0ULL,
0x677fc20c6bbdb1daULL, 0x59dc7ecc95a26efbULL, 0xe1619f40a1febe1fULL,
0x10cbc3e3f308eb18ULL, 0x81e12f30b1cefe4fULL, 0x0c10160e0206080aULL,
0x922e675ecc4917dbULL, 0xa26e3f66c45137f3ULL, 0x4ee8cf531d277469ULL,
0x78a09c6c143c5044ULL, 0xb0560e73c3582be8ULL, 0x573f9a3463a591f2ULL,
0xe69eed3cda734f95ULL, 0xd3d2358e5de76934ULL, 0xdfc223805fe1613eULL,
0xf2aed72edc79578bULL, 0x13cf486e7d87e994ULL, 0x94266c59cd4a13deULL,
0x1fdf5e607f81e19eULL, 0xc1ea049b5aee752fULL, 0x7547f3196cb4adc1ULL,
0xd5da3e895ce46d31ULL, 0x08ebeffff704fb0cULL, 0xd42d47f2266a98beULL,
0x38abb7c7ff1cdb24ULL, 0x543b11b9ed2a937eULL, 0x4a1336a2e825876fULL,
0x699c26f49dba4ed3ULL, 0x7f5fee106fb1a1ceULL, 0x03048b8d8e8f028cULL,
0x56c8e34f192b647dULL, 0xe7699447a0fdba1aULL, 0x1ad3deeaf00de717ULL,
0x113cba9889861e97ULL, 0x2278692d0f113c33ULL, 0x1238311507091c1bULL,
0xc511fd6aafec8629ULL, 0x208b9bdbfb10cb30ULL, 0x3040583808182028ULL,
0x7ea8976b153f5441ULL, 0x2e687f230d173439ULL, 0x18202c1c040c1014ULL,
0x06080b0701030405ULL, 0x4507ab2164ac8de9ULL, 0xf8b6ca27df7c5b84ULL,
0x29970d5f769ac5b3ULL, 0x0bef6472798bf980ULL, 0xf4a6dc29dd7a538eULL,
0x8ef5b2b33d47f4c9ULL, 0x74b08a62163a584eULL, 0x82e5a4bd3f41fcc3ULL,
0xb2a5fc853759dcebULL, 0x734ff81e6db7a9c4ULL, 0x90dd95a83848e0d8ULL,
0xb1a17708b9d6de67ULL, 0x37bf2a447395d1a2ULL, 0x4c1b3da5e926836aULL,
0xbeb5ea8b355fd4e1ULL, 0xe3926db655ff491cULL, 0x3baf3c4a7193d9a8ULL,
0x07ff727c7b8df18aULL, 0x0f149d838c890a86ULL, 0x31b721437296d5a7ULL,
0x1734b19f88851a92ULL, 0x0ee3e4f8f607ff09ULL, 0xfc4d33d62a7ea882ULL,
0x84edafba3e42f8c6ULL, 0xd9ca28875ee2653bULL, 0xd2254cf527699cbbULL,
0x890ac0cf46ca0543ULL, 0x286074240c14303cULL, 0x430fa02665af89ecULL,
0x6d67df0568b8bdd5ULL, 0x5b2f8c3a61a399f8ULL, 0x0a181d0903050c0fULL,
0xbc46187dc15e23e2ULL, 0xef827bb857f94116ULL, 0xcefe9918d6677fa9ULL,
0xec86f035d976439aULL, 0xcdfa129558e87d25ULL, 0xea8efb32d875479fULL,
0x4917bd2f66aa85e3ULL, 0xc8f6921fd7647bacULL, 0x9ccd83a63a4ee8d2ULL,
0x8a0e4b42c84507cfULL, 0x88fdb9b43c44f0ccULL, 0x268390dcfa13cf35ULL,
0x53c463c596a762f4ULL, 0xf551a552a7f4a601ULL, 0x77b401ef98b55ac2ULL,
0x52331abeec29977bULL, 0xb7a97c0fb8d5da62ULL, 0xa876226fc7543bfcULL,
0xc319f66daeef822cULL, 0x6b6fd40269bbb9d0ULL, 0xa762bfec4bdd317aULL,
0xdd31d176abe0963dULL, 0xd121c778a9e69e37ULL, 0x4f1fb62867a981e6ULL,
0x3c504e360a1e2822ULL, 0x8f02cbc847c90146ULL, 0x16c3c8e4f20bef1dULL,
0x99c1032cb5c2ee5bULL, 0xcc0d6bee226688aaULL, 0x647b4981e532b356ULL,
0x5e230cb0ee2f9f71ULL, 0xa399461dbedfc27cULL, 0xfa4538d12b7dac87ULL,
0x217ce2a0819e3ebfULL, 0x6c90a67e1236485aULL, 0x2d6cf4ae839836b5ULL,
0x5ad8f5411b2d6c77ULL, 0x2470622a0e123836ULL, 0xca0560e923658cafULL,
0x04fbf9f1f502f306ULL, 0x8312ddc645cf094cULL, 0xc61576e7216384a5ULL,
0x9e3e7150ce4f1fd1ULL, 0xab72a9e249db3970ULL, 0xe87d09c42c74b09cULL,
0x2c9b8dd5f916c33aULL, 0x6e635488e637bf59ULL, 0x93d91e25b6c7e254ULL,
0xf05d25d82878a088ULL, 0x72b8816517395c4bULL, 0x2b64ffa9829b32b0ULL,
0x5cd0fe461a2e6872ULL, 0x1d2cac968b80169dULL, 0x3ea3bcc0fe1fdf21ULL,
0x1b24a7918a831298ULL, 0x3648533f091b242dULL, 0x8c064045c94603caULL,
0x354cd8b2879426a1ULL, 0xb94a98f74ed2256bULL, 0x7c5b659de13ea342ULL,
0xe46d1fca2e72b896ULL, 0x62734286e431b753ULL, 0x7a536e9ae03da747ULL,
0x400b2babeb208b60ULL, 0x47f459d790ad7aeaULL, 0xff49b85ba4f1aa0eULL,
0x44f0d25a1e227866ULL, 0x395ccebc85922eabULL, 0x5d27873d60a09dfdULL,
0x0000000000000000ULL, 0xde355afb256f94b1ULL, 0x02f3f2f6f401f703ULL,
0x1cdbd5edf10ee312ULL, 0x5fd475cb94a16afeULL, 0x3a5845310b1d2c27ULL,
0x686b5f8fe734bb5cULL, 0x238f1056759fc9bcULL, 0x582b07b7ef2c9b74ULL,
0xb8bde18c345cd0e4ULL, 0xa695c6973153c4f5ULL, 0xc2ee8f16d46177a3ULL,
0xdacea30ad06d67b7ULL, 0x3344d3b5869722a4ULL, 0x19d755677e82e59bULL,
0xc901eb64adea8e23ULL, 0x34bba1c9fd1ad32eULL, 0xf6552edf297ba48dULL,
0xa09dcd903050c0f0ULL, 0x9ac588a13b4decd7ULL, 0x658c30fa9fbc46d9ULL,
0x2a9386d2f815c73fULL, 0xae7e2968c6573ff9ULL, 0x6a98ad7913354c5fULL,
0x14303a12060a181eULL, 0x1e28271b050f1411ULL, 0xa4663461c55233f6ULL,
0x6688bb7711334455ULL, 0x2f9f06587799c1b6ULL, 0x15c743697c84ed91ULL,
0x01f7797b7a8ef58fULL, 0x0de76f757888fd85ULL, 0xb4adf782365ad8eeULL,
0x48e0c4541c24706cULL, 0x96d59eaf394be4ddULL, 0xcbf2199259eb7920ULL,
0x50c0e84818286078ULL, 0xe98a70bf56fa4513ULL, 0x8df1393eb3c8f645ULL,
0x87e92437b0cdfa4aULL, 0xd83d51fc246c90b4ULL, 0xc01d7de0206080a0ULL,
0x8bf93239b2cbf240ULL, 0x4be44fd992ab72e0ULL, 0xed71894ea3f8b615ULL,
0xba4e137ac05d27e7ULL, 0x851ad6c144cc0d49ULL, 0x5137913362a695f7ULL,
0x6080b07010304050ULL, 0x9fc9082bb4c1ea5eULL, 0x3f54c5bb84912aaeULL,
0x9722e7d443c51152ULL, 0x4dec44de93a876e5ULL, 0xb65e0574c25b2fedULL,
0xa16ab4eb4ade357fULL, 0xa9815b14bddace73ULL, 0x050c808a8f8c0689ULL,
0xee7502c32d77b499ULL, 0xaf895013bcd9ca76ULL, 0x6f942df39cb94ad6ULL,
0x6177c90b6abeb5dfULL, 0x9d3afadd40c01d5dULL, 0x98367a57cf4c1bd4ULL,
0xeb798249a2fbb210ULL, 0x2774e9a7809d3abaULL, 0xbf4293f04fd1216eULL,
0x42f8d95d1f217c63ULL, 0x861e5d4cca430fc5ULL, 0xdb39da71aae39238ULL,
0x912aecd342c61557ULL
};
static const u64 T5[256] = {
0xb9bb016ad3ba68d2ULL, 0x9ae5b166fc54194dULL, 0x65e2cd14712f93bcULL,
0x8725511b9c74b9cdULL, 0xa2f7a457f5530251ULL, 0xd6d003be68d3b86bULL,
0xded604b56bd2bd6fULL, 0x52b3fe85d74d6429ULL, 0xbafdad4af0500d5dULL,
0x09cf63e0e9ac268aULL, 0x1c0984968a8d830eULL, 0x91a51a4ddcbf79c6ULL,
0xa73d4d379070adddULL, 0xaaf1a35cf6520755ULL, 0xa47be117b39ac852ULL,
0x5ab5f98ed44c612dULL, 0x0346ac2023ea658fULL, 0xe6c4118462d5a673ULL,
0xcc55c268a497f166ULL, 0xc6dc0da86ed1b263ULL, 0x85aa99d05533ffccULL,
0xb2fbaa41f3510859ULL, 0xe2c79c0fed5b2a71ULL, 0x59f355aef7a604a2ULL,
0xbefe20c17fde815fULL, 0x7aade5a2d848753dULL, 0x29d77fcce5a8329aULL,
0xbc71e80ab699c75eULL, 0x96e03be670db904bULL, 0x8dac9edb5632fac8ULL,
0xd1952215c4b751e6ULL, 0xb332ceaa19fc2bd7ULL, 0x4b70937338e348abULL,
0x8463fd3bbf9edc42ULL, 0xfc41d052ae91ef7eULL, 0xac7de61cb09bcd56ULL,
0x437694783be24dafULL, 0xb1bd0661d0bb6dd6ULL, 0x329bdaf1c3415819ULL,
0x577917e5b26ecba5ULL, 0x41f95cb3f2a50baeULL, 0x16804b5640cbc00bULL,
0x7f670cc2bd6bdab1ULL, 0xdc59cc7ea295fb6eULL, 0x61e1409ffea11fbeULL,
0xcb10e3c308f318ebULL, 0xe181302fceb14ffeULL, 0x100c0e1606020a08ULL,
0x2e925e6749ccdb17ULL, 0x6ea2663f51c4f337ULL, 0xe84e53cf271d6974ULL,
0xa0786c9c3c144450ULL, 0x56b0730e58c3e82bULL, 0x3f57349aa563f291ULL,
0x9ee63ced73da954fULL, 0xd2d38e35e75d3469ULL, 0xc2df8023e15f3e61ULL,
0xaef22ed779dc8b57ULL, 0xcf136e48877d94e9ULL, 0x2694596c4acdde13ULL,
0xdf1f605e817f9ee1ULL, 0xeac19b04ee5a2f75ULL, 0x477519f3b46cc1adULL,
0xdad5893ee45c316dULL, 0xeb08ffef04f70cfbULL, 0x2dd4f2476a26be98ULL,
0xab38c7b71cff24dbULL, 0x3b54b9112aed7e93ULL, 0x134aa23625e86f87ULL,
0x9c69f426ba9dd34eULL, 0x5f7f10eeb16fcea1ULL, 0x04038d8b8f8e8c02ULL,
0xc8564fe32b197d64ULL, 0x69e74794fda01abaULL, 0xd31aeade0df017e7ULL,
0x3c1198ba8689971eULL, 0x78222d69110f333cULL, 0x3812153109071b1cULL,
0x11c56afdecaf2986ULL, 0x8b20db9b10fb30cbULL, 0x4030385818082820ULL,
0xa87e6b973f154154ULL, 0x682e237f170d3934ULL, 0x20181c2c0c041410ULL,
0x0806070b03010504ULL, 0x074521abac64e98dULL, 0xb6f827ca7cdf845bULL,
0x97295f0d9a76b3c5ULL, 0xef0b72648b7980f9ULL, 0xa6f429dc7add8e53ULL,
0xf58eb3b2473dc9f4ULL, 0xb074628a3a164e58ULL, 0xe582bda4413fc3fcULL,
0xa5b285fc5937ebdcULL, 0x4f731ef8b76dc4a9ULL, 0xdd90a8954838d8e0ULL,
0xa1b10877d6b967deULL, 0xbf37442a9573a2d1ULL, 0x1b4ca53d26e96a83ULL,
0xb5be8bea5f35e1d4ULL, 0x92e3b66dff551c49ULL, 0xaf3b4a3c9371a8d9ULL,
0xff077c728d7b8af1ULL, 0x140f839d898c860aULL, 0xb73143219672a7d5ULL,
0x34179fb18588921aULL, 0xe30ef8e407f609ffULL, 0x4dfcd6337e2a82a8ULL,
0xed84baaf423ec6f8ULL, 0xcad98728e25e3b65ULL, 0x25d2f54c6927bb9cULL,
0x0a89cfc0ca464305ULL, 0x60282474140c3c30ULL, 0x0f4326a0af65ec89ULL,
0x676d05dfb868d5bdULL, 0x2f5b3a8ca361f899ULL, 0x180a091d05030f0cULL,
0x46bc7d185ec1e223ULL, 0x82efb87bf9571641ULL, 0xfece189967d6a97fULL,
0x86ec35f076d99a43ULL, 0xfacd9512e858257dULL, 0x8eea32fb75d89f47ULL,
0x17492fbdaa66e385ULL, 0xf6c81f9264d7ac7bULL, 0xcd9ca6834e3ad2e8ULL,
0x0e8a424b45c8cf07ULL, 0xfd88b4b9443cccf0ULL, 0x8326dc9013fa35cfULL,
0xc453c563a796f462ULL, 0x51f552a5f4a701a6ULL, 0xb477ef01b598c25aULL,
0x3352be1a29ec7b97ULL, 0xa9b70f7cd5b862daULL, 0x76a86f2254c7fc3bULL,
0x19c36df6efae2c82ULL, 0x6f6b02d4bb69d0b9ULL, 0x62a7ecbfdd4b7a31ULL,
0x31dd76d1e0ab3d96ULL, 0x21d178c7e6a9379eULL, 0x1f4f28b6a967e681ULL,
0x503c364e1e0a2228ULL, 0x028fc8cbc9474601ULL, 0xc316e4c80bf21defULL,
0xc1992c03c2b55beeULL, 0x0dccee6b6622aa88ULL, 0x7b64814932e556b3ULL,
0x235eb00c2fee719fULL, 0x99a31d46dfbe7cc2ULL, 0x45fad1387d2b87acULL,
0x7c21a0e29e81bf3eULL, 0x906c7ea636125a48ULL, 0x6c2daef49883b536ULL,
0xd85a41f52d1b776cULL, 0x70242a62120e3638ULL, 0x05cae9606523af8cULL,
0xfb04f1f902f506f3ULL, 0x1283c6ddcf454c09ULL, 0x15c6e7766321a584ULL,
0x3e9e50714fced11fULL, 0x72abe2a9db497039ULL, 0x7de8c409742c9cb0ULL,
0x9b2cd58d16f93ac3ULL, 0x636e885437e659bfULL, 0xd993251ec7b654e2ULL,
0x5df0d825782888a0ULL, 0xb872658139174b5cULL, 0x642ba9ff9b82b032ULL,
0xd05c46fe2e1a7268ULL, 0x2c1d96ac808b9d16ULL, 0xa33ec0bc1ffe21dfULL,
0x241b91a7838a9812ULL, 0x48363f531b092d24ULL, 0x068c454046c9ca03ULL,
0x4c35b2d89487a126ULL, 0x4ab9f798d24e6b25ULL, 0x5b7c9d653ee142a3ULL,
0x6de4ca1f722e96b8ULL, 0x7362864231e453b7ULL, 0x537a9a6e3de047a7ULL,
0x0b40ab2b20eb608bULL, 0xf447d759ad90ea7aULL, 0x49ff5bb8f1a40eaaULL,
0xf0445ad2221e6678ULL, 0x5c39bcce9285ab2eULL, 0x275d3d87a060fd9dULL,
0x0000000000000000ULL, 0x35defb5a6f25b194ULL, 0xf302f6f201f403f7ULL,
0xdb1cedd50ef112e3ULL, 0xd45fcb75a194fe6aULL, 0x583a31451d0b272cULL,
0x6b688f5f34e75cbbULL, 0x8f2356109f75bcc9ULL, 0x2b58b7072cef749bULL,
0xbdb88ce15c34e4d0ULL, 0x95a697c65331f5c4ULL, 0xeec2168f61d4a377ULL,
0xceda0aa36dd0b767ULL, 0x4433b5d39786a422ULL, 0xd7196755827e9be5ULL,
0x01c964ebeaad238eULL, 0xbb34c9a11afd2ed3ULL, 0x55f6df2e7b298da4ULL,
0x9da090cd5030f0c0ULL, 0xc59aa1884d3bd7ecULL, 0x8c65fa30bc9fd946ULL,
0x932ad28615f83fc7ULL, 0x7eae682957c6f93fULL, 0x986a79ad35135f4cULL,
0x3014123a0a061e18ULL, 0x281e1b270f051114ULL, 0x66a4613452c5f633ULL,
0x886677bb33115544ULL, 0x9f2f58069977b6c1ULL, 0xc7156943847c91edULL,
0xf7017b798e7a8ff5ULL, 0xe70d756f887885fdULL, 0xadb482f75a36eed8ULL,
0xe04854c4241c6c70ULL, 0xd596af9e4b39dde4ULL, 0xf2cb9219eb592079ULL,
0xc05048e828187860ULL, 0x8ae9bf70fa561345ULL, 0xf18d3e39c8b345f6ULL,
0xe9873724cdb04afaULL, 0x3dd8fc516c24b490ULL, 0x1dc0e07d6020a080ULL,
0xf98b3932cbb240f2ULL, 0xe44bd94fab92e072ULL, 0x71ed4e89f8a315b6ULL,
0x4eba7a135dc0e727ULL, 0x1a85c1d6cc44490dULL, 0x37513391a662f795ULL,
0x806070b030105040ULL, 0xc99f2b08c1b45eeaULL, 0x543fbbc59184ae2aULL,
0x2297d4e7c5435211ULL, 0xec4dde44a893e576ULL, 0x5eb674055bc2ed2fULL,
0x6aa1ebb4de4a7f35ULL, 0x81a9145bdabd73ceULL, 0x0c058a808c8f8906ULL,
0x75eec302772d99b4ULL, 0x89af1350d9bc76caULL, 0x946ff32db99cd64aULL,
0x77610bc9be6adfb5ULL, 0x3a9dddfac0405d1dULL, 0x3698577a4ccfd41bULL,
0x79eb4982fba210b2ULL, 0x7427a7e99d80ba3aULL, 0x42bff093d14f6e21ULL,
0xf8425dd9211f637cULL, 0x1e864c5d43cac50fULL, 0x39db71dae3aa3892ULL,
0x2a91d3ecc6425715ULL
};
static const u64 T6[256] = {
0x6a01bbb9d268bad3ULL, 0x66b1e59a4d1954fcULL, 0x14cde265bc932f71ULL,
0x1b512587cdb9749cULL, 0x57a4f7a2510253f5ULL, 0xbe03d0d66bb8d368ULL,
0xb504d6de6fbdd26bULL, 0x85feb35229644dd7ULL, 0x4aadfdba5d0d50f0ULL,
0xe063cf098a26ace9ULL, 0x9684091c0e838d8aULL, 0x4d1aa591c679bfdcULL,
0x374d3da7ddad7090ULL, 0x5ca3f1aa550752f6ULL, 0x17e17ba452c89ab3ULL,
0x8ef9b55a2d614cd4ULL, 0x20ac46038f65ea23ULL, 0x8411c4e673a6d562ULL,
0x68c255cc66f197a4ULL, 0xa80ddcc663b2d16eULL, 0xd099aa85ccff3355ULL,
0x41aafbb2590851f3ULL, 0x0f9cc7e2712a5bedULL, 0xae55f359a204a6f7ULL,
0xc120febe5f81de7fULL, 0xa2e5ad7a3d7548d8ULL, 0xcc7fd7299a32a8e5ULL,
0x0ae871bc5ec799b6ULL, 0xe63be0964b90db70ULL, 0xdb9eac8dc8fa3256ULL,
0x152295d1e651b7c4ULL, 0xaace32b3d72bfc19ULL, 0x7393704bab48e338ULL,
0x3bfd638442dc9ebfULL, 0x52d041fc7eef91aeULL, 0x1ce67dac56cd9bb0ULL,
0x78947643af4de23bULL, 0x6106bdb1d66dbbd0ULL, 0xf1da9b32195841c3ULL,
0xe5177957a5cb6eb2ULL, 0xb35cf941ae0ba5f2ULL, 0x564b80160bc0cb40ULL,
0xc20c677fb1da6bbdULL, 0x7ecc59dc6efb95a2ULL, 0x9f40e161be1fa1feULL,
0xc3e310cbeb18f308ULL, 0x2f3081e1fe4fb1ceULL, 0x160e0c10080a0206ULL,
0x675e922e17dbcc49ULL, 0x3f66a26e37f3c451ULL, 0xcf534ee874691d27ULL,
0x9c6c78a05044143cULL, 0x0e73b0562be8c358ULL, 0x9a34573f91f263a5ULL,
0xed3ce69e4f95da73ULL, 0x358ed3d269345de7ULL, 0x2380dfc2613e5fe1ULL,
0xd72ef2ae578bdc79ULL, 0x486e13cfe9947d87ULL, 0x6c59942613decd4aULL,
0x5e601fdfe19e7f81ULL, 0x049bc1ea752f5aeeULL, 0xf3197547adc16cb4ULL,
0x3e89d5da6d315ce4ULL, 0xefff08ebfb0cf704ULL, 0x47f2d42d98be266aULL,
0xb7c738abdb24ff1cULL, 0x11b9543b937eed2aULL, 0x36a24a13876fe825ULL,
0x26f4699c4ed39dbaULL, 0xee107f5fa1ce6fb1ULL, 0x8b8d0304028c8e8fULL,
0xe34f56c8647d192bULL, 0x9447e769ba1aa0fdULL, 0xdeea1ad3e717f00dULL,
0xba98113c1e978986ULL, 0x692d22783c330f11ULL, 0x311512381c1b0709ULL,
0xfd6ac5118629afecULL, 0x9bdb208bcb30fb10ULL, 0x5838304020280818ULL,
0x976b7ea85441153fULL, 0x7f232e6834390d17ULL, 0x2c1c18201014040cULL,
0x0b07060804050103ULL, 0xab2145078de964acULL, 0xca27f8b65b84df7cULL,
0x0d5f2997c5b3769aULL, 0x64720beff980798bULL, 0xdc29f4a6538edd7aULL,
0xb2b38ef5f4c93d47ULL, 0x8a6274b0584e163aULL, 0xa4bd82e5fcc33f41ULL,
0xfc85b2a5dceb3759ULL, 0xf81e734fa9c46db7ULL, 0x95a890dde0d83848ULL,
0x7708b1a1de67b9d6ULL, 0x2a4437bfd1a27395ULL, 0x3da54c1b836ae926ULL,
0xea8bbeb5d4e1355fULL, 0x6db6e392491c55ffULL, 0x3c4a3bafd9a87193ULL,
0x727c07fff18a7b8dULL, 0x9d830f140a868c89ULL, 0x214331b7d5a77296ULL,
0xb19f17341a928885ULL, 0xe4f80ee3ff09f607ULL, 0x33d6fc4da8822a7eULL,
0xafba84edf8c63e42ULL, 0x2887d9ca653b5ee2ULL, 0x4cf5d2259cbb2769ULL,
0xc0cf890a054346caULL, 0x74242860303c0c14ULL, 0xa026430f89ec65afULL,
0xdf056d67bdd568b8ULL, 0x8c3a5b2f99f861a3ULL, 0x1d090a180c0f0305ULL,
0x187dbc4623e2c15eULL, 0x7bb8ef82411657f9ULL, 0x9918cefe7fa9d667ULL,
0xf035ec86439ad976ULL, 0x1295cdfa7d2558e8ULL, 0xfb32ea8e479fd875ULL,
0xbd2f491785e366aaULL, 0x921fc8f67bacd764ULL, 0x83a69ccde8d23a4eULL,
0x4b428a0e07cfc845ULL, 0xb9b488fdf0cc3c44ULL, 0x90dc2683cf35fa13ULL,
0x63c553c462f496a7ULL, 0xa552f551a601a7f4ULL, 0x01ef77b45ac298b5ULL,
0x1abe5233977bec29ULL, 0x7c0fb7a9da62b8d5ULL, 0x226fa8763bfcc754ULL,
0xf66dc319822caeefULL, 0xd4026b6fb9d069bbULL, 0xbfeca762317a4bddULL,
0xd176dd31963dabe0ULL, 0xc778d1219e37a9e6ULL, 0xb6284f1f81e667a9ULL,
0x4e363c5028220a1eULL, 0xcbc88f02014647c9ULL, 0xc8e416c3ef1df20bULL,
0x032c99c1ee5bb5c2ULL, 0x6beecc0d88aa2266ULL, 0x4981647bb356e532ULL,
0x0cb05e239f71ee2fULL, 0x461da399c27cbedfULL, 0x38d1fa45ac872b7dULL,
0xe2a0217c3ebf819eULL, 0xa67e6c90485a1236ULL, 0xf4ae2d6c36b58398ULL,
0xf5415ad86c771b2dULL, 0x622a247038360e12ULL, 0x60e9ca058caf2365ULL,
0xf9f104fbf306f502ULL, 0xddc68312094c45cfULL, 0x76e7c61584a52163ULL,
0x71509e3e1fd1ce4fULL, 0xa9e2ab72397049dbULL, 0x09c4e87db09c2c74ULL,
0x8dd52c9bc33af916ULL, 0x54886e63bf59e637ULL, 0x1e2593d9e254b6c7ULL,
0x25d8f05da0882878ULL, 0x816572b85c4b1739ULL, 0xffa92b6432b0829bULL,
0xfe465cd068721a2eULL, 0xac961d2c169d8b80ULL, 0xbcc03ea3df21fe1fULL,
0xa7911b2412988a83ULL, 0x533f3648242d091bULL, 0x40458c0603cac946ULL,
0xd8b2354c26a18794ULL, 0x98f7b94a256b4ed2ULL, 0x659d7c5ba342e13eULL,
0x1fcae46db8962e72ULL, 0x42866273b753e431ULL, 0x6e9a7a53a747e03dULL,
0x2bab400b8b60eb20ULL, 0x59d747f47aea90adULL, 0xb85bff49aa0ea4f1ULL,
0xd25a44f078661e22ULL, 0xcebc395c2eab8592ULL, 0x873d5d279dfd60a0ULL,
0x0000000000000000ULL, 0x5afbde3594b1256fULL, 0xf2f602f3f703f401ULL,
0xd5ed1cdbe312f10eULL, 0x75cb5fd46afe94a1ULL, 0x45313a582c270b1dULL,
0x5f8f686bbb5ce734ULL, 0x1056238fc9bc759fULL, 0x07b7582b9b74ef2cULL,
0xe18cb8bdd0e4345cULL, 0xc697a695c4f53153ULL, 0x8f16c2ee77a3d461ULL,
0xa30adace67b7d06dULL, 0xd3b5334422a48697ULL, 0x556719d7e59b7e82ULL,
0xeb64c9018e23adeaULL, 0xa1c934bbd32efd1aULL, 0x2edff655a48d297bULL,
0xcd90a09dc0f03050ULL, 0x88a19ac5ecd73b4dULL, 0x30fa658c46d99fbcULL,
0x86d22a93c73ff815ULL, 0x2968ae7e3ff9c657ULL, 0xad796a984c5f1335ULL,
0x3a121430181e060aULL, 0x271b1e281411050fULL, 0x3461a46633f6c552ULL,
0xbb77668844551133ULL, 0x06582f9fc1b67799ULL, 0x436915c7ed917c84ULL,
0x797b01f7f58f7a8eULL, 0x6f750de7fd857888ULL, 0xf782b4add8ee365aULL,
0xc45448e0706c1c24ULL, 0x9eaf96d5e4dd394bULL, 0x1992cbf2792059ebULL,
0xe84850c060781828ULL, 0x70bfe98a451356faULL, 0x393e8df1f645b3c8ULL,
0x243787e9fa4ab0cdULL, 0x51fcd83d90b4246cULL, 0x7de0c01d80a02060ULL,
0x32398bf9f240b2cbULL, 0x4fd94be472e092abULL, 0x894eed71b615a3f8ULL,
0x137aba4e27e7c05dULL, 0xd6c1851a0d4944ccULL, 0x9133513795f762a6ULL,
0xb070608040501030ULL, 0x082b9fc9ea5eb4c1ULL, 0xc5bb3f542aae8491ULL,
0xe7d49722115243c5ULL, 0x44de4dec76e593a8ULL, 0x0574b65e2fedc25bULL,
0xb4eba16a357f4adeULL, 0x5b14a981ce73bddaULL, 0x808a050c06898f8cULL,
0x02c3ee75b4992d77ULL, 0x5013af89ca76bcd9ULL, 0x2df36f944ad69cb9ULL,
0xc90b6177b5df6abeULL, 0xfadd9d3a1d5d40c0ULL, 0x7a5798361bd4cf4cULL,
0x8249eb79b210a2fbULL, 0xe9a727743aba809dULL, 0x93f0bf42216e4fd1ULL,
0xd95d42f87c631f21ULL, 0x5d4c861e0fc5ca43ULL, 0xda71db399238aae3ULL,
0xecd3912a155742c6ULL
};
static const u64 T7[256] = {
0x016ab9bb68d2d3baULL, 0xb1669ae5194dfc54ULL, 0xcd1465e293bc712fULL,
0x511b8725b9cd9c74ULL, 0xa457a2f70251f553ULL, 0x03bed6d0b86b68d3ULL,
0x04b5ded6bd6f6bd2ULL, 0xfe8552b36429d74dULL, 0xad4abafd0d5df050ULL,
0x63e009cf268ae9acULL, 0x84961c09830e8a8dULL, 0x1a4d91a579c6dcbfULL,
0x4d37a73daddd9070ULL, 0xa35caaf10755f652ULL, 0xe117a47bc852b39aULL,
0xf98e5ab5612dd44cULL, 0xac200346658f23eaULL, 0x1184e6c4a67362d5ULL,
0xc268cc55f166a497ULL, 0x0da8c6dcb2636ed1ULL, 0x99d085aaffcc5533ULL,
0xaa41b2fb0859f351ULL, 0x9c0fe2c72a71ed5bULL, 0x55ae59f304a2f7a6ULL,
0x20c1befe815f7fdeULL, 0xe5a27aad753dd848ULL, 0x7fcc29d7329ae5a8ULL,
0xe80abc71c75eb699ULL, 0x3be696e0904b70dbULL, 0x9edb8dacfac85632ULL,
0x2215d19551e6c4b7ULL, 0xceaab3322bd719fcULL, 0x93734b7048ab38e3ULL,
0xfd3b8463dc42bf9eULL, 0xd052fc41ef7eae91ULL, 0xe61cac7dcd56b09bULL,
0x947843764daf3be2ULL, 0x0661b1bd6dd6d0bbULL, 0xdaf1329b5819c341ULL,
0x17e55779cba5b26eULL, 0x5cb341f90baef2a5ULL, 0x4b561680c00b40cbULL,
0x0cc27f67dab1bd6bULL, 0xcc7edc59fb6ea295ULL, 0x409f61e11fbefea1ULL,
0xe3c3cb1018eb08f3ULL, 0x302fe1814ffeceb1ULL, 0x0e16100c0a080602ULL,
0x5e672e92db1749ccULL, 0x663f6ea2f33751c4ULL, 0x53cfe84e6974271dULL,
0x6c9ca07844503c14ULL, 0x730e56b0e82b58c3ULL, 0x349a3f57f291a563ULL,
0x3ced9ee6954f73daULL, 0x8e35d2d33469e75dULL, 0x8023c2df3e61e15fULL,
0x2ed7aef28b5779dcULL, 0x6e48cf1394e9877dULL, 0x596c2694de134acdULL,
0x605edf1f9ee1817fULL, 0x9b04eac12f75ee5aULL, 0x19f34775c1adb46cULL,
0x893edad5316de45cULL, 0xffefeb080cfb04f7ULL, 0xf2472dd4be986a26ULL,
0xc7b7ab3824db1cffULL, 0xb9113b547e932aedULL, 0xa236134a6f8725e8ULL,
0xf4269c69d34eba9dULL, 0x10ee5f7fcea1b16fULL, 0x8d8b04038c028f8eULL,
0x4fe3c8567d642b19ULL, 0x479469e71abafda0ULL, 0xeaded31a17e70df0ULL,
0x98ba3c11971e8689ULL, 0x2d697822333c110fULL, 0x153138121b1c0907ULL,
0x6afd11c52986ecafULL, 0xdb9b8b2030cb10fbULL, 0x3858403028201808ULL,
0x6b97a87e41543f15ULL, 0x237f682e3934170dULL, 0x1c2c201814100c04ULL,
0x070b080605040301ULL, 0x21ab0745e98dac64ULL, 0x27cab6f8845b7cdfULL,
0x5f0d9729b3c59a76ULL, 0x7264ef0b80f98b79ULL, 0x29dca6f48e537addULL,
0xb3b2f58ec9f4473dULL, 0x628ab0744e583a16ULL, 0xbda4e582c3fc413fULL,
0x85fca5b2ebdc5937ULL, 0x1ef84f73c4a9b76dULL, 0xa895dd90d8e04838ULL,
0x0877a1b167ded6b9ULL, 0x442abf37a2d19573ULL, 0xa53d1b4c6a8326e9ULL,
0x8beab5bee1d45f35ULL, 0xb66d92e31c49ff55ULL, 0x4a3caf3ba8d99371ULL,
0x7c72ff078af18d7bULL, 0x839d140f860a898cULL, 0x4321b731a7d59672ULL,
0x9fb13417921a8588ULL, 0xf8e4e30e09ff07f6ULL, 0xd6334dfc82a87e2aULL,
0xbaafed84c6f8423eULL, 0x8728cad93b65e25eULL, 0xf54c25d2bb9c6927ULL,
0xcfc00a894305ca46ULL, 0x247460283c30140cULL, 0x26a00f43ec89af65ULL,
0x05df676dd5bdb868ULL, 0x3a8c2f5bf899a361ULL, 0x091d180a0f0c0503ULL,
0x7d1846bce2235ec1ULL, 0xb87b82ef1641f957ULL, 0x1899fecea97f67d6ULL,
0x35f086ec9a4376d9ULL, 0x9512facd257de858ULL, 0x32fb8eea9f4775d8ULL,
0x2fbd1749e385aa66ULL, 0x1f92f6c8ac7b64d7ULL, 0xa683cd9cd2e84e3aULL,
0x424b0e8acf0745c8ULL, 0xb4b9fd88ccf0443cULL, 0xdc90832635cf13faULL,
0xc563c453f462a796ULL, 0x52a551f501a6f4a7ULL, 0xef01b477c25ab598ULL,
0xbe1a33527b9729ecULL, 0x0f7ca9b762dad5b8ULL, 0x6f2276a8fc3b54c7ULL,
0x6df619c32c82efaeULL, 0x02d46f6bd0b9bb69ULL, 0xecbf62a77a31dd4bULL,
0x76d131dd3d96e0abULL, 0x78c721d1379ee6a9ULL, 0x28b61f4fe681a967ULL,
0x364e503c22281e0aULL, 0xc8cb028f4601c947ULL, 0xe4c8c3161def0bf2ULL,
0x2c03c1995beec2b5ULL, 0xee6b0dccaa886622ULL, 0x81497b6456b332e5ULL,
0xb00c235e719f2feeULL, 0x1d4699a37cc2dfbeULL, 0xd13845fa87ac7d2bULL,
0xa0e27c21bf3e9e81ULL, 0x7ea6906c5a483612ULL, 0xaef46c2db5369883ULL,
0x41f5d85a776c2d1bULL, 0x2a6270243638120eULL, 0xe96005caaf8c6523ULL,
0xf1f9fb0406f302f5ULL, 0xc6dd12834c09cf45ULL, 0xe77615c6a5846321ULL,
0x50713e9ed11f4fceULL, 0xe2a972ab7039db49ULL, 0xc4097de89cb0742cULL,
0xd58d9b2c3ac316f9ULL, 0x8854636e59bf37e6ULL, 0x251ed99354e2c7b6ULL,
0xd8255df088a07828ULL, 0x6581b8724b5c3917ULL, 0xa9ff642bb0329b82ULL,
0x46fed05c72682e1aULL, 0x96ac2c1d9d16808bULL, 0xc0bca33e21df1ffeULL,
0x91a7241b9812838aULL, 0x3f5348362d241b09ULL, 0x4540068cca0346c9ULL,
0xb2d84c35a1269487ULL, 0xf7984ab96b25d24eULL, 0x9d655b7c42a33ee1ULL,
0xca1f6de496b8722eULL, 0x8642736253b731e4ULL, 0x9a6e537a47a73de0ULL,
0xab2b0b40608b20ebULL, 0xd759f447ea7aad90ULL, 0x5bb849ff0eaaf1a4ULL,
0x5ad2f0446678221eULL, 0xbcce5c39ab2e9285ULL, 0x3d87275dfd9da060ULL,
0x0000000000000000ULL, 0xfb5a35deb1946f25ULL, 0xf6f2f30203f701f4ULL,
0xedd5db1c12e30ef1ULL, 0xcb75d45ffe6aa194ULL, 0x3145583a272c1d0bULL,
0x8f5f6b685cbb34e7ULL, 0x56108f23bcc99f75ULL, 0xb7072b58749b2cefULL,
0x8ce1bdb8e4d05c34ULL, 0x97c695a6f5c45331ULL, 0x168feec2a37761d4ULL,
0x0aa3cedab7676dd0ULL, 0xb5d34433a4229786ULL, 0x6755d7199be5827eULL,
0x64eb01c9238eeaadULL, 0xc9a1bb342ed31afdULL, 0xdf2e55f68da47b29ULL,
0x90cd9da0f0c05030ULL, 0xa188c59ad7ec4d3bULL, 0xfa308c65d946bc9fULL,
0xd286932a3fc715f8ULL, 0x68297eaef93f57c6ULL, 0x79ad986a5f4c3513ULL,
0x123a30141e180a06ULL, 0x1b27281e11140f05ULL, 0x613466a4f63352c5ULL,
0x77bb886655443311ULL, 0x58069f2fb6c19977ULL, 0x6943c71591ed847cULL,
0x7b79f7018ff58e7aULL, 0x756fe70d85fd8878ULL, 0x82f7adb4eed85a36ULL,
0x54c4e0486c70241cULL, 0xaf9ed596dde44b39ULL, 0x9219f2cb2079eb59ULL,
0x48e8c05078602818ULL, 0xbf708ae91345fa56ULL, 0x3e39f18d45f6c8b3ULL,
0x3724e9874afacdb0ULL, 0xfc513dd8b4906c24ULL, 0xe07d1dc0a0806020ULL,
0x3932f98b40f2cbb2ULL, 0xd94fe44be072ab92ULL, 0x4e8971ed15b6f8a3ULL,
0x7a134ebae7275dc0ULL, 0xc1d61a85490dcc44ULL, 0x33913751f795a662ULL,
0x70b0806050403010ULL, 0x2b08c99f5eeac1b4ULL, 0xbbc5543fae2a9184ULL,
0xd4e722975211c543ULL, 0xde44ec4de576a893ULL, 0x74055eb6ed2f5bc2ULL,
0xebb46aa17f35de4aULL, 0x145b81a973cedabdULL, 0x8a800c0589068c8fULL,
0xc30275ee99b4772dULL, 0x135089af76cad9bcULL, 0xf32d946fd64ab99cULL,
0x0bc97761dfb5be6aULL, 0xddfa3a9d5d1dc040ULL, 0x577a3698d41b4ccfULL,
0x498279eb10b2fba2ULL, 0xa7e97427ba3a9d80ULL, 0xf09342bf6e21d14fULL,
0x5dd9f842637c211fULL, 0x4c5d1e86c50f43caULL, 0x71da39db3892e3aaULL,
0xd3ec2a915715c642ULL
};
static const u64 c[KHAZAD_ROUNDS + 1] = {
0xba542f7453d3d24dULL, 0x50ac8dbf70529a4cULL, 0xead597d133515ba6ULL,
0xde48a899db32b7fcULL, 0xe39e919be2bb416eULL, 0xa5cb6b95a1f3b102ULL,
0xccc41d14c363da5dULL, 0x5fdc7dcd7f5a6c5cULL, 0xf726ffede89d6f8eULL
};
static int khazad_setkey(void *ctx_arg, const u8 *in_key,
unsigned int key_len, u32 *flags)
{
struct khazad_ctx *ctx = ctx_arg;
int r;
const u64 *S = T7;
u64 K2, K1;
if (key_len != 16)
{
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
K2 = ((u64)in_key[ 0] << 56) ^
((u64)in_key[ 1] << 48) ^
((u64)in_key[ 2] << 40) ^
((u64)in_key[ 3] << 32) ^
((u64)in_key[ 4] << 24) ^
((u64)in_key[ 5] << 16) ^
((u64)in_key[ 6] << 8) ^
((u64)in_key[ 7] );
K1 = ((u64)in_key[ 8] << 56) ^
((u64)in_key[ 9] << 48) ^
((u64)in_key[10] << 40) ^
((u64)in_key[11] << 32) ^
((u64)in_key[12] << 24) ^
((u64)in_key[13] << 16) ^
((u64)in_key[14] << 8) ^
((u64)in_key[15] );
/* setup the encrypt key */
for (r = 0; r <= KHAZAD_ROUNDS; r++) {
ctx->E[r] = T0[(int)(K1 >> 56) ] ^
T1[(int)(K1 >> 48) & 0xff] ^
T2[(int)(K1 >> 40) & 0xff] ^
T3[(int)(K1 >> 32) & 0xff] ^
T4[(int)(K1 >> 24) & 0xff] ^
T5[(int)(K1 >> 16) & 0xff] ^
T6[(int)(K1 >> 8) & 0xff] ^
T7[(int)(K1 ) & 0xff] ^
c[r] ^ K2;
K2 = K1;
K1 = ctx->E[r];
}
/* Setup the decrypt key */
ctx->D[0] = ctx->E[KHAZAD_ROUNDS];
for (r = 1; r < KHAZAD_ROUNDS; r++) {
K1 = ctx->E[KHAZAD_ROUNDS - r];
ctx->D[r] = T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^
T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^
T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^
T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^
T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^
T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^
T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^
T7[(int)S[(int)(K1 ) & 0xff] & 0xff];
}
ctx->D[KHAZAD_ROUNDS] = ctx->E[0];
return 0;
}
static void khazad_crypt(const u64 roundKey[KHAZAD_ROUNDS + 1],
u8 *ciphertext, const u8 *plaintext)
{
int r;
u64 state;
state = ((u64)plaintext[0] << 56) ^
((u64)plaintext[1] << 48) ^
((u64)plaintext[2] << 40) ^
((u64)plaintext[3] << 32) ^
((u64)plaintext[4] << 24) ^
((u64)plaintext[5] << 16) ^
((u64)plaintext[6] << 8) ^
((u64)plaintext[7] ) ^
roundKey[0];
for (r = 1; r < KHAZAD_ROUNDS; r++) {
state = T0[(int)(state >> 56) ] ^
T1[(int)(state >> 48) & 0xff] ^
T2[(int)(state >> 40) & 0xff] ^
T3[(int)(state >> 32) & 0xff] ^
T4[(int)(state >> 24) & 0xff] ^
T5[(int)(state >> 16) & 0xff] ^
T6[(int)(state >> 8) & 0xff] ^
T7[(int)(state ) & 0xff] ^
roundKey[r];
}
state = (T0[(int)(state >> 56) ] & 0xff00000000000000ULL) ^
(T1[(int)(state >> 48) & 0xff] & 0x00ff000000000000ULL) ^
(T2[(int)(state >> 40) & 0xff] & 0x0000ff0000000000ULL) ^
(T3[(int)(state >> 32) & 0xff] & 0x000000ff00000000ULL) ^
(T4[(int)(state >> 24) & 0xff] & 0x00000000ff000000ULL) ^
(T5[(int)(state >> 16) & 0xff] & 0x0000000000ff0000ULL) ^
(T6[(int)(state >> 8) & 0xff] & 0x000000000000ff00ULL) ^
(T7[(int)(state ) & 0xff] & 0x00000000000000ffULL) ^
roundKey[KHAZAD_ROUNDS];
ciphertext[0] = (u8)(state >> 56);
ciphertext[1] = (u8)(state >> 48);
ciphertext[2] = (u8)(state >> 40);
ciphertext[3] = (u8)(state >> 32);
ciphertext[4] = (u8)(state >> 24);
ciphertext[5] = (u8)(state >> 16);
ciphertext[6] = (u8)(state >> 8);
ciphertext[7] = (u8)(state );
}
static void khazad_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
struct khazad_ctx *ctx = ctx_arg;
khazad_crypt(ctx->E, dst, src);
}
static void khazad_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
struct khazad_ctx *ctx = ctx_arg;
khazad_crypt(ctx->D, dst, src);
}
static struct crypto_alg khazad_alg = {
.cra_name = "khazad",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = KHAZAD_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct khazad_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(khazad_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = KHAZAD_KEY_SIZE,
.cia_max_keysize = KHAZAD_KEY_SIZE,
.cia_setkey = khazad_setkey,
.cia_encrypt = khazad_encrypt,
.cia_decrypt = khazad_decrypt } }
};
static int __init init(void)
{
int ret = 0;
ret = crypto_register_alg(&khazad_alg);
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&khazad_alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Khazad Cryptographic Algorithm");

View File

@@ -0,0 +1,250 @@
/*
* Cryptographic API.
*
* MD4 Message Digest Algorithm (RFC1320).
*
* Implementation derived from Andrew Tridgell and Steve French's
* CIFS MD4 implementation, and the cryptoapi implementation
* originally based on the public domain implementation written
* by Colin Plumb in 1993.
*
* Copyright (c) Andrew Tridgell 1997-1998.
* Modified by Steve French (sfrench@us.ibm.com) 2002
* Copyright (c) Cryptoapi developers.
* Copyright (c) 2002 David S. Miller (davem@redhat.com)
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/crypto.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/byteorder.h>
#define MD4_DIGEST_SIZE 16
#define MD4_HMAC_BLOCK_SIZE 64
#define MD4_BLOCK_WORDS 16
#define MD4_HASH_WORDS 4
struct md4_ctx {
u32 hash[MD4_HASH_WORDS];
u32 block[MD4_BLOCK_WORDS];
u64 byte_count;
};
static inline u32 lshift(u32 x, unsigned int s)
{
x &= 0xFFFFFFFF;
return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
}
static inline u32 F(u32 x, u32 y, u32 z)
{
return (x & y) | ((~x) & z);
}
static inline u32 G(u32 x, u32 y, u32 z)
{
return (x & y) | (x & z) | (y & z);
}
static inline u32 H(u32 x, u32 y, u32 z)
{
return x ^ y ^ z;
}
#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
/* XXX: this stuff can be optimized */
static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
{
while (words--) {
__le32_to_cpus(buf);
buf++;
}
}
static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
{
while (words--) {
__cpu_to_le32s(buf);
buf++;
}
}
static void md4_transform(u32 *hash, u32 const *in)
{
u32 a, b, c, d;
a = hash[0];
b = hash[1];
c = hash[2];
d = hash[3];
ROUND1(a, b, c, d, in[0], 3);
ROUND1(d, a, b, c, in[1], 7);
ROUND1(c, d, a, b, in[2], 11);
ROUND1(b, c, d, a, in[3], 19);
ROUND1(a, b, c, d, in[4], 3);
ROUND1(d, a, b, c, in[5], 7);
ROUND1(c, d, a, b, in[6], 11);
ROUND1(b, c, d, a, in[7], 19);
ROUND1(a, b, c, d, in[8], 3);
ROUND1(d, a, b, c, in[9], 7);
ROUND1(c, d, a, b, in[10], 11);
ROUND1(b, c, d, a, in[11], 19);
ROUND1(a, b, c, d, in[12], 3);
ROUND1(d, a, b, c, in[13], 7);
ROUND1(c, d, a, b, in[14], 11);
ROUND1(b, c, d, a, in[15], 19);
ROUND2(a, b, c, d,in[ 0], 3);
ROUND2(d, a, b, c, in[4], 5);
ROUND2(c, d, a, b, in[8], 9);
ROUND2(b, c, d, a, in[12], 13);
ROUND2(a, b, c, d, in[1], 3);
ROUND2(d, a, b, c, in[5], 5);
ROUND2(c, d, a, b, in[9], 9);
ROUND2(b, c, d, a, in[13], 13);
ROUND2(a, b, c, d, in[2], 3);
ROUND2(d, a, b, c, in[6], 5);
ROUND2(c, d, a, b, in[10], 9);
ROUND2(b, c, d, a, in[14], 13);
ROUND2(a, b, c, d, in[3], 3);
ROUND2(d, a, b, c, in[7], 5);
ROUND2(c, d, a, b, in[11], 9);
ROUND2(b, c, d, a, in[15], 13);
ROUND3(a, b, c, d,in[ 0], 3);
ROUND3(d, a, b, c, in[8], 9);
ROUND3(c, d, a, b, in[4], 11);
ROUND3(b, c, d, a, in[12], 15);
ROUND3(a, b, c, d, in[2], 3);
ROUND3(d, a, b, c, in[10], 9);
ROUND3(c, d, a, b, in[6], 11);
ROUND3(b, c, d, a, in[14], 15);
ROUND3(a, b, c, d, in[1], 3);
ROUND3(d, a, b, c, in[9], 9);
ROUND3(c, d, a, b, in[5], 11);
ROUND3(b, c, d, a, in[13], 15);
ROUND3(a, b, c, d, in[3], 3);
ROUND3(d, a, b, c, in[11], 9);
ROUND3(c, d, a, b, in[7], 11);
ROUND3(b, c, d, a, in[15], 15);
hash[0] += a;
hash[1] += b;
hash[2] += c;
hash[3] += d;
}
static inline void md4_transform_helper(struct md4_ctx *ctx)
{
le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
md4_transform(ctx->hash, ctx->block);
}
static void md4_init(void *ctx)
{
struct md4_ctx *mctx = ctx;
mctx->hash[0] = 0x67452301;
mctx->hash[1] = 0xefcdab89;
mctx->hash[2] = 0x98badcfe;
mctx->hash[3] = 0x10325476;
mctx->byte_count = 0;
}
static void md4_update(void *ctx, const u8 *data, unsigned int len)
{
struct md4_ctx *mctx = ctx;
const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
mctx->byte_count += len;
if (avail > len) {
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
data, len);
return;
}
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
data, avail);
md4_transform_helper(mctx);
data += avail;
len -= avail;
while (len >= sizeof(mctx->block)) {
memcpy(mctx->block, data, sizeof(mctx->block));
md4_transform_helper(mctx);
data += sizeof(mctx->block);
len -= sizeof(mctx->block);
}
memcpy(mctx->block, data, len);
}
static void md4_final(void *ctx, u8 *out)
{
struct md4_ctx *mctx = ctx;
const unsigned int offset = mctx->byte_count & 0x3f;
char *p = (char *)mctx->block + offset;
int padding = 56 - (offset + 1);
*p++ = 0x80;
if (padding < 0) {
memset(p, 0x00, padding + sizeof (u64));
md4_transform_helper(mctx);
p = (char *)mctx->block;
padding = 56;
}
memset(p, 0, padding);
mctx->block[14] = mctx->byte_count << 3;
mctx->block[15] = mctx->byte_count >> 29;
le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
sizeof(u64)) / sizeof(u32));
md4_transform(mctx->hash, mctx->block);
cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
memcpy(out, mctx->hash, sizeof(mctx->hash));
memset(mctx, 0, sizeof(*mctx));
}
static struct crypto_alg alg = {
.cra_name = "md4",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = MD4_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct md4_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = MD4_DIGEST_SIZE,
.dia_init = md4_init,
.dia_update = md4_update,
.dia_final = md4_final } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD4 Message Digest Algorithm");

View File

@@ -0,0 +1,244 @@
/*
* Cryptographic API.
*
* MD5 Message Digest Algorithm (RFC1321).
*
* Derived from cryptoapi implementation, originally based on the
* public domain implementation written by Colin Plumb in 1993.
*
* Copyright (c) Cryptoapi developers.
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <asm/byteorder.h>
#define MD5_DIGEST_SIZE 16
#define MD5_HMAC_BLOCK_SIZE 64
#define MD5_BLOCK_WORDS 16
#define MD5_HASH_WORDS 4
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
#define MD5STEP(f, w, x, y, z, in, s) \
(w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
struct md5_ctx {
u32 hash[MD5_HASH_WORDS];
u32 block[MD5_BLOCK_WORDS];
u64 byte_count;
};
static void md5_transform(u32 *hash, u32 const *in)
{
u32 a, b, c, d;
a = hash[0];
b = hash[1];
c = hash[2];
d = hash[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
hash[0] += a;
hash[1] += b;
hash[2] += c;
hash[3] += d;
}
/* XXX: this stuff can be optimized */
static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
{
while (words--) {
__le32_to_cpus(buf);
buf++;
}
}
static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
{
while (words--) {
__cpu_to_le32s(buf);
buf++;
}
}
static inline void md5_transform_helper(struct md5_ctx *ctx)
{
le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
md5_transform(ctx->hash, ctx->block);
}
static void md5_init(void *ctx)
{
struct md5_ctx *mctx = ctx;
mctx->hash[0] = 0x67452301;
mctx->hash[1] = 0xefcdab89;
mctx->hash[2] = 0x98badcfe;
mctx->hash[3] = 0x10325476;
mctx->byte_count = 0;
}
static void md5_update(void *ctx, const u8 *data, unsigned int len)
{
struct md5_ctx *mctx = ctx;
const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
mctx->byte_count += len;
if (avail > len) {
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
data, len);
return;
}
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
data, avail);
md5_transform_helper(mctx);
data += avail;
len -= avail;
while (len >= sizeof(mctx->block)) {
memcpy(mctx->block, data, sizeof(mctx->block));
md5_transform_helper(mctx);
data += sizeof(mctx->block);
len -= sizeof(mctx->block);
}
memcpy(mctx->block, data, len);
}
static void md5_final(void *ctx, u8 *out)
{
struct md5_ctx *mctx = ctx;
const unsigned int offset = mctx->byte_count & 0x3f;
char *p = (char *)mctx->block + offset;
int padding = 56 - (offset + 1);
*p++ = 0x80;
if (padding < 0) {
memset(p, 0x00, padding + sizeof (u64));
md5_transform_helper(mctx);
p = (char *)mctx->block;
padding = 56;
}
memset(p, 0, padding);
mctx->block[14] = mctx->byte_count << 3;
mctx->block[15] = mctx->byte_count >> 29;
le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
sizeof(u64)) / sizeof(u32));
md5_transform(mctx->hash, mctx->block);
cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
memcpy(out, mctx->hash, sizeof(mctx->hash));
memset(mctx, 0, sizeof(*mctx));
}
static struct crypto_alg alg = {
.cra_name = "md5",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct md5_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = MD5_DIGEST_SIZE,
.dia_init = md5_init,
.dia_update = md5_update,
.dia_final = md5_final } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD5 Message Digest Algorithm");

View File

@@ -0,0 +1,193 @@
/*
* Cryptographic API
*
* Michael MIC (IEEE 802.11i/TKIP) keyed digest
*
* Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/crypto.h>
struct michael_mic_ctx {
u8 pending[4];
size_t pending_len;
u32 l, r;
};
static inline u32 rotl(u32 val, int bits)
{
return (val << bits) | (val >> (32 - bits));
}
static inline u32 rotr(u32 val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
static inline u32 xswap(u32 val)
{
return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
}
#define michael_block(l, r) \
do { \
r ^= rotl(l, 17); \
l += r; \
r ^= xswap(l); \
l += r; \
r ^= rotl(l, 3); \
l += r; \
r ^= rotr(l, 2); \
l += r; \
} while (0)
static inline u32 get_le32(const u8 *p)
{
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
static inline void put_le32(u8 *p, u32 v)
{
p[0] = v;
p[1] = v >> 8;
p[2] = v >> 16;
p[3] = v >> 24;
}
static void michael_init(void *ctx)
{
struct michael_mic_ctx *mctx = ctx;
mctx->pending_len = 0;
}
static void michael_update(void *ctx, const u8 *data, unsigned int len)
{
struct michael_mic_ctx *mctx = ctx;
if (mctx->pending_len) {
int flen = 4 - mctx->pending_len;
if (flen > len)
flen = len;
memcpy(&mctx->pending[mctx->pending_len], data, flen);
mctx->pending_len += flen;
data += flen;
len -= flen;
if (mctx->pending_len < 4)
return;
mctx->l ^= get_le32(mctx->pending);
michael_block(mctx->l, mctx->r);
mctx->pending_len = 0;
}
while (len >= 4) {
mctx->l ^= get_le32(data);
michael_block(mctx->l, mctx->r);
data += 4;
len -= 4;
}
if (len > 0) {
mctx->pending_len = len;
memcpy(mctx->pending, data, len);
}
}
static void michael_final(void *ctx, u8 *out)
{
struct michael_mic_ctx *mctx = ctx;
u8 *data = mctx->pending;
/* Last block and padding (0x5a, 4..7 x 0) */
switch (mctx->pending_len) {
case 0:
mctx->l ^= 0x5a;
break;
case 1:
mctx->l ^= data[0] | 0x5a00;
break;
case 2:
mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
break;
case 3:
mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
0x5a000000;
break;
}
michael_block(mctx->l, mctx->r);
/* l ^= 0; */
michael_block(mctx->l, mctx->r);
put_le32(out, mctx->l);
put_le32(out + 4, mctx->r);
}
static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
u32 *flags)
{
struct michael_mic_ctx *mctx = ctx;
if (keylen != 8) {
if (flags)
*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
mctx->l = get_le32(key);
mctx->r = get_le32(key + 4);
return 0;
}
static struct crypto_alg michael_mic_alg = {
.cra_name = "michael_mic",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = 8,
.cra_ctxsize = sizeof(struct michael_mic_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = 8,
.dia_init = michael_init,
.dia_update = michael_update,
.dia_final = michael_final,
.dia_setkey = michael_setkey } }
};
static int __init michael_mic_init(void)
{
return crypto_register_alg(&michael_mic_alg);
}
static void __exit michael_mic_exit(void)
{
crypto_unregister_alg(&michael_mic_alg);
}
module_init(michael_mic_init);
module_exit(michael_mic_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Michael MIC");
MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>");

View File

@@ -0,0 +1,112 @@
/*
* Scatterlist Cryptographic API.
*
* Procfs information.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/crypto.h>
#include <linux/rwsem.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "internal.h"
extern struct list_head crypto_alg_list;
extern struct rw_semaphore crypto_alg_sem;
static void *c_start(struct seq_file *m, loff_t *pos)
{
struct list_head *v;
loff_t n = *pos;
down_read(&crypto_alg_sem);
list_for_each(v, &crypto_alg_list)
if (!n--)
return list_entry(v, struct crypto_alg, cra_list);
return NULL;
}
static void *c_next(struct seq_file *m, void *p, loff_t *pos)
{
struct list_head *v = p;
(*pos)++;
v = v->next;
return (v == &crypto_alg_list) ?
NULL : list_entry(v, struct crypto_alg, cra_list);
}
static void c_stop(struct seq_file *m, void *p)
{
up_read(&crypto_alg_sem);
}
static int c_show(struct seq_file *m, void *p)
{
struct crypto_alg *alg = (struct crypto_alg *)p;
seq_printf(m, "name : %s\n", alg->cra_name);
seq_printf(m, "module : %s\n", module_name(alg->cra_module));
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_CIPHER:
seq_printf(m, "type : cipher\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "min keysize : %u\n",
alg->cra_cipher.cia_min_keysize);
seq_printf(m, "max keysize : %u\n",
alg->cra_cipher.cia_max_keysize);
break;
case CRYPTO_ALG_TYPE_DIGEST:
seq_printf(m, "type : digest\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n",
alg->cra_digest.dia_digestsize);
break;
case CRYPTO_ALG_TYPE_COMPRESS:
seq_printf(m, "type : compression\n");
break;
default:
seq_printf(m, "type : unknown\n");
break;
}
seq_putc(m, '\n');
return 0;
}
static struct seq_operations crypto_seq_ops = {
.start = c_start,
.next = c_next,
.stop = c_stop,
.show = c_show
};
static int crypto_info_open(struct inode *inode, struct file *file)
{
return seq_open(file, &crypto_seq_ops);
}
static struct file_operations proc_crypto_ops = {
.open = crypto_info_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
void __init crypto_init_proc(void)
{
struct proc_dir_entry *proc;
proc = create_proc_entry("crypto", 0, NULL);
if (proc)
proc->proc_fops = &proc_crypto_ops;
}

View File

@@ -0,0 +1,124 @@
/*
* Cryptographic API.
*
* Cipher operations.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* 2002 Adam J. Richter <adam@yggdrasil.com>
* 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/kernel.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <asm/scatterlist.h>
#include "internal.h"
#include "scatterwalk.h"
enum km_type crypto_km_types[] = {
KM_USER0,
KM_USER1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
};
void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
{
if (nbytes <= walk->len_this_page &&
(((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
PAGE_CACHE_SIZE)
return walk->data;
else
return scratch;
}
static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
{
if (out)
memcpy(sgdata, buf, nbytes);
else
memcpy(buf, sgdata, nbytes);
}
void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
{
unsigned int rest_of_page;
walk->sg = sg;
walk->page = sg->page;
walk->len_this_segment = sg->length;
rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
walk->len_this_page = min(sg->length, rest_of_page);
walk->offset = sg->offset;
}
void scatterwalk_map(struct scatter_walk *walk, int out)
{
walk->data = crypto_kmap(walk->page, out) + walk->offset;
}
static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
unsigned int more)
{
/* walk->data may be pointing the first byte of the next page;
however, we know we transfered at least one byte. So,
walk->data - 1 will be a virtual address in the mapped page. */
if (out)
flush_dcache_page(walk->page);
if (more) {
walk->len_this_segment -= walk->len_this_page;
if (walk->len_this_segment) {
walk->page++;
walk->len_this_page = min(walk->len_this_segment,
(unsigned)PAGE_CACHE_SIZE);
walk->offset = 0;
}
else
scatterwalk_start(walk, sg_next(walk->sg));
}
}
void scatterwalk_done(struct scatter_walk *walk, int out, int more)
{
crypto_kunmap(walk->data, out);
if (walk->len_this_page == 0 || !more)
scatterwalk_pagedone(walk, out, more);
}
/*
* Do not call this unless the total length of all of the fragments
* has been verified as multiple of the block size.
*/
int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
size_t nbytes, int out)
{
if (buf != walk->data) {
while (nbytes > walk->len_this_page) {
memcpy_dir(buf, walk->data, walk->len_this_page, out);
buf += walk->len_this_page;
nbytes -= walk->len_this_page;
crypto_kunmap(walk->data, out);
scatterwalk_pagedone(walk, out, 1);
scatterwalk_map(walk, out);
}
memcpy_dir(buf, walk->data, nbytes, out);
}
walk->offset += nbytes;
walk->len_this_page -= nbytes;
walk->len_this_segment -= nbytes;
return 0;
}

View File

@@ -0,0 +1,51 @@
/*
* Cryptographic API.
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
* Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
#ifndef _CRYPTO_SCATTERWALK_H
#define _CRYPTO_SCATTERWALK_H
#include <linux/mm.h>
#include <asm/scatterlist.h>
struct scatter_walk {
struct scatterlist *sg;
struct page *page;
void *data;
unsigned int len_this_page;
unsigned int len_this_segment;
unsigned int offset;
};
/* Define sg_next is an inline routine now in case we want to change
scatterlist to a linked list later. */
static inline struct scatterlist *sg_next(struct scatterlist *sg)
{
return sg + 1;
}
static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
struct scatter_walk *walk_out,
void *src_p, void *dst_p)
{
return walk_in->page == walk_out->page &&
walk_in->offset == walk_out->offset &&
walk_in->data == src_p && walk_out->data == dst_p;
}
void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
void scatterwalk_map(struct scatter_walk *walk, int out);
void scatterwalk_done(struct scatter_walk *walk, int out, int more);
#endif /* _CRYPTO_SCATTERWALK_H */

View File

@@ -0,0 +1,595 @@
/*
* Cryptographic API.
*
* Serpent Cipher Algorithm.
*
* Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
* 2003 Herbert Valerio Riedel <hvr@gnu.org>
*
* Added tnepres support: Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
* Based on code by hvr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <asm/byteorder.h>
#include <linux/crypto.h>
/* Key is padded to the maximum of 256 bits before round key generation.
* Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
*/
#define SERPENT_MIN_KEY_SIZE 0
#define SERPENT_MAX_KEY_SIZE 32
#define SERPENT_EXPKEY_WORDS 132
#define SERPENT_BLOCK_SIZE 16
#define PHI 0x9e3779b9UL
#define ROL(x,r) ((x) = ((x) << (r)) | ((x) >> (32-(r))))
#define ROR(x,r) ((x) = ((x) >> (r)) | ((x) << (32-(r))))
#define keyiter(a,b,c,d,i,j) \
b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; ROL(b,11); k[j] = b;
#define loadkeys(x0,x1,x2,x3,i) \
x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3];
#define storekeys(x0,x1,x2,x3,i) \
k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3;
#define K(x0,x1,x2,x3,i) \
x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \
x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0];
#define LK(x0,x1,x2,x3,x4,i) \
ROL(x0,13); \
ROL(x2,3); x1 ^= x0; x4 = x0 << 3; \
x3 ^= x2; x1 ^= x2; \
ROL(x1,1); x3 ^= x4; \
ROL(x3,7); x4 = x1; \
x0 ^= x1; x4 <<= 7; x2 ^= x3; \
x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \
x1 ^= k[4*i+1]; ROL(x0,5); ROL(x2,22); \
x0 ^= k[4*i+0]; x2 ^= k[4*i+2];
#define KL(x0,x1,x2,x3,x4,i) \
x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \
x3 ^= k[4*i+3]; ROR(x0,5); ROR(x2,22); \
x4 = x1; x2 ^= x3; x0 ^= x3; \
x4 <<= 7; x0 ^= x1; ROR(x1,1); \
x2 ^= x4; ROR(x3,7); x4 = x0 << 3; \
x1 ^= x0; x3 ^= x4; ROR(x0,13); \
x1 ^= x2; x3 ^= x2; ROR(x2,3);
#define S0(x0,x1,x2,x3,x4) \
x4 = x3; \
x3 |= x0; x0 ^= x4; x4 ^= x2; \
x4 =~ x4; x3 ^= x1; x1 &= x0; \
x1 ^= x4; x2 ^= x0; x0 ^= x3; \
x4 |= x0; x0 ^= x2; x2 &= x1; \
x3 ^= x2; x1 =~ x1; x2 ^= x4; \
x1 ^= x2;
#define S1(x0,x1,x2,x3,x4) \
x4 = x1; \
x1 ^= x0; x0 ^= x3; x3 =~ x3; \
x4 &= x1; x0 |= x1; x3 ^= x2; \
x0 ^= x3; x1 ^= x3; x3 ^= x4; \
x1 |= x4; x4 ^= x2; x2 &= x0; \
x2 ^= x1; x1 |= x0; x0 =~ x0; \
x0 ^= x2; x4 ^= x1;
#define S2(x0,x1,x2,x3,x4) \
x3 =~ x3; \
x1 ^= x0; x4 = x0; x0 &= x2; \
x0 ^= x3; x3 |= x4; x2 ^= x1; \
x3 ^= x1; x1 &= x0; x0 ^= x2; \
x2 &= x3; x3 |= x1; x0 =~ x0; \
x3 ^= x0; x4 ^= x0; x0 ^= x2; \
x1 |= x2;
#define S3(x0,x1,x2,x3,x4) \
x4 = x1; \
x1 ^= x3; x3 |= x0; x4 &= x0; \
x0 ^= x2; x2 ^= x1; x1 &= x3; \
x2 ^= x3; x0 |= x4; x4 ^= x3; \
x1 ^= x0; x0 &= x3; x3 &= x4; \
x3 ^= x2; x4 |= x1; x2 &= x1; \
x4 ^= x3; x0 ^= x3; x3 ^= x2;
#define S4(x0,x1,x2,x3,x4) \
x4 = x3; \
x3 &= x0; x0 ^= x4; \
x3 ^= x2; x2 |= x4; x0 ^= x1; \
x4 ^= x3; x2 |= x0; \
x2 ^= x1; x1 &= x0; \
x1 ^= x4; x4 &= x2; x2 ^= x3; \
x4 ^= x0; x3 |= x1; x1 =~ x1; \
x3 ^= x0;
#define S5(x0,x1,x2,x3,x4) \
x4 = x1; x1 |= x0; \
x2 ^= x1; x3 =~ x3; x4 ^= x0; \
x0 ^= x2; x1 &= x4; x4 |= x3; \
x4 ^= x0; x0 &= x3; x1 ^= x3; \
x3 ^= x2; x0 ^= x1; x2 &= x4; \
x1 ^= x2; x2 &= x0; \
x3 ^= x2;
#define S6(x0,x1,x2,x3,x4) \
x4 = x1; \
x3 ^= x0; x1 ^= x2; x2 ^= x0; \
x0 &= x3; x1 |= x3; x4 =~ x4; \
x0 ^= x1; x1 ^= x2; \
x3 ^= x4; x4 ^= x0; x2 &= x0; \
x4 ^= x1; x2 ^= x3; x3 &= x1; \
x3 ^= x0; x1 ^= x2;
#define S7(x0,x1,x2,x3,x4) \
x1 =~ x1; \
x4 = x1; x0 =~ x0; x1 &= x2; \
x1 ^= x3; x3 |= x4; x4 ^= x2; \
x2 ^= x3; x3 ^= x0; x0 |= x1; \
x2 &= x0; x0 ^= x4; x4 ^= x3; \
x3 &= x0; x4 ^= x1; \
x2 ^= x4; x3 ^= x1; x4 |= x0; \
x4 ^= x1;
#define SI0(x0,x1,x2,x3,x4) \
x4 = x3; x1 ^= x0; \
x3 |= x1; x4 ^= x1; x0 =~ x0; \
x2 ^= x3; x3 ^= x0; x0 &= x1; \
x0 ^= x2; x2 &= x3; x3 ^= x4; \
x2 ^= x3; x1 ^= x3; x3 &= x0; \
x1 ^= x0; x0 ^= x2; x4 ^= x3;
#define SI1(x0,x1,x2,x3,x4) \
x1 ^= x3; x4 = x0; \
x0 ^= x2; x2 =~ x2; x4 |= x1; \
x4 ^= x3; x3 &= x1; x1 ^= x2; \
x2 &= x4; x4 ^= x1; x1 |= x3; \
x3 ^= x0; x2 ^= x0; x0 |= x4; \
x2 ^= x4; x1 ^= x0; \
x4 ^= x1;
#define SI2(x0,x1,x2,x3,x4) \
x2 ^= x1; x4 = x3; x3 =~ x3; \
x3 |= x2; x2 ^= x4; x4 ^= x0; \
x3 ^= x1; x1 |= x2; x2 ^= x0; \
x1 ^= x4; x4 |= x3; x2 ^= x3; \
x4 ^= x2; x2 &= x1; \
x2 ^= x3; x3 ^= x4; x4 ^= x0;
#define SI3(x0,x1,x2,x3,x4) \
x2 ^= x1; \
x4 = x1; x1 &= x2; \
x1 ^= x0; x0 |= x4; x4 ^= x3; \
x0 ^= x3; x3 |= x1; x1 ^= x2; \
x1 ^= x3; x0 ^= x2; x2 ^= x3; \
x3 &= x1; x1 ^= x0; x0 &= x2; \
x4 ^= x3; x3 ^= x0; x0 ^= x1;
#define SI4(x0,x1,x2,x3,x4) \
x2 ^= x3; x4 = x0; x0 &= x1; \
x0 ^= x2; x2 |= x3; x4 =~ x4; \
x1 ^= x0; x0 ^= x2; x2 &= x4; \
x2 ^= x0; x0 |= x4; \
x0 ^= x3; x3 &= x2; \
x4 ^= x3; x3 ^= x1; x1 &= x0; \
x4 ^= x1; x0 ^= x3;
#define SI5(x0,x1,x2,x3,x4) \
x4 = x1; x1 |= x2; \
x2 ^= x4; x1 ^= x3; x3 &= x4; \
x2 ^= x3; x3 |= x0; x0 =~ x0; \
x3 ^= x2; x2 |= x0; x4 ^= x1; \
x2 ^= x4; x4 &= x0; x0 ^= x1; \
x1 ^= x3; x0 &= x2; x2 ^= x3; \
x0 ^= x2; x2 ^= x4; x4 ^= x3;
#define SI6(x0,x1,x2,x3,x4) \
x0 ^= x2; \
x4 = x0; x0 &= x3; x2 ^= x3; \
x0 ^= x2; x3 ^= x1; x2 |= x4; \
x2 ^= x3; x3 &= x0; x0 =~ x0; \
x3 ^= x1; x1 &= x2; x4 ^= x0; \
x3 ^= x4; x4 ^= x2; x0 ^= x1; \
x2 ^= x0;
#define SI7(x0,x1,x2,x3,x4) \
x4 = x3; x3 &= x0; x0 ^= x2; \
x2 |= x4; x4 ^= x1; x0 =~ x0; \
x1 |= x3; x4 ^= x0; x0 &= x2; \
x0 ^= x1; x1 &= x2; x3 ^= x2; \
x4 ^= x3; x2 &= x3; x3 |= x0; \
x1 ^= x4; x3 ^= x4; x4 &= x0; \
x4 ^= x2;
struct serpent_ctx {
u8 iv[SERPENT_BLOCK_SIZE];
u32 expkey[SERPENT_EXPKEY_WORDS];
};
static int serpent_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
{
u32 *k = ((struct serpent_ctx *)ctx)->expkey;
u8 *k8 = (u8 *)k;
u32 r0,r1,r2,r3,r4;
int i;
if ((keylen < SERPENT_MIN_KEY_SIZE)
|| (keylen > SERPENT_MAX_KEY_SIZE))
{
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
/* Copy key, add padding */
for (i = 0; i < keylen; ++i)
k8[i] = key[i];
if (i < SERPENT_MAX_KEY_SIZE)
k8[i++] = 1;
while (i < SERPENT_MAX_KEY_SIZE)
k8[i++] = 0;
/* Expand key using polynomial */
r0 = le32_to_cpu(k[3]);
r1 = le32_to_cpu(k[4]);
r2 = le32_to_cpu(k[5]);
r3 = le32_to_cpu(k[6]);
r4 = le32_to_cpu(k[7]);
keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0);
keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1);
keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2);
keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3);
keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4);
keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5);
keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6);
keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7);
keyiter(k[ 0],r3,r2,r0, 8, 8); keyiter(k[ 1],r4,r3,r1, 9, 9);
keyiter(k[ 2],r0,r4,r2, 10, 10); keyiter(k[ 3],r1,r0,r3, 11, 11);
keyiter(k[ 4],r2,r1,r4, 12, 12); keyiter(k[ 5],r3,r2,r0, 13, 13);
keyiter(k[ 6],r4,r3,r1, 14, 14); keyiter(k[ 7],r0,r4,r2, 15, 15);
keyiter(k[ 8],r1,r0,r3, 16, 16); keyiter(k[ 9],r2,r1,r4, 17, 17);
keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19);
keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21);
keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23);
keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25);
keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27);
keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29);
keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31);
k += 50;
keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17);
keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15);
keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13);
keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11);
keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9);
keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7);
keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5);
keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3);
keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1);
keyiter(k[ -8],r0,r4,r2, 50, 0); keyiter(k[ -7],r1,r0,r3, 51, 1);
keyiter(k[ -6],r2,r1,r4, 52, 2); keyiter(k[ -5],r3,r2,r0, 53, 3);
keyiter(k[ -4],r4,r3,r1, 54, 4); keyiter(k[ -3],r0,r4,r2, 55, 5);
keyiter(k[ -2],r1,r0,r3, 56, 6); keyiter(k[ -1],r2,r1,r4, 57, 7);
keyiter(k[ 0],r3,r2,r0, 58, 8); keyiter(k[ 1],r4,r3,r1, 59, 9);
keyiter(k[ 2],r0,r4,r2, 60, 10); keyiter(k[ 3],r1,r0,r3, 61, 11);
keyiter(k[ 4],r2,r1,r4, 62, 12); keyiter(k[ 5],r3,r2,r0, 63, 13);
keyiter(k[ 6],r4,r3,r1, 64, 14); keyiter(k[ 7],r0,r4,r2, 65, 15);
keyiter(k[ 8],r1,r0,r3, 66, 16); keyiter(k[ 9],r2,r1,r4, 67, 17);
keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19);
keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21);
keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23);
keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25);
keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27);
keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29);
keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31);
k += 50;
keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17);
keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15);
keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13);
keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11);
keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9);
keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7);
keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5);
keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3);
keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1);
keyiter(k[ -8],r0,r4,r2,100, 0); keyiter(k[ -7],r1,r0,r3,101, 1);
keyiter(k[ -6],r2,r1,r4,102, 2); keyiter(k[ -5],r3,r2,r0,103, 3);
keyiter(k[ -4],r4,r3,r1,104, 4); keyiter(k[ -3],r0,r4,r2,105, 5);
keyiter(k[ -2],r1,r0,r3,106, 6); keyiter(k[ -1],r2,r1,r4,107, 7);
keyiter(k[ 0],r3,r2,r0,108, 8); keyiter(k[ 1],r4,r3,r1,109, 9);
keyiter(k[ 2],r0,r4,r2,110, 10); keyiter(k[ 3],r1,r0,r3,111, 11);
keyiter(k[ 4],r2,r1,r4,112, 12); keyiter(k[ 5],r3,r2,r0,113, 13);
keyiter(k[ 6],r4,r3,r1,114, 14); keyiter(k[ 7],r0,r4,r2,115, 15);
keyiter(k[ 8],r1,r0,r3,116, 16); keyiter(k[ 9],r2,r1,r4,117, 17);
keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19);
keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21);
keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23);
keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25);
keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27);
keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29);
keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31);
/* Apply S-boxes */
S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24);
S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20);
S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16);
S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12);
S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4, 8);
S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1, 8); loadkeys(r0,r2,r4,r1, 4);
S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0, 4); loadkeys(r3,r4,r1,r0, 0);
S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0, 0); loadkeys(r2,r4,r3,r0, -4);
S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8);
S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12);
S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16);
S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20);
S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24);
S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28);
k -= 50;
S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18);
S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14);
S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10);
S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2, 6);
S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2, 6); loadkeys(r3,r0,r4,r2, 2);
S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2, 2); loadkeys(r4,r1,r0,r2, -2);
S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6);
S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10);
S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14);
S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18);
S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22);
k -= 50;
S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24);
S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20);
S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16);
S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12);
S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2, 8);
S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1, 8); loadkeys(r0,r4,r2,r1, 4);
S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1, 4); loadkeys(r3,r4,r0,r1, 0);
S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 0);
return 0;
}
static void serpent_encrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32
*k = ((struct serpent_ctx *)ctx)->expkey,
*s = (const u32 *)src;
u32 *d = (u32 *)dst,
r0, r1, r2, r3, r4;
/*
* Note: The conversions between u8* and u32* might cause trouble
* on architectures with stricter alignment rules than x86
*/
r0 = le32_to_cpu(s[0]);
r1 = le32_to_cpu(s[1]);
r2 = le32_to_cpu(s[2]);
r3 = le32_to_cpu(s[3]);
K(r0,r1,r2,r3,0);
S0(r0,r1,r2,r3,r4); LK(r2,r1,r3,r0,r4,1);
S1(r2,r1,r3,r0,r4); LK(r4,r3,r0,r2,r1,2);
S2(r4,r3,r0,r2,r1); LK(r1,r3,r4,r2,r0,3);
S3(r1,r3,r4,r2,r0); LK(r2,r0,r3,r1,r4,4);
S4(r2,r0,r3,r1,r4); LK(r0,r3,r1,r4,r2,5);
S5(r0,r3,r1,r4,r2); LK(r2,r0,r3,r4,r1,6);
S6(r2,r0,r3,r4,r1); LK(r3,r1,r0,r4,r2,7);
S7(r3,r1,r0,r4,r2); LK(r2,r0,r4,r3,r1,8);
S0(r2,r0,r4,r3,r1); LK(r4,r0,r3,r2,r1,9);
S1(r4,r0,r3,r2,r1); LK(r1,r3,r2,r4,r0,10);
S2(r1,r3,r2,r4,r0); LK(r0,r3,r1,r4,r2,11);
S3(r0,r3,r1,r4,r2); LK(r4,r2,r3,r0,r1,12);
S4(r4,r2,r3,r0,r1); LK(r2,r3,r0,r1,r4,13);
S5(r2,r3,r0,r1,r4); LK(r4,r2,r3,r1,r0,14);
S6(r4,r2,r3,r1,r0); LK(r3,r0,r2,r1,r4,15);
S7(r3,r0,r2,r1,r4); LK(r4,r2,r1,r3,r0,16);
S0(r4,r2,r1,r3,r0); LK(r1,r2,r3,r4,r0,17);
S1(r1,r2,r3,r4,r0); LK(r0,r3,r4,r1,r2,18);
S2(r0,r3,r4,r1,r2); LK(r2,r3,r0,r1,r4,19);
S3(r2,r3,r0,r1,r4); LK(r1,r4,r3,r2,r0,20);
S4(r1,r4,r3,r2,r0); LK(r4,r3,r2,r0,r1,21);
S5(r4,r3,r2,r0,r1); LK(r1,r4,r3,r0,r2,22);
S6(r1,r4,r3,r0,r2); LK(r3,r2,r4,r0,r1,23);
S7(r3,r2,r4,r0,r1); LK(r1,r4,r0,r3,r2,24);
S0(r1,r4,r0,r3,r2); LK(r0,r4,r3,r1,r2,25);
S1(r0,r4,r3,r1,r2); LK(r2,r3,r1,r0,r4,26);
S2(r2,r3,r1,r0,r4); LK(r4,r3,r2,r0,r1,27);
S3(r4,r3,r2,r0,r1); LK(r0,r1,r3,r4,r2,28);
S4(r0,r1,r3,r4,r2); LK(r1,r3,r4,r2,r0,29);
S5(r1,r3,r4,r2,r0); LK(r0,r1,r3,r2,r4,30);
S6(r0,r1,r3,r2,r4); LK(r3,r4,r1,r2,r0,31);
S7(r3,r4,r1,r2,r0); K(r0,r1,r2,r3,32);
d[0] = cpu_to_le32(r0);
d[1] = cpu_to_le32(r1);
d[2] = cpu_to_le32(r2);
d[3] = cpu_to_le32(r3);
}
static void serpent_decrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32
*k = ((struct serpent_ctx *)ctx)->expkey,
*s = (const u32 *)src;
u32 *d = (u32 *)dst,
r0, r1, r2, r3, r4;
r0 = le32_to_cpu(s[0]);
r1 = le32_to_cpu(s[1]);
r2 = le32_to_cpu(s[2]);
r3 = le32_to_cpu(s[3]);
K(r0,r1,r2,r3,32);
SI7(r0,r1,r2,r3,r4); KL(r1,r3,r0,r4,r2,31);
SI6(r1,r3,r0,r4,r2); KL(r0,r2,r4,r1,r3,30);
SI5(r0,r2,r4,r1,r3); KL(r2,r3,r0,r4,r1,29);
SI4(r2,r3,r0,r4,r1); KL(r2,r0,r1,r4,r3,28);
SI3(r2,r0,r1,r4,r3); KL(r1,r2,r3,r4,r0,27);
SI2(r1,r2,r3,r4,r0); KL(r2,r0,r4,r3,r1,26);
SI1(r2,r0,r4,r3,r1); KL(r1,r0,r4,r3,r2,25);
SI0(r1,r0,r4,r3,r2); KL(r4,r2,r0,r1,r3,24);
SI7(r4,r2,r0,r1,r3); KL(r2,r1,r4,r3,r0,23);
SI6(r2,r1,r4,r3,r0); KL(r4,r0,r3,r2,r1,22);
SI5(r4,r0,r3,r2,r1); KL(r0,r1,r4,r3,r2,21);
SI4(r0,r1,r4,r3,r2); KL(r0,r4,r2,r3,r1,20);
SI3(r0,r4,r2,r3,r1); KL(r2,r0,r1,r3,r4,19);
SI2(r2,r0,r1,r3,r4); KL(r0,r4,r3,r1,r2,18);
SI1(r0,r4,r3,r1,r2); KL(r2,r4,r3,r1,r0,17);
SI0(r2,r4,r3,r1,r0); KL(r3,r0,r4,r2,r1,16);
SI7(r3,r0,r4,r2,r1); KL(r0,r2,r3,r1,r4,15);
SI6(r0,r2,r3,r1,r4); KL(r3,r4,r1,r0,r2,14);
SI5(r3,r4,r1,r0,r2); KL(r4,r2,r3,r1,r0,13);
SI4(r4,r2,r3,r1,r0); KL(r4,r3,r0,r1,r2,12);
SI3(r4,r3,r0,r1,r2); KL(r0,r4,r2,r1,r3,11);
SI2(r0,r4,r2,r1,r3); KL(r4,r3,r1,r2,r0,10);
SI1(r4,r3,r1,r2,r0); KL(r0,r3,r1,r2,r4,9);
SI0(r0,r3,r1,r2,r4); KL(r1,r4,r3,r0,r2,8);
SI7(r1,r4,r3,r0,r2); KL(r4,r0,r1,r2,r3,7);
SI6(r4,r0,r1,r2,r3); KL(r1,r3,r2,r4,r0,6);
SI5(r1,r3,r2,r4,r0); KL(r3,r0,r1,r2,r4,5);
SI4(r3,r0,r1,r2,r4); KL(r3,r1,r4,r2,r0,4);
SI3(r3,r1,r4,r2,r0); KL(r4,r3,r0,r2,r1,3);
SI2(r4,r3,r0,r2,r1); KL(r3,r1,r2,r0,r4,2);
SI1(r3,r1,r2,r0,r4); KL(r4,r1,r2,r0,r3,1);
SI0(r4,r1,r2,r0,r3); K(r2,r3,r1,r4,0);
d[0] = cpu_to_le32(r2);
d[1] = cpu_to_le32(r3);
d[2] = cpu_to_le32(r1);
d[3] = cpu_to_le32(r4);
}
static struct crypto_alg serpent_alg = {
.cra_name = "serpent",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SERPENT_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct serpent_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = SERPENT_MIN_KEY_SIZE,
.cia_max_keysize = SERPENT_MAX_KEY_SIZE,
.cia_setkey = serpent_setkey,
.cia_encrypt = serpent_encrypt,
.cia_decrypt = serpent_decrypt } }
};
static int tnepres_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
{
u8 rev_key[SERPENT_MAX_KEY_SIZE];
int i;
if ((keylen < SERPENT_MIN_KEY_SIZE)
|| (keylen > SERPENT_MAX_KEY_SIZE)) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
for (i = 0; i < keylen; ++i)
rev_key[keylen - i - 1] = key[i];
return serpent_setkey(ctx, rev_key, keylen, flags);
}
static void tnepres_encrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32 * const s = (const u32 * const)src;
u32 * const d = (u32 * const)dst;
u32 rs[4], rd[4];
rs[0] = swab32(s[3]);
rs[1] = swab32(s[2]);
rs[2] = swab32(s[1]);
rs[3] = swab32(s[0]);
serpent_encrypt(ctx, (u8 *)rd, (u8 *)rs);
d[0] = swab32(rd[3]);
d[1] = swab32(rd[2]);
d[2] = swab32(rd[1]);
d[3] = swab32(rd[0]);
}
static void tnepres_decrypt(void *ctx, u8 *dst, const u8 *src)
{
const u32 * const s = (const u32 * const)src;
u32 * const d = (u32 * const)dst;
u32 rs[4], rd[4];
rs[0] = swab32(s[3]);
rs[1] = swab32(s[2]);
rs[2] = swab32(s[1]);
rs[3] = swab32(s[0]);
serpent_decrypt(ctx, (u8 *)rd, (u8 *)rs);
d[0] = swab32(rd[3]);
d[1] = swab32(rd[2]);
d[2] = swab32(rd[1]);
d[3] = swab32(rd[0]);
}
static struct crypto_alg tnepres_alg = {
.cra_name = "tnepres",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SERPENT_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct serpent_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = SERPENT_MIN_KEY_SIZE,
.cia_max_keysize = SERPENT_MAX_KEY_SIZE,
.cia_setkey = tnepres_setkey,
.cia_encrypt = tnepres_encrypt,
.cia_decrypt = tnepres_decrypt } }
};
static int __init init(void)
{
int ret = crypto_register_alg(&serpent_alg);
if (ret)
return ret;
ret = crypto_register_alg(&tnepres_alg);
if (ret)
crypto_unregister_alg(&serpent_alg);
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&tnepres_alg);
crypto_unregister_alg(&serpent_alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
MODULE_ALIAS("tnepres");

View File

@@ -0,0 +1,208 @@
/*
* Cryptographic API.
*
* SHA1 Secure Hash Algorithm.
*
* Derived from cryptoapi implementation, adapted for in-place
* scatterlist interface. Originally based on the public domain
* implementation written by Steve Reid.
*
* Copyright (c) Alan Smithee.
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
* Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/crypto.h>
#include <asm/scatterlist.h>
#include <asm/byteorder.h>
#define SHA1_DIGEST_SIZE 20
#define SHA1_HMAC_BLOCK_SIZE 64
static inline u32 rol(u32 value, u32 bits)
{
return (((value) << (bits)) | ((value) >> (32 - (bits))));
}
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
# define blk0(i) block32[i]
#define blk(i) (block32[i&15] = rol(block32[(i+13)&15]^block32[(i+8)&15] \
^block32[(i+2)&15]^block32[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \
w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5); \
w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \
w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
struct sha1_ctx {
u64 count;
u32 state[5];
u8 buffer[64];
};
/* Hash a single 512-bit block. This is the core of the algorithm. */
static void sha1_transform(u32 *state, const u8 *in)
{
u32 a, b, c, d, e;
u32 block32[16];
/* convert/copy data to workspace */
for (a = 0; a < sizeof(block32)/sizeof(u32); a++)
block32[a] = be32_to_cpu (((const u32 *)in)[a]);
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
memset (block32, 0x00, sizeof block32);
}
static void sha1_init(void *ctx)
{
struct sha1_ctx *sctx = ctx;
static const struct sha1_ctx initstate = {
0,
{ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
{ 0, }
};
*sctx = initstate;
}
static void sha1_update(void *ctx, const u8 *data, unsigned int len)
{
struct sha1_ctx *sctx = ctx;
unsigned int i, j;
j = (sctx->count >> 3) & 0x3f;
sctx->count += len << 3;
if ((j + len) > 63) {
memcpy(&sctx->buffer[j], data, (i = 64-j));
sha1_transform(sctx->state, sctx->buffer);
for ( ; i + 63 < len; i += 64) {
sha1_transform(sctx->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&sctx->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
static void sha1_final(void* ctx, u8 *out)
{
struct sha1_ctx *sctx = ctx;
u32 i, j, index, padlen;
u64 t;
u8 bits[8] = { 0, };
static const u8 padding[64] = { 0x80, };
t = sctx->count;
bits[7] = 0xff & t; t>>=8;
bits[6] = 0xff & t; t>>=8;
bits[5] = 0xff & t; t>>=8;
bits[4] = 0xff & t; t>>=8;
bits[3] = 0xff & t; t>>=8;
bits[2] = 0xff & t; t>>=8;
bits[1] = 0xff & t; t>>=8;
bits[0] = 0xff & t;
/* Pad out to 56 mod 64 */
index = (sctx->count >> 3) & 0x3f;
padlen = (index < 56) ? (56 - index) : ((64+56) - index);
sha1_update(sctx, padding, padlen);
/* Append length */
sha1_update(sctx, bits, sizeof bits);
/* Store state in digest */
for (i = j = 0; i < 5; i++, j += 4) {
u32 t2 = sctx->state[i];
out[j+3] = t2 & 0xff; t2>>=8;
out[j+2] = t2 & 0xff; t2>>=8;
out[j+1] = t2 & 0xff; t2>>=8;
out[j ] = t2 & 0xff;
}
/* Wipe context */
memset(sctx, 0, sizeof *sctx);
}
static struct crypto_alg alg = {
.cra_name = "sha1",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha1_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA1_DIGEST_SIZE,
.dia_init = sha1_init,
.dia_update = sha1_update,
.dia_final = sha1_final } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");

View File

@@ -0,0 +1,354 @@
/*
* Cryptographic API.
*
* SHA-256, as specified in
* http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
*
* SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
*
* Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/crypto.h>
#include <asm/scatterlist.h>
#include <asm/byteorder.h>
#define SHA256_DIGEST_SIZE 32
#define SHA256_HMAC_BLOCK_SIZE 64
struct sha256_ctx {
u32 count[2];
u32 state[8];
u8 buf[128];
};
static inline u32 Ch(u32 x, u32 y, u32 z)
{
return z ^ (x & (y ^ z));
}
static inline u32 Maj(u32 x, u32 y, u32 z)
{
return (x & y) | (z & (x | y));
}
static inline u32 RORu32(u32 x, u32 y)
{
return (x >> y) | (x << (32 - y));
}
#define e0(x) (RORu32(x, 2) ^ RORu32(x,13) ^ RORu32(x,22))
#define e1(x) (RORu32(x, 6) ^ RORu32(x,11) ^ RORu32(x,25))
#define s0(x) (RORu32(x, 7) ^ RORu32(x,18) ^ (x >> 3))
#define s1(x) (RORu32(x,17) ^ RORu32(x,19) ^ (x >> 10))
#define H0 0x6a09e667
#define H1 0xbb67ae85
#define H2 0x3c6ef372
#define H3 0xa54ff53a
#define H4 0x510e527f
#define H5 0x9b05688c
#define H6 0x1f83d9ab
#define H7 0x5be0cd19
static inline void LOAD_OP(int I, u32 *W, const u8 *input)
{
W[I] = __be32_to_cpu( ((u32*)(input))[I] );
}
static inline void BLEND_OP(int I, u32 *W)
{
W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
}
static void sha256_transform(u32 *state, const u8 *input)
{
u32 a, b, c, d, e, f, g, h, t1, t2;
u32 W[64];
int i;
/* load the input */
for (i = 0; i < 16; i++)
LOAD_OP(i, W, input);
/* now blend */
for (i = 16; i < 64; i++)
BLEND_OP(i, W);
/* load the state into our registers */
a=state[0]; b=state[1]; c=state[2]; d=state[3];
e=state[4]; f=state[5]; g=state[6]; h=state[7];
/* now iterate */
t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
state[0] += a; state[1] += b; state[2] += c; state[3] += d;
state[4] += e; state[5] += f; state[6] += g; state[7] += h;
/* clear any sensitive info... */
a = b = c = d = e = f = g = h = t1 = t2 = 0;
memset(W, 0, 64 * sizeof(u32));
}
static void sha256_init(void *ctx)
{
struct sha256_ctx *sctx = ctx;
sctx->state[0] = H0;
sctx->state[1] = H1;
sctx->state[2] = H2;
sctx->state[3] = H3;
sctx->state[4] = H4;
sctx->state[5] = H5;
sctx->state[6] = H6;
sctx->state[7] = H7;
sctx->count[0] = sctx->count[1] = 0;
memset(sctx->buf, 0, sizeof(sctx->buf));
}
static void sha256_update(void *ctx, const u8 *data, unsigned int len)
{
struct sha256_ctx *sctx = ctx;
unsigned int i, index, part_len;
/* Compute number of bytes mod 128 */
index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
/* Update number of bits */
if ((sctx->count[0] += (len << 3)) < (len << 3)) {
sctx->count[1]++;
sctx->count[1] += (len >> 29);
}
part_len = 64 - index;
/* Transform as many times as possible. */
if (len >= part_len) {
memcpy(&sctx->buf[index], data, part_len);
sha256_transform(sctx->state, sctx->buf);
for (i = part_len; i + 63 < len; i += 64)
sha256_transform(sctx->state, &data[i]);
index = 0;
} else {
i = 0;
}
/* Buffer remaining input */
memcpy(&sctx->buf[index], &data[i], len-i);
}
static void sha256_final(void* ctx, u8 *out)
{
struct sha256_ctx *sctx = ctx;
u8 bits[8];
unsigned int index, pad_len, t;
int i, j;
static const u8 padding[64] = { 0x80, };
/* Save number of bits */
t = sctx->count[0];
bits[7] = t; t >>= 8;
bits[6] = t; t >>= 8;
bits[5] = t; t >>= 8;
bits[4] = t;
t = sctx->count[1];
bits[3] = t; t >>= 8;
bits[2] = t; t >>= 8;
bits[1] = t; t >>= 8;
bits[0] = t;
/* Pad out to 56 mod 64. */
index = (sctx->count[0] >> 3) & 0x3f;
pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
sha256_update(sctx, padding, pad_len);
/* Append length (before padding) */
sha256_update(sctx, bits, 8);
/* Store state in digest */
for (i = j = 0; i < 8; i++, j += 4) {
t = sctx->state[i];
out[j+3] = t; t >>= 8;
out[j+2] = t; t >>= 8;
out[j+1] = t; t >>= 8;
out[j ] = t;
}
/* Zeroize sensitive information. */
memset(sctx, 0, sizeof(*sctx));
}
static struct crypto_alg alg = {
.cra_name = "sha256",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA256_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha256_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA256_DIGEST_SIZE,
.dia_init = sha256_init,
.dia_update = sha256_update,
.dia_final = sha256_final } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");

View File

@@ -0,0 +1,362 @@
/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
*
* Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
* Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/crypto.h>
#include <asm/scatterlist.h>
#include <asm/byteorder.h>
#define SHA384_DIGEST_SIZE 48
#define SHA512_DIGEST_SIZE 64
#define SHA384_HMAC_BLOCK_SIZE 96
#define SHA512_HMAC_BLOCK_SIZE 128
struct sha512_ctx {
u64 state[8];
u32 count[4];
u8 buf[128];
u64 W[80];
};
static inline u64 Ch(u64 x, u64 y, u64 z)
{
return z ^ (x & (y ^ z));
}
static inline u64 Maj(u64 x, u64 y, u64 z)
{
return (x & y) | (z & (x | y));
}
static inline u64 RORu64(u64 x, u64 y)
{
return (x >> y) | (x << (64 - y));
}
const u64 sha512_K[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
};
#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
/* H* initial state for SHA-512 */
#define H0 0x6a09e667f3bcc908ULL
#define H1 0xbb67ae8584caa73bULL
#define H2 0x3c6ef372fe94f82bULL
#define H3 0xa54ff53a5f1d36f1ULL
#define H4 0x510e527fade682d1ULL
#define H5 0x9b05688c2b3e6c1fULL
#define H6 0x1f83d9abfb41bd6bULL
#define H7 0x5be0cd19137e2179ULL
/* H'* initial state for SHA-384 */
#define HP0 0xcbbb9d5dc1059ed8ULL
#define HP1 0x629a292a367cd507ULL
#define HP2 0x9159015a3070dd17ULL
#define HP3 0x152fecd8f70e5939ULL
#define HP4 0x67332667ffc00b31ULL
#define HP5 0x8eb44a8768581511ULL
#define HP6 0xdb0c2e0d64f98fa7ULL
#define HP7 0x47b5481dbefa4fa4ULL
static inline void LOAD_OP(int I, u64 *W, const u8 *input)
{
W[I] = __be64_to_cpu( ((u64*)(input))[I] );
}
static inline void BLEND_OP(int I, u64 *W)
{
W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
}
static void
sha512_transform(u64 *state, u64 *W, const u8 *input)
{
u64 a, b, c, d, e, f, g, h, t1, t2;
int i;
/* load the input */
for (i = 0; i < 16; i++)
LOAD_OP(i, W, input);
for (i = 16; i < 80; i++) {
BLEND_OP(i, W);
}
/* load the state into our registers */
a=state[0]; b=state[1]; c=state[2]; d=state[3];
e=state[4]; f=state[5]; g=state[6]; h=state[7];
/* now iterate */
for (i=0; i<80; i+=8) {
t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ];
t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d;
state[4] += e; state[5] += f; state[6] += g; state[7] += h;
/* erase our data */
a = b = c = d = e = f = g = h = t1 = t2 = 0;
}
static void
sha512_init(void *ctx)
{
struct sha512_ctx *sctx = ctx;
sctx->state[0] = H0;
sctx->state[1] = H1;
sctx->state[2] = H2;
sctx->state[3] = H3;
sctx->state[4] = H4;
sctx->state[5] = H5;
sctx->state[6] = H6;
sctx->state[7] = H7;
sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
memset(sctx->buf, 0, sizeof(sctx->buf));
}
static void
sha384_init(void *ctx)
{
struct sha512_ctx *sctx = ctx;
sctx->state[0] = HP0;
sctx->state[1] = HP1;
sctx->state[2] = HP2;
sctx->state[3] = HP3;
sctx->state[4] = HP4;
sctx->state[5] = HP5;
sctx->state[6] = HP6;
sctx->state[7] = HP7;
sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
memset(sctx->buf, 0, sizeof(sctx->buf));
}
static void
sha512_update(void *ctx, const u8 *data, unsigned int len)
{
struct sha512_ctx *sctx = ctx;
unsigned int i, index, part_len;
/* Compute number of bytes mod 128 */
index = (unsigned int)((sctx->count[0] >> 3) & 0x7F);
/* Update number of bits */
if ((sctx->count[0] += (len << 3)) < (len << 3)) {
if ((sctx->count[1] += 1) < 1)
if ((sctx->count[2] += 1) < 1)
sctx->count[3]++;
sctx->count[1] += (len >> 29);
}
part_len = 128 - index;
/* Transform as many times as possible. */
if (len >= part_len) {
memcpy(&sctx->buf[index], data, part_len);
sha512_transform(sctx->state, sctx->W, sctx->buf);
for (i = part_len; i + 127 < len; i+=128)
sha512_transform(sctx->state, sctx->W, &data[i]);
index = 0;
} else {
i = 0;
}
/* Buffer remaining input */
memcpy(&sctx->buf[index], &data[i], len - i);
/* erase our data */
memset(sctx->W, 0, sizeof(sctx->W));
}
static void
sha512_final(void *ctx, u8 *hash)
{
struct sha512_ctx *sctx = ctx;
static u8 padding[128] = { 0x80, };
u32 t;
u64 t2;
u8 bits[128];
unsigned int index, pad_len;
int i, j;
index = pad_len = t = i = j = 0;
t2 = 0;
/* Save number of bits */
t = sctx->count[0];
bits[15] = t; t>>=8;
bits[14] = t; t>>=8;
bits[13] = t; t>>=8;
bits[12] = t;
t = sctx->count[1];
bits[11] = t; t>>=8;
bits[10] = t; t>>=8;
bits[9 ] = t; t>>=8;
bits[8 ] = t;
t = sctx->count[2];
bits[7 ] = t; t>>=8;
bits[6 ] = t; t>>=8;
bits[5 ] = t; t>>=8;
bits[4 ] = t;
t = sctx->count[3];
bits[3 ] = t; t>>=8;
bits[2 ] = t; t>>=8;
bits[1 ] = t; t>>=8;
bits[0 ] = t;
/* Pad out to 112 mod 128. */
index = (sctx->count[0] >> 3) & 0x7f;
pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
sha512_update(sctx, padding, pad_len);
/* Append length (before padding) */
sha512_update(sctx, bits, 16);
/* Store state in digest */
for (i = j = 0; i < 8; i++, j += 8) {
t2 = sctx->state[i];
hash[j+7] = (char)t2 & 0xff; t2>>=8;
hash[j+6] = (char)t2 & 0xff; t2>>=8;
hash[j+5] = (char)t2 & 0xff; t2>>=8;
hash[j+4] = (char)t2 & 0xff; t2>>=8;
hash[j+3] = (char)t2 & 0xff; t2>>=8;
hash[j+2] = (char)t2 & 0xff; t2>>=8;
hash[j+1] = (char)t2 & 0xff; t2>>=8;
hash[j ] = (char)t2 & 0xff;
}
/* Zeroize sensitive information. */
memset(sctx, 0, sizeof(struct sha512_ctx));
}
static void sha384_final(void *ctx, u8 *hash)
{
struct sha512_ctx *sctx = ctx;
u8 D[64];
sha512_final(sctx, D);
memcpy(hash, D, 48);
memset(D, 0, 64);
}
static struct crypto_alg sha512 = {
.cra_name = "sha512",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA512_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha512_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(sha512.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA512_DIGEST_SIZE,
.dia_init = sha512_init,
.dia_update = sha512_update,
.dia_final = sha512_final }
}
};
static struct crypto_alg sha384 = {
.cra_name = "sha384",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA384_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha512_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(sha384.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA384_DIGEST_SIZE,
.dia_init = sha384_init,
.dia_update = sha512_update,
.dia_final = sha384_final }
}
};
MODULE_ALIAS("sha384");
static int __init init(void)
{
int ret = 0;
if ((ret = crypto_register_alg(&sha384)) < 0)
goto out;
if ((ret = crypto_register_alg(&sha512)) < 0)
crypto_unregister_alg(&sha384);
out:
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&sha384);
crypto_unregister_alg(&sha512);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");

View File

@@ -0,0 +1,894 @@
/*
* Quick & dirty crypto testing module.
*
* This will only exist until we have a better testing mechanism
* (e.g. a char device).
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* 14 - 09 - 2003
* Rewritten by Kartikey Mahendra Bhatt
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include <linux/moduleparam.h>
#include "tcrypt.h"
/*
* Need to kmalloc() memory for testing kmap().
*/
#define TVMEMSIZE 4096
#define XBUFSIZE 32768
/*
* Indexes into the xbuf to simulate cross-page access.
*/
#define IDX1 37
#define IDX2 32400
#define IDX3 1
#define IDX4 8193
#define IDX5 22222
#define IDX6 17101
#define IDX7 27333
#define IDX8 3000
/*
* Used by test_cipher()
*/
#define ENCRYPT 1
#define DECRYPT 0
#define MODE_ECB 1
#define MODE_CBC 0
static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
static int mode;
static char *xbuf;
static char *tvmem;
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"khazad", "wp512", "wp384", "wp256", "tnepres", NULL
};
static void
hexdump(unsigned char *buf, unsigned int len)
{
while (len--)
printk("%02x", *buf++);
printk("\n");
}
static void
test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
{
char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
struct crypto_tfm *tfm;
struct hash_testvec *hash_tv;
unsigned int tsize;
printk("\ntesting %s\n", algo);
tsize = sizeof (struct hash_testvec);
tsize *= tcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
return;
}
memcpy(tvmem, template, tsize);
hash_tv = (void *) tvmem;
tfm = crypto_alloc_tfm(algo, 0);
if (tfm == NULL) {
printk("failed to load transform for %s\n", algo);
return;
}
for (i = 0; i < tcount; i++) {
printk ("test %u:\n", i + 1);
memset (result, 0, 64);
p = hash_tv[i].plaintext;
sg[0].page = virt_to_page (p);
sg[0].offset = offset_in_page (p);
sg[0].length = hash_tv[i].psize;
crypto_digest_init (tfm);
if (tfm->crt_u.digest.dit_setkey) {
crypto_digest_setkey (tfm, hash_tv[i].key,
hash_tv[i].ksize);
}
crypto_digest_update (tfm, sg, 1);
crypto_digest_final (tfm, result);
hexdump (result, crypto_tfm_alg_digestsize (tfm));
printk("%s\n",
memcmp(result, hash_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk ("testing %s across pages\n", algo);
/* setup the dummy buffer first */
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (hash_tv[i].np) {
j++;
printk ("test %u:\n", j);
memset (result, 0, 64);
temp = 0;
for (k = 0; k < hash_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], hash_tv[i].plaintext + temp,
hash_tv[i].tap[k]);
temp += hash_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = hash_tv[i].tap[k];
}
crypto_digest_digest (tfm, sg, hash_tv[i].np, result);
hexdump (result, crypto_tfm_alg_digestsize (tfm));
printk("%s\n",
memcmp(result, hash_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
}
crypto_free_tfm (tfm);
}
#ifdef CONFIG_CRYPTO_HMAC
static void
test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
{
char *p;
unsigned int i, j, k, temp;
struct scatterlist sg[8];
char result[64];
struct crypto_tfm *tfm;
struct hmac_testvec *hmac_tv;
unsigned int tsize, klen;
tfm = crypto_alloc_tfm(algo, 0);
if (tfm == NULL) {
printk("failed to load transform for %s\n", algo);
return;
}
printk("\ntesting hmac_%s\n", algo);
tsize = sizeof (struct hmac_testvec);
tsize *= tcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, template, tsize);
hmac_tv = (void *) tvmem;
for (i = 0; i < tcount; i++) {
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
p = hmac_tv[i].plaintext;
klen = hmac_tv[i].ksize;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = hmac_tv[i].psize;
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
printk("\ntesting hmac_%s across pages\n", algo);
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (hmac_tv[i].np) {
j++;
printk ("test %u:\n",j);
memset (result, 0, 64);
temp = 0;
klen = hmac_tv[i].ksize;
for (k = 0; k < hmac_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], hmac_tv[i].plaintext + temp,
hmac_tv[i].tap[k]);
temp += hmac_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = hmac_tv[i].tap[k];
}
crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, hmac_tv[i].np,
result);
hexdump(result, crypto_tfm_alg_digestsize(tfm));
printk("%s\n",
memcmp(result, hmac_tv[i].digest,
crypto_tfm_alg_digestsize(tfm)) ? "fail" :
"pass");
}
}
out:
crypto_free_tfm(tfm);
}
#endif /* CONFIG_CRYPTO_HMAC */
void
test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
{
unsigned int ret, i, j, k, temp;
unsigned int tsize;
char *p, *q;
struct crypto_tfm *tfm;
char *key;
struct cipher_testvec *cipher_tv;
struct scatterlist sg[8];
char e[11], m[4];
if (enc == ENCRYPT)
strncpy(e, "encryption", 11);
else
strncpy(e, "decryption", 11);
if (mode == MODE_ECB)
strncpy(m, "ECB", 4);
else
strncpy(m, "CBC", 4);
printk("\ntesting %s %s %s \n", algo, m, e);
tsize = sizeof (struct cipher_testvec);
tsize *= tcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, template, tsize);
cipher_tv = (void *) tvmem;
if (mode)
tfm = crypto_alloc_tfm (algo, 0);
else
tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC);
if (tfm == NULL) {
printk("failed to load transform for %s %s\n", algo, m);
return;
}
j = 0;
for (i = 0; i < tcount; i++) {
if (!(cipher_tv[i].np)) {
j++;
printk("test %u (%d bit key):\n",
j, cipher_tv[i].klen * 8);
tfm->crt_flags = 0;
if (cipher_tv[i].wk)
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
key = cipher_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!cipher_tv[i].fail)
goto out;
}
p = cipher_tv[i].input;
sg[0].page = virt_to_page(p);
sg[0].offset = offset_in_page(p);
sg[0].length = cipher_tv[i].ilen;
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
crypto_tfm_alg_ivsize (tfm));
}
if (enc)
ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
else
ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
if (ret) {
printk("%s () failed flags=%x\n", e, tfm->crt_flags);
goto out;
}
q = kmap(sg[0].page) + sg[0].offset;
hexdump(q, cipher_tv[i].rlen);
printk("%s\n",
memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" :
"pass");
}
}
printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e);
memset(xbuf, 0, XBUFSIZE);
j = 0;
for (i = 0; i < tcount; i++) {
if (cipher_tv[i].np) {
j++;
printk("test %u (%d bit key):\n",
j, cipher_tv[i].klen * 8);
tfm->crt_flags = 0;
if (cipher_tv[i].wk)
tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
key = cipher_tv[i].key;
ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
if (ret) {
printk("setkey() failed flags=%x\n", tfm->crt_flags);
if (!cipher_tv[i].fail)
goto out;
}
temp = 0;
for (k = 0; k < cipher_tv[i].np; k++) {
memcpy (&xbuf[IDX[k]], cipher_tv[i].input + temp,
cipher_tv[i].tap[k]);
temp += cipher_tv[i].tap[k];
p = &xbuf[IDX[k]];
sg[k].page = virt_to_page (p);
sg[k].offset = offset_in_page (p);
sg[k].length = cipher_tv[i].tap[k];
}
if (!mode) {
crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
crypto_tfm_alg_ivsize (tfm));
}
if (enc)
ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
else
ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
if (ret) {
printk("%s () failed flags=%x\n", e, tfm->crt_flags);
goto out;
}
temp = 0;
for (k = 0; k < cipher_tv[i].np; k++) {
printk("page %u\n", k);
q = kmap(sg[k].page) + sg[k].offset;
hexdump(q, cipher_tv[i].tap[k]);
printk("%s\n",
memcmp(q, cipher_tv[i].result + temp,
cipher_tv[i].tap[k]) ? "fail" :
"pass");
temp += cipher_tv[i].tap[k];
}
}
}
out:
crypto_free_tfm(tfm);
}
static void
test_deflate(void)
{
unsigned int i;
char result[COMP_BUF_SIZE];
struct crypto_tfm *tfm;
struct comp_testvec *tv;
unsigned int tsize;
printk("\ntesting deflate compression\n");
tsize = sizeof (deflate_comp_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
memcpy(tvmem, deflate_comp_tv_template, tsize);
tv = (void *) tvmem;
tfm = crypto_alloc_tfm("deflate", 0);
if (tfm == NULL) {
printk("failed to load transform for deflate\n");
return;
}
for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
ilen = tv[i].inlen;
ret = crypto_comp_compress(tfm, tv[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
continue;
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
printk("\ntesting deflate decompression\n");
tsize = sizeof (deflate_decomp_tv_template);
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
memcpy(tvmem, deflate_decomp_tv_template, tsize);
tv = (void *) tvmem;
for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
memset(result, 0, sizeof (result));
ilen = tv[i].inlen;
ret = crypto_comp_decompress(tfm, tv[i].input,
ilen, result, &dlen);
if (ret) {
printk("fail: ret=%d\n", ret);
continue;
}
hexdump(result, dlen);
printk("%s (ratio %d:%d)\n",
memcmp(result, tv[i].output, dlen) ? "fail" : "pass",
ilen, dlen);
}
out:
crypto_free_tfm(tfm);
}
static void
test_crc32c(void)
{
#define NUMVEC 6
#define VECSIZE 40
int i, j, pass;
u32 crc;
u8 b, test_vec[NUMVEC][VECSIZE];
static u32 vec_results[NUMVEC] = {
0x0e2c157f, 0xe980ebf6, 0xde74bded,
0xd579c862, 0xba979ad0, 0x2b29d913
};
static u32 tot_vec_results = 0x24c5d375;
struct scatterlist sg[NUMVEC];
struct crypto_tfm *tfm;
char *fmtdata = "testing crc32c initialized to %08x: %s\n";
#define SEEDTESTVAL 0xedcba987
u32 seed;
printk("\ntesting crc32c\n");
tfm = crypto_alloc_tfm("crc32c", 0);
if (tfm == NULL) {
printk("failed to load transform for crc32c\n");
return;
}
crypto_digest_init(tfm);
crypto_digest_final(tfm, (u8*)&crc);
printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
/*
* stuff test_vec with known values, simple incrementing
* byte values.
*/
b = 0;
for (i = 0; i < NUMVEC; i++) {
for (j = 0; j < VECSIZE; j++)
test_vec[i][j] = ++b;
sg[i].page = virt_to_page(test_vec[i]);
sg[i].offset = offset_in_page(test_vec[i]);
sg[i].length = VECSIZE;
}
seed = SEEDTESTVAL;
(void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
crypto_digest_final(tfm, (u8*)&crc);
printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
"pass" : "ERROR");
printk("testing crc32c using update/final:\n");
pass = 1; /* assume all is well */
for (i = 0; i < NUMVEC; i++) {
seed = ~(u32)0;
(void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
crypto_digest_update(tfm, &sg[i], 1);
crypto_digest_final(tfm, (u8*)&crc);
if (crc == vec_results[i]) {
printk(" %08x:OK", crc);
} else {
printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]);
pass = 0;
}
}
printk("\ntesting crc32c using incremental accumulator:\n");
crc = 0;
for (i = 0; i < NUMVEC; i++) {
seed = (crc ^ ~(u32)0);
(void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
crypto_digest_update(tfm, &sg[i], 1);
crypto_digest_final(tfm, (u8*)&crc);
}
if (crc == tot_vec_results) {
printk(" %08x:OK", crc);
} else {
printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
pass = 0;
}
printk("\ntesting crc32c using digest:\n");
seed = ~(u32)0;
(void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
if (crc == tot_vec_results) {
printk(" %08x:OK", crc);
} else {
printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
pass = 0;
}
printk("\n%s\n", pass ? "pass" : "ERROR");
crypto_free_tfm(tfm);
printk("crc32c test complete\n");
}
static void
test_available(void)
{
char **name = check;
while (*name) {
printk("alg %s ", *name);
printk((crypto_alg_available(*name, 0)) ?
"found\n" : "not found\n");
name++;
}
}
static void
do_test(void)
{
switch (mode) {
case 0:
test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
//DES
test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
//DES3_EDE
test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
//BLOWFISH
test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
//TWOFISH
test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
//SERPENT
test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
//TNEPRES
test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS);
test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS);
//AES
test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
//CAST5
test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
//CAST6
test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
//ARC4
test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS);
test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS);
//TEA
test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS);
test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS);
//XTEA
test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS);
test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
//KHAZAD
test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
//ANUBIS
test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
test_deflate();
test_crc32c();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
#endif
test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
break;
case 1:
test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
break;
case 2:
test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
break;
case 3:
test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
break;
case 4:
test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
break;
case 5:
test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
break;
case 6:
test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
break;
case 7:
test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
break;
case 8:
test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
break;
case 9:
test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
break;
case 10:
test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
break;
case 11:
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
break;
case 12:
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
break;
case 13:
test_deflate();
break;
case 14:
test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
break;
case 15:
test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
break;
case 16:
test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS);
test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS);
break;
case 17:
test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
break;
case 18:
test_crc32c();
break;
case 19:
test_cipher ("tea", MODE_ECB, ENCRYPT, tea_enc_tv_template, TEA_ENC_TEST_VECTORS);
test_cipher ("tea", MODE_ECB, DECRYPT, tea_dec_tv_template, TEA_DEC_TEST_VECTORS);
break;
case 20:
test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS);
test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
break;
case 21:
test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
break;
case 22:
test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
break;
case 23:
test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
break;
case 24:
test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
break;
case 25:
test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS);
test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS);
break;
case 26:
test_cipher ("anubis", MODE_ECB, ENCRYPT, anubis_enc_tv_template, ANUBIS_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_ECB, DECRYPT, anubis_dec_tv_template, ANUBIS_DEC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, ENCRYPT, anubis_cbc_enc_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
test_cipher ("anubis", MODE_CBC, DECRYPT, anubis_cbc_dec_tv_template, ANUBIS_CBC_ENC_TEST_VECTORS);
break;
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
break;
case 101:
test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
break;
case 102:
test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
break;
#endif
case 1000:
test_available();
break;
default:
/* useful for debugging */
printk("not testing anything\n");
break;
}
}
static int __init
init(void)
{
tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
if (tvmem == NULL)
return -ENOMEM;
xbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
if (xbuf == NULL) {
kfree(tvmem);
return -ENOMEM;
}
do_test();
kfree(xbuf);
kfree(tvmem);
return 0;
}
/*
* If an init function is provided, an exit function must also be provided
* to allow module unload.
*/
static void __exit fini(void) { }
module_init(init);
module_exit(fini);
module_param(mode, int, 0);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
/*
* Cryptographic API.
*
* TEA and Xtended TEA Algorithms
*
* The TEA and Xtended TEA algorithms were developed by David Wheeler
* and Roger Needham at the Computer Laboratory of Cambridge University.
*
* Copyright (c) 2004 Aaron Grothe ajgrothe@yahoo.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#define TEA_KEY_SIZE 16
#define TEA_BLOCK_SIZE 8
#define TEA_ROUNDS 32
#define TEA_DELTA 0x9e3779b9
#define XTEA_KEY_SIZE 16
#define XTEA_BLOCK_SIZE 8
#define XTEA_ROUNDS 32
#define XTEA_DELTA 0x9e3779b9
#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
struct tea_ctx {
u32 KEY[4];
};
struct xtea_ctx {
u32 KEY[4];
};
static int tea_setkey(void *ctx_arg, const u8 *in_key,
unsigned int key_len, u32 *flags)
{
struct tea_ctx *ctx = ctx_arg;
if (key_len != 16)
{
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
ctx->KEY[0] = u32_in (in_key);
ctx->KEY[1] = u32_in (in_key + 4);
ctx->KEY[2] = u32_in (in_key + 8);
ctx->KEY[3] = u32_in (in_key + 12);
return 0;
}
static void tea_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
u32 y, z, n, sum = 0;
u32 k0, k1, k2, k3;
struct tea_ctx *ctx = ctx_arg;
y = u32_in (src);
z = u32_in (src + 4);
k0 = ctx->KEY[0];
k1 = ctx->KEY[1];
k2 = ctx->KEY[2];
k3 = ctx->KEY[3];
n = TEA_ROUNDS;
while (n-- > 0) {
sum += TEA_DELTA;
y += ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
}
u32_out (dst, y);
u32_out (dst + 4, z);
}
static void tea_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
u32 y, z, n, sum;
u32 k0, k1, k2, k3;
struct tea_ctx *ctx = ctx_arg;
y = u32_in (src);
z = u32_in (src + 4);
k0 = ctx->KEY[0];
k1 = ctx->KEY[1];
k2 = ctx->KEY[2];
k3 = ctx->KEY[3];
sum = TEA_DELTA << 5;
n = TEA_ROUNDS;
while (n-- > 0) {
z -= ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
y -= ((z << 4) + k0) ^ (z + sum) ^ ((z >> 5) + k1);
sum -= TEA_DELTA;
}
u32_out (dst, y);
u32_out (dst + 4, z);
}
static int xtea_setkey(void *ctx_arg, const u8 *in_key,
unsigned int key_len, u32 *flags)
{
struct xtea_ctx *ctx = ctx_arg;
if (key_len != 16)
{
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
ctx->KEY[0] = u32_in (in_key);
ctx->KEY[1] = u32_in (in_key + 4);
ctx->KEY[2] = u32_in (in_key + 8);
ctx->KEY[3] = u32_in (in_key + 12);
return 0;
}
static void xtea_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
u32 y, z, sum = 0;
u32 limit = XTEA_DELTA * XTEA_ROUNDS;
struct xtea_ctx *ctx = ctx_arg;
y = u32_in (src);
z = u32_in (src + 4);
while (sum != limit) {
y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
sum += XTEA_DELTA;
z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
}
u32_out (dst, y);
u32_out (dst + 4, z);
}
static void xtea_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
{
u32 y, z, sum;
struct tea_ctx *ctx = ctx_arg;
y = u32_in (src);
z = u32_in (src + 4);
sum = XTEA_DELTA * XTEA_ROUNDS;
while (sum) {
z -= (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 & 3];
sum -= XTEA_DELTA;
y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
}
u32_out (dst, y);
u32_out (dst + 4, z);
}
static struct crypto_alg tea_alg = {
.cra_name = "tea",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = TEA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct tea_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(tea_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = TEA_KEY_SIZE,
.cia_max_keysize = TEA_KEY_SIZE,
.cia_setkey = tea_setkey,
.cia_encrypt = tea_encrypt,
.cia_decrypt = tea_decrypt } }
};
static struct crypto_alg xtea_alg = {
.cra_name = "xtea",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = XTEA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct xtea_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(xtea_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = XTEA_KEY_SIZE,
.cia_max_keysize = XTEA_KEY_SIZE,
.cia_setkey = xtea_setkey,
.cia_encrypt = xtea_encrypt,
.cia_decrypt = xtea_decrypt } }
};
static int __init init(void)
{
int ret = 0;
ret = crypto_register_alg(&tea_alg);
if (ret < 0)
goto out;
ret = crypto_register_alg(&xtea_alg);
if (ret < 0) {
crypto_unregister_alg(&tea_alg);
goto out;
}
out:
return ret;
}
static void __exit fini(void)
{
crypto_unregister_alg(&tea_alg);
crypto_unregister_alg(&xtea_alg);
}
MODULE_ALIAS("xtea");
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("TEA & XTEA Cryptographic Algorithms");

View File

@@ -0,0 +1,902 @@
/*
* Twofish for CryptoAPI
*
* Originally Twofish for GPG
* By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
* 256-bit key length added March 20, 1999
* Some modifications to reduce the text size by Werner Koch, April, 1998
* Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
* Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
*
* The original author has disclaimed all copyright interest in this
* code and thus put it in the public domain. The subsequent authors
* have put this under the GNU General Public License.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* This code is a "clean room" implementation, written from the paper
* _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
* Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
* through http://www.counterpane.com/twofish.html
*
* For background information on multiplication in finite fields, used for
* the matrix operations in the key schedule, see the book _Contemporary
* Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
* Third Edition.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/crypto.h>
/* The large precomputed tables for the Twofish cipher (twofish.c)
* Taken from the same source as twofish.c
* Marc Mutz <Marc@Mutz.com>
*/
/* These two tables are the q0 and q1 permutations, exactly as described in
* the Twofish paper. */
static const u8 q0[256] = {
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
0x4A, 0x5E, 0xC1, 0xE0
};
static const u8 q1[256] = {
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
0x55, 0x09, 0xBE, 0x91
};
/* These MDS tables are actually tables of MDS composed with q0 and q1,
* because it is only ever used that way and we can save some time by
* precomputing. Of course the main saving comes from precomputing the
* GF(2^8) multiplication involved in the MDS matrix multiply; by looking
* things up in these tables we reduce the matrix multiply to four lookups
* and three XORs. Semi-formally, the definition of these tables is:
* mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
* mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
* where ^T means "transpose", the matrix multiply is performed in GF(2^8)
* represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
* by Schneier et al, and I'm casually glossing over the byte/word
* conversion issues. */
static const u32 mds[4][256] = {
{0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
{0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
{0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
{0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
};
/* The exp_to_poly and poly_to_exp tables are used to perform efficient
* operations in GF(2^8) represented as GF(2)[x]/w(x) where
* w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
* definition of the RS matrix in the key schedule. Elements of that field
* are polynomials of degree not greater than 7 and all coefficients 0 or 1,
* which can be represented naturally by bytes (just substitute x=2). In that
* form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
* multiplication is inefficient without hardware support. To multiply
* faster, I make use of the fact x is a generator for the nonzero elements,
* so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
* some n in 0..254. Note that that caret is exponentiation in GF(2^8),
* *not* polynomial notation. So if I want to compute pq where p and q are
* in GF(2^8), I can just say:
* 1. if p=0 or q=0 then pq=0
* 2. otherwise, find m and n such that p=x^m and q=x^n
* 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
* The translations in steps 2 and 3 are looked up in the tables
* poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
* in action, look at the CALC_S macro. As additional wrinkles, note that
* one of my operands is always a constant, so the poly_to_exp lookup on it
* is done in advance; I included the original values in the comments so
* readers can have some chance of recognizing that this *is* the RS matrix
* from the Twofish paper. I've only included the table entries I actually
* need; I never do a lookup on a variable input of zero and the biggest
* exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
* never sum to more than 491. I'm repeating part of the exp_to_poly table
* so that I don't have to do mod-255 reduction in the exponent arithmetic.
* Since I know my constant operands are never zero, I only have to worry
* about zero values in the variable operand, and I do it with a simple
* conditional branch. I know conditionals are expensive, but I couldn't
* see a non-horrible way of avoiding them, and I did manage to group the
* statements so that each if covers four group multiplications. */
static const u8 poly_to_exp[255] = {
0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
0x85, 0xC8, 0xA1
};
static const u8 exp_to_poly[492] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
};
/* The table constants are indices of
* S-box entries, preprocessed through q0 and q1. */
static const u8 calc_sb_tbl[512] = {
0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
};
/* Macro to perform one column of the RS matrix multiplication. The
* parameters a, b, c, and d are the four bytes of output; i is the index
* of the key bytes, and w, x, y, and z, are the column of constants from
* the RS matrix, preprocessed through the poly_to_exp table. */
#define CALC_S(a, b, c, d, i, w, x, y, z) \
if (key[i]) { \
tmp = poly_to_exp[key[i] - 1]; \
(a) ^= exp_to_poly[tmp + (w)]; \
(b) ^= exp_to_poly[tmp + (x)]; \
(c) ^= exp_to_poly[tmp + (y)]; \
(d) ^= exp_to_poly[tmp + (z)]; \
}
/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
* the S vector from CALC_S. CALC_SB_2 computes a single entry in all
* four S-boxes, where i is the index of the entry to compute, and a and b
* are the index numbers preprocessed through the q0 and q1 tables
* respectively. */
#define CALC_SB_2(i, a, b) \
ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
#define CALC_SB192_2(i, a, b) \
ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
#define CALC_SB256_2(i, a, b) \
ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
* last two stages of the h() function for a given index (either 2i or 2i+1).
* a, b, c, and d are the four bytes going into the last two stages. For
* 128-bit keys, this is the entire h() function and a and c are the index
* preprocessed through q0 and q1 respectively; for longer keys they are the
* output of previous stages. j is the index of the first key byte to use.
* CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
* twice, doing the Pseudo-Hadamard Transform, and doing the necessary
* rotations. Its parameters are: a, the array to write the results into,
* j, the index of the first output entry, k and l, the preprocessed indices
* for index 2i, and m and n, the preprocessed indices for index 2i+1.
* CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
* additional lookup-and-XOR stage. The parameters a, b, c and d are the
* four bytes going into the last three stages. For 192-bit keys, c = d
* are the index preprocessed through q0, and a = b are the index
* preprocessed through q1; j is the index of the first key byte to use.
* CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
* instead of CALC_K_2.
* CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
* additional lookup-and-XOR stage. The parameters a and b are the index
* preprocessed through q0 and q1 respectively; j is the index of the first
* key byte to use. CALC_K256 is identical to CALC_K but for using the
* CALC_K256_2 macro instead of CALC_K_2. */
#define CALC_K_2(a, b, c, d, j) \
mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
#define CALC_K(a, j, k, l, m, n) \
x = CALC_K_2 (k, l, k, l, 0); \
y = CALC_K_2 (m, n, m, n, 4); \
y = (y << 8) + (y >> 24); \
x += y; y += x; ctx->a[j] = x; \
ctx->a[(j) + 1] = (y << 9) + (y >> 23)
#define CALC_K192_2(a, b, c, d, j) \
CALC_K_2 (q0[a ^ key[(j) + 16]], \
q1[b ^ key[(j) + 17]], \
q0[c ^ key[(j) + 18]], \
q1[d ^ key[(j) + 19]], j)
#define CALC_K192(a, j, k, l, m, n) \
x = CALC_K192_2 (l, l, k, k, 0); \
y = CALC_K192_2 (n, n, m, m, 4); \
y = (y << 8) + (y >> 24); \
x += y; y += x; ctx->a[j] = x; \
ctx->a[(j) + 1] = (y << 9) + (y >> 23)
#define CALC_K256_2(a, b, j) \
CALC_K192_2 (q1[b ^ key[(j) + 24]], \
q1[a ^ key[(j) + 25]], \
q0[a ^ key[(j) + 26]], \
q0[b ^ key[(j) + 27]], j)
#define CALC_K256(a, j, k, l, m, n) \
x = CALC_K256_2 (k, l, 0); \
y = CALC_K256_2 (m, n, 4); \
y = (y << 8) + (y >> 24); \
x += y; y += x; ctx->a[j] = x; \
ctx->a[(j) + 1] = (y << 9) + (y >> 23)
/* Macros to compute the g() function in the encryption and decryption
* rounds. G1 is the straight g() function; G2 includes the 8-bit
* rotation for the high 32-bit word. */
#define G1(a) \
(ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
#define G2(b) \
(ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
/* Encryption and decryption Feistel rounds. Each one calls the two g()
* macros, does the PHT, and performs the XOR and the appropriate bit
* rotations. The parameters are the round number (used to select subkeys),
* and the four 32-bit chunks of the text. */
#define ENCROUND(n, a, b, c, d) \
x = G1 (a); y = G2 (b); \
x += y; y += x + ctx->k[2 * (n) + 1]; \
(c) ^= x + ctx->k[2 * (n)]; \
(c) = ((c) >> 1) + ((c) << 31); \
(d) = (((d) << 1)+((d) >> 31)) ^ y
#define DECROUND(n, a, b, c, d) \
x = G1 (a); y = G2 (b); \
x += y; y += x; \
(d) ^= y + ctx->k[2 * (n) + 1]; \
(d) = ((d) >> 1) + ((d) << 31); \
(c) = (((c) << 1)+((c) >> 31)); \
(c) ^= (x + ctx->k[2 * (n)])
/* Encryption and decryption cycles; each one is simply two Feistel rounds
* with the 32-bit chunks re-ordered to simulate the "swap" */
#define ENCCYCLE(n) \
ENCROUND (2 * (n), a, b, c, d); \
ENCROUND (2 * (n) + 1, c, d, a, b)
#define DECCYCLE(n) \
DECROUND (2 * (n) + 1, c, d, a, b); \
DECROUND (2 * (n), a, b, c, d)
/* Macros to convert the input and output bytes into 32-bit words,
* and simultaneously perform the whitening step. INPACK packs word
* number n into the variable named by x, using whitening subkey number m.
* OUTUNPACK unpacks word number n from the variable named by x, using
* whitening subkey number m. */
#define INPACK(n, x, m) \
x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
#define OUTUNPACK(n, x, m) \
x ^= ctx->w[m]; \
out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
#define TF_MIN_KEY_SIZE 16
#define TF_MAX_KEY_SIZE 32
#define TF_BLOCK_SIZE 16
/* Structure for an expanded Twofish key. s contains the key-dependent
* S-boxes composed with the MDS matrix; w contains the eight "whitening"
* subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
* that k[i] corresponds to what the Twofish paper calls K[i+8]. */
struct twofish_ctx {
u32 s[4][256], w[8], k[32];
};
/* Perform the key setup. */
static int twofish_setkey(void *cx, const u8 *key,
unsigned int key_len, u32 *flags)
{
struct twofish_ctx *ctx = cx;
int i, j, k;
/* Temporaries for CALC_K. */
u32 x, y;
/* The S vector used to key the S-boxes, split up into individual bytes.
* 128-bit keys use only sa through sh; 256-bit use all of them. */
u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
/* Temporary for CALC_S. */
u8 tmp;
/* Check key length. */
if (key_len != 16 && key_len != 24 && key_len != 32)
{
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL; /* unsupported key length */
}
/* Compute the first two words of the S vector. The magic numbers are
* the entries of the RS matrix, preprocessed through poly_to_exp. The
* numbers in the comments are the original (polynomial form) matrix
* entries. */
CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
/* Calculate the third word of the S vector */
CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
}
if (key_len == 32) { /* 256-bit key */
/* Calculate the fourth word of the S vector */
CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
/* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
/* Calculate whitening and round subkeys. The constants are
* indices of subkeys, preprocessed through q0 and q1. */
CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
} else if (key_len == 24) { /* 192-bit key */
/* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
/* Calculate whitening and round subkeys. The constants are
* indices of subkeys, preprocessed through q0 and q1. */
CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
} else { /* 128-bit key */
/* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
/* Calculate whitening and round subkeys. The constants are
* indices of subkeys, preprocessed through q0 and q1. */
CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
}
return 0;
}
/* Encrypt one block. in and out may be the same. */
static void twofish_encrypt(void *cx, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = cx;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
/* Temporaries used by the round function. */
u32 x, y;
/* Input whitening and packing. */
INPACK (0, a, 0);
INPACK (1, b, 1);
INPACK (2, c, 2);
INPACK (3, d, 3);
/* Encryption Feistel cycles. */
ENCCYCLE (0);
ENCCYCLE (1);
ENCCYCLE (2);
ENCCYCLE (3);
ENCCYCLE (4);
ENCCYCLE (5);
ENCCYCLE (6);
ENCCYCLE (7);
/* Output whitening and unpacking. */
OUTUNPACK (0, c, 4);
OUTUNPACK (1, d, 5);
OUTUNPACK (2, a, 6);
OUTUNPACK (3, b, 7);
}
/* Decrypt one block. in and out may be the same. */
static void twofish_decrypt(void *cx, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = cx;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
/* Temporaries used by the round function. */
u32 x, y;
/* Input whitening and packing. */
INPACK (0, c, 4);
INPACK (1, d, 5);
INPACK (2, a, 6);
INPACK (3, b, 7);
/* Encryption Feistel cycles. */
DECCYCLE (7);
DECCYCLE (6);
DECCYCLE (5);
DECCYCLE (4);
DECCYCLE (3);
DECCYCLE (2);
DECCYCLE (1);
DECCYCLE (0);
/* Output whitening and unpacking. */
OUTUNPACK (0, a, 0);
OUTUNPACK (1, b, 1);
OUTUNPACK (2, c, 2);
OUTUNPACK (3, d, 3);
}
static struct crypto_alg alg = {
.cra_name = "twofish",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = TF_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct twofish_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = TF_MIN_KEY_SIZE,
.cia_max_keysize = TF_MAX_KEY_SIZE,
.cia_setkey = twofish_setkey,
.cia_encrypt = twofish_encrypt,
.cia_decrypt = twofish_decrypt } }
};
static int __init init(void)
{
return crypto_register_alg(&alg);
}
static void __exit fini(void)
{
crypto_unregister_alg(&alg);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION ("Twofish Cipher Algorithm");

File diff suppressed because it is too large Load Diff