Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.8 614 lines 17 kB view raw
1/* 2 * Glue Code for AVX assembler versions of Serpent Cipher 3 * 4 * Copyright (C) 2012 Johannes Goetzfried 5 * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> 6 * 7 * Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 * USA 23 * 24 */ 25 26#include <linux/module.h> 27#include <linux/hardirq.h> 28#include <linux/types.h> 29#include <linux/crypto.h> 30#include <linux/err.h> 31#include <crypto/ablk_helper.h> 32#include <crypto/algapi.h> 33#include <crypto/serpent.h> 34#include <crypto/cryptd.h> 35#include <crypto/b128ops.h> 36#include <crypto/ctr.h> 37#include <crypto/lrw.h> 38#include <crypto/xts.h> 39#include <asm/fpu/api.h> 40#include <asm/crypto/serpent-avx.h> 41#include <asm/crypto/glue_helper.h> 42 43/* 8-way parallel cipher functions */ 44asmlinkage void serpent_ecb_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, 45 const u8 *src); 46EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx); 47 48asmlinkage void serpent_ecb_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, 49 const u8 *src); 50EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx); 51 52asmlinkage void serpent_cbc_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, 53 const u8 *src); 54EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx); 55 56asmlinkage void serpent_ctr_8way_avx(struct serpent_ctx *ctx, u8 *dst, 57 const u8 *src, le128 *iv); 58EXPORT_SYMBOL_GPL(serpent_ctr_8way_avx); 59 60asmlinkage void serpent_xts_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, 61 const u8 *src, le128 *iv); 62EXPORT_SYMBOL_GPL(serpent_xts_enc_8way_avx); 63 64asmlinkage void serpent_xts_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, 65 const u8 *src, le128 *iv); 66EXPORT_SYMBOL_GPL(serpent_xts_dec_8way_avx); 67 68void __serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) 69{ 70 be128 ctrblk; 71 72 le128_to_be128(&ctrblk, iv); 73 le128_inc(iv); 74 75 __serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); 76 u128_xor(dst, src, (u128 *)&ctrblk); 77} 78EXPORT_SYMBOL_GPL(__serpent_crypt_ctr); 79 80void serpent_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) 81{ 82 glue_xts_crypt_128bit_one(ctx, dst, src, iv, 83 GLUE_FUNC_CAST(__serpent_encrypt)); 84} 85EXPORT_SYMBOL_GPL(serpent_xts_enc); 86 87void serpent_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) 88{ 89 glue_xts_crypt_128bit_one(ctx, dst, src, iv, 90 GLUE_FUNC_CAST(__serpent_decrypt)); 91} 92EXPORT_SYMBOL_GPL(serpent_xts_dec); 93 94 95static const struct common_glue_ctx serpent_enc = { 96 .num_funcs = 2, 97 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 98 99 .funcs = { { 100 .num_blocks = SERPENT_PARALLEL_BLOCKS, 101 .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_enc_8way_avx) } 102 }, { 103 .num_blocks = 1, 104 .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } 105 } } 106}; 107 108static const struct common_glue_ctx serpent_ctr = { 109 .num_funcs = 2, 110 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 111 112 .funcs = { { 113 .num_blocks = SERPENT_PARALLEL_BLOCKS, 114 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_ctr_8way_avx) } 115 }, { 116 .num_blocks = 1, 117 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(__serpent_crypt_ctr) } 118 } } 119}; 120 121static const struct common_glue_ctx serpent_enc_xts = { 122 .num_funcs = 2, 123 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 124 125 .funcs = { { 126 .num_blocks = SERPENT_PARALLEL_BLOCKS, 127 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc_8way_avx) } 128 }, { 129 .num_blocks = 1, 130 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc) } 131 } } 132}; 133 134static const struct common_glue_ctx serpent_dec = { 135 .num_funcs = 2, 136 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 137 138 .funcs = { { 139 .num_blocks = SERPENT_PARALLEL_BLOCKS, 140 .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_dec_8way_avx) } 141 }, { 142 .num_blocks = 1, 143 .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } 144 } } 145}; 146 147static const struct common_glue_ctx serpent_dec_cbc = { 148 .num_funcs = 2, 149 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 150 151 .funcs = { { 152 .num_blocks = SERPENT_PARALLEL_BLOCKS, 153 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_cbc_dec_8way_avx) } 154 }, { 155 .num_blocks = 1, 156 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } 157 } } 158}; 159 160static const struct common_glue_ctx serpent_dec_xts = { 161 .num_funcs = 2, 162 .fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS, 163 164 .funcs = { { 165 .num_blocks = SERPENT_PARALLEL_BLOCKS, 166 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec_8way_avx) } 167 }, { 168 .num_blocks = 1, 169 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec) } 170 } } 171}; 172 173static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 174 struct scatterlist *src, unsigned int nbytes) 175{ 176 return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes); 177} 178 179static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 180 struct scatterlist *src, unsigned int nbytes) 181{ 182 return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes); 183} 184 185static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 186 struct scatterlist *src, unsigned int nbytes) 187{ 188 return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc, 189 dst, src, nbytes); 190} 191 192static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 193 struct scatterlist *src, unsigned int nbytes) 194{ 195 return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src, 196 nbytes); 197} 198 199static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, 200 struct scatterlist *src, unsigned int nbytes) 201{ 202 return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes); 203} 204 205static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes) 206{ 207 return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS, 208 NULL, fpu_enabled, nbytes); 209} 210 211static inline void serpent_fpu_end(bool fpu_enabled) 212{ 213 glue_fpu_end(fpu_enabled); 214} 215 216struct crypt_priv { 217 struct serpent_ctx *ctx; 218 bool fpu_enabled; 219}; 220 221static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) 222{ 223 const unsigned int bsize = SERPENT_BLOCK_SIZE; 224 struct crypt_priv *ctx = priv; 225 int i; 226 227 ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); 228 229 if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { 230 serpent_ecb_enc_8way_avx(ctx->ctx, srcdst, srcdst); 231 return; 232 } 233 234 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) 235 __serpent_encrypt(ctx->ctx, srcdst, srcdst); 236} 237 238static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) 239{ 240 const unsigned int bsize = SERPENT_BLOCK_SIZE; 241 struct crypt_priv *ctx = priv; 242 int i; 243 244 ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes); 245 246 if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) { 247 serpent_ecb_dec_8way_avx(ctx->ctx, srcdst, srcdst); 248 return; 249 } 250 251 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) 252 __serpent_decrypt(ctx->ctx, srcdst, srcdst); 253} 254 255int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, 256 unsigned int keylen) 257{ 258 struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); 259 int err; 260 261 err = __serpent_setkey(&ctx->serpent_ctx, key, keylen - 262 SERPENT_BLOCK_SIZE); 263 if (err) 264 return err; 265 266 return lrw_init_table(&ctx->lrw_table, key + keylen - 267 SERPENT_BLOCK_SIZE); 268} 269EXPORT_SYMBOL_GPL(lrw_serpent_setkey); 270 271static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 272 struct scatterlist *src, unsigned int nbytes) 273{ 274 struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 275 be128 buf[SERPENT_PARALLEL_BLOCKS]; 276 struct crypt_priv crypt_ctx = { 277 .ctx = &ctx->serpent_ctx, 278 .fpu_enabled = false, 279 }; 280 struct lrw_crypt_req req = { 281 .tbuf = buf, 282 .tbuflen = sizeof(buf), 283 284 .table_ctx = &ctx->lrw_table, 285 .crypt_ctx = &crypt_ctx, 286 .crypt_fn = encrypt_callback, 287 }; 288 int ret; 289 290 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 291 ret = lrw_crypt(desc, dst, src, nbytes, &req); 292 serpent_fpu_end(crypt_ctx.fpu_enabled); 293 294 return ret; 295} 296 297static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 298 struct scatterlist *src, unsigned int nbytes) 299{ 300 struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 301 be128 buf[SERPENT_PARALLEL_BLOCKS]; 302 struct crypt_priv crypt_ctx = { 303 .ctx = &ctx->serpent_ctx, 304 .fpu_enabled = false, 305 }; 306 struct lrw_crypt_req req = { 307 .tbuf = buf, 308 .tbuflen = sizeof(buf), 309 310 .table_ctx = &ctx->lrw_table, 311 .crypt_ctx = &crypt_ctx, 312 .crypt_fn = decrypt_callback, 313 }; 314 int ret; 315 316 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 317 ret = lrw_crypt(desc, dst, src, nbytes, &req); 318 serpent_fpu_end(crypt_ctx.fpu_enabled); 319 320 return ret; 321} 322 323void lrw_serpent_exit_tfm(struct crypto_tfm *tfm) 324{ 325 struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm); 326 327 lrw_free_table(&ctx->lrw_table); 328} 329EXPORT_SYMBOL_GPL(lrw_serpent_exit_tfm); 330 331int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key, 332 unsigned int keylen) 333{ 334 struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm); 335 int err; 336 337 err = xts_check_key(tfm, key, keylen); 338 if (err) 339 return err; 340 341 /* first half of xts-key is for crypt */ 342 err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2); 343 if (err) 344 return err; 345 346 /* second half of xts-key is for tweak */ 347 return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2); 348} 349EXPORT_SYMBOL_GPL(xts_serpent_setkey); 350 351static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 352 struct scatterlist *src, unsigned int nbytes) 353{ 354 struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 355 356 return glue_xts_crypt_128bit(&serpent_enc_xts, desc, dst, src, nbytes, 357 XTS_TWEAK_CAST(__serpent_encrypt), 358 &ctx->tweak_ctx, &ctx->crypt_ctx); 359} 360 361static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 362 struct scatterlist *src, unsigned int nbytes) 363{ 364 struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 365 366 return glue_xts_crypt_128bit(&serpent_dec_xts, desc, dst, src, nbytes, 367 XTS_TWEAK_CAST(__serpent_encrypt), 368 &ctx->tweak_ctx, &ctx->crypt_ctx); 369} 370 371static struct crypto_alg serpent_algs[10] = { { 372 .cra_name = "__ecb-serpent-avx", 373 .cra_driver_name = "__driver-ecb-serpent-avx", 374 .cra_priority = 0, 375 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 376 CRYPTO_ALG_INTERNAL, 377 .cra_blocksize = SERPENT_BLOCK_SIZE, 378 .cra_ctxsize = sizeof(struct serpent_ctx), 379 .cra_alignmask = 0, 380 .cra_type = &crypto_blkcipher_type, 381 .cra_module = THIS_MODULE, 382 .cra_u = { 383 .blkcipher = { 384 .min_keysize = SERPENT_MIN_KEY_SIZE, 385 .max_keysize = SERPENT_MAX_KEY_SIZE, 386 .setkey = serpent_setkey, 387 .encrypt = ecb_encrypt, 388 .decrypt = ecb_decrypt, 389 }, 390 }, 391}, { 392 .cra_name = "__cbc-serpent-avx", 393 .cra_driver_name = "__driver-cbc-serpent-avx", 394 .cra_priority = 0, 395 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 396 CRYPTO_ALG_INTERNAL, 397 .cra_blocksize = SERPENT_BLOCK_SIZE, 398 .cra_ctxsize = sizeof(struct serpent_ctx), 399 .cra_alignmask = 0, 400 .cra_type = &crypto_blkcipher_type, 401 .cra_module = THIS_MODULE, 402 .cra_u = { 403 .blkcipher = { 404 .min_keysize = SERPENT_MIN_KEY_SIZE, 405 .max_keysize = SERPENT_MAX_KEY_SIZE, 406 .setkey = serpent_setkey, 407 .encrypt = cbc_encrypt, 408 .decrypt = cbc_decrypt, 409 }, 410 }, 411}, { 412 .cra_name = "__ctr-serpent-avx", 413 .cra_driver_name = "__driver-ctr-serpent-avx", 414 .cra_priority = 0, 415 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 416 CRYPTO_ALG_INTERNAL, 417 .cra_blocksize = 1, 418 .cra_ctxsize = sizeof(struct serpent_ctx), 419 .cra_alignmask = 0, 420 .cra_type = &crypto_blkcipher_type, 421 .cra_module = THIS_MODULE, 422 .cra_u = { 423 .blkcipher = { 424 .min_keysize = SERPENT_MIN_KEY_SIZE, 425 .max_keysize = SERPENT_MAX_KEY_SIZE, 426 .ivsize = SERPENT_BLOCK_SIZE, 427 .setkey = serpent_setkey, 428 .encrypt = ctr_crypt, 429 .decrypt = ctr_crypt, 430 }, 431 }, 432}, { 433 .cra_name = "__lrw-serpent-avx", 434 .cra_driver_name = "__driver-lrw-serpent-avx", 435 .cra_priority = 0, 436 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 437 CRYPTO_ALG_INTERNAL, 438 .cra_blocksize = SERPENT_BLOCK_SIZE, 439 .cra_ctxsize = sizeof(struct serpent_lrw_ctx), 440 .cra_alignmask = 0, 441 .cra_type = &crypto_blkcipher_type, 442 .cra_module = THIS_MODULE, 443 .cra_exit = lrw_serpent_exit_tfm, 444 .cra_u = { 445 .blkcipher = { 446 .min_keysize = SERPENT_MIN_KEY_SIZE + 447 SERPENT_BLOCK_SIZE, 448 .max_keysize = SERPENT_MAX_KEY_SIZE + 449 SERPENT_BLOCK_SIZE, 450 .ivsize = SERPENT_BLOCK_SIZE, 451 .setkey = lrw_serpent_setkey, 452 .encrypt = lrw_encrypt, 453 .decrypt = lrw_decrypt, 454 }, 455 }, 456}, { 457 .cra_name = "__xts-serpent-avx", 458 .cra_driver_name = "__driver-xts-serpent-avx", 459 .cra_priority = 0, 460 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 461 CRYPTO_ALG_INTERNAL, 462 .cra_blocksize = SERPENT_BLOCK_SIZE, 463 .cra_ctxsize = sizeof(struct serpent_xts_ctx), 464 .cra_alignmask = 0, 465 .cra_type = &crypto_blkcipher_type, 466 .cra_module = THIS_MODULE, 467 .cra_u = { 468 .blkcipher = { 469 .min_keysize = SERPENT_MIN_KEY_SIZE * 2, 470 .max_keysize = SERPENT_MAX_KEY_SIZE * 2, 471 .ivsize = SERPENT_BLOCK_SIZE, 472 .setkey = xts_serpent_setkey, 473 .encrypt = xts_encrypt, 474 .decrypt = xts_decrypt, 475 }, 476 }, 477}, { 478 .cra_name = "ecb(serpent)", 479 .cra_driver_name = "ecb-serpent-avx", 480 .cra_priority = 500, 481 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 482 .cra_blocksize = SERPENT_BLOCK_SIZE, 483 .cra_ctxsize = sizeof(struct async_helper_ctx), 484 .cra_alignmask = 0, 485 .cra_type = &crypto_ablkcipher_type, 486 .cra_module = THIS_MODULE, 487 .cra_init = ablk_init, 488 .cra_exit = ablk_exit, 489 .cra_u = { 490 .ablkcipher = { 491 .min_keysize = SERPENT_MIN_KEY_SIZE, 492 .max_keysize = SERPENT_MAX_KEY_SIZE, 493 .setkey = ablk_set_key, 494 .encrypt = ablk_encrypt, 495 .decrypt = ablk_decrypt, 496 }, 497 }, 498}, { 499 .cra_name = "cbc(serpent)", 500 .cra_driver_name = "cbc-serpent-avx", 501 .cra_priority = 500, 502 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 503 .cra_blocksize = SERPENT_BLOCK_SIZE, 504 .cra_ctxsize = sizeof(struct async_helper_ctx), 505 .cra_alignmask = 0, 506 .cra_type = &crypto_ablkcipher_type, 507 .cra_module = THIS_MODULE, 508 .cra_init = ablk_init, 509 .cra_exit = ablk_exit, 510 .cra_u = { 511 .ablkcipher = { 512 .min_keysize = SERPENT_MIN_KEY_SIZE, 513 .max_keysize = SERPENT_MAX_KEY_SIZE, 514 .ivsize = SERPENT_BLOCK_SIZE, 515 .setkey = ablk_set_key, 516 .encrypt = __ablk_encrypt, 517 .decrypt = ablk_decrypt, 518 }, 519 }, 520}, { 521 .cra_name = "ctr(serpent)", 522 .cra_driver_name = "ctr-serpent-avx", 523 .cra_priority = 500, 524 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 525 .cra_blocksize = 1, 526 .cra_ctxsize = sizeof(struct async_helper_ctx), 527 .cra_alignmask = 0, 528 .cra_type = &crypto_ablkcipher_type, 529 .cra_module = THIS_MODULE, 530 .cra_init = ablk_init, 531 .cra_exit = ablk_exit, 532 .cra_u = { 533 .ablkcipher = { 534 .min_keysize = SERPENT_MIN_KEY_SIZE, 535 .max_keysize = SERPENT_MAX_KEY_SIZE, 536 .ivsize = SERPENT_BLOCK_SIZE, 537 .setkey = ablk_set_key, 538 .encrypt = ablk_encrypt, 539 .decrypt = ablk_encrypt, 540 .geniv = "chainiv", 541 }, 542 }, 543}, { 544 .cra_name = "lrw(serpent)", 545 .cra_driver_name = "lrw-serpent-avx", 546 .cra_priority = 500, 547 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 548 .cra_blocksize = SERPENT_BLOCK_SIZE, 549 .cra_ctxsize = sizeof(struct async_helper_ctx), 550 .cra_alignmask = 0, 551 .cra_type = &crypto_ablkcipher_type, 552 .cra_module = THIS_MODULE, 553 .cra_init = ablk_init, 554 .cra_exit = ablk_exit, 555 .cra_u = { 556 .ablkcipher = { 557 .min_keysize = SERPENT_MIN_KEY_SIZE + 558 SERPENT_BLOCK_SIZE, 559 .max_keysize = SERPENT_MAX_KEY_SIZE + 560 SERPENT_BLOCK_SIZE, 561 .ivsize = SERPENT_BLOCK_SIZE, 562 .setkey = ablk_set_key, 563 .encrypt = ablk_encrypt, 564 .decrypt = ablk_decrypt, 565 }, 566 }, 567}, { 568 .cra_name = "xts(serpent)", 569 .cra_driver_name = "xts-serpent-avx", 570 .cra_priority = 500, 571 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 572 .cra_blocksize = SERPENT_BLOCK_SIZE, 573 .cra_ctxsize = sizeof(struct async_helper_ctx), 574 .cra_alignmask = 0, 575 .cra_type = &crypto_ablkcipher_type, 576 .cra_module = THIS_MODULE, 577 .cra_init = ablk_init, 578 .cra_exit = ablk_exit, 579 .cra_u = { 580 .ablkcipher = { 581 .min_keysize = SERPENT_MIN_KEY_SIZE * 2, 582 .max_keysize = SERPENT_MAX_KEY_SIZE * 2, 583 .ivsize = SERPENT_BLOCK_SIZE, 584 .setkey = ablk_set_key, 585 .encrypt = ablk_encrypt, 586 .decrypt = ablk_decrypt, 587 }, 588 }, 589} }; 590 591static int __init serpent_init(void) 592{ 593 const char *feature_name; 594 595 if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, 596 &feature_name)) { 597 pr_info("CPU feature '%s' is not supported.\n", feature_name); 598 return -ENODEV; 599 } 600 601 return crypto_register_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); 602} 603 604static void __exit serpent_exit(void) 605{ 606 crypto_unregister_algs(serpent_algs, ARRAY_SIZE(serpent_algs)); 607} 608 609module_init(serpent_init); 610module_exit(serpent_exit); 611 612MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized"); 613MODULE_LICENSE("GPL"); 614MODULE_ALIAS_CRYPTO("serpent");