From: Kevin Coffman Date: Mon, 24 Mar 2008 13:26:16 +0000 (+0800) Subject: [CRYPTO] cts: Add CTS mode required for Kerberos AES support X-Git-Tag: v2.6.26-rc1~1120^2~6 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=76cb9521795a167ae3d206343c072f602d84f815;p=linux-2.6-omap-h63xx.git [CRYPTO] cts: Add CTS mode required for Kerberos AES support Implement CTS wrapper for CBC mode required for support of AES encryption support for Kerberos (rfc3962). Signed-off-by: Kevin Coffman Signed-off-by: Herbert Xu --- diff --git a/crypto/Kconfig b/crypto/Kconfig index 69f1be6816f..e14ff127501 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -213,6 +213,17 @@ config CRYPTO_CTR CTR: Counter mode This block cipher algorithm is required for IPSec. +config CRYPTO_CTS + tristate "CTS support" + select CRYPTO_BLKCIPHER + help + CTS: Cipher Text Stealing + This is the Cipher Text Stealing mode as described by + Section 8 of rfc2040 and referenced by rfc3962. + (rfc3962 includes errata information in its Appendix A) + This mode is required for Kerberos gss mechanism support + for AES encryption. + config CRYPTO_GCM tristate "GCM/GMAC support" select CRYPTO_CTR diff --git a/crypto/Makefile b/crypto/Makefile index cf702a270c5..6d34bf7ecf8 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o +obj-$(CONFIG_CRYPTO_CTS) += cts.o obj-$(CONFIG_CRYPTO_LRW) += lrw.o obj-$(CONFIG_CRYPTO_XTS) += xts.o obj-$(CONFIG_CRYPTO_CTR) += ctr.o diff --git a/crypto/cts.c b/crypto/cts.c new file mode 100644 index 00000000000..c4e70bfb497 --- /dev/null +++ b/crypto/cts.c @@ -0,0 +1,347 @@ +/* + * CTS: Cipher Text Stealing mode + * + * COPYRIGHT (c) 2008 + * The Regents of the University of Michigan + * ALL RIGHTS RESERVED + * + * Permission is granted to use, copy, create derivative works + * and redistribute this software and such derivative works + * for any purpose, so long as the name of The University of + * Michigan is not used in any advertising or publicity + * pertaining to the use of distribution of this software + * without specific, written prior authorization. If the + * above copyright notice or any other identification of the + * University of Michigan is included in any copy of any + * portion of this software, then the disclaimer below must + * also be included. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* Derived from various: + * Copyright (c) 2006 Herbert Xu + */ + +/* + * This is the Cipher Text Stealing mode as described by + * Section 8 of rfc2040 and referenced by rfc3962. + * rfc3962 includes errata information in its Appendix A. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct crypto_cts_ctx { + struct crypto_blkcipher *child; +}; + +static int crypto_cts_setkey(struct crypto_tfm *parent, const u8 *key, + unsigned int keylen) +{ + struct crypto_cts_ctx *ctx = crypto_tfm_ctx(parent); + struct crypto_blkcipher *child = ctx->child; + int err; + + 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 cts_cbc_encrypt(struct crypto_cts_ctx *ctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int offset, + unsigned int nbytes) +{ + int bsize = crypto_blkcipher_blocksize(desc->tfm); + u8 tmp[bsize], tmp2[bsize]; + struct blkcipher_desc lcldesc; + struct scatterlist sgsrc[1], sgdst[1]; + int lastn = nbytes - bsize; + u8 iv[bsize]; + u8 s[bsize * 2], d[bsize * 2]; + int err; + + if (lastn < 0) + return -EINVAL; + + memset(s, 0, sizeof(s)); + scatterwalk_map_and_copy(s, src, offset, nbytes, 0); + + memcpy(iv, desc->info, bsize); + + lcldesc.tfm = ctx->child; + lcldesc.info = iv; + lcldesc.flags = desc->flags; + + sg_set_buf(&sgsrc[0], s, bsize); + sg_set_buf(&sgdst[0], tmp, bsize); + err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); + + memcpy(d + bsize, tmp, lastn); + + lcldesc.info = tmp; + + sg_set_buf(&sgsrc[0], s + bsize, bsize); + sg_set_buf(&sgdst[0], tmp2, bsize); + err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); + + memcpy(d, tmp2, bsize); + + scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); + + memcpy(desc->info, tmp2, bsize); + + return err; +} + +static int crypto_cts_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + int bsize = crypto_blkcipher_blocksize(desc->tfm); + int tot_blocks = (nbytes + bsize - 1) / bsize; + int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; + struct blkcipher_desc lcldesc; + int err; + + lcldesc.tfm = ctx->child; + lcldesc.info = desc->info; + lcldesc.flags = desc->flags; + + if (tot_blocks == 1) { + err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, bsize); + } else if (nbytes <= bsize * 2) { + err = cts_cbc_encrypt(ctx, desc, dst, src, 0, nbytes); + } else { + /* do normal function for tot_blocks - 2 */ + err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, + cbc_blocks * bsize); + if (err == 0) { + /* do cts for final two blocks */ + err = cts_cbc_encrypt(ctx, desc, dst, src, + cbc_blocks * bsize, + nbytes - (cbc_blocks * bsize)); + } + } + + return err; +} + +static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx, + struct blkcipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int offset, + unsigned int nbytes) +{ + int bsize = crypto_blkcipher_blocksize(desc->tfm); + u8 tmp[bsize]; + struct blkcipher_desc lcldesc; + struct scatterlist sgsrc[1], sgdst[1]; + int lastn = nbytes - bsize; + u8 iv[bsize]; + u8 s[bsize * 2], d[bsize * 2]; + int err; + + if (lastn < 0) + return -EINVAL; + + scatterwalk_map_and_copy(s, src, offset, nbytes, 0); + + lcldesc.tfm = ctx->child; + lcldesc.info = iv; + lcldesc.flags = desc->flags; + + /* 1. Decrypt Cn-1 (s) to create Dn (tmp)*/ + memset(iv, 0, sizeof(iv)); + sg_set_buf(&sgsrc[0], s, bsize); + sg_set_buf(&sgdst[0], tmp, bsize); + err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); + if (err) + return err; + /* 2. Pad Cn with zeros at the end to create C of length BB */ + memset(iv, 0, sizeof(iv)); + memcpy(iv, s + bsize, lastn); + /* 3. Exclusive-or Dn (tmp) with C (iv) to create Xn (tmp) */ + crypto_xor(tmp, iv, bsize); + /* 4. Select the first Ln bytes of Xn (tmp) to create Pn */ + memcpy(d + bsize, tmp, lastn); + + /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */ + memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn); + /* 6. Decrypt En to create Pn-1 */ + memset(iv, 0, sizeof(iv)); + sg_set_buf(&sgsrc[0], s + bsize, bsize); + sg_set_buf(&sgdst[0], d, bsize); + err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); + + /* XOR with previous block */ + crypto_xor(d, desc->info, bsize); + + scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); + + memcpy(desc->info, s, bsize); + return err; +} + +static int crypto_cts_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + int bsize = crypto_blkcipher_blocksize(desc->tfm); + int tot_blocks = (nbytes + bsize - 1) / bsize; + int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; + struct blkcipher_desc lcldesc; + int err; + + lcldesc.tfm = ctx->child; + lcldesc.info = desc->info; + lcldesc.flags = desc->flags; + + if (tot_blocks == 1) { + err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, bsize); + } else if (nbytes <= bsize * 2) { + err = cts_cbc_decrypt(ctx, desc, dst, src, 0, nbytes); + } else { + /* do normal function for tot_blocks - 2 */ + err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, + cbc_blocks * bsize); + if (err == 0) { + /* do cts for final two blocks */ + err = cts_cbc_decrypt(ctx, desc, dst, src, + cbc_blocks * bsize, + nbytes - (cbc_blocks * bsize)); + } + } + return err; +} + +static int crypto_cts_init_tfm(struct crypto_tfm *tfm) +{ + struct crypto_instance *inst = (void *)tfm->__crt_alg; + struct crypto_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_cts_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_cts_exit_tfm(struct crypto_tfm *tfm) +{ + struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); + crypto_free_blkcipher(ctx->child); +} + +static struct crypto_instance *crypto_cts_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); + + inst = ERR_PTR(-EINVAL); + if (!is_power_of_2(alg->cra_blocksize)) + goto out_put_alg; + + inst = crypto_alloc_instance("cts", alg); + if (IS_ERR(inst)) + goto out_put_alg; + + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_priority = alg->cra_priority; + inst->alg.cra_blocksize = alg->cra_blocksize; + inst->alg.cra_alignmask = alg->cra_alignmask; + inst->alg.cra_type = &crypto_blkcipher_type; + + /* 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_blkcipher.min_keysize; + inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize; + + inst->alg.cra_blkcipher.geniv = "seqiv"; + + inst->alg.cra_ctxsize = sizeof(struct crypto_cts_ctx); + + inst->alg.cra_init = crypto_cts_init_tfm; + inst->alg.cra_exit = crypto_cts_exit_tfm; + + inst->alg.cra_blkcipher.setkey = crypto_cts_setkey; + inst->alg.cra_blkcipher.encrypt = crypto_cts_encrypt; + inst->alg.cra_blkcipher.decrypt = crypto_cts_decrypt; + +out_put_alg: + crypto_mod_put(alg); + return inst; +} + +static void crypto_cts_free(struct crypto_instance *inst) +{ + crypto_drop_spawn(crypto_instance_ctx(inst)); + kfree(inst); +} + +static struct crypto_template crypto_cts_tmpl = { + .name = "cts", + .alloc = crypto_cts_alloc, + .free = crypto_cts_free, + .module = THIS_MODULE, +}; + +static int __init crypto_cts_module_init(void) +{ + return crypto_register_template(&crypto_cts_tmpl); +} + +static void __exit crypto_cts_module_exit(void) +{ + crypto_unregister_template(&crypto_cts_tmpl); +} + +module_init(crypto_cts_module_init); +module_exit(crypto_cts_module_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC"); diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 30e75d49f35..689482cd16c 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -82,9 +82,8 @@ static char *check[] = { "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", "salsa20", "lzo", NULL + "camellia", "seed", "salsa20", "lzo", "cts", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -1328,6 +1327,12 @@ static void do_test(void) test_cipher("ecb(seed)", DECRYPT, seed_dec_tv_template, SEED_DEC_TEST_VECTORS); + //CTS + test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template, + CTS_MODE_ENC_TEST_VECTORS); + test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template, + CTS_MODE_DEC_TEST_VECTORS); + test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); @@ -1611,6 +1616,13 @@ static void do_test(void) AES_CCM_DEC_TEST_VECTORS); break; + case 38: + test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template, + CTS_MODE_ENC_TEST_VECTORS); + test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template, + CTS_MODE_DEC_TEST_VECTORS); + break; + case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index aae79e9c256..47bc0ecb897 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -7622,6 +7622,215 @@ static struct cipher_testvec salsa20_stream_enc_tv_template[] = { }, }; +/* + * CTS (Cipher Text Stealing) mode tests + */ +#define CTS_MODE_ENC_TEST_VECTORS 6 +#define CTS_MODE_DEC_TEST_VECTORS 6 +static struct cipher_testvec cts_mode_enc_tv_template[] = { + { /* from rfc3962 */ + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 17, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20", + .rlen = 17, + .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4" + "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" + "\x97", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 31, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20", + .rlen = 31, + .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" + "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 32, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43", + .rlen = 32, + .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 47, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c", + .rlen = 47, + .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c" + "\x1b\x55\x49\xd2\xf8\x38\x02\x9e" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 48, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c\x20", + .rlen = 48, + .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" + "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .ilen = 64, + .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c\x20" + "\x61\x6e\x64\x20\x77\x6f\x6e\x74" + "\x6f\x6e\x20\x73\x6f\x75\x70\x2e", + .rlen = 64, + .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x48\x07\xef\xe8\x36\xee\x89\xa5" + "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" + "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", + } +}; + +static struct cipher_testvec cts_mode_dec_tv_template[] = { + { /* from rfc3962 */ + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 17, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20", + .ilen = 17, + .input = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4" + "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" + "\x97", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 31, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20", + .ilen = 31, + .input = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" + "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 32, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43", + .ilen = 32, + .input = "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 47, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c", + .ilen = 47, + .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c" + "\x1b\x55\x49\xd2\xf8\x38\x02\x9e" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 48, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c\x20", + .ilen = 48, + .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" + "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", + }, { + .klen = 16, + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .rlen = 64, + .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20" + "\x70\x6c\x65\x61\x73\x65\x2c\x20" + "\x61\x6e\x64\x20\x77\x6f\x6e\x74" + "\x6f\x6e\x20\x73\x6f\x75\x70\x2e", + .ilen = 64, + .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x39\x31\x25\x23\xa7\x86\x62\xd5" + "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x48\x07\xef\xe8\x36\xee\x89\xa5" + "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" + "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", + } +}; + /* * Compression stuff. */