diff options
Diffstat (limited to 'crypto')
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; |