1/* 2 * Glue Code for x86_64/AVX2/AES-NI assembler optimized version of Camellia 3 * 4 * Copyright �� 2013 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 */ 12 13#include <linux/module.h> 14#include <linux/types.h> 15#include <linux/crypto.h> 16#include <linux/err.h> 17#include <crypto/ablk_helper.h> 18#include <crypto/algapi.h> 19#include <crypto/ctr.h> 20#include <crypto/lrw.h> 21#include <crypto/xts.h> 22#include <asm/fpu/api.h> 23#include <asm/crypto/camellia.h> 24#include <asm/crypto/glue_helper.h> 25 26#define CAMELLIA_AESNI_PARALLEL_BLOCKS 16 27#define CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS 32 28 29/* 32-way AVX2/AES-NI parallel cipher functions */ 30asmlinkage void camellia_ecb_enc_32way(struct camellia_ctx *ctx, u8 *dst, 31 const u8 *src); 32asmlinkage void camellia_ecb_dec_32way(struct camellia_ctx *ctx, u8 *dst, 33 const u8 *src); 34 35asmlinkage void camellia_cbc_dec_32way(struct camellia_ctx *ctx, u8 *dst, 36 const u8 *src); 37asmlinkage void camellia_ctr_32way(struct camellia_ctx *ctx, u8 *dst, 38 const u8 *src, le128 *iv); 39 40asmlinkage void camellia_xts_enc_32way(struct camellia_ctx *ctx, u8 *dst, 41 const u8 *src, le128 *iv); 42asmlinkage void camellia_xts_dec_32way(struct camellia_ctx *ctx, u8 *dst, 43 const u8 *src, le128 *iv); 44 45static const struct common_glue_ctx camellia_enc = { 46 .num_funcs = 4, 47 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 48 49 .funcs = { { 50 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 51 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_enc_32way) } 52 }, { 53 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 54 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_enc_16way) } 55 }, { 56 .num_blocks = 2, 57 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } 58 }, { 59 .num_blocks = 1, 60 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } 61 } } 62}; 63 64static const struct common_glue_ctx camellia_ctr = { 65 .num_funcs = 4, 66 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 67 68 .funcs = { { 69 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 70 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_ctr_32way) } 71 }, { 72 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 73 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_ctr_16way) } 74 }, { 75 .num_blocks = 2, 76 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } 77 }, { 78 .num_blocks = 1, 79 .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } 80 } } 81}; 82 83static const struct common_glue_ctx camellia_enc_xts = { 84 .num_funcs = 3, 85 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 86 87 .funcs = { { 88 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 89 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc_32way) } 90 }, { 91 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 92 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc_16way) } 93 }, { 94 .num_blocks = 1, 95 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc) } 96 } } 97}; 98 99static const struct common_glue_ctx camellia_dec = { 100 .num_funcs = 4, 101 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 102 103 .funcs = { { 104 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 105 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_dec_32way) } 106 }, { 107 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 108 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_dec_16way) } 109 }, { 110 .num_blocks = 2, 111 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } 112 }, { 113 .num_blocks = 1, 114 .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } 115 } } 116}; 117 118static const struct common_glue_ctx camellia_dec_cbc = { 119 .num_funcs = 4, 120 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 121 122 .funcs = { { 123 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 124 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_cbc_dec_32way) } 125 }, { 126 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 127 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_cbc_dec_16way) } 128 }, { 129 .num_blocks = 2, 130 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } 131 }, { 132 .num_blocks = 1, 133 .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } 134 } } 135}; 136 137static const struct common_glue_ctx camellia_dec_xts = { 138 .num_funcs = 3, 139 .fpu_blocks_limit = CAMELLIA_AESNI_PARALLEL_BLOCKS, 140 141 .funcs = { { 142 .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, 143 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec_32way) } 144 }, { 145 .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, 146 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec_16way) } 147 }, { 148 .num_blocks = 1, 149 .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec) } 150 } } 151}; 152 153static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 154 struct scatterlist *src, unsigned int nbytes) 155{ 156 return glue_ecb_crypt_128bit(&camellia_enc, desc, dst, src, nbytes); 157} 158 159static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 160 struct scatterlist *src, unsigned int nbytes) 161{ 162 return glue_ecb_crypt_128bit(&camellia_dec, desc, dst, src, nbytes); 163} 164 165static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 166 struct scatterlist *src, unsigned int nbytes) 167{ 168 return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(camellia_enc_blk), desc, 169 dst, src, nbytes); 170} 171 172static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 173 struct scatterlist *src, unsigned int nbytes) 174{ 175 return glue_cbc_decrypt_128bit(&camellia_dec_cbc, desc, dst, src, 176 nbytes); 177} 178 179static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, 180 struct scatterlist *src, unsigned int nbytes) 181{ 182 return glue_ctr_crypt_128bit(&camellia_ctr, desc, dst, src, nbytes); 183} 184 185static inline bool camellia_fpu_begin(bool fpu_enabled, unsigned int nbytes) 186{ 187 return glue_fpu_begin(CAMELLIA_BLOCK_SIZE, 188 CAMELLIA_AESNI_PARALLEL_BLOCKS, NULL, fpu_enabled, 189 nbytes); 190} 191 192static inline void camellia_fpu_end(bool fpu_enabled) 193{ 194 glue_fpu_end(fpu_enabled); 195} 196 197static int camellia_setkey(struct crypto_tfm *tfm, const u8 *in_key, 198 unsigned int key_len) 199{ 200 return __camellia_setkey(crypto_tfm_ctx(tfm), in_key, key_len, 201 &tfm->crt_flags); 202} 203 204struct crypt_priv { 205 struct camellia_ctx *ctx; 206 bool fpu_enabled; 207}; 208 209static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) 210{ 211 const unsigned int bsize = CAMELLIA_BLOCK_SIZE; 212 struct crypt_priv *ctx = priv; 213 int i; 214 215 ctx->fpu_enabled = camellia_fpu_begin(ctx->fpu_enabled, nbytes); 216 217 if (nbytes >= CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS * bsize) { 218 camellia_ecb_enc_32way(ctx->ctx, srcdst, srcdst); 219 srcdst += bsize * CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS; 220 nbytes -= bsize * CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS; 221 } 222 223 if (nbytes >= CAMELLIA_AESNI_PARALLEL_BLOCKS * bsize) { 224 camellia_ecb_enc_16way(ctx->ctx, srcdst, srcdst); 225 srcdst += bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; 226 nbytes -= bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; 227 } 228 229 while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { 230 camellia_enc_blk_2way(ctx->ctx, srcdst, srcdst); 231 srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; 232 nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; 233 } 234 235 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) 236 camellia_enc_blk(ctx->ctx, srcdst, srcdst); 237} 238 239static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) 240{ 241 const unsigned int bsize = CAMELLIA_BLOCK_SIZE; 242 struct crypt_priv *ctx = priv; 243 int i; 244 245 ctx->fpu_enabled = camellia_fpu_begin(ctx->fpu_enabled, nbytes); 246 247 if (nbytes >= CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS * bsize) { 248 camellia_ecb_dec_32way(ctx->ctx, srcdst, srcdst); 249 srcdst += bsize * CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS; 250 nbytes -= bsize * CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS; 251 } 252 253 if (nbytes >= CAMELLIA_AESNI_PARALLEL_BLOCKS * bsize) { 254 camellia_ecb_dec_16way(ctx->ctx, srcdst, srcdst); 255 srcdst += bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; 256 nbytes -= bsize * CAMELLIA_AESNI_PARALLEL_BLOCKS; 257 } 258 259 while (nbytes >= CAMELLIA_PARALLEL_BLOCKS * bsize) { 260 camellia_dec_blk_2way(ctx->ctx, srcdst, srcdst); 261 srcdst += bsize * CAMELLIA_PARALLEL_BLOCKS; 262 nbytes -= bsize * CAMELLIA_PARALLEL_BLOCKS; 263 } 264 265 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) 266 camellia_dec_blk(ctx->ctx, srcdst, srcdst); 267} 268 269static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 270 struct scatterlist *src, unsigned int nbytes) 271{ 272 struct camellia_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 273 be128 buf[CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS]; 274 struct crypt_priv crypt_ctx = { 275 .ctx = &ctx->camellia_ctx, 276 .fpu_enabled = false, 277 }; 278 struct lrw_crypt_req req = { 279 .tbuf = buf, 280 .tbuflen = sizeof(buf), 281 282 .table_ctx = &ctx->lrw_table, 283 .crypt_ctx = &crypt_ctx, 284 .crypt_fn = encrypt_callback, 285 }; 286 int ret; 287 288 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 289 ret = lrw_crypt(desc, dst, src, nbytes, &req); 290 camellia_fpu_end(crypt_ctx.fpu_enabled); 291 292 return ret; 293} 294 295static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 296 struct scatterlist *src, unsigned int nbytes) 297{ 298 struct camellia_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 299 be128 buf[CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS]; 300 struct crypt_priv crypt_ctx = { 301 .ctx = &ctx->camellia_ctx, 302 .fpu_enabled = false, 303 }; 304 struct lrw_crypt_req req = { 305 .tbuf = buf, 306 .tbuflen = sizeof(buf), 307 308 .table_ctx = &ctx->lrw_table, 309 .crypt_ctx = &crypt_ctx, 310 .crypt_fn = decrypt_callback, 311 }; 312 int ret; 313 314 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 315 ret = lrw_crypt(desc, dst, src, nbytes, &req); 316 camellia_fpu_end(crypt_ctx.fpu_enabled); 317 318 return ret; 319} 320 321static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 322 struct scatterlist *src, unsigned int nbytes) 323{ 324 struct camellia_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 325 326 return glue_xts_crypt_128bit(&camellia_enc_xts, desc, dst, src, nbytes, 327 XTS_TWEAK_CAST(camellia_enc_blk), 328 &ctx->tweak_ctx, &ctx->crypt_ctx); 329} 330 331static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 332 struct scatterlist *src, unsigned int nbytes) 333{ 334 struct camellia_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 335 336 return glue_xts_crypt_128bit(&camellia_dec_xts, desc, dst, src, nbytes, 337 XTS_TWEAK_CAST(camellia_enc_blk), 338 &ctx->tweak_ctx, &ctx->crypt_ctx); 339} 340 341static struct crypto_alg cmll_algs[10] = { { 342 .cra_name = "__ecb-camellia-aesni-avx2", 343 .cra_driver_name = "__driver-ecb-camellia-aesni-avx2", 344 .cra_priority = 0, 345 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 346 CRYPTO_ALG_INTERNAL, 347 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 348 .cra_ctxsize = sizeof(struct camellia_ctx), 349 .cra_alignmask = 0, 350 .cra_type = &crypto_blkcipher_type, 351 .cra_module = THIS_MODULE, 352 .cra_u = { 353 .blkcipher = { 354 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 355 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 356 .setkey = camellia_setkey, 357 .encrypt = ecb_encrypt, 358 .decrypt = ecb_decrypt, 359 }, 360 }, 361}, { 362 .cra_name = "__cbc-camellia-aesni-avx2", 363 .cra_driver_name = "__driver-cbc-camellia-aesni-avx2", 364 .cra_priority = 0, 365 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 366 CRYPTO_ALG_INTERNAL, 367 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 368 .cra_ctxsize = sizeof(struct camellia_ctx), 369 .cra_alignmask = 0, 370 .cra_type = &crypto_blkcipher_type, 371 .cra_module = THIS_MODULE, 372 .cra_u = { 373 .blkcipher = { 374 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 375 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 376 .setkey = camellia_setkey, 377 .encrypt = cbc_encrypt, 378 .decrypt = cbc_decrypt, 379 }, 380 }, 381}, { 382 .cra_name = "__ctr-camellia-aesni-avx2", 383 .cra_driver_name = "__driver-ctr-camellia-aesni-avx2", 384 .cra_priority = 0, 385 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 386 CRYPTO_ALG_INTERNAL, 387 .cra_blocksize = 1, 388 .cra_ctxsize = sizeof(struct camellia_ctx), 389 .cra_alignmask = 0, 390 .cra_type = &crypto_blkcipher_type, 391 .cra_module = THIS_MODULE, 392 .cra_u = { 393 .blkcipher = { 394 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 395 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 396 .ivsize = CAMELLIA_BLOCK_SIZE, 397 .setkey = camellia_setkey, 398 .encrypt = ctr_crypt, 399 .decrypt = ctr_crypt, 400 }, 401 }, 402}, { 403 .cra_name = "__lrw-camellia-aesni-avx2", 404 .cra_driver_name = "__driver-lrw-camellia-aesni-avx2", 405 .cra_priority = 0, 406 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 407 CRYPTO_ALG_INTERNAL, 408 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 409 .cra_ctxsize = sizeof(struct camellia_lrw_ctx), 410 .cra_alignmask = 0, 411 .cra_type = &crypto_blkcipher_type, 412 .cra_module = THIS_MODULE, 413 .cra_exit = lrw_camellia_exit_tfm, 414 .cra_u = { 415 .blkcipher = { 416 .min_keysize = CAMELLIA_MIN_KEY_SIZE + 417 CAMELLIA_BLOCK_SIZE, 418 .max_keysize = CAMELLIA_MAX_KEY_SIZE + 419 CAMELLIA_BLOCK_SIZE, 420 .ivsize = CAMELLIA_BLOCK_SIZE, 421 .setkey = lrw_camellia_setkey, 422 .encrypt = lrw_encrypt, 423 .decrypt = lrw_decrypt, 424 }, 425 }, 426}, { 427 .cra_name = "__xts-camellia-aesni-avx2", 428 .cra_driver_name = "__driver-xts-camellia-aesni-avx2", 429 .cra_priority = 0, 430 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | 431 CRYPTO_ALG_INTERNAL, 432 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 433 .cra_ctxsize = sizeof(struct camellia_xts_ctx), 434 .cra_alignmask = 0, 435 .cra_type = &crypto_blkcipher_type, 436 .cra_module = THIS_MODULE, 437 .cra_u = { 438 .blkcipher = { 439 .min_keysize = CAMELLIA_MIN_KEY_SIZE * 2, 440 .max_keysize = CAMELLIA_MAX_KEY_SIZE * 2, 441 .ivsize = CAMELLIA_BLOCK_SIZE, 442 .setkey = xts_camellia_setkey, 443 .encrypt = xts_encrypt, 444 .decrypt = xts_decrypt, 445 }, 446 }, 447}, { 448 .cra_name = "ecb(camellia)", 449 .cra_driver_name = "ecb-camellia-aesni-avx2", 450 .cra_priority = 500, 451 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 452 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 453 .cra_ctxsize = sizeof(struct async_helper_ctx), 454 .cra_alignmask = 0, 455 .cra_type = &crypto_ablkcipher_type, 456 .cra_module = THIS_MODULE, 457 .cra_init = ablk_init, 458 .cra_exit = ablk_exit, 459 .cra_u = { 460 .ablkcipher = { 461 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 462 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 463 .setkey = ablk_set_key, 464 .encrypt = ablk_encrypt, 465 .decrypt = ablk_decrypt, 466 }, 467 }, 468}, { 469 .cra_name = "cbc(camellia)", 470 .cra_driver_name = "cbc-camellia-aesni-avx2", 471 .cra_priority = 500, 472 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 473 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 474 .cra_ctxsize = sizeof(struct async_helper_ctx), 475 .cra_alignmask = 0, 476 .cra_type = &crypto_ablkcipher_type, 477 .cra_module = THIS_MODULE, 478 .cra_init = ablk_init, 479 .cra_exit = ablk_exit, 480 .cra_u = { 481 .ablkcipher = { 482 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 483 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 484 .ivsize = CAMELLIA_BLOCK_SIZE, 485 .setkey = ablk_set_key, 486 .encrypt = __ablk_encrypt, 487 .decrypt = ablk_decrypt, 488 }, 489 }, 490}, { 491 .cra_name = "ctr(camellia)", 492 .cra_driver_name = "ctr-camellia-aesni-avx2", 493 .cra_priority = 500, 494 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 495 .cra_blocksize = 1, 496 .cra_ctxsize = sizeof(struct async_helper_ctx), 497 .cra_alignmask = 0, 498 .cra_type = &crypto_ablkcipher_type, 499 .cra_module = THIS_MODULE, 500 .cra_init = ablk_init, 501 .cra_exit = ablk_exit, 502 .cra_u = { 503 .ablkcipher = { 504 .min_keysize = CAMELLIA_MIN_KEY_SIZE, 505 .max_keysize = CAMELLIA_MAX_KEY_SIZE, 506 .ivsize = CAMELLIA_BLOCK_SIZE, 507 .setkey = ablk_set_key, 508 .encrypt = ablk_encrypt, 509 .decrypt = ablk_encrypt, 510 .geniv = "chainiv", 511 }, 512 }, 513}, { 514 .cra_name = "lrw(camellia)", 515 .cra_driver_name = "lrw-camellia-aesni-avx2", 516 .cra_priority = 500, 517 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 518 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 519 .cra_ctxsize = sizeof(struct async_helper_ctx), 520 .cra_alignmask = 0, 521 .cra_type = &crypto_ablkcipher_type, 522 .cra_module = THIS_MODULE, 523 .cra_init = ablk_init, 524 .cra_exit = ablk_exit, 525 .cra_u = { 526 .ablkcipher = { 527 .min_keysize = CAMELLIA_MIN_KEY_SIZE + 528 CAMELLIA_BLOCK_SIZE, 529 .max_keysize = CAMELLIA_MAX_KEY_SIZE + 530 CAMELLIA_BLOCK_SIZE, 531 .ivsize = CAMELLIA_BLOCK_SIZE, 532 .setkey = ablk_set_key, 533 .encrypt = ablk_encrypt, 534 .decrypt = ablk_decrypt, 535 }, 536 }, 537}, { 538 .cra_name = "xts(camellia)", 539 .cra_driver_name = "xts-camellia-aesni-avx2", 540 .cra_priority = 500, 541 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 542 .cra_blocksize = CAMELLIA_BLOCK_SIZE, 543 .cra_ctxsize = sizeof(struct async_helper_ctx), 544 .cra_alignmask = 0, 545 .cra_type = &crypto_ablkcipher_type, 546 .cra_module = THIS_MODULE, 547 .cra_init = ablk_init, 548 .cra_exit = ablk_exit, 549 .cra_u = { 550 .ablkcipher = { 551 .min_keysize = CAMELLIA_MIN_KEY_SIZE * 2, 552 .max_keysize = CAMELLIA_MAX_KEY_SIZE * 2, 553 .ivsize = CAMELLIA_BLOCK_SIZE, 554 .setkey = ablk_set_key, 555 .encrypt = ablk_encrypt, 556 .decrypt = ablk_decrypt, 557 }, 558 }, 559} }; 560 561static int __init camellia_aesni_init(void) 562{ 563 const char *feature_name; 564 565 if (!cpu_has_avx2 || !cpu_has_avx || !cpu_has_aes || !cpu_has_osxsave) { 566 pr_info("AVX2 or AES-NI instructions are not detected.\n"); 567 return -ENODEV; 568 } 569 570 if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, 571 &feature_name)) { 572 pr_info("CPU feature '%s' is not supported.\n", feature_name); 573 return -ENODEV; 574 } 575 576 return crypto_register_algs(cmll_algs, ARRAY_SIZE(cmll_algs)); 577} 578 579static void __exit camellia_aesni_fini(void) 580{ 581 crypto_unregister_algs(cmll_algs, ARRAY_SIZE(cmll_algs)); 582} 583 584module_init(camellia_aesni_init); 585module_exit(camellia_aesni_fini); 586 587MODULE_LICENSE("GPL"); 588MODULE_DESCRIPTION("Camellia Cipher Algorithm, AES-NI/AVX2 optimized"); 589MODULE_ALIAS_CRYPTO("camellia"); 590MODULE_ALIAS_CRYPTO("camellia-asm"); 591