diff options
author | Kevin Coffman <kwc@citi.umich.edu> | 2008-03-24 09:26:16 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-04-20 22:19:23 -0400 |
commit | 76cb9521795a167ae3d206343c072f602d84f815 (patch) | |
tree | 36aa2e201867c76ac244de69e1bb16befa0504ee | |
parent | fd4609a8e00a867303783ade62d67953fb72adc8 (diff) |
[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 <kwc@citi.umich.edu>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/Kconfig | 11 | ||||
-rw-r--r-- | crypto/Makefile | 1 | ||||
-rw-r--r-- | crypto/cts.c | 347 | ||||
-rw-r--r-- | crypto/tcrypt.c | 16 | ||||
-rw-r--r-- | crypto/tcrypt.h | 209 |
5 files changed, 582 insertions, 2 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 69f1be6816f7..e14ff1275018 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -213,6 +213,17 @@ config CRYPTO_CTR | |||
213 | CTR: Counter mode | 213 | CTR: Counter mode |
214 | This block cipher algorithm is required for IPSec. | 214 | This block cipher algorithm is required for IPSec. |
215 | 215 | ||
216 | config CRYPTO_CTS | ||
217 | tristate "CTS support" | ||
218 | select CRYPTO_BLKCIPHER | ||
219 | help | ||
220 | CTS: Cipher Text Stealing | ||
221 | This is the Cipher Text Stealing mode as described by | ||
222 | Section 8 of rfc2040 and referenced by rfc3962. | ||
223 | (rfc3962 includes errata information in its Appendix A) | ||
224 | This mode is required for Kerberos gss mechanism support | ||
225 | for AES encryption. | ||
226 | |||
216 | config CRYPTO_GCM | 227 | config CRYPTO_GCM |
217 | tristate "GCM/GMAC support" | 228 | tristate "GCM/GMAC support" |
218 | select CRYPTO_CTR | 229 | select CRYPTO_CTR |
diff --git a/crypto/Makefile b/crypto/Makefile index cf702a270c59..6d34bf7ecf8d 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o | |||
35 | obj-$(CONFIG_CRYPTO_ECB) += ecb.o | 35 | obj-$(CONFIG_CRYPTO_ECB) += ecb.o |
36 | obj-$(CONFIG_CRYPTO_CBC) += cbc.o | 36 | obj-$(CONFIG_CRYPTO_CBC) += cbc.o |
37 | obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o | 37 | obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o |
38 | obj-$(CONFIG_CRYPTO_CTS) += cts.o | ||
38 | obj-$(CONFIG_CRYPTO_LRW) += lrw.o | 39 | obj-$(CONFIG_CRYPTO_LRW) += lrw.o |
39 | obj-$(CONFIG_CRYPTO_XTS) += xts.o | 40 | obj-$(CONFIG_CRYPTO_XTS) += xts.o |
40 | obj-$(CONFIG_CRYPTO_CTR) += ctr.o | 41 | obj-$(CONFIG_CRYPTO_CTR) += ctr.o |
diff --git a/crypto/cts.c b/crypto/cts.c new file mode 100644 index 000000000000..c4e70bfb4970 --- /dev/null +++ b/crypto/cts.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * CTS: Cipher Text Stealing mode | ||
3 | * | ||
4 | * COPYRIGHT (c) 2008 | ||
5 | * The Regents of the University of Michigan | ||
6 | * ALL RIGHTS RESERVED | ||
7 | * | ||
8 | * Permission is granted to use, copy, create derivative works | ||
9 | * and redistribute this software and such derivative works | ||
10 | * for any purpose, so long as the name of The University of | ||
11 | * Michigan is not used in any advertising or publicity | ||
12 | * pertaining to the use of distribution of this software | ||
13 | * without specific, written prior authorization. If the | ||
14 | * above copyright notice or any other identification of the | ||
15 | * University of Michigan is included in any copy of any | ||
16 | * portion of this software, then the disclaimer below must | ||
17 | * also be included. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION | ||
20 | * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY | ||
21 | * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF | ||
22 | * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
23 | * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE | ||
25 | * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE | ||
26 | * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR | ||
27 | * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING | ||
28 | * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN | ||
29 | * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGES. | ||
31 | */ | ||
32 | |||
33 | /* Derived from various: | ||
34 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
35 | */ | ||
36 | |||
37 | /* | ||
38 | * This is the Cipher Text Stealing mode as described by | ||
39 | * Section 8 of rfc2040 and referenced by rfc3962. | ||
40 | * rfc3962 includes errata information in its Appendix A. | ||
41 | */ | ||
42 | |||
43 | #include <crypto/algapi.h> | ||
44 | #include <linux/err.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/log2.h> | ||
48 | #include <linux/module.h> | ||
49 | #include <linux/scatterlist.h> | ||
50 | #include <crypto/scatterwalk.h> | ||
51 | #include <linux/slab.h> | ||
52 | |||
53 | struct crypto_cts_ctx { | ||
54 | struct crypto_blkcipher *child; | ||
55 | }; | ||
56 | |||
57 | static int crypto_cts_setkey(struct crypto_tfm *parent, const u8 *key, | ||
58 | unsigned int keylen) | ||
59 | { | ||
60 | struct crypto_cts_ctx *ctx = crypto_tfm_ctx(parent); | ||
61 | struct crypto_blkcipher *child = ctx->child; | ||
62 | int err; | ||
63 | |||
64 | crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
65 | crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) & | ||
66 | CRYPTO_TFM_REQ_MASK); | ||
67 | err = crypto_blkcipher_setkey(child, key, keylen); | ||
68 | crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) & | ||
69 | CRYPTO_TFM_RES_MASK); | ||
70 | return err; | ||
71 | } | ||
72 | |||
73 | static int cts_cbc_encrypt(struct crypto_cts_ctx *ctx, | ||
74 | struct blkcipher_desc *desc, | ||
75 | struct scatterlist *dst, | ||
76 | struct scatterlist *src, | ||
77 | unsigned int offset, | ||
78 | unsigned int nbytes) | ||
79 | { | ||
80 | int bsize = crypto_blkcipher_blocksize(desc->tfm); | ||
81 | u8 tmp[bsize], tmp2[bsize]; | ||
82 | struct blkcipher_desc lcldesc; | ||
83 | struct scatterlist sgsrc[1], sgdst[1]; | ||
84 | int lastn = nbytes - bsize; | ||
85 | u8 iv[bsize]; | ||
86 | u8 s[bsize * 2], d[bsize * 2]; | ||
87 | int err; | ||
88 | |||
89 | if (lastn < 0) | ||
90 | return -EINVAL; | ||
91 | |||
92 | memset(s, 0, sizeof(s)); | ||
93 | scatterwalk_map_and_copy(s, src, offset, nbytes, 0); | ||
94 | |||
95 | memcpy(iv, desc->info, bsize); | ||
96 | |||
97 | lcldesc.tfm = ctx->child; | ||
98 | lcldesc.info = iv; | ||
99 | lcldesc.flags = desc->flags; | ||
100 | |||
101 | sg_set_buf(&sgsrc[0], s, bsize); | ||
102 | sg_set_buf(&sgdst[0], tmp, bsize); | ||
103 | err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); | ||
104 | |||
105 | memcpy(d + bsize, tmp, lastn); | ||
106 | |||
107 | lcldesc.info = tmp; | ||
108 | |||
109 | sg_set_buf(&sgsrc[0], s + bsize, bsize); | ||
110 | sg_set_buf(&sgdst[0], tmp2, bsize); | ||
111 | err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); | ||
112 | |||
113 | memcpy(d, tmp2, bsize); | ||
114 | |||
115 | scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); | ||
116 | |||
117 | memcpy(desc->info, tmp2, bsize); | ||
118 | |||
119 | return err; | ||
120 | } | ||
121 | |||
122 | static int crypto_cts_encrypt(struct blkcipher_desc *desc, | ||
123 | struct scatterlist *dst, struct scatterlist *src, | ||
124 | unsigned int nbytes) | ||
125 | { | ||
126 | struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
127 | int bsize = crypto_blkcipher_blocksize(desc->tfm); | ||
128 | int tot_blocks = (nbytes + bsize - 1) / bsize; | ||
129 | int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; | ||
130 | struct blkcipher_desc lcldesc; | ||
131 | int err; | ||
132 | |||
133 | lcldesc.tfm = ctx->child; | ||
134 | lcldesc.info = desc->info; | ||
135 | lcldesc.flags = desc->flags; | ||
136 | |||
137 | if (tot_blocks == 1) { | ||
138 | err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, bsize); | ||
139 | } else if (nbytes <= bsize * 2) { | ||
140 | err = cts_cbc_encrypt(ctx, desc, dst, src, 0, nbytes); | ||
141 | } else { | ||
142 | /* do normal function for tot_blocks - 2 */ | ||
143 | err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, | ||
144 | cbc_blocks * bsize); | ||
145 | if (err == 0) { | ||
146 | /* do cts for final two blocks */ | ||
147 | err = cts_cbc_encrypt(ctx, desc, dst, src, | ||
148 | cbc_blocks * bsize, | ||
149 | nbytes - (cbc_blocks * bsize)); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return err; | ||
154 | } | ||
155 | |||
156 | static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx, | ||
157 | struct blkcipher_desc *desc, | ||
158 | struct scatterlist *dst, | ||
159 | struct scatterlist *src, | ||
160 | unsigned int offset, | ||
161 | unsigned int nbytes) | ||
162 | { | ||
163 | int bsize = crypto_blkcipher_blocksize(desc->tfm); | ||
164 | u8 tmp[bsize]; | ||
165 | struct blkcipher_desc lcldesc; | ||
166 | struct scatterlist sgsrc[1], sgdst[1]; | ||
167 | int lastn = nbytes - bsize; | ||
168 | u8 iv[bsize]; | ||
169 | u8 s[bsize * 2], d[bsize * 2]; | ||
170 | int err; | ||
171 | |||
172 | if (lastn < 0) | ||
173 | return -EINVAL; | ||
174 | |||
175 | scatterwalk_map_and_copy(s, src, offset, nbytes, 0); | ||
176 | |||
177 | lcldesc.tfm = ctx->child; | ||
178 | lcldesc.info = iv; | ||
179 | lcldesc.flags = desc->flags; | ||
180 | |||
181 | /* 1. Decrypt Cn-1 (s) to create Dn (tmp)*/ | ||
182 | memset(iv, 0, sizeof(iv)); | ||
183 | sg_set_buf(&sgsrc[0], s, bsize); | ||
184 | sg_set_buf(&sgdst[0], tmp, bsize); | ||
185 | err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); | ||
186 | if (err) | ||
187 | return err; | ||
188 | /* 2. Pad Cn with zeros at the end to create C of length BB */ | ||
189 | memset(iv, 0, sizeof(iv)); | ||
190 | memcpy(iv, s + bsize, lastn); | ||
191 | /* 3. Exclusive-or Dn (tmp) with C (iv) to create Xn (tmp) */ | ||
192 | crypto_xor(tmp, iv, bsize); | ||
193 | /* 4. Select the first Ln bytes of Xn (tmp) to create Pn */ | ||
194 | memcpy(d + bsize, tmp, lastn); | ||
195 | |||
196 | /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */ | ||
197 | memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn); | ||
198 | /* 6. Decrypt En to create Pn-1 */ | ||
199 | memset(iv, 0, sizeof(iv)); | ||
200 | sg_set_buf(&sgsrc[0], s + bsize, bsize); | ||
201 | sg_set_buf(&sgdst[0], d, bsize); | ||
202 | err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); | ||
203 | |||
204 | /* XOR with previous block */ | ||
205 | crypto_xor(d, desc->info, bsize); | ||
206 | |||
207 | scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); | ||
208 | |||
209 | memcpy(desc->info, s, bsize); | ||
210 | return err; | ||
211 | } | ||
212 | |||
213 | static int crypto_cts_decrypt(struct blkcipher_desc *desc, | ||
214 | struct scatterlist *dst, struct scatterlist *src, | ||
215 | unsigned int nbytes) | ||
216 | { | ||
217 | struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
218 | int bsize = crypto_blkcipher_blocksize(desc->tfm); | ||
219 | int tot_blocks = (nbytes + bsize - 1) / bsize; | ||
220 | int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; | ||
221 | struct blkcipher_desc lcldesc; | ||
222 | int err; | ||
223 | |||
224 | lcldesc.tfm = ctx->child; | ||
225 | lcldesc.info = desc->info; | ||
226 | lcldesc.flags = desc->flags; | ||
227 | |||
228 | if (tot_blocks == 1) { | ||
229 | err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, bsize); | ||
230 | } else if (nbytes <= bsize * 2) { | ||
231 | err = cts_cbc_decrypt(ctx, desc, dst, src, 0, nbytes); | ||
232 | } else { | ||
233 | /* do normal function for tot_blocks - 2 */ | ||
234 | err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, | ||
235 | cbc_blocks * bsize); | ||
236 | if (err == 0) { | ||
237 | /* do cts for final two blocks */ | ||
238 | err = cts_cbc_decrypt(ctx, desc, dst, src, | ||
239 | cbc_blocks * bsize, | ||
240 | nbytes - (cbc_blocks * bsize)); | ||
241 | } | ||
242 | } | ||
243 | return err; | ||
244 | } | ||
245 | |||
246 | static int crypto_cts_init_tfm(struct crypto_tfm *tfm) | ||
247 | { | ||
248 | struct crypto_instance *inst = (void *)tfm->__crt_alg; | ||
249 | struct crypto_spawn *spawn = crypto_instance_ctx(inst); | ||
250 | struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
251 | struct crypto_blkcipher *cipher; | ||
252 | |||
253 | cipher = crypto_spawn_blkcipher(spawn); | ||
254 | if (IS_ERR(cipher)) | ||
255 | return PTR_ERR(cipher); | ||
256 | |||
257 | ctx->child = cipher; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static void crypto_cts_exit_tfm(struct crypto_tfm *tfm) | ||
262 | { | ||
263 | struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
264 | crypto_free_blkcipher(ctx->child); | ||
265 | } | ||
266 | |||
267 | static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) | ||
268 | { | ||
269 | struct crypto_instance *inst; | ||
270 | struct crypto_alg *alg; | ||
271 | int err; | ||
272 | |||
273 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | ||
274 | if (err) | ||
275 | return ERR_PTR(err); | ||
276 | |||
277 | alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, | ||
278 | CRYPTO_ALG_TYPE_MASK); | ||
279 | err = PTR_ERR(alg); | ||
280 | if (IS_ERR(alg)) | ||
281 | return ERR_PTR(err); | ||
282 | |||
283 | inst = ERR_PTR(-EINVAL); | ||
284 | if (!is_power_of_2(alg->cra_blocksize)) | ||
285 | goto out_put_alg; | ||
286 | |||
287 | inst = crypto_alloc_instance("cts", alg); | ||
288 | if (IS_ERR(inst)) | ||
289 | goto out_put_alg; | ||
290 | |||
291 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; | ||
292 | inst->alg.cra_priority = alg->cra_priority; | ||
293 | inst->alg.cra_blocksize = alg->cra_blocksize; | ||
294 | inst->alg.cra_alignmask = alg->cra_alignmask; | ||
295 | inst->alg.cra_type = &crypto_blkcipher_type; | ||
296 | |||
297 | /* We access the data as u32s when xoring. */ | ||
298 | inst->alg.cra_alignmask |= __alignof__(u32) - 1; | ||
299 | |||
300 | inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize; | ||
301 | inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize; | ||
302 | inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize; | ||
303 | |||
304 | inst->alg.cra_blkcipher.geniv = "seqiv"; | ||
305 | |||
306 | inst->alg.cra_ctxsize = sizeof(struct crypto_cts_ctx); | ||
307 | |||
308 | inst->alg.cra_init = crypto_cts_init_tfm; | ||
309 | inst->alg.cra_exit = crypto_cts_exit_tfm; | ||
310 | |||
311 | inst->alg.cra_blkcipher.setkey = crypto_cts_setkey; | ||
312 | inst->alg.cra_blkcipher.encrypt = crypto_cts_encrypt; | ||
313 | inst->alg.cra_blkcipher.decrypt = crypto_cts_decrypt; | ||
314 | |||
315 | out_put_alg: | ||
316 | crypto_mod_put(alg); | ||
317 | return inst; | ||
318 | } | ||
319 | |||
320 | static void crypto_cts_free(struct crypto_instance *inst) | ||
321 | { | ||
322 | crypto_drop_spawn(crypto_instance_ctx(inst)); | ||
323 | kfree(inst); | ||
324 | } | ||
325 | |||
326 | static struct crypto_template crypto_cts_tmpl = { | ||
327 | .name = "cts", | ||
328 | .alloc = crypto_cts_alloc, | ||
329 | .free = crypto_cts_free, | ||
330 | .module = THIS_MODULE, | ||
331 | }; | ||
332 | |||
333 | static int __init crypto_cts_module_init(void) | ||
334 | { | ||
335 | return crypto_register_template(&crypto_cts_tmpl); | ||
336 | } | ||
337 | |||
338 | static void __exit crypto_cts_module_exit(void) | ||
339 | { | ||
340 | crypto_unregister_template(&crypto_cts_tmpl); | ||
341 | } | ||
342 | |||
343 | module_init(crypto_cts_module_init); | ||
344 | module_exit(crypto_cts_module_exit); | ||
345 | |||
346 | MODULE_LICENSE("Dual BSD/GPL"); | ||
347 | MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC"); | ||
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 30e75d49f35a..689482cd16c2 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
@@ -82,9 +82,8 @@ static char *check[] = { | |||
82 | "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", | 82 | "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", |
83 | "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", | 83 | "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", |
84 | "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", | 84 | "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", |
85 | "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", | ||
86 | "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", | 85 | "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", |
87 | "camellia", "seed", "salsa20", "lzo", NULL | 86 | "camellia", "seed", "salsa20", "lzo", "cts", NULL |
88 | }; | 87 | }; |
89 | 88 | ||
90 | static void hexdump(unsigned char *buf, unsigned int len) | 89 | static void hexdump(unsigned char *buf, unsigned int len) |
@@ -1328,6 +1327,12 @@ static void do_test(void) | |||
1328 | test_cipher("ecb(seed)", DECRYPT, seed_dec_tv_template, | 1327 | test_cipher("ecb(seed)", DECRYPT, seed_dec_tv_template, |
1329 | SEED_DEC_TEST_VECTORS); | 1328 | SEED_DEC_TEST_VECTORS); |
1330 | 1329 | ||
1330 | //CTS | ||
1331 | test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template, | ||
1332 | CTS_MODE_ENC_TEST_VECTORS); | ||
1333 | test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template, | ||
1334 | CTS_MODE_DEC_TEST_VECTORS); | ||
1335 | |||
1331 | test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); | 1336 | test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); |
1332 | test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); | 1337 | test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); |
1333 | test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); | 1338 | test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); |
@@ -1611,6 +1616,13 @@ static void do_test(void) | |||
1611 | AES_CCM_DEC_TEST_VECTORS); | 1616 | AES_CCM_DEC_TEST_VECTORS); |
1612 | break; | 1617 | break; |
1613 | 1618 | ||
1619 | case 38: | ||
1620 | test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template, | ||
1621 | CTS_MODE_ENC_TEST_VECTORS); | ||
1622 | test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template, | ||
1623 | CTS_MODE_DEC_TEST_VECTORS); | ||
1624 | break; | ||
1625 | |||
1614 | case 100: | 1626 | case 100: |
1615 | test_hash("hmac(md5)", hmac_md5_tv_template, | 1627 | test_hash("hmac(md5)", hmac_md5_tv_template, |
1616 | HMAC_MD5_TEST_VECTORS); | 1628 | HMAC_MD5_TEST_VECTORS); |
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index aae79e9c256c..47bc0ecb8978 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h | |||
@@ -7623,6 +7623,215 @@ static struct cipher_testvec salsa20_stream_enc_tv_template[] = { | |||
7623 | }; | 7623 | }; |
7624 | 7624 | ||
7625 | /* | 7625 | /* |
7626 | * CTS (Cipher Text Stealing) mode tests | ||
7627 | */ | ||
7628 | #define CTS_MODE_ENC_TEST_VECTORS 6 | ||
7629 | #define CTS_MODE_DEC_TEST_VECTORS 6 | ||
7630 | static struct cipher_testvec cts_mode_enc_tv_template[] = { | ||
7631 | { /* from rfc3962 */ | ||
7632 | .klen = 16, | ||
7633 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7634 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7635 | .ilen = 17, | ||
7636 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7637 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7638 | "\x20", | ||
7639 | .rlen = 17, | ||
7640 | .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4" | ||
7641 | "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" | ||
7642 | "\x97", | ||
7643 | }, { | ||
7644 | .klen = 16, | ||
7645 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7646 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7647 | .ilen = 31, | ||
7648 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7649 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7650 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7651 | "\x20\x47\x61\x75\x27\x73\x20", | ||
7652 | .rlen = 31, | ||
7653 | .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" | ||
7654 | "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" | ||
7655 | "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7656 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5", | ||
7657 | }, { | ||
7658 | .klen = 16, | ||
7659 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7660 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7661 | .ilen = 32, | ||
7662 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7663 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7664 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7665 | "\x20\x47\x61\x75\x27\x73\x20\x43", | ||
7666 | .rlen = 32, | ||
7667 | .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7668 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" | ||
7669 | "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7670 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", | ||
7671 | }, { | ||
7672 | .klen = 16, | ||
7673 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7674 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7675 | .ilen = 47, | ||
7676 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7677 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7678 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7679 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7680 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7681 | "\x70\x6c\x65\x61\x73\x65\x2c", | ||
7682 | .rlen = 47, | ||
7683 | .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7684 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7685 | "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c" | ||
7686 | "\x1b\x55\x49\xd2\xf8\x38\x02\x9e" | ||
7687 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7688 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5", | ||
7689 | }, { | ||
7690 | .klen = 16, | ||
7691 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7692 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7693 | .ilen = 48, | ||
7694 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7695 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7696 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7697 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7698 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7699 | "\x70\x6c\x65\x61\x73\x65\x2c\x20", | ||
7700 | .rlen = 48, | ||
7701 | .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7702 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7703 | "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" | ||
7704 | "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" | ||
7705 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7706 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", | ||
7707 | }, { | ||
7708 | .klen = 16, | ||
7709 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7710 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7711 | .ilen = 64, | ||
7712 | .input = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7713 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7714 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7715 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7716 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7717 | "\x70\x6c\x65\x61\x73\x65\x2c\x20" | ||
7718 | "\x61\x6e\x64\x20\x77\x6f\x6e\x74" | ||
7719 | "\x6f\x6e\x20\x73\x6f\x75\x70\x2e", | ||
7720 | .rlen = 64, | ||
7721 | .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7722 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7723 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7724 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" | ||
7725 | "\x48\x07\xef\xe8\x36\xee\x89\xa5" | ||
7726 | "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" | ||
7727 | "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" | ||
7728 | "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", | ||
7729 | } | ||
7730 | }; | ||
7731 | |||
7732 | static struct cipher_testvec cts_mode_dec_tv_template[] = { | ||
7733 | { /* from rfc3962 */ | ||
7734 | .klen = 16, | ||
7735 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7736 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7737 | .rlen = 17, | ||
7738 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7739 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7740 | "\x20", | ||
7741 | .ilen = 17, | ||
7742 | .input = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4" | ||
7743 | "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" | ||
7744 | "\x97", | ||
7745 | }, { | ||
7746 | .klen = 16, | ||
7747 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7748 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7749 | .rlen = 31, | ||
7750 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7751 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7752 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7753 | "\x20\x47\x61\x75\x27\x73\x20", | ||
7754 | .ilen = 31, | ||
7755 | .input = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" | ||
7756 | "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" | ||
7757 | "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7758 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5", | ||
7759 | }, { | ||
7760 | .klen = 16, | ||
7761 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7762 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7763 | .rlen = 32, | ||
7764 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7765 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7766 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7767 | "\x20\x47\x61\x75\x27\x73\x20\x43", | ||
7768 | .ilen = 32, | ||
7769 | .input = "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7770 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" | ||
7771 | "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7772 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", | ||
7773 | }, { | ||
7774 | .klen = 16, | ||
7775 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7776 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7777 | .rlen = 47, | ||
7778 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7779 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7780 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7781 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7782 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7783 | "\x70\x6c\x65\x61\x73\x65\x2c", | ||
7784 | .ilen = 47, | ||
7785 | .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7786 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7787 | "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c" | ||
7788 | "\x1b\x55\x49\xd2\xf8\x38\x02\x9e" | ||
7789 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7790 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5", | ||
7791 | }, { | ||
7792 | .klen = 16, | ||
7793 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7794 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7795 | .rlen = 48, | ||
7796 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7797 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7798 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7799 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7800 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7801 | "\x70\x6c\x65\x61\x73\x65\x2c\x20", | ||
7802 | .ilen = 48, | ||
7803 | .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7804 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7805 | "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" | ||
7806 | "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" | ||
7807 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7808 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", | ||
7809 | }, { | ||
7810 | .klen = 16, | ||
7811 | .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" | ||
7812 | "\x74\x65\x72\x69\x79\x61\x6b\x69", | ||
7813 | .rlen = 64, | ||
7814 | .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20" | ||
7815 | "\x6c\x69\x6b\x65\x20\x74\x68\x65" | ||
7816 | "\x20\x47\x65\x6e\x65\x72\x61\x6c" | ||
7817 | "\x20\x47\x61\x75\x27\x73\x20\x43" | ||
7818 | "\x68\x69\x63\x6b\x65\x6e\x2c\x20" | ||
7819 | "\x70\x6c\x65\x61\x73\x65\x2c\x20" | ||
7820 | "\x61\x6e\x64\x20\x77\x6f\x6e\x74" | ||
7821 | "\x6f\x6e\x20\x73\x6f\x75\x70\x2e", | ||
7822 | .ilen = 64, | ||
7823 | .input = "\x97\x68\x72\x68\xd6\xec\xcc\xc0" | ||
7824 | "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" | ||
7825 | "\x39\x31\x25\x23\xa7\x86\x62\xd5" | ||
7826 | "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" | ||
7827 | "\x48\x07\xef\xe8\x36\xee\x89\xa5" | ||
7828 | "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" | ||
7829 | "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0" | ||
7830 | "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", | ||
7831 | } | ||
7832 | }; | ||
7833 | |||
7834 | /* | ||
7626 | * Compression stuff. | 7835 | * Compression stuff. |
7627 | */ | 7836 | */ |
7628 | #define COMP_BUF_SIZE 512 | 7837 | #define COMP_BUF_SIZE 512 |