| From: |
| Kazunori MIYAZAWA <kazunori@miyazawa.org> |
| To: |
| herbert@gondor.apana.org.au |
| Subject: |
| [RFC][PATCH] XCBC support with new crypto framework |
| Date: |
| Wed, 9 Aug 2006 19:14:51 +0900 |
| Cc: |
| netdev@vger.kernel.org, usagi-core@linux-ipv6.org |
Hi Herbert,
I make a patch set of introducing XCBC with your new crypto framework.
I checked the patches work well with the tcrypt module.
However I can not make sure that I completely understand the API.
So I would appreciate if you would give me some comments.
Thank you,
b30befe9e2ef5e59f9b2a8d3bf053489a10e159b
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 12b23a7..5713272 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -29,6 +29,13 @@ config CRYPTO_HMAC
HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec.
+config CRYPTO_XCBC
+ tristate "XCBC support"
+ depends on CRYPTO
+ help
+ XCBC: Keyed-Hashing for Message Authentication.
+ This is required for IPSec.
+
config CRYPTO_NULL
tristate "Null algorithms"
select CRYPTO_LOWAPI
diff --git a/crypto/Makefile b/crypto/Makefile
index 03c13fa..10c2ee4 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_CRYPTO_LOWAPI) += crypto_lo
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
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 0571d75..573a07d 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -117,7 +117,7 @@ static int crypto_hmac_init_tfm(struct c
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
struct crypto_hmac_ctx *ctx = crypto_hmac_ctx(tfm);
- ctx->child = crypto_spawn_tfm(spawn);
+ ctx->child = crypto_spawn_tfm(spawn, 0);
if (IS_ERR(ctx->child))
return PTR_ERR(ctx->child);
diff --git a/crypto/lowapi.c b/crypto/lowapi.c
index 35f26fb..79ed99a 100644
--- a/crypto/lowapi.c
+++ b/crypto/lowapi.c
@@ -376,7 +376,7 @@ void crypto_drop_spawn(struct crypto_spa
}
EXPORT_SYMBOL_GPL(crypto_drop_spawn);
-struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn)
+struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 flags)
{
struct crypto_alg *alg;
struct crypto_alg *alg2;
@@ -395,7 +395,7 @@ struct crypto_tfm *crypto_spawn_tfm(stru
return ERR_PTR(-EAGAIN);
}
- tfm = __crypto_alloc_tfm(alg, 0);
+ tfm = __crypto_alloc_tfm(alg, flags);
if (IS_ERR(tfm))
crypto_mod_put(alg);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index f778e40..c07b988 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -792,6 +792,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;
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index dd648f2..6fa65b4 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -933,6 +933,74 @@ static struct hash_testvec hmac_sha256_t
},
};
+#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 ... 127] = 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.
*/
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
new file mode 100644
index 0000000..8cee13a
--- /dev/null
+++ b/crypto/xcbc.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C)2005 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"
+
+u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ 0x03030303, 0x03030303, 0x03030303, 0x03030303};
+
+/*
+ * +------------------------
+ * | <parent tfm>
+ * +------------------------
+ * | prev (block size)
+ * +------------------------
+ * | key (block size)
+ * +------------------------
+ * | consts (block size * 3)
+ * +------------------------
+ * | crypto_xcbc_ctx
+ * +------------------------
+ */
+struct crypto_xcbc_ctx {
+ unsigned int keylen;
+ unsigned int len;
+ struct crypto_tfm *child;
+};
+
+static inline struct crypto_xcbc_ctx *crypto_xcbc_digest_ctx(struct crypto_tfm *parent)
+{
+ int bs = crypto_tfm_alg_blocksize(parent);
+ u8 *prev = crypto_tfm_ctx_aligned(parent);
+ return (struct crypto_xcbc_ctx*)(prev + bs * 5);
+}
+
+static int _crypto_xcbc_digest_setkey(struct crypto_tfm *parent,
+ const u8 *inkey, unsigned int keylen)
+{
+
+ int bs = crypto_tfm_alg_blocksize(parent);
+ u8 *prev = crypto_tfm_ctx_aligned(parent);
+ u8 *key = prev + bs;
+ u8 *consts = key + bs;
+ struct crypto_xcbc_ctx *ctx = (struct crypto_xcbc_ctx*)(consts + bs * 3);
+ int err = 0;
+ u8 key1[bs];
+
+ if ((err = crypto_cipher_setkey(ctx->child, key, keylen)))
+ return err;
+
+ ctx->child->__crt_alg->cra_cipher.cia_encrypt(ctx->child, key1,
+ consts);
+
+ return crypto_cipher_setkey(ctx->child, key1, bs);
+}
+
+static int crypto_xcbc_digest_setkey(struct crypto_tfm *parent,
+ const u8 *inkey, unsigned int keylen)
+{
+
+ int bs = crypto_tfm_alg_blocksize(parent);
+ u8 *prev = crypto_tfm_ctx_aligned(parent);
+ u8 *key = prev + bs;
+ u8 *consts = key + bs;
+ struct crypto_xcbc_ctx *ctx = (struct crypto_xcbc_ctx*)(consts + bs * 3);
+
+ if (keylen != crypto_tfm_alg_blocksize(ctx->child))
+ return -EINVAL;
+
+ if (keylen < crypto_tfm_alg_min_keysize(ctx->child) ||
+ keylen > crypto_tfm_alg_max_keysize(ctx->child))
+ return -EINVAL;
+
+ ctx->keylen = keylen;
+ memcpy(key, inkey, keylen);
+
+ memset(key + keylen, 0, crypto_tfm_alg_blocksize(ctx->child) - keylen);
+
+ memcpy(consts, ks, sizeof(ks));
+
+ ctx->len = 0;
+ memset(prev, 0, bs);
+ memset(ctx->child->crt_cipher.cit_iv, 0, crypto_tfm_alg_blocksize(ctx->child));
+
+ return _crypto_xcbc_digest_setkey(parent, key, ctx->keylen);
+}
+
+void crypto_xcbc_digest_init(struct crypto_tfm *parent)
+{
+ return;
+}
+
+void crypto_xcbc_digest_update(struct crypto_tfm *parent, struct scatterlist *sg, unsigned int
nsg)
+{
+ int bs = crypto_tfm_alg_blocksize(parent);
+ u8 *prev = crypto_tfm_ctx_aligned(parent);
+ struct crypto_xcbc_ctx *ctx = (struct crypto_xcbc_ctx*)(prev + bs * 5);
+ struct crypto_tfm *tfm = ctx->child;
+ unsigned int i;
+
+ if (!(tfm->crt_cipher.cit_mode & CRYPTO_TFM_MODE_CBC))
+ return;
+
+ for(i = 0; i < nsg; i++) {
+
+ 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(prev + 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);
+ continue;
+ }
+
+ /* filling prev with new data and encrypting it */
+ memcpy(prev + ctx->len, p, bs - ctx->len);
+ len -= bs - ctx->len;
+ p += bs - ctx->len;
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv,
+ prev);
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm,
+ tfm->crt_cipher.cit_iv,
+ tfm->crt_cipher.cit_iv);
+
+ /* clearing the length */
+ ctx->len = 0;
+
+ /* encrypting the rest of data */
+ while (len > bs) {
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, p);
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm,
+ tfm->crt_cipher.cit_iv,
+ tfm->crt_cipher.cit_iv);
+ p += bs;
+ len -= bs;
+ }
+
+ /* keeping the surplus of blocksize */
+ if (len) {
+ memcpy(prev, p, len);
+ ctx->len = len;
+ }
+ crypto_kunmap(p, 0);
+ crypto_yield(tfm);
+ slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
+ offset = 0;
+ pg++;
+ }
+ }
+}
+
+void crypto_xcbc_digest_final(struct crypto_tfm *parent, u8 *out)
+{
+ int bs = crypto_tfm_alg_blocksize(parent);
+ u8 *prev = crypto_tfm_ctx_aligned(parent);
+ u8 *key = prev + bs;
+ u8 *consts = key + bs;
+ struct crypto_xcbc_ctx *ctx = (struct crypto_xcbc_ctx*)(prev + bs * 5);
+ struct crypto_tfm *tfm = ctx->child;
+
+ if (ctx->len == bs) {
+ u8 key2[bs];
+
+ if ((crypto_cipher_setkey(tfm, key, ctx->keylen)) != 0)
+ return;
+
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key2, (const u8*)(consts+bs));
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, prev);
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, key2);
+
+ printk("%s 1\n", __FUNCTION__);
+ _crypto_xcbc_digest_setkey(parent, key, ctx->keylen);
+
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, tfm->crt_cipher.cit_iv);
+ } else {
+ u8 key3[bs];
+ unsigned int rlen;
+ u8 *p = prev + ctx->len;
+ *p = 0x80;
+ p++;
+
+ rlen = bs - ctx->len -1;
+ if (rlen)
+ memset(p, 0, rlen);
+
+ if ((crypto_cipher_setkey(tfm, key, ctx->keylen)) != 0)
+ return;
+
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key3, (const u8*)(consts+bs*2));
+
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, prev);
+ tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, key3);
+
+ printk("%s 2\n", __FUNCTION__);
+ _crypto_xcbc_digest_setkey(parent, key, ctx->keylen);
+
+ tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, tfm->crt_cipher.cit_iv);
+ }
+
+ return;
+}
+
+static int crypto_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_xcbc_digest_ctx(tfm);
+
+ ctx->child = crypto_spawn_tfm(spawn, CRYPTO_TFM_MODE_CBC);
+ if (IS_ERR(ctx->child))
+ return PTR_ERR(ctx->child);
+
+ return 0;
+};
+
+static void crypto_xcbc_exit_tfm(struct crypto_tfm *tfm)
+{
+ crypto_free_tfm(crypto_xcbc_digest_ctx(tfm)->child);
+}
+
+static struct crypto_instance *crypto_xcbc_alloc(void *param, unsigned int len)
+{
+ struct rtattr *rta = param;
+ struct crypto_instance *inst;
+ struct crypto_attr_alg *alga;
+ struct crypto_alg *alg;
+ struct crypto_spawn *spawn;
+ int err;
+
+ if (!RTA_OK(rta, len))
+ return ERR_PTR(-EBADR);
+
+ if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga))
+ return ERR_PTR(-EINVAL);
+
+ alga = RTA_DATA(rta);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_DIGEST;
+
+ alg = crypto_alg_mod_lookup(alga->name, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+
+ err = PTR_ERR(alg);
+ if (IS_ERR(alg))
+ goto err_free_inst;
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "xcbc(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
+ goto put_alg;
+
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "xcbc(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+ goto put_alg;
+
+ spawn = crypto_instance_ctx(inst);
+ err = crypto_init_spawn(spawn, alg, inst);
+
+put_alg:
+ crypto_mod_put(alg);
+ if (err)
+ goto err_free_inst;
+
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = alg->cra_blocksize;
+ inst->alg.cra_alignmask = alg->cra_alignmask;
+ inst->alg.cra_digest.dia_digestsize = alg->cra_blocksize;
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_xcbc_ctx) +
+ inst->alg.cra_blocksize * 5;
+
+ inst->alg.cra_init = crypto_xcbc_init_tfm;
+ inst->alg.cra_exit = crypto_xcbc_exit_tfm;
+
+ inst->alg.cra_digest.dia_init = crypto_xcbc_digest_init;
+ inst->alg.cra_digest.dia_update_sg = crypto_xcbc_digest_update;
+ inst->alg.cra_digest.dia_final = crypto_xcbc_digest_final;
+ inst->alg.cra_digest.dia_setkey = crypto_xcbc_digest_setkey;
+
+ return inst;
+
+err_free_inst:
+ kfree(inst);
+ return ERR_PTR(err);
+}
+
+static void crypto_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 = crypto_xcbc_alloc,
+ .free = crypto_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 digest algorithm");
diff --git a/include/crypto/lowapi.h b/include/crypto/lowapi.h
index 03c46e2..5e53b8a 100644
--- a/include/crypto/lowapi.h
+++ b/include/crypto/lowapi.h
@@ -54,7 +54,7 @@ struct crypto_template *crypto_lookup_te
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
struct crypto_instance *inst);
void crypto_drop_spawn(struct crypto_spawn *spawn);
-struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn);
+struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 flags);
struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len,
u32 type, u32 mask);
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index d5dd471..636e0fb 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -285,6 +285,7 @@ #define SADB_X_AALG_SHA2_256HMAC 5
#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
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 2783d4e..6c48292 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -119,6 +119,24 @@ static struct xfrm_algo_desc aalg_list[]
.sadb_alg_maxbits = 160
}
},
+{
+ .name = "xcbc(aes)",
+ .compat = "aes_xcbc_128",
+
+ .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[] = {
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html