summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Kconfig97
-rw-r--r--crypto/Makefile14
-rw-r--r--crypto/ablkcipher.c241
-rw-r--r--crypto/aead.c400
-rw-r--r--crypto/aes_generic.c468
-rw-r--r--crypto/algapi.c65
-rw-r--r--crypto/api.c19
-rw-r--r--crypto/authenc.c334
-rw-r--r--crypto/blkcipher.c202
-rw-r--r--crypto/camellia.c1781
-rw-r--r--crypto/cast6.c6
-rw-r--r--crypto/cbc.c109
-rw-r--r--crypto/ccm.c889
-rw-r--r--crypto/chainiv.c331
-rw-r--r--crypto/cryptd.c6
-rw-r--r--crypto/crypto_null.c70
-rw-r--r--crypto/ctr.c422
-rw-r--r--crypto/des_generic.c17
-rw-r--r--crypto/digest.c4
-rw-r--r--crypto/eseqiv.c264
-rw-r--r--crypto/gcm.c823
-rw-r--r--crypto/hmac.c3
-rw-r--r--crypto/internal.h31
-rw-r--r--crypto/lzo.c106
-rw-r--r--crypto/pcbc.c105
-rw-r--r--crypto/salsa20_generic.c255
-rw-r--r--crypto/scatterwalk.c10
-rw-r--r--crypto/scatterwalk.h80
-rw-r--r--crypto/seqiv.c345
-rw-r--r--crypto/sha256_generic.c72
-rw-r--r--crypto/tcrypt.c449
-rw-r--r--crypto/tcrypt.h3415
-rw-r--r--crypto/twofish_common.c96
-rw-r--r--crypto/xcbc.c10
34 files changed, 9478 insertions, 2061 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 083d2e1..c3166a1 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -24,10 +24,6 @@ config CRYPTO_ALGAPI
help
This option provides the API for cryptographic algorithms.
-config CRYPTO_ABLKCIPHER
- tristate
- select CRYPTO_BLKCIPHER
-
config CRYPTO_AEAD
tristate
select CRYPTO_ALGAPI
@@ -36,6 +32,15 @@ config CRYPTO_BLKCIPHER
tristate
select CRYPTO_ALGAPI
+config CRYPTO_SEQIV
+ tristate "Sequence Number IV Generator"
+ select CRYPTO_AEAD
+ select CRYPTO_BLKCIPHER
+ help
+ This IV generator generates an IV based on a sequence number by
+ xoring it with a salt. This algorithm is mainly useful for CTR
+ and similar modes.
+
config CRYPTO_HASH
tristate
select CRYPTO_ALGAPI
@@ -91,7 +96,7 @@ config CRYPTO_SHA1
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
config CRYPTO_SHA256
- tristate "SHA256 digest algorithm"
+ tristate "SHA224 and SHA256 digest algorithm"
select CRYPTO_ALGAPI
help
SHA256 secure hash standard (DFIPS 180-2).
@@ -99,6 +104,9 @@ config CRYPTO_SHA256
This version of SHA implements a 256 bit hash with 128 bits of
security against collision attacks.
+ This code also includes SHA-224, a 224 bit hash with 112 bits
+ of security against collision attacks.
+
config CRYPTO_SHA512
tristate "SHA384 and SHA512 digest algorithms"
select CRYPTO_ALGAPI
@@ -195,9 +203,34 @@ config CRYPTO_XTS
key size 256, 384 or 512 bits. This implementation currently
can't handle a sectorsize which is not a multiple of 16 bytes.
+config CRYPTO_CTR
+ tristate "CTR support"
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_SEQIV
+ select CRYPTO_MANAGER
+ help
+ CTR: Counter mode
+ This block cipher algorithm is required for IPSec.
+
+config CRYPTO_GCM
+ tristate "GCM/GMAC support"
+ select CRYPTO_CTR
+ select CRYPTO_AEAD
+ select CRYPTO_GF128MUL
+ help
+ Support for Galois/Counter Mode (GCM) and Galois Message
+ Authentication Code (GMAC). Required for IPSec.
+
+config CRYPTO_CCM
+ tristate "CCM support"
+ select CRYPTO_CTR
+ select CRYPTO_AEAD
+ help
+ Support for Counter with CBC MAC. Required for IPsec.
+
config CRYPTO_CRYPTD
tristate "Software async crypto daemon"
- select CRYPTO_ABLKCIPHER
+ select CRYPTO_BLKCIPHER
select CRYPTO_MANAGER
help
This is a generic software asynchronous crypto daemon that
@@ -320,6 +353,7 @@ config CRYPTO_AES_586
tristate "AES cipher algorithms (i586)"
depends on (X86 || UML_X86) && !64BIT
select CRYPTO_ALGAPI
+ select CRYPTO_AES
help
AES cipher algorithms (FIPS-197). AES uses the Rijndael
algorithm.
@@ -341,6 +375,7 @@ config CRYPTO_AES_X86_64
tristate "AES cipher algorithms (x86_64)"
depends on (X86 || UML_X86) && 64BIT
select CRYPTO_ALGAPI
+ select CRYPTO_AES
help
AES cipher algorithms (FIPS-197). AES uses the Rijndael
algorithm.
@@ -441,6 +476,46 @@ config CRYPTO_SEED
See also:
<http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp>
+config CRYPTO_SALSA20
+ tristate "Salsa20 stream cipher algorithm (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ select CRYPTO_BLKCIPHER
+ help
+ Salsa20 stream cipher algorithm.
+
+ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
+ Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
+
+ The Salsa20 stream cipher algorithm is designed by Daniel J.
+ Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
+
+config CRYPTO_SALSA20_586
+ tristate "Salsa20 stream cipher algorithm (i586) (EXPERIMENTAL)"
+ depends on (X86 || UML_X86) && !64BIT
+ depends on EXPERIMENTAL
+ select CRYPTO_BLKCIPHER
+ help
+ Salsa20 stream cipher algorithm.
+
+ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
+ Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
+
+ The Salsa20 stream cipher algorithm is designed by Daniel J.
+ Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
+
+config CRYPTO_SALSA20_X86_64
+ tristate "Salsa20 stream cipher algorithm (x86_64) (EXPERIMENTAL)"
+ depends on (X86 || UML_X86) && 64BIT
+ depends on EXPERIMENTAL
+ select CRYPTO_BLKCIPHER
+ help
+ Salsa20 stream cipher algorithm.
+
+ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
+ Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
+
+ The Salsa20 stream cipher algorithm is designed by Daniel J.
+ Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
@@ -491,6 +566,7 @@ config CRYPTO_TEST
tristate "Testing module"
depends on m
select CRYPTO_ALGAPI
+ select CRYPTO_AEAD
help
Quick & dirty crypto test module.
@@ -498,10 +574,19 @@ config CRYPTO_AUTHENC
tristate "Authenc support"
select CRYPTO_AEAD
select CRYPTO_MANAGER
+ select CRYPTO_HASH
help
Authenc: Combined mode wrapper for IPsec.
This is required for IPSec.
+config CRYPTO_LZO
+ tristate "LZO compression algorithm"
+ select CRYPTO_ALGAPI
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+ help
+ This is the LZO algorithm.
+
source "drivers/crypto/Kconfig"
endif # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 43c2a0d..48c7583 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -8,9 +8,14 @@ crypto_algapi-$(CONFIG_PROC_FS) += proc.o
crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y)
obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
-obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o
obj-$(CONFIG_CRYPTO_AEAD) += aead.o
-obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o
+
+crypto_blkcipher-objs := ablkcipher.o
+crypto_blkcipher-objs += blkcipher.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER) += chainiv.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER) += eseqiv.o
+obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
crypto_hash-objs := hash.o
obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o
@@ -32,6 +37,9 @@ obj-$(CONFIG_CRYPTO_CBC) += cbc.o
obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
obj-$(CONFIG_CRYPTO_XTS) += xts.o
+obj-$(CONFIG_CRYPTO_CTR) += ctr.o
+obj-$(CONFIG_CRYPTO_GCM) += gcm.o
+obj-$(CONFIG_CRYPTO_CCM) += ccm.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
obj-$(CONFIG_CRYPTO_DES) += des_generic.o
obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
@@ -48,10 +56,12 @@ obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_SEED) += seed.o
+obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
+obj-$(CONFIG_CRYPTO_LZO) += lzo.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 2731acb..3bcb099 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -13,14 +13,18 @@
*
*/
-#include <crypto/algapi.h>
-#include <linux/errno.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/rtnetlink.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include "internal.h"
+
static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key,
unsigned int keylen)
{
@@ -66,6 +70,16 @@ static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
return alg->cra_ctxsize;
}
+int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req)
+{
+ return crypto_ablkcipher_encrypt(&req->creq);
+}
+
+int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req)
+{
+ return crypto_ablkcipher_decrypt(&req->creq);
+}
+
static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
u32 mask)
{
@@ -78,6 +92,11 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
crt->setkey = setkey;
crt->encrypt = alg->encrypt;
crt->decrypt = alg->decrypt;
+ if (!alg->ivsize) {
+ crt->givencrypt = skcipher_null_givencrypt;
+ crt->givdecrypt = skcipher_null_givdecrypt;
+ }
+ crt->base = __crypto_ablkcipher_cast(tfm);
crt->ivsize = alg->ivsize;
return 0;
@@ -90,10 +109,13 @@ static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
seq_printf(m, "type : ablkcipher\n");
+ seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
+ "yes" : "no");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
+ seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<default>");
}
const struct crypto_type crypto_ablkcipher_type = {
@@ -105,5 +127,220 @@ const struct crypto_type crypto_ablkcipher_type = {
};
EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
+static int no_givdecrypt(struct skcipher_givcrypt_request *req)
+{
+ return -ENOSYS;
+}
+
+static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
+ u32 mask)
+{
+ struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
+ struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
+
+ if (alg->ivsize > PAGE_SIZE / 8)
+ return -EINVAL;
+
+ crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ?
+ alg->setkey : setkey;
+ crt->encrypt = alg->encrypt;
+ crt->decrypt = alg->decrypt;
+ crt->givencrypt = alg->givencrypt;
+ crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt;
+ crt->base = __crypto_ablkcipher_cast(tfm);
+ crt->ivsize = alg->ivsize;
+
+ return 0;
+}
+
+static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
+ __attribute__ ((unused));
+static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+ struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
+
+ seq_printf(m, "type : givcipher\n");
+ seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
+ "yes" : "no");
+ seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
+ seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
+ seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
+ seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
+ seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<built-in>");
+}
+
+const struct crypto_type crypto_givcipher_type = {
+ .ctxsize = crypto_ablkcipher_ctxsize,
+ .init = crypto_init_givcipher_ops,
+#ifdef CONFIG_PROC_FS
+ .show = crypto_givcipher_show,
+#endif
+};
+EXPORT_SYMBOL_GPL(crypto_givcipher_type);
+
+const char *crypto_default_geniv(const struct crypto_alg *alg)
+{
+ return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv";
+}
+
+static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask)
+{
+ struct rtattr *tb[3];
+ struct {
+ struct rtattr attr;
+ struct crypto_attr_type data;
+ } ptype;
+ struct {
+ struct rtattr attr;
+ struct crypto_attr_alg data;
+ } palg;
+ struct crypto_template *tmpl;
+ struct crypto_instance *inst;
+ struct crypto_alg *larval;
+ const char *geniv;
+ int err;
+
+ larval = crypto_larval_lookup(alg->cra_driver_name,
+ CRYPTO_ALG_TYPE_GIVCIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ err = PTR_ERR(larval);
+ if (IS_ERR(larval))
+ goto out;
+
+ err = -EAGAIN;
+ if (!crypto_is_larval(larval))
+ goto drop_larval;
+
+ ptype.attr.rta_len = sizeof(ptype);
+ ptype.attr.rta_type = CRYPTOA_TYPE;
+ ptype.data.type = type | CRYPTO_ALG_GENIV;
+ /* GENIV tells the template that we're making a default geniv. */
+ ptype.data.mask = mask | CRYPTO_ALG_GENIV;
+ tb[0] = &ptype.attr;
+
+ palg.attr.rta_len = sizeof(palg);
+ palg.attr.rta_type = CRYPTOA_ALG;
+ /* Must use the exact name to locate ourselves. */
+ memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME);
+ tb[1] = &palg.attr;
+
+ tb[2] = NULL;
+
+ if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER)
+ geniv = alg->cra_blkcipher.geniv;
+ else
+ geniv = alg->cra_ablkcipher.geniv;
+
+ if (!geniv)
+ geniv = crypto_default_geniv(alg);
+
+ tmpl = crypto_lookup_template(geniv);
+ err = -ENOENT;
+ if (!tmpl)
+ goto kill_larval;
+
+ inst = tmpl->alloc(tb);
+ err = PTR_ERR(inst);
+ if (IS_ERR(inst))
+ goto put_tmpl;
+
+ if ((err = crypto_register_instance(tmpl, inst))) {
+ tmpl->free(inst);
+ goto put_tmpl;
+ }
+
+ /* Redo the lookup to use the instance we just registered. */
+ err = -EAGAIN;
+
+put_tmpl:
+ crypto_tmpl_put(tmpl);
+kill_larval:
+ crypto_larval_kill(larval);
+drop_larval:
+ crypto_mod_put(larval);
+out:
+ crypto_mod_put(alg);
+ return err;
+}
+
+static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
+ u32 mask)
+{
+ struct crypto_alg *alg;
+
+ alg = crypto_alg_mod_lookup(name, type, mask);
+ if (IS_ERR(alg))
+ return alg;
+
+ if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_GIVCIPHER)
+ return alg;
+
+ if (!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+ alg->cra_ablkcipher.ivsize))
+ return alg;
+
+ return ERR_PTR(crypto_givcipher_default(alg, type, mask));
+}
+
+int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
+ u32 type, u32 mask)
+{
+ struct crypto_alg *alg;
+ int err;
+
+ type = crypto_skcipher_type(type);
+ mask = crypto_skcipher_mask(mask);
+
+ alg = crypto_lookup_skcipher(name, type, mask);
+ if (IS_ERR(alg))
+ return PTR_ERR(alg);
+
+ err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
+ crypto_mod_put(alg);
+ return err;
+}
+EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
+
+struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name,
+ u32 type, u32 mask)
+{
+ struct crypto_tfm *tfm;
+ int err;
+
+ type = crypto_skcipher_type(type);
+ mask = crypto_skcipher_mask(mask);
+
+ for (;;) {
+ struct crypto_alg *alg;
+
+ alg = crypto_lookup_skcipher(alg_name, type, mask);
+ if (IS_ERR(alg)) {
+ err = PTR_ERR(alg);
+ goto err;
+ }
+
+ tfm = __crypto_alloc_tfm(alg, type, mask);
+ if (!IS_ERR(tfm))
+ return __crypto_ablkcipher_cast(tfm);
+
+ crypto_mod_put(alg);
+ err = PTR_ERR(tfm);
+
+err:
+ if (err != -EAGAIN)
+ break;
+ if (signal_pending(current)) {
+ err = -EINTR;
+ break;
+ }
+ }
+
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Asynchronous block chaining cipher type");
diff --git a/crypto/aead.c b/crypto/aead.c
index 84a3501..3a6f3f5 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -12,14 +12,17 @@
*
*/
-#include <crypto/algapi.h>
-#include <linux/errno.h>
+#include <crypto/internal/aead.h>
+#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include "internal.h"
+
static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
unsigned int keylen)
{
@@ -53,25 +56,54 @@ static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
return aead->setkey(tfm, key, keylen);
}
+int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
+{
+ struct aead_tfm *crt = crypto_aead_crt(tfm);
+ int err;
+
+ if (authsize > crypto_aead_alg(tfm)->maxauthsize)
+ return -EINVAL;
+
+ if (crypto_aead_alg(tfm)->setauthsize) {
+ err = crypto_aead_alg(tfm)->setauthsize(crt->base, authsize);
+ if (err)
+ return err;
+ }
+
+ crypto_aead_crt(crt->base)->authsize = authsize;
+ crt->authsize = authsize;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_aead_setauthsize);
+
static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type,
u32 mask)
{
return alg->cra_ctxsize;
}
+static int no_givcrypt(struct aead_givcrypt_request *req)
+{
+ return -ENOSYS;
+}
+
static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
struct aead_tfm *crt = &tfm->crt_aead;
- if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8)
+ if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
return -EINVAL;
- crt->setkey = setkey;
+ crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ?
+ alg->setkey : setkey;
crt->encrypt = alg->encrypt;
crt->decrypt = alg->decrypt;
+ crt->givencrypt = alg->givencrypt ?: no_givcrypt;
+ crt->givdecrypt = alg->givdecrypt ?: no_givcrypt;
+ crt->base = __crypto_aead_cast(tfm);
crt->ivsize = alg->ivsize;
- crt->authsize = alg->authsize;
+ crt->authsize = alg->maxauthsize;
return 0;
}
@@ -83,9 +115,12 @@ static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
struct aead_alg *aead = &alg->cra_aead;
seq_printf(m, "type : aead\n");
+ seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
+ "yes" : "no");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "ivsize : %u\n", aead->ivsize);
- seq_printf(m, "authsize : %u\n", aead->authsize);
+ seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize);
+ seq_printf(m, "geniv : %s\n", aead->geniv ?: "<built-in>");
}
const struct crypto_type crypto_aead_type = {
@@ -97,5 +132,358 @@ const struct crypto_type crypto_aead_type = {
};
EXPORT_SYMBOL_GPL(crypto_aead_type);
+static int aead_null_givencrypt(struct aead_givcrypt_request *req)
+{
+ return crypto_aead_encrypt(&req->areq);
+}
+
+static int aead_null_givdecrypt(struct aead_givcrypt_request *req)
+{
+ return crypto_aead_decrypt(&req->areq);
+}
+
+static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+ struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
+ struct aead_tfm *crt = &tfm->crt_aead;
+
+ if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
+ return -EINVAL;
+
+ crt->setkey = setkey;
+ crt->encrypt = alg->encrypt;
+ crt->decrypt = alg->decrypt;
+ if (!alg->ivsize) {
+ crt->givencrypt = aead_null_givencrypt;
+ crt->givdecrypt = aead_null_givdecrypt;
+ }
+ crt->base = __crypto_aead_cast(tfm);
+ crt->ivsize = alg->ivsize;
+ crt->authsize = alg->maxauthsize;
+
+ return 0;
+}
+
+static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
+ __attribute__ ((unused));
+static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
+{
+ struct aead_alg *aead = &alg->cra_aead;
+
+ seq_printf(m, "type : nivaead\n");
+ seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
+ "yes" : "no");
+ seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
+ seq_printf(m, "ivsize : %u\n", aead->ivsize);
+ seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize);
+ seq_printf(m, "geniv : %s\n", aead->geniv);
+}
+
+const struct crypto_type crypto_nivaead_type = {
+ .ctxsize = crypto_aead_ctxsize,
+ .init = crypto_init_nivaead_ops,
+#ifdef CONFIG_PROC_FS
+ .show = crypto_nivaead_show,
+#endif
+};
+EXPORT_SYMBOL_GPL(crypto_nivaead_type);
+
+static int crypto_grab_nivaead(struct crypto_aead_spawn *spawn,
+ const char *name, u32 type, u32 mask)
+{
+ struct crypto_alg *alg;
+ int err;
+
+ type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ type |= CRYPTO_ALG_TYPE_AEAD;
+ mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV;
+
+ alg = crypto_alg_mod_lookup(name, type, mask);
+ if (IS_ERR(alg))
+ return PTR_ERR(alg);
+
+ err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
+ crypto_mod_put(alg);
+ return err;
+}
+
+struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl,
+ struct rtattr **tb, u32 type,
+ u32 mask)
+{
+ const char *name;
+ struct crypto_aead_spawn *spawn;
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV)) &
+ algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(name);
+ if (IS_ERR(name))
+ return ERR_PTR(err);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ spawn = crypto_instance_ctx(inst);
+
+ /* Ignore async algorithms if necessary. */
+ mask |= crypto_requires_sync(algt->type, algt->mask);
+
+ crypto_set_aead_spawn(spawn, inst);
+ err = crypto_grab_nivaead(spawn, name, type, mask);
+ if (err)
+ goto err_free_inst;
+
+ alg = crypto_aead_spawn_alg(spawn);
+
+ err = -EINVAL;
+ if (!alg->cra_aead.ivsize)
+ goto err_drop_alg;
+
+ /*
+ * This is only true if we're constructing an algorithm with its
+ * default IV generator. For the default generator we elide the
+ * template name and double-check the IV generator.
+ */
+ if (algt->mask & CRYPTO_ALG_GENIV) {
+ if (strcmp(tmpl->name, alg->cra_aead.geniv))
+ goto err_drop_alg;
+
+ memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
+ memcpy(inst->alg.cra_driver_name, alg->cra_driver_name,
+ CRYPTO_MAX_ALG_NAME);
+ } else {
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "%s(%s)", tmpl->name, alg->cra_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_drop_alg;
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "%s(%s)", tmpl->name, alg->cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_drop_alg;
+ }
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV;
+ inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
+ 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_aead_type;
+
+ inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize;
+ inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize;
+ inst->alg.cra_aead.geniv = alg->cra_aead.geniv;
+
+ inst->alg.cra_aead.setkey = alg->cra_aead.setkey;
+ inst->alg.cra_aead.setauthsize = alg->cra_aead.setauthsize;
+ inst->alg.cra_aead.encrypt = alg->cra_aead.encrypt;
+ inst->alg.cra_aead.decrypt = alg->cra_aead.decrypt;
+
+out:
+ return inst;
+
+err_drop_alg:
+ crypto_drop_aead(spawn);
+err_free_inst:
+ kfree(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+EXPORT_SYMBOL_GPL(aead_geniv_alloc);
+
+void aead_geniv_free(struct crypto_instance *inst)
+{
+ crypto_drop_aead(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+EXPORT_SYMBOL_GPL(aead_geniv_free);
+
+int aead_geniv_init(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_aead *aead;
+
+ aead = crypto_spawn_aead(crypto_instance_ctx(inst));
+ if (IS_ERR(aead))
+ return PTR_ERR(aead);
+
+ tfm->crt_aead.base = aead;
+ tfm->crt_aead.reqsize += crypto_aead_reqsize(aead);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(aead_geniv_init);
+
+void aead_geniv_exit(struct crypto_tfm *tfm)
+{
+ crypto_free_aead(tfm->crt_aead.base);
+}
+EXPORT_SYMBOL_GPL(aead_geniv_exit);
+
+static int crypto_nivaead_default(struct crypto_alg *alg, u32 type, u32 mask)
+{
+ struct rtattr *tb[3];
+ struct {
+ struct rtattr attr;
+ struct crypto_attr_type data;
+ } ptype;
+ struct {
+ struct rtattr attr;
+ struct crypto_attr_alg data;
+ } palg;
+ struct crypto_template *tmpl;
+ struct crypto_instance *inst;
+ struct crypto_alg *larval;
+ const char *geniv;
+ int err;
+
+ larval = crypto_larval_lookup(alg->cra_driver_name,
+ CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV,
+ CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ err = PTR_ERR(larval);
+ if (IS_ERR(larval))
+ goto out;
+
+ err = -EAGAIN;
+ if (!crypto_is_larval(larval))
+ goto drop_larval;
+
+ ptype.attr.rta_len = sizeof(ptype);
+ ptype.attr.rta_type = CRYPTOA_TYPE;
+ ptype.data.type = type | CRYPTO_ALG_GENIV;
+ /* GENIV tells the template that we're making a default geniv. */
+ ptype.data.mask = mask | CRYPTO_ALG_GENIV;
+ tb[0] = &ptype.attr;
+
+ palg.attr.rta_len = sizeof(palg);
+ palg.attr.rta_type = CRYPTOA_ALG;
+ /* Must use the exact name to locate ourselves. */
+ memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME);
+ tb[1] = &palg.attr;
+
+ tb[2] = NULL;
+
+ geniv = alg->cra_aead.geniv;
+
+ tmpl = crypto_lookup_template(geniv);
+ err = -ENOENT;
+ if (!tmpl)
+ goto kill_larval;
+
+ inst = tmpl->alloc(tb);
+ err = PTR_ERR(inst);
+ if (IS_ERR(inst))
+ goto put_tmpl;
+
+ if ((err = crypto_register_instance(tmpl, inst))) {
+ tmpl->free(inst);
+ goto put_tmpl;
+ }
+
+ /* Redo the lookup to use the instance we just registered. */
+ err = -EAGAIN;
+
+put_tmpl:
+ crypto_tmpl_put(tmpl);
+kill_larval:
+ crypto_larval_kill(larval);
+drop_larval:
+ crypto_mod_put(larval);
+out:
+ crypto_mod_put(alg);
+ return err;
+}
+
+static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,
+ u32 mask)
+{
+ struct crypto_alg *alg;
+
+ alg = crypto_alg_mod_lookup(name, type, mask);
+ if (IS_ERR(alg))
+ return alg;
+
+ if (alg->cra_type == &crypto_aead_type)
+ return alg;
+
+ if (!alg->cra_aead.ivsize)
+ return alg;
+
+ return ERR_PTR(crypto_nivaead_default(alg, type, mask));
+}
+
+int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
+ u32 type, u32 mask)
+{
+ struct crypto_alg *alg;
+ int err;
+
+ type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ type |= CRYPTO_ALG_TYPE_AEAD;
+ mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ mask |= CRYPTO_ALG_TYPE_MASK;
+
+ alg = crypto_lookup_aead(name, type, mask);
+ if (IS_ERR(alg))
+ return PTR_ERR(alg);
+
+ err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
+ crypto_mod_put(alg);
+ return err;
+}
+EXPORT_SYMBOL_GPL(crypto_grab_aead);
+
+struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)
+{
+ struct crypto_tfm *tfm;
+ int err;
+
+ type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ type |= CRYPTO_ALG_TYPE_AEAD;
+ mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
+ mask |= CRYPTO_ALG_TYPE_MASK;
+
+ for (;;) {
+ struct crypto_alg *alg;
+
+ alg = crypto_lookup_aead(alg_name, type, mask);
+ if (IS_ERR(alg)) {
+ err = PTR_ERR(alg);
+ goto err;
+ }
+
+ tfm = __crypto_alloc_tfm(alg, type, mask);
+ if (!IS_ERR(tfm))
+ return __crypto_aead_cast(tfm);
+
+ crypto_mod_put(alg);
+ err = PTR_ERR(tfm);
+
+err:
+ if (err != -EAGAIN)
+ break;
+ if (signal_pending(current)) {
+ err = -EINTR;
+ break;
+ }
+ }
+
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_aead);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");
diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c
index 9401dca..cf30af74 100644
--- a/crypto/aes_generic.c
+++ b/crypto/aes_generic.c
@@ -47,11 +47,7 @@
* ---------------------------------------------------------------------------
*/
-/* Some changes from the Gladman version:
- s/RIJNDAEL(e_key)/E_KEY/g
- s/RIJNDAEL(d_key)/D_KEY/g
-*/
-
+#include <crypto/aes.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -59,88 +55,46 @@
#include <linux/crypto.h>
#include <asm/byteorder.h>
-#define AES_MIN_KEY_SIZE 16
-#define AES_MAX_KEY_SIZE 32
-
-#define AES_BLOCK_SIZE 16
-
-/*
- * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
- */
-static inline u8
-byte(const u32 x, const unsigned n)
+static inline u8 byte(const u32 x, const unsigned n)
{
return x >> (n << 3);
}
-struct aes_ctx {
- int key_length;
- u32 buf[120];
-};
-
-#define E_KEY (&ctx->buf[0])
-#define D_KEY (&ctx->buf[60])
-
static u8 pow_tab[256] __initdata;
static u8 log_tab[256] __initdata;
static u8 sbx_tab[256] __initdata;
static u8 isb_tab[256] __initdata;
static u32 rco_tab[10];
-static u32 ft_tab[4][256];
-static u32 it_tab[4][256];
-static u32 fl_tab[4][256];
-static u32 il_tab[4][256];
+u32 crypto_ft_tab[4][256];
+u32 crypto_fl_tab[4][256];
+u32 crypto_it_tab[4][256];
+u32 crypto_il_tab[4][256];
-static inline u8 __init
-f_mult (u8 a, u8 b)
+EXPORT_SYMBOL_GPL(crypto_ft_tab);
+EXPORT_SYMBOL_GPL(crypto_fl_tab);
+EXPORT_SYMBOL_GPL(crypto_it_tab);
+EXPORT_SYMBOL_GPL(crypto_il_tab);
+
+static inline u8 __init f_mult(u8 a, u8 b)
{
u8 aa = log_tab[a], cc = aa + log_tab[b];
return pow_tab[cc + (cc < aa ? 1 : 0)];
}
-#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0)
-
-#define f_rn(bo, bi, n, k) \
- bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
- ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
- ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rn(bo, bi, n, k) \
- bo[n] = it_tab[0][byte(bi[n],0)] ^ \
- it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
- it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-#define ls_box(x) \
- ( fl_tab[0][byte(x, 0)] ^ \
- fl_tab[1][byte(x, 1)] ^ \
- fl_tab[2][byte(x, 2)] ^ \
- fl_tab[3][byte(x, 3)] )
-
-#define f_rl(bo, bi, n, k) \
- bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
- fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
- fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rl(bo, bi, n, k) \
- bo[n] = il_tab[0][byte(bi[n],0)] ^ \
- il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
- il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-static void __init
-gen_tabs (void)
+#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
+
+static void __init gen_tabs(void)
{
u32 i, t;
u8 p, q;
- /* log and power tables for GF(2**8) finite field with
- 0x011b as modular polynomial - the simplest primitive
- root is 0x03, used here to generate the tables */
+ /*
+ * log and power tables for GF(2**8) finite field with
+ * 0x011b as modular polynomial - the simplest primitive
+ * root is 0x03, used here to generate the tables
+ */
for (i = 0, p = 1; i < 256; ++i) {
pow_tab[i] = (u8) p;
@@ -169,92 +123,119 @@ gen_tabs (void)
p = sbx_tab[i];
t = p;
- fl_tab[0][i] = t;
- fl_tab[1][i] = rol32(t, 8);
- fl_tab[2][i] = rol32(t, 16);
- fl_tab[3][i] = rol32(t, 24);
+ crypto_fl_tab[0][i] = t;
+ crypto_fl_tab[1][i] = rol32(t, 8);
+ crypto_fl_tab[2][i] = rol32(t, 16);
+ crypto_fl_tab[3][i] = rol32(t, 24);
- t = ((u32) ff_mult (2, p)) |
+ t = ((u32) ff_mult(2, p)) |
((u32) p << 8) |
- ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
+ ((u32) p << 16) | ((u32) ff_mult(3, p) << 24);
- ft_tab[0][i] = t;
- ft_tab[1][i] = rol32(t, 8);
- ft_tab[2][i] = rol32(t, 16);
- ft_tab[3][i] = rol32(t, 24);
+ crypto_ft_tab[0][i] = t;
+ crypto_ft_tab[1][i] = rol32(t, 8);
+ crypto_ft_tab[2][i] = rol32(t, 16);
+ crypto_ft_tab[3][i] = rol32(t, 24);
p = isb_tab[i];
t = p;
- il_tab[0][i] = t;
- il_tab[1][i] = rol32(t, 8);
- il_tab[2][i] = rol32(t, 16);
- il_tab[3][i] = rol32(t, 24);
-
- t = ((u32) ff_mult (14, p)) |
- ((u32) ff_mult (9, p) << 8) |
- ((u32) ff_mult (13, p) << 16) |
- ((u32) ff_mult (11, p) << 24);
-
- it_tab[0][i] = t;
- it_tab[1][i] = rol32(t, 8);
- it_tab[2][i] = rol32(t, 16);
- it_tab[3][i] = rol32(t, 24);
+ crypto_il_tab[0][i] = t;
+ crypto_il_tab[1][i] = rol32(t, 8);
+ crypto_il_tab[2][i] = rol32(t, 16);
+ crypto_il_tab[3][i] = rol32(t, 24);
+
+ t = ((u32) ff_mult(14, p)) |
+ ((u32) ff_mult(9, p) << 8) |
+ ((u32) ff_mult(13, p) << 16) |
+ ((u32) ff_mult(11, p) << 24);
+
+ crypto_it_tab[0][i] = t;
+ crypto_it_tab[1][i] = rol32(t, 8);
+ crypto_it_tab[2][i] = rol32(t, 16);
+ crypto_it_tab[3][i] = rol32(t, 24);
}
}
-#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
-
-#define imix_col(y,x) \
- u = star_x(x); \
- v = star_x(u); \
- w = star_x(v); \
- t = w ^ (x); \
- (y) = u ^ v ^ w; \
- (y) ^= ror32(u ^ t, 8) ^ \
- ror32(v ^ t, 16) ^ \
- ror32(t,24)
-
/* initialise the key schedule from the user supplied key */
-#define loop4(i) \
-{ t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
- t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \
- t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \
- t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \
- t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \
-}
-
-#define loop6(i) \
-{ t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
- t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \
- t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \
- t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \
- t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \
- t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \
- t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \
-}
-
-#define loop8(i) \
-{ t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \
- t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \
- t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \
- t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \
- t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \
- t = E_KEY[8 * i + 4] ^ ls_box(t); \
- E_KEY[8 * i + 12] = t; \
- t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \
- t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \
- t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \
-}
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
-static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- unsigned int key_len)
+#define imix_col(y,x) do { \
+ u = star_x(x); \
+ v = star_x(u); \
+ w = star_x(v); \
+ t = w ^ (x); \
+ (y) = u ^ v ^ w; \
+ (y) ^= ror32(u ^ t, 8) ^ \
+ ror32(v ^ t, 16) ^ \
+ ror32(t, 24); \
+} while (0)
+
+#define ls_box(x) \
+ crypto_fl_tab[0][byte(x, 0)] ^ \
+ crypto_fl_tab[1][byte(x, 1)] ^ \
+ crypto_fl_tab[2][byte(x, 2)] ^ \
+ crypto_fl_tab[3][byte(x, 3)]
+
+#define loop4(i) do { \
+ t = ror32(t, 8); \
+ t = ls_box(t) ^ rco_tab[i]; \
+ t ^= ctx->key_enc[4 * i]; \
+ ctx->key_enc[4 * i + 4] = t; \
+ t ^= ctx->key_enc[4 * i + 1]; \
+ ctx->key_enc[4 * i + 5] = t; \
+ t ^= ctx->key_enc[4 * i + 2]; \
+ ctx->key_enc[4 * i + 6] = t; \
+ t ^= ctx->key_enc[4 * i + 3]; \
+ ctx->key_enc[4 * i + 7] = t; \
+} while (0)
+
+#define loop6(i) do { \
+ t = ror32(t, 8); \
+ t = ls_box(t) ^ rco_tab[i]; \
+ t ^= ctx->key_enc[6 * i]; \
+ ctx->key_enc[6 * i + 6] = t; \
+ t ^= ctx->key_enc[6 * i + 1]; \
+ ctx->key_enc[6 * i + 7] = t; \
+ t ^= ctx->key_enc[6 * i + 2]; \
+ ctx->key_enc[6 * i + 8] = t; \
+ t ^= ctx->key_enc[6 * i + 3]; \
+ ctx->key_enc[6 * i + 9] = t; \
+ t ^= ctx->key_enc[6 * i + 4]; \
+ ctx->key_enc[6 * i + 10] = t; \
+ t ^= ctx->key_enc[6 * i + 5]; \
+ ctx->key_enc[6 * i + 11] = t; \
+} while (0)
+
+#define loop8(i) do { \
+ t = ror32(t, 8); \
+ t = ls_box(t) ^ rco_tab[i]; \
+ t ^= ctx->key_enc[8 * i]; \
+ ctx->key_enc[8 * i + 8] = t; \
+ t ^= ctx->key_enc[8 * i + 1]; \
+ ctx->key_enc[8 * i + 9] = t; \
+ t ^= ctx->key_enc[8 * i + 2]; \
+ ctx->key_enc[8 * i + 10] = t; \
+ t ^= ctx->key_enc[8 * i + 3]; \
+ ctx->key_enc[8 * i + 11] = t; \
+ t = ctx->key_enc[8 * i + 4] ^ ls_box(t); \
+ ctx->key_enc[8 * i + 12] = t; \
+ t ^= ctx->key_enc[8 * i + 5]; \
+ ctx->key_enc[8 * i + 13] = t; \
+ t ^= ctx->key_enc[8 * i + 6]; \
+ ctx->key_enc[8 * i + 14] = t; \
+ t ^= ctx->key_enc[8 * i + 7]; \
+ ctx->key_enc[8 * i + 15] = t; \
+} while (0)
+
+int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
{
- struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *key = (const __le32 *)in_key;
u32 *flags = &tfm->crt_flags;
- u32 i, t, u, v, w;
+ u32 i, t, u, v, w, j;
if (key_len % 8) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
@@ -263,95 +244,113 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
ctx->key_length = key_len;
- E_KEY[0] = le32_to_cpu(key[0]);
- E_KEY[1] = le32_to_cpu(key[1]);
- E_KEY[2] = le32_to_cpu(key[2]);
- E_KEY[3] = le32_to_cpu(key[3]);
+ ctx->key_dec[key_len + 24] = ctx->key_enc[0] = le32_to_cpu(key[0]);
+ ctx->key_dec[key_len + 25] = ctx->key_enc[1] = le32_to_cpu(key[1]);
+ ctx->key_dec[key_len + 26] = ctx->key_enc[2] = le32_to_cpu(key[2]);
+ ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]);
switch (key_len) {
case 16:
- t = E_KEY[3];
+ t = ctx->key_enc[3];
for (i = 0; i < 10; ++i)
- loop4 (i);
+ loop4(i);
break;
case 24:
- E_KEY[4] = le32_to_cpu(key[4]);
- t = E_KEY[5] = le32_to_cpu(key[5]);
+ ctx->key_enc[4] = le32_to_cpu(key[4]);
+ t = ctx->key_enc[5] = le32_to_cpu(key[5]);
for (i = 0; i < 8; ++i)
- loop6 (i);
+ loop6(i);
break;
case 32:
- E_KEY[4] = le32_to_cpu(key[4]);
- E_KEY[5] = le32_to_cpu(key[5]);
- E_KEY[6] = le32_to_cpu(key[6]);
- t = E_KEY[7] = le32_to_cpu(key[7]);
+ ctx->key_enc[4] = le32_to_cpu(key[4]);
+ ctx->key_enc[5] = le32_to_cpu(key[5]);
+ ctx->key_enc[6] = le32_to_cpu(key[6]);
+ t = ctx->key_enc[7] = le32_to_cpu(key[7]);
for (i = 0; i < 7; ++i)
- loop8 (i);
+ loop8(i);
break;
}
- D_KEY[0] = E_KEY[0];
- D_KEY[1] = E_KEY[1];
- D_KEY[2] = E_KEY[2];
- D_KEY[3] = E_KEY[3];
+ ctx->key_dec[0] = ctx->key_enc[key_len + 24];
+ ctx->key_dec[1] = ctx->key_enc[key_len + 25];
+ ctx->key_dec[2] = ctx->key_enc[key_len + 26];
+ ctx->key_dec[3] = ctx->key_enc[key_len + 27];
for (i = 4; i < key_len + 24; ++i) {
- imix_col (D_KEY[i], E_KEY[i]);
+ j = key_len + 24 - (i & ~3) + (i & 3);
+ imix_col(ctx->key_dec[j], ctx->key_enc[i]);
}
-
return 0;
}
+EXPORT_SYMBOL_GPL(crypto_aes_set_key);
/* encrypt a block of text */
-#define f_nround(bo, bi, k) \
- f_rn(bo, bi, 0, k); \
- f_rn(bo, bi, 1, k); \
- f_rn(bo, bi, 2, k); \
- f_rn(bo, bi, 3, k); \
- k += 4
-
-#define f_lround(bo, bi, k) \
- f_rl(bo, bi, 0, k); \
- f_rl(bo, bi, 1, k); \
- f_rl(bo, bi, 2, k); \
- f_rl(bo, bi, 3, k)
+#define f_rn(bo, bi, n, k) do { \
+ bo[n] = crypto_ft_tab[0][byte(bi[n], 0)] ^ \
+ crypto_ft_tab[1][byte(bi[(n + 1) & 3], 1)] ^ \
+ crypto_ft_tab[2][byte(bi[(n + 2) & 3], 2)] ^ \
+ crypto_ft_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n); \
+} while (0)
+
+#define f_nround(bo, bi, k) do {\
+ f_rn(bo, bi, 0, k); \
+ f_rn(bo, bi, 1, k); \
+ f_rn(bo, bi, 2, k); \
+ f_rn(bo, bi, 3, k); \
+ k += 4; \
+} while (0)
+
+#define f_rl(bo, bi, n, k) do { \
+ bo[n] = crypto_fl_tab[0][byte(bi[n], 0)] ^ \
+ crypto_fl_tab[1][byte(bi[(n + 1) & 3], 1)] ^ \
+ crypto_fl_tab[2][byte(bi[(n + 2) & 3], 2)] ^ \
+ crypto_fl_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n); \
+} while (0)
+
+#define f_lround(bo, bi, k) do {\
+ f_rl(bo, bi, 0, k); \
+ f_rl(bo, bi, 1, k); \
+ f_rl(bo, bi, 2, k); \
+ f_rl(bo, bi, 3, k); \
+} while (0)
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
- const struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *src = (const __le32 *)in;
__le32 *dst = (__le32 *)out;
u32 b0[4], b1[4];
- const u32 *kp = E_KEY + 4;
+ const u32 *kp = ctx->key_enc + 4;
+ const int key_len = ctx->key_length;
- b0[0] = le32_to_cpu(src[0]) ^ E_KEY[0];
- b0[1] = le32_to_cpu(src[1]) ^ E_KEY[1];
- b0[2] = le32_to_cpu(src[2]) ^ E_KEY[2];
- b0[3] = le32_to_cpu(src[3]) ^ E_KEY[3];
+ b0[0] = le32_to_cpu(src[0]) ^ ctx->key_enc[0];
+ b0[1] = le32_to_cpu(src[1]) ^ ctx->key_enc[1];
+ b0[2] = le32_to_cpu(src[2]) ^ ctx->key_enc[2];
+ b0[3] = le32_to_cpu(src[3]) ^ ctx->key_enc[3];
- if (ctx->key_length > 24) {
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
+ if (key_len > 24) {
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
}
- if (ctx->key_length > 16) {
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
+ if (key_len > 16) {
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
}
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
- f_nround (b1, b0, kp);
- f_nround (b0, b1, kp);
- f_nround (b1, b0, kp);
- f_lround (b0, b1, kp);
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
+ f_nround(b1, b0, kp);
+ f_nround(b0, b1, kp);
+ f_nround(b1, b0, kp);
+ f_lround(b0, b1, kp);
dst[0] = cpu_to_le32(b0[0]);
dst[1] = cpu_to_le32(b0[1]);
@@ -361,53 +360,69 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
/* decrypt a block of text */
-#define i_nround(bo, bi, k) \
- i_rn(bo, bi, 0, k); \
- i_rn(bo, bi, 1, k); \
- i_rn(bo, bi, 2, k); \
- i_rn(bo, bi, 3, k); \
- k -= 4
-
-#define i_lround(bo, bi, k) \
- i_rl(bo, bi, 0, k); \
- i_rl(bo, bi, 1, k); \
- i_rl(bo, bi, 2, k); \
- i_rl(bo, bi, 3, k)
+#define i_rn(bo, bi, n, k) do { \
+ bo[n] = crypto_it_tab[0][byte(bi[n], 0)] ^ \
+ crypto_it_tab[1][byte(bi[(n + 3) & 3], 1)] ^ \
+ crypto_it_tab[2][byte(bi[(n + 2) & 3], 2)] ^ \
+ crypto_it_tab[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n); \
+} while (0)
+
+#define i_nround(bo, bi, k) do {\
+ i_rn(bo, bi, 0, k); \
+ i_rn(bo, bi, 1, k); \
+ i_rn(bo, bi, 2, k); \
+ i_rn(bo, bi, 3, k); \
+ k += 4; \
+} while (0)
+
+#define i_rl(bo, bi, n, k) do { \
+ bo[n] = crypto_il_tab[0][byte(bi[n], 0)] ^ \
+ crypto_il_tab[1][byte(bi[(n + 3) & 3], 1)] ^ \
+ crypto_il_tab[2][byte(bi[(n + 2) & 3], 2)] ^ \
+ crypto_il_tab[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n); \
+} while (0)
+
+#define i_lround(bo, bi, k) do {\
+ i_rl(bo, bi, 0, k); \
+ i_rl(bo, bi, 1, k); \
+ i_rl(bo, bi, 2, k); \
+ i_rl(bo, bi, 3, k); \
+} while (0)
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
- const struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *src = (const __le32 *)in;
__le32 *dst = (__le32 *)out;
u32 b0[4], b1[4];
const int key_len = ctx->key_length;
- const u32 *kp = D_KEY + key_len + 20;
+ const u32 *kp = ctx->key_dec + 4;
- b0[0] = le32_to_cpu(src[0]) ^ E_KEY[key_len + 24];
- b0[1] = le32_to_cpu(src[1]) ^ E_KEY[key_len + 25];
- b0[2] = le32_to_cpu(src[2]) ^ E_KEY[key_len + 26];
- b0[3] = le32_to_cpu(src[3]) ^ E_KEY[key_len + 27];
+ b0[0] = le32_to_cpu(src[0]) ^ ctx->key_dec[0];
+ b0[1] = le32_to_cpu(src[1]) ^ ctx->key_dec[1];
+ b0[2] = le32_to_cpu(src[2]) ^ ctx->key_dec[2];
+ b0[3] = le32_to_cpu(src[3]) ^ ctx->key_dec[3];
if (key_len > 24) {
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
}
if (key_len > 16) {
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
}
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
- i_nround (b1, b0, kp);
- i_nround (b0, b1, kp);
- i_nround (b1, b0, kp);
- i_lround (b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_nround(b0, b1, kp);
+ i_nround(b1, b0, kp);
+ i_lround(b0, b1, kp);
dst[0] = cpu_to_le32(b0[0]);
dst[1] = cpu_to_le32(b0[1]);
@@ -415,14 +430,13 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
dst[3] = cpu_to_le32(b0[3]);
}
-
static struct crypto_alg aes_alg = {
.cra_name = "aes",
.cra_driver_name = "aes-generic",
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct aes_ctx),
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
@@ -430,9 +444,9 @@ static struct crypto_alg aes_alg = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
.cia_max_keysize = AES_MAX_KEY_SIZE,
- .cia_setkey = aes_set_key,
- .cia_encrypt = aes_encrypt,
- .cia_decrypt = aes_decrypt
+ .cia_setkey = crypto_aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt
}
}
};
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 8383282..e65cb50 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -472,7 +472,7 @@ int crypto_check_attr_type(struct rtattr **tb, u32 type)
}
EXPORT_SYMBOL_GPL(crypto_check_attr_type);
-struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask)
+const char *crypto_attr_alg_name(struct rtattr *rta)
{
struct crypto_attr_alg *alga;
@@ -486,7 +486,21 @@ struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask)
alga = RTA_DATA(rta);
alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
- return crypto_alg_mod_lookup(alga->name, type, mask);
+ return alga->name;
+}
+EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
+
+struct crypto_alg *crypto_attr_alg(struct rtattr *rta, u32 type, u32 mask)
+{
+ const char *name;
+ int err;
+
+ name = crypto_attr_alg_name(rta);
+ err = PTR_ERR(name);
+ if (IS_ERR(name))
+ return ERR_PTR(err);
+
+ return crypto_alg_mod_lookup(name, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_attr_alg);
@@ -605,6 +619,53 @@ int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm)
}
EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
+static inline void crypto_inc_byte(u8 *a, unsigned int size)
+{
+ u8 *b = (a + size);
+ u8 c;
+
+ for (; size; size--) {
+ c = *--b + 1;
+ *b = c;
+ if (c)
+ break;
+ }
+}
+
+void crypto_inc(u8 *a, unsigned int size)
+{
+ __be32 *b = (__be32 *)(a + size);
+ u32 c;
+
+ for (; size >= 4; size -= 4) {
+ c = be32_to_cpu(*--b) + 1;
+ *b = cpu_to_be32(c);
+ if (c)
+ return;
+ }
+
+ crypto_inc_byte(a, size);
+}
+EXPORT_SYMBOL_GPL(crypto_inc);
+
+static inline void crypto_xor_byte(u8 *a, const u8 *b, unsigned int size)
+{
+ for (; size; size--)
+ *a++ ^= *b++;
+}
+
+void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
+{
+ u32 *a = (u32 *)dst;
+ u32 *b = (u32 *)src;
+
+ for (; size >= 4; size -= 4)
+ *a++ ^= *b++;
+
+ crypto_xor_byte((u8 *)a, (u8 *)b, size);
+}
+EXPORT_SYMBOL_GPL(crypto_xor);
+
static int __init crypto_algapi_init(void)
{
crypto_init_proc();
diff --git a/crypto/api.c b/crypto/api.c
index 1f5c724..a2496d1 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -137,7 +137,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
return alg;
}
-static void crypto_larval_kill(struct crypto_alg *alg)
+void crypto_larval_kill(struct crypto_alg *alg)
{
struct crypto_larval *larval = (void *)alg;
@@ -147,6 +147,7 @@ static void crypto_larval_kill(struct crypto_alg *alg)
complete_all(&larval->completion);
crypto_alg_put(alg);
}
+EXPORT_SYMBOL_GPL(crypto_larval_kill);
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
{
@@ -176,11 +177,9 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
return alg;
}
-struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
+struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
{
struct crypto_alg *alg;
- struct crypto_alg *larval;
- int ok;
if (!name)
return ERR_PTR(-ENOENT);
@@ -193,7 +192,17 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
if (alg)
return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
- larval = crypto_larval_alloc(name, type, mask);
+ return crypto_larval_alloc(name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_larval_lookup);
+
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
+{
+ struct crypto_alg *alg;
+ struct crypto_alg *larval;
+ int ok;
+
+ larval = crypto_larval_lookup(name, type, mask);
if (IS_ERR(larval) || !crypto_is_larval(larval))
return larval;
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 126a529..ed8ac5a 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -10,22 +10,21 @@
*
*/
-#include <crypto/algapi.h>
+#include <crypto/aead.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/authenc.h>
+#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include "scatterwalk.h"
-
struct authenc_instance_ctx {
struct crypto_spawn auth;
- struct crypto_spawn enc;
-
- unsigned int authsize;
- unsigned int enckeylen;
+ struct crypto_skcipher_spawn enc;
};
struct crypto_authenc_ctx {
@@ -37,19 +36,31 @@ struct crypto_authenc_ctx {
static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
unsigned int keylen)
{
- struct authenc_instance_ctx *ictx =
- crypto_instance_ctx(crypto_aead_alg_instance(authenc));
- unsigned int enckeylen = ictx->enckeylen;
unsigned int authkeylen;
+ unsigned int enckeylen;
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
struct crypto_hash *auth = ctx->auth;
struct crypto_ablkcipher *enc = ctx->enc;
+ struct rtattr *rta = (void *)key;
+ struct crypto_authenc_key_param *param;
int err = -EINVAL;
- if (keylen < enckeylen) {
- crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
- goto out;
- }
+ if (!RTA_OK(rta, keylen))
+ goto badkey;
+ if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
+ goto badkey;
+ if (RTA_PAYLOAD(rta) < sizeof(*param))
+ goto badkey;
+
+ param = RTA_DATA(rta);
+ enckeylen = be32_to_cpu(param->enckeylen);
+
+ key += RTA_ALIGN(rta->rta_len);
+ keylen -= RTA_ALIGN(rta->rta_len);
+
+ if (keylen < enckeylen)
+ goto badkey;
+
authkeylen = keylen - enckeylen;
crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
@@ -71,21 +82,38 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
out:
return err;
+
+badkey:
+ crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ goto out;
}
-static int crypto_authenc_hash(struct aead_request *req)
+static void authenc_chain(struct scatterlist *head, struct scatterlist *sg,
+ int chain)
+{
+ if (chain) {
+ head->length += sg->length;
+ sg = scatterwalk_sg_next(sg);
+ }
+
+ if (sg)
+ scatterwalk_sg_chain(head, 2, sg);
+ else
+ sg_mark_end(head);
+}
+
+static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags,
+ struct scatterlist *cipher,
+ unsigned int cryptlen)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
- struct authenc_instance_ctx *ictx =
- crypto_instance_ctx(crypto_aead_alg_instance(authenc));
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
struct crypto_hash *auth = ctx->auth;
struct hash_desc desc = {
.tfm = auth,
+ .flags = aead_request_flags(req) & flags,
};
u8 *hash = aead_request_ctx(req);
- struct scatterlist *dst = req->dst;
- unsigned int cryptlen = req->cryptlen;
int err;
hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth),
@@ -100,7 +128,7 @@ static int crypto_authenc_hash(struct aead_request *req)
if (err)
goto auth_unlock;
- err = crypto_hash_update(&desc, dst, cryptlen);
+ err = crypto_hash_update(&desc, cipher, cryptlen);
if (err)
goto auth_unlock;
@@ -109,17 +137,53 @@ auth_unlock:
spin_unlock_bh(&ctx->auth_lock);
if (err)
- return err;
+ return ERR_PTR(err);
+
+ return hash;
+}
- scatterwalk_map_and_copy(hash, dst, cryptlen, ictx->authsize, 1);
+static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
+ unsigned int flags)
+{
+ struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+ struct scatterlist *dst = req->dst;
+ struct scatterlist cipher[2];
+ struct page *dstp;
+ unsigned int ivsize = crypto_aead_ivsize(authenc);
+ unsigned int cryptlen;
+ u8 *vdst;
+ u8 *hash;
+
+ dstp = sg_page(dst);
+ vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
+
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, dst, vdst == iv + ivsize);
+
+ cryptlen = req->cryptlen + ivsize;
+ hash = crypto_authenc_hash(req, flags, cipher, cryptlen);
+ if (IS_ERR(hash))
+ return PTR_ERR(hash);
+
+ scatterwalk_map_and_copy(hash, cipher, cryptlen,
+ crypto_aead_authsize(authenc), 1);
return 0;
}
static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
int err)
{
- if (!err)
- err = crypto_authenc_hash(req->data);
+ if (!err) {
+ struct aead_request *areq = req->data;
+ struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
+ struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+ struct ablkcipher_request *abreq = aead_request_ctx(areq);
+ u8 *iv = (u8 *)(abreq + 1) +
+ crypto_ablkcipher_reqsize(ctx->enc);
+
+ err = crypto_authenc_genicv(areq, iv, 0);
+ }
aead_request_complete(req->data, err);
}
@@ -129,72 +193,99 @@ static int crypto_authenc_encrypt(struct aead_request *req)
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
struct ablkcipher_request *abreq = aead_request_ctx(req);
+ struct crypto_ablkcipher *enc = ctx->enc;
+ struct scatterlist *dst = req->dst;
+ unsigned int cryptlen = req->cryptlen;
+ u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc);
int err;
- ablkcipher_request_set_tfm(abreq, ctx->enc);
+ ablkcipher_request_set_tfm(abreq, enc);
ablkcipher_request_set_callback(abreq, aead_request_flags(req),
crypto_authenc_encrypt_done, req);
- ablkcipher_request_set_crypt(abreq, req->src, req->dst, req->cryptlen,
- req->iv);
+ ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv);
+
+ memcpy(iv, req->iv, crypto_aead_ivsize(authenc));
err = crypto_ablkcipher_encrypt(abreq);
if (err)
return err;
- return crypto_authenc_hash(req);
+ return crypto_authenc_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
}
-static int crypto_authenc_verify(struct aead_request *req)
+static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
+ int err)
{
- struct crypto_aead *authenc = crypto_aead_reqtfm(req);
- struct authenc_instance_ctx *ictx =
- crypto_instance_ctx(crypto_aead_alg_instance(authenc));
+ if (!err) {
+ struct aead_givcrypt_request *greq = req->data;
+
+ err = crypto_authenc_genicv(&greq->areq, greq->giv, 0);
+ }
+
+ aead_request_complete(req->data, err);
+}
+
+static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
+{
+ struct crypto_aead *authenc = aead_givcrypt_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
- struct crypto_hash *auth = ctx->auth;
- struct hash_desc desc = {
- .tfm = auth,
- .flags = aead_request_flags(req),
- };
- u8 *ohash = aead_request_ctx(req);
- u8 *ihash;
- struct scatterlist *src = req->src;
- unsigned int cryptlen = req->cryptlen;
- unsigned int authsize;
+ struct aead_request *areq = &req->areq;
+ struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
+ u8 *iv = req->giv;
int err;
- ohash = (u8 *)ALIGN((unsigned long)ohash + crypto_hash_alignmask(auth),
- crypto_hash_alignmask(auth) + 1);
- ihash = ohash + crypto_hash_digestsize(auth);
-
- spin_lock_bh(&ctx->auth_lock);
- err = crypto_hash_init(&desc);
- if (err)
- goto auth_unlock;
+ skcipher_givcrypt_set_tfm(greq, ctx->enc);
+ skcipher_givcrypt_set_callback(greq, aead_request_flags(areq),
+ crypto_authenc_givencrypt_done, areq);
+ skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen,
+ areq->iv);
+ skcipher_givcrypt_set_giv(greq, iv, req->seq);
- err = crypto_hash_update(&desc, req->assoc, req->assoclen);
+ err = crypto_skcipher_givencrypt(greq);
if (err)
- goto auth_unlock;
+ return err;
- err = crypto_hash_update(&desc, src, cryptlen);
- if (err)
- goto auth_unlock;
+ return crypto_authenc_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
+}
- err = crypto_hash_final(&desc, ohash);
-auth_unlock:
- spin_unlock_bh(&ctx->auth_lock);
+static int crypto_authenc_verify(struct aead_request *req,
+ struct scatterlist *cipher,
+ unsigned int cryptlen)
+{
+ struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+ u8 *ohash;
+ u8 *ihash;
+ unsigned int authsize;
- if (err)
- return err;
+ ohash = crypto_authenc_hash(req, CRYPTO_TFM_REQ_MAY_SLEEP, cipher,
+ cryptlen);
+ if (IS_ERR(ohash))
+ return PTR_ERR(ohash);
- authsize = ictx->authsize;
- scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0);
- return memcmp(ihash, ohash, authsize) ? -EINVAL : 0;
+ authsize = crypto_aead_authsize(authenc);
+ ihash = ohash + authsize;
+ scatterwalk_map_and_copy(ihash, cipher, cryptlen, authsize, 0);
+ return memcmp(ihash, ohash, authsize) ? -EBADMSG: 0;
}
-static void crypto_authenc_decrypt_done(struct crypto_async_request *req,
- int err)
+static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
+ unsigned int cryptlen)
{
- aead_request_complete(req->data, err);
+ struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+ struct scatterlist *src = req->src;
+ struct scatterlist cipher[2];
+ struct page *srcp;
+ unsigned int ivsize = crypto_aead_ivsize(authenc);
+ u8 *vsrc;
+
+ srcp = sg_page(src);
+ vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
+
+ sg_init_table(cipher, 2);
+ sg_set_buf(cipher, iv, ivsize);
+ authenc_chain(cipher, src, vsrc == iv + ivsize);
+
+ return crypto_authenc_verify(req, cipher, cryptlen + ivsize);
}
static int crypto_authenc_decrypt(struct aead_request *req)
@@ -202,17 +293,23 @@ static int crypto_authenc_decrypt(struct aead_request *req)
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
struct ablkcipher_request *abreq = aead_request_ctx(req);
+ unsigned int cryptlen = req->cryptlen;
+ unsigned int authsize = crypto_aead_authsize(authenc);
+ u8 *iv = req->iv;
int err;
- err = crypto_authenc_verify(req);
+ if (cryptlen < authsize)
+ return -EINVAL;
+ cryptlen -= authsize;
+
+ err = crypto_authenc_iverify(req, iv, cryptlen);
if (err)
return err;
ablkcipher_request_set_tfm(abreq, ctx->enc);
ablkcipher_request_set_callback(abreq, aead_request_flags(req),
- crypto_authenc_decrypt_done, req);
- ablkcipher_request_set_crypt(abreq, req->src, req->dst, req->cryptlen,
- req->iv);
+ req->base.complete, req->base.data);
+ ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv);
return crypto_ablkcipher_decrypt(abreq);
}
@@ -224,19 +321,13 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_hash *auth;
struct crypto_ablkcipher *enc;
- unsigned int digestsize;
int err;
auth = crypto_spawn_hash(&ictx->auth);
if (IS_ERR(auth))
return PTR_ERR(auth);
- err = -EINVAL;
- digestsize = crypto_hash_digestsize(auth);
- if (ictx->authsize > digestsize)
- goto err_free_hash;
-
- enc = crypto_spawn_ablkcipher(&ictx->enc);
+ enc = crypto_spawn_skcipher(&ictx->enc);
err = PTR_ERR(enc);
if (IS_ERR(enc))
goto err_free_hash;
@@ -246,9 +337,10 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
tfm->crt_aead.reqsize = max_t(unsigned int,
(crypto_hash_alignmask(auth) &
~(crypto_tfm_ctx_alignment() - 1)) +
- digestsize * 2,
- sizeof(struct ablkcipher_request) +
- crypto_ablkcipher_reqsize(enc));
+ crypto_hash_digestsize(auth) * 2,
+ sizeof(struct skcipher_givcrypt_request) +
+ crypto_ablkcipher_reqsize(enc) +
+ crypto_ablkcipher_ivsize(enc));
spin_lock_init(&ctx->auth_lock);
@@ -269,75 +361,74 @@ static void crypto_authenc_exit_tfm(struct crypto_tfm *tfm)
static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb)
{
+ struct crypto_attr_type *algt;
struct crypto_instance *inst;
struct crypto_alg *auth;
struct crypto_alg *enc;
struct authenc_instance_ctx *ctx;
- unsigned int authsize;
- unsigned int enckeylen;
+ const char *enc_name;
int err;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD);
- if (err)
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
return ERR_PTR(err);
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+ return ERR_PTR(-EINVAL);
+
auth = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
CRYPTO_ALG_TYPE_HASH_MASK);
if (IS_ERR(auth))
return ERR_PTR(PTR_ERR(auth));
- err = crypto_attr_u32(tb[2], &authsize);
- inst = ERR_PTR(err);
- if (err)
- goto out_put_auth;
-
- enc = crypto_attr_alg(tb[3], CRYPTO_ALG_TYPE_BLKCIPHER,
- CRYPTO_ALG_TYPE_MASK);
- inst = ERR_PTR(PTR_ERR(enc));
- if (IS_ERR(enc))
+ enc_name = crypto_attr_alg_name(tb[2]);
+ err = PTR_ERR(enc_name);
+ if (IS_ERR(enc_name))
goto out_put_auth;
- err = crypto_attr_u32(tb[4], &enckeylen);
- if (err)
- goto out_put_enc;
-
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
err = -ENOMEM;
if (!inst)
- goto out_put_enc;
-
- err = -ENAMETOOLONG;
- if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
- "authenc(%s,%u,%s,%u)", auth->cra_name, authsize,
- enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
-
- if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
- "authenc(%s,%u,%s,%u)", auth->cra_driver_name,
- authsize, enc->cra_driver_name, enckeylen) >=
- CRYPTO_MAX_ALG_NAME)
- goto err_free_inst;
+ goto out_put_auth;
ctx = crypto_instance_ctx(inst);
- ctx->authsize = authsize;
- ctx->enckeylen = enckeylen;
err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK);
if (err)
goto err_free_inst;
- err = crypto_init_spawn(&ctx->enc, enc, inst, CRYPTO_ALG_TYPE_MASK);
+ crypto_set_skcipher_spawn(&ctx->enc, inst);
+ err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
+ crypto_requires_sync(algt->type,
+ algt->mask));
if (err)
goto err_drop_auth;
- inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC;
+ enc = crypto_skcipher_spawn_alg(&ctx->enc);
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "authenc(%s,%s)", auth->cra_name, enc->cra_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_drop_enc;
+
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "authenc(%s,%s)", auth->cra_driver_name,
+ enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_drop_enc;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+ inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC;
inst->alg.cra_priority = enc->cra_priority * 10 + auth->cra_priority;
inst->alg.cra_blocksize = enc->cra_blocksize;
- inst->alg.cra_alignmask = max(auth->cra_alignmask, enc->cra_alignmask);
+ inst->alg.cra_alignmask = auth->cra_alignmask | enc->cra_alignmask;
inst->alg.cra_type = &crypto_aead_type;
- inst->alg.cra_aead.ivsize = enc->cra_blkcipher.ivsize;
- inst->alg.cra_aead.authsize = authsize;
+ inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
+ inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ?
+ auth->cra_hash.digestsize :
+ auth->cra_digest.dia_digestsize;
inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx);
@@ -347,18 +438,19 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb)
inst->alg.cra_aead.setkey = crypto_authenc_setkey;
inst->alg.cra_aead.encrypt = crypto_authenc_encrypt;
inst->alg.cra_aead.decrypt = crypto_authenc_decrypt;
+ inst->alg.cra_aead.givencrypt = crypto_authenc_givencrypt;
out:
- crypto_mod_put(enc);
-out_put_auth:
crypto_mod_put(auth);
return inst;
+err_drop_enc:
+ crypto_drop_skcipher(&ctx->enc);
err_drop_auth:
crypto_drop_spawn(&ctx->auth);
err_free_inst:
kfree(inst);
-out_put_enc:
+out_put_auth:
inst = ERR_PTR(err);
goto out;
}
@@ -367,7 +459,7 @@ static void crypto_authenc_free(struct crypto_instance *inst)
{
struct authenc_instance_ctx *ctx = crypto_instance_ctx(inst);
- crypto_drop_spawn(&ctx->enc);
+ crypto_drop_skcipher(&ctx->enc);
crypto_drop_spawn(&ctx->auth);
kfree(inst);
}
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index f6c67f9..4a7e65c 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -14,7 +14,8 @@
*
*/
-#include <linux/crypto.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
#include <linux/kernel.h>
@@ -25,7 +26,6 @@
#include <linux/string.h>
#include "internal.h"
-#include "scatterwalk.h"
enum {
BLKCIPHER_WALK_PHYS = 1 << 0,
@@ -433,9 +433,8 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type,
struct blkcipher_alg *cipher = &alg->cra_blkcipher;
unsigned int len = alg->cra_ctxsize;
- type ^= CRYPTO_ALG_ASYNC;
- mask &= CRYPTO_ALG_ASYNC;
- if ((type & mask) && cipher->ivsize) {
+ if ((mask & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_MASK &&
+ cipher->ivsize) {
len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
len += cipher->ivsize;
}
@@ -451,6 +450,11 @@ static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm)
crt->setkey = async_setkey;
crt->encrypt = async_encrypt;
crt->decrypt = async_decrypt;
+ if (!alg->ivsize) {
+ crt->givencrypt = skcipher_null_givencrypt;
+ crt->givdecrypt = skcipher_null_givdecrypt;
+ }
+ crt->base = __crypto_ablkcipher_cast(tfm);
crt->ivsize = alg->ivsize;
return 0;
@@ -482,9 +486,7 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
if (alg->ivsize > PAGE_SIZE / 8)
return -EINVAL;
- type ^= CRYPTO_ALG_ASYNC;
- mask &= CRYPTO_ALG_ASYNC;
- if (type & mask)
+ if ((mask & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_MASK)
return crypto_init_blkcipher_ops_sync(tfm);
else
return crypto_init_blkcipher_ops_async(tfm);
@@ -499,6 +501,8 @@ static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
seq_printf(m, "min keysize : %u\n", alg->cra_blkcipher.min_keysize);
seq_printf(m, "max keysize : %u\n", alg->cra_blkcipher.max_keysize);
seq_printf(m, "ivsize : %u\n", alg->cra_blkcipher.ivsize);
+ seq_printf(m, "geniv : %s\n", alg->cra_blkcipher.geniv ?:
+ "<default>");
}
const struct crypto_type crypto_blkcipher_type = {
@@ -510,5 +514,187 @@ const struct crypto_type crypto_blkcipher_type = {
};
EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
+static int crypto_grab_nivcipher(struct crypto_skcipher_spawn *spawn,
+ const char *name, u32 type, u32 mask)
+{
+ struct crypto_alg *alg;
+ int err;
+
+ type = crypto_skcipher_type(type);
+ mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV;
+
+ alg = crypto_alg_mod_lookup(name, type, mask);
+ if (IS_ERR(alg))
+ return PTR_ERR(alg);
+
+ err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
+ crypto_mod_put(alg);
+ return err;
+}
+
+struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl,
+ struct rtattr **tb, u32 type,
+ u32 mask)
+{
+ struct {
+ int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int keylen);
+ int (*encrypt)(struct ablkcipher_request *req);
+ int (*decrypt)(struct ablkcipher_request *req);
+
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+ unsigned int ivsize;
+
+ const char *geniv;
+ } balg;
+ const char *name;
+ struct crypto_skcipher_spawn *spawn;
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ (CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_GENIV)) &
+ algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(name);
+ if (IS_ERR(name))
+ return ERR_PTR(err);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ spawn = crypto_instance_ctx(inst);
+
+ /* Ignore async algorithms if necessary. */
+ mask |= crypto_requires_sync(algt->type, algt->mask);
+
+ crypto_set_skcipher_spawn(spawn, inst);
+ err = crypto_grab_nivcipher(spawn, name, type, mask);
+ if (err)
+ goto err_free_inst;
+
+ alg = crypto_skcipher_spawn_alg(spawn);
+
+ if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER) {
+ balg.ivsize = alg->cra_blkcipher.ivsize;
+ balg.min_keysize = alg->cra_blkcipher.min_keysize;
+ balg.max_keysize = alg->cra_blkcipher.max_keysize;
+
+ balg.setkey = async_setkey;
+ balg.encrypt = async_encrypt;
+ balg.decrypt = async_decrypt;
+
+ balg.geniv = alg->cra_blkcipher.geniv;
+ } else {
+ balg.ivsize = alg->cra_ablkcipher.ivsize;
+ balg.min_keysize = alg->cra_ablkcipher.min_keysize;
+ balg.max_keysize = alg->cra_ablkcipher.max_keysize;
+
+ balg.setkey = alg->cra_ablkcipher.setkey;
+ balg.encrypt = alg->cra_ablkcipher.encrypt;
+ balg.decrypt = alg->cra_ablkcipher.decrypt;
+
+ balg.geniv = alg->cra_ablkcipher.geniv;
+ }
+
+ err = -EINVAL;
+ if (!balg.ivsize)
+ goto err_drop_alg;
+
+ /*
+ * This is only true if we're constructing an algorithm with its
+ * default IV generator. For the default generator we elide the
+ * template name and double-check the IV generator.
+ */
+ if (algt->mask & CRYPTO_ALG_GENIV) {
+ if (!balg.geniv)
+ balg.geniv = crypto_default_geniv(alg);
+ err = -EAGAIN;
+ if (strcmp(tmpl->name, balg.geniv))
+ goto err_drop_alg;
+
+ memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
+ memcpy(inst->alg.cra_driver_name, alg->cra_driver_name,
+ CRYPTO_MAX_ALG_NAME);
+ } else {
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "%s(%s)", tmpl->name, alg->cra_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_drop_alg;
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "%s(%s)", tmpl->name, alg->cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto err_drop_alg;
+ }
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_GENIV;
+ inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
+ 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_givcipher_type;
+
+ inst->alg.cra_ablkcipher.ivsize = balg.ivsize;
+ inst->alg.cra_ablkcipher.min_keysize = balg.min_keysize;
+ inst->alg.cra_ablkcipher.max_keysize = balg.max_keysize;
+ inst->alg.cra_ablkcipher.geniv = balg.geniv;
+
+ inst->alg.cra_ablkcipher.setkey = balg.setkey;
+ inst->alg.cra_ablkcipher.encrypt = balg.encrypt;
+ inst->alg.cra_ablkcipher.decrypt = balg.decrypt;
+
+out:
+ return inst;
+
+err_drop_alg:
+ crypto_drop_skcipher(spawn);
+err_free_inst:
+ kfree(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+EXPORT_SYMBOL_GPL(skcipher_geniv_alloc);
+
+void skcipher_geniv_free(struct crypto_instance *inst)
+{
+ crypto_drop_skcipher(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+EXPORT_SYMBOL_GPL(skcipher_geniv_free);
+
+int skcipher_geniv_init(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_ablkcipher *cipher;
+
+ cipher = crypto_spawn_skcipher(crypto_instance_ctx(inst));
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ tfm->crt_ablkcipher.base = cipher;
+ tfm->crt_ablkcipher.reqsize += crypto_ablkcipher_reqsize(cipher);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(skcipher_geniv_init);
+
+void skcipher_geniv_exit(struct crypto_tfm *tfm)
+{
+ crypto_free_ablkcipher(tfm->crt_ablkcipher.base);
+}
+EXPORT_SYMBOL_GPL(skcipher_geniv_exit);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic block chaining cipher type");
diff --git a/crypto/camellia.c b/crypto/camellia.c
index 6877ecf..493fee7 100644
--- a/crypto/camellia.c
+++ b/crypto/camellia.c
@@ -36,176 +36,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-
-#define CAMELLIA_MIN_KEY_SIZE 16
-#define CAMELLIA_MAX_KEY_SIZE 32
-#define CAMELLIA_BLOCK_SIZE 16
-#define CAMELLIA_TABLE_BYTE_LEN 272
-#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
-
-typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
-
-
-/* key constants */
-
-#define CAMELLIA_SIGMA1L (0xA09E667FL)
-#define CAMELLIA_SIGMA1R (0x3BCC908BL)
-#define CAMELLIA_SIGMA2L (0xB67AE858L)
-#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
-#define CAMELLIA_SIGMA3L (0xC6EF372FL)
-#define CAMELLIA_SIGMA3R (0xE94F82BEL)
-#define CAMELLIA_SIGMA4L (0x54FF53A5L)
-#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
-#define CAMELLIA_SIGMA5L (0x10E527FAL)
-#define CAMELLIA_SIGMA5R (0xDE682D1DL)
-#define CAMELLIA_SIGMA6L (0xB05688C2L)
-#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
-
-struct camellia_ctx {
- int key_length;
- KEY_TABLE_TYPE key_table;
-};
-
-
-/*
- * macros
- */
-
-
-# define GETU32(pt) (((u32)(pt)[0] << 24) \
- ^ ((u32)(pt)[1] << 16) \
- ^ ((u32)(pt)[2] << 8) \
- ^ ((u32)(pt)[3]))
-
-#define COPY4WORD(dst, src) \
- do { \
- (dst)[0]=(src)[0]; \
- (dst)[1]=(src)[1]; \
- (dst)[2]=(src)[2]; \
- (dst)[3]=(src)[3]; \
- }while(0)
-
-#define SWAP4WORD(word) \
- do { \
- CAMELLIA_SWAP4((word)[0]); \
- CAMELLIA_SWAP4((word)[1]); \
- CAMELLIA_SWAP4((word)[2]); \
- CAMELLIA_SWAP4((word)[3]); \
- }while(0)
-
-#define XOR4WORD(a, b)/* a = a ^ b */ \
- do { \
- (a)[0]^=(b)[0]; \
- (a)[1]^=(b)[1]; \
- (a)[2]^=(b)[2]; \
- (a)[3]^=(b)[3]; \
- }while(0)
-
-#define XOR4WORD2(a, b, c)/* a = b ^ c */ \
- do { \
- (a)[0]=(b)[0]^(c)[0]; \
- (a)[1]=(b)[1]^(c)[1]; \
- (a)[2]=(b)[2]^(c)[2]; \
- (a)[3]=(b)[3]^(c)[3]; \
- }while(0)
-
-#define CAMELLIA_SUBKEY_L(INDEX) (subkey[(INDEX)*2])
-#define CAMELLIA_SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
-
-/* rotation right shift 1byte */
-#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
-/* rotation left shift 1bit */
-#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
-/* rotation left shift 1byte */
-#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
-
-#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
- do { \
- w0 = ll; \
- ll = (ll << bits) + (lr >> (32 - bits)); \
- lr = (lr << bits) + (rl >> (32 - bits)); \
- rl = (rl << bits) + (rr >> (32 - bits)); \
- rr = (rr << bits) + (w0 >> (32 - bits)); \
- } while(0)
-
-#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
- do { \
- w0 = ll; \
- w1 = lr; \
- ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
- lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
- rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
- rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
- } while(0)
-
-#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
-#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
-#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
-#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
-
-#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
- do { \
- il = xl ^ kl; \
- ir = xr ^ kr; \
- t0 = il >> 16; \
- t1 = ir >> 16; \
- yl = CAMELLIA_SP1110(ir & 0xff) \
- ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
- ^ CAMELLIA_SP3033(t1 & 0xff) \
- ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
- yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
- ^ CAMELLIA_SP0222(t0 & 0xff) \
- ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
- ^ CAMELLIA_SP4404(il & 0xff); \
- yl ^= yr; \
- yr = CAMELLIA_RR8(yr); \
- yr ^= yl; \
- } while(0)
-
-
-/*
- * for speed up
- *
- */
-#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
- do { \
- t0 = kll; \
- t2 = krr; \
- t0 &= ll; \
- t2 |= rr; \
- rl ^= t2; \
- lr ^= CAMELLIA_RL1(t0); \
- t3 = krl; \
- t1 = klr; \
- t3 &= rl; \
- t1 |= lr; \
- ll ^= t1; \
- rr ^= CAMELLIA_RL1(t3); \
- } while(0)
-
-#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
- do { \
- ir = CAMELLIA_SP1110(xr & 0xff); \
- il = CAMELLIA_SP1110((xl>>24) & 0xff); \
- ir ^= CAMELLIA_SP0222((xr>>24) & 0xff); \
- il ^= CAMELLIA_SP0222((xl>>16) & 0xff); \
- ir ^= CAMELLIA_SP3033((xr>>16) & 0xff); \
- il ^= CAMELLIA_SP3033((xl>>8) & 0xff); \
- ir ^= CAMELLIA_SP4404((xr>>8) & 0xff); \
- il ^= CAMELLIA_SP4404(xl & 0xff); \
- il ^= kl; \
- ir ^= il ^ kr; \
- yl ^= ir; \
- yr ^= CAMELLIA_RR8(il) ^ ir; \
- } while(0)
-
-/**
- * Stuff related to the Camellia key schedule
- */
-#define SUBL(x) subL[(x)]
-#define SUBR(x) subR[(x)]
-
-
static const u32 camellia_sp1110[256] = {
0x70707000,0x82828200,0x2c2c2c00,0xececec00,
0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
@@ -475,67 +305,348 @@ static const u32 camellia_sp4404[256] = {
};
+#define CAMELLIA_MIN_KEY_SIZE 16
+#define CAMELLIA_MAX_KEY_SIZE 32
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+
+/*
+ * NB: L and R below stand for 'left' and 'right' as in written numbers.
+ * That is, in (xxxL,xxxR) pair xxxL holds most significant digits,
+ * _not_ least significant ones!
+ */
+
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ * macros
+ */
+#define GETU32(v, pt) \
+ do { \
+ /* latest breed of gcc is clever enough to use move */ \
+ memcpy(&(v), (pt), 4); \
+ (v) = be32_to_cpu(v); \
+ } while(0)
+
+/* rotation right shift 1byte */
+#define ROR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define ROL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define ROL8(x) (((x) << 8) + ((x) >> 24))
+
+#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ ll = (ll << bits) + (lr >> (32 - bits)); \
+ lr = (lr << bits) + (rl >> (32 - bits)); \
+ rl = (rl << bits) + (rr >> (32 - bits)); \
+ rr = (rr << bits) + (w0 >> (32 - bits)); \
+ } while(0)
+
+#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ w1 = lr; \
+ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+ } while(0)
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ il = xl ^ kl; \
+ ir = xr ^ kr; \
+ t0 = il >> 16; \
+ t1 = ir >> 16; \
+ yl = camellia_sp1110[(u8)(ir )] \
+ ^ camellia_sp0222[ (t1 >> 8)] \
+ ^ camellia_sp3033[(u8)(t1 )] \
+ ^ camellia_sp4404[(u8)(ir >> 8)]; \
+ yr = camellia_sp1110[ (t0 >> 8)] \
+ ^ camellia_sp0222[(u8)(t0 )] \
+ ^ camellia_sp3033[(u8)(il >> 8)] \
+ ^ camellia_sp4404[(u8)(il )]; \
+ yl ^= yr; \
+ yr = ROR8(yr); \
+ yr ^= yl; \
+ } while(0)
+
+#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
+#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
+
+static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
+{
+ u32 dw, tl, tr;
+ u32 kw4l, kw4r;
+ int i;
+
+ /* absorb kw2 to other subkeys */
+ /* round 2 */
+ subL[3] ^= subL[1]; subR[3] ^= subR[1];
+ /* round 4 */
+ subL[5] ^= subL[1]; subR[5] ^= subR[1];
+ /* round 6 */
+ subL[7] ^= subL[1]; subR[7] ^= subR[1];
+ subL[1] ^= subR[1] & ~subR[9];
+ dw = subL[1] & subL[9],
+ subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
+ /* round 8 */
+ subL[11] ^= subL[1]; subR[11] ^= subR[1];
+ /* round 10 */
+ subL[13] ^= subL[1]; subR[13] ^= subR[1];
+ /* round 12 */
+ subL[15] ^= subL[1]; subR[15] ^= subR[1];
+ subL[1] ^= subR[1] & ~subR[17];
+ dw = subL[1] & subL[17],
+ subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
+ /* round 14 */
+ subL[19] ^= subL[1]; subR[19] ^= subR[1];
+ /* round 16 */
+ subL[21] ^= subL[1]; subR[21] ^= subR[1];
+ /* round 18 */
+ subL[23] ^= subL[1]; subR[23] ^= subR[1];
+ if (max == 24) {
+ /* kw3 */
+ subL[24] ^= subL[1]; subR[24] ^= subR[1];
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subL[25]; kw4r = subR[25];
+ } else {
+ subL[1] ^= subR[1] & ~subR[25];
+ dw = subL[1] & subL[25],
+ subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
+ /* round 20 */
+ subL[27] ^= subL[1]; subR[27] ^= subR[1];
+ /* round 22 */
+ subL[29] ^= subL[1]; subR[29] ^= subR[1];
+ /* round 24 */
+ subL[31] ^= subL[1]; subR[31] ^= subR[1];
+ /* kw3 */
+ subL[32] ^= subL[1]; subR[32] ^= subR[1];
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subL[33]; kw4r = subR[33];
+ /* round 23 */
+ subL[30] ^= kw4l; subR[30] ^= kw4r;
+ /* round 21 */
+ subL[28] ^= kw4l; subR[28] ^= kw4r;
+ /* round 19 */
+ subL[26] ^= kw4l; subR[26] ^= kw4r;
+ kw4l ^= kw4r & ~subR[24];
+ dw = kw4l & subL[24],
+ kw4r ^= ROL1(dw); /* modified for FL(kl5) */
+ }
+ /* round 17 */
+ subL[22] ^= kw4l; subR[22] ^= kw4r;
+ /* round 15 */
+ subL[20] ^= kw4l; subR[20] ^= kw4r;
+ /* round 13 */
+ subL[18] ^= kw4l; subR[18] ^= kw4r;
+ kw4l ^= kw4r & ~subR[16];
+ dw = kw4l & subL[16],
+ kw4r ^= ROL1(dw); /* modified for FL(kl3) */
+ /* round 11 */
+ subL[14] ^= kw4l; subR[14] ^= kw4r;
+ /* round 9 */
+ subL[12] ^= kw4l; subR[12] ^= kw4r;
+ /* round 7 */
+ subL[10] ^= kw4l; subR[10] ^= kw4r;
+ kw4l ^= kw4r & ~subR[8];
+ dw = kw4l & subL[8],
+ kw4r ^= ROL1(dw); /* modified for FL(kl1) */
+ /* round 5 */
+ subL[6] ^= kw4l; subR[6] ^= kw4r;
+ /* round 3 */
+ subL[4] ^= kw4l; subR[4] ^= kw4r;
+ /* round 1 */
+ subL[2] ^= kw4l; subR[2] ^= kw4r;
+ /* kw1 */
+ subL[0] ^= kw4l; subR[0] ^= kw4r;
+
+ /* key XOR is end of F-function */
+ SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
+ SUBKEY_R(0) = subR[0] ^ subR[2];
+ SUBKEY_L(2) = subL[3]; /* round 1 */
+ SUBKEY_R(2) = subR[3];
+ SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
+ SUBKEY_R(3) = subR[2] ^ subR[4];
+ SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
+ SUBKEY_R(4) = subR[3] ^ subR[5];
+ SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
+ SUBKEY_R(5) = subR[4] ^ subR[6];
+ SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
+ SUBKEY_R(6) = subR[5] ^ subR[7];
+ tl = subL[10] ^ (subR[10] & ~subR[8]);
+ dw = tl & subL[8], /* FL(kl1) */
+ tr = subR[10] ^ ROL1(dw);
+ SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
+ SUBKEY_R(7) = subR[6] ^ tr;
+ SUBKEY_L(8) = subL[8]; /* FL(kl1) */
+ SUBKEY_R(8) = subR[8];
+ SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
+ SUBKEY_R(9) = subR[9];
+ tl = subL[7] ^ (subR[7] & ~subR[9]);
+ dw = tl & subL[9], /* FLinv(kl2) */
+ tr = subR[7] ^ ROL1(dw);
+ SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
+ SUBKEY_R(10) = tr ^ subR[11];
+ SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
+ SUBKEY_R(11) = subR[10] ^ subR[12];
+ SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
+ SUBKEY_R(12) = subR[11] ^ subR[13];
+ SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
+ SUBKEY_R(13) = subR[12] ^ subR[14];
+ SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
+ SUBKEY_R(14) = subR[13] ^ subR[15];
+ tl = subL[18] ^ (subR[18] & ~subR[16]);
+ dw = tl & subL[16], /* FL(kl3) */
+ tr = subR[18] ^ ROL1(dw);
+ SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
+ SUBKEY_R(15) = subR[14] ^ tr;
+ SUBKEY_L(16) = subL[16]; /* FL(kl3) */
+ SUBKEY_R(16) = subR[16];
+ SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
+ SUBKEY_R(17) = subR[17];
+ tl = subL[15] ^ (subR[15] & ~subR[17]);
+ dw = tl & subL[17], /* FLinv(kl4) */
+ tr = subR[15] ^ ROL1(dw);
+ SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
+ SUBKEY_R(18) = tr ^ subR[19];
+ SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
+ SUBKEY_R(19) = subR[18] ^ subR[20];
+ SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
+ SUBKEY_R(20) = subR[19] ^ subR[21];
+ SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
+ SUBKEY_R(21) = subR[20] ^ subR[22];
+ SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
+ SUBKEY_R(22) = subR[21] ^ subR[23];
+ if (max == 24) {
+ SUBKEY_L(23) = subL[22]; /* round 18 */
+ SUBKEY_R(23) = subR[22];
+ SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
+ SUBKEY_R(24) = subR[24] ^ subR[23];
+ } else {
+ tl = subL[26] ^ (subR[26] & ~subR[24]);
+ dw = tl & subL[24], /* FL(kl5) */
+ tr = subR[26] ^ ROL1(dw);
+ SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
+ SUBKEY_R(23) = subR[22] ^ tr;
+ SUBKEY_L(24) = subL[24]; /* FL(kl5) */
+ SUBKEY_R(24) = subR[24];
+ SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
+ SUBKEY_R(25) = subR[25];
+ tl = subL[23] ^ (subR[23] & ~subR[25]);
+ dw = tl & subL[25], /* FLinv(kl6) */
+ tr = subR[23] ^ ROL1(dw);
+ SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
+ SUBKEY_R(26) = tr ^ subR[27];
+ SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
+ SUBKEY_R(27) = subR[26] ^ subR[28];
+ SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
+ SUBKEY_R(28) = subR[27] ^ subR[29];
+ SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
+ SUBKEY_R(29) = subR[28] ^ subR[30];
+ SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
+ SUBKEY_R(30) = subR[29] ^ subR[31];
+ SUBKEY_L(31) = subL[30]; /* round 24 */
+ SUBKEY_R(31) = subR[30];
+ SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
+ SUBKEY_R(32) = subR[32] ^ subR[31];
+ }
+
+ /* apply the inverse of the last half of P-function */
+ i = 2;
+ do {
+ dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */
+ SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
+ dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */
+ SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
+ dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */
+ SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
+ dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */
+ SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
+ dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */
+ SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
+ dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */
+ SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
+ i += 8;
+ } while (i < max);
+}
static void camellia_setup128(const unsigned char *key, u32 *subkey)
{
u32 kll, klr, krl, krr;
u32 il, ir, t0, t1, w0, w1;
- u32 kw4l, kw4r, dw, tl, tr;
u32 subL[26];
u32 subR[26];
/**
- * k == kll || klr || krl || krr (|| is concatination)
- */
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
- krr = GETU32(key + 12);
- /**
- * generate KL dependent subkeys
+ * k == kll || klr || krl || krr (|| is concatenation)
*/
+ GETU32(kll, key );
+ GETU32(klr, key + 4);
+ GETU32(krl, key + 8);
+ GETU32(krr, key + 12);
+
+ /* generate KL dependent subkeys */
/* kw1 */
- SUBL(0) = kll; SUBR(0) = klr;
+ subL[0] = kll; subR[0] = klr;
/* kw2 */
- SUBL(1) = krl; SUBR(1) = krr;
+ subL[1] = krl; subR[1] = krr;
/* rotation left shift 15bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k3 */
- SUBL(4) = kll; SUBR(4) = klr;
+ subL[4] = kll; subR[4] = klr;
/* k4 */
- SUBL(5) = krl; SUBR(5) = krr;
+ subL[5] = krl; subR[5] = krr;
/* rotation left shift 15+30bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 30);
/* k7 */
- SUBL(10) = kll; SUBR(10) = klr;
+ subL[10] = kll; subR[10] = klr;
/* k8 */
- SUBL(11) = krl; SUBR(11) = krr;
+ subL[11] = krl; subR[11] = krr;
/* rotation left shift 15+30+15bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k10 */
- SUBL(13) = krl; SUBR(13) = krr;
+ subL[13] = krl; subR[13] = krr;
/* rotation left shift 15+30+15+17 bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 17);
/* kl3 */
- SUBL(16) = kll; SUBR(16) = klr;
+ subL[16] = kll; subR[16] = klr;
/* kl4 */
- SUBL(17) = krl; SUBR(17) = krr;
+ subL[17] = krl; subR[17] = krr;
/* rotation left shift 15+30+15+17+17 bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 17);
/* k13 */
- SUBL(18) = kll; SUBR(18) = klr;
+ subL[18] = kll; subR[18] = klr;
/* k14 */
- SUBL(19) = krl; SUBR(19) = krr;
+ subL[19] = krl; subR[19] = krr;
/* rotation left shift 15+30+15+17+17+17 bit */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 17);
/* k17 */
- SUBL(22) = kll; SUBR(22) = klr;
+ subL[22] = kll; subR[22] = klr;
/* k18 */
- SUBL(23) = krl; SUBR(23) = krr;
+ subL[23] = krl; subR[23] = krr;
/* generate KA */
- kll = SUBL(0); klr = SUBR(0);
- krl = SUBL(1); krr = SUBR(1);
+ kll = subL[0]; klr = subR[0];
+ krl = subL[1]; krr = subR[1];
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
w0, w1, il, ir, t0, t1);
@@ -555,306 +666,108 @@ static void camellia_setup128(const unsigned char *key, u32 *subkey)
/* generate KA dependent subkeys */
/* k1, k2 */
- SUBL(2) = kll; SUBR(2) = klr;
- SUBL(3) = krl; SUBR(3) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subL[2] = kll; subR[2] = klr;
+ subL[3] = krl; subR[3] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k5,k6 */
- SUBL(6) = kll; SUBR(6) = klr;
- SUBL(7) = krl; SUBR(7) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subL[6] = kll; subR[6] = klr;
+ subL[7] = krl; subR[7] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* kl1, kl2 */
- SUBL(8) = kll; SUBR(8) = klr;
- SUBL(9) = krl; SUBR(9) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subL[8] = kll; subR[8] = klr;
+ subL[9] = krl; subR[9] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k9 */
- SUBL(12) = kll; SUBR(12) = klr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subL[12] = kll; subR[12] = klr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k11, k12 */
- SUBL(14) = kll; SUBR(14) = klr;
- SUBL(15) = krl; SUBR(15) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subL[14] = kll; subR[14] = klr;
+ subL[15] = krl; subR[15] = krr;
+ ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
/* k15, k16 */
- SUBL(20) = kll; SUBR(20) = klr;
- SUBL(21) = krl; SUBR(21) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subL[20] = kll; subR[20] = klr;
+ subL[21] = krl; subR[21] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 17);
/* kw3, kw4 */
- SUBL(24) = kll; SUBR(24) = klr;
- SUBL(25) = krl; SUBR(25) = krr;
+ subL[24] = kll; subR[24] = klr;
+ subL[25] = krl; subR[25] = krr;
-
- /* absorb kw2 to other subkeys */
- /* round 2 */
- SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1);
- /* round 4 */
- SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1);
- /* round 6 */
- SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1);
- SUBL(1) ^= SUBR(1) & ~SUBR(9);
- dw = SUBL(1) & SUBL(9),
- SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
- /* round 8 */
- SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1);
- /* round 10 */
- SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1);
- /* round 12 */
- SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1);
- SUBL(1) ^= SUBR(1) & ~SUBR(17);
- dw = SUBL(1) & SUBL(17),
- SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
- /* round 14 */
- SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1);
- /* round 16 */
- SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1);
- /* round 18 */
- SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1);
- /* kw3 */
- SUBL(24) ^= SUBL(1); SUBR(24) ^= SUBR(1);
-
- /* absorb kw4 to other subkeys */
- kw4l = SUBL(25); kw4r = SUBR(25);
- /* round 17 */
- SUBL(22) ^= kw4l; SUBR(22) ^= kw4r;
- /* round 15 */
- SUBL(20) ^= kw4l; SUBR(20) ^= kw4r;
- /* round 13 */
- SUBL(18) ^= kw4l; SUBR(18) ^= kw4r;
- kw4l ^= kw4r & ~SUBR(16);
- dw = kw4l & SUBL(16),
- kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
- /* round 11 */
- SUBL(14) ^= kw4l; SUBR(14) ^= kw4r;
- /* round 9 */
- SUBL(12) ^= kw4l; SUBR(12) ^= kw4r;
- /* round 7 */
- SUBL(10) ^= kw4l; SUBR(10) ^= kw4r;
- kw4l ^= kw4r & ~SUBR(8);
- dw = kw4l & SUBL(8),
- kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
- /* round 5 */
- SUBL(6) ^= kw4l; SUBR(6) ^= kw4r;
- /* round 3 */
- SUBL(4) ^= kw4l; SUBR(4) ^= kw4r;
- /* round 1 */
- SUBL(2) ^= kw4l; SUBR(2) ^= kw4r;
- /* kw1 */
- SUBL(0) ^= kw4l; SUBR(0) ^= kw4r;
-
-
- /* key XOR is end of F-function */
- CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */
- CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2);
- CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */
- CAMELLIA_SUBKEY_R(2) = SUBR(3);
- CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */
- CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4);
- CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */
- CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5);
- CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */
- CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6);
- CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */
- CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7);
- tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8));
- dw = tl & SUBL(8), /* FL(kl1) */
- tr = SUBR(10) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */
- CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr;
- CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */
- CAMELLIA_SUBKEY_R(8) = SUBR(8);
- CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */
- CAMELLIA_SUBKEY_R(9) = SUBR(9);
- tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9));
- dw = tl & SUBL(9), /* FLinv(kl2) */
- tr = SUBR(7) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */
- CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11);
- CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */
- CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12);
- CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */
- CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13);
- CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */
- CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14);
- CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */
- CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15);
- tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16));
- dw = tl & SUBL(16), /* FL(kl3) */
- tr = SUBR(18) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */
- CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr;
- CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */
- CAMELLIA_SUBKEY_R(16) = SUBR(16);
- CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */
- CAMELLIA_SUBKEY_R(17) = SUBR(17);
- tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17));
- dw = tl & SUBL(17), /* FLinv(kl4) */
- tr = SUBR(15) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */
- CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19);
- CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */
- CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20);
- CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */
- CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21);
- CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */
- CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22);
- CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */
- CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23);
- CAMELLIA_SUBKEY_L(23) = SUBL(22); /* round 18 */
- CAMELLIA_SUBKEY_R(23) = SUBR(22);
- CAMELLIA_SUBKEY_L(24) = SUBL(24) ^ SUBL(23); /* kw3 */
- CAMELLIA_SUBKEY_R(24) = SUBR(24) ^ SUBR(23);
-
- /* apply the inverse of the last half of P-function */
- dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2),
- dw = CAMELLIA_RL8(dw);/* round 1 */
- CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw,
- CAMELLIA_SUBKEY_L(2) = dw;
- dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3),
- dw = CAMELLIA_RL8(dw);/* round 2 */
- CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw,
- CAMELLIA_SUBKEY_L(3) = dw;
- dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4),
- dw = CAMELLIA_RL8(dw);/* round 3 */
- CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw,
- CAMELLIA_SUBKEY_L(4) = dw;
- dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5),
- dw = CAMELLIA_RL8(dw);/* round 4 */
- CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw,
- CAMELLIA_SUBKEY_L(5) = dw;
- dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6),
- dw = CAMELLIA_RL8(dw);/* round 5 */
- CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw,
- CAMELLIA_SUBKEY_L(6) = dw;
- dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7),
- dw = CAMELLIA_RL8(dw);/* round 6 */
- CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw,
- CAMELLIA_SUBKEY_L(7) = dw;
- dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10),
- dw = CAMELLIA_RL8(dw);/* round 7 */
- CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw,
- CAMELLIA_SUBKEY_L(10) = dw;
- dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11),
- dw = CAMELLIA_RL8(dw);/* round 8 */
- CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw,
- CAMELLIA_SUBKEY_L(11) = dw;
- dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12),
- dw = CAMELLIA_RL8(dw);/* round 9 */
- CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw,
- CAMELLIA_SUBKEY_L(12) = dw;
- dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13),
- dw = CAMELLIA_RL8(dw);/* round 10 */
- CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw,
- CAMELLIA_SUBKEY_L(13) = dw;
- dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14),
- dw = CAMELLIA_RL8(dw);/* round 11 */
- CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw,
- CAMELLIA_SUBKEY_L(14) = dw;
- dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15),
- dw = CAMELLIA_RL8(dw);/* round 12 */
- CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw,
- CAMELLIA_SUBKEY_L(15) = dw;
- dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18),
- dw = CAMELLIA_RL8(dw);/* round 13 */
- CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw,
- CAMELLIA_SUBKEY_L(18) = dw;
- dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19),
- dw = CAMELLIA_RL8(dw);/* round 14 */
- CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw,
- CAMELLIA_SUBKEY_L(19) = dw;
- dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20),
- dw = CAMELLIA_RL8(dw);/* round 15 */
- CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw,
- CAMELLIA_SUBKEY_L(20) = dw;
- dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21),
- dw = CAMELLIA_RL8(dw);/* round 16 */
- CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw,
- CAMELLIA_SUBKEY_L(21) = dw;
- dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22),
- dw = CAMELLIA_RL8(dw);/* round 17 */
- CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw,
- CAMELLIA_SUBKEY_L(22) = dw;
- dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23),
- dw = CAMELLIA_RL8(dw);/* round 18 */
- CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw,
- CAMELLIA_SUBKEY_L(23) = dw;
-
- return;
+ camellia_setup_tail(subkey, subL, subR, 24);
}
-
static void camellia_setup256(const unsigned char *key, u32 *subkey)
{
- u32 kll,klr,krl,krr; /* left half of key */
- u32 krll,krlr,krrl,krrr; /* right half of key */
+ u32 kll, klr, krl, krr; /* left half of key */
+ u32 krll, krlr, krrl, krrr; /* right half of key */
u32 il, ir, t0, t1, w0, w1; /* temporary variables */
- u32 kw4l, kw4r, dw, tl, tr;
u32 subL[34];
u32 subR[34];
/**
* key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
- * (|| is concatination)
+ * (|| is concatenation)
*/
-
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
- krr = GETU32(key + 12);
- krll = GETU32(key + 16);
- krlr = GETU32(key + 20);
- krrl = GETU32(key + 24);
- krrr = GETU32(key + 28);
+ GETU32(kll, key );
+ GETU32(klr, key + 4);
+ GETU32(krl, key + 8);
+ GETU32(krr, key + 12);
+ GETU32(krll, key + 16);
+ GETU32(krlr, key + 20);
+ GETU32(krrl, key + 24);
+ GETU32(krrr, key + 28);
/* generate KL dependent subkeys */
/* kw1 */
- SUBL(0) = kll; SUBR(0) = klr;
+ subL[0] = kll; subR[0] = klr;
/* kw2 */
- SUBL(1) = krl; SUBR(1) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+ subL[1] = krl; subR[1] = krr;
+ ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
/* k9 */
- SUBL(12) = kll; SUBR(12) = klr;
+ subL[12] = kll; subR[12] = klr;
/* k10 */
- SUBL(13) = krl; SUBR(13) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subL[13] = krl; subR[13] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* kl3 */
- SUBL(16) = kll; SUBR(16) = klr;
+ subL[16] = kll; subR[16] = klr;
/* kl4 */
- SUBL(17) = krl; SUBR(17) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subL[17] = krl; subR[17] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 17);
/* k17 */
- SUBL(22) = kll; SUBR(22) = klr;
+ subL[22] = kll; subR[22] = klr;
/* k18 */
- SUBL(23) = krl; SUBR(23) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subL[23] = krl; subR[23] = krr;
+ ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
/* k23 */
- SUBL(30) = kll; SUBR(30) = klr;
+ subL[30] = kll; subR[30] = klr;
/* k24 */
- SUBL(31) = krl; SUBR(31) = krr;
+ subL[31] = krl; subR[31] = krr;
/* generate KR dependent subkeys */
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
/* k3 */
- SUBL(4) = krll; SUBR(4) = krlr;
+ subL[4] = krll; subR[4] = krlr;
/* k4 */
- SUBL(5) = krrl; SUBR(5) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subL[5] = krrl; subR[5] = krrr;
+ ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
/* kl1 */
- SUBL(8) = krll; SUBR(8) = krlr;
+ subL[8] = krll; subR[8] = krlr;
/* kl2 */
- SUBL(9) = krrl; SUBR(9) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subL[9] = krrl; subR[9] = krrr;
+ ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
/* k13 */
- SUBL(18) = krll; SUBR(18) = krlr;
+ subL[18] = krll; subR[18] = krlr;
/* k14 */
- SUBL(19) = krrl; SUBR(19) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subL[19] = krrl; subR[19] = krrr;
+ ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
/* k19 */
- SUBL(26) = krll; SUBR(26) = krlr;
+ subL[26] = krll; subR[26] = krlr;
/* k20 */
- SUBL(27) = krrl; SUBR(27) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subL[27] = krrl; subR[27] = krrr;
+ ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
/* generate KA */
- kll = SUBL(0) ^ krll; klr = SUBR(0) ^ krlr;
- krl = SUBL(1) ^ krrl; krr = SUBR(1) ^ krrr;
+ kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
+ krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
w0, w1, il, ir, t0, t1);
@@ -885,310 +798,50 @@ static void camellia_setup256(const unsigned char *key, u32 *subkey)
krll ^= w0; krlr ^= w1;
/* generate KA dependent subkeys */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ ROLDQ(kll, klr, krl, krr, w0, w1, 15);
/* k5 */
- SUBL(6) = kll; SUBR(6) = klr;
+ subL[6] = kll; subR[6] = klr;
/* k6 */
- SUBL(7) = krl; SUBR(7) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subL[7] = krl; subR[7] = krr;
+ ROLDQ(kll, klr, krl, krr, w0, w1, 30);
/* k11 */
- SUBL(14) = kll; SUBR(14) = klr;
+ subL[14] = kll; subR[14] = klr;
/* k12 */
- SUBL(15) = krl; SUBR(15) = krr;
+ subL[15] = krl; subR[15] = krr;
/* rotation left shift 32bit */
/* kl5 */
- SUBL(24) = klr; SUBR(24) = krl;
+ subL[24] = klr; subR[24] = krl;
/* kl6 */
- SUBL(25) = krr; SUBR(25) = kll;
+ subL[25] = krr; subR[25] = kll;
/* rotation left shift 49 from k11,k12 -> k21,k22 */
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+ ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
/* k21 */
- SUBL(28) = kll; SUBR(28) = klr;
+ subL[28] = kll; subR[28] = klr;
/* k22 */
- SUBL(29) = krl; SUBR(29) = krr;
+ subL[29] = krl; subR[29] = krr;
/* generate KB dependent subkeys */
/* k1 */
- SUBL(2) = krll; SUBR(2) = krlr;
+ subL[2] = krll; subR[2] = krlr;
/* k2 */
- SUBL(3) = krrl; SUBR(3) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subL[3] = krrl; subR[3] = krrr;
+ ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
/* k7 */
- SUBL(10) = krll; SUBR(10) = krlr;
+ subL[10] = krll; subR[10] = krlr;
/* k8 */
- SUBL(11) = krrl; SUBR(11) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subL[11] = krrl; subR[11] = krrr;
+ ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
/* k15 */
- SUBL(20) = krll; SUBR(20) = krlr;
+ subL[20] = krll; subR[20] = krlr;
/* k16 */
- SUBL(21) = krrl; SUBR(21) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+ subL[21] = krrl; subR[21] = krrr;
+ ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
/* kw3 */
- SUBL(32) = krll; SUBR(32) = krlr;
+ subL[32] = krll; subR[32] = krlr;
/* kw4 */
- SUBL(33) = krrl; SUBR(33) = krrr;
-
- /* absorb kw2 to other subkeys */
- /* round 2 */
- SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1);
- /* round 4 */
- SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1);
- /* round 6 */
- SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1);
- SUBL(1) ^= SUBR(1) & ~SUBR(9);
- dw = SUBL(1) & SUBL(9),
- SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
- /* round 8 */
- SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1);
- /* round 10 */
- SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1);
- /* round 12 */
- SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1);
- SUBL(1) ^= SUBR(1) & ~SUBR(17);
- dw = SUBL(1) & SUBL(17),
- SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
- /* round 14 */
- SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1);
- /* round 16 */
- SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1);
- /* round 18 */
- SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1);
- SUBL(1) ^= SUBR(1) & ~SUBR(25);
- dw = SUBL(1) & SUBL(25),
- SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */
- /* round 20 */
- SUBL(27) ^= SUBL(1); SUBR(27) ^= SUBR(1);
- /* round 22 */
- SUBL(29) ^= SUBL(1); SUBR(29) ^= SUBR(1);
- /* round 24 */
- SUBL(31) ^= SUBL(1); SUBR(31) ^= SUBR(1);
- /* kw3 */
- SUBL(32) ^= SUBL(1); SUBR(32) ^= SUBR(1);
-
-
- /* absorb kw4 to other subkeys */
- kw4l = SUBL(33); kw4r = SUBR(33);
- /* round 23 */
- SUBL(30) ^= kw4l; SUBR(30) ^= kw4r;
- /* round 21 */
- SUBL(28) ^= kw4l; SUBR(28) ^= kw4r;
- /* round 19 */
- SUBL(26) ^= kw4l; SUBR(26) ^= kw4r;
- kw4l ^= kw4r & ~SUBR(24);
- dw = kw4l & SUBL(24),
- kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */
- /* round 17 */
- SUBL(22) ^= kw4l; SUBR(22) ^= kw4r;
- /* round 15 */
- SUBL(20) ^= kw4l; SUBR(20) ^= kw4r;
- /* round 13 */
- SUBL(18) ^= kw4l; SUBR(18) ^= kw4r;
- kw4l ^= kw4r & ~SUBR(16);
- dw = kw4l & SUBL(16),
- kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
- /* round 11 */
- SUBL(14) ^= kw4l; SUBR(14) ^= kw4r;
- /* round 9 */
- SUBL(12) ^= kw4l; SUBR(12) ^= kw4r;
- /* round 7 */
- SUBL(10) ^= kw4l; SUBR(10) ^= kw4r;
- kw4l ^= kw4r & ~SUBR(8);
- dw = kw4l & SUBL(8),
- kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
- /* round 5 */
- SUBL(6) ^= kw4l; SUBR(6) ^= kw4r;
- /* round 3 */
- SUBL(4) ^= kw4l; SUBR(4) ^= kw4r;
- /* round 1 */
- SUBL(2) ^= kw4l; SUBR(2) ^= kw4r;
- /* kw1 */
- SUBL(0) ^= kw4l; SUBR(0) ^= kw4r;
+ subL[33] = krrl; subR[33] = krrr;
- /* key XOR is end of F-function */
- CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */
- CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2);
- CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */
- CAMELLIA_SUBKEY_R(2) = SUBR(3);
- CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */
- CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4);
- CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */
- CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5);
- CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */
- CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6);
- CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */
- CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7);
- tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8));
- dw = tl & SUBL(8), /* FL(kl1) */
- tr = SUBR(10) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */
- CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr;
- CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */
- CAMELLIA_SUBKEY_R(8) = SUBR(8);
- CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */
- CAMELLIA_SUBKEY_R(9) = SUBR(9);
- tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9));
- dw = tl & SUBL(9), /* FLinv(kl2) */
- tr = SUBR(7) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */
- CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11);
- CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */
- CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12);
- CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */
- CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13);
- CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */
- CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14);
- CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */
- CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15);
- tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16));
- dw = tl & SUBL(16), /* FL(kl3) */
- tr = SUBR(18) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */
- CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr;
- CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */
- CAMELLIA_SUBKEY_R(16) = SUBR(16);
- CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */
- CAMELLIA_SUBKEY_R(17) = SUBR(17);
- tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17));
- dw = tl & SUBL(17), /* FLinv(kl4) */
- tr = SUBR(15) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */
- CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19);
- CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */
- CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20);
- CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */
- CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21);
- CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */
- CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22);
- CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */
- CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23);
- tl = SUBL(26) ^ (SUBR(26)
- & ~SUBR(24));
- dw = tl & SUBL(24), /* FL(kl5) */
- tr = SUBR(26) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(23) = SUBL(22) ^ tl; /* round 18 */
- CAMELLIA_SUBKEY_R(23) = SUBR(22) ^ tr;
- CAMELLIA_SUBKEY_L(24) = SUBL(24); /* FL(kl5) */
- CAMELLIA_SUBKEY_R(24) = SUBR(24);
- CAMELLIA_SUBKEY_L(25) = SUBL(25); /* FLinv(kl6) */
- CAMELLIA_SUBKEY_R(25) = SUBR(25);
- tl = SUBL(23) ^ (SUBR(23) &
- ~SUBR(25));
- dw = tl & SUBL(25), /* FLinv(kl6) */
- tr = SUBR(23) ^ CAMELLIA_RL1(dw);
- CAMELLIA_SUBKEY_L(26) = tl ^ SUBL(27); /* round 19 */
- CAMELLIA_SUBKEY_R(26) = tr ^ SUBR(27);
- CAMELLIA_SUBKEY_L(27) = SUBL(26) ^ SUBL(28); /* round 20 */
- CAMELLIA_SUBKEY_R(27) = SUBR(26) ^ SUBR(28);
- CAMELLIA_SUBKEY_L(28) = SUBL(27) ^ SUBL(29); /* round 21 */
- CAMELLIA_SUBKEY_R(28) = SUBR(27) ^ SUBR(29);
- CAMELLIA_SUBKEY_L(29) = SUBL(28) ^ SUBL(30); /* round 22 */
- CAMELLIA_SUBKEY_R(29) = SUBR(28) ^ SUBR(30);
- CAMELLIA_SUBKEY_L(30) = SUBL(29) ^ SUBL(31); /* round 23 */
- CAMELLIA_SUBKEY_R(30) = SUBR(29) ^ SUBR(31);
- CAMELLIA_SUBKEY_L(31) = SUBL(30); /* round 24 */
- CAMELLIA_SUBKEY_R(31) = SUBR(30);
- CAMELLIA_SUBKEY_L(32) = SUBL(32) ^ SUBL(31); /* kw3 */
- CAMELLIA_SUBKEY_R(32) = SUBR(32) ^ SUBR(31);
-
- /* apply the inverse of the last half of P-function */
- dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2),
- dw = CAMELLIA_RL8(dw);/* round 1 */
- CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw,
- CAMELLIA_SUBKEY_L(2) = dw;
- dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3),
- dw = CAMELLIA_RL8(dw);/* round 2 */
- CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw,
- CAMELLIA_SUBKEY_L(3) = dw;
- dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4),
- dw = CAMELLIA_RL8(dw);/* round 3 */
- CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw,
- CAMELLIA_SUBKEY_L(4) = dw;
- dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5),
- dw = CAMELLIA_RL8(dw);/* round 4 */
- CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw,
- CAMELLIA_SUBKEY_L(5) = dw;
- dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6),
- dw = CAMELLIA_RL8(dw);/* round 5 */
- CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw,
- CAMELLIA_SUBKEY_L(6) = dw;
- dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7),
- dw = CAMELLIA_RL8(dw);/* round 6 */
- CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw,
- CAMELLIA_SUBKEY_L(7) = dw;
- dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10),
- dw = CAMELLIA_RL8(dw);/* round 7 */
- CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw,
- CAMELLIA_SUBKEY_L(10) = dw;
- dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11),
- dw = CAMELLIA_RL8(dw);/* round 8 */
- CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw,
- CAMELLIA_SUBKEY_L(11) = dw;
- dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12),
- dw = CAMELLIA_RL8(dw);/* round 9 */
- CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw,
- CAMELLIA_SUBKEY_L(12) = dw;
- dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13),
- dw = CAMELLIA_RL8(dw);/* round 10 */
- CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw,
- CAMELLIA_SUBKEY_L(13) = dw;
- dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14),
- dw = CAMELLIA_RL8(dw);/* round 11 */
- CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw,
- CAMELLIA_SUBKEY_L(14) = dw;
- dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15),
- dw = CAMELLIA_RL8(dw);/* round 12 */
- CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw,
- CAMELLIA_SUBKEY_L(15) = dw;
- dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18),
- dw = CAMELLIA_RL8(dw);/* round 13 */
- CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw,
- CAMELLIA_SUBKEY_L(18) = dw;
- dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19),
- dw = CAMELLIA_RL8(dw);/* round 14 */
- CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw,
- CAMELLIA_SUBKEY_L(19) = dw;
- dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20),
- dw = CAMELLIA_RL8(dw);/* round 15 */
- CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw,
- CAMELLIA_SUBKEY_L(20) = dw;
- dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21),
- dw = CAMELLIA_RL8(dw);/* round 16 */
- CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw,
- CAMELLIA_SUBKEY_L(21) = dw;
- dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22),
- dw = CAMELLIA_RL8(dw);/* round 17 */
- CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw,
- CAMELLIA_SUBKEY_L(22) = dw;
- dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23),
- dw = CAMELLIA_RL8(dw);/* round 18 */
- CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw,
- CAMELLIA_SUBKEY_L(23) = dw;
- dw = CAMELLIA_SUBKEY_L(26) ^ CAMELLIA_SUBKEY_R(26),
- dw = CAMELLIA_RL8(dw);/* round 19 */
- CAMELLIA_SUBKEY_R(26) = CAMELLIA_SUBKEY_L(26) ^ dw,
- CAMELLIA_SUBKEY_L(26) = dw;
- dw = CAMELLIA_SUBKEY_L(27) ^ CAMELLIA_SUBKEY_R(27),
- dw = CAMELLIA_RL8(dw);/* round 20 */
- CAMELLIA_SUBKEY_R(27) = CAMELLIA_SUBKEY_L(27) ^ dw,
- CAMELLIA_SUBKEY_L(27) = dw;
- dw = CAMELLIA_SUBKEY_L(28) ^ CAMELLIA_SUBKEY_R(28),
- dw = CAMELLIA_RL8(dw);/* round 21 */
- CAMELLIA_SUBKEY_R(28) = CAMELLIA_SUBKEY_L(28) ^ dw,
- CAMELLIA_SUBKEY_L(28) = dw;
- dw = CAMELLIA_SUBKEY_L(29) ^ CAMELLIA_SUBKEY_R(29),
- dw = CAMELLIA_RL8(dw);/* round 22 */
- CAMELLIA_SUBKEY_R(29) = CAMELLIA_SUBKEY_L(29) ^ dw,
- CAMELLIA_SUBKEY_L(29) = dw;
- dw = CAMELLIA_SUBKEY_L(30) ^ CAMELLIA_SUBKEY_R(30),
- dw = CAMELLIA_RL8(dw);/* round 23 */
- CAMELLIA_SUBKEY_R(30) = CAMELLIA_SUBKEY_L(30) ^ dw,
- CAMELLIA_SUBKEY_L(30) = dw;
- dw = CAMELLIA_SUBKEY_L(31) ^ CAMELLIA_SUBKEY_R(31),
- dw = CAMELLIA_RL8(dw);/* round 24 */
- CAMELLIA_SUBKEY_R(31) = CAMELLIA_SUBKEY_L(31) ^ dw,
- CAMELLIA_SUBKEY_L(31) = dw;
-
- return;
+ camellia_setup_tail(subkey, subL, subR, 32);
}
static void camellia_setup192(const unsigned char *key, u32 *subkey)
@@ -1197,482 +850,168 @@ static void camellia_setup192(const unsigned char *key, u32 *subkey)
u32 krll, krlr, krrl,krrr;
memcpy(kk, key, 24);
- memcpy((unsigned char *)&krll, key+16,4);
- memcpy((unsigned char *)&krlr, key+20,4);
+ memcpy((unsigned char *)&krll, key+16, 4);
+ memcpy((unsigned char *)&krlr, key+20, 4);
krrl = ~krll;
krrr = ~krlr;
memcpy(kk+24, (unsigned char *)&krrl, 4);
memcpy(kk+28, (unsigned char *)&krrr, 4);
camellia_setup256(kk, subkey);
- return;
}
-/**
- * Stuff related to camellia encryption/decryption
+/*
+ * Encrypt/decrypt
*/
-static void camellia_encrypt128(const u32 *subkey, __be32 *io_text)
-{
- u32 il,ir,t0,t1; /* temporary valiables */
-
- u32 io[4];
-
- io[0] = be32_to_cpu(io_text[0]);
- io[1] = be32_to_cpu(io_text[1]);
- io[2] = be32_to_cpu(io_text[2]);
- io[3] = be32_to_cpu(io_text[3]);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CAMELLIA_SUBKEY_L(0);
- io[1] ^= CAMELLIA_SUBKEY_R(0);
- /* main iteration */
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8),
- CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16),
- CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23),
- io[0],io[1],il,ir,t0,t1);
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+ do { \
+ t0 = kll; \
+ t2 = krr; \
+ t0 &= ll; \
+ t2 |= rr; \
+ rl ^= t2; \
+ lr ^= ROL1(t0); \
+ t3 = krl; \
+ t1 = klr; \
+ t3 &= rl; \
+ t1 |= lr; \
+ ll ^= t1; \
+ rr ^= ROL1(t3); \
+ } while(0)
- /* post whitening but kw4 */
- io[2] ^= CAMELLIA_SUBKEY_L(24);
- io[3] ^= CAMELLIA_SUBKEY_R(24);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- io_text[0] = cpu_to_be32(io[0]);
- io_text[1] = cpu_to_be32(io[1]);
- io_text[2] = cpu_to_be32(io[2]);
- io_text[3] = cpu_to_be32(io[3]);
-
- return;
-}
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
+ do { \
+ ir = camellia_sp1110[(u8)xr]; \
+ il = camellia_sp1110[ (xl >> 24)]; \
+ ir ^= camellia_sp0222[ (xr >> 24)]; \
+ il ^= camellia_sp0222[(u8)(xl >> 16)]; \
+ ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
+ il ^= camellia_sp3033[(u8)(xl >> 8)]; \
+ ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
+ il ^= camellia_sp4404[(u8)xl]; \
+ il ^= kl; \
+ ir ^= il ^ kr; \
+ yl ^= ir; \
+ yr ^= ROR8(il) ^ ir; \
+ } while(0)
-static void camellia_decrypt128(const u32 *subkey, __be32 *io_text)
+/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
+static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
{
- u32 il,ir,t0,t1; /* temporary valiables */
+ u32 il,ir,t0,t1; /* temporary variables */
- u32 io[4];
-
- io[0] = be32_to_cpu(io_text[0]);
- io[1] = be32_to_cpu(io_text[1]);
- io[2] = be32_to_cpu(io_text[2]);
- io[3] = be32_to_cpu(io_text[3]);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CAMELLIA_SUBKEY_L(24);
- io[1] ^= CAMELLIA_SUBKEY_R(24);
+ /* pre whitening but absorb kw2 */
+ io[0] ^= SUBKEY_L(0);
+ io[1] ^= SUBKEY_R(0);
/* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17),
- CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9),
- CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2),
- io[0],io[1],il,ir,t0,t1);
-
- /* post whitening but kw4 */
- io[2] ^= CAMELLIA_SUBKEY_L(0);
- io[3] ^= CAMELLIA_SUBKEY_R(0);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- io_text[0] = cpu_to_be32(io[0]);
- io_text[1] = cpu_to_be32(io[1]);
- io_text[2] = cpu_to_be32(io[2]);
- io_text[3] = cpu_to_be32(io[3]);
-
- return;
-}
-
-
-/**
- * stuff for 192 and 256bit encryption/decryption
- */
-static void camellia_encrypt256(const u32 *subkey, __be32 *io_text)
-{
- u32 il,ir,t0,t1; /* temporary valiables */
-
- u32 io[4];
-
- io[0] = be32_to_cpu(io_text[0]);
- io[1] = be32_to_cpu(io_text[1]);
- io[2] = be32_to_cpu(io_text[2]);
- io[3] = be32_to_cpu(io_text[3]);
+#define ROUNDS(i) do { \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
+ io[0],io[1],il,ir); \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
+ io[0],io[1],il,ir); \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
+ io[0],io[1],il,ir); \
+} while (0)
+#define FLS(i) do { \
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
+ SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
+ SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
+ t0,t1,il,ir); \
+} while (0)
+
+ ROUNDS(0);
+ FLS(8);
+ ROUNDS(8);
+ FLS(16);
+ ROUNDS(16);
+ if (max == 32) {
+ FLS(24);
+ ROUNDS(24);
+ }
- /* pre whitening but absorb kw2*/
- io[0] ^= CAMELLIA_SUBKEY_L(0);
- io[1] ^= CAMELLIA_SUBKEY_R(0);
-
- /* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8),
- CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16),
- CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24),
- CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31),
- io[0],io[1],il,ir,t0,t1);
+#undef ROUNDS
+#undef FLS
/* post whitening but kw4 */
- io[2] ^= CAMELLIA_SUBKEY_L(32);
- io[3] ^= CAMELLIA_SUBKEY_R(32);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- io_text[0] = cpu_to_be32(io[0]);
- io_text[1] = cpu_to_be32(io[1]);
- io_text[2] = cpu_to_be32(io[2]);
- io_text[3] = cpu_to_be32(io[3]);
-
- return;
+ io[2] ^= SUBKEY_L(max);
+ io[3] ^= SUBKEY_R(max);
+ /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
}
-
-static void camellia_decrypt256(const u32 *subkey, __be32 *io_text)
+static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
{
- u32 il,ir,t0,t1; /* temporary valiables */
+ u32 il,ir,t0,t1; /* temporary variables */
- u32 io[4];
-
- io[0] = be32_to_cpu(io_text[0]);
- io[1] = be32_to_cpu(io_text[1]);
- io[2] = be32_to_cpu(io_text[2]);
- io[3] = be32_to_cpu(io_text[3]);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CAMELLIA_SUBKEY_L(32);
- io[1] ^= CAMELLIA_SUBKEY_R(32);
+ /* pre whitening but absorb kw2 */
+ io[0] ^= SUBKEY_L(i);
+ io[1] ^= SUBKEY_R(i);
/* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25),
- CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17),
- CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9),
- CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2),
- io[0],io[1],il,ir,t0,t1);
+#define ROUNDS(i) do { \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
+ io[0],io[1],il,ir); \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
+ io[0],io[1],il,ir); \
+ CAMELLIA_ROUNDSM(io[0],io[1], \
+ SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
+ io[2],io[3],il,ir); \
+ CAMELLIA_ROUNDSM(io[2],io[3], \
+ SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
+ io[0],io[1],il,ir); \
+} while (0)
+#define FLS(i) do { \
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
+ SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
+ SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
+ t0,t1,il,ir); \
+} while (0)
+
+ if (i == 32) {
+ ROUNDS(24);
+ FLS(24);
+ }
+ ROUNDS(16);
+ FLS(16);
+ ROUNDS(8);
+ FLS(8);
+ ROUNDS(0);
+
+#undef ROUNDS
+#undef FLS
/* post whitening but kw4 */
- io[2] ^= CAMELLIA_SUBKEY_L(0);
- io[3] ^= CAMELLIA_SUBKEY_R(0);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- io_text[0] = cpu_to_be32(io[0]);
- io_text[1] = cpu_to_be32(io[1]);
- io_text[2] = cpu_to_be32(io[2]);
- io_text[3] = cpu_to_be32(io[3]);
-
- return;
+ io[2] ^= SUBKEY_L(0);
+ io[3] ^= SUBKEY_R(0);
+ /* NB: 0,1 should be swapped with 2,3 by caller! */
}
+struct camellia_ctx {
+ int key_length;
+ u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
+};
+
static int
camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
@@ -1688,7 +1027,7 @@ camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
cctx->key_length = key_len;
- switch(key_len) {
+ switch (key_len) {
case 16:
camellia_setup128(key, cctx->key_table);
break;
@@ -1698,68 +1037,59 @@ camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
case 32:
camellia_setup256(key, cctx->key_table);
break;
- default:
- break;
}
return 0;
}
-
static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)in;
__be32 *dst = (__be32 *)out;
- __be32 tmp[4];
+ u32 tmp[4];
- memcpy(tmp, src, CAMELLIA_BLOCK_SIZE);
+ tmp[0] = be32_to_cpu(src[0]);
+ tmp[1] = be32_to_cpu(src[1]);
+ tmp[2] = be32_to_cpu(src[2]);
+ tmp[3] = be32_to_cpu(src[3]);
- switch (cctx->key_length) {
- case 16:
- camellia_encrypt128(cctx->key_table, tmp);
- break;
- case 24:
- /* fall through */
- case 32:
- camellia_encrypt256(cctx->key_table, tmp);
- break;
- default:
- break;
- }
+ camellia_do_encrypt(cctx->key_table, tmp,
+ cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
+ );
- memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE);
+ /* do_encrypt returns 0,1 swapped with 2,3 */
+ dst[0] = cpu_to_be32(tmp[2]);
+ dst[1] = cpu_to_be32(tmp[3]);
+ dst[2] = cpu_to_be32(tmp[0]);
+ dst[3] = cpu_to_be32(tmp[1]);
}
-
static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)in;
__be32 *dst = (__be32 *)out;
- __be32 tmp[4];
+ u32 tmp[4];
- memcpy(tmp, src, CAMELLIA_BLOCK_SIZE);
+ tmp[0] = be32_to_cpu(src[0]);
+ tmp[1] = be32_to_cpu(src[1]);
+ tmp[2] = be32_to_cpu(src[2]);
+ tmp[3] = be32_to_cpu(src[3]);
- switch (cctx->key_length) {
- case 16:
- camellia_decrypt128(cctx->key_table, tmp);
- break;
- case 24:
- /* fall through */
- case 32:
- camellia_decrypt256(cctx->key_table, tmp);
- break;
- default:
- break;
- }
+ camellia_do_decrypt(cctx->key_table, tmp,
+ cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
+ );
- memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE);
+ /* do_decrypt returns 0,1 swapped with 2,3 */
+ dst[0] = cpu_to_be32(tmp[2]);
+ dst[1] = cpu_to_be32(tmp[3]);
+ dst[2] = cpu_to_be32(tmp[0]);
+ dst[3] = cpu_to_be32(tmp[1]);
}
-
static struct crypto_alg camellia_alg = {
.cra_name = "camellia",
.cra_driver_name = "camellia-generic",
@@ -1786,16 +1116,13 @@ static int __init camellia_init(void)
return crypto_register_alg(&camellia_alg);
}
-
static void __exit camellia_fini(void)
{
crypto_unregister_alg(&camellia_alg);
}
-
module_init(camellia_init);
module_exit(camellia_fini);
-
MODULE_DESCRIPTION("Camellia Cipher Algorithm");
MODULE_LICENSE("GPL");
diff --git a/crypto/cast6.c b/crypto/cast6.c
index 136ab6d..5fd9420 100644
--- a/crypto/cast6.c
+++ b/crypto/cast6.c
@@ -369,7 +369,7 @@ static const u8 Tr[4][8] = {
};
/* forward octave */
-static inline void W(u32 *key, unsigned int i) {
+static void W(u32 *key, unsigned int i) {
u32 I;
key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
@@ -428,7 +428,7 @@ static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key,
}
/*forward quad round*/
-static inline void Q (u32 * block, u8 * Kr, u32 * Km) {
+static void Q (u32 * block, u8 * Kr, u32 * Km) {
u32 I;
block[2] ^= F1(block[3], Kr[0], Km[0]);
block[1] ^= F2(block[2], Kr[1], Km[1]);
@@ -437,7 +437,7 @@ static inline void Q (u32 * block, u8 * Kr, u32 * Km) {
}
/*reverse quad round*/
-static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) {
+static void QBAR (u32 * block, u8 * Kr, u32 * Km) {
u32 I;
block[3] ^= F1(block[0], Kr[3], Km[3]);
block[0] ^= F3(block[1], Kr[2], Km[2]);
diff --git a/crypto/cbc.c b/crypto/cbc.c
index 1f2649e..6affff8 100644
--- a/crypto/cbc.c
+++ b/crypto/cbc.c
@@ -14,13 +14,13 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/log2.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
struct crypto_cbc_ctx {
struct crypto_cipher *child;
- void (*xor)(u8 *dst, const u8 *src, unsigned int bs);
};
static int crypto_cbc_setkey(struct crypto_tfm *parent, const u8 *key,
@@ -41,9 +41,7 @@ static int crypto_cbc_setkey(struct crypto_tfm *parent, const u8 *key,
static int crypto_cbc_encrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
@@ -54,7 +52,7 @@ static int crypto_cbc_encrypt_segment(struct blkcipher_desc *desc,
u8 *iv = walk->iv;
do {
- xor(iv, src, bsize);
+ crypto_xor(iv, src, bsize);
fn(crypto_cipher_tfm(tfm), dst, iv);
memcpy(iv, dst, bsize);
@@ -67,9 +65,7 @@ static int crypto_cbc_encrypt_segment(struct blkcipher_desc *desc,
static int crypto_cbc_encrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
@@ -79,7 +75,7 @@ static int crypto_cbc_encrypt_inplace(struct blkcipher_desc *desc,
u8 *iv = walk->iv;
do {
- xor(src, iv, bsize);
+ crypto_xor(src, iv, bsize);
fn(crypto_cipher_tfm(tfm), src, src);
iv = src;
@@ -99,7 +95,6 @@ static int crypto_cbc_encrypt(struct blkcipher_desc *desc,
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_cbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
- void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -107,11 +102,9 @@ static int crypto_cbc_encrypt(struct blkcipher_desc *desc,
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
- nbytes = crypto_cbc_encrypt_inplace(desc, &walk, child,
- xor);
+ nbytes = crypto_cbc_encrypt_inplace(desc, &walk, child);
else
- nbytes = crypto_cbc_encrypt_segment(desc, &walk, child,
- xor);
+ nbytes = crypto_cbc_encrypt_segment(desc, &walk, child);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
@@ -120,9 +113,7 @@ static int crypto_cbc_encrypt(struct blkcipher_desc *desc,
static int crypto_cbc_decrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
@@ -134,7 +125,7 @@ static int crypto_cbc_decrypt_segment(struct blkcipher_desc *desc,
do {
fn(crypto_cipher_tfm(tfm), dst, src);
- xor(dst, iv, bsize);
+ crypto_xor(dst, iv, bsize);
iv = src;
src += bsize;
@@ -148,34 +139,29 @@ static int crypto_cbc_decrypt_segment(struct blkcipher_desc *desc,
static int crypto_cbc_decrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
int bsize = crypto_cipher_blocksize(tfm);
- unsigned long alignmask = crypto_cipher_alignmask(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
- u8 stack[bsize + alignmask];
- u8 *first_iv = (u8 *)ALIGN((unsigned long)stack, alignmask + 1);
-
- memcpy(first_iv, walk->iv, bsize);
+ u8 last_iv[bsize];
/* Start of the last block. */
- src += nbytes - nbytes % bsize - bsize;
- memcpy(walk->iv, src, bsize);
+ src += nbytes - (nbytes & (bsize - 1)) - bsize;
+ memcpy(last_iv, src, bsize);
for (;;) {
fn(crypto_cipher_tfm(tfm), src, src);
if ((nbytes -= bsize) < bsize)
break;
- xor(src, src - bsize, bsize);
+ crypto_xor(src, src - bsize, bsize);
src -= bsize;
}
- xor(src, first_iv, bsize);
+ crypto_xor(src, walk->iv, bsize);
+ memcpy(walk->iv, last_iv, bsize);
return nbytes;
}
@@ -188,7 +174,6 @@ static int crypto_cbc_decrypt(struct blkcipher_desc *desc,
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_cbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
- void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -196,48 +181,15 @@ static int crypto_cbc_decrypt(struct blkcipher_desc *desc,
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
- nbytes = crypto_cbc_decrypt_inplace(desc, &walk, child,
- xor);
+ nbytes = crypto_cbc_decrypt_inplace(desc, &walk, child);
else
- nbytes = crypto_cbc_decrypt_segment(desc, &walk, child,
- xor);
+ nbytes = crypto_cbc_decrypt_segment(desc, &walk, child);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
-static void xor_byte(u8 *a, const u8 *b, unsigned int bs)
-{
- do {
- *a++ ^= *b++;
- } while (--bs);
-}
-
-static void xor_quad(u8 *dst, const u8 *src, unsigned int bs)
-{
- u32 *a = (u32 *)dst;
- u32 *b = (u32 *)src;
-
- do {
- *a++ ^= *b++;
- } while ((bs -= 4));
-}
-
-static void xor_64(u8 *a, const u8 *b, unsigned int bs)
-{
- ((u32 *)a)[0] ^= ((u32 *)b)[0];
- ((u32 *)a)[1] ^= ((u32 *)b)[1];
-}
-
-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_cbc_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_instance *inst = (void *)tfm->__crt_alg;
@@ -245,22 +197,6 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm)
struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_cipher *cipher;
- switch (crypto_tfm_alg_blocksize(tfm)) {
- case 8:
- ctx->xor = xor_64;
- break;
-
- case 16:
- ctx->xor = xor_128;
- break;
-
- default:
- if (crypto_tfm_alg_blocksize(tfm) % 4)
- ctx->xor = xor_byte;
- else
- ctx->xor = xor_quad;
- }
-
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
@@ -290,6 +226,10 @@ static struct crypto_instance *crypto_cbc_alloc(struct rtattr **tb)
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
+ inst = ERR_PTR(-EINVAL);
+ if (!is_power_of_2(alg->cra_blocksize))
+ goto out_put_alg;
+
inst = crypto_alloc_instance("cbc", alg);
if (IS_ERR(inst))
goto out_put_alg;
@@ -300,8 +240,9 @@ static struct crypto_instance *crypto_cbc_alloc(struct rtattr **tb)
inst->alg.cra_alignmask = alg->cra_alignmask;
inst->alg.cra_type = &crypto_blkcipher_type;
- if (!(alg->cra_blocksize % 4))
- inst->alg.cra_alignmask |= 3;
+ /* We access the data as u32s when xoring. */
+ inst->alg.cra_alignmask |= __alignof__(u32) - 1;
+
inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
diff --git a/crypto/ccm.c b/crypto/ccm.c
new file mode 100644
index 0000000..7cf7e5a
--- /dev/null
+++ b/crypto/ccm.c
@@ -0,0 +1,889 @@
+/*
+ * CCM: Counter with CBC-MAC
+ *
+ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+struct ccm_instance_ctx {
+ struct crypto_skcipher_spawn ctr;
+ struct crypto_spawn cipher;
+};
+
+struct crypto_ccm_ctx {
+ struct crypto_cipher *cipher;
+ struct crypto_ablkcipher *ctr;
+};
+
+struct crypto_rfc4309_ctx {
+ struct crypto_aead *child;
+ u8 nonce[3];
+};
+
+struct crypto_ccm_req_priv_ctx {
+ u8 odata[16];
+ u8 idata[16];
+ u8 auth_tag[16];
+ u32 ilen;
+ u32 flags;
+ struct scatterlist src[2];
+ struct scatterlist dst[2];
+ struct ablkcipher_request abreq;
+};
+
+static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx(
+ struct aead_request *req)
+{
+ unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
+
+ return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
+}
+
+static int set_msg_len(u8 *block, unsigned int msglen, int csize)
+{
+ __be32 data;
+
+ memset(block, 0, csize);
+ block += csize;
+
+ if (csize >= 4)
+ csize = 4;
+ else if (msglen > (1 << (8 * csize)))
+ return -EOVERFLOW;
+
+ data = cpu_to_be32(msglen);
+ memcpy(block - csize, (u8 *)&data + 4 - csize, csize);
+
+ return 0;
+}
+
+static int crypto_ccm_setkey(struct crypto_aead *aead, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_ablkcipher *ctr = ctx->ctr;
+ struct crypto_cipher *tfm = ctx->cipher;
+ int err = 0;
+
+ crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
+ crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_ablkcipher_setkey(ctr, key, keylen);
+ crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
+ CRYPTO_TFM_RES_MASK);
+ if (err)
+ goto out;
+
+ crypto_cipher_clear_flags(tfm, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(tfm, crypto_aead_get_flags(aead) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_cipher_setkey(tfm, key, keylen);
+ crypto_aead_set_flags(aead, crypto_cipher_get_flags(tfm) &
+ CRYPTO_TFM_RES_MASK);
+
+out:
+ return err;
+}
+
+static int crypto_ccm_setauthsize(struct crypto_aead *tfm,
+ unsigned int authsize)
+{
+ switch (authsize) {
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int format_input(u8 *info, struct aead_request *req,
+ unsigned int cryptlen)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ unsigned int lp = req->iv[0];
+ unsigned int l = lp + 1;
+ unsigned int m;
+
+ m = crypto_aead_authsize(aead);
+
+ memcpy(info, req->iv, 16);
+
+ /* format control info per RFC 3610 and
+ * NIST Special Publication 800-38C
+ */
+ *info |= (8 * ((m - 2) / 2));
+ if (req->assoclen)
+ *info |= 64;
+
+ return set_msg_len(info + 16 - l, cryptlen, l);
+}
+
+static int format_adata(u8 *adata, unsigned int a)
+{
+ int len = 0;
+
+ /* add control info for associated data
+ * RFC 3610 and NIST Special Publication 800-38C
+ */
+ if (a < 65280) {
+ *(__be16 *)adata = cpu_to_be16(a);
+ len = 2;
+ } else {
+ *(__be16 *)adata = cpu_to_be16(0xfffe);
+ *(__be32 *)&adata[2] = cpu_to_be32(a);
+ len = 6;
+ }
+
+ return len;
+}
+
+static void compute_mac(struct crypto_cipher *tfm, u8 *data, int n,
+ struct crypto_ccm_req_priv_ctx *pctx)
+{
+ unsigned int bs = 16;
+ u8 *odata = pctx->odata;
+ u8 *idata = pctx->idata;
+ int datalen, getlen;
+
+ datalen = n;
+
+ /* first time in here, block may be partially filled. */
+ getlen = bs - pctx->ilen;
+ if (datalen >= getlen) {
+ memcpy(idata + pctx->ilen, data, getlen);
+ crypto_xor(odata, idata, bs);
+ crypto_cipher_encrypt_one(tfm, odata, odata);
+ datalen -= getlen;
+ data += getlen;
+ pctx->ilen = 0;
+ }
+
+ /* now encrypt rest of data */
+ while (datalen >= bs) {
+ crypto_xor(odata, data, bs);
+ crypto_cipher_encrypt_one(tfm, odata, odata);
+
+ datalen -= bs;
+ data += bs;
+ }
+
+ /* check and see if there's leftover data that wasn't
+ * enough to fill a block.
+ */
+ if (datalen) {
+ memcpy(idata + pctx->ilen, data, datalen);
+ pctx->ilen += datalen;
+ }
+}
+
+static void get_data_to_compute(struct crypto_cipher *tfm,
+ struct crypto_ccm_req_priv_ctx *pctx,
+ struct scatterlist *sg, unsigned int len)
+{
+ struct scatter_walk walk;
+ u8 *data_src;
+ int n;
+
+ scatterwalk_start(&walk, sg);
+
+ while (len) {
+ n = scatterwalk_clamp(&walk, len);
+ if (!n) {
+ scatterwalk_start(&walk, sg_next(walk.sg));
+ n = scatterwalk_clamp(&walk, len);
+ }
+ data_src = scatterwalk_map(&walk, 0);
+
+ compute_mac(tfm, data_src, n, pctx);
+ len -= n;
+
+ scatterwalk_unmap(data_src, 0);
+ scatterwalk_advance(&walk, n);
+ scatterwalk_done(&walk, 0, len);
+ if (len)
+ crypto_yield(pctx->flags);
+ }
+
+ /* any leftover needs padding and then encrypted */
+ if (pctx->ilen) {
+ int padlen;
+ u8 *odata = pctx->odata;
+ u8 *idata = pctx->idata;
+
+ padlen = 16 - pctx->ilen;
+ memset(idata + pctx->ilen, 0, padlen);
+ crypto_xor(odata, idata, 16);
+ crypto_cipher_encrypt_one(tfm, odata, odata);
+ pctx->ilen = 0;
+ }
+}
+
+static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain,
+ unsigned int cryptlen)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
+ struct crypto_cipher *cipher = ctx->cipher;
+ unsigned int assoclen = req->assoclen;
+ u8 *odata = pctx->odata;
+ u8 *idata = pctx->idata;
+ int err;
+
+ /* format control data for input */
+ err = format_input(odata, req, cryptlen);
+ if (err)
+ goto out;
+
+ /* encrypt first block to use as start in computing mac */
+ crypto_cipher_encrypt_one(cipher, odata, odata);
+
+ /* format associated data and compute into mac */
+ if (assoclen) {
+ pctx->ilen = format_adata(idata, assoclen);
+ get_data_to_compute(cipher, pctx, req->assoc, req->assoclen);
+ }
+
+ /* compute plaintext into mac */
+ get_data_to_compute(cipher, pctx, plain, cryptlen);
+
+out:
+ return err;
+}
+
+static void crypto_ccm_encrypt_done(struct crypto_async_request *areq, int err)
+{
+ struct aead_request *req = areq->data;
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
+ u8 *odata = pctx->odata;
+
+ if (!err)
+ scatterwalk_map_and_copy(odata, req->dst, req->cryptlen,
+ crypto_aead_authsize(aead), 1);
+ aead_request_complete(req, err);
+}
+
+static inline int crypto_ccm_check_iv(const u8 *iv)
+{
+ /* 2 <= L <= 8, so 1 <= L' <= 7. */
+ if (1 > iv[0] || iv[0] > 7)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int crypto_ccm_encrypt(struct aead_request *req)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
+ struct ablkcipher_request *abreq = &pctx->abreq;
+ struct scatterlist *dst;
+ unsigned int cryptlen = req->cryptlen;
+ u8 *odata = pctx->odata;
+ u8 *iv = req->iv;
+ int err;
+
+ err = crypto_ccm_check_iv(iv);
+ if (err)
+ return err;
+
+ pctx->flags = aead_request_flags(req);
+
+ err = crypto_ccm_auth(req, req->src, cryptlen);
+ if (err)
+ return err;
+
+ /* Note: rfc 3610 and NIST 800-38C require counter of
+ * zero to encrypt auth tag.
+ */
+ memset(iv + 15 - iv[0], 0, iv[0] + 1);
+
+ sg_init_table(pctx->src, 2);
+ sg_set_buf(pctx->src, odata, 16);
+ scatterwalk_sg_chain(pctx->src, 2, req->src);
+
+ dst = pctx->src;
+ if (req->src != req->dst) {
+ sg_init_table(pctx->dst, 2);
+ sg_set_buf(pctx->dst, odata, 16);
+ scatterwalk_sg_chain(pctx->dst, 2, req->dst);
+ dst = pctx->dst;
+ }
+
+ ablkcipher_request_set_tfm(abreq, ctx->ctr);
+ ablkcipher_request_set_callback(abreq, pctx->flags,
+ crypto_ccm_encrypt_done, req);
+ ablkcipher_request_set_crypt(abreq, pctx->src, dst, cryptlen + 16, iv);
+ err = crypto_ablkcipher_encrypt(abreq);
+ if (err)
+ return err;
+
+ /* copy authtag to end of dst */
+ scatterwalk_map_and_copy(odata, req->dst, cryptlen,
+ crypto_aead_authsize(aead), 1);
+ return err;
+}
+
+static void crypto_ccm_decrypt_done(struct crypto_async_request *areq,
+ int err)
+{
+ struct aead_request *req = areq->data;
+ struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ unsigned int authsize = crypto_aead_authsize(aead);
+ unsigned int cryptlen = req->cryptlen - authsize;
+
+ if (!err) {
+ err = crypto_ccm_auth(req, req->dst, cryptlen);
+ if (!err && memcmp(pctx->auth_tag, pctx->odata, authsize))
+ err = -EBADMSG;
+ }
+ aead_request_complete(req, err);
+}
+
+static int crypto_ccm_decrypt(struct aead_request *req)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_ccm_req_priv_ctx *pctx = crypto_ccm_reqctx(req);
+ struct ablkcipher_request *abreq = &pctx->abreq;
+ struct scatterlist *dst;
+ unsigned int authsize = crypto_aead_authsize(aead);
+ unsigned int cryptlen = req->cryptlen;
+ u8 *authtag = pctx->auth_tag;
+ u8 *odata = pctx->odata;
+ u8 *iv = req->iv;
+ int err;
+
+ if (cryptlen < authsize)
+ return -EINVAL;
+ cryptlen -= authsize;
+
+ err = crypto_ccm_check_iv(iv);
+ if (err)
+ return err;
+
+ pctx->flags = aead_request_flags(req);
+
+ scatterwalk_map_and_copy(authtag, req->src, cryptlen, authsize, 0);
+
+ memset(iv + 15 - iv[0], 0, iv[0] + 1);
+
+ sg_init_table(pctx->src, 2);
+ sg_set_buf(pctx->src, authtag, 16);
+ scatterwalk_sg_chain(pctx->src, 2, req->src);
+
+ dst = pctx->src;
+ if (req->src != req->dst) {
+ sg_init_table(pctx->dst, 2);
+ sg_set_buf(pctx->dst, authtag, 16);
+ scatterwalk_sg_chain(pctx->dst, 2, req->dst);
+ dst = pctx->dst;
+ }
+
+ ablkcipher_request_set_tfm(abreq, ctx->ctr);
+ ablkcipher_request_set_callback(abreq, pctx->flags,
+ crypto_ccm_decrypt_done, req);
+ ablkcipher_request_set_crypt(abreq, pctx->src, dst, cryptlen + 16, iv);
+ err = crypto_ablkcipher_decrypt(abreq);
+ if (err)
+ return err;
+
+ err = crypto_ccm_auth(req, req->dst, cryptlen);
+ if (err)
+ return err;
+
+ /* verify */
+ if (memcmp(authtag, odata, authsize))
+ return -EBADMSG;
+
+ return err;
+}
+
+static int crypto_ccm_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct ccm_instance_ctx *ictx = crypto_instance_ctx(inst);
+ struct crypto_ccm_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_cipher *cipher;
+ struct crypto_ablkcipher *ctr;
+ unsigned long align;
+ int err;
+
+ cipher = crypto_spawn_cipher(&ictx->cipher);
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ ctr = crypto_spawn_skcipher(&ictx->ctr);
+ err = PTR_ERR(ctr);
+ if (IS_ERR(ctr))
+ goto err_free_cipher;
+
+ ctx->cipher = cipher;
+ ctx->ctr = ctr;
+
+ align = crypto_tfm_alg_alignmask(tfm);
+ align &= ~(crypto_tfm_ctx_alignment() - 1);
+ tfm->crt_aead.reqsize = align +
+ sizeof(struct crypto_ccm_req_priv_ctx) +
+ crypto_ablkcipher_reqsize(ctr);
+
+ return 0;
+
+err_free_cipher:
+ crypto_free_cipher(cipher);
+ return err;
+}
+
+static void crypto_ccm_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_ccm_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_cipher(ctx->cipher);
+ crypto_free_ablkcipher(ctx->ctr);
+}
+
+static struct crypto_instance *crypto_ccm_alloc_common(struct rtattr **tb,
+ const char *full_name,
+ const char *ctr_name,
+ const char *cipher_name)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_alg *ctr;
+ struct crypto_alg *cipher;
+ struct ccm_instance_ctx *ictx;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ cipher = crypto_alg_mod_lookup(cipher_name, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ err = PTR_ERR(cipher);
+ if (IS_ERR(cipher))
+ return ERR_PTR(err);
+
+ err = -EINVAL;
+ if (cipher->cra_blocksize != 16)
+ goto out_put_cipher;
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
+ err = -ENOMEM;
+ if (!inst)
+ goto out_put_cipher;
+
+ ictx = crypto_instance_ctx(inst);
+
+ err = crypto_init_spawn(&ictx->cipher, cipher, inst,
+ CRYPTO_ALG_TYPE_MASK);
+ if (err)
+ goto err_free_inst;
+
+ crypto_set_skcipher_spawn(&ictx->ctr, inst);
+ err = crypto_grab_skcipher(&ictx->ctr, ctr_name, 0,
+ crypto_requires_sync(algt->type,
+ algt->mask));
+ if (err)
+ goto err_drop_cipher;
+
+ ctr = crypto_skcipher_spawn_alg(&ictx->ctr);
+
+ /* Not a stream cipher? */
+ err = -EINVAL;
+ if (ctr->cra_blocksize != 1)
+ goto err_drop_ctr;
+
+ /* We want the real thing! */
+ if (ctr->cra_ablkcipher.ivsize != 16)
+ goto err_drop_ctr;
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "ccm_base(%s,%s)", ctr->cra_driver_name,
+ cipher->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_drop_ctr;
+
+ memcpy(inst->alg.cra_name, full_name, CRYPTO_MAX_ALG_NAME);
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+ inst->alg.cra_flags |= ctr->cra_flags & CRYPTO_ALG_ASYNC;
+ inst->alg.cra_priority = cipher->cra_priority + ctr->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = cipher->cra_alignmask | ctr->cra_alignmask |
+ (__alignof__(u32) - 1);
+ inst->alg.cra_type = &crypto_aead_type;
+ inst->alg.cra_aead.ivsize = 16;
+ inst->alg.cra_aead.maxauthsize = 16;
+ inst->alg.cra_ctxsize = sizeof(struct crypto_ccm_ctx);
+ inst->alg.cra_init = crypto_ccm_init_tfm;
+ inst->alg.cra_exit = crypto_ccm_exit_tfm;
+ inst->alg.cra_aead.setkey = crypto_ccm_setkey;
+ inst->alg.cra_aead.setauthsize = crypto_ccm_setauthsize;
+ inst->alg.cra_aead.encrypt = crypto_ccm_encrypt;
+ inst->alg.cra_aead.decrypt = crypto_ccm_decrypt;
+
+out:
+ crypto_mod_put(cipher);
+ return inst;
+
+err_drop_ctr:
+ crypto_drop_skcipher(&ictx->ctr);
+err_drop_cipher:
+ crypto_drop_spawn(&ictx->cipher);
+err_free_inst:
+ kfree(inst);
+out_put_cipher:
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static struct crypto_instance *crypto_ccm_alloc(struct rtattr **tb)
+{
+ int err;
+ const char *cipher_name;
+ char ctr_name[CRYPTO_MAX_ALG_NAME];
+ char full_name[CRYPTO_MAX_ALG_NAME];
+
+ cipher_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(cipher_name);
+ if (IS_ERR(cipher_name))
+ return ERR_PTR(err);
+
+ if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
+ cipher_name) >= CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ return crypto_ccm_alloc_common(tb, full_name, ctr_name, cipher_name);
+}
+
+static void crypto_ccm_free(struct crypto_instance *inst)
+{
+ struct ccm_instance_ctx *ctx = crypto_instance_ctx(inst);
+
+ crypto_drop_spawn(&ctx->cipher);
+ crypto_drop_skcipher(&ctx->ctr);
+ kfree(inst);
+}
+
+static struct crypto_template crypto_ccm_tmpl = {
+ .name = "ccm",
+ .alloc = crypto_ccm_alloc,
+ .free = crypto_ccm_free,
+ .module = THIS_MODULE,
+};
+
+static struct crypto_instance *crypto_ccm_base_alloc(struct rtattr **tb)
+{
+ int err;
+ const char *ctr_name;
+ const char *cipher_name;
+ char full_name[CRYPTO_MAX_ALG_NAME];
+
+ ctr_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(ctr_name);
+ if (IS_ERR(ctr_name))
+ return ERR_PTR(err);
+
+ cipher_name = crypto_attr_alg_name(tb[2]);
+ err = PTR_ERR(cipher_name);
+ if (IS_ERR(cipher_name))
+ return ERR_PTR(err);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "ccm_base(%s,%s)",
+ ctr_name, cipher_name) >= CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ return crypto_ccm_alloc_common(tb, full_name, ctr_name, cipher_name);
+}
+
+static struct crypto_template crypto_ccm_base_tmpl = {
+ .name = "ccm_base",
+ .alloc = crypto_ccm_base_alloc,
+ .free = crypto_ccm_free,
+ .module = THIS_MODULE,
+};
+
+static int crypto_rfc4309_setkey(struct crypto_aead *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
+ struct crypto_aead *child = ctx->child;
+ int err;
+
+ if (keylen < 3)
+ return -EINVAL;
+
+ keylen -= 3;
+ memcpy(ctx->nonce, key + keylen, 3);
+
+ crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_aead_setkey(child, key, keylen);
+ crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+
+ return err;
+}
+
+static int crypto_rfc4309_setauthsize(struct crypto_aead *parent,
+ unsigned int authsize)
+{
+ struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(parent);
+
+ switch (authsize) {
+ case 8:
+ case 12:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return crypto_aead_setauthsize(ctx->child, authsize);
+}
+
+static struct aead_request *crypto_rfc4309_crypt(struct aead_request *req)
+{
+ struct aead_request *subreq = aead_request_ctx(req);
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_aead *child = ctx->child;
+ u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
+ crypto_aead_alignmask(child) + 1);
+
+ /* L' */
+ iv[0] = 3;
+
+ memcpy(iv + 1, ctx->nonce, 3);
+ memcpy(iv + 4, req->iv, 8);
+
+ aead_request_set_tfm(subreq, child);
+ aead_request_set_callback(subreq, req->base.flags, req->base.complete,
+ req->base.data);
+ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv);
+ aead_request_set_assoc(subreq, req->assoc, req->assoclen);
+
+ return subreq;
+}
+
+static int crypto_rfc4309_encrypt(struct aead_request *req)
+{
+ req = crypto_rfc4309_crypt(req);
+
+ return crypto_aead_encrypt(req);
+}
+
+static int crypto_rfc4309_decrypt(struct aead_request *req)
+{
+ req = crypto_rfc4309_crypt(req);
+
+ return crypto_aead_decrypt(req);
+}
+
+static int crypto_rfc4309_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_rfc4309_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_aead *aead;
+ unsigned long align;
+
+ aead = crypto_spawn_aead(spawn);
+ if (IS_ERR(aead))
+ return PTR_ERR(aead);
+
+ ctx->child = aead;
+
+ align = crypto_aead_alignmask(aead);
+ align &= ~(crypto_tfm_ctx_alignment() - 1);
+ tfm->crt_aead.reqsize = sizeof(struct aead_request) +
+ ALIGN(crypto_aead_reqsize(aead),
+ crypto_tfm_ctx_alignment()) +
+ align + 16;
+
+ return 0;
+}
+
+static void crypto_rfc4309_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_rfc4309_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_aead(ctx->child);
+}
+
+static struct crypto_instance *crypto_rfc4309_alloc(struct rtattr **tb)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_aead_spawn *spawn;
+ struct crypto_alg *alg;
+ const char *ccm_name;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ ccm_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(ccm_name);
+ if (IS_ERR(ccm_name))
+ return ERR_PTR(err);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ spawn = crypto_instance_ctx(inst);
+ crypto_set_aead_spawn(spawn, inst);
+ err = crypto_grab_aead(spawn, ccm_name, 0,
+ crypto_requires_sync(algt->type, algt->mask));
+ if (err)
+ goto out_free_inst;
+
+ alg = crypto_aead_spawn_alg(spawn);
+
+ err = -EINVAL;
+
+ /* We only support 16-byte blocks. */
+ if (alg->cra_aead.ivsize != 16)
+ goto out_drop_alg;
+
+ /* Not a stream cipher? */
+ if (alg->cra_blocksize != 1)
+ goto out_drop_alg;
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "rfc4309(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME ||
+ snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "rfc4309(%s)", alg->cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto out_drop_alg;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+ inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = alg->cra_alignmask;
+ inst->alg.cra_type = &crypto_nivaead_type;
+
+ inst->alg.cra_aead.ivsize = 8;
+ inst->alg.cra_aead.maxauthsize = 16;
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4309_ctx);
+
+ inst->alg.cra_init = crypto_rfc4309_init_tfm;
+ inst->alg.cra_exit = crypto_rfc4309_exit_tfm;
+
+ inst->alg.cra_aead.setkey = crypto_rfc4309_setkey;
+ inst->alg.cra_aead.setauthsize = crypto_rfc4309_setauthsize;
+ inst->alg.cra_aead.encrypt = crypto_rfc4309_encrypt;
+ inst->alg.cra_aead.decrypt = crypto_rfc4309_decrypt;
+
+ inst->alg.cra_aead.geniv = "seqiv";
+
+out:
+ return inst;
+
+out_drop_alg:
+ crypto_drop_aead(spawn);
+out_free_inst:
+ kfree(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static void crypto_rfc4309_free(struct crypto_instance *inst)
+{
+ crypto_drop_spawn(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+
+static struct crypto_template crypto_rfc4309_tmpl = {
+ .name = "rfc4309",
+ .alloc = crypto_rfc4309_alloc,
+ .free = crypto_rfc4309_free,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_ccm_module_init(void)
+{
+ int err;
+
+ err = crypto_register_template(&crypto_ccm_base_tmpl);
+ if (err)
+ goto out;
+
+ err = crypto_register_template(&crypto_ccm_tmpl);
+ if (err)
+ goto out_undo_base;
+
+ err = crypto_register_template(&crypto_rfc4309_tmpl);
+ if (err)
+ goto out_undo_ccm;
+
+out:
+ return err;
+
+out_undo_ccm:
+ crypto_unregister_template(&crypto_ccm_tmpl);
+out_undo_base:
+ crypto_unregister_template(&crypto_ccm_base_tmpl);
+ goto out;
+}
+
+static void __exit crypto_ccm_module_exit(void)
+{
+ crypto_unregister_template(&crypto_rfc4309_tmpl);
+ crypto_unregister_template(&crypto_ccm_tmpl);
+ crypto_unregister_template(&crypto_ccm_base_tmpl);
+}
+
+module_init(crypto_ccm_module_init);
+module_exit(crypto_ccm_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Counter with CBC MAC");
+MODULE_ALIAS("ccm_base");
+MODULE_ALIAS("rfc4309");
diff --git a/crypto/chainiv.c b/crypto/chainiv.c
new file mode 100644
index 0000000..d17fa04
--- /dev/null
+++ b/crypto/chainiv.c
@@ -0,0 +1,331 @@
+/*
+ * chainiv: Chain IV Generator
+ *
+ * Generate IVs simply be using the last block of the previous encryption.
+ * This is mainly useful for CBC with a synchronous algorithm.
+ *
+ * Copyright (c) 2007 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.
+ *
+ */
+
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+
+enum {
+ CHAINIV_STATE_INUSE = 0,
+};
+
+struct chainiv_ctx {
+ spinlock_t lock;
+ char iv[];
+};
+
+struct async_chainiv_ctx {
+ unsigned long state;
+
+ spinlock_t lock;
+ int err;
+
+ struct crypto_queue queue;
+ struct work_struct postponed;
+
+ char iv[];
+};
+
+static int chainiv_givencrypt(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
+ unsigned int ivsize;
+ int err;
+
+ ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
+ ablkcipher_request_set_callback(subreq, req->creq.base.flags &
+ ~CRYPTO_TFM_REQ_MAY_SLEEP,
+ req->creq.base.complete,
+ req->creq.base.data);
+ ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
+ req->creq.nbytes, req->creq.info);
+
+ spin_lock_bh(&ctx->lock);
+
+ ivsize = crypto_ablkcipher_ivsize(geniv);
+
+ memcpy(req->giv, ctx->iv, ivsize);
+ memcpy(subreq->info, ctx->iv, ivsize);
+
+ err = crypto_ablkcipher_encrypt(subreq);
+ if (err)
+ goto unlock;
+
+ memcpy(ctx->iv, subreq->info, ivsize);
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return err;
+}
+
+static int chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+
+ spin_lock_bh(&ctx->lock);
+ if (crypto_ablkcipher_crt(geniv)->givencrypt !=
+ chainiv_givencrypt_first)
+ goto unlock;
+
+ crypto_ablkcipher_crt(geniv)->givencrypt = chainiv_givencrypt;
+ get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return chainiv_givencrypt(req);
+}
+
+static int chainiv_init_common(struct crypto_tfm *tfm)
+{
+ tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);
+
+ return skcipher_geniv_init(tfm);
+}
+
+static int chainiv_init(struct crypto_tfm *tfm)
+{
+ struct chainiv_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ spin_lock_init(&ctx->lock);
+
+ return chainiv_init_common(tfm);
+}
+
+static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx)
+{
+ int queued;
+
+ if (!ctx->queue.qlen) {
+ smp_mb__before_clear_bit();
+ clear_bit(CHAINIV_STATE_INUSE, &ctx->state);
+
+ if (!ctx->queue.qlen ||
+ test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state))
+ goto out;
+ }
+
+ queued = schedule_work(&ctx->postponed);
+ BUG_ON(!queued);
+
+out:
+ return ctx->err;
+}
+
+static int async_chainiv_postpone_request(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ int err;
+
+ spin_lock_bh(&ctx->lock);
+ err = skcipher_enqueue_givcrypt(&ctx->queue, req);
+ spin_unlock_bh(&ctx->lock);
+
+ if (test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state))
+ return err;
+
+ ctx->err = err;
+ return async_chainiv_schedule_work(ctx);
+}
+
+static int async_chainiv_givencrypt_tail(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
+ unsigned int ivsize = crypto_ablkcipher_ivsize(geniv);
+
+ memcpy(req->giv, ctx->iv, ivsize);
+ memcpy(subreq->info, ctx->iv, ivsize);
+
+ ctx->err = crypto_ablkcipher_encrypt(subreq);
+ if (ctx->err)
+ goto out;
+
+ memcpy(ctx->iv, subreq->info, ivsize);
+
+out:
+ return async_chainiv_schedule_work(ctx);
+}
+
+static int async_chainiv_givencrypt(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
+
+ ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
+ ablkcipher_request_set_callback(subreq, req->creq.base.flags,
+ req->creq.base.complete,
+ req->creq.base.data);
+ ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
+ req->creq.nbytes, req->creq.info);
+
+ if (test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state))
+ goto postpone;
+
+ if (ctx->queue.qlen) {
+ clear_bit(CHAINIV_STATE_INUSE, &ctx->state);
+ goto postpone;
+ }
+
+ return async_chainiv_givencrypt_tail(req);
+
+postpone:
+ return async_chainiv_postpone_request(req);
+}
+
+static int async_chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+
+ if (test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state))
+ goto out;
+
+ if (crypto_ablkcipher_crt(geniv)->givencrypt !=
+ async_chainiv_givencrypt_first)
+ goto unlock;
+
+ crypto_ablkcipher_crt(geniv)->givencrypt = async_chainiv_givencrypt;
+ get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
+
+unlock:
+ clear_bit(CHAINIV_STATE_INUSE, &ctx->state);
+
+out:
+ return async_chainiv_givencrypt(req);
+}
+
+static void async_chainiv_do_postponed(struct work_struct *work)
+{
+ struct async_chainiv_ctx *ctx = container_of(work,
+ struct async_chainiv_ctx,
+ postponed);
+ struct skcipher_givcrypt_request *req;
+ struct ablkcipher_request *subreq;
+
+ /* Only handle one request at a time to avoid hogging keventd. */
+ spin_lock_bh(&ctx->lock);
+ req = skcipher_dequeue_givcrypt(&ctx->queue);
+ spin_unlock_bh(&ctx->lock);
+
+ if (!req) {
+ async_chainiv_schedule_work(ctx);
+ return;
+ }
+
+ subreq = skcipher_givcrypt_reqctx(req);
+ subreq->base.flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ async_chainiv_givencrypt_tail(req);
+}
+
+static int async_chainiv_init(struct crypto_tfm *tfm)
+{
+ struct async_chainiv_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ spin_lock_init(&ctx->lock);
+
+ crypto_init_queue(&ctx->queue, 100);
+ INIT_WORK(&ctx->postponed, async_chainiv_do_postponed);
+
+ return chainiv_init_common(tfm);
+}
+
+static void async_chainiv_exit(struct crypto_tfm *tfm)
+{
+ struct async_chainiv_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ BUG_ON(test_bit(CHAINIV_STATE_INUSE, &ctx->state) || ctx->queue.qlen);
+
+ skcipher_geniv_exit(tfm);
+}
+
+static struct crypto_template chainiv_tmpl;
+
+static struct crypto_instance *chainiv_alloc(struct rtattr **tb)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ inst = skcipher_geniv_alloc(&chainiv_tmpl, tb, 0, 0);
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_ablkcipher.givencrypt = chainiv_givencrypt_first;
+
+ inst->alg.cra_init = chainiv_init;
+ inst->alg.cra_exit = skcipher_geniv_exit;
+
+ inst->alg.cra_ctxsize = sizeof(struct chainiv_ctx);
+
+ if (!crypto_requires_sync(algt->type, algt->mask)) {
+ inst->alg.cra_flags |= CRYPTO_ALG_ASYNC;
+
+ inst->alg.cra_ablkcipher.givencrypt =
+ async_chainiv_givencrypt_first;
+
+ inst->alg.cra_init = async_chainiv_init;
+ inst->alg.cra_exit = async_chainiv_exit;
+
+ inst->alg.cra_ctxsize = sizeof(struct async_chainiv_ctx);
+ }
+
+ inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
+
+out:
+ return inst;
+}
+
+static struct crypto_template chainiv_tmpl = {
+ .name = "chainiv",
+ .alloc = chainiv_alloc,
+ .free = skcipher_geniv_free,
+ .module = THIS_MODULE,
+};
+
+static int __init chainiv_module_init(void)
+{
+ return crypto_register_template(&chainiv_tmpl);
+}
+
+static void __exit chainiv_module_exit(void)
+{
+ crypto_unregister_template(&chainiv_tmpl);
+}
+
+module_init(chainiv_module_init);
+module_exit(chainiv_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Chain IV Generator");
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 8bf2da8..074298f 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -228,7 +228,7 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
struct crypto_alg *alg;
alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER,
- CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+ CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
@@ -236,13 +236,15 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
if (IS_ERR(inst))
goto out_put_alg;
- inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ASYNC;
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
inst->alg.cra_type = &crypto_ablkcipher_type;
inst->alg.cra_ablkcipher.ivsize = alg->cra_blkcipher.ivsize;
inst->alg.cra_ablkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
inst->alg.cra_ablkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
+ inst->alg.cra_ablkcipher.geniv = alg->cra_blkcipher.geniv;
+
inst->alg.cra_ctxsize = sizeof(struct cryptd_blkcipher_ctx);
inst->alg.cra_init = cryptd_blkcipher_init_tfm;
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index 29f7747..ff7b3de 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -16,15 +16,17 @@
* (at your option) any later version.
*
*/
+
+#include <crypto/internal/skcipher.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/crypto.h>
#include <linux/string.h>
#define NULL_KEY_SIZE 0
#define NULL_BLOCK_SIZE 1
#define NULL_DIGEST_SIZE 0
+#define NULL_IV_SIZE 0
static int null_compress(struct crypto_tfm *tfm, const u8 *src,
unsigned int slen, u8 *dst, unsigned int *dlen)
@@ -55,6 +57,26 @@ static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
memcpy(dst, src, NULL_BLOCK_SIZE);
}
+static int skcipher_null_crypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while (walk.nbytes) {
+ if (walk.src.virt.addr != walk.dst.virt.addr)
+ memcpy(walk.dst.virt.addr, walk.src.virt.addr,
+ walk.nbytes);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ return err;
+}
+
static struct crypto_alg compress_null = {
.cra_name = "compress_null",
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
@@ -76,6 +98,7 @@ static struct crypto_alg digest_null = {
.cra_list = LIST_HEAD_INIT(digest_null.cra_list),
.cra_u = { .digest = {
.dia_digestsize = NULL_DIGEST_SIZE,
+ .dia_setkey = null_setkey,
.dia_init = null_init,
.dia_update = null_update,
.dia_final = null_final } }
@@ -96,6 +119,25 @@ static struct crypto_alg cipher_null = {
.cia_decrypt = null_crypt } }
};
+static struct crypto_alg skcipher_null = {
+ .cra_name = "ecb(cipher_null)",
+ .cra_driver_name = "ecb-cipher_null",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = NULL_BLOCK_SIZE,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_ctxsize = 0,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(skcipher_null.cra_list),
+ .cra_u = { .blkcipher = {
+ .min_keysize = NULL_KEY_SIZE,
+ .max_keysize = NULL_KEY_SIZE,
+ .ivsize = NULL_IV_SIZE,
+ .setkey = null_setkey,
+ .encrypt = skcipher_null_crypt,
+ .decrypt = skcipher_null_crypt } }
+};
+
MODULE_ALIAS("compress_null");
MODULE_ALIAS("digest_null");
MODULE_ALIAS("cipher_null");
@@ -108,27 +150,35 @@ static int __init init(void)
if (ret < 0)
goto out;
+ ret = crypto_register_alg(&skcipher_null);
+ if (ret < 0)
+ goto out_unregister_cipher;
+
ret = crypto_register_alg(&digest_null);
- if (ret < 0) {
- crypto_unregister_alg(&cipher_null);
- goto out;
- }
+ if (ret < 0)
+ goto out_unregister_skcipher;
ret = crypto_register_alg(&compress_null);
- if (ret < 0) {
- crypto_unregister_alg(&digest_null);
- crypto_unregister_alg(&cipher_null);
- goto out;
- }
+ if (ret < 0)
+ goto out_unregister_digest;
out:
return ret;
+
+out_unregister_digest:
+ crypto_unregister_alg(&digest_null);
+out_unregister_skcipher:
+ crypto_unregister_alg(&skcipher_null);
+out_unregister_cipher:
+ crypto_unregister_alg(&cipher_null);
+ goto out;
}
static void __exit fini(void)
{
crypto_unregister_alg(&compress_null);
crypto_unregister_alg(&digest_null);
+ crypto_unregister_alg(&skcipher_null);
crypto_unregister_alg(&cipher_null);
}
diff --git a/crypto/ctr.c b/crypto/ctr.c
new file mode 100644
index 0000000..2d7425f
--- /dev/null
+++ b/crypto/ctr.c
@@ -0,0 +1,422 @@
+/*
+ * CTR: Counter mode
+ *
+ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/ctr.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+struct crypto_ctr_ctx {
+ struct crypto_cipher *child;
+};
+
+struct crypto_rfc3686_ctx {
+ struct crypto_blkcipher *child;
+ u8 nonce[CTR_RFC3686_NONCE_SIZE];
+};
+
+static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_ctr_ctx *ctx = crypto_tfm_ctx(parent);
+ struct crypto_cipher *child = ctx->child;
+ int err;
+
+ crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_cipher_setkey(child, key, keylen);
+ crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+
+ return err;
+}
+
+static void crypto_ctr_crypt_final(struct blkcipher_walk *walk,
+ struct crypto_cipher *tfm)
+{
+ unsigned int bsize = crypto_cipher_blocksize(tfm);
+ unsigned long alignmask = crypto_cipher_alignmask(tfm);
+ u8 *ctrblk = walk->iv;
+ u8 tmp[bsize + alignmask];
+ u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+
+ crypto_cipher_encrypt_one(tfm, keystream, ctrblk);
+ crypto_xor(keystream, src, nbytes);
+ memcpy(dst, keystream, nbytes);
+
+ crypto_inc(ctrblk, bsize);
+}
+
+static int crypto_ctr_crypt_segment(struct blkcipher_walk *walk,
+ struct crypto_cipher *tfm)
+{
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+ crypto_cipher_alg(tfm)->cia_encrypt;
+ unsigned int bsize = crypto_cipher_blocksize(tfm);
+ u8 *ctrblk = walk->iv;
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+
+ do {
+ /* create keystream */
+ fn(crypto_cipher_tfm(tfm), dst, ctrblk);
+ crypto_xor(dst, src, bsize);
+
+ /* increment counter in counterblock */
+ crypto_inc(ctrblk, bsize);
+
+ src += bsize;
+ dst += bsize;
+ } while ((nbytes -= bsize) >= bsize);
+
+ return nbytes;
+}
+
+static int crypto_ctr_crypt_inplace(struct blkcipher_walk *walk,
+ struct crypto_cipher *tfm)
+{
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+ crypto_cipher_alg(tfm)->cia_encrypt;
+ unsigned int bsize = crypto_cipher_blocksize(tfm);
+ unsigned long alignmask = crypto_cipher_alignmask(tfm);
+ unsigned int nbytes = walk->nbytes;
+ u8 *ctrblk = walk->iv;
+ u8 *src = walk->src.virt.addr;
+ u8 tmp[bsize + alignmask];
+ u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+
+ do {
+ /* create keystream */
+ fn(crypto_cipher_tfm(tfm), keystream, ctrblk);
+ crypto_xor(src, keystream, bsize);
+
+ /* increment counter in counterblock */
+ crypto_inc(ctrblk, bsize);
+
+ src += bsize;
+ } while ((nbytes -= bsize) >= bsize);
+
+ return nbytes;
+}
+
+static int crypto_ctr_crypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct crypto_ctr_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ struct crypto_cipher *child = ctx->child;
+ unsigned int bsize = crypto_cipher_blocksize(child);
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, bsize);
+
+ while (walk.nbytes >= bsize) {
+ if (walk.src.virt.addr == walk.dst.virt.addr)
+ nbytes = crypto_ctr_crypt_inplace(&walk, child);
+ else
+ nbytes = crypto_ctr_crypt_segment(&walk, child);
+
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ if (walk.nbytes) {
+ crypto_ctr_crypt_final(&walk, child);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ return err;
+}
+
+static int crypto_ctr_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_ctr_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_cipher *cipher;
+
+ cipher = crypto_spawn_cipher(spawn);
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ ctx->child = cipher;
+
+ return 0;
+}
+
+static void crypto_ctr_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_ctr_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_cipher(ctx->child);
+}
+
+static struct crypto_instance *crypto_ctr_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
+
+ alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ if (IS_ERR(alg))
+ return ERR_PTR(PTR_ERR(alg));
+
+ /* Block size must be >= 4 bytes. */
+ err = -EINVAL;
+ if (alg->cra_blocksize < 4)
+ goto out_put_alg;
+
+ /* If this is false we'd fail the alignment of crypto_inc. */
+ if (alg->cra_blocksize % 4)
+ goto out_put_alg;
+
+ inst = crypto_alloc_instance("ctr", alg);
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = alg->cra_alignmask | (__alignof__(u32) - 1);
+ inst->alg.cra_type = &crypto_blkcipher_type;
+
+ inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
+ inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
+ inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_ctr_ctx);
+
+ inst->alg.cra_init = crypto_ctr_init_tfm;
+ inst->alg.cra_exit = crypto_ctr_exit_tfm;
+
+ inst->alg.cra_blkcipher.setkey = crypto_ctr_setkey;
+ inst->alg.cra_blkcipher.encrypt = crypto_ctr_crypt;
+ inst->alg.cra_blkcipher.decrypt = crypto_ctr_crypt;
+
+out:
+ crypto_mod_put(alg);
+ return inst;
+
+out_put_alg:
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static void crypto_ctr_free(struct crypto_instance *inst)
+{
+ crypto_drop_spawn(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+
+static struct crypto_template crypto_ctr_tmpl = {
+ .name = "ctr",
+ .alloc = crypto_ctr_alloc,
+ .free = crypto_ctr_free,
+ .module = THIS_MODULE,
+};
+
+static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(parent);
+ struct crypto_blkcipher *child = ctx->child;
+ int err;
+
+ /* the nonce is stored in bytes at end of key */
+ if (keylen < CTR_RFC3686_NONCE_SIZE)
+ return -EINVAL;
+
+ memcpy(ctx->nonce, key + (keylen - CTR_RFC3686_NONCE_SIZE),
+ CTR_RFC3686_NONCE_SIZE);
+
+ keylen -= CTR_RFC3686_NONCE_SIZE;
+
+ crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_blkcipher_setkey(child, key, keylen);
+ crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+
+ return err;
+}
+
+static int crypto_rfc3686_crypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct crypto_rfc3686_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ struct crypto_blkcipher *child = ctx->child;
+ unsigned long alignmask = crypto_blkcipher_alignmask(tfm);
+ u8 ivblk[CTR_RFC3686_BLOCK_SIZE + alignmask];
+ u8 *iv = PTR_ALIGN(ivblk + 0, alignmask + 1);
+ u8 *info = desc->info;
+ int err;
+
+ /* set up counter block */
+ memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
+ memcpy(iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE);
+
+ /* initialize counter portion of counter block */
+ *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
+ cpu_to_be32(1);
+
+ desc->tfm = child;
+ desc->info = iv;
+ err = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
+ desc->tfm = tfm;
+ desc->info = info;
+
+ return err;
+}
+
+static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_blkcipher *cipher;
+
+ cipher = crypto_spawn_blkcipher(spawn);
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ ctx->child = cipher;
+
+ return 0;
+}
+
+static void crypto_rfc3686_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_blkcipher(ctx->child);
+}
+
+static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
+
+ alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ err = PTR_ERR(alg);
+ if (IS_ERR(alg))
+ return ERR_PTR(err);
+
+ /* We only support 16-byte blocks. */
+ err = -EINVAL;
+ if (alg->cra_blkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE)
+ goto out_put_alg;
+
+ /* Not a stream cipher? */
+ if (alg->cra_blocksize != 1)
+ goto out_put_alg;
+
+ inst = crypto_alloc_instance("rfc3686", alg);
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = alg->cra_alignmask;
+ inst->alg.cra_type = &crypto_blkcipher_type;
+
+ inst->alg.cra_blkcipher.ivsize = CTR_RFC3686_IV_SIZE;
+ inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize
+ + CTR_RFC3686_NONCE_SIZE;
+ inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize
+ + CTR_RFC3686_NONCE_SIZE;
+
+ inst->alg.cra_blkcipher.geniv = "seqiv";
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx);
+
+ inst->alg.cra_init = crypto_rfc3686_init_tfm;
+ inst->alg.cra_exit = crypto_rfc3686_exit_tfm;
+
+ inst->alg.cra_blkcipher.setkey = crypto_rfc3686_setkey;
+ inst->alg.cra_blkcipher.encrypt = crypto_rfc3686_crypt;
+ inst->alg.cra_blkcipher.decrypt = crypto_rfc3686_crypt;
+
+out:
+ crypto_mod_put(alg);
+ return inst;
+
+out_put_alg:
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static struct crypto_template crypto_rfc3686_tmpl = {
+ .name = "rfc3686",
+ .alloc = crypto_rfc3686_alloc,
+ .free = crypto_ctr_free,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_ctr_module_init(void)
+{
+ int err;
+
+ err = crypto_register_template(&crypto_ctr_tmpl);
+ if (err)
+ goto out;
+
+ err = crypto_register_template(&crypto_rfc3686_tmpl);
+ if (err)
+ goto out_drop_ctr;
+
+out:
+ return err;
+
+out_drop_ctr:
+ crypto_unregister_template(&crypto_ctr_tmpl);
+ goto out;
+}
+
+static void __exit crypto_ctr_module_exit(void)
+{
+ crypto_unregister_template(&crypto_rfc3686_tmpl);
+ crypto_unregister_template(&crypto_ctr_tmpl);
+}
+
+module_init(crypto_ctr_module_init);
+module_exit(crypto_ctr_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CTR Counter block mode");
+MODULE_ALIAS("rfc3686");
diff --git a/crypto/des_generic.c b/crypto/des_generic.c
index 59966d1..355ecb7 100644
--- a/crypto/des_generic.c
+++ b/crypto/des_generic.c
@@ -20,13 +20,7 @@
#include <linux/crypto.h>
#include <linux/types.h>
-#define DES_KEY_SIZE 8
-#define DES_EXPKEY_WORDS 32
-#define DES_BLOCK_SIZE 8
-
-#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
-#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
-#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
+#include <crypto/des.h>
#define ROL(x, r) ((x) = rol32((x), (r)))
#define ROR(x, r) ((x) = ror32((x), (r)))
@@ -634,7 +628,7 @@ static const u32 S8[64] = {
* Choice 1 has operated on the key.
*
*/
-static unsigned long ekey(u32 *pe, const u8 *k)
+unsigned long des_ekey(u32 *pe, const u8 *k)
{
/* K&R: long is at least 32 bits */
unsigned long a, b, c, d, w;
@@ -709,6 +703,7 @@ static unsigned long ekey(u32 *pe, const u8 *k)
/* Zero if weak key */
return w;
}
+EXPORT_SYMBOL_GPL(des_ekey);
/*
* Decryption key expansion
@@ -792,7 +787,7 @@ static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
int ret;
/* Expand to tmp */
- ret = ekey(tmp, key);
+ ret = des_ekey(tmp, key);
if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
@@ -879,9 +874,9 @@ static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
return -EINVAL;
}
- ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
+ des_ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
- ekey(expkey, key);
+ des_ekey(expkey, key);
return 0;
}
diff --git a/crypto/digest.c b/crypto/digest.c
index 8871dec..6fd43bd 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -12,6 +12,7 @@
*
*/
+#include <crypto/scatterwalk.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/hardirq.h>
@@ -20,9 +21,6 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
-#include "internal.h"
-#include "scatterwalk.h"
-
static int init(struct hash_desc *desc)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
new file mode 100644
index 0000000..eb90d27
--- /dev/null
+++ b/crypto/eseqiv.c
@@ -0,0 +1,264 @@
+/*
+ * eseqiv: Encrypted Sequence Number IV Generator
+ *
+ * This generator generates an IV based on a sequence number by xoring it
+ * with a salt and then encrypting it with the same key as used to encrypt
+ * the plain text. This algorithm requires that the block size be equal
+ * to the IV size. It is mainly useful for CBC.
+ *
+ * Copyright (c) 2007 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.
+ *
+ */
+
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+struct eseqiv_request_ctx {
+ struct scatterlist src[2];
+ struct scatterlist dst[2];
+ char tail[];
+};
+
+struct eseqiv_ctx {
+ spinlock_t lock;
+ unsigned int reqoff;
+ char salt[];
+};
+
+static void eseqiv_complete2(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct eseqiv_request_ctx *reqctx = skcipher_givcrypt_reqctx(req);
+
+ memcpy(req->giv, PTR_ALIGN((u8 *)reqctx->tail,
+ crypto_ablkcipher_alignmask(geniv) + 1),
+ crypto_ablkcipher_ivsize(geniv));
+}
+
+static void eseqiv_complete(struct crypto_async_request *base, int err)
+{
+ struct skcipher_givcrypt_request *req = base->data;
+
+ if (err)
+ goto out;
+
+ eseqiv_complete2(req);
+
+out:
+ skcipher_givcrypt_complete(req, err);
+}
+
+static void eseqiv_chain(struct scatterlist *head, struct scatterlist *sg,
+ int chain)
+{
+ if (chain) {
+ head->length += sg->length;
+ sg = scatterwalk_sg_next(sg);
+ }
+
+ if (sg)
+ scatterwalk_sg_chain(head, 2, sg);
+ else
+ sg_mark_end(head);
+}
+
+static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ struct eseqiv_request_ctx *reqctx = skcipher_givcrypt_reqctx(req);
+ struct ablkcipher_request *subreq;
+ crypto_completion_t complete;
+ void *data;
+ struct scatterlist *osrc, *odst;
+ struct scatterlist *dst;
+ struct page *srcp;
+ struct page *dstp;
+ u8 *giv;
+ u8 *vsrc;
+ u8 *vdst;
+ __be64 seq;
+ unsigned int ivsize;
+ unsigned int len;
+ int err;
+
+ subreq = (void *)(reqctx->tail + ctx->reqoff);
+ ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
+
+ giv = req->giv;
+ complete = req->creq.base.complete;
+ data = req->creq.base.data;
+
+ osrc = req->creq.src;
+ odst = req->creq.dst;
+ srcp = sg_page(osrc);
+ dstp = sg_page(odst);
+ vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + osrc->offset;
+ vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + odst->offset;
+
+ ivsize = crypto_ablkcipher_ivsize(geniv);
+
+ if (vsrc != giv + ivsize && vdst != giv + ivsize) {
+ giv = PTR_ALIGN((u8 *)reqctx->tail,
+ crypto_ablkcipher_alignmask(geniv) + 1);
+ complete = eseqiv_complete;
+ data = req;
+ }
+
+ ablkcipher_request_set_callback(subreq, req->creq.base.flags, complete,
+ data);
+
+ sg_init_table(reqctx->src, 2);
+ sg_set_buf(reqctx->src, giv, ivsize);
+ eseqiv_chain(reqctx->src, osrc, vsrc == giv + ivsize);
+
+ dst = reqctx->src;
+ if (osrc != odst) {
+ sg_init_table(reqctx->dst, 2);
+ sg_set_buf(reqctx->dst, giv, ivsize);
+ eseqiv_chain(reqctx->dst, odst, vdst == giv + ivsize);
+
+ dst = reqctx->dst;
+ }
+
+ ablkcipher_request_set_crypt(subreq, reqctx->src, dst,
+ req->creq.nbytes, req->creq.info);
+
+ memcpy(req->creq.info, ctx->salt, ivsize);
+
+ len = ivsize;
+ if (ivsize > sizeof(u64)) {
+ memset(req->giv, 0, ivsize - sizeof(u64));
+ len = sizeof(u64);
+ }
+ seq = cpu_to_be64(req->seq);
+ memcpy(req->giv + ivsize - len, &seq, len);
+
+ err = crypto_ablkcipher_encrypt(subreq);
+ if (err)
+ goto out;
+
+ eseqiv_complete2(req);
+
+out:
+ return err;
+}
+
+static int eseqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+
+ spin_lock_bh(&ctx->lock);
+ if (crypto_ablkcipher_crt(geniv)->givencrypt != eseqiv_givencrypt_first)
+ goto unlock;
+
+ crypto_ablkcipher_crt(geniv)->givencrypt = eseqiv_givencrypt;
+ get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return eseqiv_givencrypt(req);
+}
+
+static int eseqiv_init(struct crypto_tfm *tfm)
+{
+ struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
+ struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ unsigned long alignmask;
+ unsigned int reqsize;
+
+ spin_lock_init(&ctx->lock);
+
+ alignmask = crypto_tfm_ctx_alignment() - 1;
+ reqsize = sizeof(struct eseqiv_request_ctx);
+
+ if (alignmask & reqsize) {
+ alignmask &= reqsize;
+ alignmask--;
+ }
+
+ alignmask = ~alignmask;
+ alignmask &= crypto_ablkcipher_alignmask(geniv);
+
+ reqsize += alignmask;
+ reqsize += crypto_ablkcipher_ivsize(geniv);
+ reqsize = ALIGN(reqsize, crypto_tfm_ctx_alignment());
+
+ ctx->reqoff = reqsize - sizeof(struct eseqiv_request_ctx);
+
+ tfm->crt_ablkcipher.reqsize = reqsize +
+ sizeof(struct ablkcipher_request);
+
+ return skcipher_geniv_init(tfm);
+}
+
+static struct crypto_template eseqiv_tmpl;
+
+static struct crypto_instance *eseqiv_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+ int err;
+
+ inst = skcipher_geniv_alloc(&eseqiv_tmpl, tb, 0, 0);
+ if (IS_ERR(inst))
+ goto out;
+
+ err = -EINVAL;
+ if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize)
+ goto free_inst;
+
+ inst->alg.cra_ablkcipher.givencrypt = eseqiv_givencrypt_first;
+
+ inst->alg.cra_init = eseqiv_init;
+ inst->alg.cra_exit = skcipher_geniv_exit;
+
+ inst->alg.cra_ctxsize = sizeof(struct eseqiv_ctx);
+ inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
+
+out:
+ return inst;
+
+free_inst:
+ skcipher_geniv_free(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static struct crypto_template eseqiv_tmpl = {
+ .name = "eseqiv",
+ .alloc = eseqiv_alloc,
+ .free = skcipher_geniv_free,
+ .module = THIS_MODULE,
+};
+
+static int __init eseqiv_module_init(void)
+{
+ return crypto_register_template(&eseqiv_tmpl);
+}
+
+static void __exit eseqiv_module_exit(void)
+{
+ crypto_unregister_template(&eseqiv_tmpl);
+}
+
+module_init(eseqiv_module_init);
+module_exit(eseqiv_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Encrypted Sequence Number IV Generator");
diff --git a/crypto/gcm.c b/crypto/gcm.c
new file mode 100644
index 0000000..e70afd0
--- /dev/null
+++ b/crypto/gcm.c
@@ -0,0 +1,823 @@
+/*
+ * GCM: Galois/Counter Mode.
+ *
+ * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <crypto/gf128mul.h>
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+struct gcm_instance_ctx {
+ struct crypto_skcipher_spawn ctr;
+};
+
+struct crypto_gcm_ctx {
+ struct crypto_ablkcipher *ctr;
+ struct gf128mul_4k *gf128;
+};
+
+struct crypto_rfc4106_ctx {
+ struct crypto_aead *child;
+ u8 nonce[4];
+};
+
+struct crypto_gcm_ghash_ctx {
+ u32 bytes;
+ u32 flags;
+ struct gf128mul_4k *gf128;
+ u8 buffer[16];
+};
+
+struct crypto_gcm_req_priv_ctx {
+ u8 auth_tag[16];
+ u8 iauth_tag[16];
+ struct scatterlist src[2];
+ struct scatterlist dst[2];
+ struct crypto_gcm_ghash_ctx ghash;
+ struct ablkcipher_request abreq;
+};
+
+struct crypto_gcm_setkey_result {
+ int err;
+ struct completion completion;
+};
+
+static inline struct crypto_gcm_req_priv_ctx *crypto_gcm_reqctx(
+ struct aead_request *req)
+{
+ unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
+
+ return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
+}
+
+static void crypto_gcm_ghash_init(struct crypto_gcm_ghash_ctx *ctx, u32 flags,
+ struct gf128mul_4k *gf128)
+{
+ ctx->bytes = 0;
+ ctx->flags = flags;
+ ctx->gf128 = gf128;
+ memset(ctx->buffer, 0, 16);
+}
+
+static void crypto_gcm_ghash_update(struct crypto_gcm_ghash_ctx *ctx,
+ const u8 *src, unsigned int srclen)
+{
+ u8 *dst = ctx->buffer;
+
+ if (ctx->bytes) {
+ int n = min(srclen, ctx->bytes);
+ u8 *pos = dst + (16 - ctx->bytes);
+
+ ctx->bytes -= n;
+ srclen -= n;
+
+ while (n--)
+ *pos++ ^= *src++;
+
+ if (!ctx->bytes)
+ gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+ }
+
+ while (srclen >= 16) {
+ crypto_xor(dst, src, 16);
+ gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+ src += 16;
+ srclen -= 16;
+ }
+
+ if (srclen) {
+ ctx->bytes = 16 - srclen;
+ while (srclen--)
+ *dst++ ^= *src++;
+ }
+}
+
+static void crypto_gcm_ghash_update_sg(struct crypto_gcm_ghash_ctx *ctx,
+ struct scatterlist *sg, int len)
+{
+ struct scatter_walk walk;
+ u8 *src;
+ int n;
+
+ if (!len)
+ return;
+
+ scatterwalk_start(&walk, sg);
+
+ while (len) {
+ n = scatterwalk_clamp(&walk, len);
+
+ if (!n) {
+ scatterwalk_start(&walk, scatterwalk_sg_next(walk.sg));
+ n = scatterwalk_clamp(&walk, len);
+ }
+
+ src = scatterwalk_map(&walk, 0);
+
+ crypto_gcm_ghash_update(ctx, src, n);
+ len -= n;
+
+ scatterwalk_unmap(src, 0);
+ scatterwalk_advance(&walk, n);
+ scatterwalk_done(&walk, 0, len);
+ if (len)
+ crypto_yield(ctx->flags);
+ }
+}
+
+static void crypto_gcm_ghash_flush(struct crypto_gcm_ghash_ctx *ctx)
+{
+ u8 *dst = ctx->buffer;
+
+ if (ctx->bytes) {
+ u8 *tmp = dst + (16 - ctx->bytes);
+
+ while (ctx->bytes--)
+ *tmp++ ^= 0;
+
+ gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+ }
+
+ ctx->bytes = 0;
+}
+
+static void crypto_gcm_ghash_final_xor(struct crypto_gcm_ghash_ctx *ctx,
+ unsigned int authlen,
+ unsigned int cryptlen, u8 *dst)
+{
+ u8 *buf = ctx->buffer;
+ u128 lengths;
+
+ lengths.a = cpu_to_be64(authlen * 8);
+ lengths.b = cpu_to_be64(cryptlen * 8);
+
+ crypto_gcm_ghash_flush(ctx);
+ crypto_xor(buf, (u8 *)&lengths, 16);
+ gf128mul_4k_lle((be128 *)buf, ctx->gf128);
+ crypto_xor(dst, buf, 16);
+}
+
+static void crypto_gcm_setkey_done(struct crypto_async_request *req, int err)
+{
+ struct crypto_gcm_setkey_result *result = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ result->err = err;
+ complete(&result->completion);
+}
+
+static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_ablkcipher *ctr = ctx->ctr;
+ struct {
+ be128 hash;
+ u8 iv[8];
+
+ struct crypto_gcm_setkey_result result;
+
+ struct scatterlist sg[1];
+ struct ablkcipher_request req;
+ } *data;
+ int err;
+
+ crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
+ crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
+ CRYPTO_TFM_REQ_MASK);
+
+ err = crypto_ablkcipher_setkey(ctr, key, keylen);
+ if (err)
+ return err;
+
+ crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
+ CRYPTO_TFM_RES_MASK);
+
+ data = kzalloc(sizeof(*data) + crypto_ablkcipher_reqsize(ctr),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ init_completion(&data->result.completion);
+ sg_init_one(data->sg, &data->hash, sizeof(data->hash));
+ ablkcipher_request_set_tfm(&data->req, ctr);
+ ablkcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
+ CRYPTO_TFM_REQ_MAY_BACKLOG,
+ crypto_gcm_setkey_done,
+ &data->result);
+ ablkcipher_request_set_crypt(&data->req, data->sg, data->sg,
+ sizeof(data->hash), data->iv);
+
+ err = crypto_ablkcipher_encrypt(&data->req);
+ if (err == -EINPROGRESS || err == -EBUSY) {
+ err = wait_for_completion_interruptible(
+ &data->result.completion);
+ if (!err)
+ err = data->result.err;
+ }
+
+ if (err)
+ goto out;
+
+ if (ctx->gf128 != NULL)
+ gf128mul_free_4k(ctx->gf128);
+
+ ctx->gf128 = gf128mul_init_4k_lle(&data->hash);
+
+ if (ctx->gf128 == NULL)
+ err = -ENOMEM;
+
+out:
+ kfree(data);
+ return err;
+}
+
+static int crypto_gcm_setauthsize(struct crypto_aead *tfm,
+ unsigned int authsize)
+{
+ switch (authsize) {
+ case 4:
+ case 8:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void crypto_gcm_init_crypt(struct ablkcipher_request *ablk_req,
+ struct aead_request *req,
+ unsigned int cryptlen)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
+ u32 flags = req->base.tfm->crt_flags;
+ struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
+ struct scatterlist *dst;
+ __be32 counter = cpu_to_be32(1);
+
+ memset(pctx->auth_tag, 0, sizeof(pctx->auth_tag));
+ memcpy(req->iv + 12, &counter, 4);
+
+ sg_init_table(pctx->src, 2);
+ sg_set_buf(pctx->src, pctx->auth_tag, sizeof(pctx->auth_tag));
+ scatterwalk_sg_chain(pctx->src, 2, req->src);
+
+ dst = pctx->src;
+ if (req->src != req->dst) {
+ sg_init_table(pctx->dst, 2);
+ sg_set_buf(pctx->dst, pctx->auth_tag, sizeof(pctx->auth_tag));
+ scatterwalk_sg_chain(pctx->dst, 2, req->dst);
+ dst = pctx->dst;
+ }
+
+ ablkcipher_request_set_tfm(ablk_req, ctx->ctr);
+ ablkcipher_request_set_crypt(ablk_req, pctx->src, dst,
+ cryptlen + sizeof(pctx->auth_tag),
+ req->iv);
+
+ crypto_gcm_ghash_init(ghash, flags, ctx->gf128);
+
+ crypto_gcm_ghash_update_sg(ghash, req->assoc, req->assoclen);
+ crypto_gcm_ghash_flush(ghash);
+}
+
+static int crypto_gcm_hash(struct aead_request *req)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
+ u8 *auth_tag = pctx->auth_tag;
+ struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
+
+ crypto_gcm_ghash_update_sg(ghash, req->dst, req->cryptlen);
+ crypto_gcm_ghash_final_xor(ghash, req->assoclen, req->cryptlen,
+ auth_tag);
+
+ scatterwalk_map_and_copy(auth_tag, req->dst, req->cryptlen,
+ crypto_aead_authsize(aead), 1);
+ return 0;
+}
+
+static void crypto_gcm_encrypt_done(struct crypto_async_request *areq, int err)
+{
+ struct aead_request *req = areq->data;
+
+ if (!err)
+ err = crypto_gcm_hash(req);
+
+ aead_request_complete(req, err);
+}
+
+static int crypto_gcm_encrypt(struct aead_request *req)
+{
+ struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
+ struct ablkcipher_request *abreq = &pctx->abreq;
+ int err;
+
+ crypto_gcm_init_crypt(abreq, req, req->cryptlen);
+ ablkcipher_request_set_callback(abreq, aead_request_flags(req),
+ crypto_gcm_encrypt_done, req);
+
+ err = crypto_ablkcipher_encrypt(abreq);
+ if (err)
+ return err;
+
+ return crypto_gcm_hash(req);
+}
+
+static int crypto_gcm_verify(struct aead_request *req)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
+ struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
+ u8 *auth_tag = pctx->auth_tag;
+ u8 *iauth_tag = pctx->iauth_tag;
+ unsigned int authsize = crypto_aead_authsize(aead);
+ unsigned int cryptlen = req->cryptlen - authsize;
+
+ crypto_gcm_ghash_final_xor(ghash, req->assoclen, cryptlen, auth_tag);
+
+ authsize = crypto_aead_authsize(aead);
+ scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
+ return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
+}
+
+static void crypto_gcm_decrypt_done(struct crypto_async_request *areq, int err)
+{
+ struct aead_request *req = areq->data;
+
+ if (!err)
+ err = crypto_gcm_verify(req);
+
+ aead_request_complete(req, err);
+}
+
+static int crypto_gcm_decrypt(struct aead_request *req)
+{
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
+ struct ablkcipher_request *abreq = &pctx->abreq;
+ struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
+ unsigned int cryptlen = req->cryptlen;
+ unsigned int authsize = crypto_aead_authsize(aead);
+ int err;
+
+ if (cryptlen < authsize)
+ return -EINVAL;
+ cryptlen -= authsize;
+
+ crypto_gcm_init_crypt(abreq, req, cryptlen);
+ ablkcipher_request_set_callback(abreq, aead_request_flags(req),
+ crypto_gcm_decrypt_done, req);
+
+ crypto_gcm_ghash_update_sg(ghash, req->src, cryptlen);
+
+ err = crypto_ablkcipher_decrypt(abreq);
+ if (err)
+ return err;
+
+ return crypto_gcm_verify(req);
+}
+
+static int crypto_gcm_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct gcm_instance_ctx *ictx = crypto_instance_ctx(inst);
+ struct crypto_gcm_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_ablkcipher *ctr;
+ unsigned long align;
+ int err;
+
+ ctr = crypto_spawn_skcipher(&ictx->ctr);
+ err = PTR_ERR(ctr);
+ if (IS_ERR(ctr))
+ return err;
+
+ ctx->ctr = ctr;
+ ctx->gf128 = NULL;
+
+ align = crypto_tfm_alg_alignmask(tfm);
+ align &= ~(crypto_tfm_ctx_alignment() - 1);
+ tfm->crt_aead.reqsize = align +
+ sizeof(struct crypto_gcm_req_priv_ctx) +
+ crypto_ablkcipher_reqsize(ctr);
+
+ return 0;
+}
+
+static void crypto_gcm_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_gcm_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (ctx->gf128 != NULL)
+ gf128mul_free_4k(ctx->gf128);
+
+ crypto_free_ablkcipher(ctx->ctr);
+}
+
+static struct crypto_instance *crypto_gcm_alloc_common(struct rtattr **tb,
+ const char *full_name,
+ const char *ctr_name)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_alg *ctr;
+ struct gcm_instance_ctx *ctx;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ ctx = crypto_instance_ctx(inst);
+ crypto_set_skcipher_spawn(&ctx->ctr, inst);
+ err = crypto_grab_skcipher(&ctx->ctr, ctr_name, 0,
+ crypto_requires_sync(algt->type,
+ algt->mask));
+ if (err)
+ goto err_free_inst;
+
+ ctr = crypto_skcipher_spawn_alg(&ctx->ctr);
+
+ /* We only support 16-byte blocks. */
+ if (ctr->cra_ablkcipher.ivsize != 16)
+ goto out_put_ctr;
+
+ /* Not a stream cipher? */
+ err = -EINVAL;
+ if (ctr->cra_blocksize != 1)
+ goto out_put_ctr;
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "gcm_base(%s)", ctr->cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto out_put_ctr;
+
+ memcpy(inst->alg.cra_name, full_name, CRYPTO_MAX_ALG_NAME);
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+ inst->alg.cra_flags |= ctr->cra_flags & CRYPTO_ALG_ASYNC;
+ inst->alg.cra_priority = ctr->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = ctr->cra_alignmask | (__alignof__(u64) - 1);
+ inst->alg.cra_type = &crypto_aead_type;
+ inst->alg.cra_aead.ivsize = 16;
+ inst->alg.cra_aead.maxauthsize = 16;
+ inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx);
+ inst->alg.cra_init = crypto_gcm_init_tfm;
+ inst->alg.cra_exit = crypto_gcm_exit_tfm;
+ inst->alg.cra_aead.setkey = crypto_gcm_setkey;
+ inst->alg.cra_aead.setauthsize = crypto_gcm_setauthsize;
+ inst->alg.cra_aead.encrypt = crypto_gcm_encrypt;
+ inst->alg.cra_aead.decrypt = crypto_gcm_decrypt;
+
+out:
+ return inst;
+
+out_put_ctr:
+ crypto_drop_skcipher(&ctx->ctr);
+err_free_inst:
+ kfree(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static struct crypto_instance *crypto_gcm_alloc(struct rtattr **tb)
+{
+ int err;
+ const char *cipher_name;
+ char ctr_name[CRYPTO_MAX_ALG_NAME];
+ char full_name[CRYPTO_MAX_ALG_NAME];
+
+ cipher_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(cipher_name);
+ if (IS_ERR(cipher_name))
+ return ERR_PTR(err);
+
+ if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ return crypto_gcm_alloc_common(tb, full_name, ctr_name);
+}
+
+static void crypto_gcm_free(struct crypto_instance *inst)
+{
+ struct gcm_instance_ctx *ctx = crypto_instance_ctx(inst);
+
+ crypto_drop_skcipher(&ctx->ctr);
+ kfree(inst);
+}
+
+static struct crypto_template crypto_gcm_tmpl = {
+ .name = "gcm",
+ .alloc = crypto_gcm_alloc,
+ .free = crypto_gcm_free,
+ .module = THIS_MODULE,
+};
+
+static struct crypto_instance *crypto_gcm_base_alloc(struct rtattr **tb)
+{
+ int err;
+ const char *ctr_name;
+ char full_name[CRYPTO_MAX_ALG_NAME];
+
+ ctr_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(ctr_name);
+ if (IS_ERR(ctr_name))
+ return ERR_PTR(err);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s)",
+ ctr_name) >= CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ return crypto_gcm_alloc_common(tb, full_name, ctr_name);
+}
+
+static struct crypto_template crypto_gcm_base_tmpl = {
+ .name = "gcm_base",
+ .alloc = crypto_gcm_base_alloc,
+ .free = crypto_gcm_free,
+ .module = THIS_MODULE,
+};
+
+static int crypto_rfc4106_setkey(struct crypto_aead *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent);
+ struct crypto_aead *child = ctx->child;
+ int err;
+
+ if (keylen < 4)
+ return -EINVAL;
+
+ keylen -= 4;
+ memcpy(ctx->nonce, key + keylen, 4);
+
+ crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_aead_setkey(child, key, keylen);
+ crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+
+ return err;
+}
+
+static int crypto_rfc4106_setauthsize(struct crypto_aead *parent,
+ unsigned int authsize)
+{
+ struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent);
+
+ switch (authsize) {
+ case 8:
+ case 12:
+ case 16:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return crypto_aead_setauthsize(ctx->child, authsize);
+}
+
+static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req)
+{
+ struct aead_request *subreq = aead_request_ctx(req);
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
+ struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead);
+ struct crypto_aead *child = ctx->child;
+ u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
+ crypto_aead_alignmask(child) + 1);
+
+ memcpy(iv, ctx->nonce, 4);
+ memcpy(iv + 4, req->iv, 8);
+
+ aead_request_set_tfm(subreq, child);
+ aead_request_set_callback(subreq, req->base.flags, req->base.complete,
+ req->base.data);
+ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv);
+ aead_request_set_assoc(subreq, req->assoc, req->assoclen);
+
+ return subreq;
+}
+
+static int crypto_rfc4106_encrypt(struct aead_request *req)
+{
+ req = crypto_rfc4106_crypt(req);
+
+ return crypto_aead_encrypt(req);
+}
+
+static int crypto_rfc4106_decrypt(struct aead_request *req)
+{
+ req = crypto_rfc4106_crypt(req);
+
+ return crypto_aead_decrypt(req);
+}
+
+static int crypto_rfc4106_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_rfc4106_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_aead *aead;
+ unsigned long align;
+
+ aead = crypto_spawn_aead(spawn);
+ if (IS_ERR(aead))
+ return PTR_ERR(aead);
+
+ ctx->child = aead;
+
+ align = crypto_aead_alignmask(aead);
+ align &= ~(crypto_tfm_ctx_alignment() - 1);
+ tfm->crt_aead.reqsize = sizeof(struct aead_request) +
+ ALIGN(crypto_aead_reqsize(aead),
+ crypto_tfm_ctx_alignment()) +
+ align + 16;
+
+ return 0;
+}
+
+static void crypto_rfc4106_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_rfc4106_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_aead(ctx->child);
+}
+
+static struct crypto_instance *crypto_rfc4106_alloc(struct rtattr **tb)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ struct crypto_aead_spawn *spawn;
+ struct crypto_alg *alg;
+ const char *ccm_name;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
+ return ERR_PTR(-EINVAL);
+
+ ccm_name = crypto_attr_alg_name(tb[1]);
+ err = PTR_ERR(ccm_name);
+ if (IS_ERR(ccm_name))
+ return ERR_PTR(err);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
+ if (!inst)
+ return ERR_PTR(-ENOMEM);
+
+ spawn = crypto_instance_ctx(inst);
+ crypto_set_aead_spawn(spawn, inst);
+ err = crypto_grab_aead(spawn, ccm_name, 0,
+ crypto_requires_sync(algt->type, algt->mask));
+ if (err)
+ goto out_free_inst;
+
+ alg = crypto_aead_spawn_alg(spawn);
+
+ err = -EINVAL;
+
+ /* We only support 16-byte blocks. */
+ if (alg->cra_aead.ivsize != 16)
+ goto out_drop_alg;
+
+ /* Not a stream cipher? */
+ if (alg->cra_blocksize != 1)
+ goto out_drop_alg;
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+ "rfc4106(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME ||
+ snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "rfc4106(%s)", alg->cra_driver_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ goto out_drop_alg;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
+ inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = 1;
+ inst->alg.cra_alignmask = alg->cra_alignmask;
+ inst->alg.cra_type = &crypto_nivaead_type;
+
+ inst->alg.cra_aead.ivsize = 8;
+ inst->alg.cra_aead.maxauthsize = 16;
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4106_ctx);
+
+ inst->alg.cra_init = crypto_rfc4106_init_tfm;
+ inst->alg.cra_exit = crypto_rfc4106_exit_tfm;
+
+ inst->alg.cra_aead.setkey = crypto_rfc4106_setkey;
+ inst->alg.cra_aead.setauthsize = crypto_rfc4106_setauthsize;
+ inst->alg.cra_aead.encrypt = crypto_rfc4106_encrypt;
+ inst->alg.cra_aead.decrypt = crypto_rfc4106_decrypt;
+
+ inst->alg.cra_aead.geniv = "seqiv";
+
+out:
+ return inst;
+
+out_drop_alg:
+ crypto_drop_aead(spawn);
+out_free_inst:
+ kfree(inst);
+ inst = ERR_PTR(err);
+ goto out;
+}
+
+static void crypto_rfc4106_free(struct crypto_instance *inst)
+{
+ crypto_drop_spawn(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+
+static struct crypto_template crypto_rfc4106_tmpl = {
+ .name = "rfc4106",
+ .alloc = crypto_rfc4106_alloc,
+ .free = crypto_rfc4106_free,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_gcm_module_init(void)
+{
+ int err;
+
+ err = crypto_register_template(&crypto_gcm_base_tmpl);
+ if (err)
+ goto out;
+
+ err = crypto_register_template(&crypto_gcm_tmpl);
+ if (err)
+ goto out_undo_base;
+
+ err = crypto_register_template(&crypto_rfc4106_tmpl);
+ if (err)
+ goto out_undo_gcm;
+
+out:
+ return err;
+
+out_undo_gcm:
+ crypto_unregister_template(&crypto_gcm_tmpl);
+out_undo_base:
+ crypto_unregister_template(&crypto_gcm_base_tmpl);
+ goto out;
+}
+
+static void __exit crypto_gcm_module_exit(void)
+{
+ crypto_unregister_template(&crypto_rfc4106_tmpl);
+ crypto_unregister_template(&crypto_gcm_tmpl);
+ crypto_unregister_template(&crypto_gcm_base_tmpl);
+}
+
+module_init(crypto_gcm_module_init);
+module_exit(crypto_gcm_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Galois/Counter Mode");
+MODULE_AUTHOR("Mikko Herranen <mh1@iki.fi>");
+MODULE_ALIAS("gcm_base");
+MODULE_ALIAS("rfc4106");
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 0f05be7..a1d016a 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -17,6 +17,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -160,7 +161,7 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
sg_init_table(sg1, 2);
sg_set_buf(sg1, ipad, bs);
- sg_set_page(&sg1[1], (void *) sg, 0, 0);
+ scatterwalk_sg_chain(sg1, 2, sg);
sg_init_table(sg2, 1);
sg_set_buf(sg2, opad, bs + ds);
diff --git a/crypto/internal.h b/crypto/internal.h
index abb01f7..32f4c21 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -25,7 +25,6 @@
#include <linux/notifier.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
-#include <asm/kmap_types.h>
/* Crypto notification events. */
enum {
@@ -50,34 +49,6 @@ extern struct list_head crypto_alg_list;
extern struct rw_semaphore crypto_alg_sem;
extern struct blocking_notifier_head crypto_chain;
-static inline enum km_type crypto_kmap_type(int out)
-{
- enum km_type type;
-
- if (in_softirq())
- type = out * (KM_SOFTIRQ1 - KM_SOFTIRQ0) + KM_SOFTIRQ0;
- else
- type = out * (KM_USER1 - KM_USER0) + KM_USER0;
-
- return type;
-}
-
-static inline void *crypto_kmap(struct page *page, int out)
-{
- return kmap_atomic(page, crypto_kmap_type(out));
-}
-
-static inline void crypto_kunmap(void *vaddr, int out)
-{
- kunmap_atomic(vaddr, crypto_kmap_type(out));
-}
-
-static inline void crypto_yield(u32 flags)
-{
- if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
- cond_resched();
-}
-
#ifdef CONFIG_PROC_FS
void __init crypto_init_proc(void);
void __exit crypto_exit_proc(void);
@@ -122,6 +93,8 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+void crypto_larval_kill(struct crypto_alg *alg);
+struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
void crypto_larval_error(const char *name, u32 type, u32 mask);
void crypto_shoot_alg(struct crypto_alg *alg);
diff --git a/crypto/lzo.c b/crypto/lzo.c
new file mode 100644
index 0000000..48c3288
--- /dev/null
+++ b/crypto/lzo.c
@@ -0,0 +1,106 @@
+/*
+ * Cryptographic API.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/vmalloc.h>
+#include <linux/lzo.h>
+
+struct lzo_ctx {
+ void *lzo_comp_mem;
+};
+
+static int lzo_init(struct crypto_tfm *tfm)
+{
+ struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS);
+ if (!ctx->lzo_comp_mem)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void lzo_exit(struct crypto_tfm *tfm)
+{
+ struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ vfree(ctx->lzo_comp_mem);
+}
+
+static int lzo_compress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);
+ size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
+ int err;
+
+ err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx->lzo_comp_mem);
+
+ if (err != LZO_E_OK)
+ return -EINVAL;
+
+ *dlen = tmp_len;
+ return 0;
+}
+
+static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ int err;
+ size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */
+
+ err = lzo1x_decompress_safe(src, slen, dst, &tmp_len);
+
+ if (err != LZO_E_OK)
+ return -EINVAL;
+
+ *dlen = tmp_len;
+ return 0;
+
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "lzo",
+ .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
+ .cra_ctxsize = sizeof(struct lzo_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_init = lzo_init,
+ .cra_exit = lzo_exit,
+ .cra_u = { .compress = {
+ .coa_compress = lzo_compress,
+ .coa_decompress = lzo_decompress } }
+};
+
+static int __init init(void)
+{
+ return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZO Compression Algorithm");
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index c3ed8a1..fe70477 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -24,7 +24,6 @@
struct crypto_pcbc_ctx {
struct crypto_cipher *child;
- void (*xor)(u8 *dst, const u8 *src, unsigned int bs);
};
static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key,
@@ -45,9 +44,7 @@ static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key,
static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
@@ -58,10 +55,10 @@ static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
u8 *iv = walk->iv;
do {
- xor(iv, src, bsize);
+ crypto_xor(iv, src, bsize);
fn(crypto_cipher_tfm(tfm), dst, iv);
memcpy(iv, dst, bsize);
- xor(iv, src, bsize);
+ crypto_xor(iv, src, bsize);
src += bsize;
dst += bsize;
@@ -72,9 +69,7 @@ static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc,
static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
@@ -86,10 +81,10 @@ static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc,
do {
memcpy(tmpbuf, src, bsize);
- xor(iv, tmpbuf, bsize);
+ crypto_xor(iv, src, bsize);
fn(crypto_cipher_tfm(tfm), src, iv);
- memcpy(iv, src, bsize);
- xor(iv, tmpbuf, bsize);
+ memcpy(iv, tmpbuf, bsize);
+ crypto_xor(iv, src, bsize);
src += bsize;
} while ((nbytes -= bsize) >= bsize);
@@ -107,7 +102,6 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
- void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -115,11 +109,11 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
- nbytes = crypto_pcbc_encrypt_inplace(desc, &walk, child,
- xor);
+ nbytes = crypto_pcbc_encrypt_inplace(desc, &walk,
+ child);
else
- nbytes = crypto_pcbc_encrypt_segment(desc, &walk, child,
- xor);
+ nbytes = crypto_pcbc_encrypt_segment(desc, &walk,
+ child);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
@@ -128,9 +122,7 @@ static int crypto_pcbc_encrypt(struct blkcipher_desc *desc,
static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
@@ -142,9 +134,9 @@ static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
do {
fn(crypto_cipher_tfm(tfm), dst, src);
- xor(dst, iv, bsize);
+ crypto_xor(dst, iv, bsize);
memcpy(iv, src, bsize);
- xor(iv, dst, bsize);
+ crypto_xor(iv, dst, bsize);
src += bsize;
dst += bsize;
@@ -157,9 +149,7 @@ static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc,
static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
- struct crypto_cipher *tfm,
- void (*xor)(u8 *, const u8 *,
- unsigned int))
+ struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_decrypt;
@@ -172,9 +162,9 @@ static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc,
do {
memcpy(tmpbuf, src, bsize);
fn(crypto_cipher_tfm(tfm), src, src);
- xor(src, iv, bsize);
+ crypto_xor(src, iv, bsize);
memcpy(iv, tmpbuf, bsize);
- xor(iv, src, bsize);
+ crypto_xor(iv, src, bsize);
src += bsize;
} while ((nbytes -= bsize) >= bsize);
@@ -192,7 +182,6 @@ static int crypto_pcbc_decrypt(struct blkcipher_desc *desc,
struct crypto_blkcipher *tfm = desc->tfm;
struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct crypto_cipher *child = ctx->child;
- void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -200,48 +189,17 @@ static int crypto_pcbc_decrypt(struct blkcipher_desc *desc,
while ((nbytes = walk.nbytes)) {
if (walk.src.virt.addr == walk.dst.virt.addr)
- nbytes = crypto_pcbc_decrypt_inplace(desc, &walk, child,
- xor);
+ nbytes = crypto_pcbc_decrypt_inplace(desc, &walk,
+ child);
else
- nbytes = crypto_pcbc_decrypt_segment(desc, &walk, child,
- xor);
+ nbytes = crypto_pcbc_decrypt_segment(desc, &walk,
+ child);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
-static void xor_byte(u8 *a, const u8 *b, unsigned int bs)
-{
- do {
- *a++ ^= *b++;
- } while (--bs);
-}
-
-static void xor_quad(u8 *dst, const u8 *src, unsigned int bs)
-{
- u32 *a = (u32 *)dst;
- u32 *b = (u32 *)src;
-
- do {
- *a++ ^= *b++;
- } while ((bs -= 4));
-}
-
-static void xor_64(u8 *a, const u8 *b, unsigned int bs)
-{
- ((u32 *)a)[0] ^= ((u32 *)b)[0];
- ((u32 *)a)[1] ^= ((u32 *)b)[1];
-}
-
-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_pcbc_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_instance *inst = (void *)tfm->__crt_alg;
@@ -249,22 +207,6 @@ static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm)
struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_cipher *cipher;
- switch (crypto_tfm_alg_blocksize(tfm)) {
- case 8:
- ctx->xor = xor_64;
- break;
-
- case 16:
- ctx->xor = xor_128;
- break;
-
- default:
- if (crypto_tfm_alg_blocksize(tfm) % 4)
- ctx->xor = xor_byte;
- else
- ctx->xor = xor_quad;
- }
-
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
@@ -304,8 +246,9 @@ static struct crypto_instance *crypto_pcbc_alloc(struct rtattr **tb)
inst->alg.cra_alignmask = alg->cra_alignmask;
inst->alg.cra_type = &crypto_blkcipher_type;
- if (!(alg->cra_blocksize % 4))
- inst->alg.cra_alignmask |= 3;
+ /* We access the data as u32s when xoring. */
+ inst->alg.cra_alignmask |= __alignof__(u32) - 1;
+
inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize;
inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
new file mode 100644
index 0000000..1fa4e4d
--- /dev/null
+++ b/crypto/salsa20_generic.c
@@ -0,0 +1,255 @@
+/*
+ * Salsa20: Salsa20 stream cipher algorithm
+ *
+ * Copyright (c) 2007 Tan Swee Heng <thesweeheng@gmail.com>
+ *
+ * Derived from:
+ * - salsa20.c: Public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
+ *
+ * Salsa20 is a stream cipher candidate in eSTREAM, the ECRYPT Stream
+ * Cipher Project. It is designed by Daniel J. Bernstein <djb@cr.yp.to>.
+ * More information about eSTREAM and Salsa20 can be found here:
+ * http://www.ecrypt.eu.org/stream/
+ * http://cr.yp.to/snuffle.html
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/algapi.h>
+#include <asm/byteorder.h>
+
+#define SALSA20_IV_SIZE 8U
+#define SALSA20_MIN_KEY_SIZE 16U
+#define SALSA20_MAX_KEY_SIZE 32U
+
+/*
+ * Start of code taken from D. J. Bernstein's reference implementation.
+ * With some modifications and optimizations made to suit our needs.
+ */
+
+/*
+salsa20-ref.c version 20051118
+D. J. Bernstein
+Public domain.
+*/
+
+#define ROTATE(v,n) (((v) << (n)) | ((v) >> (32 - (n))))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+#define U32TO8_LITTLE(p, v) \
+ { (p)[0] = (v >> 0) & 0xff; (p)[1] = (v >> 8) & 0xff; \
+ (p)[2] = (v >> 16) & 0xff; (p)[3] = (v >> 24) & 0xff; }
+#define U8TO32_LITTLE(p) \
+ (((u32)((p)[0]) ) | ((u32)((p)[1]) << 8) | \
+ ((u32)((p)[2]) << 16) | ((u32)((p)[3]) << 24) )
+
+struct salsa20_ctx
+{
+ u32 input[16];
+};
+
+static void salsa20_wordtobyte(u8 output[64], const u32 input[16])
+{
+ u32 x[16];
+ int i;
+
+ memcpy(x, input, sizeof(x));
+ for (i = 20; i > 0; i -= 2) {
+ x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 0],x[12]), 7));
+ x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[ 4],x[ 0]), 9));
+ x[12] = XOR(x[12],ROTATE(PLUS(x[ 8],x[ 4]),13));
+ x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[12],x[ 8]),18));
+ x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 5],x[ 1]), 7));
+ x[13] = XOR(x[13],ROTATE(PLUS(x[ 9],x[ 5]), 9));
+ x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[13],x[ 9]),13));
+ x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 1],x[13]),18));
+ x[14] = XOR(x[14],ROTATE(PLUS(x[10],x[ 6]), 7));
+ x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[14],x[10]), 9));
+ x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 2],x[14]),13));
+ x[10] = XOR(x[10],ROTATE(PLUS(x[ 6],x[ 2]),18));
+ x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[15],x[11]), 7));
+ x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 3],x[15]), 9));
+ x[11] = XOR(x[11],ROTATE(PLUS(x[ 7],x[ 3]),13));
+ x[15] = XOR(x[15],ROTATE(PLUS(x[11],x[ 7]),18));
+ x[ 1] = XOR(x[ 1],ROTATE(PLUS(x[ 0],x[ 3]), 7));
+ x[ 2] = XOR(x[ 2],ROTATE(PLUS(x[ 1],x[ 0]), 9));
+ x[ 3] = XOR(x[ 3],ROTATE(PLUS(x[ 2],x[ 1]),13));
+ x[ 0] = XOR(x[ 0],ROTATE(PLUS(x[ 3],x[ 2]),18));
+ x[ 6] = XOR(x[ 6],ROTATE(PLUS(x[ 5],x[ 4]), 7));
+ x[ 7] = XOR(x[ 7],ROTATE(PLUS(x[ 6],x[ 5]), 9));
+ x[ 4] = XOR(x[ 4],ROTATE(PLUS(x[ 7],x[ 6]),13));
+ x[ 5] = XOR(x[ 5],ROTATE(PLUS(x[ 4],x[ 7]),18));
+ x[11] = XOR(x[11],ROTATE(PLUS(x[10],x[ 9]), 7));
+ x[ 8] = XOR(x[ 8],ROTATE(PLUS(x[11],x[10]), 9));
+ x[ 9] = XOR(x[ 9],ROTATE(PLUS(x[ 8],x[11]),13));
+ x[10] = XOR(x[10],ROTATE(PLUS(x[ 9],x[ 8]),18));
+ x[12] = XOR(x[12],ROTATE(PLUS(x[15],x[14]), 7));
+ x[13] = XOR(x[13],ROTATE(PLUS(x[12],x[15]), 9));
+ x[14] = XOR(x[14],ROTATE(PLUS(x[13],x[12]),13));
+ x[15] = XOR(x[15],ROTATE(PLUS(x[14],x[13]),18));
+ }
+ for (i = 0; i < 16; ++i)
+ x[i] = PLUS(x[i],input[i]);
+ for (i = 0; i < 16; ++i)
+ U32TO8_LITTLE(output + 4 * i,x[i]);
+}
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+static void salsa20_keysetup(struct salsa20_ctx *ctx, const u8 *k, u32 kbytes)
+{
+ const char *constants;
+
+ ctx->input[1] = U8TO32_LITTLE(k + 0);
+ ctx->input[2] = U8TO32_LITTLE(k + 4);
+ ctx->input[3] = U8TO32_LITTLE(k + 8);
+ ctx->input[4] = U8TO32_LITTLE(k + 12);
+ if (kbytes == 32) { /* recommended */
+ k += 16;
+ constants = sigma;
+ } else { /* kbytes == 16 */
+ constants = tau;
+ }
+ ctx->input[11] = U8TO32_LITTLE(k + 0);
+ ctx->input[12] = U8TO32_LITTLE(k + 4);
+ ctx->input[13] = U8TO32_LITTLE(k + 8);
+ ctx->input[14] = U8TO32_LITTLE(k + 12);
+ ctx->input[0] = U8TO32_LITTLE(constants + 0);
+ ctx->input[5] = U8TO32_LITTLE(constants + 4);
+ ctx->input[10] = U8TO32_LITTLE(constants + 8);
+ ctx->input[15] = U8TO32_LITTLE(constants + 12);
+}
+
+static void salsa20_ivsetup(struct salsa20_ctx *ctx, const u8 *iv)
+{
+ ctx->input[6] = U8TO32_LITTLE(iv + 0);
+ ctx->input[7] = U8TO32_LITTLE(iv + 4);
+ ctx->input[8] = 0;
+ ctx->input[9] = 0;
+}
+
+static void salsa20_encrypt_bytes(struct salsa20_ctx *ctx, u8 *dst,
+ const u8 *src, unsigned int bytes)
+{
+ u8 buf[64];
+
+ if (dst != src)
+ memcpy(dst, src, bytes);
+
+ while (bytes) {
+ salsa20_wordtobyte(buf, ctx->input);
+
+ ctx->input[8] = PLUSONE(ctx->input[8]);
+ if (!ctx->input[8])
+ ctx->input[9] = PLUSONE(ctx->input[9]);
+
+ if (bytes <= 64) {
+ crypto_xor(dst, buf, bytes);
+ return;
+ }
+
+ crypto_xor(dst, buf, 64);
+ bytes -= 64;
+ dst += 64;
+ }
+}
+
+/*
+ * End of code taken from D. J. Bernstein's reference implementation.
+ */
+
+static int setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keysize)
+{
+ struct salsa20_ctx *ctx = crypto_tfm_ctx(tfm);
+ salsa20_keysetup(ctx, key, keysize);
+ return 0;
+}
+
+static int encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct salsa20_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, 64);
+
+ salsa20_ivsetup(ctx, walk.iv);
+
+ if (likely(walk.nbytes == nbytes))
+ {
+ salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
+ walk.src.virt.addr, nbytes);
+ return blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ while (walk.nbytes >= 64) {
+ salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
+ walk.src.virt.addr,
+ walk.nbytes - (walk.nbytes % 64));
+ err = blkcipher_walk_done(desc, &walk, walk.nbytes % 64);
+ }
+
+ if (walk.nbytes) {
+ salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
+ walk.src.virt.addr, walk.nbytes);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ return err;
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "salsa20",
+ .cra_driver_name = "salsa20-generic",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct salsa20_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .setkey = setkey,
+ .encrypt = encrypt,
+ .decrypt = encrypt,
+ .min_keysize = SALSA20_MIN_KEY_SIZE,
+ .max_keysize = SALSA20_MAX_KEY_SIZE,
+ .ivsize = SALSA20_IV_SIZE,
+ }
+ }
+};
+
+static int __init init(void)
+{
+ return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm");
+MODULE_ALIAS("salsa20");
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index b9bbda0..9aeeb52 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -13,6 +13,8 @@
* any later version.
*
*/
+
+#include <crypto/scatterwalk.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -20,9 +22,6 @@
#include <linux/highmem.h>
#include <linux/scatterlist.h>
-#include "internal.h"
-#include "scatterwalk.h"
-
static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
{
void *src = out ? buf : sgdata;
@@ -106,6 +105,9 @@ void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
struct scatter_walk walk;
unsigned int offset = 0;
+ if (!nbytes)
+ return;
+
for (;;) {
scatterwalk_start(&walk, sg);
@@ -113,7 +115,7 @@ void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
break;
offset += sg->length;
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
scatterwalk_advance(&walk, start - offset);
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
deleted file mode 100644
index 87ed681..0000000
--- a/crypto/scatterwalk.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
- * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- */
-
-#ifndef _CRYPTO_SCATTERWALK_H
-#define _CRYPTO_SCATTERWALK_H
-
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-
-#include "internal.h"
-
-static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
-{
- return (++sg)->length ? sg : (void *) sg_page(sg);
-}
-
-static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
- struct scatter_walk *walk_out)
-{
- return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
- (int)(walk_in->offset - walk_out->offset));
-}
-
-static inline unsigned int scatterwalk_pagelen(struct scatter_walk *walk)
-{
- unsigned int len = walk->sg->offset + walk->sg->length - walk->offset;
- unsigned int len_this_page = offset_in_page(~walk->offset) + 1;
- return len_this_page > len ? len : len_this_page;
-}
-
-static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk,
- unsigned int nbytes)
-{
- unsigned int len_this_page = scatterwalk_pagelen(walk);
- return nbytes > len_this_page ? len_this_page : nbytes;
-}
-
-static inline void scatterwalk_advance(struct scatter_walk *walk,
- unsigned int nbytes)
-{
- walk->offset += nbytes;
-}
-
-static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
- unsigned int alignmask)
-{
- return !(walk->offset & alignmask);
-}
-
-static inline struct page *scatterwalk_page(struct scatter_walk *walk)
-{
- return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
-}
-
-static inline void scatterwalk_unmap(void *vaddr, int out)
-{
- crypto_kunmap(vaddr, out);
-}
-
-void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
-void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
- size_t nbytes, int out);
-void *scatterwalk_map(struct scatter_walk *walk, int out);
-void scatterwalk_done(struct scatter_walk *walk, int out, int more);
-
-void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
- unsigned int start, unsigned int nbytes, int out);
-
-#endif /* _CRYPTO_SCATTERWALK_H */
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
new file mode 100644
index 0000000..b903aab
--- /dev/null
+++ b/crypto/seqiv.c
@@ -0,0 +1,345 @@
+/*
+ * seqiv: Sequence Number IV Generator
+ *
+ * This generator generates an IV based on a sequence number by xoring it
+ * with a salt. This algorithm is mainly useful for CTR and similar modes.
+ *
+ * Copyright (c) 2007 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.
+ *
+ */
+
+#include <crypto/internal/aead.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+struct seqiv_ctx {
+ spinlock_t lock;
+ u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
+};
+
+static void seqiv_complete2(struct skcipher_givcrypt_request *req, int err)
+{
+ struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
+ struct crypto_ablkcipher *geniv;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ if (err)
+ goto out;
+
+ geniv = skcipher_givcrypt_reqtfm(req);
+ memcpy(req->creq.info, subreq->info, crypto_ablkcipher_ivsize(geniv));
+
+out:
+ kfree(subreq->info);
+}
+
+static void seqiv_complete(struct crypto_async_request *base, int err)
+{
+ struct skcipher_givcrypt_request *req = base->data;
+
+ seqiv_complete2(req, err);
+ skcipher_givcrypt_complete(req, err);
+}
+
+static void seqiv_aead_complete2(struct aead_givcrypt_request *req, int err)
+{
+ struct aead_request *subreq = aead_givcrypt_reqctx(req);
+ struct crypto_aead *geniv;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ if (err)
+ goto out;
+
+ geniv = aead_givcrypt_reqtfm(req);
+ memcpy(req->areq.iv, subreq->iv, crypto_aead_ivsize(geniv));
+
+out:
+ kfree(subreq->iv);
+}
+
+static void seqiv_aead_complete(struct crypto_async_request *base, int err)
+{
+ struct aead_givcrypt_request *req = base->data;
+
+ seqiv_aead_complete2(req, err);
+ aead_givcrypt_complete(req, err);
+}
+
+static void seqiv_geniv(struct seqiv_ctx *ctx, u8 *info, u64 seq,
+ unsigned int ivsize)
+{
+ unsigned int len = ivsize;
+
+ if (ivsize > sizeof(u64)) {
+ memset(info, 0, ivsize - sizeof(u64));
+ len = sizeof(u64);
+ }
+ seq = cpu_to_be64(seq);
+ memcpy(info + ivsize - len, &seq, len);
+ crypto_xor(info, ctx->salt, ivsize);
+}
+
+static int seqiv_givencrypt(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+ struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
+ crypto_completion_t complete;
+ void *data;
+ u8 *info;
+ unsigned int ivsize;
+ int err;
+
+ ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
+
+ complete = req->creq.base.complete;
+ data = req->creq.base.data;
+ info = req->creq.info;
+
+ ivsize = crypto_ablkcipher_ivsize(geniv);
+
+ if (unlikely(!IS_ALIGNED((unsigned long)info,
+ crypto_ablkcipher_alignmask(geniv) + 1))) {
+ info = kmalloc(ivsize, req->creq.base.flags &
+ CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
+ GFP_ATOMIC);
+ if (!info)
+ return -ENOMEM;
+
+ complete = seqiv_complete;
+ data = req;
+ }
+
+ ablkcipher_request_set_callback(subreq, req->creq.base.flags, complete,
+ data);
+ ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
+ req->creq.nbytes, info);
+
+ seqiv_geniv(ctx, info, req->seq, ivsize);
+ memcpy(req->giv, info, ivsize);
+
+ err = crypto_ablkcipher_encrypt(subreq);
+ if (unlikely(info != req->creq.info))
+ seqiv_complete2(req, err);
+ return err;
+}
+
+static int seqiv_aead_givencrypt(struct aead_givcrypt_request *req)
+{
+ struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
+ struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
+ struct aead_request *areq = &req->areq;
+ struct aead_request *subreq = aead_givcrypt_reqctx(req);
+ crypto_completion_t complete;
+ void *data;
+ u8 *info;
+ unsigned int ivsize;
+ int err;
+
+ aead_request_set_tfm(subreq, aead_geniv_base(geniv));
+
+ complete = areq->base.complete;
+ data = areq->base.data;
+ info = areq->iv;
+
+ ivsize = crypto_aead_ivsize(geniv);
+
+ if (unlikely(!IS_ALIGNED((unsigned long)info,
+ crypto_aead_alignmask(geniv) + 1))) {
+ info = kmalloc(ivsize, areq->base.flags &
+ CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
+ GFP_ATOMIC);
+ if (!info)
+ return -ENOMEM;
+
+ complete = seqiv_aead_complete;
+ data = req;
+ }
+
+ aead_request_set_callback(subreq, areq->base.flags, complete, data);
+ aead_request_set_crypt(subreq, areq->src, areq->dst, areq->cryptlen,
+ info);
+ aead_request_set_assoc(subreq, areq->assoc, areq->assoclen);
+
+ seqiv_geniv(ctx, info, req->seq, ivsize);
+ memcpy(req->giv, info, ivsize);
+
+ err = crypto_aead_encrypt(subreq);
+ if (unlikely(info != areq->iv))
+ seqiv_aead_complete2(req, err);
+ return err;
+}
+
+static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
+{
+ struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+ struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+
+ spin_lock_bh(&ctx->lock);
+ if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first)
+ goto unlock;
+
+ crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
+ get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return seqiv_givencrypt(req);
+}
+
+static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req)
+{
+ struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
+ struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
+
+ spin_lock_bh(&ctx->lock);
+ if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first)
+ goto unlock;
+
+ crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt;
+ get_random_bytes(ctx->salt, crypto_aead_ivsize(geniv));
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return seqiv_aead_givencrypt(req);
+}
+
+static int seqiv_init(struct crypto_tfm *tfm)
+{
+ struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
+ struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+
+ spin_lock_init(&ctx->lock);
+
+ tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);
+
+ return skcipher_geniv_init(tfm);
+}
+
+static int seqiv_aead_init(struct crypto_tfm *tfm)
+{
+ struct crypto_aead *geniv = __crypto_aead_cast(tfm);
+ struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
+
+ spin_lock_init(&ctx->lock);
+
+ tfm->crt_aead.reqsize = sizeof(struct aead_request);
+
+ return aead_geniv_init(tfm);
+}
+
+static struct crypto_template seqiv_tmpl;
+
+static struct crypto_instance *seqiv_ablkcipher_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+
+ inst = skcipher_geniv_alloc(&seqiv_tmpl, tb, 0, 0);
+
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt_first;
+
+ inst->alg.cra_init = seqiv_init;
+ inst->alg.cra_exit = skcipher_geniv_exit;
+
+ inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
+
+out:
+ return inst;
+}
+
+static struct crypto_instance *seqiv_aead_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst;
+
+ inst = aead_geniv_alloc(&seqiv_tmpl, tb, 0, 0);
+
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt_first;
+
+ inst->alg.cra_init = seqiv_aead_init;
+ inst->alg.cra_exit = aead_geniv_exit;
+
+ inst->alg.cra_ctxsize = inst->alg.cra_aead.ivsize;
+
+out:
+ return inst;
+}
+
+static struct crypto_instance *seqiv_alloc(struct rtattr **tb)
+{
+ struct crypto_attr_type *algt;
+ struct crypto_instance *inst;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ err = PTR_ERR(algt);
+ if (IS_ERR(algt))
+ return ERR_PTR(err);
+
+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
+ inst = seqiv_ablkcipher_alloc(tb);
+ else
+ inst = seqiv_aead_alloc(tb);
+
+ if (IS_ERR(inst))
+ goto out;
+
+ inst->alg.cra_alignmask |= __alignof__(u32) - 1;
+ inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);
+
+out:
+ return inst;
+}
+
+static void seqiv_free(struct crypto_instance *inst)
+{
+ if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
+ skcipher_geniv_free(inst);
+ else
+ aead_geniv_free(inst);
+}
+
+static struct crypto_template seqiv_tmpl = {
+ .name = "seqiv",
+ .alloc = seqiv_alloc,
+ .free = seqiv_free,
+ .module = THIS_MODULE,
+};
+
+static int __init seqiv_module_init(void)
+{
+ return crypto_register_template(&seqiv_tmpl);
+}
+
+static void __exit seqiv_module_exit(void)
+{
+ crypto_unregister_template(&seqiv_tmpl);
+}
+
+module_init(seqiv_module_init);
+module_exit(seqiv_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Sequence Number IV Generator");
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index fd3918b..3cc93fd 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -9,6 +9,7 @@
* Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -218,6 +219,22 @@ static void sha256_transform(u32 *state, const u8 *input)
memset(W, 0, 64 * sizeof(u32));
}
+
+static void sha224_init(struct crypto_tfm *tfm)
+{
+ struct sha256_ctx *sctx = crypto_tfm_ctx(tfm);
+ sctx->state[0] = SHA224_H0;
+ sctx->state[1] = SHA224_H1;
+ sctx->state[2] = SHA224_H2;
+ sctx->state[3] = SHA224_H3;
+ sctx->state[4] = SHA224_H4;
+ sctx->state[5] = SHA224_H5;
+ sctx->state[6] = SHA224_H6;
+ sctx->state[7] = SHA224_H7;
+ sctx->count[0] = 0;
+ sctx->count[1] = 0;
+}
+
static void sha256_init(struct crypto_tfm *tfm)
{
struct sha256_ctx *sctx = crypto_tfm_ctx(tfm);
@@ -294,8 +311,17 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
memset(sctx, 0, sizeof(*sctx));
}
+static void sha224_final(struct crypto_tfm *tfm, u8 *hash)
+{
+ u8 D[SHA256_DIGEST_SIZE];
+
+ sha256_final(tfm, D);
+
+ memcpy(hash, D, SHA224_DIGEST_SIZE);
+ memset(D, 0, SHA256_DIGEST_SIZE);
+}
-static struct crypto_alg alg = {
+static struct crypto_alg sha256 = {
.cra_name = "sha256",
.cra_driver_name= "sha256-generic",
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
@@ -303,28 +329,58 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct sha256_ctx),
.cra_module = THIS_MODULE,
.cra_alignmask = 3,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_list = LIST_HEAD_INIT(sha256.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA256_DIGEST_SIZE,
- .dia_init = sha256_init,
- .dia_update = sha256_update,
- .dia_final = sha256_final } }
+ .dia_init = sha256_init,
+ .dia_update = sha256_update,
+ .dia_final = sha256_final } }
+};
+
+static struct crypto_alg sha224 = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-generic",
+ .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sha256_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 3,
+ .cra_list = LIST_HEAD_INIT(sha224.cra_list),
+ .cra_u = { .digest = {
+ .dia_digestsize = SHA224_DIGEST_SIZE,
+ .dia_init = sha224_init,
+ .dia_update = sha256_update,
+ .dia_final = sha224_final } }
};
static int __init init(void)
{
- return crypto_register_alg(&alg);
+ int ret = 0;
+
+ ret = crypto_register_alg(&sha224);
+
+ if (ret < 0)
+ return ret;
+
+ ret = crypto_register_alg(&sha256);
+
+ if (ret < 0)
+ crypto_unregister_alg(&sha224);
+
+ return ret;
}
static void __exit fini(void)
{
- crypto_unregister_alg(&alg);
+ crypto_unregister_alg(&sha224);
+ crypto_unregister_alg(&sha256);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
+MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm");
+MODULE_ALIAS("sha224");
MODULE_ALIAS("sha256");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 24141fb..1ab8c01 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -6,12 +6,16 @@
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
*
* 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.
*
+ * 2007-11-13 Added GCM tests
+ * 2007-11-13 Added AEAD support
+ * 2007-11-06 Added SHA-224 and SHA-224-HMAC tests
* 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests
* 2004-08-09 Added cipher speed tests (Reyk Floeter <reyk@vantronix.net>)
* 2003-09-14 Rewritten by Kartikey Mahendra Bhatt
@@ -71,22 +75,23 @@ static unsigned int sec;
static int mode;
static char *xbuf;
+static char *axbuf;
static char *tvmem;
static char *check[] = {
- "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
- "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
+ "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
+ "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes",
+ "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
- "camellia", "seed", NULL
+ "camellia", "seed", "salsa20", "lzo", NULL
};
static void hexdump(unsigned char *buf, unsigned int len)
{
- while (len--)
- printk("%02x", *buf++);
-
- printk("\n");
+ print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+ 16, 1,
+ buf, len, false);
}
static void tcrypt_complete(struct crypto_async_request *req, int err)
@@ -215,6 +220,238 @@ out:
crypto_free_hash(tfm);
}
+static void test_aead(char *algo, int enc, struct aead_testvec *template,
+ unsigned int tcount)
+{
+ unsigned int ret, i, j, k, temp;
+ unsigned int tsize;
+ char *q;
+ struct crypto_aead *tfm;
+ char *key;
+ struct aead_testvec *aead_tv;
+ struct aead_request *req;
+ struct scatterlist sg[8];
+ struct scatterlist asg[8];
+ const char *e;
+ struct tcrypt_result result;
+ unsigned int authsize;
+
+ if (enc == ENCRYPT)
+ e = "encryption";
+ else
+ e = "decryption";
+
+ printk(KERN_INFO "\ntesting %s %s\n", algo, e);
+
+ tsize = sizeof(struct aead_testvec);
+ tsize *= tcount;
+
+ if (tsize > TVMEMSIZE) {
+ printk(KERN_INFO "template (%u) too big for tvmem (%u)\n",
+ tsize, TVMEMSIZE);
+ return;
+ }
+
+ memcpy(tvmem, template, tsize);
+ aead_tv = (void *)tvmem;
+
+ init_completion(&result.completion);
+
+ tfm = crypto_alloc_aead(algo, 0, 0);
+
+ if (IS_ERR(tfm)) {
+ printk(KERN_INFO "failed to load transform for %s: %ld\n",
+ algo, PTR_ERR(tfm));
+ return;
+ }
+
+ req = aead_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ printk(KERN_INFO "failed to allocate request for %s\n", algo);
+ goto out;
+ }
+
+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+ for (i = 0, j = 0; i < tcount; i++) {
+ if (!aead_tv[i].np) {
+ printk(KERN_INFO "test %u (%d bit key):\n",
+ ++j, aead_tv[i].klen * 8);
+
+ crypto_aead_clear_flags(tfm, ~0);
+ if (aead_tv[i].wk)
+ crypto_aead_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+ key = aead_tv[i].key;
+
+ ret = crypto_aead_setkey(tfm, key,
+ aead_tv[i].klen);
+ if (ret) {
+ printk(KERN_INFO "setkey() failed flags=%x\n",
+ crypto_aead_get_flags(tfm));
+
+ if (!aead_tv[i].fail)
+ goto out;
+ }
+
+ authsize = abs(aead_tv[i].rlen - aead_tv[i].ilen);
+ ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ printk(KERN_INFO
+ "failed to set authsize = %u\n",
+ authsize);
+ goto out;
+ }
+
+ sg_init_one(&sg[0], aead_tv[i].input,
+ aead_tv[i].ilen + (enc ? authsize : 0));
+
+ sg_init_one(&asg[0], aead_tv[i].assoc,
+ aead_tv[i].alen);
+
+ aead_request_set_crypt(req, sg, sg,
+ aead_tv[i].ilen,
+ aead_tv[i].iv);
+
+ aead_request_set_assoc(req, asg, aead_tv[i].alen);
+
+ ret = enc ?
+ crypto_aead_encrypt(req) :
+ crypto_aead_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !(ret = result.err)) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_INFO "%s () failed err=%d\n",
+ e, -ret);
+ goto out;
+ }
+
+ q = kmap(sg_page(&sg[0])) + sg[0].offset;
+ hexdump(q, aead_tv[i].rlen);
+
+ printk(KERN_INFO "enc/dec: %s\n",
+ memcmp(q, aead_tv[i].result,
+ aead_tv[i].rlen) ? "fail" : "pass");
+ }
+ }
+
+ printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e);
+ memset(xbuf, 0, XBUFSIZE);
+ memset(axbuf, 0, XBUFSIZE);
+
+ for (i = 0, j = 0; i < tcount; i++) {
+ if (aead_tv[i].np) {
+ printk(KERN_INFO "test %u (%d bit key):\n",
+ ++j, aead_tv[i].klen * 8);
+
+ crypto_aead_clear_flags(tfm, ~0);
+ if (aead_tv[i].wk)
+ crypto_aead_set_flags(
+ tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+ key = aead_tv[i].key;
+
+ ret = crypto_aead_setkey(tfm, key, aead_tv[i].klen);
+ if (ret) {
+ printk(KERN_INFO "setkey() failed flags=%x\n",
+ crypto_aead_get_flags(tfm));
+
+ if (!aead_tv[i].fail)
+ goto out;
+ }
+
+ sg_init_table(sg, aead_tv[i].np);
+ for (k = 0, temp = 0; k < aead_tv[i].np; k++) {
+ memcpy(&xbuf[IDX[k]],
+ aead_tv[i].input + temp,
+ aead_tv[i].tap[k]);
+ temp += aead_tv[i].tap[k];
+ sg_set_buf(&sg[k], &xbuf[IDX[k]],
+ aead_tv[i].tap[k]);
+ }
+
+ authsize = abs(aead_tv[i].rlen - aead_tv[i].ilen);
+ ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ printk(KERN_INFO
+ "failed to set authsize = %u\n",
+ authsize);
+ goto out;
+ }
+
+ if (enc)
+ sg[k - 1].length += authsize;
+
+ sg_init_table(asg, aead_tv[i].anp);
+ for (k = 0, temp = 0; k < aead_tv[i].anp; k++) {
+ memcpy(&axbuf[IDX[k]],
+ aead_tv[i].assoc + temp,
+ aead_tv[i].atap[k]);
+ temp += aead_tv[i].atap[k];
+ sg_set_buf(&asg[k], &axbuf[IDX[k]],
+ aead_tv[i].atap[k]);
+ }
+
+ aead_request_set_crypt(req, sg, sg,
+ aead_tv[i].ilen,
+ aead_tv[i].iv);
+
+ aead_request_set_assoc(req, asg, aead_tv[i].alen);
+
+ ret = enc ?
+ crypto_aead_encrypt(req) :
+ crypto_aead_decrypt(req);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &result.completion);
+ if (!ret && !(ret = result.err)) {
+ INIT_COMPLETION(result.completion);
+ break;
+ }
+ /* fall through */
+ default:
+ printk(KERN_INFO "%s () failed err=%d\n",
+ e, -ret);
+ goto out;
+ }
+
+ for (k = 0, temp = 0; k < aead_tv[i].np; k++) {
+ printk(KERN_INFO "page %u\n", k);
+ q = kmap(sg_page(&sg[k])) + sg[k].offset;
+ hexdump(q, aead_tv[i].tap[k]);
+ printk(KERN_INFO "%s\n",
+ memcmp(q, aead_tv[i].result + temp,
+ aead_tv[i].tap[k] -
+ (k < aead_tv[i].np - 1 || enc ?
+ 0 : authsize)) ?
+ "fail" : "pass");
+
+ temp += aead_tv[i].tap[k];
+ }
+ }
+ }
+
+out:
+ crypto_free_aead(tfm);
+ aead_request_free(req);
+}
+
static void test_cipher(char *algo, int enc,
struct cipher_testvec *template, unsigned int tcount)
{
@@ -237,15 +474,11 @@ static void test_cipher(char *algo, int enc,
printk("\ntesting %s %s\n", algo, e);
tsize = sizeof (struct cipher_testvec);
- tsize *= tcount;
-
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
-
- memcpy(tvmem, template, tsize);
cipher_tv = (void *)tvmem;
init_completion(&result.completion);
@@ -269,33 +502,34 @@ static void test_cipher(char *algo, int enc,
j = 0;
for (i = 0; i < tcount; i++) {
- if (!(cipher_tv[i].np)) {
+ memcpy(cipher_tv, &template[i], tsize);
+ if (!(cipher_tv->np)) {
j++;
printk("test %u (%d bit key):\n",
- j, cipher_tv[i].klen * 8);
+ j, cipher_tv->klen * 8);
crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv[i].wk)
+ if (cipher_tv->wk)
crypto_ablkcipher_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv[i].key;
+ key = cipher_tv->key;
ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv[i].klen);
+ cipher_tv->klen);
if (ret) {
printk("setkey() failed flags=%x\n",
crypto_ablkcipher_get_flags(tfm));
- if (!cipher_tv[i].fail)
+ if (!cipher_tv->fail)
goto out;
}
- sg_init_one(&sg[0], cipher_tv[i].input,
- cipher_tv[i].ilen);
+ sg_init_one(&sg[0], cipher_tv->input,
+ cipher_tv->ilen);
ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv[i].ilen,
- cipher_tv[i].iv);
+ cipher_tv->ilen,
+ cipher_tv->iv);
ret = enc ?
crypto_ablkcipher_encrypt(req) :
@@ -319,11 +553,11 @@ static void test_cipher(char *algo, int enc,
}
q = kmap(sg_page(&sg[0])) + sg[0].offset;
- hexdump(q, cipher_tv[i].rlen);
+ hexdump(q, cipher_tv->rlen);
printk("%s\n",
- memcmp(q, cipher_tv[i].result,
- cipher_tv[i].rlen) ? "fail" : "pass");
+ memcmp(q, cipher_tv->result,
+ cipher_tv->rlen) ? "fail" : "pass");
}
}
@@ -332,41 +566,42 @@ static void test_cipher(char *algo, int enc,
j = 0;
for (i = 0; i < tcount; i++) {
- if (cipher_tv[i].np) {
+ memcpy(cipher_tv, &template[i], tsize);
+ if (cipher_tv->np) {
j++;
printk("test %u (%d bit key):\n",
- j, cipher_tv[i].klen * 8);
+ j, cipher_tv->klen * 8);
crypto_ablkcipher_clear_flags(tfm, ~0);
- if (cipher_tv[i].wk)
+ if (cipher_tv->wk)
crypto_ablkcipher_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = cipher_tv[i].key;
+ key = cipher_tv->key;
ret = crypto_ablkcipher_setkey(tfm, key,
- cipher_tv[i].klen);
+ cipher_tv->klen);
if (ret) {
printk("setkey() failed flags=%x\n",
crypto_ablkcipher_get_flags(tfm));
- if (!cipher_tv[i].fail)
+ if (!cipher_tv->fail)
goto out;
}
temp = 0;
- sg_init_table(sg, cipher_tv[i].np);
- for (k = 0; k < cipher_tv[i].np; k++) {
+ sg_init_table(sg, cipher_tv->np);
+ for (k = 0; k < cipher_tv->np; k++) {
memcpy(&xbuf[IDX[k]],
- cipher_tv[i].input + temp,
- cipher_tv[i].tap[k]);
- temp += cipher_tv[i].tap[k];
+ cipher_tv->input + temp,
+ cipher_tv->tap[k]);
+ temp += cipher_tv->tap[k];
sg_set_buf(&sg[k], &xbuf[IDX[k]],
- cipher_tv[i].tap[k]);
+ cipher_tv->tap[k]);
}
ablkcipher_request_set_crypt(req, sg, sg,
- cipher_tv[i].ilen,
- cipher_tv[i].iv);
+ cipher_tv->ilen,
+ cipher_tv->iv);
ret = enc ?
crypto_ablkcipher_encrypt(req) :
@@ -390,15 +625,15 @@ static void test_cipher(char *algo, int enc,
}
temp = 0;
- for (k = 0; k < cipher_tv[i].np; k++) {
+ for (k = 0; k < cipher_tv->np; k++) {
printk("page %u\n", k);
q = kmap(sg_page(&sg[k])) + sg[k].offset;
- hexdump(q, cipher_tv[i].tap[k]);
+ hexdump(q, cipher_tv->tap[k]);
printk("%s\n",
- memcmp(q, cipher_tv[i].result + temp,
- cipher_tv[i].tap[k]) ? "fail" :
+ memcmp(q, cipher_tv->result + temp,
+ cipher_tv->tap[k]) ? "fail" :
"pass");
- temp += cipher_tv[i].tap[k];
+ temp += cipher_tv->tap[k];
}
}
}
@@ -800,7 +1035,8 @@ out:
crypto_free_hash(tfm);
}
-static void test_deflate(void)
+static void test_comp(char *algo, struct comp_testvec *ctemplate,
+ struct comp_testvec *dtemplate, int ctcount, int dtcount)
{
unsigned int i;
char result[COMP_BUF_SIZE];
@@ -808,25 +1044,26 @@ static void test_deflate(void)
struct comp_testvec *tv;
unsigned int tsize;
- printk("\ntesting deflate compression\n");
+ printk("\ntesting %s compression\n", algo);
- tsize = sizeof (deflate_comp_tv_template);
+ tsize = sizeof(struct comp_testvec);
+ tsize *= ctcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
return;
}
- memcpy(tvmem, deflate_comp_tv_template, tsize);
+ memcpy(tvmem, ctemplate, tsize);
tv = (void *)tvmem;
- tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC);
+ tfm = crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
- printk("failed to load transform for deflate\n");
+ printk("failed to load transform for %s\n", algo);
return;
}
- for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
+ for (i = 0; i < ctcount; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
@@ -845,19 +1082,20 @@ static void test_deflate(void)
ilen, dlen);
}
- printk("\ntesting deflate decompression\n");
+ printk("\ntesting %s decompression\n", algo);
- tsize = sizeof (deflate_decomp_tv_template);
+ tsize = sizeof(struct comp_testvec);
+ tsize *= dtcount;
if (tsize > TVMEMSIZE) {
printk("template (%u) too big for tvmem (%u)\n", tsize,
TVMEMSIZE);
goto out;
}
- memcpy(tvmem, deflate_decomp_tv_template, tsize);
+ memcpy(tvmem, dtemplate, tsize);
tv = (void *)tvmem;
- for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
+ for (i = 0; i < dtcount; i++) {
int ilen, ret, dlen = COMP_BUF_SIZE;
printk("test %u:\n", i + 1);
@@ -918,6 +1156,8 @@ static void do_test(void)
test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
+ test_hash("sha224", sha224_tv_template, SHA224_TEST_VECTORS);
+
test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
//BLOWFISH
@@ -969,6 +1209,18 @@ static void do_test(void)
AES_XTS_ENC_TEST_VECTORS);
test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
AES_XTS_DEC_TEST_VECTORS);
+ test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
+ AES_CTR_ENC_TEST_VECTORS);
+ test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
+ AES_CTR_DEC_TEST_VECTORS);
+ test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
+ AES_GCM_ENC_TEST_VECTORS);
+ test_aead("gcm(aes)", DECRYPT, aes_gcm_dec_tv_template,
+ AES_GCM_DEC_TEST_VECTORS);
+ test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template,
+ AES_CCM_ENC_TEST_VECTORS);
+ test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template,
+ AES_CCM_DEC_TEST_VECTORS);
//CAST5
test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
@@ -1057,12 +1309,18 @@ static void do_test(void)
test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
- test_deflate();
+ test_comp("deflate", deflate_comp_tv_template,
+ deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
+ DEFLATE_DECOMP_TEST_VECTORS);
+ test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
+ LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
test_hash("hmac(md5)", hmac_md5_tv_template,
HMAC_MD5_TEST_VECTORS);
test_hash("hmac(sha1)", hmac_sha1_tv_template,
HMAC_SHA1_TEST_VECTORS);
+ test_hash("hmac(sha224)", hmac_sha224_tv_template,
+ HMAC_SHA224_TEST_VECTORS);
test_hash("hmac(sha256)", hmac_sha256_tv_template,
HMAC_SHA256_TEST_VECTORS);
test_hash("hmac(sha384)", hmac_sha384_tv_template,
@@ -1156,6 +1414,10 @@ static void do_test(void)
AES_XTS_ENC_TEST_VECTORS);
test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
AES_XTS_DEC_TEST_VECTORS);
+ test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
+ AES_CTR_ENC_TEST_VECTORS);
+ test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
+ AES_CTR_DEC_TEST_VECTORS);
break;
case 11:
@@ -1167,7 +1429,9 @@ static void do_test(void)
break;
case 13:
- test_deflate();
+ test_comp("deflate", deflate_comp_tv_template,
+ deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
+ DEFLATE_DECOMP_TEST_VECTORS);
break;
case 14:
@@ -1291,6 +1555,34 @@ static void do_test(void)
camellia_cbc_dec_tv_template,
CAMELLIA_CBC_DEC_TEST_VECTORS);
break;
+ case 33:
+ test_hash("sha224", sha224_tv_template, SHA224_TEST_VECTORS);
+ break;
+
+ case 34:
+ test_cipher("salsa20", ENCRYPT,
+ salsa20_stream_enc_tv_template,
+ SALSA20_STREAM_ENC_TEST_VECTORS);
+ break;
+
+ case 35:
+ test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
+ AES_GCM_ENC_TEST_VECTORS);
+ test_aead("gcm(aes)", DECRYPT, aes_gcm_dec_tv_template,
+ AES_GCM_DEC_TEST_VECTORS);
+ break;
+
+ case 36:
+ test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
+ LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
+ break;
+
+ case 37:
+ test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template,
+ AES_CCM_ENC_TEST_VECTORS);
+ test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template,
+ AES_CCM_DEC_TEST_VECTORS);
+ break;
case 100:
test_hash("hmac(md5)", hmac_md5_tv_template,
@@ -1317,6 +1609,15 @@ static void do_test(void)
HMAC_SHA512_TEST_VECTORS);
break;
+ case 105:
+ test_hash("hmac(sha224)", hmac_sha224_tv_template,
+ HMAC_SHA224_TEST_VECTORS);
+ break;
+
+ case 106:
+ test_hash("xcbc(aes)", aes_xcbc128_tv_template,
+ XCBC_AES_TEST_VECTORS);
+ break;
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
@@ -1400,6 +1701,11 @@ static void do_test(void)
camellia_speed_template);
break;
+ case 206:
+ test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
+ salsa20_speed_template);
+ break;
+
case 300:
/* fall through */
@@ -1451,6 +1757,10 @@ static void do_test(void)
test_hash_speed("tgr192", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
+ case 313:
+ test_hash_speed("sha224", sec, generic_hash_speed_template);
+ if (mode > 300 && mode < 400) break;
+
case 399:
break;
@@ -1467,20 +1777,21 @@ static void do_test(void)
static int __init init(void)
{
+ int err = -ENOMEM;
+
tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
if (tvmem == NULL)
- return -ENOMEM;
+ return err;
xbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
- if (xbuf == NULL) {
- kfree(tvmem);
- return -ENOMEM;
- }
+ if (xbuf == NULL)
+ goto err_free_tv;
- do_test();
+ axbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
+ if (axbuf == NULL)
+ goto err_free_xbuf;
- kfree(xbuf);
- kfree(tvmem);
+ do_test();
/* We intentionaly return -EAGAIN to prevent keeping
* the module. It does all its work from init()
@@ -1488,7 +1799,15 @@ static int __init init(void)
* => we don't need it in the memory, do we?
* -- mludvig
*/
- return -EAGAIN;
+ err = -EAGAIN;
+
+ kfree(axbuf);
+ err_free_xbuf:
+ kfree(xbuf);
+ err_free_tv:
+ kfree(tvmem);
+
+ return err;
}
/*
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index ec86138..f785e561 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -6,12 +6,15 @@
*
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
* Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
*
* 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.
*
+ * 2007-11-13 Added GCM tests
+ * 2007-11-13 Added AEAD support
* 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests
* 2004-08-09 Cipher speed tests by Reyk Floeter <reyk@vantronix.net>
* 2003-09-14 Changes by Kartikey Mahendra Bhatt
@@ -40,14 +43,32 @@ struct hash_testvec {
struct cipher_testvec {
char key[MAX_KEYLEN] __attribute__ ((__aligned__(4)));
char iv[MAX_IVLEN];
+ char input[4100];
+ char result[4100];
+ unsigned char tap[MAX_TAP];
+ int np;
+ unsigned char fail;
+ unsigned char wk; /* weak key flag */
+ unsigned char klen;
+ unsigned short ilen;
+ unsigned short rlen;
+};
+
+struct aead_testvec {
+ char key[MAX_KEYLEN] __attribute__ ((__aligned__(4)));
+ char iv[MAX_IVLEN];
char input[512];
+ char assoc[512];
char result[512];
unsigned char tap[MAX_TAP];
+ unsigned char atap[MAX_TAP];
int np;
+ int anp;
unsigned char fail;
unsigned char wk; /* weak key flag */
unsigned char klen;
unsigned short ilen;
+ unsigned short alen;
unsigned short rlen;
};
@@ -173,6 +194,33 @@ static struct hash_testvec sha1_tv_template[] = {
}
};
+
+/*
+ * SHA224 test vectors from from FIPS PUB 180-2
+ */
+#define SHA224_TEST_VECTORS 2
+
+static struct hash_testvec sha224_tv_template[] = {
+ {
+ .plaintext = "abc",
+ .psize = 3,
+ .digest = { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
+ 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
+ 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
+ 0xE3, 0x6C, 0x9D, 0xA7},
+ }, {
+ .plaintext =
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .psize = 56,
+ .digest = { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
+ 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
+ 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
+ 0x52, 0x52, 0x25, 0x25 },
+ .np = 2,
+ .tap = { 28, 28 }
+ }
+};
+
/*
* SHA256 test vectors from from NIST
*/
@@ -817,6 +865,121 @@ static struct hash_testvec hmac_sha1_tv_template[] = {
},
};
+
+/*
+ * SHA224 HMAC test vectors from RFC4231
+ */
+#define HMAC_SHA224_TEST_VECTORS 4
+
+static struct hash_testvec hmac_sha224_tv_template[] = {
+ {
+ .key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b },
+ .ksize = 20,
+ /* ("Hi There") */
+ .plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 },
+ .psize = 8,
+ .digest = { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
+ 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
+ 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
+ 0x53, 0x68, 0x4b, 0x22},
+ }, {
+ .key = { 0x4a, 0x65, 0x66, 0x65 }, /* ("Jefe") */
+ .ksize = 4,
+ /* ("what do ya want for nothing?") */
+ .plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
+ 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
+ 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x3f },
+ .psize = 28,
+ .digest = { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
+ 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
+ 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
+ 0x8f, 0xd0, 0x5e, 0x44 },
+ .np = 4,
+ .tap = { 7, 7, 7, 7 }
+ }, {
+ .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa },
+ .ksize = 131,
+ /* ("Test Using Larger Than Block-Size Key - Hash Key First") */
+ .plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
+ 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
+ 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
+ 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
+ 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
+ 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 },
+ .psize = 54,
+ .digest = { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
+ 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
+ 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
+ 0x3f, 0xa6, 0x87, 0x0e },
+ }, {
+ .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa },
+ .ksize = 131,
+ /* ("This is a test using a larger than block-size key and a")
+ (" larger than block-size data. The key needs to be")
+ (" hashed before being used by the HMAC algorithm.") */
+ .plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
+ 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75,
+ 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
+ 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68,
+ 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65,
+ 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
+ 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74,
+ 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
+ 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64,
+ 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
+ 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65,
+ 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
+ 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20,
+ 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
+ 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65,
+ 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c,
+ 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e },
+ .psize = 152,
+ .digest = { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
+ 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
+ 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
+ 0xf6, 0xf5, 0x65, 0xd1 },
+ },
+};
+
/*
* HMAC-SHA256 test vectors from
* draft-ietf-ipsec-ciph-sha-256-01.txt
@@ -2140,12 +2303,18 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
*/
#define AES_ENC_TEST_VECTORS 3
#define AES_DEC_TEST_VECTORS 3
-#define AES_CBC_ENC_TEST_VECTORS 2
-#define AES_CBC_DEC_TEST_VECTORS 2
+#define AES_CBC_ENC_TEST_VECTORS 4
+#define AES_CBC_DEC_TEST_VECTORS 4
#define AES_LRW_ENC_TEST_VECTORS 8
#define AES_LRW_DEC_TEST_VECTORS 8
#define AES_XTS_ENC_TEST_VECTORS 4
#define AES_XTS_DEC_TEST_VECTORS 4
+#define AES_CTR_ENC_TEST_VECTORS 7
+#define AES_CTR_DEC_TEST_VECTORS 6
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
static struct cipher_testvec aes_enc_tv_template[] = {
{ /* From FIPS-197 */
@@ -2249,6 +2418,57 @@ static struct cipher_testvec aes_cbc_enc_tv_template[] = {
0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
.rlen = 32,
+ }, { /* From NIST SP800-38A */
+ .key = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+ 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+ 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b },
+ .klen = 24,
+ .iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .input = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ .ilen = 64,
+ .result = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+ 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4,
+ 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
+ 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0,
+ 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
+ 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81,
+ 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd },
+ .rlen = 64,
+ }, {
+ .key = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 },
+ .klen = 32,
+ .iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .input = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ .ilen = 64,
+ .result = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+ 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
+ 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
+ 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
+ 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
+ 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
+ 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b },
+ .rlen = 64,
},
};
@@ -2280,6 +2500,57 @@ static struct cipher_testvec aes_cbc_dec_tv_template[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
.rlen = 32,
+ }, { /* From NIST SP800-38A */
+ .key = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
+ 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
+ 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b },
+ .klen = 24,
+ .iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .input = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+ 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4,
+ 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
+ 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0,
+ 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
+ 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81,
+ 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd },
+ .ilen = 64,
+ .result = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ .rlen = 64,
+ }, {
+ .key = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 },
+ .klen = 32,
+ .iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ .input = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+ 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
+ 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
+ 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
+ 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
+ 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
+ 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b },
+ .ilen = 64,
+ .result = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ .rlen = 64,
},
};
@@ -3180,6 +3451,1843 @@ static struct cipher_testvec aes_xts_dec_tv_template[] = {
}
};
+
+static struct cipher_testvec aes_ctr_enc_tv_template[] = {
+ { /* From RFC 3686 */
+ .key = { 0xae, 0x68, 0x52, 0xf8, 0x12, 0x10, 0x67, 0xcc,
+ 0x4b, 0xf7, 0xa5, 0x76, 0x55, 0x77, 0xf3, 0x9e,
+ 0x00, 0x00, 0x00, 0x30 },
+ .klen = 20,
+ .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .input = { "Single block msg" },
+ .ilen = 16,
+ .result = { 0xe4, 0x09, 0x5d, 0x4f, 0xb7, 0xa7, 0xb3, 0x79,
+ 0x2d, 0x61, 0x75, 0xa3, 0x26, 0x13, 0x11, 0xb8 },
+ .rlen = 16,
+ }, {
+ .key = { 0x7e, 0x24, 0x06, 0x78, 0x17, 0xfa, 0xe0, 0xd7,
+ 0x43, 0xd6, 0xce, 0x1f, 0x32, 0x53, 0x91, 0x63,
+ 0x00, 0x6c, 0xb6, 0xdb },
+ .klen = 20,
+ .iv = { 0xc0, 0x54, 0x3b, 0x59, 0xda, 0x48, 0xd9, 0x0b },
+ .input = { 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 },
+ .ilen = 32,
+ .result = { 0x51, 0x04, 0xa1, 0x06, 0x16, 0x8a, 0x72, 0xd9,
+ 0x79, 0x0d, 0x41, 0xee, 0x8e, 0xda, 0xd3, 0x88,
+ 0xeb, 0x2e, 0x1e, 0xfc, 0x46, 0xda, 0x57, 0xc8,
+ 0xfc, 0xe6, 0x30, 0xdf, 0x91, 0x41, 0xbe, 0x28 },
+ .rlen = 32,
+ }, {
+ .key = { 0x16, 0xaf, 0x5b, 0x14, 0x5f, 0xc9, 0xf5, 0x79,
+ 0xc1, 0x75, 0xf9, 0x3e, 0x3b, 0xfb, 0x0e, 0xed,
+ 0x86, 0x3d, 0x06, 0xcc, 0xfd, 0xb7, 0x85, 0x15,
+ 0x00, 0x00, 0x00, 0x48 },
+ .klen = 28,
+ .iv = { 0x36, 0x73, 0x3c, 0x14, 0x7d, 0x6d, 0x93, 0xcb },
+ .input = { "Single block msg" },
+ .ilen = 16,
+ .result = { 0x4b, 0x55, 0x38, 0x4f, 0xe2, 0x59, 0xc9, 0xc8,
+ 0x4e, 0x79, 0x35, 0xa0, 0x03, 0xcb, 0xe9, 0x28 },
+ .rlen = 16,
+ }, {
+ .key = { 0x7c, 0x5c, 0xb2, 0x40, 0x1b, 0x3d, 0xc3, 0x3c,
+ 0x19, 0xe7, 0x34, 0x08, 0x19, 0xe0, 0xf6, 0x9c,
+ 0x67, 0x8c, 0x3d, 0xb8, 0xe6, 0xf6, 0xa9, 0x1a,
+ 0x00, 0x96, 0xb0, 0x3b },
+ .klen = 28,
+ .iv = { 0x02, 0x0c, 0x6e, 0xad, 0xc2, 0xcb, 0x50, 0x0d },
+ .input = { 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 },
+ .ilen = 32,
+ .result = { 0x45, 0x32, 0x43, 0xfc, 0x60, 0x9b, 0x23, 0x32,
+ 0x7e, 0xdf, 0xaa, 0xfa, 0x71, 0x31, 0xcd, 0x9f,
+ 0x84, 0x90, 0x70, 0x1c, 0x5a, 0xd4, 0xa7, 0x9c,
+ 0xfc, 0x1f, 0xe0, 0xff, 0x42, 0xf4, 0xfb, 0x00 },
+ .rlen = 32,
+ }, {
+ .key = { 0x77, 0x6b, 0xef, 0xf2, 0x85, 0x1d, 0xb0, 0x6f,
+ 0x4c, 0x8a, 0x05, 0x42, 0xc8, 0x69, 0x6f, 0x6c,
+ 0x6a, 0x81, 0xaf, 0x1e, 0xec, 0x96, 0xb4, 0xd3,
+ 0x7f, 0xc1, 0xd6, 0x89, 0xe6, 0xc1, 0xc1, 0x04,
+ 0x00, 0x00, 0x00, 0x60 },
+ .klen = 36,
+ .iv = { 0xdb, 0x56, 0x72, 0xc9, 0x7a, 0xa8, 0xf0, 0xb2 },
+ .input = { "Single block msg" },
+ .ilen = 16,
+ .result = { 0x14, 0x5a, 0xd0, 0x1d, 0xbf, 0x82, 0x4e, 0xc7,
+ 0x56, 0x08, 0x63, 0xdc, 0x71, 0xe3, 0xe0, 0xc0 },
+ .rlen = 16,
+ }, {
+ .key = { 0xf6, 0xd6, 0x6d, 0x6b, 0xd5, 0x2d, 0x59, 0xbb,
+ 0x07, 0x96, 0x36, 0x58, 0x79, 0xef, 0xf8, 0x86,
+ 0xc6, 0x6d, 0xd5, 0x1a, 0x5b, 0x6a, 0x99, 0x74,
+ 0x4b, 0x50, 0x59, 0x0c, 0x87, 0xa2, 0x38, 0x84,
+ 0x00, 0xfa, 0xac, 0x24 },
+ .klen = 36,
+ .iv = { 0xc1, 0x58, 0x5e, 0xf1, 0x5a, 0x43, 0xd8, 0x75 },
+ .input = { 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 },
+ .ilen = 32,
+ .result = { 0xf0, 0x5e, 0x23, 0x1b, 0x38, 0x94, 0x61, 0x2c,
+ 0x49, 0xee, 0x00, 0x0b, 0x80, 0x4e, 0xb2, 0xa9,
+ 0xb8, 0x30, 0x6b, 0x50, 0x8f, 0x83, 0x9d, 0x6a,
+ 0x55, 0x30, 0x83, 0x1d, 0x93, 0x44, 0xaf, 0x1c },
+ .rlen = 32,
+ }, {
+ // generated using Crypto++
+ .key = {
+ 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,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ .klen = 32 + 4,
+ .iv = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .input = {
+ 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, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ 0x00, 0x03, 0x06, 0x09, 0x0c, 0x0f, 0x12, 0x15,
+ 0x18, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d,
+ 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45,
+ 0x48, 0x4b, 0x4e, 0x51, 0x54, 0x57, 0x5a, 0x5d,
+ 0x60, 0x63, 0x66, 0x69, 0x6c, 0x6f, 0x72, 0x75,
+ 0x78, 0x7b, 0x7e, 0x81, 0x84, 0x87, 0x8a, 0x8d,
+ 0x90, 0x93, 0x96, 0x99, 0x9c, 0x9f, 0xa2, 0xa5,
+ 0xa8, 0xab, 0xae, 0xb1, 0xb4, 0xb7, 0xba, 0xbd,
+ 0xc0, 0xc3, 0xc6, 0xc9, 0xcc, 0xcf, 0xd2, 0xd5,
+ 0xd8, 0xdb, 0xde, 0xe1, 0xe4, 0xe7, 0xea, 0xed,
+ 0xf0, 0xf3, 0xf6, 0xf9, 0xfc, 0xff, 0x02, 0x05,
+ 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, 0x1a, 0x1d,
+ 0x20, 0x23, 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35,
+ 0x38, 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d,
+ 0x50, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0x65,
+ 0x68, 0x6b, 0x6e, 0x71, 0x74, 0x77, 0x7a, 0x7d,
+ 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95,
+ 0x98, 0x9b, 0x9e, 0xa1, 0xa4, 0xa7, 0xaa, 0xad,
+ 0xb0, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc2, 0xc5,
+ 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, 0xdd,
+ 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, 0xf5,
+ 0xf8, 0xfb, 0xfe, 0x01, 0x04, 0x07, 0x0a, 0x0d,
+ 0x10, 0x13, 0x16, 0x19, 0x1c, 0x1f, 0x22, 0x25,
+ 0x28, 0x2b, 0x2e, 0x31, 0x34, 0x37, 0x3a, 0x3d,
+ 0x40, 0x43, 0x46, 0x49, 0x4c, 0x4f, 0x52, 0x55,
+ 0x58, 0x5b, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6d,
+ 0x70, 0x73, 0x76, 0x79, 0x7c, 0x7f, 0x82, 0x85,
+ 0x88, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9d,
+ 0xa0, 0xa3, 0xa6, 0xa9, 0xac, 0xaf, 0xb2, 0xb5,
+ 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
+ 0xd0, 0xd3, 0xd6, 0xd9, 0xdc, 0xdf, 0xe2, 0xe5,
+ 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf7, 0xfa, 0xfd,
+ 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1e, 0x23,
+ 0x28, 0x2d, 0x32, 0x37, 0x3c, 0x41, 0x46, 0x4b,
+ 0x50, 0x55, 0x5a, 0x5f, 0x64, 0x69, 0x6e, 0x73,
+ 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91, 0x96, 0x9b,
+ 0xa0, 0xa5, 0xaa, 0xaf, 0xb4, 0xb9, 0xbe, 0xc3,
+ 0xc8, 0xcd, 0xd2, 0xd7, 0xdc, 0xe1, 0xe6, 0xeb,
+ 0xf0, 0xf5, 0xfa, 0xff, 0x04, 0x09, 0x0e, 0x13,
+ 0x18, 0x1d, 0x22, 0x27, 0x2c, 0x31, 0x36, 0x3b,
+ 0x40, 0x45, 0x4a, 0x4f, 0x54, 0x59, 0x5e, 0x63,
+ 0x68, 0x6d, 0x72, 0x77, 0x7c, 0x81, 0x86, 0x8b,
+ 0x90, 0x95, 0x9a, 0x9f, 0xa4, 0xa9, 0xae, 0xb3,
+ 0xb8, 0xbd, 0xc2, 0xc7, 0xcc, 0xd1, 0xd6, 0xdb,
+ 0xe0, 0xe5, 0xea, 0xef, 0xf4, 0xf9, 0xfe, 0x03,
+ 0x08, 0x0d, 0x12, 0x17, 0x1c, 0x21, 0x26, 0x2b,
+ 0x30, 0x35, 0x3a, 0x3f, 0x44, 0x49, 0x4e, 0x53,
+ 0x58, 0x5d, 0x62, 0x67, 0x6c, 0x71, 0x76, 0x7b,
+ 0x80, 0x85, 0x8a, 0x8f, 0x94, 0x99, 0x9e, 0xa3,
+ 0xa8, 0xad, 0xb2, 0xb7, 0xbc, 0xc1, 0xc6, 0xcb,
+ 0xd0, 0xd5, 0xda, 0xdf, 0xe4, 0xe9, 0xee, 0xf3,
+ 0xf8, 0xfd, 0x02, 0x07, 0x0c, 0x11, 0x16, 0x1b,
+ 0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3e, 0x43,
+ 0x48, 0x4d, 0x52, 0x57, 0x5c, 0x61, 0x66, 0x6b,
+ 0x70, 0x75, 0x7a, 0x7f, 0x84, 0x89, 0x8e, 0x93,
+ 0x98, 0x9d, 0xa2, 0xa7, 0xac, 0xb1, 0xb6, 0xbb,
+ 0xc0, 0xc5, 0xca, 0xcf, 0xd4, 0xd9, 0xde, 0xe3,
+ 0xe8, 0xed, 0xf2, 0xf7, 0xfc, 0x01, 0x06, 0x0b,
+ 0x10, 0x15, 0x1a, 0x1f, 0x24, 0x29, 0x2e, 0x33,
+ 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x51, 0x56, 0x5b,
+ 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7e, 0x83,
+ 0x88, 0x8d, 0x92, 0x97, 0x9c, 0xa1, 0xa6, 0xab,
+ 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9, 0xce, 0xd3,
+ 0xd8, 0xdd, 0xe2, 0xe7, 0xec, 0xf1, 0xf6, 0xfb,
+ 0x00, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31,
+ 0x38, 0x3f, 0x46, 0x4d, 0x54, 0x5b, 0x62, 0x69,
+ 0x70, 0x77, 0x7e, 0x85, 0x8c, 0x93, 0x9a, 0xa1,
+ 0xa8, 0xaf, 0xb6, 0xbd, 0xc4, 0xcb, 0xd2, 0xd9,
+ 0xe0, 0xe7, 0xee, 0xf5, 0xfc, 0x03, 0x0a, 0x11,
+ 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x49,
+ 0x50, 0x57, 0x5e, 0x65, 0x6c, 0x73, 0x7a, 0x81,
+ 0x88, 0x8f, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb9,
+ 0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1,
+ 0xf8, 0xff, 0x06, 0x0d, 0x14, 0x1b, 0x22, 0x29,
+ 0x30, 0x37, 0x3e, 0x45, 0x4c, 0x53, 0x5a, 0x61,
+ 0x68, 0x6f, 0x76, 0x7d, 0x84, 0x8b, 0x92, 0x99,
+ 0xa0, 0xa7, 0xae, 0xb5, 0xbc, 0xc3, 0xca, 0xd1,
+ 0xd8, 0xdf, 0xe6, 0xed, 0xf4, 0xfb, 0x02, 0x09,
+ 0x10, 0x17, 0x1e, 0x25, 0x2c, 0x33, 0x3a, 0x41,
+ 0x48, 0x4f, 0x56, 0x5d, 0x64, 0x6b, 0x72, 0x79,
+ 0x80, 0x87, 0x8e, 0x95, 0x9c, 0xa3, 0xaa, 0xb1,
+ 0xb8, 0xbf, 0xc6, 0xcd, 0xd4, 0xdb, 0xe2, 0xe9,
+ 0xf0, 0xf7, 0xfe, 0x05, 0x0c, 0x13, 0x1a, 0x21,
+ 0x28, 0x2f, 0x36, 0x3d, 0x44, 0x4b, 0x52, 0x59,
+ 0x60, 0x67, 0x6e, 0x75, 0x7c, 0x83, 0x8a, 0x91,
+ 0x98, 0x9f, 0xa6, 0xad, 0xb4, 0xbb, 0xc2, 0xc9,
+ 0xd0, 0xd7, 0xde, 0xe5, 0xec, 0xf3, 0xfa, 0x01,
+ 0x08, 0x0f, 0x16, 0x1d, 0x24, 0x2b, 0x32, 0x39,
+ 0x40, 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71,
+ 0x78, 0x7f, 0x86, 0x8d, 0x94, 0x9b, 0xa2, 0xa9,
+ 0xb0, 0xb7, 0xbe, 0xc5, 0xcc, 0xd3, 0xda, 0xe1,
+ 0xe8, 0xef, 0xf6, 0xfd, 0x04, 0x0b, 0x12, 0x19,
+ 0x20, 0x27, 0x2e, 0x35, 0x3c, 0x43, 0x4a, 0x51,
+ 0x58, 0x5f, 0x66, 0x6d, 0x74, 0x7b, 0x82, 0x89,
+ 0x90, 0x97, 0x9e, 0xa5, 0xac, 0xb3, 0xba, 0xc1,
+ 0xc8, 0xcf, 0xd6, 0xdd, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x51, 0x5a, 0x63, 0x6c, 0x75, 0x7e, 0x87,
+ 0x90, 0x99, 0xa2, 0xab, 0xb4, 0xbd, 0xc6, 0xcf,
+ 0xd8, 0xe1, 0xea, 0xf3, 0xfc, 0x05, 0x0e, 0x17,
+ 0x20, 0x29, 0x32, 0x3b, 0x44, 0x4d, 0x56, 0x5f,
+ 0x68, 0x71, 0x7a, 0x83, 0x8c, 0x95, 0x9e, 0xa7,
+ 0xb0, 0xb9, 0xc2, 0xcb, 0xd4, 0xdd, 0xe6, 0xef,
+ 0xf8, 0x01, 0x0a, 0x13, 0x1c, 0x25, 0x2e, 0x37,
+ 0x40, 0x49, 0x52, 0x5b, 0x64, 0x6d, 0x76, 0x7f,
+ 0x88, 0x91, 0x9a, 0xa3, 0xac, 0xb5, 0xbe, 0xc7,
+ 0xd0, 0xd9, 0xe2, 0xeb, 0xf4, 0xfd, 0x06, 0x0f,
+ 0x18, 0x21, 0x2a, 0x33, 0x3c, 0x45, 0x4e, 0x57,
+ 0x60, 0x69, 0x72, 0x7b, 0x84, 0x8d, 0x96, 0x9f,
+ 0xa8, 0xb1, 0xba, 0xc3, 0xcc, 0xd5, 0xde, 0xe7,
+ 0xf0, 0xf9, 0x02, 0x0b, 0x14, 0x1d, 0x26, 0x2f,
+ 0x38, 0x41, 0x4a, 0x53, 0x5c, 0x65, 0x6e, 0x77,
+ 0x80, 0x89, 0x92, 0x9b, 0xa4, 0xad, 0xb6, 0xbf,
+ 0xc8, 0xd1, 0xda, 0xe3, 0xec, 0xf5, 0xfe, 0x07,
+ 0x10, 0x19, 0x22, 0x2b, 0x34, 0x3d, 0x46, 0x4f,
+ 0x58, 0x61, 0x6a, 0x73, 0x7c, 0x85, 0x8e, 0x97,
+ 0xa0, 0xa9, 0xb2, 0xbb, 0xc4, 0xcd, 0xd6, 0xdf,
+ 0xe8, 0xf1, 0xfa, 0x03, 0x0c, 0x15, 0x1e, 0x27,
+ 0x30, 0x39, 0x42, 0x4b, 0x54, 0x5d, 0x66, 0x6f,
+ 0x78, 0x81, 0x8a, 0x93, 0x9c, 0xa5, 0xae, 0xb7,
+ 0xc0, 0xc9, 0xd2, 0xdb, 0xe4, 0xed, 0xf6, 0xff,
+ 0x08, 0x11, 0x1a, 0x23, 0x2c, 0x35, 0x3e, 0x47,
+ 0x50, 0x59, 0x62, 0x6b, 0x74, 0x7d, 0x86, 0x8f,
+ 0x98, 0xa1, 0xaa, 0xb3, 0xbc, 0xc5, 0xce, 0xd7,
+ 0xe0, 0xe9, 0xf2, 0xfb, 0x04, 0x0d, 0x16, 0x1f,
+ 0x28, 0x31, 0x3a, 0x43, 0x4c, 0x55, 0x5e, 0x67,
+ 0x70, 0x79, 0x82, 0x8b, 0x94, 0x9d, 0xa6, 0xaf,
+ 0xb8, 0xc1, 0xca, 0xd3, 0xdc, 0xe5, 0xee, 0xf7,
+ 0x00, 0x0b, 0x16, 0x21, 0x2c, 0x37, 0x42, 0x4d,
+ 0x58, 0x63, 0x6e, 0x79, 0x84, 0x8f, 0x9a, 0xa5,
+ 0xb0, 0xbb, 0xc6, 0xd1, 0xdc, 0xe7, 0xf2, 0xfd,
+ 0x08, 0x13, 0x1e, 0x29, 0x34, 0x3f, 0x4a, 0x55,
+ 0x60, 0x6b, 0x76, 0x81, 0x8c, 0x97, 0xa2, 0xad,
+ 0xb8, 0xc3, 0xce, 0xd9, 0xe4, 0xef, 0xfa, 0x05,
+ 0x10, 0x1b, 0x26, 0x31, 0x3c, 0x47, 0x52, 0x5d,
+ 0x68, 0x73, 0x7e, 0x89, 0x94, 0x9f, 0xaa, 0xb5,
+ 0xc0, 0xcb, 0xd6, 0xe1, 0xec, 0xf7, 0x02, 0x0d,
+ 0x18, 0x23, 0x2e, 0x39, 0x44, 0x4f, 0x5a, 0x65,
+ 0x70, 0x7b, 0x86, 0x91, 0x9c, 0xa7, 0xb2, 0xbd,
+ 0xc8, 0xd3, 0xde, 0xe9, 0xf4, 0xff, 0x0a, 0x15,
+ 0x20, 0x2b, 0x36, 0x41, 0x4c, 0x57, 0x62, 0x6d,
+ 0x78, 0x83, 0x8e, 0x99, 0xa4, 0xaf, 0xba, 0xc5,
+ 0xd0, 0xdb, 0xe6, 0xf1, 0xfc, 0x07, 0x12, 0x1d,
+ 0x28, 0x33, 0x3e, 0x49, 0x54, 0x5f, 0x6a, 0x75,
+ 0x80, 0x8b, 0x96, 0xa1, 0xac, 0xb7, 0xc2, 0xcd,
+ 0xd8, 0xe3, 0xee, 0xf9, 0x04, 0x0f, 0x1a, 0x25,
+ 0x30, 0x3b, 0x46, 0x51, 0x5c, 0x67, 0x72, 0x7d,
+ 0x88, 0x93, 0x9e, 0xa9, 0xb4, 0xbf, 0xca, 0xd5,
+ 0xe0, 0xeb, 0xf6, 0x01, 0x0c, 0x17, 0x22, 0x2d,
+ 0x38, 0x43, 0x4e, 0x59, 0x64, 0x6f, 0x7a, 0x85,
+ 0x90, 0x9b, 0xa6, 0xb1, 0xbc, 0xc7, 0xd2, 0xdd,
+ 0xe8, 0xf3, 0xfe, 0x09, 0x14, 0x1f, 0x2a, 0x35,
+ 0x40, 0x4b, 0x56, 0x61, 0x6c, 0x77, 0x82, 0x8d,
+ 0x98, 0xa3, 0xae, 0xb9, 0xc4, 0xcf, 0xda, 0xe5,
+ 0xf0, 0xfb, 0x06, 0x11, 0x1c, 0x27, 0x32, 0x3d,
+ 0x48, 0x53, 0x5e, 0x69, 0x74, 0x7f, 0x8a, 0x95,
+ 0xa0, 0xab, 0xb6, 0xc1, 0xcc, 0xd7, 0xe2, 0xed,
+ 0xf8, 0x03, 0x0e, 0x19, 0x24, 0x2f, 0x3a, 0x45,
+ 0x50, 0x5b, 0x66, 0x71, 0x7c, 0x87, 0x92, 0x9d,
+ 0xa8, 0xb3, 0xbe, 0xc9, 0xd4, 0xdf, 0xea, 0xf5,
+ 0x00, 0x0d, 0x1a, 0x27, 0x34, 0x41, 0x4e, 0x5b,
+ 0x68, 0x75, 0x82, 0x8f, 0x9c, 0xa9, 0xb6, 0xc3,
+ 0xd0, 0xdd, 0xea, 0xf7, 0x04, 0x11, 0x1e, 0x2b,
+ 0x38, 0x45, 0x52, 0x5f, 0x6c, 0x79, 0x86, 0x93,
+ 0xa0, 0xad, 0xba, 0xc7, 0xd4, 0xe1, 0xee, 0xfb,
+ 0x08, 0x15, 0x22, 0x2f, 0x3c, 0x49, 0x56, 0x63,
+ 0x70, 0x7d, 0x8a, 0x97, 0xa4, 0xb1, 0xbe, 0xcb,
+ 0xd8, 0xe5, 0xf2, 0xff, 0x0c, 0x19, 0x26, 0x33,
+ 0x40, 0x4d, 0x5a, 0x67, 0x74, 0x81, 0x8e, 0x9b,
+ 0xa8, 0xb5, 0xc2, 0xcf, 0xdc, 0xe9, 0xf6, 0x03,
+ 0x10, 0x1d, 0x2a, 0x37, 0x44, 0x51, 0x5e, 0x6b,
+ 0x78, 0x85, 0x92, 0x9f, 0xac, 0xb9, 0xc6, 0xd3,
+ 0xe0, 0xed, 0xfa, 0x07, 0x14, 0x21, 0x2e, 0x3b,
+ 0x48, 0x55, 0x62, 0x6f, 0x7c, 0x89, 0x96, 0xa3,
+ 0xb0, 0xbd, 0xca, 0xd7, 0xe4, 0xf1, 0xfe, 0x0b,
+ 0x18, 0x25, 0x32, 0x3f, 0x4c, 0x59, 0x66, 0x73,
+ 0x80, 0x8d, 0x9a, 0xa7, 0xb4, 0xc1, 0xce, 0xdb,
+ 0xe8, 0xf5, 0x02, 0x0f, 0x1c, 0x29, 0x36, 0x43,
+ 0x50, 0x5d, 0x6a, 0x77, 0x84, 0x91, 0x9e, 0xab,
+ 0xb8, 0xc5, 0xd2, 0xdf, 0xec, 0xf9, 0x06, 0x13,
+ 0x20, 0x2d, 0x3a, 0x47, 0x54, 0x61, 0x6e, 0x7b,
+ 0x88, 0x95, 0xa2, 0xaf, 0xbc, 0xc9, 0xd6, 0xe3,
+ 0xf0, 0xfd, 0x0a, 0x17, 0x24, 0x31, 0x3e, 0x4b,
+ 0x58, 0x65, 0x72, 0x7f, 0x8c, 0x99, 0xa6, 0xb3,
+ 0xc0, 0xcd, 0xda, 0xe7, 0xf4, 0x01, 0x0e, 0x1b,
+ 0x28, 0x35, 0x42, 0x4f, 0x5c, 0x69, 0x76, 0x83,
+ 0x90, 0x9d, 0xaa, 0xb7, 0xc4, 0xd1, 0xde, 0xeb,
+ 0xf8, 0x05, 0x12, 0x1f, 0x2c, 0x39, 0x46, 0x53,
+ 0x60, 0x6d, 0x7a, 0x87, 0x94, 0xa1, 0xae, 0xbb,
+ 0xc8, 0xd5, 0xe2, 0xef, 0xfc, 0x09, 0x16, 0x23,
+ 0x30, 0x3d, 0x4a, 0x57, 0x64, 0x71, 0x7e, 0x8b,
+ 0x98, 0xa5, 0xb2, 0xbf, 0xcc, 0xd9, 0xe6, 0xf3,
+ 0x00, 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69,
+ 0x78, 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1,
+ 0xf0, 0xff, 0x0e, 0x1d, 0x2c, 0x3b, 0x4a, 0x59,
+ 0x68, 0x77, 0x86, 0x95, 0xa4, 0xb3, 0xc2, 0xd1,
+ 0xe0, 0xef, 0xfe, 0x0d, 0x1c, 0x2b, 0x3a, 0x49,
+ 0x58, 0x67, 0x76, 0x85, 0x94, 0xa3, 0xb2, 0xc1,
+ 0xd0, 0xdf, 0xee, 0xfd, 0x0c, 0x1b, 0x2a, 0x39,
+ 0x48, 0x57, 0x66, 0x75, 0x84, 0x93, 0xa2, 0xb1,
+ 0xc0, 0xcf, 0xde, 0xed, 0xfc, 0x0b, 0x1a, 0x29,
+ 0x38, 0x47, 0x56, 0x65, 0x74, 0x83, 0x92, 0xa1,
+ 0xb0, 0xbf, 0xce, 0xdd, 0xec, 0xfb, 0x0a, 0x19,
+ 0x28, 0x37, 0x46, 0x55, 0x64, 0x73, 0x82, 0x91,
+ 0xa0, 0xaf, 0xbe, 0xcd, 0xdc, 0xeb, 0xfa, 0x09,
+ 0x18, 0x27, 0x36, 0x45, 0x54, 0x63, 0x72, 0x81,
+ 0x90, 0x9f, 0xae, 0xbd, 0xcc, 0xdb, 0xea, 0xf9,
+ 0x08, 0x17, 0x26, 0x35, 0x44, 0x53, 0x62, 0x71,
+ 0x80, 0x8f, 0x9e, 0xad, 0xbc, 0xcb, 0xda, 0xe9,
+ 0xf8, 0x07, 0x16, 0x25, 0x34, 0x43, 0x52, 0x61,
+ 0x70, 0x7f, 0x8e, 0x9d, 0xac, 0xbb, 0xca, 0xd9,
+ 0xe8, 0xf7, 0x06, 0x15, 0x24, 0x33, 0x42, 0x51,
+ 0x60, 0x6f, 0x7e, 0x8d, 0x9c, 0xab, 0xba, 0xc9,
+ 0xd8, 0xe7, 0xf6, 0x05, 0x14, 0x23, 0x32, 0x41,
+ 0x50, 0x5f, 0x6e, 0x7d, 0x8c, 0x9b, 0xaa, 0xb9,
+ 0xc8, 0xd7, 0xe6, 0xf5, 0x04, 0x13, 0x22, 0x31,
+ 0x40, 0x4f, 0x5e, 0x6d, 0x7c, 0x8b, 0x9a, 0xa9,
+ 0xb8, 0xc7, 0xd6, 0xe5, 0xf4, 0x03, 0x12, 0x21,
+ 0x30, 0x3f, 0x4e, 0x5d, 0x6c, 0x7b, 0x8a, 0x99,
+ 0xa8, 0xb7, 0xc6, 0xd5, 0xe4, 0xf3, 0x02, 0x11,
+ 0x20, 0x2f, 0x3e, 0x4d, 0x5c, 0x6b, 0x7a, 0x89,
+ 0x98, 0xa7, 0xb6, 0xc5, 0xd4, 0xe3, 0xf2, 0x01,
+ 0x10, 0x1f, 0x2e, 0x3d, 0x4c, 0x5b, 0x6a, 0x79,
+ 0x88, 0x97, 0xa6, 0xb5, 0xc4, 0xd3, 0xe2, 0xf1,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+ 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
+ 0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0x0f,
+ 0x20, 0x31, 0x42, 0x53, 0x64, 0x75, 0x86, 0x97,
+ 0xa8, 0xb9, 0xca, 0xdb, 0xec, 0xfd, 0x0e, 0x1f,
+ 0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
+ 0xb8, 0xc9, 0xda, 0xeb, 0xfc, 0x0d, 0x1e, 0x2f,
+ 0x40, 0x51, 0x62, 0x73, 0x84, 0x95, 0xa6, 0xb7,
+ 0xc8, 0xd9, 0xea, 0xfb, 0x0c, 0x1d, 0x2e, 0x3f,
+ 0x50, 0x61, 0x72, 0x83, 0x94, 0xa5, 0xb6, 0xc7,
+ 0xd8, 0xe9, 0xfa, 0x0b, 0x1c, 0x2d, 0x3e, 0x4f,
+ 0x60, 0x71, 0x82, 0x93, 0xa4, 0xb5, 0xc6, 0xd7,
+ 0xe8, 0xf9, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f,
+ 0x70, 0x81, 0x92, 0xa3, 0xb4, 0xc5, 0xd6, 0xe7,
+ 0xf8, 0x09, 0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f,
+ 0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7,
+ 0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f,
+ 0x90, 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6, 0x07,
+ 0x18, 0x29, 0x3a, 0x4b, 0x5c, 0x6d, 0x7e, 0x8f,
+ 0xa0, 0xb1, 0xc2, 0xd3, 0xe4, 0xf5, 0x06, 0x17,
+ 0x28, 0x39, 0x4a, 0x5b, 0x6c, 0x7d, 0x8e, 0x9f,
+ 0xb0, 0xc1, 0xd2, 0xe3, 0xf4, 0x05, 0x16, 0x27,
+ 0x38, 0x49, 0x5a, 0x6b, 0x7c, 0x8d, 0x9e, 0xaf,
+ 0xc0, 0xd1, 0xe2, 0xf3, 0x04, 0x15, 0x26, 0x37,
+ 0x48, 0x59, 0x6a, 0x7b, 0x8c, 0x9d, 0xae, 0xbf,
+ 0xd0, 0xe1, 0xf2, 0x03, 0x14, 0x25, 0x36, 0x47,
+ 0x58, 0x69, 0x7a, 0x8b, 0x9c, 0xad, 0xbe, 0xcf,
+ 0xe0, 0xf1, 0x02, 0x13, 0x24, 0x35, 0x46, 0x57,
+ 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf,
+ 0xf0, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67,
+ 0x78, 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef,
+ 0x00, 0x13, 0x26, 0x39, 0x4c, 0x5f, 0x72, 0x85,
+ 0x98, 0xab, 0xbe, 0xd1, 0xe4, 0xf7, 0x0a, 0x1d,
+ 0x30, 0x43, 0x56, 0x69, 0x7c, 0x8f, 0xa2, 0xb5,
+ 0xc8, 0xdb, 0xee, 0x01, 0x14, 0x27, 0x3a, 0x4d,
+ 0x60, 0x73, 0x86, 0x99, 0xac, 0xbf, 0xd2, 0xe5,
+ 0xf8, 0x0b, 0x1e, 0x31, 0x44, 0x57, 0x6a, 0x7d,
+ 0x90, 0xa3, 0xb6, 0xc9, 0xdc, 0xef, 0x02, 0x15,
+ 0x28, 0x3b, 0x4e, 0x61, 0x74, 0x87, 0x9a, 0xad,
+ 0xc0, 0xd3, 0xe6, 0xf9, 0x0c, 0x1f, 0x32, 0x45,
+ 0x58, 0x6b, 0x7e, 0x91, 0xa4, 0xb7, 0xca, 0xdd,
+ 0xf0, 0x03, 0x16, 0x29, 0x3c, 0x4f, 0x62, 0x75,
+ 0x88, 0x9b, 0xae, 0xc1, 0xd4, 0xe7, 0xfa, 0x0d,
+ 0x20, 0x33, 0x46, 0x59, 0x6c, 0x7f, 0x92, 0xa5,
+ 0xb8, 0xcb, 0xde, 0xf1, 0x04, 0x17, 0x2a, 0x3d,
+ 0x50, 0x63, 0x76, 0x89, 0x9c, 0xaf, 0xc2, 0xd5,
+ 0xe8, 0xfb, 0x0e, 0x21, 0x34, 0x47, 0x5a, 0x6d,
+ 0x80, 0x93, 0xa6, 0xb9, 0xcc, 0xdf, 0xf2, 0x05,
+ 0x18, 0x2b, 0x3e, 0x51, 0x64, 0x77, 0x8a, 0x9d,
+ 0xb0, 0xc3, 0xd6, 0xe9, 0xfc, 0x0f, 0x22, 0x35,
+ 0x48, 0x5b, 0x6e, 0x81, 0x94, 0xa7, 0xba, 0xcd,
+ 0xe0, 0xf3, 0x06, 0x19, 0x2c, 0x3f, 0x52, 0x65,
+ 0x78, 0x8b, 0x9e, 0xb1, 0xc4, 0xd7, 0xea, 0xfd,
+ 0x10, 0x23, 0x36, 0x49, 0x5c, 0x6f, 0x82, 0x95,
+ 0xa8, 0xbb, 0xce, 0xe1, 0xf4, 0x07, 0x1a, 0x2d,
+ 0x40, 0x53, 0x66, 0x79, 0x8c, 0x9f, 0xb2, 0xc5,
+ 0xd8, 0xeb, 0xfe, 0x11, 0x24, 0x37, 0x4a, 0x5d,
+ 0x70, 0x83, 0x96, 0xa9, 0xbc, 0xcf, 0xe2, 0xf5,
+ 0x08, 0x1b, 0x2e, 0x41, 0x54, 0x67, 0x7a, 0x8d,
+ 0xa0, 0xb3, 0xc6, 0xd9, 0xec, 0xff, 0x12, 0x25,
+ 0x38, 0x4b, 0x5e, 0x71, 0x84, 0x97, 0xaa, 0xbd,
+ 0xd0, 0xe3, 0xf6, 0x09, 0x1c, 0x2f, 0x42, 0x55,
+ 0x68, 0x7b, 0x8e, 0xa1, 0xb4, 0xc7, 0xda, 0xed,
+ 0x00, 0x15, 0x2a, 0x3f, 0x54, 0x69, 0x7e, 0x93,
+ 0xa8, 0xbd, 0xd2, 0xe7, 0xfc, 0x11, 0x26, 0x3b,
+ 0x50, 0x65, 0x7a, 0x8f, 0xa4, 0xb9, 0xce, 0xe3,
+ 0xf8, 0x0d, 0x22, 0x37, 0x4c, 0x61, 0x76, 0x8b,
+ 0xa0, 0xb5, 0xca, 0xdf, 0xf4, 0x09, 0x1e, 0x33,
+ 0x48, 0x5d, 0x72, 0x87, 0x9c, 0xb1, 0xc6, 0xdb,
+ 0xf0, 0x05, 0x1a, 0x2f, 0x44, 0x59, 0x6e, 0x83,
+ 0x98, 0xad, 0xc2, 0xd7, 0xec, 0x01, 0x16, 0x2b,
+ 0x40, 0x55, 0x6a, 0x7f, 0x94, 0xa9, 0xbe, 0xd3,
+ 0xe8, 0xfd, 0x12, 0x27, 0x3c, 0x51, 0x66, 0x7b,
+ 0x90, 0xa5, 0xba, 0xcf, 0xe4, 0xf9, 0x0e, 0x23,
+ 0x38, 0x4d, 0x62, 0x77, 0x8c, 0xa1, 0xb6, 0xcb,
+ 0xe0, 0xf5, 0x0a, 0x1f, 0x34, 0x49, 0x5e, 0x73,
+ 0x88, 0x9d, 0xb2, 0xc7, 0xdc, 0xf1, 0x06, 0x1b,
+ 0x30, 0x45, 0x5a, 0x6f, 0x84, 0x99, 0xae, 0xc3,
+ 0xd8, 0xed, 0x02, 0x17, 0x2c, 0x41, 0x56, 0x6b,
+ 0x80, 0x95, 0xaa, 0xbf, 0xd4, 0xe9, 0xfe, 0x13,
+ 0x28, 0x3d, 0x52, 0x67, 0x7c, 0x91, 0xa6, 0xbb,
+ 0xd0, 0xe5, 0xfa, 0x0f, 0x24, 0x39, 0x4e, 0x63,
+ 0x78, 0x8d, 0xa2, 0xb7, 0xcc, 0xe1, 0xf6, 0x0b,
+ 0x20, 0x35, 0x4a, 0x5f, 0x74, 0x89, 0x9e, 0xb3,
+ 0xc8, 0xdd, 0xf2, 0x07, 0x1c, 0x31, 0x46, 0x5b,
+ 0x70, 0x85, 0x9a, 0xaf, 0xc4, 0xd9, 0xee, 0x03,
+ 0x18, 0x2d, 0x42, 0x57, 0x6c, 0x81, 0x96, 0xab,
+ 0xc0, 0xd5, 0xea, 0xff, 0x14, 0x29, 0x3e, 0x53,
+ 0x68, 0x7d, 0x92, 0xa7, 0xbc, 0xd1, 0xe6, 0xfb,
+ 0x10, 0x25, 0x3a, 0x4f, 0x64, 0x79, 0x8e, 0xa3,
+ 0xb8, 0xcd, 0xe2, 0xf7, 0x0c, 0x21, 0x36, 0x4b,
+ 0x60, 0x75, 0x8a, 0x9f, 0xb4, 0xc9, 0xde, 0xf3,
+ 0x08, 0x1d, 0x32, 0x47, 0x5c, 0x71, 0x86, 0x9b,
+ 0xb0, 0xc5, 0xda, 0xef, 0x04, 0x19, 0x2e, 0x43,
+ 0x58, 0x6d, 0x82, 0x97, 0xac, 0xc1, 0xd6, 0xeb,
+ 0x00, 0x17, 0x2e, 0x45, 0x5c, 0x73, 0x8a, 0xa1,
+ 0xb8, 0xcf, 0xe6, 0xfd, 0x14, 0x2b, 0x42, 0x59,
+ 0x70, 0x87, 0x9e, 0xb5, 0xcc, 0xe3, 0xfa, 0x11,
+ 0x28, 0x3f, 0x56, 0x6d, 0x84, 0x9b, 0xb2, 0xc9,
+ 0xe0, 0xf7, 0x0e, 0x25, 0x3c, 0x53, 0x6a, 0x81,
+ 0x98, 0xaf, 0xc6, 0xdd, 0xf4, 0x0b, 0x22, 0x39,
+ 0x50, 0x67, 0x7e, 0x95, 0xac, 0xc3, 0xda, 0xf1,
+ 0x08, 0x1f, 0x36, 0x4d, 0x64, 0x7b, 0x92, 0xa9,
+ 0xc0, 0xd7, 0xee, 0x05, 0x1c, 0x33, 0x4a, 0x61,
+ 0x78, 0x8f, 0xa6, 0xbd, 0xd4, 0xeb, 0x02, 0x19,
+ 0x30, 0x47, 0x5e, 0x75, 0x8c, 0xa3, 0xba, 0xd1,
+ 0xe8, 0xff, 0x16, 0x2d, 0x44, 0x5b, 0x72, 0x89,
+ 0xa0, 0xb7, 0xce, 0xe5, 0xfc, 0x13, 0x2a, 0x41,
+ 0x58, 0x6f, 0x86, 0x9d, 0xb4, 0xcb, 0xe2, 0xf9,
+ 0x10, 0x27, 0x3e, 0x55, 0x6c, 0x83, 0x9a, 0xb1,
+ 0xc8, 0xdf, 0xf6, 0x0d, 0x24, 0x3b, 0x52, 0x69,
+ 0x80, 0x97, 0xae, 0xc5, 0xdc, 0xf3, 0x0a, 0x21,
+ 0x38, 0x4f, 0x66, 0x7d, 0x94, 0xab, 0xc2, 0xd9,
+ 0xf0, 0x07, 0x1e, 0x35, 0x4c, 0x63, 0x7a, 0x91,
+ 0xa8, 0xbf, 0xd6, 0xed, 0x04, 0x1b, 0x32, 0x49,
+ 0x60, 0x77, 0x8e, 0xa5, 0xbc, 0xd3, 0xea, 0x01,
+ 0x18, 0x2f, 0x46, 0x5d, 0x74, 0x8b, 0xa2, 0xb9,
+ 0xd0, 0xe7, 0xfe, 0x15, 0x2c, 0x43, 0x5a, 0x71,
+ 0x88, 0x9f, 0xb6, 0xcd, 0xe4, 0xfb, 0x12, 0x29,
+ 0x40, 0x57, 0x6e, 0x85, 0x9c, 0xb3, 0xca, 0xe1,
+ 0xf8, 0x0f, 0x26, 0x3d, 0x54, 0x6b, 0x82, 0x99,
+ 0xb0, 0xc7, 0xde, 0xf5, 0x0c, 0x23, 0x3a, 0x51,
+ 0x68, 0x7f, 0x96, 0xad, 0xc4, 0xdb, 0xf2, 0x09,
+ 0x20, 0x37, 0x4e, 0x65, 0x7c, 0x93, 0xaa, 0xc1,
+ 0xd8, 0xef, 0x06, 0x1d, 0x34, 0x4b, 0x62, 0x79,
+ 0x90, 0xa7, 0xbe, 0xd5, 0xec, 0x03, 0x1a, 0x31,
+ 0x48, 0x5f, 0x76, 0x8d, 0xa4, 0xbb, 0xd2, 0xe9,
+ 0x00, 0x19, 0x32, 0x4b, 0x64, 0x7d, 0x96, 0xaf,
+ 0xc8, 0xe1, 0xfa, 0x13, 0x2c, 0x45, 0x5e, 0x77,
+ 0x90, 0xa9, 0xc2, 0xdb, 0xf4, 0x0d, 0x26, 0x3f,
+ 0x58, 0x71, 0x8a, 0xa3, 0xbc, 0xd5, 0xee, 0x07,
+ 0x20, 0x39, 0x52, 0x6b, 0x84, 0x9d, 0xb6, 0xcf,
+ 0xe8, 0x01, 0x1a, 0x33, 0x4c, 0x65, 0x7e, 0x97,
+ 0xb0, 0xc9, 0xe2, 0xfb, 0x14, 0x2d, 0x46, 0x5f,
+ 0x78, 0x91, 0xaa, 0xc3, 0xdc, 0xf5, 0x0e, 0x27,
+ 0x40, 0x59, 0x72, 0x8b, 0xa4, 0xbd, 0xd6, 0xef,
+ 0x08, 0x21, 0x3a, 0x53, 0x6c, 0x85, 0x9e, 0xb7,
+ 0xd0, 0xe9, 0x02, 0x1b, 0x34, 0x4d, 0x66, 0x7f,
+ 0x98, 0xb1, 0xca, 0xe3, 0xfc, 0x15, 0x2e, 0x47,
+ 0x60, 0x79, 0x92, 0xab, 0xc4, 0xdd, 0xf6, 0x0f,
+ 0x28, 0x41, 0x5a, 0x73, 0x8c, 0xa5, 0xbe, 0xd7,
+ 0xf0, 0x09, 0x22, 0x3b, 0x54, 0x6d, 0x86, 0x9f,
+ 0xb8, 0xd1, 0xea, 0x03, 0x1c, 0x35, 0x4e, 0x67,
+ 0x80, 0x99, 0xb2, 0xcb, 0xe4, 0xfd, 0x16, 0x2f,
+ 0x48, 0x61, 0x7a, 0x93, 0xac, 0xc5, 0xde, 0xf7,
+ 0x10, 0x29, 0x42, 0x5b, 0x74, 0x8d, 0xa6, 0xbf,
+ 0xd8, 0xf1, 0x0a, 0x23, 0x3c, 0x55, 0x6e, 0x87,
+ 0xa0, 0xb9, 0xd2, 0xeb, 0x04, 0x1d, 0x36, 0x4f,
+ 0x68, 0x81, 0x9a, 0xb3, 0xcc, 0xe5, 0xfe, 0x17,
+ 0x30, 0x49, 0x62, 0x7b, 0x94, 0xad, 0xc6, 0xdf,
+ 0xf8, 0x11, 0x2a, 0x43, 0x5c, 0x75, 0x8e, 0xa7,
+ 0xc0, 0xd9, 0xf2, 0x0b, 0x24, 0x3d, 0x56, 0x6f,
+ 0x88, 0xa1, 0xba, 0xd3, 0xec, 0x05, 0x1e, 0x37,
+ 0x50, 0x69, 0x82, 0x9b, 0xb4, 0xcd, 0xe6, 0xff,
+ 0x18, 0x31, 0x4a, 0x63, 0x7c, 0x95, 0xae, 0xc7,
+ 0xe0, 0xf9, 0x12, 0x2b, 0x44, 0x5d, 0x76, 0x8f,
+ 0xa8, 0xc1, 0xda, 0xf3, 0x0c, 0x25, 0x3e, 0x57,
+ 0x70, 0x89, 0xa2, 0xbb, 0xd4, 0xed, 0x06, 0x1f,
+ 0x38, 0x51, 0x6a, 0x83, 0x9c, 0xb5, 0xce, 0xe7,
+ 0x00, 0x1b, 0x36, 0x51, 0x6c, 0x87, 0xa2, 0xbd,
+ 0xd8, 0xf3, 0x0e, 0x29, 0x44, 0x5f, 0x7a, 0x95,
+ 0xb0, 0xcb, 0xe6, 0x01, 0x1c, 0x37, 0x52, 0x6d,
+ 0x88, 0xa3, 0xbe, 0xd9, 0xf4, 0x0f, 0x2a, 0x45,
+ 0x60, 0x7b, 0x96, 0xb1, 0xcc, 0xe7, 0x02, 0x1d,
+ 0x38, 0x53, 0x6e, 0x89, 0xa4, 0xbf, 0xda, 0xf5,
+ 0x10, 0x2b, 0x46, 0x61, 0x7c, 0x97, 0xb2, 0xcd,
+ 0xe8, 0x03, 0x1e, 0x39, 0x54, 0x6f, 0x8a, 0xa5,
+ 0xc0, 0xdb, 0xf6, 0x11, 0x2c, 0x47, 0x62, 0x7d,
+ 0x98, 0xb3, 0xce, 0xe9, 0x04, 0x1f, 0x3a, 0x55,
+ 0x70, 0x8b, 0xa6, 0xc1, 0xdc, 0xf7, 0x12, 0x2d,
+ 0x48, 0x63, 0x7e, 0x99, 0xb4, 0xcf, 0xea, 0x05,
+ 0x20, 0x3b, 0x56, 0x71, 0x8c, 0xa7, 0xc2, 0xdd,
+ 0xf8, 0x13, 0x2e, 0x49, 0x64, 0x7f, 0x9a, 0xb5,
+ 0xd0, 0xeb, 0x06, 0x21, 0x3c, 0x57, 0x72, 0x8d,
+ 0xa8, 0xc3, 0xde, 0xf9, 0x14, 0x2f, 0x4a, 0x65,
+ 0x80, 0x9b, 0xb6, 0xd1, 0xec, 0x07, 0x22, 0x3d,
+ 0x58, 0x73, 0x8e, 0xa9, 0xc4, 0xdf, 0xfa, 0x15,
+ 0x30, 0x4b, 0x66, 0x81, 0x9c, 0xb7, 0xd2, 0xed,
+ 0x08, 0x23, 0x3e, 0x59, 0x74, 0x8f, 0xaa, 0xc5,
+ 0xe0, 0xfb, 0x16, 0x31, 0x4c, 0x67, 0x82, 0x9d,
+ 0xb8, 0xd3, 0xee, 0x09, 0x24, 0x3f, 0x5a, 0x75,
+ 0x90, 0xab, 0xc6, 0xe1, 0xfc, 0x17, 0x32, 0x4d,
+ 0x68, 0x83, 0x9e, 0xb9, 0xd4, 0xef, 0x0a, 0x25,
+ 0x40, 0x5b, 0x76, 0x91, 0xac, 0xc7, 0xe2, 0xfd,
+ 0x18, 0x33, 0x4e, 0x69, 0x84, 0x9f, 0xba, 0xd5,
+ 0xf0, 0x0b, 0x26, 0x41, 0x5c, 0x77, 0x92, 0xad,
+ 0xc8, 0xe3, 0xfe, 0x19, 0x34, 0x4f, 0x6a, 0x85,
+ 0xa0, 0xbb, 0xd6, 0xf1, 0x0c, 0x27, 0x42, 0x5d,
+ 0x78, 0x93, 0xae, 0xc9, 0xe4, 0xff, 0x1a, 0x35,
+ 0x50, 0x6b, 0x86, 0xa1, 0xbc, 0xd7, 0xf2, 0x0d,
+ 0x28, 0x43, 0x5e, 0x79, 0x94, 0xaf, 0xca, 0xe5,
+ 0x00, 0x1d, 0x3a, 0x57, 0x74, 0x91, 0xae, 0xcb,
+ 0xe8, 0x05, 0x22, 0x3f, 0x5c, 0x79, 0x96, 0xb3,
+ 0xd0, 0xed, 0x0a, 0x27, 0x44, 0x61, 0x7e, 0x9b,
+ 0xb8, 0xd5, 0xf2, 0x0f, 0x2c, 0x49, 0x66, 0x83,
+ 0xa0, 0xbd, 0xda, 0xf7, 0x14, 0x31, 0x4e, 0x6b,
+ 0x88, 0xa5, 0xc2, 0xdf, 0xfc, 0x19, 0x36, 0x53,
+ 0x70, 0x8d, 0xaa, 0xc7, 0xe4, 0x01, 0x1e, 0x3b,
+ 0x58, 0x75, 0x92, 0xaf, 0xcc, 0xe9, 0x06, 0x23,
+ 0x40, 0x5d, 0x7a, 0x97, 0xb4, 0xd1, 0xee, 0x0b,
+ 0x28, 0x45, 0x62, 0x7f, 0x9c, 0xb9, 0xd6, 0xf3,
+ 0x10, 0x2d, 0x4a, 0x67, 0x84, 0xa1, 0xbe, 0xdb,
+ 0xf8, 0x15, 0x32, 0x4f, 0x6c, 0x89, 0xa6, 0xc3,
+ 0xe0, 0xfd, 0x1a, 0x37, 0x54, 0x71, 0x8e, 0xab,
+ 0xc8, 0xe5, 0x02, 0x1f, 0x3c, 0x59, 0x76, 0x93,
+ 0xb0, 0xcd, 0xea, 0x07, 0x24, 0x41, 0x5e, 0x7b,
+ 0x98, 0xb5, 0xd2, 0xef, 0x0c, 0x29, 0x46, 0x63,
+ 0x80, 0x9d, 0xba, 0xd7, 0xf4, 0x11, 0x2e, 0x4b,
+ 0x68, 0x85, 0xa2, 0xbf, 0xdc, 0xf9, 0x16, 0x33,
+ 0x50, 0x6d, 0x8a, 0xa7, 0xc4, 0xe1, 0xfe, 0x1b,
+ 0x38, 0x55, 0x72, 0x8f, 0xac, 0xc9, 0xe6, 0x03,
+ 0x20, 0x3d, 0x5a, 0x77, 0x94, 0xb1, 0xce, 0xeb,
+ 0x08, 0x25, 0x42, 0x5f, 0x7c, 0x99, 0xb6, 0xd3,
+ 0xf0, 0x0d, 0x2a, 0x47, 0x64, 0x81, 0x9e, 0xbb,
+ 0xd8, 0xf5, 0x12, 0x2f, 0x4c, 0x69, 0x86, 0xa3,
+ 0xc0, 0xdd, 0xfa, 0x17, 0x34, 0x51, 0x6e, 0x8b,
+ 0xa8, 0xc5, 0xe2, 0xff, 0x1c, 0x39, 0x56, 0x73,
+ 0x90, 0xad, 0xca, 0xe7, 0x04, 0x21, 0x3e, 0x5b,
+ 0x78, 0x95, 0xb2, 0xcf, 0xec, 0x09, 0x26, 0x43,
+ 0x60, 0x7d, 0x9a, 0xb7, 0xd4, 0xf1, 0x0e, 0x2b,
+ 0x48, 0x65, 0x82, 0x9f, 0xbc, 0xd9, 0xf6, 0x13,
+ 0x30, 0x4d, 0x6a, 0x87, 0xa4, 0xc1, 0xde, 0xfb,
+ 0x18, 0x35, 0x52, 0x6f, 0x8c, 0xa9, 0xc6, 0xe3,
+ 0x00, 0x1f, 0x3e, 0x5d, 0x7c, 0x9b, 0xba, 0xd9,
+ 0xf8, 0x17, 0x36, 0x55, 0x74, 0x93, 0xb2, 0xd1,
+ 0xf0, 0x0f, 0x2e, 0x4d, 0x6c, 0x8b, 0xaa, 0xc9,
+ 0xe8, 0x07, 0x26, 0x45, 0x64, 0x83, 0xa2, 0xc1,
+ 0xe0, 0xff, 0x1e, 0x3d, 0x5c, 0x7b, 0x9a, 0xb9,
+ 0xd8, 0xf7, 0x16, 0x35, 0x54, 0x73, 0x92, 0xb1,
+ 0xd0, 0xef, 0x0e, 0x2d, 0x4c, 0x6b, 0x8a, 0xa9,
+ 0xc8, 0xe7, 0x06, 0x25, 0x44, 0x63, 0x82, 0xa1,
+ 0xc0, 0xdf, 0xfe, 0x1d, 0x3c, 0x5b, 0x7a, 0x99,
+ 0xb8, 0xd7, 0xf6, 0x15, 0x34, 0x53, 0x72, 0x91,
+ 0xb0, 0xcf, 0xee, 0x0d, 0x2c, 0x4b, 0x6a, 0x89,
+ 0xa8, 0xc7, 0xe6, 0x05, 0x24, 0x43, 0x62, 0x81,
+ 0xa0, 0xbf, 0xde, 0xfd, 0x1c, 0x3b, 0x5a, 0x79,
+ 0x98, 0xb7, 0xd6, 0xf5, 0x14, 0x33, 0x52, 0x71,
+ 0x90, 0xaf, 0xce, 0xed, 0x0c, 0x2b, 0x4a, 0x69,
+ 0x88, 0xa7, 0xc6, 0xe5, 0x04, 0x23, 0x42, 0x61,
+ 0x80, 0x9f, 0xbe, 0xdd, 0xfc, 0x1b, 0x3a, 0x59,
+ 0x78, 0x97, 0xb6, 0xd5, 0xf4, 0x13, 0x32, 0x51,
+ 0x70, 0x8f, 0xae, 0xcd, 0xec, 0x0b, 0x2a, 0x49,
+ 0x68, 0x87, 0xa6, 0xc5, 0xe4, 0x03, 0x22, 0x41,
+ 0x60, 0x7f, 0x9e, 0xbd, 0xdc, 0xfb, 0x1a, 0x39,
+ 0x58, 0x77, 0x96, 0xb5, 0xd4, 0xf3, 0x12, 0x31,
+ 0x50, 0x6f, 0x8e, 0xad, 0xcc, 0xeb, 0x0a, 0x29,
+ 0x48, 0x67, 0x86, 0xa5, 0xc4, 0xe3, 0x02, 0x21,
+ 0x40, 0x5f, 0x7e, 0x9d, 0xbc, 0xdb, 0xfa, 0x19,
+ 0x38, 0x57, 0x76, 0x95, 0xb4, 0xd3, 0xf2, 0x11,
+ 0x30, 0x4f, 0x6e, 0x8d, 0xac, 0xcb, 0xea, 0x09,
+ 0x28, 0x47, 0x66, 0x85, 0xa4, 0xc3, 0xe2, 0x01,
+ 0x20, 0x3f, 0x5e, 0x7d, 0x9c, 0xbb, 0xda, 0xf9,
+ 0x18, 0x37, 0x56, 0x75, 0x94, 0xb3, 0xd2, 0xf1,
+ 0x10, 0x2f, 0x4e, 0x6d, 0x8c, 0xab, 0xca, 0xe9,
+ 0x08, 0x27, 0x46, 0x65, 0x84, 0xa3, 0xc2, 0xe1,
+ 0x00, 0x21, 0x42, 0x63,
+ },
+ .ilen = 4100,
+ .result = {
+ 0xf0, 0x5c, 0x74, 0xad, 0x4e, 0xbc, 0x99, 0xe2,
+ 0xae, 0xff, 0x91, 0x3a, 0x44, 0xcf, 0x38, 0x32,
+ 0x1e, 0xad, 0xa7, 0xcd, 0xa1, 0x39, 0x95, 0xaa,
+ 0x10, 0xb1, 0xb3, 0x2e, 0x04, 0x31, 0x8f, 0x86,
+ 0xf2, 0x62, 0x74, 0x70, 0x0c, 0xa4, 0x46, 0x08,
+ 0xa8, 0xb7, 0x99, 0xa8, 0xe9, 0xd2, 0x73, 0x79,
+ 0x7e, 0x6e, 0xd4, 0x8f, 0x1e, 0xc7, 0x8e, 0x31,
+ 0x0b, 0xfa, 0x4b, 0xce, 0xfd, 0xf3, 0x57, 0x71,
+ 0xe9, 0x46, 0x03, 0xa5, 0x3d, 0x34, 0x00, 0xe2,
+ 0x18, 0xff, 0x75, 0x6d, 0x06, 0x2d, 0x00, 0xab,
+ 0xb9, 0x3e, 0x6c, 0x59, 0xc5, 0x84, 0x06, 0xb5,
+ 0x8b, 0xd0, 0x89, 0x9c, 0x4a, 0x79, 0x16, 0xc6,
+ 0x3d, 0x74, 0x54, 0xfa, 0x44, 0xcd, 0x23, 0x26,
+ 0x5c, 0xcf, 0x7e, 0x28, 0x92, 0x32, 0xbf, 0xdf,
+ 0xa7, 0x20, 0x3c, 0x74, 0x58, 0x2a, 0x9a, 0xde,
+ 0x61, 0x00, 0x1c, 0x4f, 0xff, 0x59, 0xc4, 0x22,
+ 0xac, 0x3c, 0xd0, 0xe8, 0x6c, 0xf9, 0x97, 0x1b,
+ 0x58, 0x9b, 0xad, 0x71, 0xe8, 0xa9, 0xb5, 0x0d,
+ 0xee, 0x2f, 0x04, 0x1f, 0x7f, 0xbc, 0x99, 0xee,
+ 0x84, 0xff, 0x42, 0x60, 0xdc, 0x3a, 0x18, 0xa5,
+ 0x81, 0xf9, 0xef, 0xdc, 0x7a, 0x0f, 0x65, 0x41,
+ 0x2f, 0xa3, 0xd3, 0xf9, 0xc2, 0xcb, 0xc0, 0x4d,
+ 0x8f, 0xd3, 0x76, 0x96, 0xad, 0x49, 0x6d, 0x38,
+ 0x3d, 0x39, 0x0b, 0x6c, 0x80, 0xb7, 0x54, 0x69,
+ 0xf0, 0x2c, 0x90, 0x02, 0x29, 0x0d, 0x1c, 0x12,
+ 0xad, 0x55, 0xc3, 0x8b, 0x68, 0xd9, 0xcc, 0xb3,
+ 0xb2, 0x64, 0x33, 0x90, 0x5e, 0xca, 0x4b, 0xe2,
+ 0xfb, 0x75, 0xdc, 0x63, 0xf7, 0x9f, 0x82, 0x74,
+ 0xf0, 0xc9, 0xaa, 0x7f, 0xe9, 0x2a, 0x9b, 0x33,
+ 0xbc, 0x88, 0x00, 0x7f, 0xca, 0xb2, 0x1f, 0x14,
+ 0xdb, 0xc5, 0x8e, 0x7b, 0x11, 0x3c, 0x3e, 0x08,
+ 0xf3, 0x83, 0xe8, 0xe0, 0x94, 0x86, 0x2e, 0x92,
+ 0x78, 0x6b, 0x01, 0xc9, 0xc7, 0x83, 0xba, 0x21,
+ 0x6a, 0x25, 0x15, 0x33, 0x4e, 0x45, 0x08, 0xec,
+ 0x35, 0xdb, 0xe0, 0x6e, 0x31, 0x51, 0x79, 0xa9,
+ 0x42, 0x44, 0x65, 0xc1, 0xa0, 0xf1, 0xf9, 0x2a,
+ 0x70, 0xd5, 0xb6, 0xc6, 0xc1, 0x8c, 0x39, 0xfc,
+ 0x25, 0xa6, 0x55, 0xd9, 0xdd, 0x2d, 0x4c, 0xec,
+ 0x49, 0xc6, 0xeb, 0x0e, 0xa8, 0x25, 0x2a, 0x16,
+ 0x1b, 0x66, 0x84, 0xda, 0xe2, 0x92, 0xe5, 0xc0,
+ 0xc8, 0x53, 0x07, 0xaf, 0x80, 0x84, 0xec, 0xfd,
+ 0xcd, 0xd1, 0x6e, 0xcd, 0x6f, 0x6a, 0xf5, 0x36,
+ 0xc5, 0x15, 0xe5, 0x25, 0x7d, 0x77, 0xd1, 0x1a,
+ 0x93, 0x36, 0xa9, 0xcf, 0x7c, 0xa4, 0x54, 0x4a,
+ 0x06, 0x51, 0x48, 0x4e, 0xf6, 0x59, 0x87, 0xd2,
+ 0x04, 0x02, 0xef, 0xd3, 0x44, 0xde, 0x76, 0x31,
+ 0xb3, 0x34, 0x17, 0x1b, 0x9d, 0x66, 0x11, 0x9f,
+ 0x1e, 0xcc, 0x17, 0xe9, 0xc7, 0x3c, 0x1b, 0xe7,
+ 0xcb, 0x50, 0x08, 0xfc, 0xdc, 0x2b, 0x24, 0xdb,
+ 0x65, 0x83, 0xd0, 0x3b, 0xe3, 0x30, 0xea, 0x94,
+ 0x6c, 0xe7, 0xe8, 0x35, 0x32, 0xc7, 0xdb, 0x64,
+ 0xb4, 0x01, 0xab, 0x36, 0x2c, 0x77, 0x13, 0xaf,
+ 0xf8, 0x2b, 0x88, 0x3f, 0x54, 0x39, 0xc4, 0x44,
+ 0xfe, 0xef, 0x6f, 0x68, 0x34, 0xbe, 0x0f, 0x05,
+ 0x16, 0x6d, 0xf6, 0x0a, 0x30, 0xe7, 0xe3, 0xed,
+ 0xc4, 0xde, 0x3c, 0x1b, 0x13, 0xd8, 0xdb, 0xfe,
+ 0x41, 0x62, 0xe5, 0x28, 0xd4, 0x8d, 0xa3, 0xc7,
+ 0x93, 0x97, 0xc6, 0x48, 0x45, 0x1d, 0x9f, 0x83,
+ 0xdf, 0x4b, 0x40, 0x3e, 0x42, 0x25, 0x87, 0x80,
+ 0x4c, 0x7d, 0xa8, 0xd4, 0x98, 0x23, 0x95, 0x75,
+ 0x41, 0x8c, 0xda, 0x41, 0x9b, 0xd4, 0xa7, 0x06,
+ 0xb5, 0xf1, 0x71, 0x09, 0x53, 0xbe, 0xca, 0xbf,
+ 0x32, 0x03, 0xed, 0xf0, 0x50, 0x1c, 0x56, 0x39,
+ 0x5b, 0xa4, 0x75, 0x18, 0xf7, 0x9b, 0x58, 0xef,
+ 0x53, 0xfc, 0x2a, 0x38, 0x23, 0x15, 0x75, 0xcd,
+ 0x45, 0xe5, 0x5a, 0x82, 0x55, 0xba, 0x21, 0xfa,
+ 0xd4, 0xbd, 0xc6, 0x94, 0x7c, 0xc5, 0x80, 0x12,
+ 0xf7, 0x4b, 0x32, 0xc4, 0x9a, 0x82, 0xd8, 0x28,
+ 0x8f, 0xd9, 0xc2, 0x0f, 0x60, 0x03, 0xbe, 0x5e,
+ 0x21, 0xd6, 0x5f, 0x58, 0xbf, 0x5c, 0xb1, 0x32,
+ 0x82, 0x8d, 0xa9, 0xe5, 0xf2, 0x66, 0x1a, 0xc0,
+ 0xa0, 0xbc, 0x58, 0x2f, 0x71, 0xf5, 0x2f, 0xed,
+ 0xd1, 0x26, 0xb9, 0xd8, 0x49, 0x5a, 0x07, 0x19,
+ 0x01, 0x7c, 0x59, 0xb0, 0xf8, 0xa4, 0xb7, 0xd3,
+ 0x7b, 0x1a, 0x8c, 0x38, 0xf4, 0x50, 0xa4, 0x59,
+ 0xb0, 0xcc, 0x41, 0x0b, 0x88, 0x7f, 0xe5, 0x31,
+ 0xb3, 0x42, 0xba, 0xa2, 0x7e, 0xd4, 0x32, 0x71,
+ 0x45, 0x87, 0x48, 0xa9, 0xc2, 0xf2, 0x89, 0xb3,
+ 0xe4, 0xa7, 0x7e, 0x52, 0x15, 0x61, 0xfa, 0xfe,
+ 0xc9, 0xdd, 0x81, 0xeb, 0x13, 0xab, 0xab, 0xc3,
+ 0x98, 0x59, 0xd8, 0x16, 0x3d, 0x14, 0x7a, 0x1c,
+ 0x3c, 0x41, 0x9a, 0x16, 0x16, 0x9b, 0xd2, 0xd2,
+ 0x69, 0x3a, 0x29, 0x23, 0xac, 0x86, 0x32, 0xa5,
+ 0x48, 0x9c, 0x9e, 0xf3, 0x47, 0x77, 0x81, 0x70,
+ 0x24, 0xe8, 0x85, 0xd2, 0xf5, 0xb5, 0xfa, 0xff,
+ 0x59, 0x6a, 0xd3, 0x50, 0x59, 0x43, 0x59, 0xde,
+ 0xd9, 0xf1, 0x55, 0xa5, 0x0c, 0xc3, 0x1a, 0x1a,
+ 0x18, 0x34, 0x0d, 0x1a, 0x63, 0x33, 0xed, 0x10,
+ 0xe0, 0x1d, 0x2a, 0x18, 0xd2, 0xc0, 0x54, 0xa8,
+ 0xca, 0xb5, 0x9a, 0xd3, 0xdd, 0xca, 0x45, 0x84,
+ 0x50, 0xe7, 0x0f, 0xfe, 0xa4, 0x99, 0x5a, 0xbe,
+ 0x43, 0x2d, 0x9a, 0xcb, 0x92, 0x3f, 0x5a, 0x1d,
+ 0x85, 0xd8, 0xc9, 0xdf, 0x68, 0xc9, 0x12, 0x80,
+ 0x56, 0x0c, 0xdc, 0x00, 0xdc, 0x3a, 0x7d, 0x9d,
+ 0xa3, 0xa2, 0xe8, 0x4d, 0xbf, 0xf9, 0x70, 0xa0,
+ 0xa4, 0x13, 0x4f, 0x6b, 0xaf, 0x0a, 0x89, 0x7f,
+ 0xda, 0xf0, 0xbf, 0x9b, 0xc8, 0x1d, 0xe5, 0xf8,
+ 0x2e, 0x8b, 0x07, 0xb5, 0x73, 0x1b, 0xcc, 0xa2,
+ 0xa6, 0xad, 0x30, 0xbc, 0x78, 0x3c, 0x5b, 0x10,
+ 0xfa, 0x5e, 0x62, 0x2d, 0x9e, 0x64, 0xb3, 0x33,
+ 0xce, 0xf9, 0x1f, 0x86, 0xe7, 0x8b, 0xa2, 0xb8,
+ 0xe8, 0x99, 0x57, 0x8c, 0x11, 0xed, 0x66, 0xd9,
+ 0x3c, 0x72, 0xb9, 0xc3, 0xe6, 0x4e, 0x17, 0x3a,
+ 0x6a, 0xcb, 0x42, 0x24, 0x06, 0xed, 0x3e, 0x4e,
+ 0xa3, 0xe8, 0x6a, 0x94, 0xda, 0x0d, 0x4e, 0xd5,
+ 0x14, 0x19, 0xcf, 0xb6, 0x26, 0xd8, 0x2e, 0xcc,
+ 0x64, 0x76, 0x38, 0x49, 0x4d, 0xfe, 0x30, 0x6d,
+ 0xe4, 0xc8, 0x8c, 0x7b, 0xc4, 0xe0, 0x35, 0xba,
+ 0x22, 0x6e, 0x76, 0xe1, 0x1a, 0xf2, 0x53, 0xc3,
+ 0x28, 0xa2, 0x82, 0x1f, 0x61, 0x69, 0xad, 0xc1,
+ 0x7b, 0x28, 0x4b, 0x1e, 0x6c, 0x85, 0x95, 0x9b,
+ 0x51, 0xb5, 0x17, 0x7f, 0x12, 0x69, 0x8c, 0x24,
+ 0xd5, 0xc7, 0x5a, 0x5a, 0x11, 0x54, 0xff, 0x5a,
+ 0xf7, 0x16, 0xc3, 0x91, 0xa6, 0xf0, 0xdc, 0x0a,
+ 0xb6, 0xa7, 0x4a, 0x0d, 0x7a, 0x58, 0xfe, 0xa5,
+ 0xf5, 0xcb, 0x8f, 0x7b, 0x0e, 0xea, 0x57, 0xe7,
+ 0xbd, 0x79, 0xd6, 0x1c, 0x88, 0x23, 0x6c, 0xf2,
+ 0x4d, 0x29, 0x77, 0x53, 0x35, 0x6a, 0x00, 0x8d,
+ 0xcd, 0xa3, 0x58, 0xbe, 0x77, 0x99, 0x18, 0xf8,
+ 0xe6, 0xe1, 0x8f, 0xe9, 0x37, 0x8f, 0xe3, 0xe2,
+ 0x5a, 0x8a, 0x93, 0x25, 0xaf, 0xf3, 0x78, 0x80,
+ 0xbe, 0xa6, 0x1b, 0xc6, 0xac, 0x8b, 0x1c, 0x91,
+ 0x58, 0xe1, 0x9f, 0x89, 0x35, 0x9d, 0x1d, 0x21,
+ 0x29, 0x9f, 0xf4, 0x99, 0x02, 0x27, 0x0f, 0xa8,
+ 0x4f, 0x79, 0x94, 0x2b, 0x33, 0x2c, 0xda, 0xa2,
+ 0x26, 0x39, 0x83, 0x94, 0xef, 0x27, 0xd8, 0x53,
+ 0x8f, 0x66, 0x0d, 0xe4, 0x41, 0x7d, 0x34, 0xcd,
+ 0x43, 0x7c, 0x95, 0x0a, 0x53, 0xef, 0x66, 0xda,
+ 0x7e, 0x9b, 0xf3, 0x93, 0xaf, 0xd0, 0x73, 0x71,
+ 0xba, 0x40, 0x9b, 0x74, 0xf8, 0xd7, 0xd7, 0x41,
+ 0x6d, 0xaf, 0x72, 0x9c, 0x8d, 0x21, 0x87, 0x3c,
+ 0xfd, 0x0a, 0x90, 0xa9, 0x47, 0x96, 0x9e, 0xd3,
+ 0x88, 0xee, 0x73, 0xcf, 0x66, 0x2f, 0x52, 0x56,
+ 0x6d, 0xa9, 0x80, 0x4c, 0xe2, 0x6f, 0x62, 0x88,
+ 0x3f, 0x0e, 0x54, 0x17, 0x48, 0x80, 0x5d, 0xd3,
+ 0xc3, 0xda, 0x25, 0x3d, 0xa1, 0xc8, 0xcb, 0x9f,
+ 0x9b, 0x70, 0xb3, 0xa1, 0xeb, 0x04, 0x52, 0xa1,
+ 0xf2, 0x22, 0x0f, 0xfc, 0xc8, 0x18, 0xfa, 0xf9,
+ 0x85, 0x9c, 0xf1, 0xac, 0xeb, 0x0c, 0x02, 0x46,
+ 0x75, 0xd2, 0xf5, 0x2c, 0xe3, 0xd2, 0x59, 0x94,
+ 0x12, 0xf3, 0x3c, 0xfc, 0xd7, 0x92, 0xfa, 0x36,
+ 0xba, 0x61, 0x34, 0x38, 0x7c, 0xda, 0x48, 0x3e,
+ 0x08, 0xc9, 0x39, 0x23, 0x5e, 0x02, 0x2c, 0x1a,
+ 0x18, 0x7e, 0xb4, 0xd9, 0xfd, 0x9e, 0x40, 0x02,
+ 0xb1, 0x33, 0x37, 0x32, 0xe7, 0xde, 0xd6, 0xd0,
+ 0x7c, 0x58, 0x65, 0x4b, 0xf8, 0x34, 0x27, 0x9c,
+ 0x44, 0xb4, 0xbd, 0xe9, 0xe9, 0x4c, 0x78, 0x7d,
+ 0x4b, 0x9f, 0xce, 0xb1, 0xcd, 0x47, 0xa5, 0x37,
+ 0xe5, 0x6d, 0xbd, 0xb9, 0x43, 0x94, 0x0a, 0xd4,
+ 0xd6, 0xf9, 0x04, 0x5f, 0xb5, 0x66, 0x6c, 0x1a,
+ 0x35, 0x12, 0xe3, 0x36, 0x28, 0x27, 0x36, 0x58,
+ 0x01, 0x2b, 0x79, 0xe4, 0xba, 0x6d, 0x10, 0x7d,
+ 0x65, 0xdf, 0x84, 0x95, 0xf4, 0xd5, 0xb6, 0x8f,
+ 0x2b, 0x9f, 0x96, 0x00, 0x86, 0x60, 0xf0, 0x21,
+ 0x76, 0xa8, 0x6a, 0x8c, 0x28, 0x1c, 0xb3, 0x6b,
+ 0x97, 0xd7, 0xb6, 0x53, 0x2a, 0xcc, 0xab, 0x40,
+ 0x9d, 0x62, 0x79, 0x58, 0x52, 0xe6, 0x65, 0xb7,
+ 0xab, 0x55, 0x67, 0x9c, 0x89, 0x7c, 0x03, 0xb0,
+ 0x73, 0x59, 0xc5, 0x81, 0xf5, 0x18, 0x17, 0x5c,
+ 0x89, 0xf3, 0x78, 0x35, 0x44, 0x62, 0x78, 0x72,
+ 0xd0, 0x96, 0xeb, 0x31, 0xe7, 0x87, 0x77, 0x14,
+ 0x99, 0x51, 0xf2, 0x59, 0x26, 0x9e, 0xb5, 0xa6,
+ 0x45, 0xfe, 0x6e, 0xbd, 0x07, 0x4c, 0x94, 0x5a,
+ 0xa5, 0x7d, 0xfc, 0xf1, 0x2b, 0x77, 0xe2, 0xfe,
+ 0x17, 0xd4, 0x84, 0xa0, 0xac, 0xb5, 0xc7, 0xda,
+ 0xa9, 0x1a, 0xb6, 0xf3, 0x74, 0x11, 0xb4, 0x9d,
+ 0xfb, 0x79, 0x2e, 0x04, 0x2d, 0x50, 0x28, 0x83,
+ 0xbf, 0xc6, 0x52, 0xd3, 0x34, 0xd6, 0xe8, 0x7a,
+ 0xb6, 0xea, 0xe7, 0xa8, 0x6c, 0x15, 0x1e, 0x2c,
+ 0x57, 0xbc, 0x48, 0x4e, 0x5f, 0x5c, 0xb6, 0x92,
+ 0xd2, 0x49, 0x77, 0x81, 0x6d, 0x90, 0x70, 0xae,
+ 0x98, 0xa1, 0x03, 0x0d, 0x6b, 0xb9, 0x77, 0x14,
+ 0xf1, 0x4e, 0x23, 0xd3, 0xf8, 0x68, 0xbd, 0xc2,
+ 0xfe, 0x04, 0xb7, 0x5c, 0xc5, 0x17, 0x60, 0x8f,
+ 0x65, 0x54, 0xa4, 0x7a, 0x42, 0xdc, 0x18, 0x0d,
+ 0xb5, 0xcf, 0x0f, 0xd3, 0xc7, 0x91, 0x66, 0x1b,
+ 0x45, 0x42, 0x27, 0x75, 0x50, 0xe5, 0xee, 0xb8,
+ 0x7f, 0x33, 0x2c, 0xba, 0x4a, 0x92, 0x4d, 0x2c,
+ 0x3c, 0xe3, 0x0d, 0x80, 0x01, 0xba, 0x0d, 0x29,
+ 0xd8, 0x3c, 0xe9, 0x13, 0x16, 0x57, 0xe6, 0xea,
+ 0x94, 0x52, 0xe7, 0x00, 0x4d, 0x30, 0xb0, 0x0f,
+ 0x35, 0xb8, 0xb8, 0xa7, 0xb1, 0xb5, 0x3b, 0x44,
+ 0xe1, 0x2f, 0xfd, 0x88, 0xed, 0x43, 0xe7, 0x52,
+ 0x10, 0x93, 0xb3, 0x8a, 0x30, 0x6b, 0x0a, 0xf7,
+ 0x23, 0xc6, 0x50, 0x9d, 0x4a, 0xb0, 0xde, 0xc3,
+ 0xdc, 0x9b, 0x2f, 0x01, 0x56, 0x36, 0x09, 0xc5,
+ 0x2f, 0x6b, 0xfe, 0xf1, 0xd8, 0x27, 0x45, 0x03,
+ 0x30, 0x5e, 0x5c, 0x5b, 0xb4, 0x62, 0x0e, 0x1a,
+ 0xa9, 0x21, 0x2b, 0x92, 0x94, 0x87, 0x62, 0x57,
+ 0x4c, 0x10, 0x74, 0x1a, 0xf1, 0x0a, 0xc5, 0x84,
+ 0x3b, 0x9e, 0x72, 0x02, 0xd7, 0xcc, 0x09, 0x56,
+ 0xbd, 0x54, 0xc1, 0xf0, 0xc3, 0xe3, 0xb3, 0xf8,
+ 0xd2, 0x0d, 0x61, 0xcb, 0xef, 0xce, 0x0d, 0x05,
+ 0xb0, 0x98, 0xd9, 0x8e, 0x4f, 0xf9, 0xbc, 0x93,
+ 0xa6, 0xea, 0xc8, 0xcf, 0x10, 0x53, 0x4b, 0xf1,
+ 0xec, 0xfc, 0x89, 0xf9, 0x64, 0xb0, 0x22, 0xbf,
+ 0x9e, 0x55, 0x46, 0x9f, 0x7c, 0x50, 0x8e, 0x84,
+ 0x54, 0x20, 0x98, 0xd7, 0x6c, 0x40, 0x1e, 0xdb,
+ 0x69, 0x34, 0x78, 0x61, 0x24, 0x21, 0x9c, 0x8a,
+ 0xb3, 0x62, 0x31, 0x8b, 0x6e, 0xf5, 0x2a, 0x35,
+ 0x86, 0x13, 0xb1, 0x6c, 0x64, 0x2e, 0x41, 0xa5,
+ 0x05, 0xf2, 0x42, 0xba, 0xd2, 0x3a, 0x0d, 0x8e,
+ 0x8a, 0x59, 0x94, 0x3c, 0xcf, 0x36, 0x27, 0x82,
+ 0xc2, 0x45, 0xee, 0x58, 0xcd, 0x88, 0xb4, 0xec,
+ 0xde, 0xb2, 0x96, 0x0a, 0xaf, 0x38, 0x6f, 0x88,
+ 0xd7, 0xd8, 0xe1, 0xdf, 0xb9, 0x96, 0xa9, 0x0a,
+ 0xb1, 0x95, 0x28, 0x86, 0x20, 0xe9, 0x17, 0x49,
+ 0xa2, 0x29, 0x38, 0xaa, 0xa5, 0xe9, 0x6e, 0xf1,
+ 0x19, 0x27, 0xc0, 0xd5, 0x2a, 0x22, 0xc3, 0x0b,
+ 0xdb, 0x7c, 0x73, 0x10, 0xb9, 0xba, 0x89, 0x76,
+ 0x54, 0xae, 0x7d, 0x71, 0xb3, 0x93, 0xf6, 0x32,
+ 0xe6, 0x47, 0x43, 0x55, 0xac, 0xa0, 0x0d, 0xc2,
+ 0x93, 0x27, 0x4a, 0x8e, 0x0e, 0x74, 0x15, 0xc7,
+ 0x0b, 0x85, 0xd9, 0x0c, 0xa9, 0x30, 0x7a, 0x3e,
+ 0xea, 0x8f, 0x85, 0x6d, 0x3a, 0x12, 0x4f, 0x72,
+ 0x69, 0x58, 0x7a, 0x80, 0xbb, 0xb5, 0x97, 0xf3,
+ 0xcf, 0x70, 0xd2, 0x5d, 0xdd, 0x4d, 0x21, 0x79,
+ 0x54, 0x4d, 0xe4, 0x05, 0xe8, 0xbd, 0xc2, 0x62,
+ 0xb1, 0x3b, 0x77, 0x1c, 0xd6, 0x5c, 0xf3, 0xa0,
+ 0x79, 0x00, 0xa8, 0x6c, 0x29, 0xd9, 0x18, 0x24,
+ 0x36, 0xa2, 0x46, 0xc0, 0x96, 0x65, 0x7f, 0xbd,
+ 0x2a, 0xed, 0x36, 0x16, 0x0c, 0xaa, 0x9f, 0xf4,
+ 0xc5, 0xb4, 0xe2, 0x12, 0xed, 0x69, 0xed, 0x4f,
+ 0x26, 0x2c, 0x39, 0x52, 0x89, 0x98, 0xe7, 0x2c,
+ 0x99, 0xa4, 0x9e, 0xa3, 0x9b, 0x99, 0x46, 0x7a,
+ 0x3a, 0xdc, 0xa8, 0x59, 0xa3, 0xdb, 0xc3, 0x3b,
+ 0x95, 0x0d, 0x3b, 0x09, 0x6e, 0xee, 0x83, 0x5d,
+ 0x32, 0x4d, 0xed, 0xab, 0xfa, 0x98, 0x14, 0x4e,
+ 0xc3, 0x15, 0x45, 0x53, 0x61, 0xc4, 0x93, 0xbd,
+ 0x90, 0xf4, 0x99, 0x95, 0x4c, 0xe6, 0x76, 0x92,
+ 0x29, 0x90, 0x46, 0x30, 0x92, 0x69, 0x7d, 0x13,
+ 0xf2, 0xa5, 0xcd, 0x69, 0x49, 0x44, 0xb2, 0x0f,
+ 0x63, 0x40, 0x36, 0x5f, 0x09, 0xe2, 0x78, 0xf8,
+ 0x91, 0xe3, 0xe2, 0xfa, 0x10, 0xf7, 0xc8, 0x24,
+ 0xa8, 0x89, 0x32, 0x5c, 0x37, 0x25, 0x1d, 0xb2,
+ 0xea, 0x17, 0x8a, 0x0a, 0xa9, 0x64, 0xc3, 0x7c,
+ 0x3c, 0x7c, 0xbd, 0xc6, 0x79, 0x34, 0xe7, 0xe2,
+ 0x85, 0x8e, 0xbf, 0xf8, 0xde, 0x92, 0xa0, 0xae,
+ 0x20, 0xc4, 0xf6, 0xbb, 0x1f, 0x38, 0x19, 0x0e,
+ 0xe8, 0x79, 0x9c, 0xa1, 0x23, 0xe9, 0x54, 0x7e,
+ 0x37, 0x2f, 0xe2, 0x94, 0x32, 0xaf, 0xa0, 0x23,
+ 0x49, 0xe4, 0xc0, 0xb3, 0xac, 0x00, 0x8f, 0x36,
+ 0x05, 0xc4, 0xa6, 0x96, 0xec, 0x05, 0x98, 0x4f,
+ 0x96, 0x67, 0x57, 0x1f, 0x20, 0x86, 0x1b, 0x2d,
+ 0x69, 0xe4, 0x29, 0x93, 0x66, 0x5f, 0xaf, 0x6b,
+ 0x88, 0x26, 0x2c, 0x67, 0x02, 0x4b, 0x52, 0xd0,
+ 0x83, 0x7a, 0x43, 0x1f, 0xc0, 0x71, 0x15, 0x25,
+ 0x77, 0x65, 0x08, 0x60, 0x11, 0x76, 0x4c, 0x8d,
+ 0xed, 0xa9, 0x27, 0xc6, 0xb1, 0x2a, 0x2c, 0x6a,
+ 0x4a, 0x97, 0xf5, 0xc6, 0xb7, 0x70, 0x42, 0xd3,
+ 0x03, 0xd1, 0x24, 0x95, 0xec, 0x6d, 0xab, 0x38,
+ 0x72, 0xce, 0xe2, 0x8b, 0x33, 0xd7, 0x51, 0x09,
+ 0xdc, 0x45, 0xe0, 0x09, 0x96, 0x32, 0xf3, 0xc4,
+ 0x84, 0xdc, 0x73, 0x73, 0x2d, 0x1b, 0x11, 0x98,
+ 0xc5, 0x0e, 0x69, 0x28, 0x94, 0xc7, 0xb5, 0x4d,
+ 0xc8, 0x8a, 0xd0, 0xaa, 0x13, 0x2e, 0x18, 0x74,
+ 0xdd, 0xd1, 0x1e, 0xf3, 0x90, 0xe8, 0xfc, 0x9a,
+ 0x72, 0x4a, 0x0e, 0xd1, 0xe4, 0xfb, 0x0d, 0x96,
+ 0xd1, 0x0c, 0x79, 0x85, 0x1b, 0x1c, 0xfe, 0xe1,
+ 0x62, 0x8f, 0x7a, 0x73, 0x32, 0xab, 0xc8, 0x18,
+ 0x69, 0xe3, 0x34, 0x30, 0xdf, 0x13, 0xa6, 0xe5,
+ 0xe8, 0x0e, 0x67, 0x7f, 0x81, 0x11, 0xb4, 0x60,
+ 0xc7, 0xbd, 0x79, 0x65, 0x50, 0xdc, 0xc4, 0x5b,
+ 0xde, 0x39, 0xa4, 0x01, 0x72, 0x63, 0xf3, 0xd1,
+ 0x64, 0x4e, 0xdf, 0xfc, 0x27, 0x92, 0x37, 0x0d,
+ 0x57, 0xcd, 0x11, 0x4f, 0x11, 0x04, 0x8e, 0x1d,
+ 0x16, 0xf7, 0xcd, 0x92, 0x9a, 0x99, 0x30, 0x14,
+ 0xf1, 0x7c, 0x67, 0x1b, 0x1f, 0x41, 0x0b, 0xe8,
+ 0x32, 0xe8, 0xb8, 0xc1, 0x4f, 0x54, 0x86, 0x4f,
+ 0xe5, 0x79, 0x81, 0x73, 0xcd, 0x43, 0x59, 0x68,
+ 0x73, 0x02, 0x3b, 0x78, 0x21, 0x72, 0x43, 0x00,
+ 0x49, 0x17, 0xf7, 0x00, 0xaf, 0x68, 0x24, 0x53,
+ 0x05, 0x0a, 0xc3, 0x33, 0xe0, 0x33, 0x3f, 0x69,
+ 0xd2, 0x84, 0x2f, 0x0b, 0xed, 0xde, 0x04, 0xf4,
+ 0x11, 0x94, 0x13, 0x69, 0x51, 0x09, 0x28, 0xde,
+ 0x57, 0x5c, 0xef, 0xdc, 0x9a, 0x49, 0x1c, 0x17,
+ 0x97, 0xf3, 0x96, 0xc1, 0x7f, 0x5d, 0x2e, 0x7d,
+ 0x55, 0xb8, 0xb3, 0x02, 0x09, 0xb3, 0x1f, 0xe7,
+ 0xc9, 0x8d, 0xa3, 0x36, 0x34, 0x8a, 0x77, 0x13,
+ 0x30, 0x63, 0x4c, 0xa5, 0xcd, 0xc3, 0xe0, 0x7e,
+ 0x05, 0xa1, 0x7b, 0x0c, 0xcb, 0x74, 0x47, 0x31,
+ 0x62, 0x03, 0x43, 0xf1, 0x87, 0xb4, 0xb0, 0x85,
+ 0x87, 0x8e, 0x4b, 0x25, 0xc7, 0xcf, 0xae, 0x4b,
+ 0x36, 0x46, 0x3e, 0x62, 0xbc, 0x6f, 0xeb, 0x5f,
+ 0x73, 0xac, 0xe6, 0x07, 0xee, 0xc1, 0xa1, 0xd6,
+ 0xc4, 0xab, 0xc9, 0xd6, 0x89, 0x45, 0xe1, 0xf1,
+ 0x04, 0x4e, 0x1a, 0x6f, 0xbb, 0x4f, 0x3a, 0xa3,
+ 0xa0, 0xcb, 0xa3, 0x0a, 0xd8, 0x71, 0x35, 0x55,
+ 0xe4, 0xbc, 0x2e, 0x04, 0x06, 0xe6, 0xff, 0x5b,
+ 0x1c, 0xc0, 0x11, 0x7c, 0xc5, 0x17, 0xf3, 0x38,
+ 0xcf, 0xe9, 0xba, 0x0f, 0x0e, 0xef, 0x02, 0xc2,
+ 0x8d, 0xc6, 0xbc, 0x4b, 0x67, 0x20, 0x95, 0xd7,
+ 0x2c, 0x45, 0x5b, 0x86, 0x44, 0x8c, 0x6f, 0x2e,
+ 0x7e, 0x9f, 0x1c, 0x77, 0xba, 0x6b, 0x0e, 0xa3,
+ 0x69, 0xdc, 0xab, 0x24, 0x57, 0x60, 0x47, 0xc1,
+ 0xd1, 0xa5, 0x9d, 0x23, 0xe6, 0xb1, 0x37, 0xfe,
+ 0x93, 0xd2, 0x4c, 0x46, 0xf9, 0x0c, 0xc6, 0xfb,
+ 0xd6, 0x9d, 0x99, 0x69, 0xab, 0x7a, 0x07, 0x0c,
+ 0x65, 0xe7, 0xc4, 0x08, 0x96, 0xe2, 0xa5, 0x01,
+ 0x3f, 0x46, 0x07, 0x05, 0x7e, 0xe8, 0x9a, 0x90,
+ 0x50, 0xdc, 0xe9, 0x7a, 0xea, 0xa1, 0x39, 0x6e,
+ 0x66, 0xe4, 0x6f, 0xa5, 0x5f, 0xb2, 0xd9, 0x5b,
+ 0xf5, 0xdb, 0x2a, 0x32, 0xf0, 0x11, 0x6f, 0x7c,
+ 0x26, 0x10, 0x8f, 0x3d, 0x80, 0xe9, 0x58, 0xf7,
+ 0xe0, 0xa8, 0x57, 0xf8, 0xdb, 0x0e, 0xce, 0x99,
+ 0x63, 0x19, 0x3d, 0xd5, 0xec, 0x1b, 0x77, 0x69,
+ 0x98, 0xf6, 0xe4, 0x5f, 0x67, 0x17, 0x4b, 0x09,
+ 0x85, 0x62, 0x82, 0x70, 0x18, 0xe2, 0x9a, 0x78,
+ 0xe2, 0x62, 0xbd, 0xb4, 0xf1, 0x42, 0xc6, 0xfb,
+ 0x08, 0xd0, 0xbd, 0xeb, 0x4e, 0x09, 0xf2, 0xc8,
+ 0x1e, 0xdc, 0x3d, 0x32, 0x21, 0x56, 0x9c, 0x4f,
+ 0x35, 0xf3, 0x61, 0x06, 0x72, 0x84, 0xc4, 0x32,
+ 0xf2, 0xf1, 0xfa, 0x0b, 0x2f, 0xc3, 0xdb, 0x02,
+ 0x04, 0xc2, 0xde, 0x57, 0x64, 0x60, 0x8d, 0xcf,
+ 0xcb, 0x86, 0x5d, 0x97, 0x3e, 0xb1, 0x9c, 0x01,
+ 0xd6, 0x28, 0x8f, 0x99, 0xbc, 0x46, 0xeb, 0x05,
+ 0xaf, 0x7e, 0xb8, 0x21, 0x2a, 0x56, 0x85, 0x1c,
+ 0xb3, 0x71, 0xa0, 0xde, 0xca, 0x96, 0xf1, 0x78,
+ 0x49, 0xa2, 0x99, 0x81, 0x80, 0x5c, 0x01, 0xf5,
+ 0xa0, 0xa2, 0x56, 0x63, 0xe2, 0x70, 0x07, 0xa5,
+ 0x95, 0xd6, 0x85, 0xeb, 0x36, 0x9e, 0xa9, 0x51,
+ 0x66, 0x56, 0x5f, 0x1d, 0x02, 0x19, 0xe2, 0xf6,
+ 0x4f, 0x73, 0x38, 0x09, 0x75, 0x64, 0x48, 0xe0,
+ 0xf1, 0x7e, 0x0e, 0xe8, 0x9d, 0xf9, 0xed, 0x94,
+ 0xfe, 0x16, 0x26, 0x62, 0x49, 0x74, 0xf4, 0xb0,
+ 0xd4, 0xa9, 0x6c, 0xb0, 0xfd, 0x53, 0xe9, 0x81,
+ 0xe0, 0x7a, 0xbf, 0xcf, 0xb5, 0xc4, 0x01, 0x81,
+ 0x79, 0x99, 0x77, 0x01, 0x3b, 0xe9, 0xa2, 0xb6,
+ 0xe6, 0x6a, 0x8a, 0x9e, 0x56, 0x1c, 0x8d, 0x1e,
+ 0x8f, 0x06, 0x55, 0x2c, 0x6c, 0xdc, 0x92, 0x87,
+ 0x64, 0x3b, 0x4b, 0x19, 0xa1, 0x13, 0x64, 0x1d,
+ 0x4a, 0xe9, 0xc0, 0x00, 0xb8, 0x95, 0xef, 0x6b,
+ 0x1a, 0x86, 0x6d, 0x37, 0x52, 0x02, 0xc2, 0xe0,
+ 0xc8, 0xbb, 0x42, 0x0c, 0x02, 0x21, 0x4a, 0xc9,
+ 0xef, 0xa0, 0x54, 0xe4, 0x5e, 0x16, 0x53, 0x81,
+ 0x70, 0x62, 0x10, 0xaf, 0xde, 0xb8, 0xb5, 0xd3,
+ 0xe8, 0x5e, 0x6c, 0xc3, 0x8a, 0x3e, 0x18, 0x07,
+ 0xf2, 0x2f, 0x7d, 0xa7, 0xe1, 0x3d, 0x4e, 0xb4,
+ 0x26, 0xa7, 0xa3, 0x93, 0x86, 0xb2, 0x04, 0x1e,
+ 0x53, 0x5d, 0x86, 0xd6, 0xde, 0x65, 0xca, 0xe3,
+ 0x4e, 0xc1, 0xcf, 0xef, 0xc8, 0x70, 0x1b, 0x83,
+ 0x13, 0xdd, 0x18, 0x8b, 0x0d, 0x76, 0xd2, 0xf6,
+ 0x37, 0x7a, 0x93, 0x7a, 0x50, 0x11, 0x9f, 0x96,
+ 0x86, 0x25, 0xfd, 0xac, 0xdc, 0xbe, 0x18, 0x93,
+ 0x19, 0x6b, 0xec, 0x58, 0x4f, 0xb9, 0x75, 0xa7,
+ 0xdd, 0x3f, 0x2f, 0xec, 0xc8, 0x5a, 0x84, 0xab,
+ 0xd5, 0xe4, 0x8a, 0x07, 0xf6, 0x4d, 0x23, 0xd6,
+ 0x03, 0xfb, 0x03, 0x6a, 0xea, 0x66, 0xbf, 0xd4,
+ 0xb1, 0x34, 0xfb, 0x78, 0xe9, 0x55, 0xdc, 0x7c,
+ 0x3d, 0x9c, 0xe5, 0x9a, 0xac, 0xc3, 0x7a, 0x80,
+ 0x24, 0x6d, 0xa0, 0xef, 0x25, 0x7c, 0xb7, 0xea,
+ 0xce, 0x4d, 0x5f, 0x18, 0x60, 0xce, 0x87, 0x22,
+ 0x66, 0x2f, 0xd5, 0xdd, 0xdd, 0x02, 0x21, 0x75,
+ 0x82, 0xa0, 0x1f, 0x58, 0xc6, 0xd3, 0x62, 0xf7,
+ 0x32, 0xd8, 0xaf, 0x1e, 0x07, 0x77, 0x51, 0x96,
+ 0xd5, 0x6b, 0x1e, 0x7e, 0x80, 0x02, 0xe8, 0x67,
+ 0xea, 0x17, 0x0b, 0x10, 0xd2, 0x3f, 0x28, 0x25,
+ 0x4f, 0x05, 0x77, 0x02, 0x14, 0x69, 0xf0, 0x2c,
+ 0xbe, 0x0c, 0xf1, 0x74, 0x30, 0xd1, 0xb9, 0x9b,
+ 0xfc, 0x8c, 0xbb, 0x04, 0x16, 0xd9, 0xba, 0xc3,
+ 0xbc, 0x91, 0x8a, 0xc4, 0x30, 0xa4, 0xb0, 0x12,
+ 0x4c, 0x21, 0x87, 0xcb, 0xc9, 0x1d, 0x16, 0x96,
+ 0x07, 0x6f, 0x23, 0x54, 0xb9, 0x6f, 0x79, 0xe5,
+ 0x64, 0xc0, 0x64, 0xda, 0xb1, 0xae, 0xdd, 0x60,
+ 0x6c, 0x1a, 0x9d, 0xd3, 0x04, 0x8e, 0x45, 0xb0,
+ 0x92, 0x61, 0xd0, 0x48, 0x81, 0xed, 0x5e, 0x1d,
+ 0xa0, 0xc9, 0xa4, 0x33, 0xc7, 0x13, 0x51, 0x5d,
+ 0x7f, 0x83, 0x73, 0xb6, 0x70, 0x18, 0x65, 0x3e,
+ 0x2f, 0x0e, 0x7a, 0x12, 0x39, 0x98, 0xab, 0xd8,
+ 0x7e, 0x6f, 0xa3, 0xd1, 0xba, 0x56, 0xad, 0xbd,
+ 0xf0, 0x03, 0x01, 0x1c, 0x85, 0x35, 0x9f, 0xeb,
+ 0x19, 0x63, 0xa1, 0xaf, 0xfe, 0x2d, 0x35, 0x50,
+ 0x39, 0xa0, 0x65, 0x7c, 0x95, 0x7e, 0x6b, 0xfe,
+ 0xc1, 0xac, 0x07, 0x7c, 0x98, 0x4f, 0xbe, 0x57,
+ 0xa7, 0x22, 0xec, 0xe2, 0x7e, 0x29, 0x09, 0x53,
+ 0xe8, 0xbf, 0xb4, 0x7e, 0x3f, 0x8f, 0xfc, 0x14,
+ 0xce, 0x54, 0xf9, 0x18, 0x58, 0xb5, 0xff, 0x44,
+ 0x05, 0x9d, 0xce, 0x1b, 0xb6, 0x82, 0x23, 0xc8,
+ 0x2e, 0xbc, 0x69, 0xbb, 0x4a, 0x29, 0x0f, 0x65,
+ 0x94, 0xf0, 0x63, 0x06, 0x0e, 0xef, 0x8c, 0xbd,
+ 0xff, 0xfd, 0xb0, 0x21, 0x6e, 0x57, 0x05, 0x75,
+ 0xda, 0xd5, 0xc4, 0xeb, 0x8d, 0x32, 0xf7, 0x50,
+ 0xd3, 0x6f, 0x22, 0xed, 0x5f, 0x8e, 0xa2, 0x5b,
+ 0x80, 0x8c, 0xc8, 0x78, 0x40, 0x24, 0x4b, 0x89,
+ 0x30, 0xce, 0x7a, 0x97, 0x0e, 0xc4, 0xaf, 0xef,
+ 0x9b, 0xb4, 0xcd, 0x66, 0x74, 0x14, 0x04, 0x2b,
+ 0xf7, 0xce, 0x0b, 0x1c, 0x6e, 0xc2, 0x78, 0x8c,
+ 0xca, 0xc5, 0xd0, 0x1c, 0x95, 0x4a, 0x91, 0x2d,
+ 0xa7, 0x20, 0xeb, 0x86, 0x52, 0xb7, 0x67, 0xd8,
+ 0x0c, 0xd6, 0x04, 0x14, 0xde, 0x51, 0x74, 0x75,
+ 0xe7, 0x11, 0xb4, 0x87, 0xa3, 0x3d, 0x2d, 0xad,
+ 0x4f, 0xef, 0xa0, 0x0f, 0x70, 0x00, 0x6d, 0x13,
+ 0x19, 0x1d, 0x41, 0x50, 0xe9, 0xd8, 0xf0, 0x32,
+ 0x71, 0xbc, 0xd3, 0x11, 0xf2, 0xac, 0xbe, 0xaf,
+ 0x75, 0x46, 0x65, 0x4e, 0x07, 0x34, 0x37, 0xa3,
+ 0x89, 0xfe, 0x75, 0xd4, 0x70, 0x4c, 0xc6, 0x3f,
+ 0x69, 0x24, 0x0e, 0x38, 0x67, 0x43, 0x8c, 0xde,
+ 0x06, 0xb5, 0xb8, 0xe7, 0xc4, 0xf0, 0x41, 0x8f,
+ 0xf0, 0xbd, 0x2f, 0x0b, 0xb9, 0x18, 0xf8, 0xde,
+ 0x64, 0xb1, 0xdb, 0xee, 0x00, 0x50, 0x77, 0xe1,
+ 0xc7, 0xff, 0xa6, 0xfa, 0xdd, 0x70, 0xf4, 0xe3,
+ 0x93, 0xe9, 0x77, 0x35, 0x3d, 0x4b, 0x2f, 0x2b,
+ 0x6d, 0x55, 0xf0, 0xfc, 0x88, 0x54, 0x4e, 0x89,
+ 0xc1, 0x8a, 0x23, 0x31, 0x2d, 0x14, 0x2a, 0xb8,
+ 0x1b, 0x15, 0xdd, 0x9e, 0x6e, 0x7b, 0xda, 0x05,
+ 0x91, 0x7d, 0x62, 0x64, 0x96, 0x72, 0xde, 0xfc,
+ 0xc1, 0xec, 0xf0, 0x23, 0x51, 0x6f, 0xdb, 0x5b,
+ 0x1d, 0x08, 0x57, 0xce, 0x09, 0xb8, 0xf6, 0xcd,
+ 0x8d, 0x95, 0xf2, 0x20, 0xbf, 0x0f, 0x20, 0x57,
+ 0x98, 0x81, 0x84, 0x4f, 0x15, 0x5c, 0x76, 0xe7,
+ 0x3e, 0x0a, 0x3a, 0x6c, 0xc4, 0x8a, 0xbe, 0x78,
+ 0x74, 0x77, 0xc3, 0x09, 0x4b, 0x5d, 0x48, 0xe4,
+ 0xc8, 0xcb, 0x0b, 0xea, 0x17, 0x28, 0xcf, 0xcf,
+ 0x31, 0x32, 0x44, 0xa4, 0xe5, 0x0e, 0x1a, 0x98,
+ 0x94, 0xc4, 0xf0, 0xff, 0xae, 0x3e, 0x44, 0xe8,
+ 0xa5, 0xb3, 0xb5, 0x37, 0x2f, 0xe8, 0xaf, 0x6f,
+ 0x28, 0xc1, 0x37, 0x5f, 0x31, 0xd2, 0xb9, 0x33,
+ 0xb1, 0xb2, 0x52, 0x94, 0x75, 0x2c, 0x29, 0x59,
+ 0x06, 0xc2, 0x25, 0xe8, 0x71, 0x65, 0x4e, 0xed,
+ 0xc0, 0x9c, 0xb1, 0xbb, 0x25, 0xdc, 0x6c, 0xe7,
+ 0x4b, 0xa5, 0x7a, 0x54, 0x7a, 0x60, 0xff, 0x7a,
+ 0xe0, 0x50, 0x40, 0x96, 0x35, 0x63, 0xe4, 0x0b,
+ 0x76, 0xbd, 0xa4, 0x65, 0x00, 0x1b, 0x57, 0x88,
+ 0xae, 0xed, 0x39, 0x88, 0x42, 0x11, 0x3c, 0xed,
+ 0x85, 0x67, 0x7d, 0xb9, 0x68, 0x82, 0xe9, 0x43,
+ 0x3c, 0x47, 0x53, 0xfa, 0xe8, 0xf8, 0x9f, 0x1f,
+ 0x9f, 0xef, 0x0f, 0xf7, 0x30, 0xd9, 0x30, 0x0e,
+ 0xb9, 0x9f, 0x69, 0x18, 0x2f, 0x7e, 0xf8, 0xf8,
+ 0xf8, 0x8c, 0x0f, 0xd4, 0x02, 0x4d, 0xea, 0xcd,
+ 0x0a, 0x9c, 0x6f, 0x71, 0x6d, 0x5a, 0x4c, 0x60,
+ 0xce, 0x20, 0x56, 0x32, 0xc6, 0xc5, 0x99, 0x1f,
+ 0x09, 0xe6, 0x4e, 0x18, 0x1a, 0x15, 0x13, 0xa8,
+ 0x7d, 0xb1, 0x6b, 0xc0, 0xb2, 0x6d, 0xf8, 0x26,
+ 0x66, 0xf8, 0x3d, 0x18, 0x74, 0x70, 0x66, 0x7a,
+ 0x34, 0x17, 0xde, 0xba, 0x47, 0xf1, 0x06, 0x18,
+ 0xcb, 0xaf, 0xeb, 0x4a, 0x1e, 0x8f, 0xa7, 0x77,
+ 0xe0, 0x3b, 0x78, 0x62, 0x66, 0xc9, 0x10, 0xea,
+ 0x1f, 0xb7, 0x29, 0x0a, 0x45, 0xa1, 0x1d, 0x1e,
+ 0x1d, 0xe2, 0x65, 0x61, 0x50, 0x9c, 0xd7, 0x05,
+ 0xf2, 0x0b, 0x5b, 0x12, 0x61, 0x02, 0xc8, 0xe5,
+ 0x63, 0x4f, 0x20, 0x0c, 0x07, 0x17, 0x33, 0x5e,
+ 0x03, 0x9a, 0x53, 0x0f, 0x2e, 0x55, 0xfe, 0x50,
+ 0x43, 0x7d, 0xd0, 0xb6, 0x7e, 0x5a, 0xda, 0xae,
+ 0x58, 0xef, 0x15, 0xa9, 0x83, 0xd9, 0x46, 0xb1,
+ 0x42, 0xaa, 0xf5, 0x02, 0x6c, 0xce, 0x92, 0x06,
+ 0x1b, 0xdb, 0x66, 0x45, 0x91, 0x79, 0xc2, 0x2d,
+ 0xe6, 0x53, 0xd3, 0x14, 0xfd, 0xbb, 0x44, 0x63,
+ 0xc6, 0xd7, 0x3d, 0x7a, 0x0c, 0x75, 0x78, 0x9d,
+ 0x5c, 0xa6, 0x39, 0xb3, 0xe5, 0x63, 0xca, 0x8b,
+ 0xfe, 0xd3, 0xef, 0x60, 0x83, 0xf6, 0x8e, 0x70,
+ 0xb6, 0x67, 0xc7, 0x77, 0xed, 0x23, 0xef, 0x4c,
+ 0xf0, 0xed, 0x2d, 0x07, 0x59, 0x6f, 0xc1, 0x01,
+ 0x34, 0x37, 0x08, 0xab, 0xd9, 0x1f, 0x09, 0xb1,
+ 0xce, 0x5b, 0x17, 0xff, 0x74, 0xf8, 0x9c, 0xd5,
+ 0x2c, 0x56, 0x39, 0x79, 0x0f, 0x69, 0x44, 0x75,
+ 0x58, 0x27, 0x01, 0xc4, 0xbf, 0xa7, 0xa1, 0x1d,
+ 0x90, 0x17, 0x77, 0x86, 0x5a, 0x3f, 0xd9, 0xd1,
+ 0x0e, 0xa0, 0x10, 0xf8, 0xec, 0x1e, 0xa5, 0x7f,
+ 0x5e, 0x36, 0xd1, 0xe3, 0x04, 0x2c, 0x70, 0xf7,
+ 0x8e, 0xc0, 0x98, 0x2f, 0x6c, 0x94, 0x2b, 0x41,
+ 0xb7, 0x60, 0x00, 0xb7, 0x2e, 0xb8, 0x02, 0x8d,
+ 0xb8, 0xb0, 0xd3, 0x86, 0xba, 0x1d, 0xd7, 0x90,
+ 0xd6, 0xb6, 0xe1, 0xfc, 0xd7, 0xd8, 0x28, 0x06,
+ 0x63, 0x9b, 0xce, 0x61, 0x24, 0x79, 0xc0, 0x70,
+ 0x52, 0xd0, 0xb6, 0xd4, 0x28, 0x95, 0x24, 0x87,
+ 0x03, 0x1f, 0xb7, 0x9a, 0xda, 0xa3, 0xfb, 0x52,
+ 0x5b, 0x68, 0xe7, 0x4c, 0x8c, 0x24, 0xe1, 0x42,
+ 0xf7, 0xd5, 0xfd, 0xad, 0x06, 0x32, 0x9f, 0xba,
+ 0xc1, 0xfc, 0xdd, 0xc6, 0xfc, 0xfc, 0xb3, 0x38,
+ 0x74, 0x56, 0x58, 0x40, 0x02, 0x37, 0x52, 0x2c,
+ 0x55, 0xcc, 0xb3, 0x9e, 0x7a, 0xe9, 0xd4, 0x38,
+ 0x41, 0x5e, 0x0c, 0x35, 0xe2, 0x11, 0xd1, 0x13,
+ 0xf8, 0xb7, 0x8d, 0x72, 0x6b, 0x22, 0x2a, 0xb0,
+ 0xdb, 0x08, 0xba, 0x35, 0xb9, 0x3f, 0xc8, 0xd3,
+ 0x24, 0x90, 0xec, 0x58, 0xd2, 0x09, 0xc7, 0x2d,
+ 0xed, 0x38, 0x80, 0x36, 0x72, 0x43, 0x27, 0x49,
+ 0x4a, 0x80, 0x8a, 0xa2, 0xe8, 0xd3, 0xda, 0x30,
+ 0x7d, 0xb6, 0x82, 0x37, 0x86, 0x92, 0x86, 0x3e,
+ 0x08, 0xb2, 0x28, 0x5a, 0x55, 0x44, 0x24, 0x7d,
+ 0x40, 0x48, 0x8a, 0xb6, 0x89, 0x58, 0x08, 0xa0,
+ 0xd6, 0x6d, 0x3a, 0x17, 0xbf, 0xf6, 0x54, 0xa2,
+ 0xf5, 0xd3, 0x8c, 0x0f, 0x78, 0x12, 0x57, 0x8b,
+ 0xd5, 0xc2, 0xfd, 0x58, 0x5b, 0x7f, 0x38, 0xe3,
+ 0xcc, 0xb7, 0x7c, 0x48, 0xb3, 0x20, 0xe8, 0x81,
+ 0x14, 0x32, 0x45, 0x05, 0xe0, 0xdb, 0x9f, 0x75,
+ 0x85, 0xb4, 0x6a, 0xfc, 0x95, 0xe3, 0x54, 0x22,
+ 0x12, 0xee, 0x30, 0xfe, 0xd8, 0x30, 0xef, 0x34,
+ 0x50, 0xab, 0x46, 0x30, 0x98, 0x2f, 0xb7, 0xc0,
+ 0x15, 0xa2, 0x83, 0xb6, 0xf2, 0x06, 0x21, 0xa2,
+ 0xc3, 0x26, 0x37, 0x14, 0xd1, 0x4d, 0xb5, 0x10,
+ 0x52, 0x76, 0x4d, 0x6a, 0xee, 0xb5, 0x2b, 0x15,
+ 0xb7, 0xf9, 0x51, 0xe8, 0x2a, 0xaf, 0xc7, 0xfa,
+ 0x77, 0xaf, 0xb0, 0x05, 0x4d, 0xd1, 0x68, 0x8e,
+ 0x74, 0x05, 0x9f, 0x9d, 0x93, 0xa5, 0x3e, 0x7f,
+ 0x4e, 0x5f, 0x9d, 0xcb, 0x09, 0xc7, 0x83, 0xe3,
+ 0x02, 0x9d, 0x27, 0x1f, 0xef, 0x85, 0x05, 0x8d,
+ 0xec, 0x55, 0x88, 0x0f, 0x0d, 0x7c, 0x4c, 0xe8,
+ 0xa1, 0x75, 0xa0, 0xd8, 0x06, 0x47, 0x14, 0xef,
+ 0xaa, 0x61, 0xcf, 0x26, 0x15, 0xad, 0xd8, 0xa3,
+ 0xaa, 0x75, 0xf2, 0x78, 0x4a, 0x5a, 0x61, 0xdf,
+ 0x8b, 0xc7, 0x04, 0xbc, 0xb2, 0x32, 0xd2, 0x7e,
+ 0x42, 0xee, 0xb4, 0x2f, 0x51, 0xff, 0x7b, 0x2e,
+ 0xd3, 0x02, 0xe8, 0xdc, 0x5d, 0x0d, 0x50, 0xdc,
+ 0xae, 0xb7, 0x46, 0xf9, 0xa8, 0xe6, 0xd0, 0x16,
+ 0xcc, 0xe6, 0x2c, 0x81, 0xc7, 0xad, 0xe9, 0xf0,
+ 0x05, 0x72, 0x6d, 0x3d, 0x0a, 0x7a, 0xa9, 0x02,
+ 0xac, 0x82, 0x93, 0x6e, 0xb6, 0x1c, 0x28, 0xfc,
+ 0x44, 0x12, 0xfb, 0x73, 0x77, 0xd4, 0x13, 0x39,
+ 0x29, 0x88, 0x8a, 0xf3, 0x5c, 0xa6, 0x36, 0xa0,
+ 0x2a, 0xed, 0x7e, 0xb1, 0x1d, 0xd6, 0x4c, 0x6b,
+ 0x41, 0x01, 0x18, 0x5d, 0x5d, 0x07, 0x97, 0xa6,
+ 0x4b, 0xef, 0x31, 0x18, 0xea, 0xac, 0xb1, 0x84,
+ 0x21, 0xed, 0xda, 0x86,
+ },
+ .rlen = 4100,
+ },
+};
+
+static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+ { /* From RFC 3686 */
+ .key = { 0xae, 0x68, 0x52, 0xf8, 0x12, 0x10, 0x67, 0xcc,
+ 0x4b, 0xf7, 0xa5, 0x76, 0x55, 0x77, 0xf3, 0x9e,
+ 0x00, 0x00, 0x00, 0x30 },
+ .klen = 20,
+ .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .input = { 0xe4, 0x09, 0x5d, 0x4f, 0xb7, 0xa7, 0xb3, 0x79,
+ 0x2d, 0x61, 0x75, 0xa3, 0x26, 0x13, 0x11, 0xb8 },
+ .ilen = 16,
+ .result = { "Single block msg" },
+ .rlen = 16,
+ }, {
+ .key = { 0x7e, 0x24, 0x06, 0x78, 0x17, 0xfa, 0xe0, 0xd7,
+ 0x43, 0xd6, 0xce, 0x1f, 0x32, 0x53, 0x91, 0x63,
+ 0x00, 0x6c, 0xb6, 0xdb },
+ .klen = 20,
+ .iv = { 0xc0, 0x54, 0x3b, 0x59, 0xda, 0x48, 0xd9, 0x0b },
+ .input = { 0x51, 0x04, 0xa1, 0x06, 0x16, 0x8a, 0x72, 0xd9,
+ 0x79, 0x0d, 0x41, 0xee, 0x8e, 0xda, 0xd3, 0x88,
+ 0xeb, 0x2e, 0x1e, 0xfc, 0x46, 0xda, 0x57, 0xc8,
+ 0xfc, 0xe6, 0x30, 0xdf, 0x91, 0x41, 0xbe, 0x28 },
+ .ilen = 32,
+ .result = { 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 },
+ .rlen = 32,
+ }, {
+ .key = { 0x16, 0xaf, 0x5b, 0x14, 0x5f, 0xc9, 0xf5, 0x79,
+ 0xc1, 0x75, 0xf9, 0x3e, 0x3b, 0xfb, 0x0e, 0xed,
+ 0x86, 0x3d, 0x06, 0xcc, 0xfd, 0xb7, 0x85, 0x15,
+ 0x00, 0x00, 0x00, 0x48 },
+ .klen = 28,
+ .iv = { 0x36, 0x73, 0x3c, 0x14, 0x7d, 0x6d, 0x93, 0xcb },
+ .input = { 0x4b, 0x55, 0x38, 0x4f, 0xe2, 0x59, 0xc9, 0xc8,
+ 0x4e, 0x79, 0x35, 0xa0, 0x03, 0xcb, 0xe9, 0x28 },
+ .ilen = 16,
+ .result = { "Single block msg" },
+ .rlen = 16,
+ }, {
+ .key = { 0x7c, 0x5c, 0xb2, 0x40, 0x1b, 0x3d, 0xc3, 0x3c,
+ 0x19, 0xe7, 0x34, 0x08, 0x19, 0xe0, 0xf6, 0x9c,
+ 0x67, 0x8c, 0x3d, 0xb8, 0xe6, 0xf6, 0xa9, 0x1a,
+ 0x00, 0x96, 0xb0, 0x3b },
+ .klen = 28,
+ .iv = { 0x02, 0x0c, 0x6e, 0xad, 0xc2, 0xcb, 0x50, 0x0d },
+ .input = { 0x45, 0x32, 0x43, 0xfc, 0x60, 0x9b, 0x23, 0x32,
+ 0x7e, 0xdf, 0xaa, 0xfa, 0x71, 0x31, 0xcd, 0x9f,
+ 0x84, 0x90, 0x70, 0x1c, 0x5a, 0xd4, 0xa7, 0x9c,
+ 0xfc, 0x1f, 0xe0, 0xff, 0x42, 0xf4, 0xfb, 0x00 },
+ .ilen = 32,
+ .result = { 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 },
+ .rlen = 32,
+ }, {
+ .key = { 0x77, 0x6b, 0xef, 0xf2, 0x85, 0x1d, 0xb0, 0x6f,
+ 0x4c, 0x8a, 0x05, 0x42, 0xc8, 0x69, 0x6f, 0x6c,
+ 0x6a, 0x81, 0xaf, 0x1e, 0xec, 0x96, 0xb4, 0xd3,
+ 0x7f, 0xc1, 0xd6, 0x89, 0xe6, 0xc1, 0xc1, 0x04,
+ 0x00, 0x00, 0x00, 0x60 },
+ .klen = 36,
+ .iv = { 0xdb, 0x56, 0x72, 0xc9, 0x7a, 0xa8, 0xf0, 0xb2 },
+ .input = { 0x14, 0x5a, 0xd0, 0x1d, 0xbf, 0x82, 0x4e, 0xc7,
+ 0x56, 0x08, 0x63, 0xdc, 0x71, 0xe3, 0xe0, 0xc0 },
+ .ilen = 16,
+ .result = { "Single block msg" },
+ .rlen = 16,
+ }, {
+ .key = { 0xf6, 0xd6, 0x6d, 0x6b, 0xd5, 0x2d, 0x59, 0xbb,
+ 0x07, 0x96, 0x36, 0x58, 0x79, 0xef, 0xf8, 0x86,
+ 0xc6, 0x6d, 0xd5, 0x1a, 0x5b, 0x6a, 0x99, 0x74,
+ 0x4b, 0x50, 0x59, 0x0c, 0x87, 0xa2, 0x38, 0x84,
+ 0x00, 0xfa, 0xac, 0x24 },
+ .klen = 36,
+ .iv = { 0xc1, 0x58, 0x5e, 0xf1, 0x5a, 0x43, 0xd8, 0x75 },
+ .input = { 0xf0, 0x5e, 0x23, 0x1b, 0x38, 0x94, 0x61, 0x2c,
+ 0x49, 0xee, 0x00, 0x0b, 0x80, 0x4e, 0xb2, 0xa9,
+ 0xb8, 0x30, 0x6b, 0x50, 0x8f, 0x83, 0x9d, 0x6a,
+ 0x55, 0x30, 0x83, 0x1d, 0x93, 0x44, 0xaf, 0x1c },
+ .ilen = 32,
+ .result = { 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 },
+ .rlen = 32,
+ },
+};
+
+static struct aead_testvec aes_gcm_enc_tv_template[] = {
+ { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+ .klen = 16,
+ .result = { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+ 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
+ .rlen = 16,
+ }, {
+ .klen = 16,
+ .ilen = 16,
+ .result = { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+ 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78,
+ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+ 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
+ .rlen = 32,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 16,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .ilen = 64,
+ .result = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85,
+ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
+ .rlen = 80,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 16,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .ilen = 60,
+ .assoc = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+ .alen = 20,
+ .result = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91,
+ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
+ .rlen = 76,
+ }, {
+ .klen = 24,
+ .result = { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+ 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
+ .rlen = 16,
+ }, {
+ .klen = 24,
+ .ilen = 16,
+ .result = { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+ 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00,
+ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+ 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
+ .rlen = 32,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c },
+ .klen = 24,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .ilen = 64,
+ .result = { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56,
+ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+ 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
+ .rlen = 80,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c },
+ .klen = 24,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .ilen = 60,
+ .assoc = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+ .alen = 20,
+ .result = { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10,
+ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+ 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
+ .rlen = 76,
+ .np = 2,
+ .tap = { 32, 28 },
+ .anp = 2,
+ .atap = { 8, 12 }
+ }, {
+ .klen = 32,
+ .result = { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+ 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
+ .rlen = 16,
+ }
+};
+
+static struct aead_testvec aes_gcm_dec_tv_template[] = {
+ { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+ .klen = 32,
+ .input = { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+ 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18,
+ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+ 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
+ .ilen = 32,
+ .rlen = 16,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 32,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad,
+ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+ 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
+ .ilen = 80,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .rlen = 64,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 32,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62,
+ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+ 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
+ .ilen = 76,
+ .assoc = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+ .alen = 20,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .rlen = 60,
+ .np = 2,
+ .tap = { 48, 28 },
+ .anp = 3,
+ .atap = { 8, 8, 4 }
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 16,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85,
+ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
+ .ilen = 80,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .rlen = 64,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+ .klen = 16,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91,
+ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
+ .ilen = 76,
+ .assoc = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+ .alen = 20,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .rlen = 60,
+ }, {
+ .klen = 24,
+ .input = { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+ 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00,
+ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+ 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
+ .ilen = 32,
+ .rlen = 16,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c },
+ .klen = 24,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56,
+ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+ 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
+ .ilen = 80,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+ .rlen = 64,
+ }, {
+ .key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c },
+ .klen = 24,
+ .iv = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ .input = { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10,
+ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+ 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
+ .ilen = 76,
+ .assoc = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+ .alen = 20,
+ .result = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39 },
+ .rlen = 60,
+ }
+};
+
+static struct aead_testvec aes_ccm_enc_tv_template[] = {
+ { /* From RFC 3610 */
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+ .alen = 8,
+ .input = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e },
+ .ilen = 23,
+ .result = { 0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
+ 0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
+ 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84, 0x17,
+ 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
+ .rlen = 31,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x07, 0x06, 0x05, 0x04,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b },
+ .alen = 12,
+ .input = { 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f },
+ .ilen = 20,
+ .result = { 0xdc, 0xf1, 0xfb, 0x7b, 0x5d, 0x9e, 0x23, 0xfb,
+ 0x9d, 0x4e, 0x13, 0x12, 0x53, 0x65, 0x8a, 0xd8,
+ 0x6e, 0xbd, 0xca, 0x3e, 0x51, 0xe8, 0x3f, 0x07,
+ 0x7d, 0x9c, 0x2d, 0x93 },
+ .rlen = 28,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x09, 0x08,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+ .alen = 8,
+ .input = { 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 },
+ .ilen = 25,
+ .result = { 0x82, 0x53, 0x1a, 0x60, 0xcc, 0x24, 0x94, 0x5a,
+ 0x4b, 0x82, 0x79, 0x18, 0x1a, 0xb5, 0xc8, 0x4d,
+ 0xf2, 0x1c, 0xe7, 0xf9, 0xb7, 0x3f, 0x42, 0xe1,
+ 0x97, 0xea, 0x9c, 0x07, 0xe5, 0x6b, 0x5e, 0xb1,
+ 0x7e, 0x5f, 0x4e },
+ .rlen = 35,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x0a, 0x09,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b },
+ .alen = 12,
+ .input = { 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e },
+ .ilen = 19,
+ .result = { 0x07, 0x34, 0x25, 0x94, 0x15, 0x77, 0x85, 0x15,
+ 0x2b, 0x07, 0x40, 0x98, 0x33, 0x0a, 0xbb, 0x14,
+ 0x1b, 0x94, 0x7b, 0x56, 0x6a, 0xa9, 0x40, 0x6b,
+ 0x4d, 0x99, 0x99, 0x88, 0xdd },
+ .rlen = 29,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x33, 0x56, 0x8e, 0xf7, 0xb2, 0x63,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0x63, 0x01, 0x8f, 0x76, 0xdc, 0x8a, 0x1b, 0xcb },
+ .alen = 8,
+ .input = { 0x90, 0x20, 0xea, 0x6f, 0x91, 0xbd, 0xd8, 0x5a,
+ 0xfa, 0x00, 0x39, 0xba, 0x4b, 0xaf, 0xf9, 0xbf,
+ 0xb7, 0x9c, 0x70, 0x28, 0x94, 0x9c, 0xd0, 0xec },
+ .ilen = 24,
+ .result = { 0x4c, 0xcb, 0x1e, 0x7c, 0xa9, 0x81, 0xbe, 0xfa,
+ 0xa0, 0x72, 0x6c, 0x55, 0xd3, 0x78, 0x06, 0x12,
+ 0x98, 0xc8, 0x5c, 0x92, 0x81, 0x4a, 0xbc, 0x33,
+ 0xc5, 0x2e, 0xe8, 0x1d, 0x7d, 0x77, 0xc0, 0x8a },
+ .rlen = 32,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0xd5, 0x60, 0x91, 0x2d, 0x3f, 0x70,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0xcd, 0x90, 0x44, 0xd2, 0xb7, 0x1f, 0xdb, 0x81,
+ 0x20, 0xea, 0x60, 0xc0 },
+ .alen = 12,
+ .input = { 0x64, 0x35, 0xac, 0xba, 0xfb, 0x11, 0xa8, 0x2e,
+ 0x2f, 0x07, 0x1d, 0x7c, 0xa4, 0xa5, 0xeb, 0xd9,
+ 0x3a, 0x80, 0x3b, 0xa8, 0x7f },
+ .ilen = 21,
+ .result = { 0x00, 0x97, 0x69, 0xec, 0xab, 0xdf, 0x48, 0x62,
+ 0x55, 0x94, 0xc5, 0x92, 0x51, 0xe6, 0x03, 0x57,
+ 0x22, 0x67, 0x5e, 0x04, 0xc8, 0x47, 0x09, 0x9e,
+ 0x5a, 0xe0, 0x70, 0x45, 0x51 },
+ .rlen = 29,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x42, 0xff, 0xf8, 0xf1, 0x95, 0x1c,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0xd8, 0x5b, 0xc7, 0xe6, 0x9f, 0x94, 0x4f, 0xb8 },
+ .alen = 8,
+ .input = { 0x8a, 0x19, 0xb9, 0x50, 0xbc, 0xf7, 0x1a, 0x01,
+ 0x8e, 0x5e, 0x67, 0x01, 0xc9, 0x17, 0x87, 0x65,
+ 0x98, 0x09, 0xd6, 0x7d, 0xbe, 0xdd, 0x18 },
+ .ilen = 23,
+ .result = { 0xbc, 0x21, 0x8d, 0xaa, 0x94, 0x74, 0x27, 0xb6,
+ 0xdb, 0x38, 0x6a, 0x99, 0xac, 0x1a, 0xef, 0x23,
+ 0xad, 0xe0, 0xb5, 0x29, 0x39, 0xcb, 0x6a, 0x63,
+ 0x7c, 0xf9, 0xbe, 0xc2, 0x40, 0x88, 0x97, 0xc6,
+ 0xba },
+ .rlen = 33,
+ },
+};
+
+static struct aead_testvec aes_ccm_dec_tv_template[] = {
+ { /* From RFC 3610 */
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+ .alen = 8,
+ .input = { 0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
+ 0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
+ 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84, 0x17,
+ 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
+ .ilen = 31,
+ .result = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e },
+ .rlen = 23,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x07, 0x06, 0x05, 0x04,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b },
+ .alen = 12,
+ .input = { 0xdc, 0xf1, 0xfb, 0x7b, 0x5d, 0x9e, 0x23, 0xfb,
+ 0x9d, 0x4e, 0x13, 0x12, 0x53, 0x65, 0x8a, 0xd8,
+ 0x6e, 0xbd, 0xca, 0x3e, 0x51, 0xe8, 0x3f, 0x07,
+ 0x7d, 0x9c, 0x2d, 0x93 },
+ .ilen = 28,
+ .result = { 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f },
+ .rlen = 20,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x09, 0x08,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+ .alen = 8,
+ .input = { 0x82, 0x53, 0x1a, 0x60, 0xcc, 0x24, 0x94, 0x5a,
+ 0x4b, 0x82, 0x79, 0x18, 0x1a, 0xb5, 0xc8, 0x4d,
+ 0xf2, 0x1c, 0xe7, 0xf9, 0xb7, 0x3f, 0x42, 0xe1,
+ 0x97, 0xea, 0x9c, 0x07, 0xe5, 0x6b, 0x5e, 0xb1,
+ 0x7e, 0x5f, 0x4e },
+ .ilen = 35,
+ .result = { 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 },
+ .rlen = 25,
+ }, {
+ .key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x0a, 0x09,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x00 },
+ .assoc = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b },
+ .alen = 12,
+ .input = { 0x07, 0x34, 0x25, 0x94, 0x15, 0x77, 0x85, 0x15,
+ 0x2b, 0x07, 0x40, 0x98, 0x33, 0x0a, 0xbb, 0x14,
+ 0x1b, 0x94, 0x7b, 0x56, 0x6a, 0xa9, 0x40, 0x6b,
+ 0x4d, 0x99, 0x99, 0x88, 0xdd },
+ .ilen = 29,
+ .result = { 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e },
+ .rlen = 19,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x33, 0x56, 0x8e, 0xf7, 0xb2, 0x63,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0x63, 0x01, 0x8f, 0x76, 0xdc, 0x8a, 0x1b, 0xcb },
+ .alen = 8,
+ .input = { 0x4c, 0xcb, 0x1e, 0x7c, 0xa9, 0x81, 0xbe, 0xfa,
+ 0xa0, 0x72, 0x6c, 0x55, 0xd3, 0x78, 0x06, 0x12,
+ 0x98, 0xc8, 0x5c, 0x92, 0x81, 0x4a, 0xbc, 0x33,
+ 0xc5, 0x2e, 0xe8, 0x1d, 0x7d, 0x77, 0xc0, 0x8a },
+ .ilen = 32,
+ .result = { 0x90, 0x20, 0xea, 0x6f, 0x91, 0xbd, 0xd8, 0x5a,
+ 0xfa, 0x00, 0x39, 0xba, 0x4b, 0xaf, 0xf9, 0xbf,
+ 0xb7, 0x9c, 0x70, 0x28, 0x94, 0x9c, 0xd0, 0xec },
+ .rlen = 24,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0xd5, 0x60, 0x91, 0x2d, 0x3f, 0x70,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0xcd, 0x90, 0x44, 0xd2, 0xb7, 0x1f, 0xdb, 0x81,
+ 0x20, 0xea, 0x60, 0xc0 },
+ .alen = 12,
+ .input = { 0x00, 0x97, 0x69, 0xec, 0xab, 0xdf, 0x48, 0x62,
+ 0x55, 0x94, 0xc5, 0x92, 0x51, 0xe6, 0x03, 0x57,
+ 0x22, 0x67, 0x5e, 0x04, 0xc8, 0x47, 0x09, 0x9e,
+ 0x5a, 0xe0, 0x70, 0x45, 0x51 },
+ .ilen = 29,
+ .result = { 0x64, 0x35, 0xac, 0xba, 0xfb, 0x11, 0xa8, 0x2e,
+ 0x2f, 0x07, 0x1d, 0x7c, 0xa4, 0xa5, 0xeb, 0xd9,
+ 0x3a, 0x80, 0x3b, 0xa8, 0x7f },
+ .rlen = 21,
+ }, {
+ .key = { 0xd7, 0x82, 0x8d, 0x13, 0xb2, 0xb0, 0xbd, 0xc3,
+ 0x25, 0xa7, 0x62, 0x36, 0xdf, 0x93, 0xcc, 0x6b },
+ .klen = 16,
+ .iv = { 0x01, 0x00, 0x42, 0xff, 0xf8, 0xf1, 0x95, 0x1c,
+ 0x3c, 0x96, 0x96, 0x76, 0x6c, 0xfa, 0x00, 0x00 },
+ .assoc = { 0xd8, 0x5b, 0xc7, 0xe6, 0x9f, 0x94, 0x4f, 0xb8 },
+ .alen = 8,
+ .input = { 0xbc, 0x21, 0x8d, 0xaa, 0x94, 0x74, 0x27, 0xb6,
+ 0xdb, 0x38, 0x6a, 0x99, 0xac, 0x1a, 0xef, 0x23,
+ 0xad, 0xe0, 0xb5, 0x29, 0x39, 0xcb, 0x6a, 0x63,
+ 0x7c, 0xf9, 0xbe, 0xc2, 0x40, 0x88, 0x97, 0xc6,
+ 0xba },
+ .ilen = 33,
+ .result = { 0x8a, 0x19, 0xb9, 0x50, 0xbc, 0xf7, 0x1a, 0x01,
+ 0x8e, 0x5e, 0x67, 0x01, 0xc9, 0x17, 0x87, 0x65,
+ 0x98, 0x09, 0xd6, 0x7d, 0xbe, 0xdd, 0x18 },
+ .rlen = 23,
+ },
+};
+
/* Cast5 test vectors from RFC 2144 */
#define CAST5_ENC_TEST_VECTORS 3
#define CAST5_DEC_TEST_VECTORS 3
@@ -4317,6 +6425,1211 @@ static struct cipher_testvec seed_dec_tv_template[] = {
}
};
+#define SALSA20_STREAM_ENC_TEST_VECTORS 5
+static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
+ /*
+ * Testvectors from verified.test-vectors submitted to ECRYPT.
+ * They are truncated to size 39, 64, 111, 129 to test a variety
+ * of input length.
+ */
+ { /* Set 3, vector 0 */
+ .key = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ },
+ .klen = 16,
+ .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .input = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .ilen = 39,
+ .result = {
+ 0x2D, 0xD5, 0xC3, 0xF7, 0xBA, 0x2B, 0x20, 0xF7,
+ 0x68, 0x02, 0x41, 0x0C, 0x68, 0x86, 0x88, 0x89,
+ 0x5A, 0xD8, 0xC1, 0xBD, 0x4E, 0xA6, 0xC9, 0xB1,
+ 0x40, 0xFB, 0x9B, 0x90, 0xE2, 0x10, 0x49, 0xBF,
+ 0x58, 0x3F, 0x52, 0x79, 0x70, 0xEB, 0xC1,
+ },
+ .rlen = 39,
+ }, { /* Set 5, vector 0 */
+ .key = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .klen = 16,
+ .iv = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .input = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .ilen = 64,
+ .result = {
+ 0xB6, 0x6C, 0x1E, 0x44, 0x46, 0xDD, 0x95, 0x57,
+ 0xE5, 0x78, 0xE2, 0x23, 0xB0, 0xB7, 0x68, 0x01,
+ 0x7B, 0x23, 0xB2, 0x67, 0xBB, 0x02, 0x34, 0xAE,
+ 0x46, 0x26, 0xBF, 0x44, 0x3F, 0x21, 0x97, 0x76,
+ 0x43, 0x6F, 0xB1, 0x9F, 0xD0, 0xE8, 0x86, 0x6F,
+ 0xCD, 0x0D, 0xE9, 0xA9, 0x53, 0x8F, 0x4A, 0x09,
+ 0xCA, 0x9A, 0xC0, 0x73, 0x2E, 0x30, 0xBC, 0xF9,
+ 0x8E, 0x4F, 0x13, 0xE4, 0xB9, 0xE2, 0x01, 0xD9,
+ },
+ .rlen = 64,
+ }, { /* Set 3, vector 27 */
+ .key = {
+ 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
+ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
+ 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
+ 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A
+ },
+ .klen = 32,
+ .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .input = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .ilen = 111,
+ .result = {
+ 0xAE, 0x39, 0x50, 0x8E, 0xAC, 0x9A, 0xEC, 0xE7,
+ 0xBF, 0x97, 0xBB, 0x20, 0xB9, 0xDE, 0xE4, 0x1F,
+ 0x87, 0xD9, 0x47, 0xF8, 0x28, 0x91, 0x35, 0x98,
+ 0xDB, 0x72, 0xCC, 0x23, 0x29, 0x48, 0x56, 0x5E,
+ 0x83, 0x7E, 0x0B, 0xF3, 0x7D, 0x5D, 0x38, 0x7B,
+ 0x2D, 0x71, 0x02, 0xB4, 0x3B, 0xB5, 0xD8, 0x23,
+ 0xB0, 0x4A, 0xDF, 0x3C, 0xEC, 0xB6, 0xD9, 0x3B,
+ 0x9B, 0xA7, 0x52, 0xBE, 0xC5, 0xD4, 0x50, 0x59,
+
+ 0x15, 0x14, 0xB4, 0x0E, 0x40, 0xE6, 0x53, 0xD1,
+ 0x83, 0x9C, 0x5B, 0xA0, 0x92, 0x29, 0x6B, 0x5E,
+ 0x96, 0x5B, 0x1E, 0x2F, 0xD3, 0xAC, 0xC1, 0x92,
+ 0xB1, 0x41, 0x3F, 0x19, 0x2F, 0xC4, 0x3B, 0xC6,
+ 0x95, 0x46, 0x45, 0x54, 0xE9, 0x75, 0x03, 0x08,
+ 0x44, 0xAF, 0xE5, 0x8A, 0x81, 0x12, 0x09,
+ },
+ .rlen = 111,
+
+ }, { /* Set 5, vector 27 */
+ .key = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .klen = 32,
+ .iv = { 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00 },
+ .input = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00,
+ },
+ .ilen = 129,
+ .result = {
+ 0xD2, 0xDB, 0x1A, 0x5C, 0xF1, 0xC1, 0xAC, 0xDB,
+ 0xE8, 0x1A, 0x7A, 0x43, 0x40, 0xEF, 0x53, 0x43,
+ 0x5E, 0x7F, 0x4B, 0x1A, 0x50, 0x52, 0x3F, 0x8D,
+ 0x28, 0x3D, 0xCF, 0x85, 0x1D, 0x69, 0x6E, 0x60,
+ 0xF2, 0xDE, 0x74, 0x56, 0x18, 0x1B, 0x84, 0x10,
+ 0xD4, 0x62, 0xBA, 0x60, 0x50, 0xF0, 0x61, 0xF2,
+ 0x1C, 0x78, 0x7F, 0xC1, 0x24, 0x34, 0xAF, 0x58,
+ 0xBF, 0x2C, 0x59, 0xCA, 0x90, 0x77, 0xF3, 0xB0,
+
+ 0x5B, 0x4A, 0xDF, 0x89, 0xCE, 0x2C, 0x2F, 0xFC,
+ 0x67, 0xF0, 0xE3, 0x45, 0xE8, 0xB3, 0xB3, 0x75,
+ 0xA0, 0x95, 0x71, 0xA1, 0x29, 0x39, 0x94, 0xCA,
+ 0x45, 0x2F, 0xBD, 0xCB, 0x10, 0xB6, 0xBE, 0x9F,
+ 0x8E, 0xF9, 0xB2, 0x01, 0x0A, 0x5A, 0x0A, 0xB7,
+ 0x6B, 0x9D, 0x70, 0x8E, 0x4B, 0xD6, 0x2F, 0xCD,
+ 0x2E, 0x40, 0x48, 0x75, 0xE9, 0xE2, 0x21, 0x45,
+ 0x0B, 0xC9, 0xB6, 0xB5, 0x66, 0xBC, 0x9A, 0x59,
+
+ 0x5A,
+ },
+ .rlen = 129,
+ }, { /* large test vector generated using Crypto++ */
+ .key = {
+ 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,
+ },
+ .klen = 32,
+ .iv = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .input = {
+ 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, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+ 0x00, 0x03, 0x06, 0x09, 0x0c, 0x0f, 0x12, 0x15,
+ 0x18, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d,
+ 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45,
+ 0x48, 0x4b, 0x4e, 0x51, 0x54, 0x57, 0x5a, 0x5d,
+ 0x60, 0x63, 0x66, 0x69, 0x6c, 0x6f, 0x72, 0x75,
+ 0x78, 0x7b, 0x7e, 0x81, 0x84, 0x87, 0x8a, 0x8d,
+ 0x90, 0x93, 0x96, 0x99, 0x9c, 0x9f, 0xa2, 0xa5,
+ 0xa8, 0xab, 0xae, 0xb1, 0xb4, 0xb7, 0xba, 0xbd,
+ 0xc0, 0xc3, 0xc6, 0xc9, 0xcc, 0xcf, 0xd2, 0xd5,
+ 0xd8, 0xdb, 0xde, 0xe1, 0xe4, 0xe7, 0xea, 0xed,
+ 0xf0, 0xf3, 0xf6, 0xf9, 0xfc, 0xff, 0x02, 0x05,
+ 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17, 0x1a, 0x1d,
+ 0x20, 0x23, 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35,
+ 0x38, 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d,
+ 0x50, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0x65,
+ 0x68, 0x6b, 0x6e, 0x71, 0x74, 0x77, 0x7a, 0x7d,
+ 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95,
+ 0x98, 0x9b, 0x9e, 0xa1, 0xa4, 0xa7, 0xaa, 0xad,
+ 0xb0, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc2, 0xc5,
+ 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, 0xdd,
+ 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, 0xf5,
+ 0xf8, 0xfb, 0xfe, 0x01, 0x04, 0x07, 0x0a, 0x0d,
+ 0x10, 0x13, 0x16, 0x19, 0x1c, 0x1f, 0x22, 0x25,
+ 0x28, 0x2b, 0x2e, 0x31, 0x34, 0x37, 0x3a, 0x3d,
+ 0x40, 0x43, 0x46, 0x49, 0x4c, 0x4f, 0x52, 0x55,
+ 0x58, 0x5b, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6d,
+ 0x70, 0x73, 0x76, 0x79, 0x7c, 0x7f, 0x82, 0x85,
+ 0x88, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9d,
+ 0xa0, 0xa3, 0xa6, 0xa9, 0xac, 0xaf, 0xb2, 0xb5,
+ 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
+ 0xd0, 0xd3, 0xd6, 0xd9, 0xdc, 0xdf, 0xe2, 0xe5,
+ 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf7, 0xfa, 0xfd,
+ 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1e, 0x23,
+ 0x28, 0x2d, 0x32, 0x37, 0x3c, 0x41, 0x46, 0x4b,
+ 0x50, 0x55, 0x5a, 0x5f, 0x64, 0x69, 0x6e, 0x73,
+ 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91, 0x96, 0x9b,
+ 0xa0, 0xa5, 0xaa, 0xaf, 0xb4, 0xb9, 0xbe, 0xc3,
+ 0xc8, 0xcd, 0xd2, 0xd7, 0xdc, 0xe1, 0xe6, 0xeb,
+ 0xf0, 0xf5, 0xfa, 0xff, 0x04, 0x09, 0x0e, 0x13,
+ 0x18, 0x1d, 0x22, 0x27, 0x2c, 0x31, 0x36, 0x3b,
+ 0x40, 0x45, 0x4a, 0x4f, 0x54, 0x59, 0x5e, 0x63,
+ 0x68, 0x6d, 0x72, 0x77, 0x7c, 0x81, 0x86, 0x8b,
+ 0x90, 0x95, 0x9a, 0x9f, 0xa4, 0xa9, 0xae, 0xb3,
+ 0xb8, 0xbd, 0xc2, 0xc7, 0xcc, 0xd1, 0xd6, 0xdb,
+ 0xe0, 0xe5, 0xea, 0xef, 0xf4, 0xf9, 0xfe, 0x03,
+ 0x08, 0x0d, 0x12, 0x17, 0x1c, 0x21, 0x26, 0x2b,
+ 0x30, 0x35, 0x3a, 0x3f, 0x44, 0x49, 0x4e, 0x53,
+ 0x58, 0x5d, 0x62, 0x67, 0x6c, 0x71, 0x76, 0x7b,
+ 0x80, 0x85, 0x8a, 0x8f, 0x94, 0x99, 0x9e, 0xa3,
+ 0xa8, 0xad, 0xb2, 0xb7, 0xbc, 0xc1, 0xc6, 0xcb,
+ 0xd0, 0xd5, 0xda, 0xdf, 0xe4, 0xe9, 0xee, 0xf3,
+ 0xf8, 0xfd, 0x02, 0x07, 0x0c, 0x11, 0x16, 0x1b,
+ 0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3e, 0x43,
+ 0x48, 0x4d, 0x52, 0x57, 0x5c, 0x61, 0x66, 0x6b,
+ 0x70, 0x75, 0x7a, 0x7f, 0x84, 0x89, 0x8e, 0x93,
+ 0x98, 0x9d, 0xa2, 0xa7, 0xac, 0xb1, 0xb6, 0xbb,
+ 0xc0, 0xc5, 0xca, 0xcf, 0xd4, 0xd9, 0xde, 0xe3,
+ 0xe8, 0xed, 0xf2, 0xf7, 0xfc, 0x01, 0x06, 0x0b,
+ 0x10, 0x15, 0x1a, 0x1f, 0x24, 0x29, 0x2e, 0x33,
+ 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x51, 0x56, 0x5b,
+ 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7e, 0x83,
+ 0x88, 0x8d, 0x92, 0x97, 0x9c, 0xa1, 0xa6, 0xab,
+ 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9, 0xce, 0xd3,
+ 0xd8, 0xdd, 0xe2, 0xe7, 0xec, 0xf1, 0xf6, 0xfb,
+ 0x00, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31,
+ 0x38, 0x3f, 0x46, 0x4d, 0x54, 0x5b, 0x62, 0x69,
+ 0x70, 0x77, 0x7e, 0x85, 0x8c, 0x93, 0x9a, 0xa1,
+ 0xa8, 0xaf, 0xb6, 0xbd, 0xc4, 0xcb, 0xd2, 0xd9,
+ 0xe0, 0xe7, 0xee, 0xf5, 0xfc, 0x03, 0x0a, 0x11,
+ 0x18, 0x1f, 0x26, 0x2d, 0x34, 0x3b, 0x42, 0x49,
+ 0x50, 0x57, 0x5e, 0x65, 0x6c, 0x73, 0x7a, 0x81,
+ 0x88, 0x8f, 0x96, 0x9d, 0xa4, 0xab, 0xb2, 0xb9,
+ 0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1,
+ 0xf8, 0xff, 0x06, 0x0d, 0x14, 0x1b, 0x22, 0x29,
+ 0x30, 0x37, 0x3e, 0x45, 0x4c, 0x53, 0x5a, 0x61,
+ 0x68, 0x6f, 0x76, 0x7d, 0x84, 0x8b, 0x92, 0x99,
+ 0xa0, 0xa7, 0xae, 0xb5, 0xbc, 0xc3, 0xca, 0xd1,
+ 0xd8, 0xdf, 0xe6, 0xed, 0xf4, 0xfb, 0x02, 0x09,
+ 0x10, 0x17, 0x1e, 0x25, 0x2c, 0x33, 0x3a, 0x41,
+ 0x48, 0x4f, 0x56, 0x5d, 0x64, 0x6b, 0x72, 0x79,
+ 0x80, 0x87, 0x8e, 0x95, 0x9c, 0xa3, 0xaa, 0xb1,
+ 0xb8, 0xbf, 0xc6, 0xcd, 0xd4, 0xdb, 0xe2, 0xe9,
+ 0xf0, 0xf7, 0xfe, 0x05, 0x0c, 0x13, 0x1a, 0x21,
+ 0x28, 0x2f, 0x36, 0x3d, 0x44, 0x4b, 0x52, 0x59,
+ 0x60, 0x67, 0x6e, 0x75, 0x7c, 0x83, 0x8a, 0x91,
+ 0x98, 0x9f, 0xa6, 0xad, 0xb4, 0xbb, 0xc2, 0xc9,
+ 0xd0, 0xd7, 0xde, 0xe5, 0xec, 0xf3, 0xfa, 0x01,
+ 0x08, 0x0f, 0x16, 0x1d, 0x24, 0x2b, 0x32, 0x39,
+ 0x40, 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71,
+ 0x78, 0x7f, 0x86, 0x8d, 0x94, 0x9b, 0xa2, 0xa9,
+ 0xb0, 0xb7, 0xbe, 0xc5, 0xcc, 0xd3, 0xda, 0xe1,
+ 0xe8, 0xef, 0xf6, 0xfd, 0x04, 0x0b, 0x12, 0x19,
+ 0x20, 0x27, 0x2e, 0x35, 0x3c, 0x43, 0x4a, 0x51,
+ 0x58, 0x5f, 0x66, 0x6d, 0x74, 0x7b, 0x82, 0x89,
+ 0x90, 0x97, 0x9e, 0xa5, 0xac, 0xb3, 0xba, 0xc1,
+ 0xc8, 0xcf, 0xd6, 0xdd, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x51, 0x5a, 0x63, 0x6c, 0x75, 0x7e, 0x87,
+ 0x90, 0x99, 0xa2, 0xab, 0xb4, 0xbd, 0xc6, 0xcf,
+ 0xd8, 0xe1, 0xea, 0xf3, 0xfc, 0x05, 0x0e, 0x17,
+ 0x20, 0x29, 0x32, 0x3b, 0x44, 0x4d, 0x56, 0x5f,
+ 0x68, 0x71, 0x7a, 0x83, 0x8c, 0x95, 0x9e, 0xa7,
+ 0xb0, 0xb9, 0xc2, 0xcb, 0xd4, 0xdd, 0xe6, 0xef,
+ 0xf8, 0x01, 0x0a, 0x13, 0x1c, 0x25, 0x2e, 0x37,
+ 0x40, 0x49, 0x52, 0x5b, 0x64, 0x6d, 0x76, 0x7f,
+ 0x88, 0x91, 0x9a, 0xa3, 0xac, 0xb5, 0xbe, 0xc7,
+ 0xd0, 0xd9, 0xe2, 0xeb, 0xf4, 0xfd, 0x06, 0x0f,
+ 0x18, 0x21, 0x2a, 0x33, 0x3c, 0x45, 0x4e, 0x57,
+ 0x60, 0x69, 0x72, 0x7b, 0x84, 0x8d, 0x96, 0x9f,
+ 0xa8, 0xb1, 0xba, 0xc3, 0xcc, 0xd5, 0xde, 0xe7,
+ 0xf0, 0xf9, 0x02, 0x0b, 0x14, 0x1d, 0x26, 0x2f,
+ 0x38, 0x41, 0x4a, 0x53, 0x5c, 0x65, 0x6e, 0x77,
+ 0x80, 0x89, 0x92, 0x9b, 0xa4, 0xad, 0xb6, 0xbf,
+ 0xc8, 0xd1, 0xda, 0xe3, 0xec, 0xf5, 0xfe, 0x07,
+ 0x10, 0x19, 0x22, 0x2b, 0x34, 0x3d, 0x46, 0x4f,
+ 0x58, 0x61, 0x6a, 0x73, 0x7c, 0x85, 0x8e, 0x97,
+ 0xa0, 0xa9, 0xb2, 0xbb, 0xc4, 0xcd, 0xd6, 0xdf,
+ 0xe8, 0xf1, 0xfa, 0x03, 0x0c, 0x15, 0x1e, 0x27,
+ 0x30, 0x39, 0x42, 0x4b, 0x54, 0x5d, 0x66, 0x6f,
+ 0x78, 0x81, 0x8a, 0x93, 0x9c, 0xa5, 0xae, 0xb7,
+ 0xc0, 0xc9, 0xd2, 0xdb, 0xe4, 0xed, 0xf6, 0xff,
+ 0x08, 0x11, 0x1a, 0x23, 0x2c, 0x35, 0x3e, 0x47,
+ 0x50, 0x59, 0x62, 0x6b, 0x74, 0x7d, 0x86, 0x8f,
+ 0x98, 0xa1, 0xaa, 0xb3, 0xbc, 0xc5, 0xce, 0xd7,
+ 0xe0, 0xe9, 0xf2, 0xfb, 0x04, 0x0d, 0x16, 0x1f,
+ 0x28, 0x31, 0x3a, 0x43, 0x4c, 0x55, 0x5e, 0x67,
+ 0x70, 0x79, 0x82, 0x8b, 0x94, 0x9d, 0xa6, 0xaf,
+ 0xb8, 0xc1, 0xca, 0xd3, 0xdc, 0xe5, 0xee, 0xf7,
+ 0x00, 0x0b, 0x16, 0x21, 0x2c, 0x37, 0x42, 0x4d,
+ 0x58, 0x63, 0x6e, 0x79, 0x84, 0x8f, 0x9a, 0xa5,
+ 0xb0, 0xbb, 0xc6, 0xd1, 0xdc, 0xe7, 0xf2, 0xfd,
+ 0x08, 0x13, 0x1e, 0x29, 0x34, 0x3f, 0x4a, 0x55,
+ 0x60, 0x6b, 0x76, 0x81, 0x8c, 0x97, 0xa2, 0xad,
+ 0xb8, 0xc3, 0xce, 0xd9, 0xe4, 0xef, 0xfa, 0x05,
+ 0x10, 0x1b, 0x26, 0x31, 0x3c, 0x47, 0x52, 0x5d,
+ 0x68, 0x73, 0x7e, 0x89, 0x94, 0x9f, 0xaa, 0xb5,
+ 0xc0, 0xcb, 0xd6, 0xe1, 0xec, 0xf7, 0x02, 0x0d,
+ 0x18, 0x23, 0x2e, 0x39, 0x44, 0x4f, 0x5a, 0x65,
+ 0x70, 0x7b, 0x86, 0x91, 0x9c, 0xa7, 0xb2, 0xbd,
+ 0xc8, 0xd3, 0xde, 0xe9, 0xf4, 0xff, 0x0a, 0x15,
+ 0x20, 0x2b, 0x36, 0x41, 0x4c, 0x57, 0x62, 0x6d,
+ 0x78, 0x83, 0x8e, 0x99, 0xa4, 0xaf, 0xba, 0xc5,
+ 0xd0, 0xdb, 0xe6, 0xf1, 0xfc, 0x07, 0x12, 0x1d,
+ 0x28, 0x33, 0x3e, 0x49, 0x54, 0x5f, 0x6a, 0x75,
+ 0x80, 0x8b, 0x96, 0xa1, 0xac, 0xb7, 0xc2, 0xcd,
+ 0xd8, 0xe3, 0xee, 0xf9, 0x04, 0x0f, 0x1a, 0x25,
+ 0x30, 0x3b, 0x46, 0x51, 0x5c, 0x67, 0x72, 0x7d,
+ 0x88, 0x93, 0x9e, 0xa9, 0xb4, 0xbf, 0xca, 0xd5,
+ 0xe0, 0xeb, 0xf6, 0x01, 0x0c, 0x17, 0x22, 0x2d,
+ 0x38, 0x43, 0x4e, 0x59, 0x64, 0x6f, 0x7a, 0x85,
+ 0x90, 0x9b, 0xa6, 0xb1, 0xbc, 0xc7, 0xd2, 0xdd,
+ 0xe8, 0xf3, 0xfe, 0x09, 0x14, 0x1f, 0x2a, 0x35,
+ 0x40, 0x4b, 0x56, 0x61, 0x6c, 0x77, 0x82, 0x8d,
+ 0x98, 0xa3, 0xae, 0xb9, 0xc4, 0xcf, 0xda, 0xe5,
+ 0xf0, 0xfb, 0x06, 0x11, 0x1c, 0x27, 0x32, 0x3d,
+ 0x48, 0x53, 0x5e, 0x69, 0x74, 0x7f, 0x8a, 0x95,
+ 0xa0, 0xab, 0xb6, 0xc1, 0xcc, 0xd7, 0xe2, 0xed,
+ 0xf8, 0x03, 0x0e, 0x19, 0x24, 0x2f, 0x3a, 0x45,
+ 0x50, 0x5b, 0x66, 0x71, 0x7c, 0x87, 0x92, 0x9d,
+ 0xa8, 0xb3, 0xbe, 0xc9, 0xd4, 0xdf, 0xea, 0xf5,
+ 0x00, 0x0d, 0x1a, 0x27, 0x34, 0x41, 0x4e, 0x5b,
+ 0x68, 0x75, 0x82, 0x8f, 0x9c, 0xa9, 0xb6, 0xc3,
+ 0xd0, 0xdd, 0xea, 0xf7, 0x04, 0x11, 0x1e, 0x2b,
+ 0x38, 0x45, 0x52, 0x5f, 0x6c, 0x79, 0x86, 0x93,
+ 0xa0, 0xad, 0xba, 0xc7, 0xd4, 0xe1, 0xee, 0xfb,
+ 0x08, 0x15, 0x22, 0x2f, 0x3c, 0x49, 0x56, 0x63,
+ 0x70, 0x7d, 0x8a, 0x97, 0xa4, 0xb1, 0xbe, 0xcb,
+ 0xd8, 0xe5, 0xf2, 0xff, 0x0c, 0x19, 0x26, 0x33,
+ 0x40, 0x4d, 0x5a, 0x67, 0x74, 0x81, 0x8e, 0x9b,
+ 0xa8, 0xb5, 0xc2, 0xcf, 0xdc, 0xe9, 0xf6, 0x03,
+ 0x10, 0x1d, 0x2a, 0x37, 0x44, 0x51, 0x5e, 0x6b,
+ 0x78, 0x85, 0x92, 0x9f, 0xac, 0xb9, 0xc6, 0xd3,
+ 0xe0, 0xed, 0xfa, 0x07, 0x14, 0x21, 0x2e, 0x3b,
+ 0x48, 0x55, 0x62, 0x6f, 0x7c, 0x89, 0x96, 0xa3,
+ 0xb0, 0xbd, 0xca, 0xd7, 0xe4, 0xf1, 0xfe, 0x0b,
+ 0x18, 0x25, 0x32, 0x3f, 0x4c, 0x59, 0x66, 0x73,
+ 0x80, 0x8d, 0x9a, 0xa7, 0xb4, 0xc1, 0xce, 0xdb,
+ 0xe8, 0xf5, 0x02, 0x0f, 0x1c, 0x29, 0x36, 0x43,
+ 0x50, 0x5d, 0x6a, 0x77, 0x84, 0x91, 0x9e, 0xab,
+ 0xb8, 0xc5, 0xd2, 0xdf, 0xec, 0xf9, 0x06, 0x13,
+ 0x20, 0x2d, 0x3a, 0x47, 0x54, 0x61, 0x6e, 0x7b,
+ 0x88, 0x95, 0xa2, 0xaf, 0xbc, 0xc9, 0xd6, 0xe3,
+ 0xf0, 0xfd, 0x0a, 0x17, 0x24, 0x31, 0x3e, 0x4b,
+ 0x58, 0x65, 0x72, 0x7f, 0x8c, 0x99, 0xa6, 0xb3,
+ 0xc0, 0xcd, 0xda, 0xe7, 0xf4, 0x01, 0x0e, 0x1b,
+ 0x28, 0x35, 0x42, 0x4f, 0x5c, 0x69, 0x76, 0x83,
+ 0x90, 0x9d, 0xaa, 0xb7, 0xc4, 0xd1, 0xde, 0xeb,
+ 0xf8, 0x05, 0x12, 0x1f, 0x2c, 0x39, 0x46, 0x53,
+ 0x60, 0x6d, 0x7a, 0x87, 0x94, 0xa1, 0xae, 0xbb,
+ 0xc8, 0xd5, 0xe2, 0xef, 0xfc, 0x09, 0x16, 0x23,
+ 0x30, 0x3d, 0x4a, 0x57, 0x64, 0x71, 0x7e, 0x8b,
+ 0x98, 0xa5, 0xb2, 0xbf, 0xcc, 0xd9, 0xe6, 0xf3,
+ 0x00, 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69,
+ 0x78, 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1,
+ 0xf0, 0xff, 0x0e, 0x1d, 0x2c, 0x3b, 0x4a, 0x59,
+ 0x68, 0x77, 0x86, 0x95, 0xa4, 0xb3, 0xc2, 0xd1,
+ 0xe0, 0xef, 0xfe, 0x0d, 0x1c, 0x2b, 0x3a, 0x49,
+ 0x58, 0x67, 0x76, 0x85, 0x94, 0xa3, 0xb2, 0xc1,
+ 0xd0, 0xdf, 0xee, 0xfd, 0x0c, 0x1b, 0x2a, 0x39,
+ 0x48, 0x57, 0x66, 0x75, 0x84, 0x93, 0xa2, 0xb1,
+ 0xc0, 0xcf, 0xde, 0xed, 0xfc, 0x0b, 0x1a, 0x29,
+ 0x38, 0x47, 0x56, 0x65, 0x74, 0x83, 0x92, 0xa1,
+ 0xb0, 0xbf, 0xce, 0xdd, 0xec, 0xfb, 0x0a, 0x19,
+ 0x28, 0x37, 0x46, 0x55, 0x64, 0x73, 0x82, 0x91,
+ 0xa0, 0xaf, 0xbe, 0xcd, 0xdc, 0xeb, 0xfa, 0x09,
+ 0x18, 0x27, 0x36, 0x45, 0x54, 0x63, 0x72, 0x81,
+ 0x90, 0x9f, 0xae, 0xbd, 0xcc, 0xdb, 0xea, 0xf9,
+ 0x08, 0x17, 0x26, 0x35, 0x44, 0x53, 0x62, 0x71,
+ 0x80, 0x8f, 0x9e, 0xad, 0xbc, 0xcb, 0xda, 0xe9,
+ 0xf8, 0x07, 0x16, 0x25, 0x34, 0x43, 0x52, 0x61,
+ 0x70, 0x7f, 0x8e, 0x9d, 0xac, 0xbb, 0xca, 0xd9,
+ 0xe8, 0xf7, 0x06, 0x15, 0x24, 0x33, 0x42, 0x51,
+ 0x60, 0x6f, 0x7e, 0x8d, 0x9c, 0xab, 0xba, 0xc9,
+ 0xd8, 0xe7, 0xf6, 0x05, 0x14, 0x23, 0x32, 0x41,
+ 0x50, 0x5f, 0x6e, 0x7d, 0x8c, 0x9b, 0xaa, 0xb9,
+ 0xc8, 0xd7, 0xe6, 0xf5, 0x04, 0x13, 0x22, 0x31,
+ 0x40, 0x4f, 0x5e, 0x6d, 0x7c, 0x8b, 0x9a, 0xa9,
+ 0xb8, 0xc7, 0xd6, 0xe5, 0xf4, 0x03, 0x12, 0x21,
+ 0x30, 0x3f, 0x4e, 0x5d, 0x6c, 0x7b, 0x8a, 0x99,
+ 0xa8, 0xb7, 0xc6, 0xd5, 0xe4, 0xf3, 0x02, 0x11,
+ 0x20, 0x2f, 0x3e, 0x4d, 0x5c, 0x6b, 0x7a, 0x89,
+ 0x98, 0xa7, 0xb6, 0xc5, 0xd4, 0xe3, 0xf2, 0x01,
+ 0x10, 0x1f, 0x2e, 0x3d, 0x4c, 0x5b, 0x6a, 0x79,
+ 0x88, 0x97, 0xa6, 0xb5, 0xc4, 0xd3, 0xe2, 0xf1,
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+ 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
+ 0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0x0f,
+ 0x20, 0x31, 0x42, 0x53, 0x64, 0x75, 0x86, 0x97,
+ 0xa8, 0xb9, 0xca, 0xdb, 0xec, 0xfd, 0x0e, 0x1f,
+ 0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
+ 0xb8, 0xc9, 0xda, 0xeb, 0xfc, 0x0d, 0x1e, 0x2f,
+ 0x40, 0x51, 0x62, 0x73, 0x84, 0x95, 0xa6, 0xb7,
+ 0xc8, 0xd9, 0xea, 0xfb, 0x0c, 0x1d, 0x2e, 0x3f,
+ 0x50, 0x61, 0x72, 0x83, 0x94, 0xa5, 0xb6, 0xc7,
+ 0xd8, 0xe9, 0xfa, 0x0b, 0x1c, 0x2d, 0x3e, 0x4f,
+ 0x60, 0x71, 0x82, 0x93, 0xa4, 0xb5, 0xc6, 0xd7,
+ 0xe8, 0xf9, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f,
+ 0x70, 0x81, 0x92, 0xa3, 0xb4, 0xc5, 0xd6, 0xe7,
+ 0xf8, 0x09, 0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f,
+ 0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7,
+ 0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f,
+ 0x90, 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6, 0x07,
+ 0x18, 0x29, 0x3a, 0x4b, 0x5c, 0x6d, 0x7e, 0x8f,
+ 0xa0, 0xb1, 0xc2, 0xd3, 0xe4, 0xf5, 0x06, 0x17,
+ 0x28, 0x39, 0x4a, 0x5b, 0x6c, 0x7d, 0x8e, 0x9f,
+ 0xb0, 0xc1, 0xd2, 0xe3, 0xf4, 0x05, 0x16, 0x27,
+ 0x38, 0x49, 0x5a, 0x6b, 0x7c, 0x8d, 0x9e, 0xaf,
+ 0xc0, 0xd1, 0xe2, 0xf3, 0x04, 0x15, 0x26, 0x37,
+ 0x48, 0x59, 0x6a, 0x7b, 0x8c, 0x9d, 0xae, 0xbf,
+ 0xd0, 0xe1, 0xf2, 0x03, 0x14, 0x25, 0x36, 0x47,
+ 0x58, 0x69, 0x7a, 0x8b, 0x9c, 0xad, 0xbe, 0xcf,
+ 0xe0, 0xf1, 0x02, 0x13, 0x24, 0x35, 0x46, 0x57,
+ 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf,
+ 0xf0, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67,
+ 0x78, 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef,
+ 0x00, 0x13, 0x26, 0x39, 0x4c, 0x5f, 0x72, 0x85,
+ 0x98, 0xab, 0xbe, 0xd1, 0xe4, 0xf7, 0x0a, 0x1d,
+ 0x30, 0x43, 0x56, 0x69, 0x7c, 0x8f, 0xa2, 0xb5,
+ 0xc8, 0xdb, 0xee, 0x01, 0x14, 0x27, 0x3a, 0x4d,
+ 0x60, 0x73, 0x86, 0x99, 0xac, 0xbf, 0xd2, 0xe5,
+ 0xf8, 0x0b, 0x1e, 0x31, 0x44, 0x57, 0x6a, 0x7d,
+ 0x90, 0xa3, 0xb6, 0xc9, 0xdc, 0xef, 0x02, 0x15,
+ 0x28, 0x3b, 0x4e, 0x61, 0x74, 0x87, 0x9a, 0xad,
+ 0xc0, 0xd3, 0xe6, 0xf9, 0x0c, 0x1f, 0x32, 0x45,
+ 0x58, 0x6b, 0x7e, 0x91, 0xa4, 0xb7, 0xca, 0xdd,
+ 0xf0, 0x03, 0x16, 0x29, 0x3c, 0x4f, 0x62, 0x75,
+ 0x88, 0x9b, 0xae, 0xc1, 0xd4, 0xe7, 0xfa, 0x0d,
+ 0x20, 0x33, 0x46, 0x59, 0x6c, 0x7f, 0x92, 0xa5,
+ 0xb8, 0xcb, 0xde, 0xf1, 0x04, 0x17, 0x2a, 0x3d,
+ 0x50, 0x63, 0x76, 0x89, 0x9c, 0xaf, 0xc2, 0xd5,
+ 0xe8, 0xfb, 0x0e, 0x21, 0x34, 0x47, 0x5a, 0x6d,
+ 0x80, 0x93, 0xa6, 0xb9, 0xcc, 0xdf, 0xf2, 0x05,
+ 0x18, 0x2b, 0x3e, 0x51, 0x64, 0x77, 0x8a, 0x9d,
+ 0xb0, 0xc3, 0xd6, 0xe9, 0xfc, 0x0f, 0x22, 0x35,
+ 0x48, 0x5b, 0x6e, 0x81, 0x94, 0xa7, 0xba, 0xcd,
+ 0xe0, 0xf3, 0x06, 0x19, 0x2c, 0x3f, 0x52, 0x65,
+ 0x78, 0x8b, 0x9e, 0xb1, 0xc4, 0xd7, 0xea, 0xfd,
+ 0x10, 0x23, 0x36, 0x49, 0x5c, 0x6f, 0x82, 0x95,
+ 0xa8, 0xbb, 0xce, 0xe1, 0xf4, 0x07, 0x1a, 0x2d,
+ 0x40, 0x53, 0x66, 0x79, 0x8c, 0x9f, 0xb2, 0xc5,
+ 0xd8, 0xeb, 0xfe, 0x11, 0x24, 0x37, 0x4a, 0x5d,
+ 0x70, 0x83, 0x96, 0xa9, 0xbc, 0xcf, 0xe2, 0xf5,
+ 0x08, 0x1b, 0x2e, 0x41, 0x54, 0x67, 0x7a, 0x8d,
+ 0xa0, 0xb3, 0xc6, 0xd9, 0xec, 0xff, 0x12, 0x25,
+ 0x38, 0x4b, 0x5e, 0x71, 0x84, 0x97, 0xaa, 0xbd,
+ 0xd0, 0xe3, 0xf6, 0x09, 0x1c, 0x2f, 0x42, 0x55,
+ 0x68, 0x7b, 0x8e, 0xa1, 0xb4, 0xc7, 0xda, 0xed,
+ 0x00, 0x15, 0x2a, 0x3f, 0x54, 0x69, 0x7e, 0x93,
+ 0xa8, 0xbd, 0xd2, 0xe7, 0xfc, 0x11, 0x26, 0x3b,
+ 0x50, 0x65, 0x7a, 0x8f, 0xa4, 0xb9, 0xce, 0xe3,
+ 0xf8, 0x0d, 0x22, 0x37, 0x4c, 0x61, 0x76, 0x8b,
+ 0xa0, 0xb5, 0xca, 0xdf, 0xf4, 0x09, 0x1e, 0x33,
+ 0x48, 0x5d, 0x72, 0x87, 0x9c, 0xb1, 0xc6, 0xdb,
+ 0xf0, 0x05, 0x1a, 0x2f, 0x44, 0x59, 0x6e, 0x83,
+ 0x98, 0xad, 0xc2, 0xd7, 0xec, 0x01, 0x16, 0x2b,
+ 0x40, 0x55, 0x6a, 0x7f, 0x94, 0xa9, 0xbe, 0xd3,
+ 0xe8, 0xfd, 0x12, 0x27, 0x3c, 0x51, 0x66, 0x7b,
+ 0x90, 0xa5, 0xba, 0xcf, 0xe4, 0xf9, 0x0e, 0x23,
+ 0x38, 0x4d, 0x62, 0x77, 0x8c, 0xa1, 0xb6, 0xcb,
+ 0xe0, 0xf5, 0x0a, 0x1f, 0x34, 0x49, 0x5e, 0x73,
+ 0x88, 0x9d, 0xb2, 0xc7, 0xdc, 0xf1, 0x06, 0x1b,
+ 0x30, 0x45, 0x5a, 0x6f, 0x84, 0x99, 0xae, 0xc3,
+ 0xd8, 0xed, 0x02, 0x17, 0x2c, 0x41, 0x56, 0x6b,
+ 0x80, 0x95, 0xaa, 0xbf, 0xd4, 0xe9, 0xfe, 0x13,
+ 0x28, 0x3d, 0x52, 0x67, 0x7c, 0x91, 0xa6, 0xbb,
+ 0xd0, 0xe5, 0xfa, 0x0f, 0x24, 0x39, 0x4e, 0x63,
+ 0x78, 0x8d, 0xa2, 0xb7, 0xcc, 0xe1, 0xf6, 0x0b,
+ 0x20, 0x35, 0x4a, 0x5f, 0x74, 0x89, 0x9e, 0xb3,
+ 0xc8, 0xdd, 0xf2, 0x07, 0x1c, 0x31, 0x46, 0x5b,
+ 0x70, 0x85, 0x9a, 0xaf, 0xc4, 0xd9, 0xee, 0x03,
+ 0x18, 0x2d, 0x42, 0x57, 0x6c, 0x81, 0x96, 0xab,
+ 0xc0, 0xd5, 0xea, 0xff, 0x14, 0x29, 0x3e, 0x53,
+ 0x68, 0x7d, 0x92, 0xa7, 0xbc, 0xd1, 0xe6, 0xfb,
+ 0x10, 0x25, 0x3a, 0x4f, 0x64, 0x79, 0x8e, 0xa3,
+ 0xb8, 0xcd, 0xe2, 0xf7, 0x0c, 0x21, 0x36, 0x4b,
+ 0x60, 0x75, 0x8a, 0x9f, 0xb4, 0xc9, 0xde, 0xf3,
+ 0x08, 0x1d, 0x32, 0x47, 0x5c, 0x71, 0x86, 0x9b,
+ 0xb0, 0xc5, 0xda, 0xef, 0x04, 0x19, 0x2e, 0x43,
+ 0x58, 0x6d, 0x82, 0x97, 0xac, 0xc1, 0xd6, 0xeb,
+ 0x00, 0x17, 0x2e, 0x45, 0x5c, 0x73, 0x8a, 0xa1,
+ 0xb8, 0xcf, 0xe6, 0xfd, 0x14, 0x2b, 0x42, 0x59,
+ 0x70, 0x87, 0x9e, 0xb5, 0xcc, 0xe3, 0xfa, 0x11,
+ 0x28, 0x3f, 0x56, 0x6d, 0x84, 0x9b, 0xb2, 0xc9,
+ 0xe0, 0xf7, 0x0e, 0x25, 0x3c, 0x53, 0x6a, 0x81,
+ 0x98, 0xaf, 0xc6, 0xdd, 0xf4, 0x0b, 0x22, 0x39,
+ 0x50, 0x67, 0x7e, 0x95, 0xac, 0xc3, 0xda, 0xf1,
+ 0x08, 0x1f, 0x36, 0x4d, 0x64, 0x7b, 0x92, 0xa9,
+ 0xc0, 0xd7, 0xee, 0x05, 0x1c, 0x33, 0x4a, 0x61,
+ 0x78, 0x8f, 0xa6, 0xbd, 0xd4, 0xeb, 0x02, 0x19,
+ 0x30, 0x47, 0x5e, 0x75, 0x8c, 0xa3, 0xba, 0xd1,
+ 0xe8, 0xff, 0x16, 0x2d, 0x44, 0x5b, 0x72, 0x89,
+ 0xa0, 0xb7, 0xce, 0xe5, 0xfc, 0x13, 0x2a, 0x41,
+ 0x58, 0x6f, 0x86, 0x9d, 0xb4, 0xcb, 0xe2, 0xf9,
+ 0x10, 0x27, 0x3e, 0x55, 0x6c, 0x83, 0x9a, 0xb1,
+ 0xc8, 0xdf, 0xf6, 0x0d, 0x24, 0x3b, 0x52, 0x69,
+ 0x80, 0x97, 0xae, 0xc5, 0xdc, 0xf3, 0x0a, 0x21,
+ 0x38, 0x4f, 0x66, 0x7d, 0x94, 0xab, 0xc2, 0xd9,
+ 0xf0, 0x07, 0x1e, 0x35, 0x4c, 0x63, 0x7a, 0x91,
+ 0xa8, 0xbf, 0xd6, 0xed, 0x04, 0x1b, 0x32, 0x49,
+ 0x60, 0x77, 0x8e, 0xa5, 0xbc, 0xd3, 0xea, 0x01,
+ 0x18, 0x2f, 0x46, 0x5d, 0x74, 0x8b, 0xa2, 0xb9,
+ 0xd0, 0xe7, 0xfe, 0x15, 0x2c, 0x43, 0x5a, 0x71,
+ 0x88, 0x9f, 0xb6, 0xcd, 0xe4, 0xfb, 0x12, 0x29,
+ 0x40, 0x57, 0x6e, 0x85, 0x9c, 0xb3, 0xca, 0xe1,
+ 0xf8, 0x0f, 0x26, 0x3d, 0x54, 0x6b, 0x82, 0x99,
+ 0xb0, 0xc7, 0xde, 0xf5, 0x0c, 0x23, 0x3a, 0x51,
+ 0x68, 0x7f, 0x96, 0xad, 0xc4, 0xdb, 0xf2, 0x09,
+ 0x20, 0x37, 0x4e, 0x65, 0x7c, 0x93, 0xaa, 0xc1,
+ 0xd8, 0xef, 0x06, 0x1d, 0x34, 0x4b, 0x62, 0x79,
+ 0x90, 0xa7, 0xbe, 0xd5, 0xec, 0x03, 0x1a, 0x31,
+ 0x48, 0x5f, 0x76, 0x8d, 0xa4, 0xbb, 0xd2, 0xe9,
+ 0x00, 0x19, 0x32, 0x4b, 0x64, 0x7d, 0x96, 0xaf,
+ 0xc8, 0xe1, 0xfa, 0x13, 0x2c, 0x45, 0x5e, 0x77,
+ 0x90, 0xa9, 0xc2, 0xdb, 0xf4, 0x0d, 0x26, 0x3f,
+ 0x58, 0x71, 0x8a, 0xa3, 0xbc, 0xd5, 0xee, 0x07,
+ 0x20, 0x39, 0x52, 0x6b, 0x84, 0x9d, 0xb6, 0xcf,
+ 0xe8, 0x01, 0x1a, 0x33, 0x4c, 0x65, 0x7e, 0x97,
+ 0xb0, 0xc9, 0xe2, 0xfb, 0x14, 0x2d, 0x46, 0x5f,
+ 0x78, 0x91, 0xaa, 0xc3, 0xdc, 0xf5, 0x0e, 0x27,
+ 0x40, 0x59, 0x72, 0x8b, 0xa4, 0xbd, 0xd6, 0xef,
+ 0x08, 0x21, 0x3a, 0x53, 0x6c, 0x85, 0x9e, 0xb7,
+ 0xd0, 0xe9, 0x02, 0x1b, 0x34, 0x4d, 0x66, 0x7f,
+ 0x98, 0xb1, 0xca, 0xe3, 0xfc, 0x15, 0x2e, 0x47,
+ 0x60, 0x79, 0x92, 0xab, 0xc4, 0xdd, 0xf6, 0x0f,
+ 0x28, 0x41, 0x5a, 0x73, 0x8c, 0xa5, 0xbe, 0xd7,
+ 0xf0, 0x09, 0x22, 0x3b, 0x54, 0x6d, 0x86, 0x9f,
+ 0xb8, 0xd1, 0xea, 0x03, 0x1c, 0x35, 0x4e, 0x67,
+ 0x80, 0x99, 0xb2, 0xcb, 0xe4, 0xfd, 0x16, 0x2f,
+ 0x48, 0x61, 0x7a, 0x93, 0xac, 0xc5, 0xde, 0xf7,
+ 0x10, 0x29, 0x42, 0x5b, 0x74, 0x8d, 0xa6, 0xbf,
+ 0xd8, 0xf1, 0x0a, 0x23, 0x3c, 0x55, 0x6e, 0x87,
+ 0xa0, 0xb9, 0xd2, 0xeb, 0x04, 0x1d, 0x36, 0x4f,
+ 0x68, 0x81, 0x9a, 0xb3, 0xcc, 0xe5, 0xfe, 0x17,
+ 0x30, 0x49, 0x62, 0x7b, 0x94, 0xad, 0xc6, 0xdf,
+ 0xf8, 0x11, 0x2a, 0x43, 0x5c, 0x75, 0x8e, 0xa7,
+ 0xc0, 0xd9, 0xf2, 0x0b, 0x24, 0x3d, 0x56, 0x6f,
+ 0x88, 0xa1, 0xba, 0xd3, 0xec, 0x05, 0x1e, 0x37,
+ 0x50, 0x69, 0x82, 0x9b, 0xb4, 0xcd, 0xe6, 0xff,
+ 0x18, 0x31, 0x4a, 0x63, 0x7c, 0x95, 0xae, 0xc7,
+ 0xe0, 0xf9, 0x12, 0x2b, 0x44, 0x5d, 0x76, 0x8f,
+ 0xa8, 0xc1, 0xda, 0xf3, 0x0c, 0x25, 0x3e, 0x57,
+ 0x70, 0x89, 0xa2, 0xbb, 0xd4, 0xed, 0x06, 0x1f,
+ 0x38, 0x51, 0x6a, 0x83, 0x9c, 0xb5, 0xce, 0xe7,
+ 0x00, 0x1b, 0x36, 0x51, 0x6c, 0x87, 0xa2, 0xbd,
+ 0xd8, 0xf3, 0x0e, 0x29, 0x44, 0x5f, 0x7a, 0x95,
+ 0xb0, 0xcb, 0xe6, 0x01, 0x1c, 0x37, 0x52, 0x6d,
+ 0x88, 0xa3, 0xbe, 0xd9, 0xf4, 0x0f, 0x2a, 0x45,
+ 0x60, 0x7b, 0x96, 0xb1, 0xcc, 0xe7, 0x02, 0x1d,
+ 0x38, 0x53, 0x6e, 0x89, 0xa4, 0xbf, 0xda, 0xf5,
+ 0x10, 0x2b, 0x46, 0x61, 0x7c, 0x97, 0xb2, 0xcd,
+ 0xe8, 0x03, 0x1e, 0x39, 0x54, 0x6f, 0x8a, 0xa5,
+ 0xc0, 0xdb, 0xf6, 0x11, 0x2c, 0x47, 0x62, 0x7d,
+ 0x98, 0xb3, 0xce, 0xe9, 0x04, 0x1f, 0x3a, 0x55,
+ 0x70, 0x8b, 0xa6, 0xc1, 0xdc, 0xf7, 0x12, 0x2d,
+ 0x48, 0x63, 0x7e, 0x99, 0xb4, 0xcf, 0xea, 0x05,
+ 0x20, 0x3b, 0x56, 0x71, 0x8c, 0xa7, 0xc2, 0xdd,
+ 0xf8, 0x13, 0x2e, 0x49, 0x64, 0x7f, 0x9a, 0xb5,
+ 0xd0, 0xeb, 0x06, 0x21, 0x3c, 0x57, 0x72, 0x8d,
+ 0xa8, 0xc3, 0xde, 0xf9, 0x14, 0x2f, 0x4a, 0x65,
+ 0x80, 0x9b, 0xb6, 0xd1, 0xec, 0x07, 0x22, 0x3d,
+ 0x58, 0x73, 0x8e, 0xa9, 0xc4, 0xdf, 0xfa, 0x15,
+ 0x30, 0x4b, 0x66, 0x81, 0x9c, 0xb7, 0xd2, 0xed,
+ 0x08, 0x23, 0x3e, 0x59, 0x74, 0x8f, 0xaa, 0xc5,
+ 0xe0, 0xfb, 0x16, 0x31, 0x4c, 0x67, 0x82, 0x9d,
+ 0xb8, 0xd3, 0xee, 0x09, 0x24, 0x3f, 0x5a, 0x75,
+ 0x90, 0xab, 0xc6, 0xe1, 0xfc, 0x17, 0x32, 0x4d,
+ 0x68, 0x83, 0x9e, 0xb9, 0xd4, 0xef, 0x0a, 0x25,
+ 0x40, 0x5b, 0x76, 0x91, 0xac, 0xc7, 0xe2, 0xfd,
+ 0x18, 0x33, 0x4e, 0x69, 0x84, 0x9f, 0xba, 0xd5,
+ 0xf0, 0x0b, 0x26, 0x41, 0x5c, 0x77, 0x92, 0xad,
+ 0xc8, 0xe3, 0xfe, 0x19, 0x34, 0x4f, 0x6a, 0x85,
+ 0xa0, 0xbb, 0xd6, 0xf1, 0x0c, 0x27, 0x42, 0x5d,
+ 0x78, 0x93, 0xae, 0xc9, 0xe4, 0xff, 0x1a, 0x35,
+ 0x50, 0x6b, 0x86, 0xa1, 0xbc, 0xd7, 0xf2, 0x0d,
+ 0x28, 0x43, 0x5e, 0x79, 0x94, 0xaf, 0xca, 0xe5,
+ 0x00, 0x1d, 0x3a, 0x57, 0x74, 0x91, 0xae, 0xcb,
+ 0xe8, 0x05, 0x22, 0x3f, 0x5c, 0x79, 0x96, 0xb3,
+ 0xd0, 0xed, 0x0a, 0x27, 0x44, 0x61, 0x7e, 0x9b,
+ 0xb8, 0xd5, 0xf2, 0x0f, 0x2c, 0x49, 0x66, 0x83,
+ 0xa0, 0xbd, 0xda, 0xf7, 0x14, 0x31, 0x4e, 0x6b,
+ 0x88, 0xa5, 0xc2, 0xdf, 0xfc, 0x19, 0x36, 0x53,
+ 0x70, 0x8d, 0xaa, 0xc7, 0xe4, 0x01, 0x1e, 0x3b,
+ 0x58, 0x75, 0x92, 0xaf, 0xcc, 0xe9, 0x06, 0x23,
+ 0x40, 0x5d, 0x7a, 0x97, 0xb4, 0xd1, 0xee, 0x0b,
+ 0x28, 0x45, 0x62, 0x7f, 0x9c, 0xb9, 0xd6, 0xf3,
+ 0x10, 0x2d, 0x4a, 0x67, 0x84, 0xa1, 0xbe, 0xdb,
+ 0xf8, 0x15, 0x32, 0x4f, 0x6c, 0x89, 0xa6, 0xc3,
+ 0xe0, 0xfd, 0x1a, 0x37, 0x54, 0x71, 0x8e, 0xab,
+ 0xc8, 0xe5, 0x02, 0x1f, 0x3c, 0x59, 0x76, 0x93,
+ 0xb0, 0xcd, 0xea, 0x07, 0x24, 0x41, 0x5e, 0x7b,
+ 0x98, 0xb5, 0xd2, 0xef, 0x0c, 0x29, 0x46, 0x63,
+ 0x80, 0x9d, 0xba, 0xd7, 0xf4, 0x11, 0x2e, 0x4b,
+ 0x68, 0x85, 0xa2, 0xbf, 0xdc, 0xf9, 0x16, 0x33,
+ 0x50, 0x6d, 0x8a, 0xa7, 0xc4, 0xe1, 0xfe, 0x1b,
+ 0x38, 0x55, 0x72, 0x8f, 0xac, 0xc9, 0xe6, 0x03,
+ 0x20, 0x3d, 0x5a, 0x77, 0x94, 0xb1, 0xce, 0xeb,
+ 0x08, 0x25, 0x42, 0x5f, 0x7c, 0x99, 0xb6, 0xd3,
+ 0xf0, 0x0d, 0x2a, 0x47, 0x64, 0x81, 0x9e, 0xbb,
+ 0xd8, 0xf5, 0x12, 0x2f, 0x4c, 0x69, 0x86, 0xa3,
+ 0xc0, 0xdd, 0xfa, 0x17, 0x34, 0x51, 0x6e, 0x8b,
+ 0xa8, 0xc5, 0xe2, 0xff, 0x1c, 0x39, 0x56, 0x73,
+ 0x90, 0xad, 0xca, 0xe7, 0x04, 0x21, 0x3e, 0x5b,
+ 0x78, 0x95, 0xb2, 0xcf, 0xec, 0x09, 0x26, 0x43,
+ 0x60, 0x7d, 0x9a, 0xb7, 0xd4, 0xf1, 0x0e, 0x2b,
+ 0x48, 0x65, 0x82, 0x9f, 0xbc, 0xd9, 0xf6, 0x13,
+ 0x30, 0x4d, 0x6a, 0x87, 0xa4, 0xc1, 0xde, 0xfb,
+ 0x18, 0x35, 0x52, 0x6f, 0x8c, 0xa9, 0xc6, 0xe3,
+ 0x00, 0x1f, 0x3e, 0x5d, 0x7c, 0x9b, 0xba, 0xd9,
+ 0xf8, 0x17, 0x36, 0x55, 0x74, 0x93, 0xb2, 0xd1,
+ 0xf0, 0x0f, 0x2e, 0x4d, 0x6c, 0x8b, 0xaa, 0xc9,
+ 0xe8, 0x07, 0x26, 0x45, 0x64, 0x83, 0xa2, 0xc1,
+ 0xe0, 0xff, 0x1e, 0x3d, 0x5c, 0x7b, 0x9a, 0xb9,
+ 0xd8, 0xf7, 0x16, 0x35, 0x54, 0x73, 0x92, 0xb1,
+ 0xd0, 0xef, 0x0e, 0x2d, 0x4c, 0x6b, 0x8a, 0xa9,
+ 0xc8, 0xe7, 0x06, 0x25, 0x44, 0x63, 0x82, 0xa1,
+ 0xc0, 0xdf, 0xfe, 0x1d, 0x3c, 0x5b, 0x7a, 0x99,
+ 0xb8, 0xd7, 0xf6, 0x15, 0x34, 0x53, 0x72, 0x91,
+ 0xb0, 0xcf, 0xee, 0x0d, 0x2c, 0x4b, 0x6a, 0x89,
+ 0xa8, 0xc7, 0xe6, 0x05, 0x24, 0x43, 0x62, 0x81,
+ 0xa0, 0xbf, 0xde, 0xfd, 0x1c, 0x3b, 0x5a, 0x79,
+ 0x98, 0xb7, 0xd6, 0xf5, 0x14, 0x33, 0x52, 0x71,
+ 0x90, 0xaf, 0xce, 0xed, 0x0c, 0x2b, 0x4a, 0x69,
+ 0x88, 0xa7, 0xc6, 0xe5, 0x04, 0x23, 0x42, 0x61,
+ 0x80, 0x9f, 0xbe, 0xdd, 0xfc, 0x1b, 0x3a, 0x59,
+ 0x78, 0x97, 0xb6, 0xd5, 0xf4, 0x13, 0x32, 0x51,
+ 0x70, 0x8f, 0xae, 0xcd, 0xec, 0x0b, 0x2a, 0x49,
+ 0x68, 0x87, 0xa6, 0xc5, 0xe4, 0x03, 0x22, 0x41,
+ 0x60, 0x7f, 0x9e, 0xbd, 0xdc, 0xfb, 0x1a, 0x39,
+ 0x58, 0x77, 0x96, 0xb5, 0xd4, 0xf3, 0x12, 0x31,
+ 0x50, 0x6f, 0x8e, 0xad, 0xcc, 0xeb, 0x0a, 0x29,
+ 0x48, 0x67, 0x86, 0xa5, 0xc4, 0xe3, 0x02, 0x21,
+ 0x40, 0x5f, 0x7e, 0x9d, 0xbc, 0xdb, 0xfa, 0x19,
+ 0x38, 0x57, 0x76, 0x95, 0xb4, 0xd3, 0xf2, 0x11,
+ 0x30, 0x4f, 0x6e, 0x8d, 0xac, 0xcb, 0xea, 0x09,
+ 0x28, 0x47, 0x66, 0x85, 0xa4, 0xc3, 0xe2, 0x01,
+ 0x20, 0x3f, 0x5e, 0x7d, 0x9c, 0xbb, 0xda, 0xf9,
+ 0x18, 0x37, 0x56, 0x75, 0x94, 0xb3, 0xd2, 0xf1,
+ 0x10, 0x2f, 0x4e, 0x6d, 0x8c, 0xab, 0xca, 0xe9,
+ 0x08, 0x27, 0x46, 0x65, 0x84, 0xa3, 0xc2, 0xe1,
+ 0x00, 0x21, 0x42, 0x63,
+ },
+ .ilen = 4100,
+ .result = {
+ 0xb5, 0x81, 0xf5, 0x64, 0x18, 0x73, 0xe3, 0xf0,
+ 0x4c, 0x13, 0xf2, 0x77, 0x18, 0x60, 0x65, 0x5e,
+ 0x29, 0x01, 0xce, 0x98, 0x55, 0x53, 0xf9, 0x0c,
+ 0x2a, 0x08, 0xd5, 0x09, 0xb3, 0x57, 0x55, 0x56,
+ 0xc5, 0xe9, 0x56, 0x90, 0xcb, 0x6a, 0xa3, 0xc0,
+ 0xff, 0xc4, 0x79, 0xb4, 0xd2, 0x97, 0x5d, 0xc4,
+ 0x43, 0xd1, 0xfe, 0x94, 0x7b, 0x88, 0x06, 0x5a,
+ 0xb2, 0x9e, 0x2c, 0xfc, 0x44, 0x03, 0xb7, 0x90,
+ 0xa0, 0xc1, 0xba, 0x6a, 0x33, 0xb8, 0xc7, 0xb2,
+ 0x9d, 0xe1, 0x12, 0x4f, 0xc0, 0x64, 0xd4, 0x01,
+ 0xfe, 0x8c, 0x7a, 0x66, 0xf7, 0xe6, 0x5a, 0x91,
+ 0xbb, 0xde, 0x56, 0x86, 0xab, 0x65, 0x21, 0x30,
+ 0x00, 0x84, 0x65, 0x24, 0xa5, 0x7d, 0x85, 0xb4,
+ 0xe3, 0x17, 0xed, 0x3a, 0xb7, 0x6f, 0xb4, 0x0b,
+ 0x0b, 0xaf, 0x15, 0xae, 0x5a, 0x8f, 0xf2, 0x0c,
+ 0x2f, 0x27, 0xf4, 0x09, 0xd8, 0xd2, 0x96, 0xb7,
+ 0x71, 0xf2, 0xc5, 0x99, 0x4d, 0x7e, 0x7f, 0x75,
+ 0x77, 0x89, 0x30, 0x8b, 0x59, 0xdb, 0xa2, 0xb2,
+ 0xa0, 0xf3, 0x19, 0x39, 0x2b, 0xc5, 0x7e, 0x3f,
+ 0x4f, 0xd9, 0xd3, 0x56, 0x28, 0x97, 0x44, 0xdc,
+ 0xc0, 0x8b, 0x77, 0x24, 0xd9, 0x52, 0xe7, 0xc5,
+ 0xaf, 0xf6, 0x7d, 0x59, 0xb2, 0x44, 0x05, 0x1d,
+ 0xb1, 0xb0, 0x11, 0xa5, 0x0f, 0xec, 0x33, 0xe1,
+ 0x6d, 0x1b, 0x4e, 0x1f, 0xff, 0x57, 0x91, 0xb4,
+ 0x5b, 0x9a, 0x96, 0xc5, 0x53, 0xbc, 0xae, 0x20,
+ 0x3c, 0xbb, 0x14, 0xe2, 0xe8, 0x22, 0x33, 0xc1,
+ 0x5e, 0x76, 0x9e, 0x46, 0x99, 0xf6, 0x2a, 0x15,
+ 0xc6, 0x97, 0x02, 0xa0, 0x66, 0x43, 0xd1, 0xa6,
+ 0x31, 0xa6, 0x9f, 0xfb, 0xf4, 0xd3, 0x69, 0xe5,
+ 0xcd, 0x76, 0x95, 0xb8, 0x7a, 0x82, 0x7f, 0x21,
+ 0x45, 0xff, 0x3f, 0xce, 0x55, 0xf6, 0x95, 0x10,
+ 0x08, 0x77, 0x10, 0x43, 0xc6, 0xf3, 0x09, 0xe5,
+ 0x68, 0xe7, 0x3c, 0xad, 0x00, 0x52, 0x45, 0x0d,
+ 0xfe, 0x2d, 0xc6, 0xc2, 0x94, 0x8c, 0x12, 0x1d,
+ 0xe6, 0x25, 0xae, 0x98, 0x12, 0x8e, 0x19, 0x9c,
+ 0x81, 0x68, 0xb1, 0x11, 0xf6, 0x69, 0xda, 0xe3,
+ 0x62, 0x08, 0x18, 0x7a, 0x25, 0x49, 0x28, 0xac,
+ 0xba, 0x71, 0x12, 0x0b, 0xe4, 0xa2, 0xe5, 0xc7,
+ 0x5d, 0x8e, 0xec, 0x49, 0x40, 0x21, 0xbf, 0x5a,
+ 0x98, 0xf3, 0x02, 0x68, 0x55, 0x03, 0x7f, 0x8a,
+ 0xe5, 0x94, 0x0c, 0x32, 0x5c, 0x07, 0x82, 0x63,
+ 0xaf, 0x6f, 0x91, 0x40, 0x84, 0x8e, 0x52, 0x25,
+ 0xd0, 0xb0, 0x29, 0x53, 0x05, 0xe2, 0x50, 0x7a,
+ 0x34, 0xeb, 0xc9, 0x46, 0x20, 0xa8, 0x3d, 0xde,
+ 0x7f, 0x16, 0x5f, 0x36, 0xc5, 0x2e, 0xdc, 0xd1,
+ 0x15, 0x47, 0xc7, 0x50, 0x40, 0x6d, 0x91, 0xc5,
+ 0xe7, 0x93, 0x95, 0x1a, 0xd3, 0x57, 0xbc, 0x52,
+ 0x33, 0xee, 0x14, 0x19, 0x22, 0x52, 0x89, 0xa7,
+ 0x4a, 0x25, 0x56, 0x77, 0x4b, 0xca, 0xcf, 0x0a,
+ 0xe1, 0xf5, 0x35, 0x85, 0x30, 0x7e, 0x59, 0x4a,
+ 0xbd, 0x14, 0x5b, 0xdf, 0xe3, 0x46, 0xcb, 0xac,
+ 0x1f, 0x6c, 0x96, 0x0e, 0xf4, 0x81, 0xd1, 0x99,
+ 0xca, 0x88, 0x63, 0x3d, 0x02, 0x58, 0x6b, 0xa9,
+ 0xe5, 0x9f, 0xb3, 0x00, 0xb2, 0x54, 0xc6, 0x74,
+ 0x1c, 0xbf, 0x46, 0xab, 0x97, 0xcc, 0xf8, 0x54,
+ 0x04, 0x07, 0x08, 0x52, 0xe6, 0xc0, 0xda, 0x93,
+ 0x74, 0x7d, 0x93, 0x99, 0x5d, 0x78, 0x68, 0xa6,
+ 0x2e, 0x6b, 0xd3, 0x6a, 0x69, 0xcc, 0x12, 0x6b,
+ 0xd4, 0xc7, 0xa5, 0xc6, 0xe7, 0xf6, 0x03, 0x04,
+ 0x5d, 0xcd, 0x61, 0x5e, 0x17, 0x40, 0xdc, 0xd1,
+ 0x5c, 0xf5, 0x08, 0xdf, 0x5c, 0x90, 0x85, 0xa4,
+ 0xaf, 0xf6, 0x78, 0xbb, 0x0d, 0xf1, 0xf4, 0xa4,
+ 0x54, 0x26, 0x72, 0x9e, 0x61, 0xfa, 0x86, 0xcf,
+ 0xe8, 0x9e, 0xa1, 0xe0, 0xc7, 0x48, 0x23, 0xae,
+ 0x5a, 0x90, 0xae, 0x75, 0x0a, 0x74, 0x18, 0x89,
+ 0x05, 0xb1, 0x92, 0xb2, 0x7f, 0xd0, 0x1b, 0xa6,
+ 0x62, 0x07, 0x25, 0x01, 0xc7, 0xc2, 0x4f, 0xf9,
+ 0xe8, 0xfe, 0x63, 0x95, 0x80, 0x07, 0xb4, 0x26,
+ 0xcc, 0xd1, 0x26, 0xb6, 0xc4, 0x3f, 0x9e, 0xcb,
+ 0x8e, 0x3b, 0x2e, 0x44, 0x16, 0xd3, 0x10, 0x9a,
+ 0x95, 0x08, 0xeb, 0xc8, 0xcb, 0xeb, 0xbf, 0x6f,
+ 0x0b, 0xcd, 0x1f, 0xc8, 0xca, 0x86, 0xaa, 0xec,
+ 0x33, 0xe6, 0x69, 0xf4, 0x45, 0x25, 0x86, 0x3a,
+ 0x22, 0x94, 0x4f, 0x00, 0x23, 0x6a, 0x44, 0xc2,
+ 0x49, 0x97, 0x33, 0xab, 0x36, 0x14, 0x0a, 0x70,
+ 0x24, 0xc3, 0xbe, 0x04, 0x3b, 0x79, 0xa0, 0xf9,
+ 0xb8, 0xe7, 0x76, 0x29, 0x22, 0x83, 0xd7, 0xf2,
+ 0x94, 0xf4, 0x41, 0x49, 0xba, 0x5f, 0x7b, 0x07,
+ 0xb5, 0xfb, 0xdb, 0x03, 0x1a, 0x9f, 0xb6, 0x4c,
+ 0xc2, 0x2e, 0x37, 0x40, 0x49, 0xc3, 0x38, 0x16,
+ 0xe2, 0x4f, 0x77, 0x82, 0xb0, 0x68, 0x4c, 0x71,
+ 0x1d, 0x57, 0x61, 0x9c, 0xd9, 0x4e, 0x54, 0x99,
+ 0x47, 0x13, 0x28, 0x73, 0x3c, 0xbb, 0x00, 0x90,
+ 0xf3, 0x4d, 0xc9, 0x0e, 0xfd, 0xe7, 0xb1, 0x71,
+ 0xd3, 0x15, 0x79, 0xbf, 0xcc, 0x26, 0x2f, 0xbd,
+ 0xad, 0x6c, 0x50, 0x69, 0x6c, 0x3e, 0x6d, 0x80,
+ 0x9a, 0xea, 0x78, 0xaf, 0x19, 0xb2, 0x0d, 0x4d,
+ 0xad, 0x04, 0x07, 0xae, 0x22, 0x90, 0x4a, 0x93,
+ 0x32, 0x0e, 0x36, 0x9b, 0x1b, 0x46, 0xba, 0x3b,
+ 0xb4, 0xac, 0xc6, 0xd1, 0xa2, 0x31, 0x53, 0x3b,
+ 0x2a, 0x3d, 0x45, 0xfe, 0x03, 0x61, 0x10, 0x85,
+ 0x17, 0x69, 0xa6, 0x78, 0xcc, 0x6c, 0x87, 0x49,
+ 0x53, 0xf9, 0x80, 0x10, 0xde, 0x80, 0xa2, 0x41,
+ 0x6a, 0xc3, 0x32, 0x02, 0xad, 0x6d, 0x3c, 0x56,
+ 0x00, 0x71, 0x51, 0x06, 0xa7, 0xbd, 0xfb, 0xef,
+ 0x3c, 0xb5, 0x9f, 0xfc, 0x48, 0x7d, 0x53, 0x7c,
+ 0x66, 0xb0, 0x49, 0x23, 0xc4, 0x47, 0x10, 0x0e,
+ 0xe5, 0x6c, 0x74, 0x13, 0xe6, 0xc5, 0x3f, 0xaa,
+ 0xde, 0xff, 0x07, 0x44, 0xdd, 0x56, 0x1b, 0xad,
+ 0x09, 0x77, 0xfb, 0x5b, 0x12, 0xb8, 0x0d, 0x38,
+ 0x17, 0x37, 0x35, 0x7b, 0x9b, 0xbc, 0xfe, 0xd4,
+ 0x7e, 0x8b, 0xda, 0x7e, 0x5b, 0x04, 0xa7, 0x22,
+ 0xa7, 0x31, 0xa1, 0x20, 0x86, 0xc7, 0x1b, 0x99,
+ 0xdb, 0xd1, 0x89, 0xf4, 0x94, 0xa3, 0x53, 0x69,
+ 0x8d, 0xe7, 0xe8, 0x74, 0x11, 0x8d, 0x74, 0xd6,
+ 0x07, 0x37, 0x91, 0x9f, 0xfd, 0x67, 0x50, 0x3a,
+ 0xc9, 0xe1, 0xf4, 0x36, 0xd5, 0xa0, 0x47, 0xd1,
+ 0xf9, 0xe5, 0x39, 0xa3, 0x31, 0xac, 0x07, 0x36,
+ 0x23, 0xf8, 0x66, 0x18, 0x14, 0x28, 0x34, 0x0f,
+ 0xb8, 0xd0, 0xe7, 0x29, 0xb3, 0x04, 0x4b, 0x55,
+ 0x01, 0x41, 0xb2, 0x75, 0x8d, 0xcb, 0x96, 0x85,
+ 0x3a, 0xfb, 0xab, 0x2b, 0x9e, 0xfa, 0x58, 0x20,
+ 0x44, 0x1f, 0xc0, 0x14, 0x22, 0x75, 0x61, 0xe8,
+ 0xaa, 0x19, 0xcf, 0xf1, 0x82, 0x56, 0xf4, 0xd7,
+ 0x78, 0x7b, 0x3d, 0x5f, 0xb3, 0x9e, 0x0b, 0x8a,
+ 0x57, 0x50, 0xdb, 0x17, 0x41, 0x65, 0x4d, 0xa3,
+ 0x02, 0xc9, 0x9c, 0x9c, 0x53, 0xfb, 0x39, 0x39,
+ 0x9b, 0x1d, 0x72, 0x24, 0xda, 0xb7, 0x39, 0xbe,
+ 0x13, 0x3b, 0xfa, 0x29, 0xda, 0x9e, 0x54, 0x64,
+ 0x6e, 0xba, 0xd8, 0xa1, 0xcb, 0xb3, 0x36, 0xfa,
+ 0xcb, 0x47, 0x85, 0xe9, 0x61, 0x38, 0xbc, 0xbe,
+ 0xc5, 0x00, 0x38, 0x2a, 0x54, 0xf7, 0xc4, 0xb9,
+ 0xb3, 0xd3, 0x7b, 0xa0, 0xa0, 0xf8, 0x72, 0x7f,
+ 0x8c, 0x8e, 0x82, 0x0e, 0xc6, 0x1c, 0x75, 0x9d,
+ 0xca, 0x8e, 0x61, 0x87, 0xde, 0xad, 0x80, 0xd2,
+ 0xf5, 0xf9, 0x80, 0xef, 0x15, 0x75, 0xaf, 0xf5,
+ 0x80, 0xfb, 0xff, 0x6d, 0x1e, 0x25, 0xb7, 0x40,
+ 0x61, 0x6a, 0x39, 0x5a, 0x6a, 0xb5, 0x31, 0xab,
+ 0x97, 0x8a, 0x19, 0x89, 0x44, 0x40, 0xc0, 0xa6,
+ 0xb4, 0x4e, 0x30, 0x32, 0x7b, 0x13, 0xe7, 0x67,
+ 0xa9, 0x8b, 0x57, 0x04, 0xc2, 0x01, 0xa6, 0xf4,
+ 0x28, 0x99, 0xad, 0x2c, 0x76, 0xa3, 0x78, 0xc2,
+ 0x4a, 0xe6, 0xca, 0x5c, 0x50, 0x6a, 0xc1, 0xb0,
+ 0x62, 0x4b, 0x10, 0x8e, 0x7c, 0x17, 0x43, 0xb3,
+ 0x17, 0x66, 0x1c, 0x3e, 0x8d, 0x69, 0xf0, 0x5a,
+ 0x71, 0xf5, 0x97, 0xdc, 0xd1, 0x45, 0xdd, 0x28,
+ 0xf3, 0x5d, 0xdf, 0x53, 0x7b, 0x11, 0xe5, 0xbc,
+ 0x4c, 0xdb, 0x1b, 0x51, 0x6b, 0xe9, 0xfb, 0x3d,
+ 0xc1, 0xc3, 0x2c, 0xb9, 0x71, 0xf5, 0xb6, 0xb2,
+ 0x13, 0x36, 0x79, 0x80, 0x53, 0xe8, 0xd3, 0xa6,
+ 0x0a, 0xaf, 0xfd, 0x56, 0x97, 0xf7, 0x40, 0x8e,
+ 0x45, 0xce, 0xf8, 0xb0, 0x9e, 0x5c, 0x33, 0x82,
+ 0xb0, 0x44, 0x56, 0xfc, 0x05, 0x09, 0xe9, 0x2a,
+ 0xac, 0x26, 0x80, 0x14, 0x1d, 0xc8, 0x3a, 0x35,
+ 0x4c, 0x82, 0x97, 0xfd, 0x76, 0xb7, 0xa9, 0x0a,
+ 0x35, 0x58, 0x79, 0x8e, 0x0f, 0x66, 0xea, 0xaf,
+ 0x51, 0x6c, 0x09, 0xa9, 0x6e, 0x9b, 0xcb, 0x9a,
+ 0x31, 0x47, 0xa0, 0x2f, 0x7c, 0x71, 0xb4, 0x4a,
+ 0x11, 0xaa, 0x8c, 0x66, 0xc5, 0x64, 0xe6, 0x3a,
+ 0x54, 0xda, 0x24, 0x6a, 0xc4, 0x41, 0x65, 0x46,
+ 0x82, 0xa0, 0x0a, 0x0f, 0x5f, 0xfb, 0x25, 0xd0,
+ 0x2c, 0x91, 0xa7, 0xee, 0xc4, 0x81, 0x07, 0x86,
+ 0x75, 0x5e, 0x33, 0x69, 0x97, 0xe4, 0x2c, 0xa8,
+ 0x9d, 0x9f, 0x0b, 0x6a, 0xbe, 0xad, 0x98, 0xda,
+ 0x6d, 0x94, 0x41, 0xda, 0x2c, 0x1e, 0x89, 0xc4,
+ 0xc2, 0xaf, 0x1e, 0x00, 0x05, 0x0b, 0x83, 0x60,
+ 0xbd, 0x43, 0xea, 0x15, 0x23, 0x7f, 0xb9, 0xac,
+ 0xee, 0x4f, 0x2c, 0xaf, 0x2a, 0xf3, 0xdf, 0xd0,
+ 0xf3, 0x19, 0x31, 0xbb, 0x4a, 0x74, 0x84, 0x17,
+ 0x52, 0x32, 0x2c, 0x7d, 0x61, 0xe4, 0xcb, 0xeb,
+ 0x80, 0x38, 0x15, 0x52, 0xcb, 0x6f, 0xea, 0xe5,
+ 0x73, 0x9c, 0xd9, 0x24, 0x69, 0xc6, 0x95, 0x32,
+ 0x21, 0xc8, 0x11, 0xe4, 0xdc, 0x36, 0xd7, 0x93,
+ 0x38, 0x66, 0xfb, 0xb2, 0x7f, 0x3a, 0xb9, 0xaf,
+ 0x31, 0xdd, 0x93, 0x75, 0x78, 0x8a, 0x2c, 0x94,
+ 0x87, 0x1a, 0x58, 0xec, 0x9e, 0x7d, 0x4d, 0xba,
+ 0xe1, 0xe5, 0x4d, 0xfc, 0xbc, 0xa4, 0x2a, 0x14,
+ 0xef, 0xcc, 0xa7, 0xec, 0xab, 0x43, 0x09, 0x18,
+ 0xd3, 0xab, 0x68, 0xd1, 0x07, 0x99, 0x44, 0x47,
+ 0xd6, 0x83, 0x85, 0x3b, 0x30, 0xea, 0xa9, 0x6b,
+ 0x63, 0xea, 0xc4, 0x07, 0xfb, 0x43, 0x2f, 0xa4,
+ 0xaa, 0xb0, 0xab, 0x03, 0x89, 0xce, 0x3f, 0x8c,
+ 0x02, 0x7c, 0x86, 0x54, 0xbc, 0x88, 0xaf, 0x75,
+ 0xd2, 0xdc, 0x63, 0x17, 0xd3, 0x26, 0xf6, 0x96,
+ 0xa9, 0x3c, 0xf1, 0x61, 0x8c, 0x11, 0x18, 0xcc,
+ 0xd6, 0xea, 0x5b, 0xe2, 0xcd, 0xf0, 0xf1, 0xb2,
+ 0xe5, 0x35, 0x90, 0x1f, 0x85, 0x4c, 0x76, 0x5b,
+ 0x66, 0xce, 0x44, 0xa4, 0x32, 0x9f, 0xe6, 0x7b,
+ 0x71, 0x6e, 0x9f, 0x58, 0x15, 0x67, 0x72, 0x87,
+ 0x64, 0x8e, 0x3a, 0x44, 0x45, 0xd4, 0x76, 0xfa,
+ 0xc2, 0xf6, 0xef, 0x85, 0x05, 0x18, 0x7a, 0x9b,
+ 0xba, 0x41, 0x54, 0xac, 0xf0, 0xfc, 0x59, 0x12,
+ 0x3f, 0xdf, 0xa0, 0xe5, 0x8a, 0x65, 0xfd, 0x3a,
+ 0x62, 0x8d, 0x83, 0x2c, 0x03, 0xbe, 0x05, 0x76,
+ 0x2e, 0x53, 0x49, 0x97, 0x94, 0x33, 0xae, 0x40,
+ 0x81, 0x15, 0xdb, 0x6e, 0xad, 0xaa, 0xf5, 0x4b,
+ 0xe3, 0x98, 0x70, 0xdf, 0xe0, 0x7c, 0xcd, 0xdb,
+ 0x02, 0xd4, 0x7d, 0x2f, 0xc1, 0xe6, 0xb4, 0xf3,
+ 0xd7, 0x0d, 0x7a, 0xd9, 0x23, 0x9e, 0x87, 0x2d,
+ 0xce, 0x87, 0xad, 0xcc, 0x72, 0x05, 0x00, 0x29,
+ 0xdc, 0x73, 0x7f, 0x64, 0xc1, 0x15, 0x0e, 0xc2,
+ 0xdf, 0xa7, 0x5f, 0xeb, 0x41, 0xa1, 0xcd, 0xef,
+ 0x5c, 0x50, 0x79, 0x2a, 0x56, 0x56, 0x71, 0x8c,
+ 0xac, 0xc0, 0x79, 0x50, 0x69, 0xca, 0x59, 0x32,
+ 0x65, 0xf2, 0x54, 0xe4, 0x52, 0x38, 0x76, 0xd1,
+ 0x5e, 0xde, 0x26, 0x9e, 0xfb, 0x75, 0x2e, 0x11,
+ 0xb5, 0x10, 0xf4, 0x17, 0x73, 0xf5, 0x89, 0xc7,
+ 0x4f, 0x43, 0x5c, 0x8e, 0x7c, 0xb9, 0x05, 0x52,
+ 0x24, 0x40, 0x99, 0xfe, 0x9b, 0x85, 0x0b, 0x6c,
+ 0x22, 0x3e, 0x8b, 0xae, 0x86, 0xa1, 0xd2, 0x79,
+ 0x05, 0x68, 0x6b, 0xab, 0xe3, 0x41, 0x49, 0xed,
+ 0x15, 0xa1, 0x8d, 0x40, 0x2d, 0x61, 0xdf, 0x1a,
+ 0x59, 0xc9, 0x26, 0x8b, 0xef, 0x30, 0x4c, 0x88,
+ 0x4b, 0x10, 0xf8, 0x8d, 0xa6, 0x92, 0x9f, 0x4b,
+ 0xf3, 0xc4, 0x53, 0x0b, 0x89, 0x5d, 0x28, 0x92,
+ 0xcf, 0x78, 0xb2, 0xc0, 0x5d, 0xed, 0x7e, 0xfc,
+ 0xc0, 0x12, 0x23, 0x5f, 0x5a, 0x78, 0x86, 0x43,
+ 0x6e, 0x27, 0xf7, 0x5a, 0xa7, 0x6a, 0xed, 0x19,
+ 0x04, 0xf0, 0xb3, 0x12, 0xd1, 0xbd, 0x0e, 0x89,
+ 0x6e, 0xbc, 0x96, 0xa8, 0xd8, 0x49, 0x39, 0x9f,
+ 0x7e, 0x67, 0xf0, 0x2e, 0x3e, 0x01, 0xa9, 0xba,
+ 0xec, 0x8b, 0x62, 0x8e, 0xcb, 0x4a, 0x70, 0x43,
+ 0xc7, 0xc2, 0xc4, 0xca, 0x82, 0x03, 0x73, 0xe9,
+ 0x11, 0xdf, 0xcf, 0x54, 0xea, 0xc9, 0xb0, 0x95,
+ 0x51, 0xc0, 0x13, 0x3d, 0x92, 0x05, 0xfa, 0xf4,
+ 0xa9, 0x34, 0xc8, 0xce, 0x6c, 0x3d, 0x54, 0xcc,
+ 0xc4, 0xaf, 0xf1, 0xdc, 0x11, 0x44, 0x26, 0xa2,
+ 0xaf, 0xf1, 0x85, 0x75, 0x7d, 0x03, 0x61, 0x68,
+ 0x4e, 0x78, 0xc6, 0x92, 0x7d, 0x86, 0x7d, 0x77,
+ 0xdc, 0x71, 0x72, 0xdb, 0xc6, 0xae, 0xa1, 0xcb,
+ 0x70, 0x9a, 0x0b, 0x19, 0xbe, 0x4a, 0x6c, 0x2a,
+ 0xe2, 0xba, 0x6c, 0x64, 0x9a, 0x13, 0x28, 0xdf,
+ 0x85, 0x75, 0xe6, 0x43, 0xf6, 0x87, 0x08, 0x68,
+ 0x6e, 0xba, 0x6e, 0x79, 0x9f, 0x04, 0xbc, 0x23,
+ 0x50, 0xf6, 0x33, 0x5c, 0x1f, 0x24, 0x25, 0xbe,
+ 0x33, 0x47, 0x80, 0x45, 0x56, 0xa3, 0xa7, 0xd7,
+ 0x7a, 0xb1, 0x34, 0x0b, 0x90, 0x3c, 0x9c, 0xad,
+ 0x44, 0x5f, 0x9e, 0x0e, 0x9d, 0xd4, 0xbd, 0x93,
+ 0x5e, 0xfa, 0x3c, 0xe0, 0xb0, 0xd9, 0xed, 0xf3,
+ 0xd6, 0x2e, 0xff, 0x24, 0xd8, 0x71, 0x6c, 0xed,
+ 0xaf, 0x55, 0xeb, 0x22, 0xac, 0x93, 0x68, 0x32,
+ 0x05, 0x5b, 0x47, 0xdd, 0xc6, 0x4a, 0xcb, 0xc7,
+ 0x10, 0xe1, 0x3c, 0x92, 0x1a, 0xf3, 0x23, 0x78,
+ 0x2b, 0xa1, 0xd2, 0x80, 0xf4, 0x12, 0xb1, 0x20,
+ 0x8f, 0xff, 0x26, 0x35, 0xdd, 0xfb, 0xc7, 0x4e,
+ 0x78, 0xf1, 0x2d, 0x50, 0x12, 0x77, 0xa8, 0x60,
+ 0x7c, 0x0f, 0xf5, 0x16, 0x2f, 0x63, 0x70, 0x2a,
+ 0xc0, 0x96, 0x80, 0x4e, 0x0a, 0xb4, 0x93, 0x35,
+ 0x5d, 0x1d, 0x3f, 0x56, 0xf7, 0x2f, 0xbb, 0x90,
+ 0x11, 0x16, 0x8f, 0xa2, 0xec, 0x47, 0xbe, 0xac,
+ 0x56, 0x01, 0x26, 0x56, 0xb1, 0x8c, 0xb2, 0x10,
+ 0xf9, 0x1a, 0xca, 0xf5, 0xd1, 0xb7, 0x39, 0x20,
+ 0x63, 0xf1, 0x69, 0x20, 0x4f, 0x13, 0x12, 0x1f,
+ 0x5b, 0x65, 0xfc, 0x98, 0xf7, 0xc4, 0x7a, 0xbe,
+ 0xf7, 0x26, 0x4d, 0x2b, 0x84, 0x7b, 0x42, 0xad,
+ 0xd8, 0x7a, 0x0a, 0xb4, 0xd8, 0x74, 0xbf, 0xc1,
+ 0xf0, 0x6e, 0xb4, 0x29, 0xa3, 0xbb, 0xca, 0x46,
+ 0x67, 0x70, 0x6a, 0x2d, 0xce, 0x0e, 0xa2, 0x8a,
+ 0xa9, 0x87, 0xbf, 0x05, 0xc4, 0xc1, 0x04, 0xa3,
+ 0xab, 0xd4, 0x45, 0x43, 0x8c, 0xb6, 0x02, 0xb0,
+ 0x41, 0xc8, 0xfc, 0x44, 0x3d, 0x59, 0xaa, 0x2e,
+ 0x44, 0x21, 0x2a, 0x8d, 0x88, 0x9d, 0x57, 0xf4,
+ 0xa0, 0x02, 0x77, 0xb8, 0xa6, 0xa0, 0xe6, 0x75,
+ 0x5c, 0x82, 0x65, 0x3e, 0x03, 0x5c, 0x29, 0x8f,
+ 0x38, 0x55, 0xab, 0x33, 0x26, 0xef, 0x9f, 0x43,
+ 0x52, 0xfd, 0x68, 0xaf, 0x36, 0xb4, 0xbb, 0x9a,
+ 0x58, 0x09, 0x09, 0x1b, 0xc3, 0x65, 0x46, 0x46,
+ 0x1d, 0xa7, 0x94, 0x18, 0x23, 0x50, 0x2c, 0xca,
+ 0x2c, 0x55, 0x19, 0x97, 0x01, 0x9d, 0x93, 0x3b,
+ 0x63, 0x86, 0xf2, 0x03, 0x67, 0x45, 0xd2, 0x72,
+ 0x28, 0x52, 0x6c, 0xf4, 0xe3, 0x1c, 0xb5, 0x11,
+ 0x13, 0xf1, 0xeb, 0x21, 0xc7, 0xd9, 0x56, 0x82,
+ 0x2b, 0x82, 0x39, 0xbd, 0x69, 0x54, 0xed, 0x62,
+ 0xc3, 0xe2, 0xde, 0x73, 0xd4, 0x6a, 0x12, 0xae,
+ 0x13, 0x21, 0x7f, 0x4b, 0x5b, 0xfc, 0xbf, 0xe8,
+ 0x2b, 0xbe, 0x56, 0xba, 0x68, 0x8b, 0x9a, 0xb1,
+ 0x6e, 0xfa, 0xbf, 0x7e, 0x5a, 0x4b, 0xf1, 0xac,
+ 0x98, 0x65, 0x85, 0xd1, 0x93, 0x53, 0xd3, 0x7b,
+ 0x09, 0xdd, 0x4b, 0x10, 0x6d, 0x84, 0xb0, 0x13,
+ 0x65, 0xbd, 0xcf, 0x52, 0x09, 0xc4, 0x85, 0xe2,
+ 0x84, 0x74, 0x15, 0x65, 0xb7, 0xf7, 0x51, 0xaf,
+ 0x55, 0xad, 0xa4, 0xd1, 0x22, 0x54, 0x70, 0x94,
+ 0xa0, 0x1c, 0x90, 0x41, 0xfd, 0x99, 0xd7, 0x5a,
+ 0x31, 0xef, 0xaa, 0x25, 0xd0, 0x7f, 0x4f, 0xea,
+ 0x1d, 0x55, 0x42, 0xe5, 0x49, 0xb0, 0xd0, 0x46,
+ 0x62, 0x36, 0x43, 0xb2, 0x82, 0x15, 0x75, 0x50,
+ 0xa4, 0x72, 0xeb, 0x54, 0x27, 0x1f, 0x8a, 0xe4,
+ 0x7d, 0xe9, 0x66, 0xc5, 0xf1, 0x53, 0xa4, 0xd1,
+ 0x0c, 0xeb, 0xb8, 0xf8, 0xbc, 0xd4, 0xe2, 0xe7,
+ 0xe1, 0xf8, 0x4b, 0xcb, 0xa9, 0xa1, 0xaf, 0x15,
+ 0x83, 0xcb, 0x72, 0xd0, 0x33, 0x79, 0x00, 0x2d,
+ 0x9f, 0xd7, 0xf1, 0x2e, 0x1e, 0x10, 0xe4, 0x45,
+ 0xc0, 0x75, 0x3a, 0x39, 0xea, 0x68, 0xf7, 0x5d,
+ 0x1b, 0x73, 0x8f, 0xe9, 0x8e, 0x0f, 0x72, 0x47,
+ 0xae, 0x35, 0x0a, 0x31, 0x7a, 0x14, 0x4d, 0x4a,
+ 0x6f, 0x47, 0xf7, 0x7e, 0x91, 0x6e, 0x74, 0x8b,
+ 0x26, 0x47, 0xf9, 0xc3, 0xf9, 0xde, 0x70, 0xf5,
+ 0x61, 0xab, 0xa9, 0x27, 0x9f, 0x82, 0xe4, 0x9c,
+ 0x89, 0x91, 0x3f, 0x2e, 0x6a, 0xfd, 0xb5, 0x49,
+ 0xe9, 0xfd, 0x59, 0x14, 0x36, 0x49, 0x40, 0x6d,
+ 0x32, 0xd8, 0x85, 0x42, 0xf3, 0xa5, 0xdf, 0x0c,
+ 0xa8, 0x27, 0xd7, 0x54, 0xe2, 0x63, 0x2f, 0xf2,
+ 0x7e, 0x8b, 0x8b, 0xe7, 0xf1, 0x9a, 0x95, 0x35,
+ 0x43, 0xdc, 0x3a, 0xe4, 0xb6, 0xf4, 0xd0, 0xdf,
+ 0x9c, 0xcb, 0x94, 0xf3, 0x21, 0xa0, 0x77, 0x50,
+ 0xe2, 0xc6, 0xc4, 0xc6, 0x5f, 0x09, 0x64, 0x5b,
+ 0x92, 0x90, 0xd8, 0xe1, 0xd1, 0xed, 0x4b, 0x42,
+ 0xd7, 0x37, 0xaf, 0x65, 0x3d, 0x11, 0x39, 0xb6,
+ 0x24, 0x8a, 0x60, 0xae, 0xd6, 0x1e, 0xbf, 0x0e,
+ 0x0d, 0xd7, 0xdc, 0x96, 0x0e, 0x65, 0x75, 0x4e,
+ 0x29, 0x06, 0x9d, 0xa4, 0x51, 0x3a, 0x10, 0x63,
+ 0x8f, 0x17, 0x07, 0xd5, 0x8e, 0x3c, 0xf4, 0x28,
+ 0x00, 0x5a, 0x5b, 0x05, 0x19, 0xd8, 0xc0, 0x6c,
+ 0xe5, 0x15, 0xe4, 0x9c, 0x9d, 0x71, 0x9d, 0x5e,
+ 0x94, 0x29, 0x1a, 0xa7, 0x80, 0xfa, 0x0e, 0x33,
+ 0x03, 0xdd, 0xb7, 0x3e, 0x9a, 0xa9, 0x26, 0x18,
+ 0x37, 0xa9, 0x64, 0x08, 0x4d, 0x94, 0x5a, 0x88,
+ 0xca, 0x35, 0xce, 0x81, 0x02, 0xe3, 0x1f, 0x1b,
+ 0x89, 0x1a, 0x77, 0x85, 0xe3, 0x41, 0x6d, 0x32,
+ 0x42, 0x19, 0x23, 0x7d, 0xc8, 0x73, 0xee, 0x25,
+ 0x85, 0x0d, 0xf8, 0x31, 0x25, 0x79, 0x1b, 0x6f,
+ 0x79, 0x25, 0xd2, 0xd8, 0xd4, 0x23, 0xfd, 0xf7,
+ 0x82, 0x36, 0x6a, 0x0c, 0x46, 0x22, 0x15, 0xe9,
+ 0xff, 0x72, 0x41, 0x91, 0x91, 0x7d, 0x3a, 0xb7,
+ 0xdd, 0x65, 0x99, 0x70, 0xf6, 0x8d, 0x84, 0xf8,
+ 0x67, 0x15, 0x20, 0x11, 0xd6, 0xb2, 0x55, 0x7b,
+ 0xdb, 0x87, 0xee, 0xef, 0x55, 0x89, 0x2a, 0x59,
+ 0x2b, 0x07, 0x8f, 0x43, 0x8a, 0x59, 0x3c, 0x01,
+ 0x8b, 0x65, 0x54, 0xa1, 0x66, 0xd5, 0x38, 0xbd,
+ 0xc6, 0x30, 0xa9, 0xcc, 0x49, 0xb6, 0xa8, 0x1b,
+ 0xb8, 0xc0, 0x0e, 0xe3, 0x45, 0x28, 0xe2, 0xff,
+ 0x41, 0x9f, 0x7e, 0x7c, 0xd1, 0xae, 0x9e, 0x25,
+ 0x3f, 0x4c, 0x7c, 0x7c, 0xf4, 0xa8, 0x26, 0x4d,
+ 0x5c, 0xfd, 0x4b, 0x27, 0x18, 0xf9, 0x61, 0x76,
+ 0x48, 0xba, 0x0c, 0x6b, 0xa9, 0x4d, 0xfc, 0xf5,
+ 0x3b, 0x35, 0x7e, 0x2f, 0x4a, 0xa9, 0xc2, 0x9a,
+ 0xae, 0xab, 0x86, 0x09, 0x89, 0xc9, 0xc2, 0x40,
+ 0x39, 0x2c, 0x81, 0xb3, 0xb8, 0x17, 0x67, 0xc2,
+ 0x0d, 0x32, 0x4a, 0x3a, 0x67, 0x81, 0xd7, 0x1a,
+ 0x34, 0x52, 0xc5, 0xdb, 0x0a, 0xf5, 0x63, 0x39,
+ 0xea, 0x1f, 0xe1, 0x7c, 0xa1, 0x9e, 0xc1, 0x35,
+ 0xe3, 0xb1, 0x18, 0x45, 0x67, 0xf9, 0x22, 0x38,
+ 0x95, 0xd9, 0x34, 0x34, 0x86, 0xc6, 0x41, 0x94,
+ 0x15, 0xf9, 0x5b, 0x41, 0xa6, 0x87, 0x8b, 0xf8,
+ 0xd5, 0xe1, 0x1b, 0xe2, 0x5b, 0xf3, 0x86, 0x10,
+ 0xff, 0xe6, 0xae, 0x69, 0x76, 0xbc, 0x0d, 0xb4,
+ 0x09, 0x90, 0x0c, 0xa2, 0x65, 0x0c, 0xad, 0x74,
+ 0xf5, 0xd7, 0xff, 0xda, 0xc1, 0xce, 0x85, 0xbe,
+ 0x00, 0xa7, 0xff, 0x4d, 0x2f, 0x65, 0xd3, 0x8c,
+ 0x86, 0x2d, 0x05, 0xe8, 0xed, 0x3e, 0x6b, 0x8b,
+ 0x0f, 0x3d, 0x83, 0x8c, 0xf1, 0x1d, 0x5b, 0x96,
+ 0x2e, 0xb1, 0x9c, 0xc2, 0x98, 0xe1, 0x70, 0xb9,
+ 0xba, 0x5c, 0x8a, 0x43, 0xd6, 0x34, 0xa7, 0x2d,
+ 0xc9, 0x92, 0xae, 0xf2, 0xa5, 0x7b, 0x05, 0x49,
+ 0xa7, 0x33, 0x34, 0x86, 0xca, 0xe4, 0x96, 0x23,
+ 0x76, 0x5b, 0xf2, 0xc6, 0xf1, 0x51, 0x28, 0x42,
+ 0x7b, 0xcc, 0x76, 0x8f, 0xfa, 0xa2, 0xad, 0x31,
+ 0xd4, 0xd6, 0x7a, 0x6d, 0x25, 0x25, 0x54, 0xe4,
+ 0x3f, 0x50, 0x59, 0xe1, 0x5c, 0x05, 0xb7, 0x27,
+ 0x48, 0xbf, 0x07, 0xec, 0x1b, 0x13, 0xbe, 0x2b,
+ 0xa1, 0x57, 0x2b, 0xd5, 0xab, 0xd7, 0xd0, 0x4c,
+ 0x1e, 0xcb, 0x71, 0x9b, 0xc5, 0x90, 0x85, 0xd3,
+ 0xde, 0x59, 0xec, 0x71, 0xeb, 0x89, 0xbb, 0xd0,
+ 0x09, 0x50, 0xe1, 0x16, 0x3f, 0xfd, 0x1c, 0x34,
+ 0xc3, 0x1c, 0xa1, 0x10, 0x77, 0x53, 0x98, 0xef,
+ 0xf2, 0xfd, 0xa5, 0x01, 0x59, 0xc2, 0x9b, 0x26,
+ 0xc7, 0x42, 0xd9, 0x49, 0xda, 0x58, 0x2b, 0x6e,
+ 0x9f, 0x53, 0x19, 0x76, 0x7e, 0xd9, 0xc9, 0x0e,
+ 0x68, 0xc8, 0x7f, 0x51, 0x22, 0x42, 0xef, 0x49,
+ 0xa4, 0x55, 0xb6, 0x36, 0xac, 0x09, 0xc7, 0x31,
+ 0x88, 0x15, 0x4b, 0x2e, 0x8f, 0x3a, 0x08, 0xf7,
+ 0xd8, 0xf7, 0xa8, 0xc5, 0xa9, 0x33, 0xa6, 0x45,
+ 0xe4, 0xc4, 0x94, 0x76, 0xf3, 0x0d, 0x8f, 0x7e,
+ 0xc8, 0xf6, 0xbc, 0x23, 0x0a, 0xb6, 0x4c, 0xd3,
+ 0x6a, 0xcd, 0x36, 0xc2, 0x90, 0x5c, 0x5c, 0x3c,
+ 0x65, 0x7b, 0xc2, 0xd6, 0xcc, 0xe6, 0x0d, 0x87,
+ 0x73, 0x2e, 0x71, 0x79, 0x16, 0x06, 0x63, 0x28,
+ 0x09, 0x15, 0xd8, 0x89, 0x38, 0x38, 0x3d, 0xb5,
+ 0x42, 0x1c, 0x08, 0x24, 0xf7, 0x2a, 0xd2, 0x9d,
+ 0xc8, 0xca, 0xef, 0xf9, 0x27, 0xd8, 0x07, 0x86,
+ 0xf7, 0x43, 0x0b, 0x55, 0x15, 0x3f, 0x9f, 0x83,
+ 0xef, 0xdc, 0x49, 0x9d, 0x2a, 0xc1, 0x54, 0x62,
+ 0xbd, 0x9b, 0x66, 0x55, 0x9f, 0xb7, 0x12, 0xf3,
+ 0x1b, 0x4d, 0x9d, 0x2a, 0x5c, 0xed, 0x87, 0x75,
+ 0x87, 0x26, 0xec, 0x61, 0x2c, 0xb4, 0x0f, 0x89,
+ 0xb0, 0xfb, 0x2e, 0x68, 0x5d, 0x15, 0xc7, 0x8d,
+ 0x2e, 0xc0, 0xd9, 0xec, 0xaf, 0x4f, 0xd2, 0x25,
+ 0x29, 0xe8, 0xd2, 0x26, 0x2b, 0x67, 0xe9, 0xfc,
+ 0x2b, 0xa8, 0x67, 0x96, 0x12, 0x1f, 0x5b, 0x96,
+ 0xc6, 0x14, 0x53, 0xaf, 0x44, 0xea, 0xd6, 0xe2,
+ 0x94, 0x98, 0xe4, 0x12, 0x93, 0x4c, 0x92, 0xe0,
+ 0x18, 0xa5, 0x8d, 0x2d, 0xe4, 0x71, 0x3c, 0x47,
+ 0x4c, 0xf7, 0xe6, 0x47, 0x9e, 0xc0, 0x68, 0xdf,
+ 0xd4, 0xf5, 0x5a, 0x74, 0xb1, 0x2b, 0x29, 0x03,
+ 0x19, 0x07, 0xaf, 0x90, 0x62, 0x5c, 0x68, 0x98,
+ 0x48, 0x16, 0x11, 0x02, 0x9d, 0xee, 0xb4, 0x9b,
+ 0xe5, 0x42, 0x7f, 0x08, 0xfd, 0x16, 0x32, 0x0b,
+ 0xd0, 0xb3, 0xfa, 0x2b, 0xb7, 0x99, 0xf9, 0x29,
+ 0xcd, 0x20, 0x45, 0x9f, 0xb3, 0x1a, 0x5d, 0xa2,
+ 0xaf, 0x4d, 0xe0, 0xbd, 0x42, 0x0d, 0xbc, 0x74,
+ 0x99, 0x9c, 0x8e, 0x53, 0x1a, 0xb4, 0x3e, 0xbd,
+ 0xa2, 0x9a, 0x2d, 0xf7, 0xf8, 0x39, 0x0f, 0x67,
+ 0x63, 0xfc, 0x6b, 0xc0, 0xaf, 0xb3, 0x4b, 0x4f,
+ 0x55, 0xc4, 0xcf, 0xa7, 0xc8, 0x04, 0x11, 0x3e,
+ 0x14, 0x32, 0xbb, 0x1b, 0x38, 0x77, 0xd6, 0x7f,
+ 0x54, 0x4c, 0xdf, 0x75, 0xf3, 0x07, 0x2d, 0x33,
+ 0x9b, 0xa8, 0x20, 0xe1, 0x7b, 0x12, 0xb5, 0xf3,
+ 0xef, 0x2f, 0xce, 0x72, 0xe5, 0x24, 0x60, 0xc1,
+ 0x30, 0xe2, 0xab, 0xa1, 0x8e, 0x11, 0x09, 0xa8,
+ 0x21, 0x33, 0x44, 0xfe, 0x7f, 0x35, 0x32, 0x93,
+ 0x39, 0xa7, 0xad, 0x8b, 0x79, 0x06, 0xb2, 0xcb,
+ 0x4e, 0xa9, 0x5f, 0xc7, 0xba, 0x74, 0x29, 0xec,
+ 0x93, 0xa0, 0x4e, 0x54, 0x93, 0xc0, 0xbc, 0x55,
+ 0x64, 0xf0, 0x48, 0xe5, 0x57, 0x99, 0xee, 0x75,
+ 0xd6, 0x79, 0x0f, 0x66, 0xb7, 0xc6, 0x57, 0x76,
+ 0xf7, 0xb7, 0xf3, 0x9c, 0xc5, 0x60, 0xe8, 0x7f,
+ 0x83, 0x76, 0xd6, 0x0e, 0xaa, 0xe6, 0x90, 0x39,
+ 0x1d, 0xa6, 0x32, 0x6a, 0x34, 0xe3, 0x55, 0xf8,
+ 0x58, 0xa0, 0x58, 0x7d, 0x33, 0xe0, 0x22, 0x39,
+ 0x44, 0x64, 0x87, 0x86, 0x5a, 0x2f, 0xa7, 0x7e,
+ 0x0f, 0x38, 0xea, 0xb0, 0x30, 0xcc, 0x61, 0xa5,
+ 0x6a, 0x32, 0xae, 0x1e, 0xf7, 0xe9, 0xd0, 0xa9,
+ 0x0c, 0x32, 0x4b, 0xb5, 0x49, 0x28, 0xab, 0x85,
+ 0x2f, 0x8e, 0x01, 0x36, 0x38, 0x52, 0xd0, 0xba,
+ 0xd6, 0x02, 0x78, 0xf8, 0x0e, 0x3e, 0x9c, 0x8b,
+ 0x6b, 0x45, 0x99, 0x3f, 0x5c, 0xfe, 0x58, 0xf1,
+ 0x5c, 0x94, 0x04, 0xe1, 0xf5, 0x18, 0x6d, 0x51,
+ 0xb2, 0x5d, 0x18, 0x20, 0xb6, 0xc2, 0x9a, 0x42,
+ 0x1d, 0xb3, 0xab, 0x3c, 0xb6, 0x3a, 0x13, 0x03,
+ 0xb2, 0x46, 0x82, 0x4f, 0xfc, 0x64, 0xbc, 0x4f,
+ 0xca, 0xfa, 0x9c, 0xc0, 0xd5, 0xa7, 0xbd, 0x11,
+ 0xb7, 0xe4, 0x5a, 0xf6, 0x6f, 0x4d, 0x4d, 0x54,
+ 0xea, 0xa4, 0x98, 0x66, 0xd4, 0x22, 0x3b, 0xd3,
+ 0x8f, 0x34, 0x47, 0xd9, 0x7c, 0xf4, 0x72, 0x3b,
+ 0x4d, 0x02, 0x77, 0xf6, 0xd6, 0xdd, 0x08, 0x0a,
+ 0x81, 0xe1, 0x86, 0x89, 0x3e, 0x56, 0x10, 0x3c,
+ 0xba, 0xd7, 0x81, 0x8c, 0x08, 0xbc, 0x8b, 0xe2,
+ 0x53, 0xec, 0xa7, 0x89, 0xee, 0xc8, 0x56, 0xb5,
+ 0x36, 0x2c, 0xb2, 0x03, 0xba, 0x99, 0xdd, 0x7c,
+ 0x48, 0xa0, 0xb0, 0xbc, 0x91, 0x33, 0xe9, 0xa8,
+ 0xcb, 0xcd, 0xcf, 0x59, 0x5f, 0x1f, 0x15, 0xe2,
+ 0x56, 0xf5, 0x4e, 0x01, 0x35, 0x27, 0x45, 0x77,
+ 0x47, 0xc8, 0xbc, 0xcb, 0x7e, 0x39, 0xc1, 0x97,
+ 0x28, 0xd3, 0x84, 0xfc, 0x2c, 0x3e, 0xc8, 0xad,
+ 0x9c, 0xf8, 0x8a, 0x61, 0x9c, 0x28, 0xaa, 0xc5,
+ 0x99, 0x20, 0x43, 0x85, 0x9d, 0xa5, 0xe2, 0x8b,
+ 0xb8, 0xae, 0xeb, 0xd0, 0x32, 0x0d, 0x52, 0x78,
+ 0x09, 0x56, 0x3f, 0xc7, 0xd8, 0x7e, 0x26, 0xfc,
+ 0x37, 0xfb, 0x6f, 0x04, 0xfc, 0xfa, 0x92, 0x10,
+ 0xac, 0xf8, 0x3e, 0x21, 0xdc, 0x8c, 0x21, 0x16,
+ 0x7d, 0x67, 0x6e, 0xf6, 0xcd, 0xda, 0xb6, 0x98,
+ 0x23, 0xab, 0x23, 0x3c, 0xb2, 0x10, 0xa0, 0x53,
+ 0x5a, 0x56, 0x9f, 0xc5, 0xd0, 0xff, 0xbb, 0xe4,
+ 0x98, 0x3c, 0x69, 0x1e, 0xdb, 0x38, 0x8f, 0x7e,
+ 0x0f, 0xd2, 0x98, 0x88, 0x81, 0x8b, 0x45, 0x67,
+ 0xea, 0x33, 0xf1, 0xeb, 0xe9, 0x97, 0x55, 0x2e,
+ 0xd9, 0xaa, 0xeb, 0x5a, 0xec, 0xda, 0xe1, 0x68,
+ 0xa8, 0x9d, 0x3c, 0x84, 0x7c, 0x05, 0x3d, 0x62,
+ 0x87, 0x8f, 0x03, 0x21, 0x28, 0x95, 0x0c, 0x89,
+ 0x25, 0x22, 0x4a, 0xb0, 0x93, 0xa9, 0x50, 0xa2,
+ 0x2f, 0x57, 0x6e, 0x18, 0x42, 0x19, 0x54, 0x0c,
+ 0x55, 0x67, 0xc6, 0x11, 0x49, 0xf4, 0x5c, 0xd2,
+ 0xe9, 0x3d, 0xdd, 0x8b, 0x48, 0x71, 0x21, 0x00,
+ 0xc3, 0x9a, 0x6c, 0x85, 0x74, 0x28, 0x83, 0x4a,
+ 0x1b, 0x31, 0x05, 0xe1, 0x06, 0x92, 0xe7, 0xda,
+ 0x85, 0x73, 0x78, 0x45, 0x20, 0x7f, 0xae, 0x13,
+ 0x7c, 0x33, 0x06, 0x22, 0xf4, 0x83, 0xf9, 0x35,
+ 0x3f, 0x6c, 0x71, 0xa8, 0x4e, 0x48, 0xbe, 0x9b,
+ 0xce, 0x8a, 0xba, 0xda, 0xbe, 0x28, 0x08, 0xf7,
+ 0xe2, 0x14, 0x8c, 0x71, 0xea, 0x72, 0xf9, 0x33,
+ 0xf2, 0x88, 0x3f, 0xd7, 0xbb, 0x69, 0x6c, 0x29,
+ 0x19, 0xdc, 0x84, 0xce, 0x1f, 0x12, 0x4f, 0xc8,
+ 0xaf, 0xa5, 0x04, 0xba, 0x5a, 0xab, 0xb0, 0xd9,
+ 0x14, 0x1f, 0x6c, 0x68, 0x98, 0x39, 0x89, 0x7a,
+ 0xd9, 0xd8, 0x2f, 0xdf, 0xa8, 0x47, 0x4a, 0x25,
+ 0xe2, 0xfb, 0x33, 0xf4, 0x59, 0x78, 0xe1, 0x68,
+ 0x85, 0xcf, 0xfe, 0x59, 0x20, 0xd4, 0x05, 0x1d,
+ 0x80, 0x99, 0xae, 0xbc, 0xca, 0xae, 0x0f, 0x2f,
+ 0x65, 0x43, 0x34, 0x8e, 0x7e, 0xac, 0xd3, 0x93,
+ 0x2f, 0xac, 0x6d, 0x14, 0x3d, 0x02, 0x07, 0x70,
+ 0x9d, 0xa4, 0xf3, 0x1b, 0x5c, 0x36, 0xfc, 0x01,
+ 0x73, 0x34, 0x85, 0x0c, 0x6c, 0xd6, 0xf1, 0xbd,
+ 0x3f, 0xdf, 0xee, 0xf5, 0xd9, 0xba, 0x56, 0xef,
+ 0xf4, 0x9b, 0x6b, 0xee, 0x9f, 0x5a, 0x78, 0x6d,
+ 0x32, 0x19, 0xf4, 0xf7, 0xf8, 0x4c, 0x69, 0x0b,
+ 0x4b, 0xbc, 0xbb, 0xb7, 0xf2, 0x85, 0xaf, 0x70,
+ 0x75, 0x24, 0x6c, 0x54, 0xa7, 0x0e, 0x4d, 0x1d,
+ 0x01, 0xbf, 0x08, 0xac, 0xcf, 0x7f, 0x2c, 0xe3,
+ 0x14, 0x89, 0x5e, 0x70, 0x5a, 0x99, 0x92, 0xcd,
+ 0x01, 0x84, 0xc8, 0xd2, 0xab, 0xe5, 0x4f, 0x58,
+ 0xe7, 0x0f, 0x2f, 0x0e, 0xff, 0x68, 0xea, 0xfd,
+ 0x15, 0xb3, 0x17, 0xe6, 0xb0, 0xe7, 0x85, 0xd8,
+ 0x23, 0x2e, 0x05, 0xc7, 0xc9, 0xc4, 0x46, 0x1f,
+ 0xe1, 0x9e, 0x49, 0x20, 0x23, 0x24, 0x4d, 0x7e,
+ 0x29, 0x65, 0xff, 0xf4, 0xb6, 0xfd, 0x1a, 0x85,
+ 0xc4, 0x16, 0xec, 0xfc, 0xea, 0x7b, 0xd6, 0x2c,
+ 0x43, 0xf8, 0xb7, 0xbf, 0x79, 0xc0, 0x85, 0xcd,
+ 0xef, 0xe1, 0x98, 0xd3, 0xa5, 0xf7, 0x90, 0x8c,
+ 0xe9, 0x7f, 0x80, 0x6b, 0xd2, 0xac, 0x4c, 0x30,
+ 0xa7, 0xc6, 0x61, 0x6c, 0xd2, 0xf9, 0x2c, 0xff,
+ 0x30, 0xbc, 0x22, 0x81, 0x7d, 0x93, 0x12, 0xe4,
+ 0x0a, 0xcd, 0xaf, 0xdd, 0xe8, 0xab, 0x0a, 0x1e,
+ 0x13, 0xa4, 0x27, 0xc3, 0x5f, 0xf7, 0x4b, 0xbb,
+ 0x37, 0x09, 0x4b, 0x91, 0x6f, 0x92, 0x4f, 0xaf,
+ 0x52, 0xee, 0xdf, 0xef, 0x09, 0x6f, 0xf7, 0x5c,
+ 0x6e, 0x12, 0x17, 0x72, 0x63, 0x57, 0xc7, 0xba,
+ 0x3b, 0x6b, 0x38, 0x32, 0x73, 0x1b, 0x9c, 0x80,
+ 0xc1, 0x7a, 0xc6, 0xcf, 0xcd, 0x35, 0xc0, 0x6b,
+ 0x31, 0x1a, 0x6b, 0xe9, 0xd8, 0x2c, 0x29, 0x3f,
+ 0x96, 0xfb, 0xb6, 0xcd, 0x13, 0x91, 0x3b, 0xc2,
+ 0xd2, 0xa3, 0x31, 0x8d, 0xa4, 0xcd, 0x57, 0xcd,
+ 0x13, 0x3d, 0x64, 0xfd, 0x06, 0xce, 0xe6, 0xdc,
+ 0x0c, 0x24, 0x43, 0x31, 0x40, 0x57, 0xf1, 0x72,
+ 0x17, 0xe3, 0x3a, 0x63, 0x6d, 0x35, 0xcf, 0x5d,
+ 0x97, 0x40, 0x59, 0xdd, 0xf7, 0x3c, 0x02, 0xf7,
+ 0x1c, 0x7e, 0x05, 0xbb, 0xa9, 0x0d, 0x01, 0xb1,
+ 0x8e, 0xc0, 0x30, 0xa9, 0x53, 0x24, 0xc9, 0x89,
+ 0x84, 0x6d, 0xaa, 0xd0, 0xcd, 0x91, 0xc2, 0x4d,
+ 0x91, 0xb0, 0x89, 0xe2, 0xbf, 0x83, 0x44, 0xaa,
+ 0x28, 0x72, 0x23, 0xa0, 0xc2, 0xad, 0xad, 0x1c,
+ 0xfc, 0x3f, 0x09, 0x7a, 0x0b, 0xdc, 0xc5, 0x1b,
+ 0x87, 0x13, 0xc6, 0x5b, 0x59, 0x8d, 0xf2, 0xc8,
+ 0xaf, 0xdf, 0x11, 0x95,
+ },
+ .rlen = 4100,
+ },
+};
+
/*
* Compression stuff.
*/
@@ -4408,6 +7721,88 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
};
/*
+ * LZO test vectors (null-terminated strings).
+ */
+#define LZO_COMP_TEST_VECTORS 2
+#define LZO_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec lzo_comp_tv_template[] = {
+ {
+ .inlen = 70,
+ .outlen = 46,
+ .input = "Join us now and share the software "
+ "Join us now and share the software ",
+ .output = { 0x00, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x20, 0x75,
+ 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x61, 0x6e,
+ 0x64, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20,
+ 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74,
+ 0x77, 0x70, 0x01, 0x01, 0x4a, 0x6f, 0x69, 0x6e,
+ 0x3d, 0x88, 0x00, 0x11, 0x00, 0x00 },
+ }, {
+ .inlen = 159,
+ .outlen = 133,
+ .input = "This document describes a compression method based on the LZO "
+ "compression algorithm. This document defines the application of "
+ "the LZO algorithm used in UBIFS.",
+ .output = { 0x00, 0x2b, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64,
+ 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
+ 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+ 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x62,
+ 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20,
+ 0x74, 0x68, 0x65, 0x20, 0x4c, 0x5a, 0x4f, 0x2b,
+ 0x8c, 0x00, 0x0d, 0x61, 0x6c, 0x67, 0x6f, 0x72,
+ 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x20, 0x20, 0x54,
+ 0x68, 0x69, 0x73, 0x2a, 0x54, 0x01, 0x02, 0x66,
+ 0x69, 0x6e, 0x65, 0x73, 0x94, 0x06, 0x05, 0x61,
+ 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x76,
+ 0x0a, 0x6f, 0x66, 0x88, 0x02, 0x60, 0x09, 0x27,
+ 0xf0, 0x00, 0x0c, 0x20, 0x75, 0x73, 0x65, 0x64,
+ 0x20, 0x69, 0x6e, 0x20, 0x55, 0x42, 0x49, 0x46,
+ 0x53, 0x2e, 0x11, 0x00, 0x00 },
+ },
+};
+
+static struct comp_testvec lzo_decomp_tv_template[] = {
+ {
+ .inlen = 133,
+ .outlen = 159,
+ .input = { 0x00, 0x2b, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64,
+ 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
+ 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+ 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x62,
+ 0x61, 0x73, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20,
+ 0x74, 0x68, 0x65, 0x20, 0x4c, 0x5a, 0x4f, 0x2b,
+ 0x8c, 0x00, 0x0d, 0x61, 0x6c, 0x67, 0x6f, 0x72,
+ 0x69, 0x74, 0x68, 0x6d, 0x2e, 0x20, 0x20, 0x54,
+ 0x68, 0x69, 0x73, 0x2a, 0x54, 0x01, 0x02, 0x66,
+ 0x69, 0x6e, 0x65, 0x73, 0x94, 0x06, 0x05, 0x61,
+ 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x76,
+ 0x0a, 0x6f, 0x66, 0x88, 0x02, 0x60, 0x09, 0x27,
+ 0xf0, 0x00, 0x0c, 0x20, 0x75, 0x73, 0x65, 0x64,
+ 0x20, 0x69, 0x6e, 0x20, 0x55, 0x42, 0x49, 0x46,
+ 0x53, 0x2e, 0x11, 0x00, 0x00 },
+ .output = "This document describes a compression method based on the LZO "
+ "compression algorithm. This document defines the application of "
+ "the LZO algorithm used in UBIFS.",
+ }, {
+ .inlen = 46,
+ .outlen = 70,
+ .input = { 0x00, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x20, 0x75,
+ 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x61, 0x6e,
+ 0x64, 0x20, 0x73, 0x68, 0x61, 0x72, 0x65, 0x20,
+ 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74,
+ 0x77, 0x70, 0x01, 0x01, 0x4a, 0x6f, 0x69, 0x6e,
+ 0x3d, 0x88, 0x00, 0x11, 0x00, 0x00 },
+ .output = "Join us now and share the software "
+ "Join us now and share the software ",
+ },
+};
+
+/*
* Michael MIC test vectors from IEEE 802.11i
*/
#define MICHAEL_MIC_TEST_VECTORS 6
@@ -4812,4 +8207,20 @@ static struct cipher_speed camellia_speed_template[] = {
{ .klen = 0, .blen = 0, }
};
+static struct cipher_speed salsa20_speed_template[] = {
+ { .klen = 16, .blen = 16, },
+ { .klen = 16, .blen = 64, },
+ { .klen = 16, .blen = 256, },
+ { .klen = 16, .blen = 1024, },
+ { .klen = 16, .blen = 8192, },
+ { .klen = 32, .blen = 16, },
+ { .klen = 32, .blen = 64, },
+ { .klen = 32, .blen = 256, },
+ { .klen = 32, .blen = 1024, },
+ { .klen = 32, .blen = 8192, },
+
+ /* End marker */
+ { .klen = 0, .blen = 0, }
+};
+
#endif /* _CRYPTO_TCRYPT_H */
diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c
index b4b9c0c..0af216c 100644
--- a/crypto/twofish_common.c
+++ b/crypto/twofish_common.c
@@ -655,84 +655,48 @@ int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ /* CALC_K256/CALC_K192/CALC_K loops were unrolled.
+ * Unrolling produced x2.5 more code (+18k on i386),
+ * and speeded up key setup by 7%:
+ * unrolled: twofish_setkey/sec: 41128
+ * loop: twofish_setkey/sec: 38148
+ * CALC_K256: ~100 insns each
+ * CALC_K192: ~90 insns
+ * CALC_K: ~70 insns
+ */
+ /* Calculate whitening and round subkeys */
+ for ( i = 0; i < 8; i += 2 ) {
+ CALC_K256 (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
+ }
+ for ( i = 0; i < 32; i += 2 ) {
+ CALC_K256 (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
+ }
} else if (key_len == 24) { /* 192-bit key */
/* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ /* Calculate whitening and round subkeys */
+ for ( i = 0; i < 8; i += 2 ) {
+ CALC_K192 (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
+ }
+ for ( i = 0; i < 32; i += 2 ) {
+ CALC_K192 (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
+ }
} else { /* 128-bit key */
/* Compute the S-boxes. */
for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
}
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ /* Calculate whitening and round subkeys */
+ for ( i = 0; i < 8; i += 2 ) {
+ CALC_K (w, i, q0[i], q1[i], q0[i+1], q1[i+1]);
+ }
+ for ( i = 0; i < 32; i += 2 ) {
+ CALC_K (k, i, q0[i+8], q1[i+8], q0[i+9], q1[i+9]);
+ }
}
return 0;
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index ac68f3b..a82959d 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -19,6 +19,7 @@
* Kazunori Miyazawa <miyazawa@linux-ipv6.org>
*/
+#include <crypto/scatterwalk.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/hardirq.h>
@@ -27,7 +28,6 @@
#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,
@@ -307,7 +307,8 @@ static struct crypto_instance *xcbc_alloc(struct rtattr **tb)
case 16:
break;
default:
- return ERR_PTR(PTR_ERR(alg));
+ inst = ERR_PTR(-EINVAL);
+ goto out_put_alg;
}
inst = crypto_alloc_instance("xcbc", alg);
@@ -320,10 +321,7 @@ static struct crypto_instance *xcbc_alloc(struct rtattr **tb)
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_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;
OpenPOWER on IntegriCloud