Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (48 commits) [NETFILTER]: Fix non-ANSI func. decl. [TG3]: Identify Serdes devices more clearly. [TG3]: Use msleep. [TG3]: Use netif_msg_*. [TG3]: Allow partial speed advertisement. [TG3]: Add TG3_FLG2_IS_NIC flag. [TG3]: Add 5787F device ID. [TG3]: Fix Phy loopback. [WANROUTER]: Kill kmalloc debugging code. [TCP] inet_twdr_hangman: Delete unnecessary memory barrier(). [NET]: Memory barrier cleanups [IPSEC]: Fix inetpeer leak in ipv4 xfrm dst entries. audit: disable ipsec auditing when CONFIG_AUDITSYSCALL=n audit: Add auditing to ipsec [IRDA] irlan: Fix compile warning when CONFIG_PROC_FS=n [IrDA]: Incorrect TTP header reservation [IrDA]: PXA FIR code device model conversion [GENETLINK]: Fix misplaced command flags. [NETLIK]: Add a pointer to the Generic Netlink wiki page. [IPV6] RAW: Don't release unlocked sock. ...
This commit is contained in:
commit
2685b267bc
@ -58,6 +58,8 @@ fore200e.txt
|
||||
- FORE Systems PCA-200E/SBA-200E ATM NIC driver info.
|
||||
framerelay.txt
|
||||
- info on using Frame Relay/Data Link Connection Identifier (DLCI).
|
||||
generic_netlink.txt
|
||||
- info on Generic Netlink
|
||||
ip-sysctl.txt
|
||||
- /proc/sys/net/ipv4/* variables
|
||||
ip_dynaddr.txt
|
||||
|
3
Documentation/networking/generic_netlink.txt
Normal file
3
Documentation/networking/generic_netlink.txt
Normal file
@ -0,0 +1,3 @@
|
||||
A wiki document on how to use Generic Netlink can be found here:
|
||||
|
||||
* http://linux-net.osdl.org/index.php/Generic_Netlink_HOWTO
|
@ -39,6 +39,17 @@ config CRYPTO_HMAC
|
||||
HMAC: Keyed-Hashing for Message Authentication (RFC2104).
|
||||
This is required for IPSec.
|
||||
|
||||
config CRYPTO_XCBC
|
||||
tristate "XCBC support"
|
||||
depends on EXPERIMENTAL
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
XCBC: Keyed-Hashing with encryption algorithm
|
||||
http://www.ietf.org/rfc/rfc3566.txt
|
||||
http://csrc.nist.gov/encryption/modes/proposedmodes/
|
||||
xcbc-mac/xcbc-mac-spec.pdf
|
||||
|
||||
config CRYPTO_NULL
|
||||
tristate "Null algorithms"
|
||||
select CRYPTO_ALGAPI
|
||||
@ -128,6 +139,16 @@ config CRYPTO_TGR192
|
||||
See also:
|
||||
<http://www.cs.technion.ac.il/~biham/Reports/Tiger/>.
|
||||
|
||||
config CRYPTO_GF128MUL
|
||||
tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
help
|
||||
Efficient table driven implementation of multiplications in the
|
||||
field GF(2^128). This is needed by some cypher modes. This
|
||||
option will be selected automatically if you select such a
|
||||
cipher mode. Only select this option by hand if you expect to load
|
||||
an external module that requires these functions.
|
||||
|
||||
config CRYPTO_ECB
|
||||
tristate "ECB support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
@ -147,6 +168,19 @@ config CRYPTO_CBC
|
||||
CBC: Cipher Block Chaining mode
|
||||
This block cipher algorithm is required for IPSec.
|
||||
|
||||
config CRYPTO_LRW
|
||||
tristate "LRW support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
select CRYPTO_GF128MUL
|
||||
help
|
||||
LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable
|
||||
narrow block cipher mode for dm-crypt. Use it with cipher
|
||||
specification string aes-lrw-benbi, the key must be 256, 320 or 384.
|
||||
The first 128, 192 or 256 bits in the key are used for AES and the
|
||||
rest is used to tie each cipher block to its logical position.
|
||||
|
||||
config CRYPTO_DES
|
||||
tristate "DES and Triple DES EDE cipher algorithms"
|
||||
select CRYPTO_ALGAPI
|
||||
|
@ -15,6 +15,7 @@ obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
|
||||
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
|
||||
obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
|
||||
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
|
||||
obj-$(CONFIG_CRYPTO_MD4) += md4.o
|
||||
obj-$(CONFIG_CRYPTO_MD5) += md5.o
|
||||
@ -23,8 +24,10 @@ obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
|
||||
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
|
||||
obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
|
||||
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
|
||||
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
|
||||
obj-$(CONFIG_CRYPTO_CBC) += cbc.o
|
||||
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
|
||||
obj-$(CONFIG_CRYPTO_DES) += des.o
|
||||
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
|
||||
|
15
crypto/api.c
15
crypto/api.c
@ -466,23 +466,8 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
int crypto_alg_available(const char *name, u32 flags)
|
||||
{
|
||||
int ret = 0;
|
||||
struct crypto_alg *alg = crypto_alg_mod_lookup(name, 0,
|
||||
CRYPTO_ALG_ASYNC);
|
||||
|
||||
if (!IS_ERR(alg)) {
|
||||
crypto_mod_put(alg);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
|
||||
EXPORT_SYMBOL_GPL(crypto_free_tfm);
|
||||
EXPORT_SYMBOL_GPL(crypto_alg_available);
|
||||
|
||||
int crypto_has_alg(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
|
@ -21,54 +21,6 @@
|
||||
#include "internal.h"
|
||||
#include "scatterwalk.h"
|
||||
|
||||
void crypto_digest_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_hash *hash = crypto_hash_cast(tfm);
|
||||
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
|
||||
|
||||
crypto_hash_init(&desc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_digest_init);
|
||||
|
||||
void crypto_digest_update(struct crypto_tfm *tfm,
|
||||
struct scatterlist *sg, unsigned int nsg)
|
||||
{
|
||||
struct crypto_hash *hash = crypto_hash_cast(tfm);
|
||||
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
|
||||
unsigned int nbytes = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nsg; i++)
|
||||
nbytes += sg[i].length;
|
||||
|
||||
crypto_hash_update(&desc, sg, nbytes);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_digest_update);
|
||||
|
||||
void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
|
||||
{
|
||||
struct crypto_hash *hash = crypto_hash_cast(tfm);
|
||||
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
|
||||
|
||||
crypto_hash_final(&desc, out);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_digest_final);
|
||||
|
||||
void crypto_digest_digest(struct crypto_tfm *tfm,
|
||||
struct scatterlist *sg, unsigned int nsg, u8 *out)
|
||||
{
|
||||
struct crypto_hash *hash = crypto_hash_cast(tfm);
|
||||
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
|
||||
unsigned int nbytes = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nsg; i++)
|
||||
nbytes += sg[i].length;
|
||||
|
||||
crypto_hash_digest(&desc, sg, nbytes, out);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_digest_digest);
|
||||
|
||||
static int init(struct hash_desc *desc)
|
||||
{
|
||||
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
|
||||
|
466
crypto/gf128mul.c
Normal file
466
crypto/gf128mul.c
Normal file
@ -0,0 +1,466 @@
|
||||
/* gf128mul.c - GF(2^128) multiplication functions
|
||||
*
|
||||
* Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.
|
||||
* Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* Based on Dr Brian Gladman's (GPL'd) work published at
|
||||
* http://fp.gladman.plus.com/cryptography_technology/index.htm
|
||||
* See the original copyright notice below.
|
||||
*
|
||||
* 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) 2003, Dr Brian Gladman, 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.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 31/01/2006
|
||||
|
||||
This file provides fast multiplication in GF(128) as required by several
|
||||
cryptographic authentication modes
|
||||
*/
|
||||
|
||||
#include <crypto/gf128mul.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define gf128mul_dat(q) { \
|
||||
q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
|
||||
q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
|
||||
q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
|
||||
q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
|
||||
q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
|
||||
q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
|
||||
q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
|
||||
q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
|
||||
q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
|
||||
q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
|
||||
q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
|
||||
q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
|
||||
q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
|
||||
q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
|
||||
q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
|
||||
q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
|
||||
q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
|
||||
q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
|
||||
q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
|
||||
q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
|
||||
q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
|
||||
q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
|
||||
q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
|
||||
q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
|
||||
q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
|
||||
q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
|
||||
q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
|
||||
q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
|
||||
q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
|
||||
q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
|
||||
q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
|
||||
q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) \
|
||||
}
|
||||
|
||||
/* Given the value i in 0..255 as the byte overflow when a field element
|
||||
in GHASH is multipled by x^8, this function will return the values that
|
||||
are generated in the lo 16-bit word of the field value by applying the
|
||||
modular polynomial. The values lo_byte and hi_byte are returned via the
|
||||
macro xp_fun(lo_byte, hi_byte) so that the values can be assembled into
|
||||
memory as required by a suitable definition of this macro operating on
|
||||
the table above
|
||||
*/
|
||||
|
||||
#define xx(p, q) 0x##p##q
|
||||
|
||||
#define xda_bbe(i) ( \
|
||||
(i & 0x80 ? xx(43, 80) : 0) ^ (i & 0x40 ? xx(21, c0) : 0) ^ \
|
||||
(i & 0x20 ? xx(10, e0) : 0) ^ (i & 0x10 ? xx(08, 70) : 0) ^ \
|
||||
(i & 0x08 ? xx(04, 38) : 0) ^ (i & 0x04 ? xx(02, 1c) : 0) ^ \
|
||||
(i & 0x02 ? xx(01, 0e) : 0) ^ (i & 0x01 ? xx(00, 87) : 0) \
|
||||
)
|
||||
|
||||
#define xda_lle(i) ( \
|
||||
(i & 0x80 ? xx(e1, 00) : 0) ^ (i & 0x40 ? xx(70, 80) : 0) ^ \
|
||||
(i & 0x20 ? xx(38, 40) : 0) ^ (i & 0x10 ? xx(1c, 20) : 0) ^ \
|
||||
(i & 0x08 ? xx(0e, 10) : 0) ^ (i & 0x04 ? xx(07, 08) : 0) ^ \
|
||||
(i & 0x02 ? xx(03, 84) : 0) ^ (i & 0x01 ? xx(01, c2) : 0) \
|
||||
)
|
||||
|
||||
static const u16 gf128mul_table_lle[256] = gf128mul_dat(xda_lle);
|
||||
static const u16 gf128mul_table_bbe[256] = gf128mul_dat(xda_bbe);
|
||||
|
||||
/* These functions multiply a field element by x, by x^4 and by x^8
|
||||
* in the polynomial field representation. It uses 32-bit word operations
|
||||
* to gain speed but compensates for machine endianess and hence works
|
||||
* correctly on both styles of machine.
|
||||
*/
|
||||
|
||||
static void gf128mul_x_lle(be128 *r, const be128 *x)
|
||||
{
|
||||
u64 a = be64_to_cpu(x->a);
|
||||
u64 b = be64_to_cpu(x->b);
|
||||
u64 _tt = gf128mul_table_lle[(b << 7) & 0xff];
|
||||
|
||||
r->b = cpu_to_be64((b >> 1) | (a << 63));
|
||||
r->a = cpu_to_be64((a >> 1) ^ (_tt << 48));
|
||||
}
|
||||
|
||||
static void gf128mul_x_bbe(be128 *r, const be128 *x)
|
||||
{
|
||||
u64 a = be64_to_cpu(x->a);
|
||||
u64 b = be64_to_cpu(x->b);
|
||||
u64 _tt = gf128mul_table_bbe[a >> 63];
|
||||
|
||||
r->a = cpu_to_be64((a << 1) | (b >> 63));
|
||||
r->b = cpu_to_be64((b << 1) ^ _tt);
|
||||
}
|
||||
|
||||
static void gf128mul_x8_lle(be128 *x)
|
||||
{
|
||||
u64 a = be64_to_cpu(x->a);
|
||||
u64 b = be64_to_cpu(x->b);
|
||||
u64 _tt = gf128mul_table_lle[b & 0xff];
|
||||
|
||||
x->b = cpu_to_be64((b >> 8) | (a << 56));
|
||||
x->a = cpu_to_be64((a >> 8) ^ (_tt << 48));
|
||||
}
|
||||
|
||||
static void gf128mul_x8_bbe(be128 *x)
|
||||
{
|
||||
u64 a = be64_to_cpu(x->a);
|
||||
u64 b = be64_to_cpu(x->b);
|
||||
u64 _tt = gf128mul_table_bbe[a >> 56];
|
||||
|
||||
x->a = cpu_to_be64((a << 8) | (b >> 56));
|
||||
x->b = cpu_to_be64((b << 8) ^ _tt);
|
||||
}
|
||||
|
||||
void gf128mul_lle(be128 *r, const be128 *b)
|
||||
{
|
||||
be128 p[8];
|
||||
int i;
|
||||
|
||||
p[0] = *r;
|
||||
for (i = 0; i < 7; ++i)
|
||||
gf128mul_x_lle(&p[i + 1], &p[i]);
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
for (i = 0;;) {
|
||||
u8 ch = ((u8 *)b)[15 - i];
|
||||
|
||||
if (ch & 0x80)
|
||||
be128_xor(r, r, &p[0]);
|
||||
if (ch & 0x40)
|
||||
be128_xor(r, r, &p[1]);
|
||||
if (ch & 0x20)
|
||||
be128_xor(r, r, &p[2]);
|
||||
if (ch & 0x10)
|
||||
be128_xor(r, r, &p[3]);
|
||||
if (ch & 0x08)
|
||||
be128_xor(r, r, &p[4]);
|
||||
if (ch & 0x04)
|
||||
be128_xor(r, r, &p[5]);
|
||||
if (ch & 0x02)
|
||||
be128_xor(r, r, &p[6]);
|
||||
if (ch & 0x01)
|
||||
be128_xor(r, r, &p[7]);
|
||||
|
||||
if (++i >= 16)
|
||||
break;
|
||||
|
||||
gf128mul_x8_lle(r);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_lle);
|
||||
|
||||
void gf128mul_bbe(be128 *r, const be128 *b)
|
||||
{
|
||||
be128 p[8];
|
||||
int i;
|
||||
|
||||
p[0] = *r;
|
||||
for (i = 0; i < 7; ++i)
|
||||
gf128mul_x_bbe(&p[i + 1], &p[i]);
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
for (i = 0;;) {
|
||||
u8 ch = ((u8 *)b)[i];
|
||||
|
||||
if (ch & 0x80)
|
||||
be128_xor(r, r, &p[7]);
|
||||
if (ch & 0x40)
|
||||
be128_xor(r, r, &p[6]);
|
||||
if (ch & 0x20)
|
||||
be128_xor(r, r, &p[5]);
|
||||
if (ch & 0x10)
|
||||
be128_xor(r, r, &p[4]);
|
||||
if (ch & 0x08)
|
||||
be128_xor(r, r, &p[3]);
|
||||
if (ch & 0x04)
|
||||
be128_xor(r, r, &p[2]);
|
||||
if (ch & 0x02)
|
||||
be128_xor(r, r, &p[1]);
|
||||
if (ch & 0x01)
|
||||
be128_xor(r, r, &p[0]);
|
||||
|
||||
if (++i >= 16)
|
||||
break;
|
||||
|
||||
gf128mul_x8_bbe(r);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_bbe);
|
||||
|
||||
/* This version uses 64k bytes of table space.
|
||||
A 16 byte buffer has to be multiplied by a 16 byte key
|
||||
value in GF(128). If we consider a GF(128) value in
|
||||
the buffer's lowest byte, we can construct a table of
|
||||
the 256 16 byte values that result from the 256 values
|
||||
of this byte. This requires 4096 bytes. But we also
|
||||
need tables for each of the 16 higher bytes in the
|
||||
buffer as well, which makes 64 kbytes in total.
|
||||
*/
|
||||
/* additional explanation
|
||||
* t[0][BYTE] contains g*BYTE
|
||||
* t[1][BYTE] contains g*x^8*BYTE
|
||||
* ..
|
||||
* t[15][BYTE] contains g*x^120*BYTE */
|
||||
struct gf128mul_64k *gf128mul_init_64k_lle(const be128 *g)
|
||||
{
|
||||
struct gf128mul_64k *t;
|
||||
int i, j, k;
|
||||
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (!t)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
t->t[i] = kzalloc(sizeof(*t->t[i]), GFP_KERNEL);
|
||||
if (!t->t[i]) {
|
||||
gf128mul_free_64k(t);
|
||||
t = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
t->t[0]->t[128] = *g;
|
||||
for (j = 64; j > 0; j >>= 1)
|
||||
gf128mul_x_lle(&t->t[0]->t[j], &t->t[0]->t[j + j]);
|
||||
|
||||
for (i = 0;;) {
|
||||
for (j = 2; j < 256; j += j)
|
||||
for (k = 1; k < j; ++k)
|
||||
be128_xor(&t->t[i]->t[j + k],
|
||||
&t->t[i]->t[j], &t->t[i]->t[k]);
|
||||
|
||||
if (++i >= 16)
|
||||
break;
|
||||
|
||||
for (j = 128; j > 0; j >>= 1) {
|
||||
t->t[i]->t[j] = t->t[i - 1]->t[j];
|
||||
gf128mul_x8_lle(&t->t[i]->t[j]);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return t;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_init_64k_lle);
|
||||
|
||||
struct gf128mul_64k *gf128mul_init_64k_bbe(const be128 *g)
|
||||
{
|
||||
struct gf128mul_64k *t;
|
||||
int i, j, k;
|
||||
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (!t)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
t->t[i] = kzalloc(sizeof(*t->t[i]), GFP_KERNEL);
|
||||
if (!t->t[i]) {
|
||||
gf128mul_free_64k(t);
|
||||
t = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
t->t[0]->t[1] = *g;
|
||||
for (j = 1; j <= 64; j <<= 1)
|
||||
gf128mul_x_bbe(&t->t[0]->t[j + j], &t->t[0]->t[j]);
|
||||
|
||||
for (i = 0;;) {
|
||||
for (j = 2; j < 256; j += j)
|
||||
for (k = 1; k < j; ++k)
|
||||
be128_xor(&t->t[i]->t[j + k],
|
||||
&t->t[i]->t[j], &t->t[i]->t[k]);
|
||||
|
||||
if (++i >= 16)
|
||||
break;
|
||||
|
||||
for (j = 128; j > 0; j >>= 1) {
|
||||
t->t[i]->t[j] = t->t[i - 1]->t[j];
|
||||
gf128mul_x8_bbe(&t->t[i]->t[j]);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return t;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_init_64k_bbe);
|
||||
|
||||
void gf128mul_free_64k(struct gf128mul_64k *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
kfree(t->t[i]);
|
||||
kfree(t);
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_free_64k);
|
||||
|
||||
void gf128mul_64k_lle(be128 *a, struct gf128mul_64k *t)
|
||||
{
|
||||
u8 *ap = (u8 *)a;
|
||||
be128 r[1];
|
||||
int i;
|
||||
|
||||
*r = t->t[0]->t[ap[0]];
|
||||
for (i = 1; i < 16; ++i)
|
||||
be128_xor(r, r, &t->t[i]->t[ap[i]]);
|
||||
*a = *r;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_64k_lle);
|
||||
|
||||
void gf128mul_64k_bbe(be128 *a, struct gf128mul_64k *t)
|
||||
{
|
||||
u8 *ap = (u8 *)a;
|
||||
be128 r[1];
|
||||
int i;
|
||||
|
||||
*r = t->t[0]->t[ap[15]];
|
||||
for (i = 1; i < 16; ++i)
|
||||
be128_xor(r, r, &t->t[i]->t[ap[15 - i]]);
|
||||
*a = *r;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_64k_bbe);
|
||||
|
||||
/* This version uses 4k bytes of table space.
|
||||
A 16 byte buffer has to be multiplied by a 16 byte key
|
||||
value in GF(128). If we consider a GF(128) value in a
|
||||
single byte, we can construct a table of the 256 16 byte
|
||||
values that result from the 256 values of this byte.
|
||||
This requires 4096 bytes. If we take the highest byte in
|
||||
the buffer and use this table to get the result, we then
|
||||
have to multiply by x^120 to get the final value. For the
|
||||
next highest byte the result has to be multiplied by x^112
|
||||
and so on. But we can do this by accumulating the result
|
||||
in an accumulator starting with the result for the top
|
||||
byte. We repeatedly multiply the accumulator value by
|
||||
x^8 and then add in (i.e. xor) the 16 bytes of the next
|
||||
lower byte in the buffer, stopping when we reach the
|
||||
lowest byte. This requires a 4096 byte table.
|
||||
*/
|
||||
struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g)
|
||||
{
|
||||
struct gf128mul_4k *t;
|
||||
int j, k;
|
||||
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (!t)
|
||||
goto out;
|
||||
|
||||
t->t[128] = *g;
|
||||
for (j = 64; j > 0; j >>= 1)
|
||||
gf128mul_x_lle(&t->t[j], &t->t[j+j]);
|
||||
|
||||
for (j = 2; j < 256; j += j)
|
||||
for (k = 1; k < j; ++k)
|
||||
be128_xor(&t->t[j + k], &t->t[j], &t->t[k]);
|
||||
|
||||
out:
|
||||
return t;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_init_4k_lle);
|
||||
|
||||
struct gf128mul_4k *gf128mul_init_4k_bbe(const be128 *g)
|
||||
{
|
||||
struct gf128mul_4k *t;
|
||||
int j, k;
|
||||
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (!t)
|
||||
goto out;
|
||||
|
||||
t->t[1] = *g;
|
||||
for (j = 1; j <= 64; j <<= 1)
|
||||
gf128mul_x_bbe(&t->t[j + j], &t->t[j]);
|
||||
|
||||
for (j = 2; j < 256; j += j)
|
||||
for (k = 1; k < j; ++k)
|
||||
be128_xor(&t->t[j + k], &t->t[j], &t->t[k]);
|
||||
|
||||
out:
|
||||
return t;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_init_4k_bbe);
|
||||
|
||||
void gf128mul_4k_lle(be128 *a, struct gf128mul_4k *t)
|
||||
{
|
||||
u8 *ap = (u8 *)a;
|
||||
be128 r[1];
|
||||
int i = 15;
|
||||
|
||||
*r = t->t[ap[15]];
|
||||
while (i--) {
|
||||
gf128mul_x8_lle(r);
|
||||
be128_xor(r, r, &t->t[ap[i]]);
|
||||
}
|
||||
*a = *r;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_4k_lle);
|
||||
|
||||
void gf128mul_4k_bbe(be128 *a, struct gf128mul_4k *t)
|
||||
{
|
||||
u8 *ap = (u8 *)a;
|
||||
be128 r[1];
|
||||
int i = 0;
|
||||
|
||||
*r = t->t[ap[0]];
|
||||
while (++i < 16) {
|
||||
gf128mul_x8_bbe(r);
|
||||
be128_xor(r, r, &t->t[ap[i]]);
|
||||
}
|
||||
*a = *r;
|
||||
}
|
||||
EXPORT_SYMBOL(gf128mul_4k_bbe);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Functions for multiplying elements of GF(2^128)");
|
301
crypto/lrw.c
Normal file
301
crypto/lrw.c
Normal file
@ -0,0 +1,301 @@
|
||||
/* LRW: as defined by Cyril Guyot in
|
||||
* http://grouper.ieee.org/groups/1619/email/pdf00017.pdf
|
||||
*
|
||||
* Copyright (c) 2006 Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* Based om ecb.c
|
||||
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.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.
|
||||
*/
|
||||
/* This implementation is checked against the test vectors in the above
|
||||
* document and by a test vector provided by Ken Buchanan at
|
||||
* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html
|
||||
*
|
||||
* The test vectors are included in the testing module tcrypt.[ch] */
|
||||
#include <crypto/algapi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <crypto/b128ops.h>
|
||||
#include <crypto/gf128mul.h>
|
||||
|
||||
struct priv {
|
||||
struct crypto_cipher *child;
|
||||
/* optimizes multiplying a random (non incrementing, as at the
|
||||
* start of a new sector) value with key2, we could also have
|
||||
* used 4k optimization tables or no optimization at all. In the
|
||||
* latter case we would have to store key2 here */
|
||||
struct gf128mul_64k *table;
|
||||
/* stores:
|
||||
* key2*{ 0,0,...0,0,0,0,1 }, key2*{ 0,0,...0,0,0,1,1 },
|
||||
* key2*{ 0,0,...0,0,1,1,1 }, key2*{ 0,0,...0,1,1,1,1 }
|
||||
* key2*{ 0,0,...1,1,1,1,1 }, etc
|
||||
* needed for optimized multiplication of incrementing values
|
||||
* with key2 */
|
||||
be128 mulinc[128];
|
||||
};
|
||||
|
||||
static inline void setbit128_bbe(void *b, int bit)
|
||||
{
|
||||
__set_bit(bit ^ 0x78, b);
|
||||
}
|
||||
|
||||
static int setkey(struct crypto_tfm *parent, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct priv *ctx = crypto_tfm_ctx(parent);
|
||||
struct crypto_cipher *child = ctx->child;
|
||||
int err, i;
|
||||
be128 tmp = { 0 };
|
||||
int bsize = crypto_cipher_blocksize(child);
|
||||
|
||||
crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
|
||||
crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
if ((err = crypto_cipher_setkey(child, key, keylen - bsize)))
|
||||
return err;
|
||||
crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
|
||||
if (ctx->table)
|
||||
gf128mul_free_64k(ctx->table);
|
||||
|
||||
/* initialize multiplication table for Key2 */
|
||||
ctx->table = gf128mul_init_64k_bbe((be128 *)(key + keylen - bsize));
|
||||
if (!ctx->table)
|
||||
return -ENOMEM;
|
||||
|
||||
/* initialize optimization table */
|
||||
for (i = 0; i < 128; i++) {
|
||||
setbit128_bbe(&tmp, i);
|
||||
ctx->mulinc[i] = tmp;
|
||||
gf128mul_64k_bbe(&ctx->mulinc[i], ctx->table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sinfo {
|
||||
be128 t;
|
||||
struct crypto_tfm *tfm;
|
||||
void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
|
||||
};
|
||||
|
||||
static inline void inc(be128 *iv)
|
||||
{
|
||||
if (!(iv->b = cpu_to_be64(be64_to_cpu(iv->b) + 1)))
|
||||
iv->a = cpu_to_be64(be64_to_cpu(iv->a) + 1);
|
||||
}
|
||||
|
||||
static inline void lrw_round(struct sinfo *s, void *dst, const void *src)
|
||||
{
|
||||
be128_xor(dst, &s->t, src); /* PP <- T xor P */
|
||||
s->fn(s->tfm, dst, dst); /* CC <- E(Key2,PP) */
|
||||
be128_xor(dst, dst, &s->t); /* C <- T xor CC */
|
||||
}
|
||||
|
||||
/* this returns the number of consequative 1 bits starting
|
||||
* from the right, get_index128(00 00 00 00 00 00 ... 00 00 10 FB) = 2 */
|
||||
static inline int get_index128(be128 *block)
|
||||
{
|
||||
int x;
|
||||
__be32 *p = (__be32 *) block;
|
||||
|
||||
for (p += 3, x = 0; x < 128; p--, x += 32) {
|
||||
u32 val = be32_to_cpup(p);
|
||||
|
||||
if (!~val)
|
||||
continue;
|
||||
|
||||
return x + ffz(val);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static int crypt(struct blkcipher_desc *d,
|
||||
struct blkcipher_walk *w, struct priv *ctx,
|
||||
void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
|
||||
{
|
||||
int err;
|
||||
unsigned int avail;
|
||||
const int bs = crypto_cipher_blocksize(ctx->child);
|
||||
struct sinfo s = {
|
||||
.tfm = crypto_cipher_tfm(ctx->child),
|
||||
.fn = fn
|
||||
};
|
||||
be128 *iv;
|
||||
u8 *wsrc;
|
||||
u8 *wdst;
|
||||
|
||||
err = blkcipher_walk_virt(d, w);
|
||||
if (!(avail = w->nbytes))
|
||||
return err;
|
||||
|
||||
wsrc = w->src.virt.addr;
|
||||
wdst = w->dst.virt.addr;
|
||||
|
||||
/* calculate first value of T */
|
||||
iv = (be128 *)w->iv;
|
||||
s.t = *iv;
|
||||
|
||||
/* T <- I*Key2 */
|
||||
gf128mul_64k_bbe(&s.t, ctx->table);
|
||||
|
||||
goto first;
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
/* T <- I*Key2, using the optimization
|
||||
* discussed in the specification */
|
||||
be128_xor(&s.t, &s.t, &ctx->mulinc[get_index128(iv)]);
|
||||
inc(iv);
|
||||
|
||||
first:
|
||||
lrw_round(&s, wdst, wsrc);
|
||||
|
||||
wsrc += bs;
|
||||
wdst += bs;
|
||||
} while ((avail -= bs) >= bs);
|
||||
|
||||
err = blkcipher_walk_done(d, w, avail);
|
||||
if (!(avail = w->nbytes))
|
||||
break;
|
||||
|
||||
wsrc = w->src.virt.addr;
|
||||
wdst = w->dst.virt.addr;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct priv *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk w;
|
||||
|
||||
blkcipher_walk_init(&w, dst, src, nbytes);
|
||||
return crypt(desc, &w, ctx,
|
||||
crypto_cipher_alg(ctx->child)->cia_encrypt);
|
||||
}
|
||||
|
||||
static int decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct priv *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk w;
|
||||
|
||||
blkcipher_walk_init(&w, dst, src, nbytes);
|
||||
return crypt(desc, &w, ctx,
|
||||
crypto_cipher_alg(ctx->child)->cia_decrypt);
|
||||
}
|
||||
|
||||
static int init_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_instance *inst = (void *)tfm->__crt_alg;
|
||||
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
|
||||
struct priv *ctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
|
||||
tfm = crypto_spawn_tfm(spawn);
|
||||
if (IS_ERR(tfm))
|
||||
return PTR_ERR(tfm);
|
||||
|
||||
if (crypto_tfm_alg_blocksize(tfm) != 16) {
|
||||
*flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->child = crypto_cipher_cast(tfm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void exit_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct priv *ctx = crypto_tfm_ctx(tfm);
|
||||
if (ctx->table)
|
||||
gf128mul_free_64k(ctx->table);
|
||||
crypto_free_cipher(ctx->child);
|
||||
}
|
||||
|
||||
static struct crypto_instance *alloc(void *param, unsigned int len)
|
||||
{
|
||||
struct crypto_instance *inst;
|
||||
struct crypto_alg *alg;
|
||||
|
||||
alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(alg))
|
||||
return ERR_PTR(PTR_ERR(alg));
|
||||
|
||||
inst = crypto_alloc_instance("lrw", alg);
|
||||
if (IS_ERR(inst))
|
||||
goto out_put_alg;
|
||||
|
||||
inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
|
||||
inst->alg.cra_priority = alg->cra_priority;
|
||||
inst->alg.cra_blocksize = alg->cra_blocksize;
|
||||
|
||||
if (alg->cra_alignmask < 7) inst->alg.cra_alignmask = 7;
|
||||
else inst->alg.cra_alignmask = alg->cra_alignmask;
|
||||
inst->alg.cra_type = &crypto_blkcipher_type;
|
||||
|
||||
if (!(alg->cra_blocksize % 4))
|
||||
inst->alg.cra_alignmask |= 3;
|
||||
inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
|
||||
inst->alg.cra_blkcipher.min_keysize =
|
||||
alg->cra_cipher.cia_min_keysize + alg->cra_blocksize;
|
||||
inst->alg.cra_blkcipher.max_keysize =
|
||||
alg->cra_cipher.cia_max_keysize + alg->cra_blocksize;
|
||||
|
||||
inst->alg.cra_ctxsize = sizeof(struct priv);
|
||||
|
||||
inst->alg.cra_init = init_tfm;
|
||||
inst->alg.cra_exit = exit_tfm;
|
||||
|
||||
inst->alg.cra_blkcipher.setkey = setkey;
|
||||
inst->alg.cra_blkcipher.encrypt = encrypt;
|
||||
inst->alg.cra_blkcipher.decrypt = decrypt;
|
||||
|
||||
out_put_alg:
|
||||
crypto_mod_put(alg);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void free(struct crypto_instance *inst)
|
||||
{
|
||||
crypto_drop_spawn(crypto_instance_ctx(inst));
|
||||
kfree(inst);
|
||||
}
|
||||
|
||||
static struct crypto_template crypto_tmpl = {
|
||||
.name = "lrw",
|
||||
.alloc = alloc,
|
||||
.free = free,
|
||||
.module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init crypto_module_init(void)
|
||||
{
|
||||
return crypto_register_template(&crypto_tmpl);
|
||||
}
|
||||
|
||||
static void __exit crypto_module_exit(void)
|
||||
{
|
||||
crypto_unregister_template(&crypto_tmpl);
|
||||
}
|
||||
|
||||
module_init(crypto_module_init);
|
||||
module_exit(crypto_module_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("LRW block cipher mode");
|
@ -906,6 +906,10 @@ static void do_test(void)
|
||||
AES_CBC_ENC_TEST_VECTORS);
|
||||
test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
|
||||
AES_CBC_DEC_TEST_VECTORS);
|
||||
test_cipher("lrw(aes)", ENCRYPT, aes_lrw_enc_tv_template,
|
||||
AES_LRW_ENC_TEST_VECTORS);
|
||||
test_cipher("lrw(aes)", DECRYPT, aes_lrw_dec_tv_template,
|
||||
AES_LRW_DEC_TEST_VECTORS);
|
||||
|
||||
//CAST5
|
||||
test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
|
||||
@ -977,6 +981,9 @@ static void do_test(void)
|
||||
test_hash("hmac(sha256)", hmac_sha256_tv_template,
|
||||
HMAC_SHA256_TEST_VECTORS);
|
||||
|
||||
test_hash("xcbc(aes)", aes_xcbc128_tv_template,
|
||||
XCBC_AES_TEST_VECTORS);
|
||||
|
||||
test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
|
||||
break;
|
||||
|
||||
@ -1052,6 +1059,10 @@ static void do_test(void)
|
||||
AES_CBC_ENC_TEST_VECTORS);
|
||||
test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
|
||||
AES_CBC_DEC_TEST_VECTORS);
|
||||
test_cipher("lrw(aes)", ENCRYPT, aes_lrw_enc_tv_template,
|
||||
AES_LRW_ENC_TEST_VECTORS);
|
||||
test_cipher("lrw(aes)", DECRYPT, aes_lrw_dec_tv_template,
|
||||
AES_LRW_DEC_TEST_VECTORS);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
@ -1191,6 +1202,10 @@ static void do_test(void)
|
||||
aes_speed_template);
|
||||
test_cipher_speed("cbc(aes)", DECRYPT, sec, NULL, 0,
|
||||
aes_speed_template);
|
||||
test_cipher_speed("lrw(aes)", ENCRYPT, sec, NULL, 0,
|
||||
aes_lrw_speed_template);
|
||||
test_cipher_speed("lrw(aes)", DECRYPT, sec, NULL, 0,
|
||||
aes_lrw_speed_template);
|
||||
break;
|
||||
|
||||
case 201:
|
||||
|
602
crypto/tcrypt.h
602
crypto/tcrypt.h
@ -39,15 +39,15 @@ struct hash_testvec {
|
||||
struct cipher_testvec {
|
||||
char key[MAX_KEYLEN] __attribute__ ((__aligned__(4)));
|
||||
char iv[MAX_IVLEN];
|
||||
char input[48];
|
||||
char result[48];
|
||||
char input[512];
|
||||
char result[512];
|
||||
unsigned char tap[MAX_TAP];
|
||||
int np;
|
||||
unsigned char fail;
|
||||
unsigned char wk; /* weak key flag */
|
||||
unsigned char klen;
|
||||
unsigned char ilen;
|
||||
unsigned char rlen;
|
||||
unsigned short ilen;
|
||||
unsigned short rlen;
|
||||
};
|
||||
|
||||
struct cipher_speed {
|
||||
@ -933,6 +933,74 @@ static struct hash_testvec hmac_sha256_tv_template[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define XCBC_AES_TEST_VECTORS 6
|
||||
|
||||
static struct hash_testvec aes_xcbc128_tv_template[] = {
|
||||
{
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { [0 ... 15] = 0 },
|
||||
.digest = { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, 0xc0, 0x1c,
|
||||
0x45, 0x73, 0xdf, 0xd5, 0x84, 0xd7, 0x9f, 0x29 },
|
||||
.psize = 0,
|
||||
.ksize = 16,
|
||||
}, {
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { 0x00, 0x01, 0x02 },
|
||||
.digest = { 0x5b, 0x37, 0x65, 0x80, 0xae, 0x2f, 0x19, 0xaf,
|
||||
0xe7, 0x21, 0x9c, 0xee, 0xf1, 0x72, 0x75, 0x6f },
|
||||
.psize = 3,
|
||||
.ksize = 16,
|
||||
} , {
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.digest = { 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, 0x68, 0xa7,
|
||||
0x99, 0x98, 0xa4, 0x39, 0x4f, 0xf7, 0xa2, 0x63 },
|
||||
.psize = 16,
|
||||
.ksize = 16,
|
||||
}, {
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13 },
|
||||
.digest = { 0x47, 0xf5, 0x1b, 0x45, 0x64, 0x96, 0x62, 0x15,
|
||||
0xb8, 0x98, 0x5c, 0x63, 0x05, 0x5e, 0xd3, 0x08 },
|
||||
.tap = { 10, 10 },
|
||||
.psize = 20,
|
||||
.np = 2,
|
||||
.ksize = 16,
|
||||
}, {
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
|
||||
.digest = { 0xf5, 0x4f, 0x0e, 0xc8, 0xd2, 0xb9, 0xf3, 0xd3,
|
||||
0x68, 0x07, 0x73, 0x4b, 0xd5, 0x28, 0x3f, 0xd4 },
|
||||
.psize = 32,
|
||||
.ksize = 16,
|
||||
}, {
|
||||
.key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
.plaintext = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21 },
|
||||
.digest = { 0xbe, 0xcb, 0xb3, 0xbc, 0xcd, 0xb5, 0x18, 0xa3,
|
||||
0x06, 0x77, 0xd5, 0x48, 0x1f, 0xb6, 0xb4, 0xd8 },
|
||||
.tap = { 17, 17 },
|
||||
.psize = 34,
|
||||
.np = 2,
|
||||
.ksize = 16,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* DES test vectors.
|
||||
*/
|
||||
@ -1831,6 +1899,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
|
||||
#define AES_DEC_TEST_VECTORS 3
|
||||
#define AES_CBC_ENC_TEST_VECTORS 2
|
||||
#define AES_CBC_DEC_TEST_VECTORS 2
|
||||
#define AES_LRW_ENC_TEST_VECTORS 8
|
||||
#define AES_LRW_DEC_TEST_VECTORS 8
|
||||
|
||||
static struct cipher_testvec aes_enc_tv_template[] = {
|
||||
{ /* From FIPS-197 */
|
||||
@ -1968,6 +2038,509 @@ static struct cipher_testvec aes_cbc_dec_tv_template[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct cipher_testvec aes_lrw_enc_tv_template[] = {
|
||||
/* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
|
||||
{ /* LRW-32-AES 1 */
|
||||
.key = { 0x45, 0x62, 0xac, 0x25, 0xf8, 0x28, 0x17, 0x6d,
|
||||
0x4c, 0x26, 0x84, 0x14, 0xb5, 0x68, 0x01, 0x85,
|
||||
0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03,
|
||||
0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 },
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0xf1, 0xb2, 0x73, 0xcd, 0x65, 0xa3, 0xdf, 0x5f,
|
||||
0xe9, 0x5d, 0x48, 0x92, 0x54, 0x63, 0x4e, 0xb8 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 2 */
|
||||
.key = { 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c,
|
||||
0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44,
|
||||
0x0d, 0x48, 0xf0, 0xb7, 0xb1, 0x5a, 0x53, 0xea,
|
||||
0x1c, 0xaa, 0x6b, 0x29, 0xc2, 0xca, 0xfb, 0xaf
|
||||
},
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5,
|
||||
0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 3 */
|
||||
.key = { 0xd8, 0x2a, 0x91, 0x34, 0xb2, 0x6a, 0x56, 0x50,
|
||||
0x30, 0xfe, 0x69, 0xe2, 0x37, 0x7f, 0x98, 0x47,
|
||||
0xcd, 0xf9, 0x0b, 0x16, 0x0c, 0x64, 0x8f, 0xb6,
|
||||
0xb0, 0x0d, 0x0d, 0x1b, 0xae, 0x85, 0x87, 0x1f },
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0x76, 0x32, 0x21, 0x83, 0xed, 0x8f, 0xf1, 0x82,
|
||||
0xf9, 0x59, 0x62, 0x03, 0x69, 0x0e, 0x5e, 0x01 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 4 */
|
||||
.key = { 0x0f, 0x6a, 0xef, 0xf8, 0xd3, 0xd2, 0xbb, 0x15,
|
||||
0x25, 0x83, 0xf7, 0x3c, 0x1f, 0x01, 0x28, 0x74,
|
||||
0xca, 0xc6, 0xbc, 0x35, 0x4d, 0x4a, 0x65, 0x54,
|
||||
0x90, 0xae, 0x61, 0xcf, 0x7b, 0xae, 0xbd, 0xcc,
|
||||
0xad, 0xe4, 0x94, 0xc5, 0x4a, 0x29, 0xae, 0x70 },
|
||||
.klen = 40,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0x9c, 0x0f, 0x15, 0x2f, 0x55, 0xa2, 0xd8, 0xf0,
|
||||
0xd6, 0x7b, 0x8f, 0x9e, 0x28, 0x22, 0xbc, 0x41 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 5 */
|
||||
.key = { 0x8a, 0xd4, 0xee, 0x10, 0x2f, 0xbd, 0x81, 0xff,
|
||||
0xf8, 0x86, 0xce, 0xac, 0x93, 0xc5, 0xad, 0xc6,
|
||||
0xa0, 0x19, 0x07, 0xc0, 0x9d, 0xf7, 0xbb, 0xdd,
|
||||
0x52, 0x13, 0xb2, 0xb7, 0xf0, 0xff, 0x11, 0xd8,
|
||||
0xd6, 0x08, 0xd0, 0xcd, 0x2e, 0xb1, 0x17, 0x6f },
|
||||
.klen = 40,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0xd4, 0x27, 0x6a, 0x7f, 0x14, 0x91, 0x3d, 0x65,
|
||||
0xc8, 0x60, 0x48, 0x02, 0x87, 0xe3, 0x34, 0x06 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 6 */
|
||||
.key = { 0xf8, 0xd4, 0x76, 0xff, 0xd6, 0x46, 0xee, 0x6c,
|
||||
0x23, 0x84, 0xcb, 0x1c, 0x77, 0xd6, 0x19, 0x5d,
|
||||
0xfe, 0xf1, 0xa9, 0xf3, 0x7b, 0xbc, 0x8d, 0x21,
|
||||
0xa7, 0x9c, 0x21, 0xf8, 0xcb, 0x90, 0x02, 0x89,
|
||||
0xa8, 0x45, 0x34, 0x8e, 0xc8, 0xc5, 0xb5, 0xf1,
|
||||
0x26, 0xf5, 0x0e, 0x76, 0xfe, 0xfd, 0x1b, 0x1e },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0xbd, 0x06, 0xb8, 0xe1, 0xdb, 0x98, 0x89, 0x9e,
|
||||
0xc4, 0x98, 0xe4, 0x91, 0xcf, 0x1c, 0x70, 0x2b },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 7 */
|
||||
.key = { 0xfb, 0x76, 0x15, 0xb2, 0x3d, 0x80, 0x89, 0x1d,
|
||||
0xd4, 0x70, 0x98, 0x0b, 0xc7, 0x95, 0x84, 0xc8,
|
||||
0xb2, 0xfb, 0x64, 0xce, 0x60, 0x97, 0x87, 0x8d,
|
||||
0x17, 0xfc, 0xe4, 0x5a, 0x49, 0xe8, 0x30, 0xb7,
|
||||
0x6e, 0x78, 0x17, 0xe7, 0x2d, 0x5e, 0x12, 0xd4,
|
||||
0x60, 0x64, 0x04, 0x7a, 0xf1, 0x2f, 0x9e, 0x0c },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.ilen = 16,
|
||||
.result = { 0x5b, 0x90, 0x8e, 0xc1, 0xab, 0xdd, 0x67, 0x5f,
|
||||
0x3d, 0x69, 0x8a, 0x95, 0x53, 0xc8, 0x9c, 0xe5 },
|
||||
.rlen = 16,
|
||||
}, {
|
||||
/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
|
||||
.key = { 0xf8, 0xd4, 0x76, 0xff, 0xd6, 0x46, 0xee, 0x6c,
|
||||
0x23, 0x84, 0xcb, 0x1c, 0x77, 0xd6, 0x19, 0x5d,
|
||||
0xfe, 0xf1, 0xa9, 0xf3, 0x7b, 0xbc, 0x8d, 0x21,
|
||||
0xa7, 0x9c, 0x21, 0xf8, 0xcb, 0x90, 0x02, 0x89,
|
||||
0xa8, 0x45, 0x34, 0x8e, 0xc8, 0xc5, 0xb5, 0xf1,
|
||||
0x26, 0xf5, 0x0e, 0x76, 0xfe, 0xfd, 0x1b, 0x1e },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x05, 0x11, 0xb7, 0x18, 0xab, 0xc6, 0x2d, 0xac,
|
||||
0x70, 0x5d, 0xf6, 0x22, 0x94, 0xcd, 0xe5, 0x6c,
|
||||
0x17, 0x6b, 0xf6, 0x1c, 0xf0, 0xf3, 0x6e, 0xf8,
|
||||
0x50, 0x38, 0x1f, 0x71, 0x49, 0xb6, 0x57, 0xd6,
|
||||
0x8f, 0xcb, 0x8d, 0x6b, 0xe3, 0xa6, 0x29, 0x90,
|
||||
0xfe, 0x2a, 0x62, 0x82, 0xae, 0x6d, 0x8b, 0xf6,
|
||||
0xad, 0x1e, 0x9e, 0x20, 0x5f, 0x38, 0xbe, 0x04,
|
||||
0xda, 0x10, 0x8e, 0xed, 0xa2, 0xa4, 0x87, 0xab,
|
||||
0xda, 0x6b, 0xb4, 0x0c, 0x75, 0xba, 0xd3, 0x7c,
|
||||
0xc9, 0xac, 0x42, 0x31, 0x95, 0x7c, 0xc9, 0x04,
|
||||
0xeb, 0xd5, 0x6e, 0x32, 0x69, 0x8a, 0xdb, 0xa6,
|
||||
0x15, 0xd7, 0x3f, 0x4f, 0x2f, 0x66, 0x69, 0x03,
|
||||
0x9c, 0x1f, 0x54, 0x0f, 0xde, 0x1f, 0xf3, 0x65,
|
||||
0x4c, 0x96, 0x12, 0xed, 0x7c, 0x92, 0x03, 0x01,
|
||||
0x6f, 0xbc, 0x35, 0x93, 0xac, 0xf1, 0x27, 0xf1,
|
||||
0xb4, 0x96, 0x82, 0x5a, 0x5f, 0xb0, 0xa0, 0x50,
|
||||
0x89, 0xa4, 0x8e, 0x66, 0x44, 0x85, 0xcc, 0xfd,
|
||||
0x33, 0x14, 0x70, 0xe3, 0x96, 0xb2, 0xc3, 0xd3,
|
||||
0xbb, 0x54, 0x5a, 0x1a, 0xf9, 0x74, 0xa2, 0xc5,
|
||||
0x2d, 0x64, 0x75, 0xdd, 0xb4, 0x54, 0xe6, 0x74,
|
||||
0x8c, 0xd3, 0x9d, 0x9e, 0x86, 0xab, 0x51, 0x53,
|
||||
0xb7, 0x93, 0x3e, 0x6f, 0xd0, 0x4e, 0x2c, 0x40,
|
||||
0xf6, 0xa8, 0x2e, 0x3e, 0x9d, 0xf4, 0x66, 0xa5,
|
||||
0x76, 0x12, 0x73, 0x44, 0x1a, 0x56, 0xd7, 0x72,
|
||||
0x88, 0xcd, 0x21, 0x8c, 0x4c, 0x0f, 0xfe, 0xda,
|
||||
0x95, 0xe0, 0x3a, 0xa6, 0xa5, 0x84, 0x46, 0xcd,
|
||||
0xd5, 0x3e, 0x9d, 0x3a, 0xe2, 0x67, 0xe6, 0x60,
|
||||
0x1a, 0xe2, 0x70, 0x85, 0x58, 0xc2, 0x1b, 0x09,
|
||||
0xe1, 0xd7, 0x2c, 0xca, 0xad, 0xa8, 0x8f, 0xf9,
|
||||
0xac, 0xb3, 0x0e, 0xdb, 0xca, 0x2e, 0xe2, 0xb8,
|
||||
0x51, 0x71, 0xd9, 0x3c, 0x6c, 0xf1, 0x56, 0xf8,
|
||||
0xea, 0x9c, 0xf1, 0xfb, 0x0c, 0xe6, 0xb7, 0x10,
|
||||
0x1c, 0xf8, 0xa9, 0x7c, 0xe8, 0x53, 0x35, 0xc1,
|
||||
0x90, 0x3e, 0x76, 0x4a, 0x74, 0xa4, 0x21, 0x2c,
|
||||
0xf6, 0x2c, 0x4e, 0x0f, 0x94, 0x3a, 0x88, 0x2e,
|
||||
0x41, 0x09, 0x6a, 0x33, 0x7d, 0xf6, 0xdd, 0x3f,
|
||||
0x8d, 0x23, 0x31, 0x74, 0x84, 0xeb, 0x88, 0x6e,
|
||||
0xcc, 0xb9, 0xbc, 0x22, 0x83, 0x19, 0x07, 0x22,
|
||||
0xa5, 0x2d, 0xdf, 0xa5, 0xf3, 0x80, 0x85, 0x78,
|
||||
0x84, 0x39, 0x6a, 0x6d, 0x6a, 0x99, 0x4f, 0xa5,
|
||||
0x15, 0xfe, 0x46, 0xb0, 0xe4, 0x6c, 0xa5, 0x41,
|
||||
0x3c, 0xce, 0x8f, 0x42, 0x60, 0x71, 0xa7, 0x75,
|
||||
0x08, 0x40, 0x65, 0x8a, 0x82, 0xbf, 0xf5, 0x43,
|
||||
0x71, 0x96, 0xa9, 0x4d, 0x44, 0x8a, 0x20, 0xbe,
|
||||
0xfa, 0x4d, 0xbb, 0xc0, 0x7d, 0x31, 0x96, 0x65,
|
||||
0xe7, 0x75, 0xe5, 0x3e, 0xfd, 0x92, 0x3b, 0xc9,
|
||||
0x55, 0xbb, 0x16, 0x7e, 0xf7, 0xc2, 0x8c, 0xa4,
|
||||
0x40, 0x1d, 0xe5, 0xef, 0x0e, 0xdf, 0xe4, 0x9a,
|
||||
0x62, 0x73, 0x65, 0xfd, 0x46, 0x63, 0x25, 0x3d,
|
||||
0x2b, 0xaf, 0xe5, 0x64, 0xfe, 0xa5, 0x5c, 0xcf,
|
||||
0x24, 0xf3, 0xb4, 0xac, 0x64, 0xba, 0xdf, 0x4b,
|
||||
0xc6, 0x96, 0x7d, 0x81, 0x2d, 0x8d, 0x97, 0xf7,
|
||||
0xc5, 0x68, 0x77, 0x84, 0x32, 0x2b, 0xcc, 0x85,
|
||||
0x74, 0x96, 0xf0, 0x12, 0x77, 0x61, 0xb9, 0xeb,
|
||||
0x71, 0xaa, 0x82, 0xcb, 0x1c, 0xdb, 0x89, 0xc8,
|
||||
0xc6, 0xb5, 0xe3, 0x5c, 0x7d, 0x39, 0x07, 0x24,
|
||||
0xda, 0x39, 0x87, 0x45, 0xc0, 0x2b, 0xbb, 0x01,
|
||||
0xac, 0xbc, 0x2a, 0x5c, 0x7f, 0xfc, 0xe8, 0xce,
|
||||
0x6d, 0x9c, 0x6f, 0xed, 0xd3, 0xc1, 0xa1, 0xd6,
|
||||
0xc5, 0x55, 0xa9, 0x66, 0x2f, 0xe1, 0xc8, 0x32,
|
||||
0xa6, 0x5d, 0xa4, 0x3a, 0x98, 0x73, 0xe8, 0x45,
|
||||
0xa4, 0xc7, 0xa8, 0xb4, 0xf6, 0x13, 0x03, 0xf6,
|
||||
0xe9, 0x2e, 0xc4, 0x29, 0x0f, 0x84, 0xdb, 0xc4,
|
||||
0x21, 0xc4, 0xc2, 0x75, 0x67, 0x89, 0x37, 0x0a },
|
||||
.ilen = 512,
|
||||
.result = { 0x1a, 0x1d, 0xa9, 0x30, 0xad, 0xf9, 0x2f, 0x9b,
|
||||
0xb6, 0x1d, 0xae, 0xef, 0xf0, 0x2f, 0xf8, 0x5a,
|
||||
0x39, 0x3c, 0xbf, 0x2a, 0xb2, 0x45, 0xb2, 0x23,
|
||||
0x1b, 0x63, 0x3c, 0xcf, 0xaa, 0xbe, 0xcf, 0x4e,
|
||||
0xfa, 0xe8, 0x29, 0xc2, 0x20, 0x68, 0x2b, 0x3c,
|
||||
0x2e, 0x8b, 0xf7, 0x6e, 0x25, 0xbd, 0xe3, 0x3d,
|
||||
0x66, 0x27, 0xd6, 0xaf, 0xd6, 0x64, 0x3e, 0xe3,
|
||||
0xe8, 0x58, 0x46, 0x97, 0x39, 0x51, 0x07, 0xde,
|
||||
0xcb, 0x37, 0xbc, 0xa9, 0xc0, 0x5f, 0x75, 0xc3,
|
||||
0x0e, 0x84, 0x23, 0x1d, 0x16, 0xd4, 0x1c, 0x59,
|
||||
0x9c, 0x1a, 0x02, 0x55, 0xab, 0x3a, 0x97, 0x1d,
|
||||
0xdf, 0xdd, 0xc7, 0x06, 0x51, 0xd7, 0x70, 0xae,
|
||||
0x23, 0xc6, 0x8c, 0xf5, 0x1e, 0xa0, 0xe5, 0x82,
|
||||
0xb8, 0xb2, 0xbf, 0x04, 0xa0, 0x32, 0x8e, 0x68,
|
||||
0xeb, 0xaf, 0x6e, 0x2d, 0x94, 0x22, 0x2f, 0xce,
|
||||
0x4c, 0xb5, 0x59, 0xe2, 0xa2, 0x2f, 0xa0, 0x98,
|
||||
0x1a, 0x97, 0xc6, 0xd4, 0xb5, 0x00, 0x59, 0xf2,
|
||||
0x84, 0x14, 0x72, 0xb1, 0x9a, 0x6e, 0xa3, 0x7f,
|
||||
0xea, 0x20, 0xe7, 0xcb, 0x65, 0x77, 0x3a, 0xdf,
|
||||
0xc8, 0x97, 0x67, 0x15, 0xc2, 0x2a, 0x27, 0xcc,
|
||||
0x18, 0x55, 0xa1, 0x24, 0x0b, 0x24, 0x24, 0xaf,
|
||||
0x5b, 0xec, 0x68, 0xb8, 0xc8, 0xf5, 0xba, 0x63,
|
||||
0xff, 0xed, 0x89, 0xce, 0xd5, 0x3d, 0x88, 0xf3,
|
||||
0x25, 0xef, 0x05, 0x7c, 0x3a, 0xef, 0xeb, 0xd8,
|
||||
0x7a, 0x32, 0x0d, 0xd1, 0x1e, 0x58, 0x59, 0x99,
|
||||
0x90, 0x25, 0xb5, 0x26, 0xb0, 0xe3, 0x2b, 0x6c,
|
||||
0x4c, 0xa9, 0x8b, 0x84, 0x4f, 0x5e, 0x01, 0x50,
|
||||
0x41, 0x30, 0x58, 0xc5, 0x62, 0x74, 0x52, 0x1d,
|
||||
0x45, 0x24, 0x6a, 0x42, 0x64, 0x4f, 0x97, 0x1c,
|
||||
0xa8, 0x66, 0xb5, 0x6d, 0x79, 0xd4, 0x0d, 0x48,
|
||||
0xc5, 0x5f, 0xf3, 0x90, 0x32, 0xdd, 0xdd, 0xe1,
|
||||
0xe4, 0xa9, 0x9f, 0xfc, 0xc3, 0x52, 0x5a, 0x46,
|
||||
0xe4, 0x81, 0x84, 0x95, 0x36, 0x59, 0x7a, 0x6b,
|
||||
0xaa, 0xb3, 0x60, 0xad, 0xce, 0x9f, 0x9f, 0x28,
|
||||
0xe0, 0x01, 0x75, 0x22, 0xc4, 0x4e, 0xa9, 0x62,
|
||||
0x5c, 0x62, 0x0d, 0x00, 0xcb, 0x13, 0xe8, 0x43,
|
||||
0x72, 0xd4, 0x2d, 0x53, 0x46, 0xb5, 0xd1, 0x16,
|
||||
0x22, 0x18, 0xdf, 0x34, 0x33, 0xf5, 0xd6, 0x1c,
|
||||
0xb8, 0x79, 0x78, 0x97, 0x94, 0xff, 0x72, 0x13,
|
||||
0x4c, 0x27, 0xfc, 0xcb, 0xbf, 0x01, 0x53, 0xa6,
|
||||
0xb4, 0x50, 0x6e, 0xde, 0xdf, 0xb5, 0x43, 0xa4,
|
||||
0x59, 0xdf, 0x52, 0xf9, 0x7c, 0xe0, 0x11, 0x6f,
|
||||
0x2d, 0x14, 0x8e, 0x24, 0x61, 0x2c, 0xe1, 0x17,
|
||||
0xcc, 0xce, 0x51, 0x0c, 0x19, 0x8a, 0x82, 0x30,
|
||||
0x94, 0xd5, 0x3d, 0x6a, 0x53, 0x06, 0x5e, 0xbd,
|
||||
0xb7, 0xeb, 0xfa, 0xfd, 0x27, 0x51, 0xde, 0x85,
|
||||
0x1e, 0x86, 0x53, 0x11, 0x53, 0x94, 0x00, 0xee,
|
||||
0x2b, 0x8c, 0x08, 0x2a, 0xbf, 0xdd, 0xae, 0x11,
|
||||
0xcb, 0x1e, 0xa2, 0x07, 0x9a, 0x80, 0xcf, 0x62,
|
||||
0x9b, 0x09, 0xdc, 0x95, 0x3c, 0x96, 0x8e, 0xb1,
|
||||
0x09, 0xbd, 0xe4, 0xeb, 0xdb, 0xca, 0x70, 0x7a,
|
||||
0x9e, 0xfa, 0x31, 0x18, 0x45, 0x3c, 0x21, 0x33,
|
||||
0xb0, 0xb3, 0x2b, 0xea, 0xf3, 0x71, 0x2d, 0xe1,
|
||||
0x03, 0xad, 0x1b, 0x48, 0xd4, 0x67, 0x27, 0xf0,
|
||||
0x62, 0xe4, 0x3d, 0xfb, 0x9b, 0x08, 0x76, 0xe7,
|
||||
0xdd, 0x2b, 0x01, 0x39, 0x04, 0x5a, 0x58, 0x7a,
|
||||
0xf7, 0x11, 0x90, 0xec, 0xbd, 0x51, 0x5c, 0x32,
|
||||
0x6b, 0xd7, 0x35, 0x39, 0x02, 0x6b, 0xf2, 0xa6,
|
||||
0xd0, 0x0d, 0x07, 0xe1, 0x06, 0xc4, 0x5b, 0x7d,
|
||||
0xe4, 0x6a, 0xd7, 0xee, 0x15, 0x1f, 0x83, 0xb4,
|
||||
0xa3, 0xa7, 0x5e, 0xc3, 0x90, 0xb7, 0xef, 0xd3,
|
||||
0xb7, 0x4f, 0xf8, 0x92, 0x4c, 0xb7, 0x3c, 0x29,
|
||||
0xcd, 0x7e, 0x2b, 0x5d, 0x43, 0xea, 0x42, 0xe7,
|
||||
0x74, 0x3f, 0x7d, 0x58, 0x88, 0x75, 0xde, 0x3e },
|
||||
.rlen = 512,
|
||||
}
|
||||
};
|
||||
|
||||
static struct cipher_testvec aes_lrw_dec_tv_template[] = {
|
||||
/* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
|
||||
/* same as enc vectors with input and result reversed */
|
||||
{ /* LRW-32-AES 1 */
|
||||
.key = { 0x45, 0x62, 0xac, 0x25, 0xf8, 0x28, 0x17, 0x6d,
|
||||
0x4c, 0x26, 0x84, 0x14, 0xb5, 0x68, 0x01, 0x85,
|
||||
0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03,
|
||||
0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 },
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0xf1, 0xb2, 0x73, 0xcd, 0x65, 0xa3, 0xdf, 0x5f,
|
||||
0xe9, 0x5d, 0x48, 0x92, 0x54, 0x63, 0x4e, 0xb8 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 2 */
|
||||
.key = { 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c,
|
||||
0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44,
|
||||
0x0d, 0x48, 0xf0, 0xb7, 0xb1, 0x5a, 0x53, 0xea,
|
||||
0x1c, 0xaa, 0x6b, 0x29, 0xc2, 0xca, 0xfb, 0xaf
|
||||
},
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
|
||||
.input = { 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5,
|
||||
0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 3 */
|
||||
.key = { 0xd8, 0x2a, 0x91, 0x34, 0xb2, 0x6a, 0x56, 0x50,
|
||||
0x30, 0xfe, 0x69, 0xe2, 0x37, 0x7f, 0x98, 0x47,
|
||||
0xcd, 0xf9, 0x0b, 0x16, 0x0c, 0x64, 0x8f, 0xb6,
|
||||
0xb0, 0x0d, 0x0d, 0x1b, 0xae, 0x85, 0x87, 0x1f },
|
||||
.klen = 32,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0x76, 0x32, 0x21, 0x83, 0xed, 0x8f, 0xf1, 0x82,
|
||||
0xf9, 0x59, 0x62, 0x03, 0x69, 0x0e, 0x5e, 0x01 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 4 */
|
||||
.key = { 0x0f, 0x6a, 0xef, 0xf8, 0xd3, 0xd2, 0xbb, 0x15,
|
||||
0x25, 0x83, 0xf7, 0x3c, 0x1f, 0x01, 0x28, 0x74,
|
||||
0xca, 0xc6, 0xbc, 0x35, 0x4d, 0x4a, 0x65, 0x54,
|
||||
0x90, 0xae, 0x61, 0xcf, 0x7b, 0xae, 0xbd, 0xcc,
|
||||
0xad, 0xe4, 0x94, 0xc5, 0x4a, 0x29, 0xae, 0x70 },
|
||||
.klen = 40,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x9c, 0x0f, 0x15, 0x2f, 0x55, 0xa2, 0xd8, 0xf0,
|
||||
0xd6, 0x7b, 0x8f, 0x9e, 0x28, 0x22, 0xbc, 0x41 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 5 */
|
||||
.key = { 0x8a, 0xd4, 0xee, 0x10, 0x2f, 0xbd, 0x81, 0xff,
|
||||
0xf8, 0x86, 0xce, 0xac, 0x93, 0xc5, 0xad, 0xc6,
|
||||
0xa0, 0x19, 0x07, 0xc0, 0x9d, 0xf7, 0xbb, 0xdd,
|
||||
0x52, 0x13, 0xb2, 0xb7, 0xf0, 0xff, 0x11, 0xd8,
|
||||
0xd6, 0x08, 0xd0, 0xcd, 0x2e, 0xb1, 0x17, 0x6f },
|
||||
.klen = 40,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0xd4, 0x27, 0x6a, 0x7f, 0x14, 0x91, 0x3d, 0x65,
|
||||
0xc8, 0x60, 0x48, 0x02, 0x87, 0xe3, 0x34, 0x06 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 6 */
|
||||
.key = { 0xf8, 0xd4, 0x76, 0xff, 0xd6, 0x46, 0xee, 0x6c,
|
||||
0x23, 0x84, 0xcb, 0x1c, 0x77, 0xd6, 0x19, 0x5d,
|
||||
0xfe, 0xf1, 0xa9, 0xf3, 0x7b, 0xbc, 0x8d, 0x21,
|
||||
0xa7, 0x9c, 0x21, 0xf8, 0xcb, 0x90, 0x02, 0x89,
|
||||
0xa8, 0x45, 0x34, 0x8e, 0xc8, 0xc5, 0xb5, 0xf1,
|
||||
0x26, 0xf5, 0x0e, 0x76, 0xfe, 0xfd, 0x1b, 0x1e },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0xbd, 0x06, 0xb8, 0xe1, 0xdb, 0x98, 0x89, 0x9e,
|
||||
0xc4, 0x98, 0xe4, 0x91, 0xcf, 0x1c, 0x70, 0x2b },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, { /* LRW-32-AES 7 */
|
||||
.key = { 0xfb, 0x76, 0x15, 0xb2, 0x3d, 0x80, 0x89, 0x1d,
|
||||
0xd4, 0x70, 0x98, 0x0b, 0xc7, 0x95, 0x84, 0xc8,
|
||||
0xb2, 0xfb, 0x64, 0xce, 0x60, 0x97, 0x87, 0x8d,
|
||||
0x17, 0xfc, 0xe4, 0x5a, 0x49, 0xe8, 0x30, 0xb7,
|
||||
0x6e, 0x78, 0x17, 0xe7, 0x2d, 0x5e, 0x12, 0xd4,
|
||||
0x60, 0x64, 0x04, 0x7a, 0xf1, 0x2f, 0x9e, 0x0c },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
|
||||
.input = { 0x5b, 0x90, 0x8e, 0xc1, 0xab, 0xdd, 0x67, 0x5f,
|
||||
0x3d, 0x69, 0x8a, 0x95, 0x53, 0xc8, 0x9c, 0xe5 },
|
||||
.ilen = 16,
|
||||
.result = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 },
|
||||
.rlen = 16,
|
||||
}, {
|
||||
/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
|
||||
.key = { 0xf8, 0xd4, 0x76, 0xff, 0xd6, 0x46, 0xee, 0x6c,
|
||||
0x23, 0x84, 0xcb, 0x1c, 0x77, 0xd6, 0x19, 0x5d,
|
||||
0xfe, 0xf1, 0xa9, 0xf3, 0x7b, 0xbc, 0x8d, 0x21,
|
||||
0xa7, 0x9c, 0x21, 0xf8, 0xcb, 0x90, 0x02, 0x89,
|
||||
0xa8, 0x45, 0x34, 0x8e, 0xc8, 0xc5, 0xb5, 0xf1,
|
||||
0x26, 0xf5, 0x0e, 0x76, 0xfe, 0xfd, 0x1b, 0x1e },
|
||||
.klen = 48,
|
||||
.iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
.input = { 0x1a, 0x1d, 0xa9, 0x30, 0xad, 0xf9, 0x2f, 0x9b,
|
||||
0xb6, 0x1d, 0xae, 0xef, 0xf0, 0x2f, 0xf8, 0x5a,
|
||||
0x39, 0x3c, 0xbf, 0x2a, 0xb2, 0x45, 0xb2, 0x23,
|
||||
0x1b, 0x63, 0x3c, 0xcf, 0xaa, 0xbe, 0xcf, 0x4e,
|
||||
0xfa, 0xe8, 0x29, 0xc2, 0x20, 0x68, 0x2b, 0x3c,
|
||||
0x2e, 0x8b, 0xf7, 0x6e, 0x25, 0xbd, 0xe3, 0x3d,
|
||||
0x66, 0x27, 0xd6, 0xaf, 0xd6, 0x64, 0x3e, 0xe3,
|
||||
0xe8, 0x58, 0x46, 0x97, 0x39, 0x51, 0x07, 0xde,
|
||||
0xcb, 0x37, 0xbc, 0xa9, 0xc0, 0x5f, 0x75, 0xc3,
|
||||
0x0e, 0x84, 0x23, 0x1d, 0x16, 0xd4, 0x1c, 0x59,
|
||||
0x9c, 0x1a, 0x02, 0x55, 0xab, 0x3a, 0x97, 0x1d,
|
||||
0xdf, 0xdd, 0xc7, 0x06, 0x51, 0xd7, 0x70, 0xae,
|
||||
0x23, 0xc6, 0x8c, 0xf5, 0x1e, 0xa0, 0xe5, 0x82,
|
||||
0xb8, 0xb2, 0xbf, 0x04, 0xa0, 0x32, 0x8e, 0x68,
|
||||
0xeb, 0xaf, 0x6e, 0x2d, 0x94, 0x22, 0x2f, 0xce,
|
||||
0x4c, 0xb5, 0x59, 0xe2, 0xa2, 0x2f, 0xa0, 0x98,
|
||||
0x1a, 0x97, 0xc6, 0xd4, 0xb5, 0x00, 0x59, 0xf2,
|
||||
0x84, 0x14, 0x72, 0xb1, 0x9a, 0x6e, 0xa3, 0x7f,
|
||||
0xea, 0x20, 0xe7, 0xcb, 0x65, 0x77, 0x3a, 0xdf,
|
||||
0xc8, 0x97, 0x67, 0x15, 0xc2, 0x2a, 0x27, 0xcc,
|
||||
0x18, 0x55, 0xa1, 0x24, 0x0b, 0x24, 0x24, 0xaf,
|
||||
0x5b, 0xec, 0x68, 0xb8, 0xc8, 0xf5, 0xba, 0x63,
|
||||
0xff, 0xed, 0x89, 0xce, 0xd5, 0x3d, 0x88, 0xf3,
|
||||
0x25, 0xef, 0x05, 0x7c, 0x3a, 0xef, 0xeb, 0xd8,
|
||||
0x7a, 0x32, 0x0d, 0xd1, 0x1e, 0x58, 0x59, 0x99,
|
||||
0x90, 0x25, 0xb5, 0x26, 0xb0, 0xe3, 0x2b, 0x6c,
|
||||
0x4c, 0xa9, 0x8b, 0x84, 0x4f, 0x5e, 0x01, 0x50,
|
||||
0x41, 0x30, 0x58, 0xc5, 0x62, 0x74, 0x52, 0x1d,
|
||||
0x45, 0x24, 0x6a, 0x42, 0x64, 0x4f, 0x97, 0x1c,
|
||||
0xa8, 0x66, 0xb5, 0x6d, 0x79, 0xd4, 0x0d, 0x48,
|
||||
0xc5, 0x5f, 0xf3, 0x90, 0x32, 0xdd, 0xdd, 0xe1,
|
||||
0xe4, 0xa9, 0x9f, 0xfc, 0xc3, 0x52, 0x5a, 0x46,
|
||||
0xe4, 0x81, 0x84, 0x95, 0x36, 0x59, 0x7a, 0x6b,
|
||||
0xaa, 0xb3, 0x60, 0xad, 0xce, 0x9f, 0x9f, 0x28,
|
||||
0xe0, 0x01, 0x75, 0x22, 0xc4, 0x4e, 0xa9, 0x62,
|
||||
0x5c, 0x62, 0x0d, 0x00, 0xcb, 0x13, 0xe8, 0x43,
|
||||
0x72, 0xd4, 0x2d, 0x53, 0x46, 0xb5, 0xd1, 0x16,
|
||||
0x22, 0x18, 0xdf, 0x34, 0x33, 0xf5, 0xd6, 0x1c,
|
||||
0xb8, 0x79, 0x78, 0x97, 0x94, 0xff, 0x72, 0x13,
|
||||
0x4c, 0x27, 0xfc, 0xcb, 0xbf, 0x01, 0x53, 0xa6,
|
||||
0xb4, 0x50, 0x6e, 0xde, 0xdf, 0xb5, 0x43, 0xa4,
|
||||
0x59, 0xdf, 0x52, 0xf9, 0x7c, 0xe0, 0x11, 0x6f,
|
||||
0x2d, 0x14, 0x8e, 0x24, 0x61, 0x2c, 0xe1, 0x17,
|
||||
0xcc, 0xce, 0x51, 0x0c, 0x19, 0x8a, 0x82, 0x30,
|
||||
0x94, 0xd5, 0x3d, 0x6a, 0x53, 0x06, 0x5e, 0xbd,
|
||||
0xb7, 0xeb, 0xfa, 0xfd, 0x27, 0x51, 0xde, 0x85,
|
||||
0x1e, 0x86, 0x53, 0x11, 0x53, 0x94, 0x00, 0xee,
|
||||
0x2b, 0x8c, 0x08, 0x2a, 0xbf, 0xdd, 0xae, 0x11,
|
||||
0xcb, 0x1e, 0xa2, 0x07, 0x9a, 0x80, 0xcf, 0x62,
|
||||
0x9b, 0x09, 0xdc, 0x95, 0x3c, 0x96, 0x8e, 0xb1,
|
||||
0x09, 0xbd, 0xe4, 0xeb, 0xdb, 0xca, 0x70, 0x7a,
|
||||
0x9e, 0xfa, 0x31, 0x18, 0x45, 0x3c, 0x21, 0x33,
|
||||
0xb0, 0xb3, 0x2b, 0xea, 0xf3, 0x71, 0x2d, 0xe1,
|
||||
0x03, 0xad, 0x1b, 0x48, 0xd4, 0x67, 0x27, 0xf0,
|
||||
0x62, 0xe4, 0x3d, 0xfb, 0x9b, 0x08, 0x76, 0xe7,
|
||||
0xdd, 0x2b, 0x01, 0x39, 0x04, 0x5a, 0x58, 0x7a,
|
||||
0xf7, 0x11, 0x90, 0xec, 0xbd, 0x51, 0x5c, 0x32,
|
||||
0x6b, 0xd7, 0x35, 0x39, 0x02, 0x6b, 0xf2, 0xa6,
|
||||
0xd0, 0x0d, 0x07, 0xe1, 0x06, 0xc4, 0x5b, 0x7d,
|
||||
0xe4, 0x6a, 0xd7, 0xee, 0x15, 0x1f, 0x83, 0xb4,
|
||||
0xa3, 0xa7, 0x5e, 0xc3, 0x90, 0xb7, 0xef, 0xd3,
|
||||
0xb7, 0x4f, 0xf8, 0x92, 0x4c, 0xb7, 0x3c, 0x29,
|
||||
0xcd, 0x7e, 0x2b, 0x5d, 0x43, 0xea, 0x42, 0xe7,
|
||||
0x74, 0x3f, 0x7d, 0x58, 0x88, 0x75, 0xde, 0x3e },
|
||||
.ilen = 512,
|
||||
.result = { 0x05, 0x11, 0xb7, 0x18, 0xab, 0xc6, 0x2d, 0xac,
|
||||
0x70, 0x5d, 0xf6, 0x22, 0x94, 0xcd, 0xe5, 0x6c,
|
||||
0x17, 0x6b, 0xf6, 0x1c, 0xf0, 0xf3, 0x6e, 0xf8,
|
||||
0x50, 0x38, 0x1f, 0x71, 0x49, 0xb6, 0x57, 0xd6,
|
||||
0x8f, 0xcb, 0x8d, 0x6b, 0xe3, 0xa6, 0x29, 0x90,
|
||||
0xfe, 0x2a, 0x62, 0x82, 0xae, 0x6d, 0x8b, 0xf6,
|
||||
0xad, 0x1e, 0x9e, 0x20, 0x5f, 0x38, 0xbe, 0x04,
|
||||
0xda, 0x10, 0x8e, 0xed, 0xa2, 0xa4, 0x87, 0xab,
|
||||
0xda, 0x6b, 0xb4, 0x0c, 0x75, 0xba, 0xd3, 0x7c,
|
||||
0xc9, 0xac, 0x42, 0x31, 0x95, 0x7c, 0xc9, 0x04,
|
||||
0xeb, 0xd5, 0x6e, 0x32, 0x69, 0x8a, 0xdb, 0xa6,
|
||||
0x15, 0xd7, 0x3f, 0x4f, 0x2f, 0x66, 0x69, 0x03,
|
||||
0x9c, 0x1f, 0x54, 0x0f, 0xde, 0x1f, 0xf3, 0x65,
|
||||
0x4c, 0x96, 0x12, 0xed, 0x7c, 0x92, 0x03, 0x01,
|
||||
0x6f, 0xbc, 0x35, 0x93, 0xac, 0xf1, 0x27, 0xf1,
|
||||
0xb4, 0x96, 0x82, 0x5a, 0x5f, 0xb0, 0xa0, 0x50,
|
||||
0x89, 0xa4, 0x8e, 0x66, 0x44, 0x85, 0xcc, 0xfd,
|
||||
0x33, 0x14, 0x70, 0xe3, 0x96, 0xb2, 0xc3, 0xd3,
|
||||
0xbb, 0x54, 0x5a, 0x1a, 0xf9, 0x74, 0xa2, 0xc5,
|
||||
0x2d, 0x64, 0x75, 0xdd, 0xb4, 0x54, 0xe6, 0x74,
|
||||
0x8c, 0xd3, 0x9d, 0x9e, 0x86, 0xab, 0x51, 0x53,
|
||||
0xb7, 0x93, 0x3e, 0x6f, 0xd0, 0x4e, 0x2c, 0x40,
|
||||
0xf6, 0xa8, 0x2e, 0x3e, 0x9d, 0xf4, 0x66, 0xa5,
|
||||
0x76, 0x12, 0x73, 0x44, 0x1a, 0x56, 0xd7, 0x72,
|
||||
0x88, 0xcd, 0x21, 0x8c, 0x4c, 0x0f, 0xfe, 0xda,
|
||||
0x95, 0xe0, 0x3a, 0xa6, 0xa5, 0x84, 0x46, 0xcd,
|
||||
0xd5, 0x3e, 0x9d, 0x3a, 0xe2, 0x67, 0xe6, 0x60,
|
||||
0x1a, 0xe2, 0x70, 0x85, 0x58, 0xc2, 0x1b, 0x09,
|
||||
0xe1, 0xd7, 0x2c, 0xca, 0xad, 0xa8, 0x8f, 0xf9,
|
||||
0xac, 0xb3, 0x0e, 0xdb, 0xca, 0x2e, 0xe2, 0xb8,
|
||||
0x51, 0x71, 0xd9, 0x3c, 0x6c, 0xf1, 0x56, 0xf8,
|
||||
0xea, 0x9c, 0xf1, 0xfb, 0x0c, 0xe6, 0xb7, 0x10,
|
||||
0x1c, 0xf8, 0xa9, 0x7c, 0xe8, 0x53, 0x35, 0xc1,
|
||||
0x90, 0x3e, 0x76, 0x4a, 0x74, 0xa4, 0x21, 0x2c,
|
||||
0xf6, 0x2c, 0x4e, 0x0f, 0x94, 0x3a, 0x88, 0x2e,
|
||||
0x41, 0x09, 0x6a, 0x33, 0x7d, 0xf6, 0xdd, 0x3f,
|
||||
0x8d, 0x23, 0x31, 0x74, 0x84, 0xeb, 0x88, 0x6e,
|
||||
0xcc, 0xb9, 0xbc, 0x22, 0x83, 0x19, 0x07, 0x22,
|
||||
0xa5, 0x2d, 0xdf, 0xa5, 0xf3, 0x80, 0x85, 0x78,
|
||||
0x84, 0x39, 0x6a, 0x6d, 0x6a, 0x99, 0x4f, 0xa5,
|
||||
0x15, 0xfe, 0x46, 0xb0, 0xe4, 0x6c, 0xa5, 0x41,
|
||||
0x3c, 0xce, 0x8f, 0x42, 0x60, 0x71, 0xa7, 0x75,
|
||||
0x08, 0x40, 0x65, 0x8a, 0x82, 0xbf, 0xf5, 0x43,
|
||||
0x71, 0x96, 0xa9, 0x4d, 0x44, 0x8a, 0x20, 0xbe,
|
||||
0xfa, 0x4d, 0xbb, 0xc0, 0x7d, 0x31, 0x96, 0x65,
|
||||
0xe7, 0x75, 0xe5, 0x3e, 0xfd, 0x92, 0x3b, 0xc9,
|
||||
0x55, 0xbb, 0x16, 0x7e, 0xf7, 0xc2, 0x8c, 0xa4,
|
||||
0x40, 0x1d, 0xe5, 0xef, 0x0e, 0xdf, 0xe4, 0x9a,
|
||||
0x62, 0x73, 0x65, 0xfd, 0x46, 0x63, 0x25, 0x3d,
|
||||
0x2b, 0xaf, 0xe5, 0x64, 0xfe, 0xa5, 0x5c, 0xcf,
|
||||
0x24, 0xf3, 0xb4, 0xac, 0x64, 0xba, 0xdf, 0x4b,
|
||||
0xc6, 0x96, 0x7d, 0x81, 0x2d, 0x8d, 0x97, 0xf7,
|
||||
0xc5, 0x68, 0x77, 0x84, 0x32, 0x2b, 0xcc, 0x85,
|
||||
0x74, 0x96, 0xf0, 0x12, 0x77, 0x61, 0xb9, 0xeb,
|
||||
0x71, 0xaa, 0x82, 0xcb, 0x1c, 0xdb, 0x89, 0xc8,
|
||||
0xc6, 0xb5, 0xe3, 0x5c, 0x7d, 0x39, 0x07, 0x24,
|
||||
0xda, 0x39, 0x87, 0x45, 0xc0, 0x2b, 0xbb, 0x01,
|
||||
0xac, 0xbc, 0x2a, 0x5c, 0x7f, 0xfc, 0xe8, 0xce,
|
||||
0x6d, 0x9c, 0x6f, 0xed, 0xd3, 0xc1, 0xa1, 0xd6,
|
||||
0xc5, 0x55, 0xa9, 0x66, 0x2f, 0xe1, 0xc8, 0x32,
|
||||
0xa6, 0x5d, 0xa4, 0x3a, 0x98, 0x73, 0xe8, 0x45,
|
||||
0xa4, 0xc7, 0xa8, 0xb4, 0xf6, 0x13, 0x03, 0xf6,
|
||||
0xe9, 0x2e, 0xc4, 0x29, 0x0f, 0x84, 0xdb, 0xc4,
|
||||
0x21, 0xc4, 0xc2, 0x75, 0x67, 0x89, 0x37, 0x0a },
|
||||
.rlen = 512,
|
||||
}
|
||||
};
|
||||
|
||||
/* Cast5 test vectors from RFC 2144 */
|
||||
#define CAST5_ENC_TEST_VECTORS 3
|
||||
#define CAST5_DEC_TEST_VECTORS 3
|
||||
@ -3084,6 +3657,27 @@ static struct cipher_speed aes_speed_template[] = {
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed aes_lrw_speed_template[] = {
|
||||
{ .klen = 32, .blen = 16, },
|
||||
{ .klen = 32, .blen = 64, },
|
||||
{ .klen = 32, .blen = 256, },
|
||||
{ .klen = 32, .blen = 1024, },
|
||||
{ .klen = 32, .blen = 8192, },
|
||||
{ .klen = 40, .blen = 16, },
|
||||
{ .klen = 40, .blen = 64, },
|
||||
{ .klen = 40, .blen = 256, },
|
||||
{ .klen = 40, .blen = 1024, },
|
||||
{ .klen = 40, .blen = 8192, },
|
||||
{ .klen = 48, .blen = 16, },
|
||||
{ .klen = 48, .blen = 64, },
|
||||
{ .klen = 48, .blen = 256, },
|
||||
{ .klen = 48, .blen = 1024, },
|
||||
{ .klen = 48, .blen = 8192, },
|
||||
|
||||
/* End marker */
|
||||
{ .klen = 0, .blen = 0, }
|
||||
};
|
||||
|
||||
static struct cipher_speed des3_ede_speed_template[] = {
|
||||
{ .klen = 24, .blen = 16, },
|
||||
{ .klen = 24, .blen = 64, },
|
||||
|
348
crypto/xcbc.c
Normal file
348
crypto/xcbc.c
Normal file
@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (C)2006 USAGI/WIDE Project
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Author:
|
||||
* Kazunori Miyazawa <miyazawa@linux-ipv6.org>
|
||||
*/
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include "internal.h"
|
||||
|
||||
static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
|
||||
0x02020202, 0x02020202, 0x02020202, 0x02020202,
|
||||
0x03030303, 0x03030303, 0x03030303, 0x03030303};
|
||||
/*
|
||||
* +------------------------
|
||||
* | <parent tfm>
|
||||
* +------------------------
|
||||
* | crypto_xcbc_ctx
|
||||
* +------------------------
|
||||
* | odds (block size)
|
||||
* +------------------------
|
||||
* | prev (block size)
|
||||
* +------------------------
|
||||
* | key (block size)
|
||||
* +------------------------
|
||||
* | consts (block size * 3)
|
||||
* +------------------------
|
||||
*/
|
||||
struct crypto_xcbc_ctx {
|
||||
struct crypto_tfm *child;
|
||||
u8 *odds;
|
||||
u8 *prev;
|
||||
u8 *key;
|
||||
u8 *consts;
|
||||
void (*xor)(u8 *a, const u8 *b, unsigned int bs);
|
||||
unsigned int keylen;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
static void xor_128(u8 *a, const u8 *b, unsigned int bs)
|
||||
{
|
||||
((u32 *)a)[0] ^= ((u32 *)b)[0];
|
||||
((u32 *)a)[1] ^= ((u32 *)b)[1];
|
||||
((u32 *)a)[2] ^= ((u32 *)b)[2];
|
||||
((u32 *)a)[3] ^= ((u32 *)b)[3];
|
||||
}
|
||||
|
||||
static int _crypto_xcbc_digest_setkey(struct crypto_hash *parent,
|
||||
struct crypto_xcbc_ctx *ctx)
|
||||
{
|
||||
int bs = crypto_hash_blocksize(parent);
|
||||
int err = 0;
|
||||
u8 key1[bs];
|
||||
|
||||
if ((err = crypto_cipher_setkey(ctx->child, ctx->key, ctx->keylen)))
|
||||
return err;
|
||||
|
||||
ctx->child->__crt_alg->cra_cipher.cia_encrypt(ctx->child, key1,
|
||||
ctx->consts);
|
||||
|
||||
return crypto_cipher_setkey(ctx->child, key1, bs);
|
||||
}
|
||||
|
||||
static int crypto_xcbc_digest_setkey(struct crypto_hash *parent,
|
||||
const u8 *inkey, unsigned int keylen)
|
||||
{
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
|
||||
|
||||
if (keylen != crypto_tfm_alg_blocksize(ctx->child))
|
||||
return -EINVAL;
|
||||
|
||||
ctx->keylen = keylen;
|
||||
memcpy(ctx->key, inkey, keylen);
|
||||
ctx->consts = (u8*)ks;
|
||||
|
||||
return _crypto_xcbc_digest_setkey(parent, ctx);
|
||||
}
|
||||
|
||||
static int crypto_xcbc_digest_init(struct hash_desc *pdesc)
|
||||
{
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(pdesc->tfm);
|
||||
int bs = crypto_hash_blocksize(pdesc->tfm);
|
||||
|
||||
ctx->len = 0;
|
||||
memset(ctx->odds, 0, bs);
|
||||
memset(ctx->prev, 0, bs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_xcbc_digest_update(struct hash_desc *pdesc,
|
||||
struct scatterlist *sg,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_hash *parent = pdesc->tfm;
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
|
||||
struct crypto_tfm *tfm = ctx->child;
|
||||
int bs = crypto_hash_blocksize(parent);
|
||||
unsigned int i = 0;
|
||||
|
||||
do {
|
||||
|
||||
struct page *pg = sg[i].page;
|
||||
unsigned int offset = sg[i].offset;
|
||||
unsigned int slen = sg[i].length;
|
||||
|
||||
while (slen > 0) {
|
||||
unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
|
||||
char *p = crypto_kmap(pg, 0) + offset;
|
||||
|
||||
/* checking the data can fill the block */
|
||||
if ((ctx->len + len) <= bs) {
|
||||
memcpy(ctx->odds + ctx->len, p, len);
|
||||
ctx->len += len;
|
||||
slen -= len;
|
||||
|
||||
/* checking the rest of the page */
|
||||
if (len + offset >= PAGE_SIZE) {
|
||||
offset = 0;
|
||||
pg++;
|
||||
} else
|
||||
offset += len;
|
||||
|
||||
crypto_kunmap(p, 0);
|
||||
crypto_yield(tfm->crt_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* filling odds with new data and encrypting it */
|
||||
memcpy(ctx->odds + ctx->len, p, bs - ctx->len);
|
||||
len -= bs - ctx->len;
|
||||
p += bs - ctx->len;
|
||||
|
||||
ctx->xor(ctx->prev, ctx->odds, bs);
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev);
|
||||
|
||||
/* clearing the length */
|
||||
ctx->len = 0;
|
||||
|
||||
/* encrypting the rest of data */
|
||||
while (len > bs) {
|
||||
ctx->xor(ctx->prev, p, bs);
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev);
|
||||
p += bs;
|
||||
len -= bs;
|
||||
}
|
||||
|
||||
/* keeping the surplus of blocksize */
|
||||
if (len) {
|
||||
memcpy(ctx->odds, p, len);
|
||||
ctx->len = len;
|
||||
}
|
||||
crypto_kunmap(p, 0);
|
||||
crypto_yield(tfm->crt_flags);
|
||||
slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
|
||||
offset = 0;
|
||||
pg++;
|
||||
}
|
||||
nbytes-=sg[i].length;
|
||||
i++;
|
||||
} while (nbytes>0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out)
|
||||
{
|
||||
struct crypto_hash *parent = pdesc->tfm;
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
|
||||
struct crypto_tfm *tfm = ctx->child;
|
||||
int bs = crypto_hash_blocksize(parent);
|
||||
int err = 0;
|
||||
|
||||
if (ctx->len == bs) {
|
||||
u8 key2[bs];
|
||||
|
||||
if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
|
||||
return err;
|
||||
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key2, (const u8*)(ctx->consts+bs));
|
||||
|
||||
ctx->xor(ctx->prev, ctx->odds, bs);
|
||||
ctx->xor(ctx->prev, key2, bs);
|
||||
_crypto_xcbc_digest_setkey(parent, ctx);
|
||||
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev);
|
||||
} else {
|
||||
u8 key3[bs];
|
||||
unsigned int rlen;
|
||||
u8 *p = ctx->odds + ctx->len;
|
||||
*p = 0x80;
|
||||
p++;
|
||||
|
||||
rlen = bs - ctx->len -1;
|
||||
if (rlen)
|
||||
memset(p, 0, rlen);
|
||||
|
||||
if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
|
||||
return err;
|
||||
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key3, (const u8*)(ctx->consts+bs*2));
|
||||
|
||||
ctx->xor(ctx->prev, ctx->odds, bs);
|
||||
ctx->xor(ctx->prev, key3, bs);
|
||||
|
||||
_crypto_xcbc_digest_setkey(parent, ctx);
|
||||
|
||||
tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_xcbc_digest(struct hash_desc *pdesc,
|
||||
struct scatterlist *sg, unsigned int nbytes, u8 *out)
|
||||
{
|
||||
crypto_xcbc_digest_init(pdesc);
|
||||
crypto_xcbc_digest_update(pdesc, sg, nbytes);
|
||||
return crypto_xcbc_digest_final(pdesc, out);
|
||||
}
|
||||
|
||||
static int xcbc_init_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_instance *inst = (void *)tfm->__crt_alg;
|
||||
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(__crypto_hash_cast(tfm));
|
||||
int bs = crypto_hash_blocksize(__crypto_hash_cast(tfm));
|
||||
|
||||
tfm = crypto_spawn_tfm(spawn);
|
||||
if (IS_ERR(tfm))
|
||||
return PTR_ERR(tfm);
|
||||
|
||||
switch(bs) {
|
||||
case 16:
|
||||
ctx->xor = xor_128;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->child = crypto_cipher_cast(tfm);
|
||||
ctx->odds = (u8*)(ctx+1);
|
||||
ctx->prev = ctx->odds + bs;
|
||||
ctx->key = ctx->prev + bs;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void xcbc_exit_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(__crypto_hash_cast(tfm));
|
||||
crypto_free_cipher(ctx->child);
|
||||
}
|
||||
|
||||
static struct crypto_instance *xcbc_alloc(void *param, unsigned int len)
|
||||
{
|
||||
struct crypto_instance *inst;
|
||||
struct crypto_alg *alg;
|
||||
alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(alg))
|
||||
return ERR_PTR(PTR_ERR(alg));
|
||||
|
||||
switch(alg->cra_blocksize) {
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
return ERR_PTR(PTR_ERR(alg));
|
||||
}
|
||||
|
||||
inst = crypto_alloc_instance("xcbc", alg);
|
||||
if (IS_ERR(inst))
|
||||
goto out_put_alg;
|
||||
|
||||
inst->alg.cra_flags = CRYPTO_ALG_TYPE_HASH;
|
||||
inst->alg.cra_priority = alg->cra_priority;
|
||||
inst->alg.cra_blocksize = alg->cra_blocksize;
|
||||
inst->alg.cra_alignmask = alg->cra_alignmask;
|
||||
inst->alg.cra_type = &crypto_hash_type;
|
||||
|
||||
inst->alg.cra_hash.digestsize =
|
||||
(alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
|
||||
CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize :
|
||||
alg->cra_blocksize;
|
||||
inst->alg.cra_ctxsize = sizeof(struct crypto_xcbc_ctx) +
|
||||
ALIGN(inst->alg.cra_blocksize * 3, sizeof(void *));
|
||||
inst->alg.cra_init = xcbc_init_tfm;
|
||||
inst->alg.cra_exit = xcbc_exit_tfm;
|
||||
|
||||
inst->alg.cra_hash.init = crypto_xcbc_digest_init;
|
||||
inst->alg.cra_hash.update = crypto_xcbc_digest_update;
|
||||
inst->alg.cra_hash.final = crypto_xcbc_digest_final;
|
||||
inst->alg.cra_hash.digest = crypto_xcbc_digest;
|
||||
inst->alg.cra_hash.setkey = crypto_xcbc_digest_setkey;
|
||||
|
||||
out_put_alg:
|
||||
crypto_mod_put(alg);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static void xcbc_free(struct crypto_instance *inst)
|
||||
{
|
||||
crypto_drop_spawn(crypto_instance_ctx(inst));
|
||||
kfree(inst);
|
||||
}
|
||||
|
||||
static struct crypto_template crypto_xcbc_tmpl = {
|
||||
.name = "xcbc",
|
||||
.alloc = xcbc_alloc,
|
||||
.free = xcbc_free,
|
||||
.module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init crypto_xcbc_module_init(void)
|
||||
{
|
||||
return crypto_register_template(&crypto_xcbc_tmpl);
|
||||
}
|
||||
|
||||
static void __exit crypto_xcbc_module_exit(void)
|
||||
{
|
||||
crypto_unregister_template(&crypto_xcbc_tmpl);
|
||||
}
|
||||
|
||||
module_init(crypto_xcbc_module_init);
|
||||
module_exit(crypto_xcbc_module_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("XCBC keyed hash algorithm");
|
@ -41,7 +41,7 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
|
||||
# guess the target endianess to choose the right PCA-200E firmware image
|
||||
ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
|
||||
byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
|
||||
CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
|
||||
CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -306,6 +306,7 @@ config BLK_DEV_LOOP
|
||||
config BLK_DEV_CRYPTOLOOP
|
||||
tristate "Cryptoloop Support"
|
||||
select CRYPTO
|
||||
select CRYPTO_CBC
|
||||
depends on BLK_DEV_LOOP
|
||||
---help---
|
||||
Say Y here if you want to be able to use the ciphers that are
|
||||
|
@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA
|
||||
If unsure say M. The compiled module will be
|
||||
called padlock-sha.ko
|
||||
|
||||
config CRYPTO_DEV_GEODE
|
||||
tristate "Support for the Geode LX AES engine"
|
||||
depends on CRYPTO && X86_32
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_BLKCIPHER
|
||||
default m
|
||||
help
|
||||
Say 'Y' here to use the AMD Geode LX processor on-board AES
|
||||
engine for the CryptoAPI AES alogrithm.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called geode-aes.
|
||||
|
||||
endmenu
|
||||
|
@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
|
||||
|
474
drivers/crypto/geode-aes.c
Normal file
474
drivers/crypto/geode-aes.c
Normal file
@ -0,0 +1,474 @@
|
||||
/* Copyright (C) 2004-2006, Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
#include "geode-aes.h"
|
||||
|
||||
/* Register definitions */
|
||||
|
||||
#define AES_CTRLA_REG 0x0000
|
||||
|
||||
#define AES_CTRL_START 0x01
|
||||
#define AES_CTRL_DECRYPT 0x00
|
||||
#define AES_CTRL_ENCRYPT 0x02
|
||||
#define AES_CTRL_WRKEY 0x04
|
||||
#define AES_CTRL_DCA 0x08
|
||||
#define AES_CTRL_SCA 0x10
|
||||
#define AES_CTRL_CBC 0x20
|
||||
|
||||
#define AES_INTR_REG 0x0008
|
||||
|
||||
#define AES_INTRA_PENDING (1 << 16)
|
||||
#define AES_INTRB_PENDING (1 << 17)
|
||||
|
||||
#define AES_INTR_PENDING (AES_INTRA_PENDING | AES_INTRB_PENDING)
|
||||
#define AES_INTR_MASK 0x07
|
||||
|
||||
#define AES_SOURCEA_REG 0x0010
|
||||
#define AES_DSTA_REG 0x0014
|
||||
#define AES_LENA_REG 0x0018
|
||||
#define AES_WRITEKEY0_REG 0x0030
|
||||
#define AES_WRITEIV0_REG 0x0040
|
||||
|
||||
/* A very large counter that is used to gracefully bail out of an
|
||||
* operation in case of trouble
|
||||
*/
|
||||
|
||||
#define AES_OP_TIMEOUT 0x50000
|
||||
|
||||
/* Static structures */
|
||||
|
||||
static void __iomem * _iobase;
|
||||
static spinlock_t lock;
|
||||
|
||||
/* Write a 128 bit field (either a writable key or IV) */
|
||||
static inline void
|
||||
_writefield(u32 offset, void *value)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 4; i++)
|
||||
iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4));
|
||||
}
|
||||
|
||||
/* Read a 128 bit field (either a writable key or IV) */
|
||||
static inline void
|
||||
_readfield(u32 offset, void *value)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 4; i++)
|
||||
((u32 *) value)[i] = ioread32(_iobase + offset + (i * 4));
|
||||
}
|
||||
|
||||
static int
|
||||
do_crypt(void *src, void *dst, int len, u32 flags)
|
||||
{
|
||||
u32 status;
|
||||
u32 counter = AES_OP_TIMEOUT;
|
||||
|
||||
iowrite32(virt_to_phys(src), _iobase + AES_SOURCEA_REG);
|
||||
iowrite32(virt_to_phys(dst), _iobase + AES_DSTA_REG);
|
||||
iowrite32(len, _iobase + AES_LENA_REG);
|
||||
|
||||
/* Start the operation */
|
||||
iowrite32(AES_CTRL_START | flags, _iobase + AES_CTRLA_REG);
|
||||
|
||||
do
|
||||
status = ioread32(_iobase + AES_INTR_REG);
|
||||
while(!(status & AES_INTRA_PENDING) && --counter);
|
||||
|
||||
/* Clear the event */
|
||||
iowrite32((status & 0xFF) | AES_INTRA_PENDING, _iobase + AES_INTR_REG);
|
||||
return counter ? 0 : 1;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
geode_aes_crypt(struct geode_aes_op *op)
|
||||
{
|
||||
|
||||
u32 flags = 0;
|
||||
int iflags;
|
||||
|
||||
if (op->len == 0 || op->src == op->dst)
|
||||
return 0;
|
||||
|
||||
if (op->flags & AES_FLAGS_COHERENT)
|
||||
flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
|
||||
|
||||
if (op->dir == AES_DIR_ENCRYPT)
|
||||
flags |= AES_CTRL_ENCRYPT;
|
||||
|
||||
/* Start the critical section */
|
||||
|
||||
spin_lock_irqsave(&lock, iflags);
|
||||
|
||||
if (op->mode == AES_MODE_CBC) {
|
||||
flags |= AES_CTRL_CBC;
|
||||
_writefield(AES_WRITEIV0_REG, op->iv);
|
||||
}
|
||||
|
||||
if (op->flags & AES_FLAGS_USRKEY) {
|
||||
flags |= AES_CTRL_WRKEY;
|
||||
_writefield(AES_WRITEKEY0_REG, op->key);
|
||||
}
|
||||
|
||||
do_crypt(op->src, op->dst, op->len, flags);
|
||||
|
||||
if (op->mode == AES_MODE_CBC)
|
||||
_readfield(AES_WRITEIV0_REG, op->iv);
|
||||
|
||||
spin_unlock_irqrestore(&lock, iflags);
|
||||
|
||||
return op->len;
|
||||
}
|
||||
|
||||
/* CRYPTO-API Functions */
|
||||
|
||||
static int
|
||||
geode_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int len)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_tfm_ctx(tfm);
|
||||
|
||||
if (len != AES_KEY_LENGTH) {
|
||||
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(op->key, key, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_tfm_ctx(tfm);
|
||||
|
||||
if ((out == NULL) || (in == NULL))
|
||||
return;
|
||||
|
||||
op->src = (void *) in;
|
||||
op->dst = (void *) out;
|
||||
op->mode = AES_MODE_ECB;
|
||||
op->flags = 0;
|
||||
op->len = AES_MIN_BLOCK_SIZE;
|
||||
op->dir = AES_DIR_ENCRYPT;
|
||||
|
||||
geode_aes_crypt(op);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_tfm_ctx(tfm);
|
||||
|
||||
if ((out == NULL) || (in == NULL))
|
||||
return;
|
||||
|
||||
op->src = (void *) in;
|
||||
op->dst = (void *) out;
|
||||
op->mode = AES_MODE_ECB;
|
||||
op->flags = 0;
|
||||
op->len = AES_MIN_BLOCK_SIZE;
|
||||
op->dir = AES_DIR_DECRYPT;
|
||||
|
||||
geode_aes_crypt(op);
|
||||
}
|
||||
|
||||
|
||||
static struct crypto_alg geode_alg = {
|
||||
.cra_name = "aes",
|
||||
.cra_driver_name = "geode-aes-128",
|
||||
.cra_priority = 300,
|
||||
.cra_alignmask = 15,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = AES_MIN_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct geode_aes_op),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(geode_alg.cra_list),
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = AES_KEY_LENGTH,
|
||||
.cia_max_keysize = AES_KEY_LENGTH,
|
||||
.cia_setkey = geode_setkey,
|
||||
.cia_encrypt = geode_encrypt,
|
||||
.cia_decrypt = geode_decrypt
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int
|
||||
geode_cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err, ret;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while((nbytes = walk.nbytes)) {
|
||||
op->src = walk.src.virt.addr,
|
||||
op->dst = walk.dst.virt.addr;
|
||||
op->mode = AES_MODE_CBC;
|
||||
op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
|
||||
op->dir = AES_DIR_DECRYPT;
|
||||
|
||||
memcpy(op->iv, walk.iv, AES_IV_LENGTH);
|
||||
|
||||
ret = geode_aes_crypt(op);
|
||||
|
||||
memcpy(walk.iv, op->iv, AES_IV_LENGTH);
|
||||
nbytes -= ret;
|
||||
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
geode_cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err, ret;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while((nbytes = walk.nbytes)) {
|
||||
op->src = walk.src.virt.addr,
|
||||
op->dst = walk.dst.virt.addr;
|
||||
op->mode = AES_MODE_CBC;
|
||||
op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
|
||||
op->dir = AES_DIR_ENCRYPT;
|
||||
|
||||
memcpy(op->iv, walk.iv, AES_IV_LENGTH);
|
||||
|
||||
ret = geode_aes_crypt(op);
|
||||
nbytes -= ret;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg geode_cbc_alg = {
|
||||
.cra_name = "cbc(aes)",
|
||||
.cra_driver_name = "cbc-aes-geode-128",
|
||||
.cra_priority = 400,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_MIN_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct geode_aes_op),
|
||||
.cra_alignmask = 15,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(geode_cbc_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_KEY_LENGTH,
|
||||
.max_keysize = AES_KEY_LENGTH,
|
||||
.setkey = geode_setkey,
|
||||
.encrypt = geode_cbc_encrypt,
|
||||
.decrypt = geode_cbc_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int
|
||||
geode_ecb_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err, ret;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while((nbytes = walk.nbytes)) {
|
||||
op->src = walk.src.virt.addr,
|
||||
op->dst = walk.dst.virt.addr;
|
||||
op->mode = AES_MODE_ECB;
|
||||
op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
|
||||
op->dir = AES_DIR_DECRYPT;
|
||||
|
||||
ret = geode_aes_crypt(op);
|
||||
nbytes -= ret;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
geode_ecb_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err, ret;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while((nbytes = walk.nbytes)) {
|
||||
op->src = walk.src.virt.addr,
|
||||
op->dst = walk.dst.virt.addr;
|
||||
op->mode = AES_MODE_ECB;
|
||||
op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
|
||||
op->dir = AES_DIR_ENCRYPT;
|
||||
|
||||
ret = geode_aes_crypt(op);
|
||||
nbytes -= ret;
|
||||
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg geode_ecb_alg = {
|
||||
.cra_name = "ecb(aes)",
|
||||
.cra_driver_name = "ecb-aes-geode-128",
|
||||
.cra_priority = 400,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_MIN_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct geode_aes_op),
|
||||
.cra_alignmask = 15,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(geode_ecb_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_KEY_LENGTH,
|
||||
.max_keysize = AES_KEY_LENGTH,
|
||||
.setkey = geode_setkey,
|
||||
.encrypt = geode_ecb_encrypt,
|
||||
.decrypt = geode_ecb_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
geode_aes_remove(struct pci_dev *dev)
|
||||
{
|
||||
crypto_unregister_alg(&geode_alg);
|
||||
crypto_unregister_alg(&geode_ecb_alg);
|
||||
crypto_unregister_alg(&geode_cbc_alg);
|
||||
|
||||
pci_iounmap(dev, _iobase);
|
||||
_iobase = NULL;
|
||||
|
||||
pci_release_regions(dev);
|
||||
pci_disable_device(dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pci_enable_device(dev)))
|
||||
return ret;
|
||||
|
||||
if ((ret = pci_request_regions(dev, "geode-aes-128")))
|
||||
goto eenable;
|
||||
|
||||
_iobase = pci_iomap(dev, 0, 0);
|
||||
|
||||
if (_iobase == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto erequest;
|
||||
}
|
||||
|
||||
spin_lock_init(&lock);
|
||||
|
||||
/* Clear any pending activity */
|
||||
iowrite32(AES_INTR_PENDING | AES_INTR_MASK, _iobase + AES_INTR_REG);
|
||||
|
||||
if ((ret = crypto_register_alg(&geode_alg)))
|
||||
goto eiomap;
|
||||
|
||||
if ((ret = crypto_register_alg(&geode_ecb_alg)))
|
||||
goto ealg;
|
||||
|
||||
if ((ret = crypto_register_alg(&geode_cbc_alg)))
|
||||
goto eecb;
|
||||
|
||||
printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled.\n");
|
||||
return 0;
|
||||
|
||||
eecb:
|
||||
crypto_unregister_alg(&geode_ecb_alg);
|
||||
|
||||
ealg:
|
||||
crypto_unregister_alg(&geode_alg);
|
||||
|
||||
eiomap:
|
||||
pci_iounmap(dev, _iobase);
|
||||
|
||||
erequest:
|
||||
pci_release_regions(dev);
|
||||
|
||||
eenable:
|
||||
pci_disable_device(dev);
|
||||
|
||||
printk(KERN_ERR "geode-aes: GEODE AES initialization failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pci_device_id geode_aes_tbl[] = {
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES, PCI_ANY_ID, PCI_ANY_ID} ,
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, geode_aes_tbl);
|
||||
|
||||
static struct pci_driver geode_aes_driver = {
|
||||
.name = "Geode LX AES",
|
||||
.id_table = geode_aes_tbl,
|
||||
.probe = geode_aes_probe,
|
||||
.remove = __devexit_p(geode_aes_remove)
|
||||
};
|
||||
|
||||
static int __init
|
||||
geode_aes_init(void)
|
||||
{
|
||||
return pci_module_init(&geode_aes_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
geode_aes_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&geode_aes_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
|
||||
MODULE_DESCRIPTION("Geode LX Hardware AES driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(geode_aes_init);
|
||||
module_exit(geode_aes_exit);
|
40
drivers/crypto/geode-aes.h
Normal file
40
drivers/crypto/geode-aes.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright (C) 2003-2006, Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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 _GEODE_AES_H_
|
||||
#define _GEODE_AES_H_
|
||||
|
||||
#define AES_KEY_LENGTH 16
|
||||
#define AES_IV_LENGTH 16
|
||||
|
||||
#define AES_MIN_BLOCK_SIZE 16
|
||||
|
||||
#define AES_MODE_ECB 0
|
||||
#define AES_MODE_CBC 1
|
||||
|
||||
#define AES_DIR_DECRYPT 0
|
||||
#define AES_DIR_ENCRYPT 1
|
||||
|
||||
#define AES_FLAGS_USRKEY (1 << 0)
|
||||
#define AES_FLAGS_COHERENT (1 << 1)
|
||||
|
||||
struct geode_aes_op {
|
||||
|
||||
void *src;
|
||||
void *dst;
|
||||
|
||||
u32 mode;
|
||||
u32 dir;
|
||||
u32 flags;
|
||||
int len;
|
||||
|
||||
u8 key[AES_KEY_LENGTH];
|
||||
u8 iv[AES_IV_LENGTH];
|
||||
};
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "dm.h"
|
||||
|
||||
@ -85,7 +86,10 @@ struct crypt_config {
|
||||
*/
|
||||
struct crypt_iv_operations *iv_gen_ops;
|
||||
char *iv_mode;
|
||||
struct crypto_cipher *iv_gen_private;
|
||||
union {
|
||||
struct crypto_cipher *essiv_tfm;
|
||||
int benbi_shift;
|
||||
} iv_gen_private;
|
||||
sector_t iv_offset;
|
||||
unsigned int iv_size;
|
||||
|
||||
@ -113,6 +117,9 @@ static struct kmem_cache *_crypt_io_pool;
|
||||
* encrypted with the bulk cipher using a salt as key. The salt
|
||||
* should be derived from the bulk cipher's key via hashing.
|
||||
*
|
||||
* benbi: the 64-bit "big-endian 'narrow block'-count", starting at 1
|
||||
* (needed for LRW-32-AES and possible other narrow block modes)
|
||||
*
|
||||
* plumb: unimplemented, see:
|
||||
* http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454
|
||||
*/
|
||||
@ -191,21 +198,61 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
|
||||
}
|
||||
kfree(salt);
|
||||
|
||||
cc->iv_gen_private = essiv_tfm;
|
||||
cc->iv_gen_private.essiv_tfm = essiv_tfm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_iv_essiv_dtr(struct crypt_config *cc)
|
||||
{
|
||||
crypto_free_cipher(cc->iv_gen_private);
|
||||
cc->iv_gen_private = NULL;
|
||||
crypto_free_cipher(cc->iv_gen_private.essiv_tfm);
|
||||
cc->iv_gen_private.essiv_tfm = NULL;
|
||||
}
|
||||
|
||||
static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
|
||||
{
|
||||
memset(iv, 0, cc->iv_size);
|
||||
*(u64 *)iv = cpu_to_le64(sector);
|
||||
crypto_cipher_encrypt_one(cc->iv_gen_private, iv, iv);
|
||||
crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
|
||||
const char *opts)
|
||||
{
|
||||
unsigned int bs = crypto_blkcipher_blocksize(cc->tfm);
|
||||
int log = long_log2(bs);
|
||||
|
||||
/* we need to calculate how far we must shift the sector count
|
||||
* to get the cipher block count, we use this shift in _gen */
|
||||
|
||||
if (1 << log != bs) {
|
||||
ti->error = "cypher blocksize is not a power of 2";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (log > 9) {
|
||||
ti->error = "cypher blocksize is > 512";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cc->iv_gen_private.benbi_shift = 9 - log;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_iv_benbi_dtr(struct crypt_config *cc)
|
||||
{
|
||||
}
|
||||
|
||||
static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
|
||||
{
|
||||
__be64 val;
|
||||
|
||||
memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */
|
||||
|
||||
val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1);
|
||||
put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -219,13 +266,18 @@ static struct crypt_iv_operations crypt_iv_essiv_ops = {
|
||||
.generator = crypt_iv_essiv_gen
|
||||
};
|
||||
|
||||
static struct crypt_iv_operations crypt_iv_benbi_ops = {
|
||||
.ctr = crypt_iv_benbi_ctr,
|
||||
.dtr = crypt_iv_benbi_dtr,
|
||||
.generator = crypt_iv_benbi_gen
|
||||
};
|
||||
|
||||
static int
|
||||
crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
|
||||
struct scatterlist *in, unsigned int length,
|
||||
int write, sector_t sector)
|
||||
{
|
||||
u8 iv[cc->iv_size];
|
||||
u8 iv[cc->iv_size] __attribute__ ((aligned(__alignof__(u64))));
|
||||
struct blkcipher_desc desc = {
|
||||
.tfm = cc->tfm,
|
||||
.info = iv,
|
||||
@ -768,7 +820,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
cc->tfm = tfm;
|
||||
|
||||
/*
|
||||
* Choose ivmode. Valid modes: "plain", "essiv:<esshash>".
|
||||
* Choose ivmode. Valid modes: "plain", "essiv:<esshash>", "benbi".
|
||||
* See comments at iv code
|
||||
*/
|
||||
|
||||
@ -778,6 +830,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
cc->iv_gen_ops = &crypt_iv_plain_ops;
|
||||
else if (strcmp(ivmode, "essiv") == 0)
|
||||
cc->iv_gen_ops = &crypt_iv_essiv_ops;
|
||||
else if (strcmp(ivmode, "benbi") == 0)
|
||||
cc->iv_gen_ops = &crypt_iv_benbi_ops;
|
||||
else {
|
||||
ti->error = "Invalid IV mode";
|
||||
goto bad2;
|
||||
|
@ -704,9 +704,9 @@ static int pxa_irda_stop(struct net_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
|
||||
static int pxa_irda_suspend(struct platform_device *_dev, pm_message_t state)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(_dev);
|
||||
struct net_device *dev = platform_get_drvdata(_dev);
|
||||
struct pxa_irda *si;
|
||||
|
||||
if (dev && netif_running(dev)) {
|
||||
@ -718,9 +718,9 @@ static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa_irda_resume(struct device *_dev)
|
||||
static int pxa_irda_resume(struct platform_device *_dev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(_dev);
|
||||
struct net_device *dev = platform_get_drvdata(_dev);
|
||||
struct pxa_irda *si;
|
||||
|
||||
if (dev && netif_running(dev)) {
|
||||
@ -746,9 +746,8 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size)
|
||||
return io->head ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int pxa_irda_probe(struct device *_dev)
|
||||
static int pxa_irda_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(_dev);
|
||||
struct net_device *dev;
|
||||
struct pxa_irda *si;
|
||||
unsigned int baudrate_mask;
|
||||
@ -822,9 +821,9 @@ err_mem_1:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pxa_irda_remove(struct device *_dev)
|
||||
static int pxa_irda_remove(struct platform_device *_dev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(_dev);
|
||||
struct net_device *dev = platform_get_drvdata(_dev);
|
||||
|
||||
if (dev) {
|
||||
struct pxa_irda *si = netdev_priv(dev);
|
||||
@ -840,9 +839,10 @@ static int pxa_irda_remove(struct device *_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver pxa_ir_driver = {
|
||||
.name = "pxa2xx-ir",
|
||||
.bus = &platform_bus_type,
|
||||
static struct platform_driver pxa_ir_driver = {
|
||||
.driver = {
|
||||
.name = "pxa2xx-ir",
|
||||
},
|
||||
.probe = pxa_irda_probe,
|
||||
.remove = pxa_irda_remove,
|
||||
.suspend = pxa_irda_suspend,
|
||||
@ -851,12 +851,12 @@ static struct device_driver pxa_ir_driver = {
|
||||
|
||||
static int __init pxa_irda_init(void)
|
||||
{
|
||||
return driver_register(&pxa_ir_driver);
|
||||
return platform_driver_register(&pxa_ir_driver);
|
||||
}
|
||||
|
||||
static void __exit pxa_irda_exit(void)
|
||||
{
|
||||
driver_unregister(&pxa_ir_driver);
|
||||
platform_driver_unregister(&pxa_ir_driver);
|
||||
}
|
||||
|
||||
module_init(pxa_irda_init);
|
||||
|
@ -68,8 +68,8 @@
|
||||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.69"
|
||||
#define DRV_MODULE_RELDATE "November 15, 2006"
|
||||
#define DRV_MODULE_VERSION "3.70"
|
||||
#define DRV_MODULE_RELDATE "December 1, 2006"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
@ -192,6 +192,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)},
|
||||
@ -1061,7 +1062,7 @@ static void tg3_frob_aux_power(struct tg3 *tp)
|
||||
{
|
||||
struct tg3 *tp_peer = tp;
|
||||
|
||||
if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0)
|
||||
if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0)
|
||||
return;
|
||||
|
||||
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
|
||||
@ -1212,8 +1213,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
|
||||
power_control);
|
||||
udelay(100); /* Delay after power state change */
|
||||
|
||||
/* Switch out of Vaux if it is not a LOM */
|
||||
if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
|
||||
/* Switch out of Vaux if it is a NIC */
|
||||
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
|
||||
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
|
||||
|
||||
return 0;
|
||||
@ -1401,8 +1402,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
|
||||
static void tg3_link_report(struct tg3 *tp)
|
||||
{
|
||||
if (!netif_carrier_ok(tp->dev)) {
|
||||
printk(KERN_INFO PFX "%s: Link is down.\n", tp->dev->name);
|
||||
} else {
|
||||
if (netif_msg_link(tp))
|
||||
printk(KERN_INFO PFX "%s: Link is down.\n",
|
||||
tp->dev->name);
|
||||
} else if (netif_msg_link(tp)) {
|
||||
printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
|
||||
tp->dev->name,
|
||||
(tp->link_config.active_speed == SPEED_1000 ?
|
||||
@ -1557,12 +1560,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
|
||||
|
||||
tg3_writephy(tp, MII_ADVERTISE, new_adv);
|
||||
} else if (tp->link_config.speed == SPEED_INVALID) {
|
||||
tp->link_config.advertising =
|
||||
(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
|
||||
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
|
||||
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
|
||||
ADVERTISED_Autoneg | ADVERTISED_MII);
|
||||
|
||||
if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
|
||||
tp->link_config.advertising &=
|
||||
~(ADVERTISED_1000baseT_Half |
|
||||
@ -1706,25 +1703,36 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tg3_copper_is_advertising_all(struct tg3 *tp)
|
||||
static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask)
|
||||
{
|
||||
u32 adv_reg, all_mask;
|
||||
u32 adv_reg, all_mask = 0;
|
||||
|
||||
if (mask & ADVERTISED_10baseT_Half)
|
||||
all_mask |= ADVERTISE_10HALF;
|
||||
if (mask & ADVERTISED_10baseT_Full)
|
||||
all_mask |= ADVERTISE_10FULL;
|
||||
if (mask & ADVERTISED_100baseT_Half)
|
||||
all_mask |= ADVERTISE_100HALF;
|
||||
if (mask & ADVERTISED_100baseT_Full)
|
||||
all_mask |= ADVERTISE_100FULL;
|
||||
|
||||
if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg))
|
||||
return 0;
|
||||
|
||||
all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL);
|
||||
if ((adv_reg & all_mask) != all_mask)
|
||||
return 0;
|
||||
if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
|
||||
u32 tg3_ctrl;
|
||||
|
||||
all_mask = 0;
|
||||
if (mask & ADVERTISED_1000baseT_Half)
|
||||
all_mask |= ADVERTISE_1000HALF;
|
||||
if (mask & ADVERTISED_1000baseT_Full)
|
||||
all_mask |= ADVERTISE_1000FULL;
|
||||
|
||||
if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl))
|
||||
return 0;
|
||||
|
||||
all_mask = (MII_TG3_CTRL_ADV_1000_HALF |
|
||||
MII_TG3_CTRL_ADV_1000_FULL);
|
||||
if ((tg3_ctrl & all_mask) != all_mask)
|
||||
return 0;
|
||||
}
|
||||
@ -1884,7 +1892,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
|
||||
/* Force autoneg restart if we are exiting
|
||||
* low power mode.
|
||||
*/
|
||||
if (!tg3_copper_is_advertising_all(tp))
|
||||
if (!tg3_copper_is_advertising_all(tp,
|
||||
tp->link_config.advertising))
|
||||
current_link_up = 0;
|
||||
} else {
|
||||
current_link_up = 0;
|
||||
@ -3703,8 +3712,9 @@ static void tg3_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
|
||||
printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
|
||||
dev->name);
|
||||
if (netif_msg_tx_err(tp))
|
||||
printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
|
||||
dev->name);
|
||||
|
||||
schedule_work(&tp->reset_task);
|
||||
}
|
||||
@ -6396,16 +6406,17 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||
udelay(40);
|
||||
|
||||
/* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
|
||||
* If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the
|
||||
* If TG3_FLG2_IS_NIC is zero, we should read the
|
||||
* register to preserve the GPIO settings for LOMs. The GPIOs,
|
||||
* whether used as inputs or outputs, are set by boot code after
|
||||
* reset.
|
||||
*/
|
||||
if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
|
||||
if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) {
|
||||
u32 gpio_mask;
|
||||
|
||||
gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 |
|
||||
GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2;
|
||||
gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 |
|
||||
GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 |
|
||||
GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2;
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
|
||||
gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
|
||||
@ -6417,8 +6428,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||
tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
|
||||
|
||||
/* GPIO1 must be driven high for eeprom write protect */
|
||||
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
|
||||
GRC_LCLCTRL_GPIO_OUTPUT1);
|
||||
if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)
|
||||
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
|
||||
GRC_LCLCTRL_GPIO_OUTPUT1);
|
||||
}
|
||||
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
||||
udelay(100);
|
||||
@ -8656,7 +8668,9 @@ static int tg3_test_registers(struct tg3 *tp)
|
||||
return 0;
|
||||
|
||||
out:
|
||||
printk(KERN_ERR PFX "Register test failed at offset %x\n", offset);
|
||||
if (netif_msg_hw(tp))
|
||||
printk(KERN_ERR PFX "Register test failed at offset %x\n",
|
||||
offset);
|
||||
tw32(offset, save_val);
|
||||
return -EIO;
|
||||
}
|
||||
@ -8781,17 +8795,20 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
|
||||
tg3_writephy(tp, 0x10, phy & ~0x4000);
|
||||
tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
|
||||
}
|
||||
}
|
||||
val = BMCR_LOOPBACK | BMCR_FULLDPLX;
|
||||
if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
|
||||
val |= BMCR_SPEED100;
|
||||
else
|
||||
val |= BMCR_SPEED1000;
|
||||
val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
|
||||
} else
|
||||
val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
|
||||
|
||||
tg3_writephy(tp, MII_BMCR, val);
|
||||
udelay(40);
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
|
||||
|
||||
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
|
||||
MAC_MODE_LINK_POLARITY;
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
|
||||
tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
|
||||
mac_mode |= MAC_MODE_PORT_MODE_MII;
|
||||
} else
|
||||
mac_mode |= MAC_MODE_PORT_MODE_GMII;
|
||||
|
||||
/* reset to prevent losing 1st rx packet intermittently */
|
||||
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
|
||||
@ -8799,12 +8816,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
|
||||
udelay(10);
|
||||
tw32_f(MAC_RX_MODE, tp->rx_mode);
|
||||
}
|
||||
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
|
||||
MAC_MODE_LINK_POLARITY;
|
||||
if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
|
||||
mac_mode |= MAC_MODE_PORT_MODE_MII;
|
||||
else
|
||||
mac_mode |= MAC_MODE_PORT_MODE_GMII;
|
||||
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
|
||||
mac_mode &= ~MAC_MODE_LINK_POLARITY;
|
||||
tg3_writephy(tp, MII_TG3_EXT_CTRL,
|
||||
@ -9456,16 +9467,12 @@ static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
|
||||
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
|
||||
static void __devinit tg3_nvram_init(struct tg3 *tp)
|
||||
{
|
||||
int j;
|
||||
|
||||
tw32_f(GRC_EEPROM_ADDR,
|
||||
(EEPROM_ADDR_FSM_RESET |
|
||||
(EEPROM_DEFAULT_CLOCK_PERIOD <<
|
||||
EEPROM_ADDR_CLKPERD_SHIFT)));
|
||||
|
||||
/* XXX schedule_timeout() ... */
|
||||
for (j = 0; j < 100; j++)
|
||||
udelay(10);
|
||||
msleep(1);
|
||||
|
||||
/* Enable seeprom accesses. */
|
||||
tw32_f(GRC_LOCAL_CTRL,
|
||||
@ -9526,12 +9533,12 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
|
||||
EEPROM_ADDR_ADDR_MASK) |
|
||||
EEPROM_ADDR_READ | EEPROM_ADDR_START);
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
for (i = 0; i < 1000; i++) {
|
||||
tmp = tr32(GRC_EEPROM_ADDR);
|
||||
|
||||
if (tmp & EEPROM_ADDR_COMPLETE)
|
||||
break;
|
||||
udelay(100);
|
||||
msleep(1);
|
||||
}
|
||||
if (!(tmp & EEPROM_ADDR_COMPLETE))
|
||||
return -EBUSY;
|
||||
@ -9656,12 +9663,12 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
|
||||
EEPROM_ADDR_START |
|
||||
EEPROM_ADDR_WRITE);
|
||||
|
||||
for (j = 0; j < 10000; j++) {
|
||||
for (j = 0; j < 1000; j++) {
|
||||
val = tr32(GRC_EEPROM_ADDR);
|
||||
|
||||
if (val & EEPROM_ADDR_COMPLETE)
|
||||
break;
|
||||
udelay(100);
|
||||
msleep(1);
|
||||
}
|
||||
if (!(val & EEPROM_ADDR_COMPLETE)) {
|
||||
rc = -EBUSY;
|
||||
@ -9965,8 +9972,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
|
||||
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
|
||||
if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM))
|
||||
if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) {
|
||||
tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
|
||||
tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10066,10 +10075,17 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
|
||||
tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
|
||||
tp->led_ctrl = LED_CTRL_MODE_PHY_2;
|
||||
|
||||
if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)
|
||||
if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
|
||||
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
|
||||
else
|
||||
if ((tp->pdev->subsystem_vendor ==
|
||||
PCI_VENDOR_ID_ARIMA) &&
|
||||
(tp->pdev->subsystem_device == 0x205a ||
|
||||
tp->pdev->subsystem_device == 0x2063))
|
||||
tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
|
||||
} else {
|
||||
tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
|
||||
tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
|
||||
}
|
||||
|
||||
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
|
||||
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
|
||||
@ -10147,7 +10163,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
|
||||
|
||||
if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) &&
|
||||
!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
|
||||
u32 bmsr, adv_reg, tg3_ctrl;
|
||||
u32 bmsr, adv_reg, tg3_ctrl, mask;
|
||||
|
||||
tg3_readphy(tp, MII_BMSR, &bmsr);
|
||||
if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
|
||||
@ -10171,7 +10187,10 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
|
||||
MII_TG3_CTRL_ENABLE_AS_MASTER);
|
||||
}
|
||||
|
||||
if (!tg3_copper_is_advertising_all(tp)) {
|
||||
mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
|
||||
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
|
||||
ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
|
||||
if (!tg3_copper_is_advertising_all(tp, mask)) {
|
||||
tg3_writephy(tp, MII_ADVERTISE, adv_reg);
|
||||
|
||||
if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
|
||||
@ -10695,7 +10714,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
|
||||
|
||||
/* Get eeprom hw config before calling tg3_set_power_state().
|
||||
* In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
|
||||
* In particular, the TG3_FLG2_IS_NIC flag must be
|
||||
* determined before calling tg3_set_power_state() so that
|
||||
* we know whether or not to switch out of Vaux power.
|
||||
* When the flag is set, it means that GPIO1 is used for eeprom
|
||||
@ -10862,7 +10881,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
|
||||
(tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
|
||||
(tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
|
||||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) ||
|
||||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
|
||||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
|
||||
tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
|
||||
|
||||
@ -11912,13 +11932,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ",
|
||||
printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ",
|
||||
dev->name,
|
||||
tp->board_part_number,
|
||||
tp->pci_chip_rev_id,
|
||||
tg3_phy_string(tp),
|
||||
tg3_bus_string(tp, str),
|
||||
(tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000");
|
||||
((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
|
||||
((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
|
||||
"10/100/1000Base-T")));
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%2.2x%c", dev->dev_addr[i],
|
||||
|
@ -2233,6 +2233,7 @@ struct tg3 {
|
||||
#define TG3_FLG2_PCI_EXPRESS 0x00000200
|
||||
#define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400
|
||||
#define TG3_FLG2_HW_AUTONEG 0x00000800
|
||||
#define TG3_FLG2_IS_NIC 0x00001000
|
||||
#define TG3_FLG2_PHY_SERDES 0x00002000
|
||||
#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000
|
||||
#define TG3_FLG2_FLASH 0x00008000
|
||||
|
80
include/crypto/b128ops.h
Normal file
80
include/crypto/b128ops.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* b128ops.h - common 128-bit block operations
|
||||
*
|
||||
* Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.
|
||||
* Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* Based on Dr Brian Gladman's (GPL'd) work published at
|
||||
* http://fp.gladman.plus.com/cryptography_technology/index.htm
|
||||
* See the original copyright notice below.
|
||||
*
|
||||
* 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) 2003, Dr Brian Gladman, 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.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 13/06/2006
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_B128OPS_H
|
||||
#define _CRYPTO_B128OPS_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef struct {
|
||||
u64 a, b;
|
||||
} u128;
|
||||
|
||||
typedef struct {
|
||||
__be64 a, b;
|
||||
} be128;
|
||||
|
||||
typedef struct {
|
||||
__le64 b, a;
|
||||
} le128;
|
||||
|
||||
static inline void u128_xor(u128 *r, const u128 *p, const u128 *q)
|
||||
{
|
||||
r->a = p->a ^ q->a;
|
||||
r->b = p->b ^ q->b;
|
||||
}
|
||||
|
||||
static inline void be128_xor(be128 *r, const be128 *p, const be128 *q)
|
||||
{
|
||||
u128_xor((u128 *)r, (u128 *)p, (u128 *)q);
|
||||
}
|
||||
|
||||
static inline void le128_xor(le128 *r, const le128 *p, const le128 *q)
|
||||
{
|
||||
u128_xor((u128 *)r, (u128 *)p, (u128 *)q);
|
||||
}
|
||||
|
||||
#endif /* _CRYPTO_B128OPS_H */
|
198
include/crypto/gf128mul.h
Normal file
198
include/crypto/gf128mul.h
Normal file
@ -0,0 +1,198 @@
|
||||
/* gf128mul.h - GF(2^128) multiplication functions
|
||||
*
|
||||
* Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.
|
||||
* Copyright (c) 2006 Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* Based on Dr Brian Gladman's (GPL'd) work published at
|
||||
* http://fp.gladman.plus.com/cryptography_technology/index.htm
|
||||
* See the original copyright notice below.
|
||||
*
|
||||
* 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) 2003, Dr Brian Gladman, 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.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 31/01/2006
|
||||
|
||||
An implementation of field multiplication in Galois Field GF(128)
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_GF128MUL_H
|
||||
#define _CRYPTO_GF128MUL_H
|
||||
|
||||
#include <crypto/b128ops.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Comment by Rik:
|
||||
*
|
||||
* For some background on GF(2^128) see for example: http://-
|
||||
* csrc.nist.gov/CryptoToolkit/modes/proposedmodes/gcm/gcm-revised-spec.pdf
|
||||
*
|
||||
* The elements of GF(2^128) := GF(2)[X]/(X^128-X^7-X^2-X^1-1) can
|
||||
* be mapped to computer memory in a variety of ways. Let's examine
|
||||
* three common cases.
|
||||
*
|
||||
* Take a look at the 16 binary octets below in memory order. The msb's
|
||||
* are left and the lsb's are right. char b[16] is an array and b[0] is
|
||||
* the first octet.
|
||||
*
|
||||
* 80000000 00000000 00000000 00000000 .... 00000000 00000000 00000000
|
||||
* b[0] b[1] b[2] b[3] b[13] b[14] b[15]
|
||||
*
|
||||
* Every bit is a coefficient of some power of X. We can store the bits
|
||||
* in every byte in little-endian order and the bytes themselves also in
|
||||
* little endian order. I will call this lle (little-little-endian).
|
||||
* The above buffer represents the polynomial 1, and X^7+X^2+X^1+1 looks
|
||||
* like 11100001 00000000 .... 00000000 = { 0xE1, 0x00, }.
|
||||
* This format was originally implemented in gf128mul and is used
|
||||
* in GCM (Galois/Counter mode) and in ABL (Arbitrary Block Length).
|
||||
*
|
||||
* Another convention says: store the bits in bigendian order and the
|
||||
* bytes also. This is bbe (big-big-endian). Now the buffer above
|
||||
* represents X^127. X^7+X^2+X^1+1 looks like 00000000 .... 10000111,
|
||||
* b[15] = 0x87 and the rest is 0. LRW uses this convention and bbe
|
||||
* is partly implemented.
|
||||
*
|
||||
* Both of the above formats are easy to implement on big-endian
|
||||
* machines.
|
||||
*
|
||||
* EME (which is patent encumbered) uses the ble format (bits are stored
|
||||
* in big endian order and the bytes in little endian). The above buffer
|
||||
* represents X^7 in this case and the primitive polynomial is b[0] = 0x87.
|
||||
*
|
||||
* The common machine word-size is smaller than 128 bits, so to make
|
||||
* an efficient implementation we must split into machine word sizes.
|
||||
* This file uses one 32bit for the moment. Machine endianness comes into
|
||||
* play. The lle format in relation to machine endianness is discussed
|
||||
* below by the original author of gf128mul Dr Brian Gladman.
|
||||
*
|
||||
* Let's look at the bbe and ble format on a little endian machine.
|
||||
*
|
||||
* bbe on a little endian machine u32 x[4]:
|
||||
*
|
||||
* MS x[0] LS MS x[1] LS
|
||||
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
* 103..96 111.104 119.112 127.120 71...64 79...72 87...80 95...88
|
||||
*
|
||||
* MS x[2] LS MS x[3] LS
|
||||
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
* 39...32 47...40 55...48 63...56 07...00 15...08 23...16 31...24
|
||||
*
|
||||
* ble on a little endian machine
|
||||
*
|
||||
* MS x[0] LS MS x[1] LS
|
||||
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
* 31...24 23...16 15...08 07...00 63...56 55...48 47...40 39...32
|
||||
*
|
||||
* MS x[2] LS MS x[3] LS
|
||||
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
* 95...88 87...80 79...72 71...64 127.120 199.112 111.104 103..96
|
||||
*
|
||||
* Multiplications in GF(2^128) are mostly bit-shifts, so you see why
|
||||
* ble (and lbe also) are easier to implement on a little-endian
|
||||
* machine than on a big-endian machine. The converse holds for bbe
|
||||
* and lle.
|
||||
*
|
||||
* Note: to have good alignment, it seems to me that it is sufficient
|
||||
* to keep elements of GF(2^128) in type u64[2]. On 32-bit wordsize
|
||||
* machines this will automatically aligned to wordsize and on a 64-bit
|
||||
* machine also.
|
||||
*/
|
||||
/* Multiply a GF128 field element by x. Field elements are held in arrays
|
||||
of bytes in which field bits 8n..8n + 7 are held in byte[n], with lower
|
||||
indexed bits placed in the more numerically significant bit positions
|
||||
within bytes.
|
||||
|
||||
On little endian machines the bit indexes translate into the bit
|
||||
positions within four 32-bit words in the following way
|
||||
|
||||
MS x[0] LS MS x[1] LS
|
||||
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
24...31 16...23 08...15 00...07 56...63 48...55 40...47 32...39
|
||||
|
||||
MS x[2] LS MS x[3] LS
|
||||
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
88...95 80...87 72...79 64...71 120.127 112.119 104.111 96..103
|
||||
|
||||
On big endian machines the bit indexes translate into the bit
|
||||
positions within four 32-bit words in the following way
|
||||
|
||||
MS x[0] LS MS x[1] LS
|
||||
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
00...07 08...15 16...23 24...31 32...39 40...47 48...55 56...63
|
||||
|
||||
MS x[2] LS MS x[3] LS
|
||||
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
|
||||
64...71 72...79 80...87 88...95 96..103 104.111 112.119 120.127
|
||||
*/
|
||||
|
||||
/* A slow generic version of gf_mul, implemented for lle and bbe
|
||||
* It multiplies a and b and puts the result in a */
|
||||
void gf128mul_lle(be128 *a, const be128 *b);
|
||||
|
||||
void gf128mul_bbe(be128 *a, const be128 *b);
|
||||
|
||||
|
||||
/* 4k table optimization */
|
||||
|
||||
struct gf128mul_4k {
|
||||
be128 t[256];
|
||||
};
|
||||
|
||||
struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g);
|
||||
struct gf128mul_4k *gf128mul_init_4k_bbe(const be128 *g);
|
||||
void gf128mul_4k_lle(be128 *a, struct gf128mul_4k *t);
|
||||
void gf128mul_4k_bbe(be128 *a, struct gf128mul_4k *t);
|
||||
|
||||
static inline void gf128mul_free_4k(struct gf128mul_4k *t)
|
||||
{
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
|
||||
/* 64k table optimization, implemented for lle and bbe */
|
||||
|
||||
struct gf128mul_64k {
|
||||
struct gf128mul_4k *t[16];
|
||||
};
|
||||
|
||||
/* first initialize with the constant factor with which you
|
||||
* want to multiply and then call gf128_64k_lle with the other
|
||||
* factor in the first argument, the table in the second and a
|
||||
* scratch register in the third. Afterwards *a = *r. */
|
||||
struct gf128mul_64k *gf128mul_init_64k_lle(const be128 *g);
|
||||
struct gf128mul_64k *gf128mul_init_64k_bbe(const be128 *g);
|
||||
void gf128mul_free_64k(struct gf128mul_64k *t);
|
||||
void gf128mul_64k_lle(be128 *a, struct gf128mul_64k *t);
|
||||
void gf128mul_64k_bbe(be128 *a, struct gf128mul_64k *t);
|
||||
|
||||
#endif /* _CRYPTO_GF128MUL_H */
|
@ -101,6 +101,10 @@
|
||||
#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */
|
||||
#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */
|
||||
#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */
|
||||
#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Add a XFRM state */
|
||||
#define AUDIT_MAC_IPSEC_DELSA 1412 /* Delete a XFRM state */
|
||||
#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Add a XFRM policy */
|
||||
#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Delete a XFRM policy */
|
||||
|
||||
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
|
||||
#define AUDIT_LAST_KERN_ANOM_MSG 1799
|
||||
@ -377,6 +381,7 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
|
||||
struct timespec *t, unsigned int *serial);
|
||||
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
|
||||
extern uid_t audit_get_loginuid(struct audit_context *ctx);
|
||||
extern void audit_log_task_context(struct audit_buffer *ab);
|
||||
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
||||
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
|
||||
extern int audit_bprm(struct linux_binprm *bprm);
|
||||
@ -449,6 +454,7 @@ extern int audit_n_rules;
|
||||
#define audit_inode_update(i) do { ; } while (0)
|
||||
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
|
||||
#define audit_get_loginuid(c) ({ -1; })
|
||||
#define audit_log_task_context(b) do { ; } while (0)
|
||||
#define audit_ipc_obj(i) ({ 0; })
|
||||
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
|
||||
#define audit_bprm(p) ({ 0; })
|
||||
|
@ -241,12 +241,8 @@ int crypto_unregister_alg(struct crypto_alg *alg);
|
||||
* Algorithm query interface.
|
||||
*/
|
||||
#ifdef CONFIG_CRYPTO
|
||||
int crypto_alg_available(const char *name, u32 flags)
|
||||
__deprecated_for_modules;
|
||||
int crypto_has_alg(const char *name, u32 type, u32 mask);
|
||||
#else
|
||||
static int crypto_alg_available(const char *name, u32 flags)
|
||||
__deprecated_for_modules;
|
||||
static inline int crypto_alg_available(const char *name, u32 flags)
|
||||
{
|
||||
return 0;
|
||||
@ -707,16 +703,6 @@ static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
|
||||
dst, src);
|
||||
}
|
||||
|
||||
void crypto_digest_init(struct crypto_tfm *tfm) __deprecated_for_modules;
|
||||
void crypto_digest_update(struct crypto_tfm *tfm,
|
||||
struct scatterlist *sg, unsigned int nsg)
|
||||
__deprecated_for_modules;
|
||||
void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
|
||||
__deprecated_for_modules;
|
||||
void crypto_digest_digest(struct crypto_tfm *tfm,
|
||||
struct scatterlist *sg, unsigned int nsg, u8 *out)
|
||||
__deprecated_for_modules;
|
||||
|
||||
static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm)
|
||||
{
|
||||
return (struct crypto_hash *)tfm;
|
||||
@ -729,14 +715,6 @@ static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm)
|
||||
return __crypto_hash_cast(tfm);
|
||||
}
|
||||
|
||||
static int crypto_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int keylen) __deprecated;
|
||||
static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return tfm->crt_hash.setkey(crypto_hash_cast(tfm), key, keylen);
|
||||
}
|
||||
|
||||
static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name,
|
||||
u32 type, u32 mask)
|
||||
{
|
||||
|
@ -17,6 +17,9 @@ struct genlmsghdr {
|
||||
#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
|
||||
|
||||
#define GENL_ADMIN_PERM 0x01
|
||||
#define GENL_CMD_CAP_DO 0x02
|
||||
#define GENL_CMD_CAP_DUMP 0x04
|
||||
#define GENL_CMD_CAP_HASPOL 0x08
|
||||
|
||||
/*
|
||||
* List of reserved static generic netlink identifiers:
|
||||
@ -58,9 +61,6 @@ enum {
|
||||
CTRL_ATTR_OP_UNSPEC,
|
||||
CTRL_ATTR_OP_ID,
|
||||
CTRL_ATTR_OP_FLAGS,
|
||||
CTRL_ATTR_OP_POLICY,
|
||||
CTRL_ATTR_OP_DOIT,
|
||||
CTRL_ATTR_OP_DUMPIT,
|
||||
__CTRL_ATTR_OP_MAX,
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#ifndef _NF_CONNTRACK_PPTP_H
|
||||
#define _NF_CONNTRACK_PPTP_H
|
||||
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
|
||||
/* state of the control session */
|
||||
enum pptp_ctrlsess_state {
|
||||
PPTP_SESSION_NONE, /* no session present */
|
||||
@ -295,7 +297,6 @@ union pptp_ctrl_union {
|
||||
/* crap needed for nf_conntrack_compat.h */
|
||||
struct nf_conn;
|
||||
struct nf_conntrack_expect;
|
||||
enum ip_conntrack_info;
|
||||
|
||||
extern int
|
||||
(*nf_nat_pptp_hook_outbound)(struct sk_buff **pskb,
|
||||
|
@ -1931,6 +1931,7 @@
|
||||
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
|
||||
#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
|
||||
#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
|
||||
#define PCI_DEVICE_ID_TIGON3_5787F 0x167f
|
||||
#define PCI_DEVICE_ID_TIGON3_5787M 0x1693
|
||||
#define PCI_DEVICE_ID_TIGON3_5782 0x1696
|
||||
#define PCI_DEVICE_ID_TIGON3_5786 0x169a
|
||||
@ -2002,6 +2003,8 @@
|
||||
#define PCI_DEVICE_ID_FARSITE_TE1 0x1610
|
||||
#define PCI_DEVICE_ID_FARSITE_TE1C 0x1612
|
||||
|
||||
#define PCI_VENDOR_ID_ARIMA 0x161f
|
||||
|
||||
#define PCI_VENDOR_ID_SIBYTE 0x166d
|
||||
#define PCI_DEVICE_ID_BCM1250_PCI 0x0001
|
||||
#define PCI_DEVICE_ID_BCM1250_HT 0x0002
|
||||
|
@ -285,6 +285,7 @@ struct sadb_x_sec_ctx {
|
||||
#define SADB_X_AALG_SHA2_384HMAC 6
|
||||
#define SADB_X_AALG_SHA2_512HMAC 7
|
||||
#define SADB_X_AALG_RIPEMD160HMAC 8
|
||||
#define SADB_X_AALG_AES_XCBC_MAC 9
|
||||
#define SADB_X_AALG_NULL 251 /* kame */
|
||||
#define SADB_AALG_MAX 251
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
void irlan_check_command_param(struct irlan_cb *self, char *param,
|
||||
char *value);
|
||||
void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
void irlan_print_filter(struct seq_file *seq, int filter_type);
|
||||
#endif
|
||||
|
||||
#endif /* IRLAN_FILTER_H */
|
||||
|
@ -392,6 +392,20 @@ extern int xfrm_unregister_km(struct xfrm_mgr *km);
|
||||
|
||||
extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
|
||||
|
||||
/* Audit Information */
|
||||
struct xfrm_audit
|
||||
{
|
||||
uid_t loginuid;
|
||||
u32 secid;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
|
||||
struct xfrm_policy *xp, struct xfrm_state *x);
|
||||
#else
|
||||
#define xfrm_audit_log(a,s,t,r,p,x) do { ; } while (0)
|
||||
#endif /* CONFIG_AUDITSYSCALL */
|
||||
|
||||
static inline void xfrm_pol_hold(struct xfrm_policy *policy)
|
||||
{
|
||||
if (likely(policy != NULL))
|
||||
@ -906,7 +920,7 @@ static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **s
|
||||
#endif
|
||||
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
|
||||
extern int xfrm_state_delete(struct xfrm_state *x);
|
||||
extern void xfrm_state_flush(u8 proto);
|
||||
extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
|
||||
extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
|
||||
extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
|
||||
extern void xfrm_replay_notify(struct xfrm_state *x, int event);
|
||||
@ -959,13 +973,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
|
||||
struct xfrm_selector *sel,
|
||||
struct xfrm_sec_ctx *ctx, int delete);
|
||||
struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
|
||||
void xfrm_policy_flush(u8 type);
|
||||
void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
|
||||
u32 xfrm_get_acqseq(void);
|
||||
void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
|
||||
struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
|
||||
xfrm_address_t *daddr, xfrm_address_t *saddr,
|
||||
struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
|
||||
xfrm_address_t *daddr, xfrm_address_t *saddr,
|
||||
int create, unsigned short family);
|
||||
extern void xfrm_policy_flush(u8 type);
|
||||
extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
|
||||
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
|
||||
extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
|
||||
struct flowi *fl, int family, int strict);
|
||||
|
@ -731,7 +731,7 @@ static inline void audit_free_context(struct audit_context *context)
|
||||
printk(KERN_ERR "audit: freed %d contexts\n", count);
|
||||
}
|
||||
|
||||
static void audit_log_task_context(struct audit_buffer *ab)
|
||||
void audit_log_task_context(struct audit_buffer *ab)
|
||||
{
|
||||
char *ctx = NULL;
|
||||
ssize_t len = 0;
|
||||
@ -760,6 +760,8 @@ error_path:
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(audit_log_task_context);
|
||||
|
||||
static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
|
||||
{
|
||||
char name[sizeof(tsk->comm)];
|
||||
@ -1488,6 +1490,8 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
|
||||
return ctx ? ctx->loginuid : -1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(audit_get_loginuid);
|
||||
|
||||
/**
|
||||
* __audit_mq_open - record audit data for a POSIX MQ open
|
||||
* @oflag: open flag
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
#include <linux/in_route.h>
|
||||
#include <linux/inetdevice.h>
|
||||
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
@ -221,10 +222,14 @@ static void __br_dnat_complain(void)
|
||||
*
|
||||
* Otherwise, the packet is considered to be routed and we just
|
||||
* change the destination MAC address so that the packet will
|
||||
* later be passed up to the IP stack to be routed.
|
||||
* later be passed up to the IP stack to be routed. For a redirected
|
||||
* packet, ip_route_input() will give back the localhost as output device,
|
||||
* which differs from the bridge device.
|
||||
*
|
||||
* Let us now consider the case that ip_route_input() fails:
|
||||
*
|
||||
* This can be because the destination address is martian, in which case
|
||||
* the packet will be dropped.
|
||||
* After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
|
||||
* will fail, while __ip_route_output_key() will return success. The source
|
||||
* address for __ip_route_output_key() is set to zero, so __ip_route_output_key
|
||||
@ -237,7 +242,8 @@ static void __br_dnat_complain(void)
|
||||
*
|
||||
* --Lennert, 20020411
|
||||
* --Bart, 20020416 (updated)
|
||||
* --Bart, 20021007 (updated) */
|
||||
* --Bart, 20021007 (updated)
|
||||
* --Bart, 20062711 (updated) */
|
||||
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
|
||||
{
|
||||
if (skb->pkt_type == PACKET_OTHERHOST) {
|
||||
@ -264,15 +270,15 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
|
||||
struct net_device *dev = skb->dev;
|
||||
struct iphdr *iph = skb->nh.iph;
|
||||
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||
int err;
|
||||
|
||||
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->mask ^= BRNF_PKT_TYPE;
|
||||
}
|
||||
nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
|
||||
|
||||
if (dnat_took_place(skb)) {
|
||||
if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) {
|
||||
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
|
||||
struct rtable *rt;
|
||||
struct flowi fl = {
|
||||
.nl_u = {
|
||||
@ -283,19 +289,33 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
|
||||
},
|
||||
.proto = 0,
|
||||
};
|
||||
struct in_device *in_dev = in_dev_get(dev);
|
||||
|
||||
/* If err equals -EHOSTUNREACH the error is due to a
|
||||
* martian destination or due to the fact that
|
||||
* forwarding is disabled. For most martian packets,
|
||||
* ip_route_output_key() will fail. It won't fail for 2 types of
|
||||
* martian destinations: loopback destinations and destination
|
||||
* 0.0.0.0. In both cases the packet will be dropped because the
|
||||
* destination is the loopback device and not the bridge. */
|
||||
if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
|
||||
goto free_skb;
|
||||
|
||||
if (!ip_route_output_key(&rt, &fl)) {
|
||||
/* - Bridged-and-DNAT'ed traffic doesn't
|
||||
* require ip_forwarding.
|
||||
* - Deal with redirected traffic. */
|
||||
if (((struct dst_entry *)rt)->dev == dev ||
|
||||
rt->rt_type == RTN_LOCAL) {
|
||||
* require ip_forwarding. */
|
||||
if (((struct dst_entry *)rt)->dev == dev) {
|
||||
skb->dst = (struct dst_entry *)rt;
|
||||
goto bridged_dnat;
|
||||
}
|
||||
/* we are sure that forwarding is disabled, so printing
|
||||
* this message is no problem. Note that the packet could
|
||||
* still have a martian destination address, in which case
|
||||
* the packet could be dropped even if forwarding were enabled */
|
||||
__br_dnat_complain();
|
||||
dst_release((struct dst_entry *)rt);
|
||||
}
|
||||
free_skb:
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -2130,7 +2130,7 @@ int iw_handler_set_spy(struct net_device * dev,
|
||||
* The rtnl_lock() make sure we don't race with the other iw_handlers.
|
||||
* This make sure wireless_spy_update() "see" that the spy list
|
||||
* is temporarily disabled. */
|
||||
wmb();
|
||||
smp_wmb();
|
||||
|
||||
/* Are there are addresses to copy? */
|
||||
if(wrqu->data.length > 0) {
|
||||
@ -2159,7 +2159,7 @@ int iw_handler_set_spy(struct net_device * dev,
|
||||
}
|
||||
|
||||
/* Make sure above is updated before re-enabling */
|
||||
wmb();
|
||||
smp_wmb();
|
||||
|
||||
/* Enable addresses */
|
||||
spydata->spy_number = wrqu->data.length;
|
||||
|
@ -178,7 +178,6 @@ void inet_twdr_hangman(unsigned long data)
|
||||
need_timer = 0;
|
||||
if (inet_twdr_do_twkill_work(twdr, twdr->slot)) {
|
||||
twdr->thread_slots |= (1 << twdr->slot);
|
||||
mb();
|
||||
schedule_work(&twdr->twkill_work);
|
||||
need_timer = 1;
|
||||
} else {
|
||||
|
@ -375,6 +375,13 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
&& unconditional(&e->arp)) {
|
||||
unsigned int oldpos, size;
|
||||
|
||||
if (t->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("mark_source_chains: bad "
|
||||
"negative verdict (%i)\n",
|
||||
t->verdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return: backtrack through the last
|
||||
* big jump.
|
||||
*/
|
||||
@ -404,6 +411,14 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
if (strcmp(t->target.u.user.name,
|
||||
ARPT_STANDARD_TARGET) == 0
|
||||
&& newpos >= 0) {
|
||||
if (newpos > newinfo->size -
|
||||
sizeof(struct arpt_entry)) {
|
||||
duprintf("mark_source_chains: "
|
||||
"bad verdict (%i)\n",
|
||||
newpos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This a jump; chase it. */
|
||||
duprintf("Jump rule %u -> %u\n",
|
||||
pos, newpos);
|
||||
@ -426,8 +441,6 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
static inline int standard_check(const struct arpt_entry_target *t,
|
||||
unsigned int max_offset)
|
||||
{
|
||||
struct arpt_standard_target *targ = (void *)t;
|
||||
|
||||
/* Check standard info. */
|
||||
if (t->u.target_size
|
||||
!= ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
|
||||
@ -437,18 +450,6 @@ static inline int standard_check(const struct arpt_entry_target *t,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (targ->verdict >= 0
|
||||
&& targ->verdict > max_offset - sizeof(struct arpt_entry)) {
|
||||
duprintf("arpt_standard_check: bad verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (targ->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("arpt_standard_check: bad negative verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -627,18 +628,20 @@ static int translate_table(const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
|
||||
duprintf("Looping hook\n");
|
||||
return -ELOOP;
|
||||
}
|
||||
|
||||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
check_entry, name, size, &i);
|
||||
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = -ELOOP;
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
|
||||
duprintf("Looping hook\n");
|
||||
goto cleanup;
|
||||
if (ret != 0) {
|
||||
ARPT_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* And one copy for every other CPU */
|
||||
@ -647,9 +650,6 @@ static int translate_table(const char *name,
|
||||
memcpy(newinfo->entries[i], entry0, newinfo->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -401,6 +401,13 @@ mark_source_chains(struct xt_table_info *newinfo,
|
||||
&& unconditional(&e->ip)) {
|
||||
unsigned int oldpos, size;
|
||||
|
||||
if (t->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("mark_source_chains: bad "
|
||||
"negative verdict (%i)\n",
|
||||
t->verdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return: backtrack through the last
|
||||
big jump. */
|
||||
do {
|
||||
@ -438,6 +445,13 @@ mark_source_chains(struct xt_table_info *newinfo,
|
||||
if (strcmp(t->target.u.user.name,
|
||||
IPT_STANDARD_TARGET) == 0
|
||||
&& newpos >= 0) {
|
||||
if (newpos > newinfo->size -
|
||||
sizeof(struct ipt_entry)) {
|
||||
duprintf("mark_source_chains: "
|
||||
"bad verdict (%i)\n",
|
||||
newpos);
|
||||
return 0;
|
||||
}
|
||||
/* This a jump; chase it. */
|
||||
duprintf("Jump rule %u -> %u\n",
|
||||
pos, newpos);
|
||||
@ -469,27 +483,6 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
standard_check(const struct ipt_entry_target *t,
|
||||
unsigned int max_offset)
|
||||
{
|
||||
struct ipt_standard_target *targ = (void *)t;
|
||||
|
||||
/* Check standard info. */
|
||||
if (targ->verdict >= 0
|
||||
&& targ->verdict > max_offset - sizeof(struct ipt_entry)) {
|
||||
duprintf("ipt_standard_check: bad verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
if (targ->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("ipt_standard_check: bad negative verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_match(struct ipt_entry_match *m,
|
||||
const char *name,
|
||||
@ -576,12 +569,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (t->u.kernel.target == &ipt_standard_target) {
|
||||
if (!standard_check(t, size)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
} else if (t->u.kernel.target->checkentry
|
||||
if (t->u.kernel.target->checkentry
|
||||
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
|
||||
e->comefrom)) {
|
||||
duprintf("ip_tables: check failed for `%s'.\n",
|
||||
@ -718,17 +706,19 @@ translate_table(const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0))
|
||||
return -ELOOP;
|
||||
|
||||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
check_entry, name, size, &i);
|
||||
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = -ELOOP;
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0))
|
||||
goto cleanup;
|
||||
if (ret != 0) {
|
||||
IPT_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* And one copy for every other CPU */
|
||||
for_each_possible_cpu(i) {
|
||||
@ -736,9 +726,6 @@ translate_table(const char *name,
|
||||
memcpy(newinfo->entries[i], entry0, newinfo->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1529,25 +1516,8 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
|
||||
void **dstptr, compat_uint_t *size, const char *name,
|
||||
const struct ipt_ip *ip, unsigned int hookmask)
|
||||
{
|
||||
struct ipt_entry_match *dm;
|
||||
struct ipt_match *match;
|
||||
int ret;
|
||||
|
||||
dm = (struct ipt_entry_match *)*dstptr;
|
||||
match = m->u.kernel.match;
|
||||
xt_compat_match_from_user(m, dstptr, size);
|
||||
|
||||
ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
|
||||
name, hookmask, ip->proto,
|
||||
ip->invflags & IPT_INV_PROTO);
|
||||
if (!ret && m->u.kernel.match->checkentry
|
||||
&& !m->u.kernel.match->checkentry(name, ip, match, dm->data,
|
||||
hookmask)) {
|
||||
duprintf("ip_tables: check failed for `%s'.\n",
|
||||
m->u.kernel.match->name);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
|
||||
@ -1569,7 +1539,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
|
||||
ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
|
||||
name, &de->ip, de->comefrom);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
de->target_offset = e->target_offset - (origsize - *size);
|
||||
t = ipt_get_target(e);
|
||||
target = t->u.kernel.target;
|
||||
@ -1582,31 +1552,62 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
|
||||
if ((unsigned char *)de - base < newinfo->underflow[h])
|
||||
newinfo->underflow[h] -= origsize - *size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
t = ipt_get_target(de);
|
||||
static inline int compat_check_match(struct ipt_entry_match *m, const char *name,
|
||||
const struct ipt_ip *ip, unsigned int hookmask)
|
||||
{
|
||||
struct ipt_match *match;
|
||||
int ret;
|
||||
|
||||
match = m->u.kernel.match;
|
||||
ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
|
||||
name, hookmask, ip->proto,
|
||||
ip->invflags & IPT_INV_PROTO);
|
||||
if (!ret && m->u.kernel.match->checkentry
|
||||
&& !m->u.kernel.match->checkentry(name, ip, match, m->data,
|
||||
hookmask)) {
|
||||
duprintf("ip_tables: compat: check failed for `%s'.\n",
|
||||
m->u.kernel.match->name);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int compat_check_target(struct ipt_entry *e, const char *name)
|
||||
{
|
||||
struct ipt_entry_target *t;
|
||||
struct ipt_target *target;
|
||||
int ret;
|
||||
|
||||
t = ipt_get_target(e);
|
||||
target = t->u.kernel.target;
|
||||
ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
|
||||
name, e->comefrom, e->ip.proto,
|
||||
e->ip.invflags & IPT_INV_PROTO);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (t->u.kernel.target == &ipt_standard_target) {
|
||||
if (!standard_check(t, *size))
|
||||
goto err;
|
||||
} else if (t->u.kernel.target->checkentry
|
||||
&& !t->u.kernel.target->checkentry(name, de, target,
|
||||
t->data, de->comefrom)) {
|
||||
if (!ret && t->u.kernel.target->checkentry
|
||||
&& !t->u.kernel.target->checkentry(name, e, target,
|
||||
t->data, e->comefrom)) {
|
||||
duprintf("ip_tables: compat: check failed for `%s'.\n",
|
||||
t->u.kernel.target->name);
|
||||
goto err;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
ret = 0;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int compat_check_entry(struct ipt_entry *e, const char *name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = IPT_MATCH_ITERATE(e, compat_check_match, name, &e->ip,
|
||||
e->comefrom);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return compat_check_target(e, name);
|
||||
}
|
||||
|
||||
static int
|
||||
translate_compat_table(const char *name,
|
||||
unsigned int valid_hooks,
|
||||
@ -1695,6 +1696,11 @@ translate_compat_table(const char *name,
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry1))
|
||||
goto free_newinfo;
|
||||
|
||||
ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
|
||||
name);
|
||||
if (ret)
|
||||
goto free_newinfo;
|
||||
|
||||
/* And one copy for every other CPU */
|
||||
for_each_possible_cpu(i)
|
||||
if (newinfo->entries[i] && newinfo->entries[i] != entry1)
|
||||
|
@ -1780,7 +1780,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
|
||||
#endif
|
||||
if (in_dev->cnf.no_policy)
|
||||
rth->u.dst.flags |= DST_NOPOLICY;
|
||||
if (in_dev->cnf.no_xfrm)
|
||||
if (out_dev->cnf.no_xfrm)
|
||||
rth->u.dst.flags |= DST_NOXFRM;
|
||||
rth->fl.fl4_dst = daddr;
|
||||
rth->rt_dst = daddr;
|
||||
|
@ -4235,7 +4235,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
* Change state from SYN-SENT only after copied_seq
|
||||
* is initialized. */
|
||||
tp->copied_seq = tp->rcv_nxt;
|
||||
mb();
|
||||
smp_mb();
|
||||
tcp_set_state(sk, TCP_ESTABLISHED);
|
||||
|
||||
security_inet_conn_established(sk, skb);
|
||||
@ -4483,7 +4483,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
|
||||
case TCP_SYN_RECV:
|
||||
if (acceptable) {
|
||||
tp->copied_seq = tp->rcv_nxt;
|
||||
mb();
|
||||
smp_mb();
|
||||
tcp_set_state(sk, TCP_ESTABLISHED);
|
||||
sk->sk_state_change(sk);
|
||||
|
||||
|
@ -274,6 +274,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
|
||||
|
||||
if (likely(xdst->u.rt.idev))
|
||||
in_dev_put(xdst->u.rt.idev);
|
||||
if (likely(xdst->u.rt.peer))
|
||||
inet_putpeer(xdst->u.rt.peer);
|
||||
xfrm_dst_destroy(xdst);
|
||||
}
|
||||
|
||||
|
@ -624,13 +624,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
||||
skb_shinfo(skb)->frag_list = NULL;
|
||||
/* BUILD HEADER */
|
||||
|
||||
*prevhdr = NEXTHDR_FRAGMENT;
|
||||
tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC);
|
||||
if (!tmp_hdr) {
|
||||
IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*prevhdr = NEXTHDR_FRAGMENT;
|
||||
__skb_pull(skb, hlen);
|
||||
fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
|
||||
skb->nh.raw = __skb_push(skb, hlen);
|
||||
|
@ -440,6 +440,13 @@ mark_source_chains(struct xt_table_info *newinfo,
|
||||
&& unconditional(&e->ipv6)) {
|
||||
unsigned int oldpos, size;
|
||||
|
||||
if (t->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("mark_source_chains: bad "
|
||||
"negative verdict (%i)\n",
|
||||
t->verdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return: backtrack through the last
|
||||
big jump. */
|
||||
do {
|
||||
@ -477,6 +484,13 @@ mark_source_chains(struct xt_table_info *newinfo,
|
||||
if (strcmp(t->target.u.user.name,
|
||||
IP6T_STANDARD_TARGET) == 0
|
||||
&& newpos >= 0) {
|
||||
if (newpos > newinfo->size -
|
||||
sizeof(struct ip6t_entry)) {
|
||||
duprintf("mark_source_chains: "
|
||||
"bad verdict (%i)\n",
|
||||
newpos);
|
||||
return 0;
|
||||
}
|
||||
/* This a jump; chase it. */
|
||||
duprintf("Jump rule %u -> %u\n",
|
||||
pos, newpos);
|
||||
@ -508,27 +522,6 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
standard_check(const struct ip6t_entry_target *t,
|
||||
unsigned int max_offset)
|
||||
{
|
||||
struct ip6t_standard_target *targ = (void *)t;
|
||||
|
||||
/* Check standard info. */
|
||||
if (targ->verdict >= 0
|
||||
&& targ->verdict > max_offset - sizeof(struct ip6t_entry)) {
|
||||
duprintf("ip6t_standard_check: bad verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
if (targ->verdict < -NF_MAX_VERDICT - 1) {
|
||||
duprintf("ip6t_standard_check: bad negative verdict (%i)\n",
|
||||
targ->verdict);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_match(struct ip6t_entry_match *m,
|
||||
const char *name,
|
||||
@ -616,12 +609,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (t->u.kernel.target == &ip6t_standard_target) {
|
||||
if (!standard_check(t, size)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
} else if (t->u.kernel.target->checkentry
|
||||
if (t->u.kernel.target->checkentry
|
||||
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
|
||||
e->comefrom)) {
|
||||
duprintf("ip_tables: check failed for `%s'.\n",
|
||||
@ -758,17 +746,19 @@ translate_table(const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0))
|
||||
return -ELOOP;
|
||||
|
||||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
check_entry, name, size, &i);
|
||||
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = -ELOOP;
|
||||
if (!mark_source_chains(newinfo, valid_hooks, entry0))
|
||||
goto cleanup;
|
||||
if (ret != 0) {
|
||||
IP6T_ENTRY_ITERATE(entry0, newinfo->size,
|
||||
cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* And one copy for every other CPU */
|
||||
for_each_possible_cpu(i) {
|
||||
@ -777,9 +767,6 @@ translate_table(const char *name,
|
||||
}
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Gets counters. */
|
||||
|
@ -854,7 +854,8 @@ back_from_confirm:
|
||||
}
|
||||
done:
|
||||
dst_release(dst);
|
||||
release_sock(sk);
|
||||
if (!inet->hdrincl)
|
||||
release_sock(sk);
|
||||
out:
|
||||
fl6_sock_release(flowlabel);
|
||||
return err<0?err:len;
|
||||
|
@ -1100,7 +1100,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
|
||||
return -ENOMEM;
|
||||
|
||||
/* Reserve space for MUX_CONTROL and LAP header */
|
||||
skb_reserve(tx_skb, TTP_MAX_HEADER);
|
||||
skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
|
||||
} else {
|
||||
tx_skb = userdata;
|
||||
/*
|
||||
@ -1349,7 +1349,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
|
||||
return -ENOMEM;
|
||||
|
||||
/* Reserve space for MUX_CONTROL and LAP header */
|
||||
skb_reserve(tx_skb, TTP_MAX_HEADER);
|
||||
skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
|
||||
} else {
|
||||
tx_skb = userdata;
|
||||
/*
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <net/xfrm.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
@ -1420,6 +1421,9 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||
else
|
||||
err = xfrm_state_update(x);
|
||||
|
||||
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
|
||||
AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
|
||||
|
||||
if (err < 0) {
|
||||
x->km.state = XFRM_STATE_DEAD;
|
||||
__xfrm_state_put(x);
|
||||
@ -1460,8 +1464,12 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
err = xfrm_state_delete(x);
|
||||
|
||||
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
|
||||
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
|
||||
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
@ -1637,12 +1645,15 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
|
||||
{
|
||||
unsigned proto;
|
||||
struct km_event c;
|
||||
struct xfrm_audit audit_info;
|
||||
|
||||
proto = pfkey_satype2proto(hdr->sadb_msg_satype);
|
||||
if (proto == 0)
|
||||
return -EINVAL;
|
||||
|
||||
xfrm_state_flush(proto);
|
||||
audit_info.loginuid = audit_get_loginuid(current->audit_context);
|
||||
audit_info.secid = 0;
|
||||
xfrm_state_flush(proto, &audit_info);
|
||||
c.data.proto = proto;
|
||||
c.seq = hdr->sadb_msg_seq;
|
||||
c.pid = hdr->sadb_msg_pid;
|
||||
@ -2205,6 +2216,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
|
||||
err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
|
||||
hdr->sadb_msg_type != SADB_X_SPDUPDATE);
|
||||
|
||||
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
|
||||
AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -2282,6 +2296,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
|
||||
xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1,
|
||||
&sel, tmp.security, 1);
|
||||
security_xfrm_policy_free(&tmp);
|
||||
|
||||
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
|
||||
AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
|
||||
|
||||
if (xp == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
@ -2416,8 +2434,11 @@ static int key_notify_policy_flush(struct km_event *c)
|
||||
static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
|
||||
{
|
||||
struct km_event c;
|
||||
struct xfrm_audit audit_info;
|
||||
|
||||
xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN);
|
||||
audit_info.loginuid = audit_get_loginuid(current->audit_context);
|
||||
audit_info.secid = 0;
|
||||
xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
|
||||
c.data.type = XFRM_POLICY_TYPE_MAIN;
|
||||
c.event = XFRM_MSG_FLUSHPOLICY;
|
||||
c.pid = hdr->sadb_msg_pid;
|
||||
|
@ -1093,7 +1093,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
|
||||
get_order(sizeof(struct list_head) * size));
|
||||
}
|
||||
|
||||
void nf_conntrack_flush()
|
||||
void nf_conntrack_flush(void)
|
||||
{
|
||||
nf_ct_iterate_cleanup(kill_all, NULL);
|
||||
}
|
||||
|
@ -91,25 +91,28 @@ EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get);
|
||||
struct nf_conntrack_expect *
|
||||
find_expectation(const struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
struct nf_conntrack_expect *i;
|
||||
struct nf_conntrack_expect *exp;
|
||||
|
||||
exp = __nf_conntrack_expect_find(tuple);
|
||||
if (!exp)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(i, &nf_conntrack_expect_list, list) {
|
||||
/* If master is not in hash table yet (ie. packet hasn't left
|
||||
this machine yet), how can other end know about expected?
|
||||
Hence these are not the droids you are looking for (if
|
||||
master ct never got confirmed, we'd hold a reference to it
|
||||
and weird things would happen to future packets). */
|
||||
if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
|
||||
&& nf_ct_is_confirmed(i->master)) {
|
||||
if (i->flags & NF_CT_EXPECT_PERMANENT) {
|
||||
atomic_inc(&i->use);
|
||||
return i;
|
||||
} else if (del_timer(&i->timeout)) {
|
||||
nf_ct_unlink_expect(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (!nf_ct_is_confirmed(exp->master))
|
||||
return NULL;
|
||||
|
||||
if (exp->flags & NF_CT_EXPECT_PERMANENT) {
|
||||
atomic_inc(&exp->use);
|
||||
return exp;
|
||||
} else if (del_timer(&exp->timeout)) {
|
||||
nf_ct_unlink_expect(exp);
|
||||
return exp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,13 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ops->dumpit)
|
||||
ops->flags |= GENL_CMD_CAP_DUMP;
|
||||
if (ops->doit)
|
||||
ops->flags |= GENL_CMD_CAP_DO;
|
||||
if (ops->policy)
|
||||
ops->flags |= GENL_CMD_CAP_HASPOL;
|
||||
|
||||
genl_lock();
|
||||
list_add_tail(&ops->ops_list, &family->ops_list);
|
||||
genl_unlock();
|
||||
@ -387,7 +394,7 @@ static void genl_rcv(struct sock *sk, int len)
|
||||
static struct genl_family genl_ctrl = {
|
||||
.id = GENL_ID_CTRL,
|
||||
.name = "nlctrl",
|
||||
.version = 0x1,
|
||||
.version = 0x2,
|
||||
.maxattr = CTRL_ATTR_MAX,
|
||||
};
|
||||
|
||||
@ -425,15 +432,6 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
|
||||
|
||||
if (ops->policy)
|
||||
NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY);
|
||||
|
||||
if (ops->doit)
|
||||
NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT);
|
||||
|
||||
if (ops->dumpit)
|
||||
NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT);
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
}
|
||||
|
||||
|
@ -660,7 +660,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
|
||||
sll->sll_ifindex = dev->ifindex;
|
||||
|
||||
h->tp_status = status;
|
||||
mb();
|
||||
smp_mb();
|
||||
|
||||
{
|
||||
struct page *p_start, *p_end;
|
||||
|
@ -101,9 +101,10 @@ static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
|
||||
struct fw_head *head = (struct fw_head*)tp->root;
|
||||
struct fw_filter *f;
|
||||
int r;
|
||||
u32 id = skb->mark & head->mask;
|
||||
u32 id = skb->mark;
|
||||
|
||||
if (head != NULL) {
|
||||
id &= head->mask;
|
||||
for (f=head->ht[fw_hash(id)]; f; f=f->next) {
|
||||
if (f->id == id) {
|
||||
*res = f->res;
|
||||
|
@ -62,63 +62,6 @@
|
||||
|
||||
#define KMEM_SAFETYZONE 8
|
||||
|
||||
/***********FOR DEBUGGING PURPOSES*********************************************
|
||||
static void * dbg_kmalloc(unsigned int size, int prio, int line) {
|
||||
int i = 0;
|
||||
void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
|
||||
char * c1 = v;
|
||||
c1 += sizeof(unsigned int);
|
||||
*((unsigned int *)v) = size;
|
||||
|
||||
for (i = 0; i < KMEM_SAFETYZONE; i++) {
|
||||
c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
|
||||
c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
|
||||
c1 += 8;
|
||||
}
|
||||
c1 += size;
|
||||
for (i = 0; i < KMEM_SAFETYZONE; i++) {
|
||||
c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
|
||||
c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
|
||||
c1 += 8;
|
||||
}
|
||||
v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
|
||||
printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v);
|
||||
return v;
|
||||
}
|
||||
static void dbg_kfree(void * v, int line) {
|
||||
unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
|
||||
unsigned int size = *sp;
|
||||
char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
|
||||
int i = 0;
|
||||
for (i = 0; i < KMEM_SAFETYZONE; i++) {
|
||||
if ( c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
|
||||
|| c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
|
||||
printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
|
||||
printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
|
||||
c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
|
||||
}
|
||||
c1 += 8;
|
||||
}
|
||||
c1 += size;
|
||||
for (i = 0; i < KMEM_SAFETYZONE; i++) {
|
||||
if ( c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
|
||||
|| c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
|
||||
) {
|
||||
printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
|
||||
printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
|
||||
c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
|
||||
}
|
||||
c1 += 8;
|
||||
}
|
||||
printk(KERN_INFO "line %d kfree(%p)\n",line,v);
|
||||
v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
|
||||
kfree(v);
|
||||
}
|
||||
|
||||
#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
|
||||
#define kfree(x) dbg_kfree(x,__LINE__)
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Function Prototypes
|
||||
*/
|
||||
|
@ -119,6 +119,23 @@ static struct xfrm_algo_desc aalg_list[] = {
|
||||
.sadb_alg_maxbits = 160
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "xcbc(aes)",
|
||||
|
||||
.uinfo = {
|
||||
.auth = {
|
||||
.icv_truncbits = 96,
|
||||
.icv_fullbits = 128,
|
||||
}
|
||||
},
|
||||
|
||||
.desc = {
|
||||
.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
|
||||
.sadb_alg_ivlen = 0,
|
||||
.sadb_alg_minbits = 128,
|
||||
.sadb_alg_maxbits = 128
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct xfrm_algo_desc ealg_list[] = {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/cache.h>
|
||||
#include <net/xfrm.h>
|
||||
#include <net/ip.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#include "xfrm_hash.h"
|
||||
|
||||
@ -804,7 +805,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_byid);
|
||||
|
||||
void xfrm_policy_flush(u8 type)
|
||||
void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
|
||||
{
|
||||
int dir;
|
||||
|
||||
@ -824,6 +825,9 @@ void xfrm_policy_flush(u8 type)
|
||||
hlist_del(&pol->byidx);
|
||||
write_unlock_bh(&xfrm_policy_lock);
|
||||
|
||||
xfrm_audit_log(audit_info->loginuid, audit_info->secid,
|
||||
AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL);
|
||||
|
||||
xfrm_policy_kill(pol);
|
||||
killed++;
|
||||
|
||||
@ -842,6 +846,11 @@ void xfrm_policy_flush(u8 type)
|
||||
hlist_del(&pol->byidx);
|
||||
write_unlock_bh(&xfrm_policy_lock);
|
||||
|
||||
xfrm_audit_log(audit_info->loginuid,
|
||||
audit_info->secid,
|
||||
AUDIT_MAC_IPSEC_DELSPD, 1,
|
||||
pol, NULL);
|
||||
|
||||
xfrm_policy_kill(pol);
|
||||
killed++;
|
||||
|
||||
@ -860,33 +869,12 @@ EXPORT_SYMBOL(xfrm_policy_flush);
|
||||
int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*),
|
||||
void *data)
|
||||
{
|
||||
struct xfrm_policy *pol;
|
||||
struct xfrm_policy *pol, *last = NULL;
|
||||
struct hlist_node *entry;
|
||||
int dir, count, error;
|
||||
int dir, last_dir = 0, count, error;
|
||||
|
||||
read_lock_bh(&xfrm_policy_lock);
|
||||
count = 0;
|
||||
for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
|
||||
struct hlist_head *table = xfrm_policy_bydst[dir].table;
|
||||
int i;
|
||||
|
||||
hlist_for_each_entry(pol, entry,
|
||||
&xfrm_policy_inexact[dir], bydst) {
|
||||
if (pol->type == type)
|
||||
count++;
|
||||
}
|
||||
for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
|
||||
hlist_for_each_entry(pol, entry, table + i, bydst) {
|
||||
if (pol->type == type)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
error = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
|
||||
struct hlist_head *table = xfrm_policy_bydst[dir].table;
|
||||
@ -896,21 +884,37 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*)
|
||||
&xfrm_policy_inexact[dir], bydst) {
|
||||
if (pol->type != type)
|
||||
continue;
|
||||
error = func(pol, dir % XFRM_POLICY_MAX, --count, data);
|
||||
if (error)
|
||||
goto out;
|
||||
if (last) {
|
||||
error = func(last, last_dir % XFRM_POLICY_MAX,
|
||||
count, data);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
last = pol;
|
||||
last_dir = dir;
|
||||
count++;
|
||||
}
|
||||
for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
|
||||
hlist_for_each_entry(pol, entry, table + i, bydst) {
|
||||
if (pol->type != type)
|
||||
continue;
|
||||
error = func(pol, dir % XFRM_POLICY_MAX, --count, data);
|
||||
if (error)
|
||||
goto out;
|
||||
if (last) {
|
||||
error = func(last, last_dir % XFRM_POLICY_MAX,
|
||||
count, data);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
last = pol;
|
||||
last_dir = dir;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
error = 0;
|
||||
if (count == 0) {
|
||||
error = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
error = func(last, last_dir % XFRM_POLICY_MAX, 0, data);
|
||||
out:
|
||||
read_unlock_bh(&xfrm_policy_lock);
|
||||
return error;
|
||||
@ -1982,6 +1986,117 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
|
||||
|
||||
EXPORT_SYMBOL(xfrm_bundle_ok);
|
||||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
/* Audit addition and deletion of SAs and ipsec policy */
|
||||
|
||||
void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
|
||||
struct xfrm_policy *xp, struct xfrm_state *x)
|
||||
{
|
||||
|
||||
char *secctx;
|
||||
u32 secctx_len;
|
||||
struct xfrm_sec_ctx *sctx = NULL;
|
||||
struct audit_buffer *audit_buf;
|
||||
int family;
|
||||
extern int audit_enabled;
|
||||
|
||||
if (audit_enabled == 0)
|
||||
return;
|
||||
|
||||
audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
|
||||
if (audit_buf == NULL)
|
||||
return;
|
||||
|
||||
switch(type) {
|
||||
case AUDIT_MAC_IPSEC_ADDSA:
|
||||
audit_log_format(audit_buf, "SAD add: auid=%u", auid);
|
||||
break;
|
||||
case AUDIT_MAC_IPSEC_DELSA:
|
||||
audit_log_format(audit_buf, "SAD delete: auid=%u", auid);
|
||||
break;
|
||||
case AUDIT_MAC_IPSEC_ADDSPD:
|
||||
audit_log_format(audit_buf, "SPD add: auid=%u", auid);
|
||||
break;
|
||||
case AUDIT_MAC_IPSEC_DELSPD:
|
||||
audit_log_format(audit_buf, "SPD delete: auid=%u", auid);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (sid != 0 &&
|
||||
security_secid_to_secctx(sid, &secctx, &secctx_len) == 0)
|
||||
audit_log_format(audit_buf, " subj=%s", secctx);
|
||||
else
|
||||
audit_log_task_context(audit_buf);
|
||||
|
||||
if (xp) {
|
||||
family = xp->selector.family;
|
||||
if (xp->security)
|
||||
sctx = xp->security;
|
||||
} else {
|
||||
family = x->props.family;
|
||||
if (x->security)
|
||||
sctx = x->security;
|
||||
}
|
||||
|
||||
if (sctx)
|
||||
audit_log_format(audit_buf,
|
||||
" sec_alg=%u sec_doi=%u sec_obj=%s",
|
||||
sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
|
||||
|
||||
switch(family) {
|
||||
case AF_INET:
|
||||
{
|
||||
struct in_addr saddr, daddr;
|
||||
if (xp) {
|
||||
saddr.s_addr = xp->selector.saddr.a4;
|
||||
daddr.s_addr = xp->selector.daddr.a4;
|
||||
} else {
|
||||
saddr.s_addr = x->props.saddr.a4;
|
||||
daddr.s_addr = x->id.daddr.a4;
|
||||
}
|
||||
audit_log_format(audit_buf,
|
||||
" src=%u.%u.%u.%u dst=%u.%u.%u.%u",
|
||||
NIPQUAD(saddr), NIPQUAD(daddr));
|
||||
}
|
||||
break;
|
||||
case AF_INET6:
|
||||
{
|
||||
struct in6_addr saddr6, daddr6;
|
||||
if (xp) {
|
||||
memcpy(&saddr6, xp->selector.saddr.a6,
|
||||
sizeof(struct in6_addr));
|
||||
memcpy(&daddr6, xp->selector.daddr.a6,
|
||||
sizeof(struct in6_addr));
|
||||
} else {
|
||||
memcpy(&saddr6, x->props.saddr.a6,
|
||||
sizeof(struct in6_addr));
|
||||
memcpy(&daddr6, x->id.daddr.a6,
|
||||
sizeof(struct in6_addr));
|
||||
}
|
||||
audit_log_format(audit_buf,
|
||||
" src=" NIP6_FMT "dst=" NIP6_FMT,
|
||||
NIP6(saddr6), NIP6(daddr6));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (x)
|
||||
audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s",
|
||||
(unsigned long)ntohl(x->id.spi),
|
||||
(unsigned long)ntohl(x->id.spi),
|
||||
x->id.proto == IPPROTO_AH ? "AH" :
|
||||
(x->id.proto == IPPROTO_ESP ?
|
||||
"ESP" : "IPCOMP"));
|
||||
|
||||
audit_log_format(audit_buf, " res=%u", result);
|
||||
audit_log_end(audit_buf);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(xfrm_audit_log);
|
||||
#endif /* CONFIG_AUDITSYSCALL */
|
||||
|
||||
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/cache.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#include "xfrm_hash.h"
|
||||
|
||||
@ -238,6 +239,7 @@ static void xfrm_timer_handler(unsigned long data)
|
||||
unsigned long now = (unsigned long)xtime.tv_sec;
|
||||
long next = LONG_MAX;
|
||||
int warn = 0;
|
||||
int err = 0;
|
||||
|
||||
spin_lock(&x->lock);
|
||||
if (x->km.state == XFRM_STATE_DEAD)
|
||||
@ -295,9 +297,14 @@ expired:
|
||||
next = 2;
|
||||
goto resched;
|
||||
}
|
||||
if (!__xfrm_state_delete(x) && x->id.spi)
|
||||
|
||||
err = __xfrm_state_delete(x);
|
||||
if (!err && x->id.spi)
|
||||
km_state_expired(x, 1, 0);
|
||||
|
||||
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
|
||||
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
|
||||
|
||||
out:
|
||||
spin_unlock(&x->lock);
|
||||
}
|
||||
@ -384,9 +391,10 @@ int xfrm_state_delete(struct xfrm_state *x)
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_state_delete);
|
||||
|
||||
void xfrm_state_flush(u8 proto)
|
||||
void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
for (i = 0; i <= xfrm_state_hmask; i++) {
|
||||
@ -399,7 +407,11 @@ restart:
|
||||
xfrm_state_hold(x);
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
|
||||
xfrm_state_delete(x);
|
||||
err = xfrm_state_delete(x);
|
||||
xfrm_audit_log(audit_info->loginuid,
|
||||
audit_info->secid,
|
||||
AUDIT_MAC_IPSEC_DELSA,
|
||||
err ? 0 : 1, NULL, x);
|
||||
xfrm_state_put(x);
|
||||
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
@ -1099,7 +1111,7 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
|
||||
void *data)
|
||||
{
|
||||
int i;
|
||||
struct xfrm_state *x;
|
||||
struct xfrm_state *x, *last = NULL;
|
||||
struct hlist_node *entry;
|
||||
int count = 0;
|
||||
int err = 0;
|
||||
@ -1107,24 +1119,22 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
|
||||
spin_lock_bh(&xfrm_state_lock);
|
||||
for (i = 0; i <= xfrm_state_hmask; i++) {
|
||||
hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
|
||||
if (xfrm_id_proto_match(x->id.proto, proto))
|
||||
count++;
|
||||
if (!xfrm_id_proto_match(x->id.proto, proto))
|
||||
continue;
|
||||
if (last) {
|
||||
err = func(last, count, data);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
last = x;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i <= xfrm_state_hmask; i++) {
|
||||
hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
|
||||
if (!xfrm_id_proto_match(x->id.proto, proto))
|
||||
continue;
|
||||
err = func(x, --count, data);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
err = func(last, 0, data);
|
||||
out:
|
||||
spin_unlock_bh(&xfrm_state_lock);
|
||||
return err;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#include <linux/in6.h>
|
||||
#endif
|
||||
#include <linux/audit.h>
|
||||
|
||||
static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
|
||||
{
|
||||
@ -454,6 +455,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
|
||||
else
|
||||
err = xfrm_state_update(x);
|
||||
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
|
||||
|
||||
if (err < 0) {
|
||||
x->km.state = XFRM_STATE_DEAD;
|
||||
__xfrm_state_put(x);
|
||||
@ -523,6 +527,10 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
|
||||
}
|
||||
|
||||
err = xfrm_state_delete(x);
|
||||
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
|
||||
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
@ -1030,6 +1038,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
|
||||
* a type XFRM_MSG_UPDPOLICY - JHS */
|
||||
excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
|
||||
err = xfrm_policy_insert(p->dir, xp, excl);
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
|
||||
|
||||
if (err) {
|
||||
security_xfrm_policy_free(xp);
|
||||
kfree(xp);
|
||||
@ -1257,6 +1268,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
|
||||
xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete);
|
||||
security_xfrm_policy_free(&tmp);
|
||||
}
|
||||
if (delete)
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
|
||||
|
||||
if (xp == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
@ -1291,8 +1306,11 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma
|
||||
{
|
||||
struct km_event c;
|
||||
struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
|
||||
struct xfrm_audit audit_info;
|
||||
|
||||
xfrm_state_flush(p->proto);
|
||||
audit_info.loginuid = NETLINK_CB(skb).loginuid;
|
||||
audit_info.secid = NETLINK_CB(skb).sid;
|
||||
xfrm_state_flush(p->proto, &audit_info);
|
||||
c.data.proto = p->proto;
|
||||
c.event = nlh->nlmsg_type;
|
||||
c.seq = nlh->nlmsg_seq;
|
||||
@ -1442,12 +1460,15 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
|
||||
struct km_event c;
|
||||
u8 type = XFRM_POLICY_TYPE_MAIN;
|
||||
int err;
|
||||
struct xfrm_audit audit_info;
|
||||
|
||||
err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
xfrm_policy_flush(type);
|
||||
audit_info.loginuid = NETLINK_CB(skb).loginuid;
|
||||
audit_info.secid = NETLINK_CB(skb).sid;
|
||||
xfrm_policy_flush(type, &audit_info);
|
||||
c.data.type = type;
|
||||
c.event = nlh->nlmsg_type;
|
||||
c.seq = nlh->nlmsg_seq;
|
||||
@ -1502,6 +1523,9 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
|
||||
err = 0;
|
||||
if (up->hard) {
|
||||
xfrm_policy_delete(xp, p->dir);
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL);
|
||||
|
||||
} else {
|
||||
// reset the timers here?
|
||||
printk("Dont know what to do with soft policy expire\n");
|
||||
@ -1533,8 +1557,11 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **
|
||||
goto out;
|
||||
km_state_expired(x, ue->hard, current->pid);
|
||||
|
||||
if (ue->hard)
|
||||
if (ue->hard) {
|
||||
__xfrm_state_delete(x);
|
||||
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
|
||||
AUDIT_MAC_IPSEC_DELSA, 1, NULL, x);
|
||||
}
|
||||
out:
|
||||
spin_unlock_bh(&x->lock);
|
||||
xfrm_state_put(x);
|
||||
|
Loading…
x
Reference in New Issue
Block a user