162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Glue Code for assembler optimized version of 3DES 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: 862306a36Sopenharmony_ci * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <crypto/algapi.h> 1262306a36Sopenharmony_ci#include <crypto/des.h> 1362306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 1462306a36Sopenharmony_ci#include <linux/crypto.h> 1562306a36Sopenharmony_ci#include <linux/init.h> 1662306a36Sopenharmony_ci#include <linux/module.h> 1762306a36Sopenharmony_ci#include <linux/types.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct des3_ede_x86_ctx { 2062306a36Sopenharmony_ci struct des3_ede_ctx enc; 2162306a36Sopenharmony_ci struct des3_ede_ctx dec; 2262306a36Sopenharmony_ci}; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* regular block cipher functions */ 2562306a36Sopenharmony_ciasmlinkage void des3_ede_x86_64_crypt_blk(const u32 *expkey, u8 *dst, 2662306a36Sopenharmony_ci const u8 *src); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 3-way parallel cipher functions */ 2962306a36Sopenharmony_ciasmlinkage void des3_ede_x86_64_crypt_blk_3way(const u32 *expkey, u8 *dst, 3062306a36Sopenharmony_ci const u8 *src); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic inline void des3_ede_enc_blk(struct des3_ede_x86_ctx *ctx, u8 *dst, 3362306a36Sopenharmony_ci const u8 *src) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci u32 *enc_ctx = ctx->enc.expkey; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci des3_ede_x86_64_crypt_blk(enc_ctx, dst, src); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline void des3_ede_dec_blk(struct des3_ede_x86_ctx *ctx, u8 *dst, 4162306a36Sopenharmony_ci const u8 *src) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci u32 *dec_ctx = ctx->dec.expkey; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci des3_ede_x86_64_crypt_blk(dec_ctx, dst, src); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic inline void des3_ede_dec_blk_3way(struct des3_ede_x86_ctx *ctx, u8 *dst, 4962306a36Sopenharmony_ci const u8 *src) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci u32 *dec_ctx = ctx->dec.expkey; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci des3_ede_x86_64_crypt_blk_3way(dec_ctx, dst, src); 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic void des3_ede_x86_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci des3_ede_enc_blk(crypto_tfm_ctx(tfm), dst, src); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic void des3_ede_x86_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci des3_ede_dec_blk(crypto_tfm_ctx(tfm), dst, src); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic int ecb_crypt(struct skcipher_request *req, const u32 *expkey) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci const unsigned int bsize = DES3_EDE_BLOCK_SIZE; 6962306a36Sopenharmony_ci struct skcipher_walk walk; 7062306a36Sopenharmony_ci unsigned int nbytes; 7162306a36Sopenharmony_ci int err; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci while ((nbytes = walk.nbytes)) { 7662306a36Sopenharmony_ci u8 *wsrc = walk.src.virt.addr; 7762306a36Sopenharmony_ci u8 *wdst = walk.dst.virt.addr; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci /* Process four block batch */ 8062306a36Sopenharmony_ci if (nbytes >= bsize * 3) { 8162306a36Sopenharmony_ci do { 8262306a36Sopenharmony_ci des3_ede_x86_64_crypt_blk_3way(expkey, wdst, 8362306a36Sopenharmony_ci wsrc); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci wsrc += bsize * 3; 8662306a36Sopenharmony_ci wdst += bsize * 3; 8762306a36Sopenharmony_ci nbytes -= bsize * 3; 8862306a36Sopenharmony_ci } while (nbytes >= bsize * 3); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (nbytes < bsize) 9162306a36Sopenharmony_ci goto done; 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* Handle leftovers */ 9562306a36Sopenharmony_ci do { 9662306a36Sopenharmony_ci des3_ede_x86_64_crypt_blk(expkey, wdst, wsrc); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci wsrc += bsize; 9962306a36Sopenharmony_ci wdst += bsize; 10062306a36Sopenharmony_ci nbytes -= bsize; 10162306a36Sopenharmony_ci } while (nbytes >= bsize); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cidone: 10462306a36Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci return err; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistatic int ecb_encrypt(struct skcipher_request *req) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 11362306a36Sopenharmony_ci struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci return ecb_crypt(req, ctx->enc.expkey); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic int ecb_decrypt(struct skcipher_request *req) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 12162306a36Sopenharmony_ci struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return ecb_crypt(req, ctx->dec.expkey); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic unsigned int __cbc_encrypt(struct des3_ede_x86_ctx *ctx, 12762306a36Sopenharmony_ci struct skcipher_walk *walk) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci unsigned int bsize = DES3_EDE_BLOCK_SIZE; 13062306a36Sopenharmony_ci unsigned int nbytes = walk->nbytes; 13162306a36Sopenharmony_ci u64 *src = (u64 *)walk->src.virt.addr; 13262306a36Sopenharmony_ci u64 *dst = (u64 *)walk->dst.virt.addr; 13362306a36Sopenharmony_ci u64 *iv = (u64 *)walk->iv; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci do { 13662306a36Sopenharmony_ci *dst = *src ^ *iv; 13762306a36Sopenharmony_ci des3_ede_enc_blk(ctx, (u8 *)dst, (u8 *)dst); 13862306a36Sopenharmony_ci iv = dst; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci src += 1; 14162306a36Sopenharmony_ci dst += 1; 14262306a36Sopenharmony_ci nbytes -= bsize; 14362306a36Sopenharmony_ci } while (nbytes >= bsize); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci *(u64 *)walk->iv = *iv; 14662306a36Sopenharmony_ci return nbytes; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic int cbc_encrypt(struct skcipher_request *req) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 15262306a36Sopenharmony_ci struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm); 15362306a36Sopenharmony_ci struct skcipher_walk walk; 15462306a36Sopenharmony_ci unsigned int nbytes; 15562306a36Sopenharmony_ci int err; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci while (walk.nbytes) { 16062306a36Sopenharmony_ci nbytes = __cbc_encrypt(ctx, &walk); 16162306a36Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 16262306a36Sopenharmony_ci } 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci return err; 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic unsigned int __cbc_decrypt(struct des3_ede_x86_ctx *ctx, 16862306a36Sopenharmony_ci struct skcipher_walk *walk) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci unsigned int bsize = DES3_EDE_BLOCK_SIZE; 17162306a36Sopenharmony_ci unsigned int nbytes = walk->nbytes; 17262306a36Sopenharmony_ci u64 *src = (u64 *)walk->src.virt.addr; 17362306a36Sopenharmony_ci u64 *dst = (u64 *)walk->dst.virt.addr; 17462306a36Sopenharmony_ci u64 ivs[3 - 1]; 17562306a36Sopenharmony_ci u64 last_iv; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Start of the last block. */ 17862306a36Sopenharmony_ci src += nbytes / bsize - 1; 17962306a36Sopenharmony_ci dst += nbytes / bsize - 1; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci last_iv = *src; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* Process four block batch */ 18462306a36Sopenharmony_ci if (nbytes >= bsize * 3) { 18562306a36Sopenharmony_ci do { 18662306a36Sopenharmony_ci nbytes -= bsize * 3 - bsize; 18762306a36Sopenharmony_ci src -= 3 - 1; 18862306a36Sopenharmony_ci dst -= 3 - 1; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci ivs[0] = src[0]; 19162306a36Sopenharmony_ci ivs[1] = src[1]; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci des3_ede_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci dst[1] ^= ivs[0]; 19662306a36Sopenharmony_ci dst[2] ^= ivs[1]; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci nbytes -= bsize; 19962306a36Sopenharmony_ci if (nbytes < bsize) 20062306a36Sopenharmony_ci goto done; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci *dst ^= *(src - 1); 20362306a36Sopenharmony_ci src -= 1; 20462306a36Sopenharmony_ci dst -= 1; 20562306a36Sopenharmony_ci } while (nbytes >= bsize * 3); 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci /* Handle leftovers */ 20962306a36Sopenharmony_ci for (;;) { 21062306a36Sopenharmony_ci des3_ede_dec_blk(ctx, (u8 *)dst, (u8 *)src); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci nbytes -= bsize; 21362306a36Sopenharmony_ci if (nbytes < bsize) 21462306a36Sopenharmony_ci break; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci *dst ^= *(src - 1); 21762306a36Sopenharmony_ci src -= 1; 21862306a36Sopenharmony_ci dst -= 1; 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cidone: 22262306a36Sopenharmony_ci *dst ^= *(u64 *)walk->iv; 22362306a36Sopenharmony_ci *(u64 *)walk->iv = last_iv; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci return nbytes; 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic int cbc_decrypt(struct skcipher_request *req) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 23162306a36Sopenharmony_ci struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm); 23262306a36Sopenharmony_ci struct skcipher_walk walk; 23362306a36Sopenharmony_ci unsigned int nbytes; 23462306a36Sopenharmony_ci int err; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci while (walk.nbytes) { 23962306a36Sopenharmony_ci nbytes = __cbc_decrypt(ctx, &walk); 24062306a36Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 24162306a36Sopenharmony_ci } 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci return err; 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic int des3_ede_x86_setkey(struct crypto_tfm *tfm, const u8 *key, 24762306a36Sopenharmony_ci unsigned int keylen) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci struct des3_ede_x86_ctx *ctx = crypto_tfm_ctx(tfm); 25062306a36Sopenharmony_ci u32 i, j, tmp; 25162306a36Sopenharmony_ci int err; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci err = des3_ede_expand_key(&ctx->enc, key, keylen); 25462306a36Sopenharmony_ci if (err == -ENOKEY) { 25562306a36Sopenharmony_ci if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 25662306a36Sopenharmony_ci err = -EINVAL; 25762306a36Sopenharmony_ci else 25862306a36Sopenharmony_ci err = 0; 25962306a36Sopenharmony_ci } 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci if (err) { 26262306a36Sopenharmony_ci memset(ctx, 0, sizeof(*ctx)); 26362306a36Sopenharmony_ci return err; 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci /* Fix encryption context for this implementation and form decryption 26762306a36Sopenharmony_ci * context. */ 26862306a36Sopenharmony_ci j = DES3_EDE_EXPKEY_WORDS - 2; 26962306a36Sopenharmony_ci for (i = 0; i < DES3_EDE_EXPKEY_WORDS; i += 2, j -= 2) { 27062306a36Sopenharmony_ci tmp = ror32(ctx->enc.expkey[i + 1], 4); 27162306a36Sopenharmony_ci ctx->enc.expkey[i + 1] = tmp; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci ctx->dec.expkey[j + 0] = ctx->enc.expkey[i + 0]; 27462306a36Sopenharmony_ci ctx->dec.expkey[j + 1] = tmp; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci return 0; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic int des3_ede_x86_setkey_skcipher(struct crypto_skcipher *tfm, 28162306a36Sopenharmony_ci const u8 *key, 28262306a36Sopenharmony_ci unsigned int keylen) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci return des3_ede_x86_setkey(&tfm->base, key, keylen); 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic struct crypto_alg des3_ede_cipher = { 28862306a36Sopenharmony_ci .cra_name = "des3_ede", 28962306a36Sopenharmony_ci .cra_driver_name = "des3_ede-asm", 29062306a36Sopenharmony_ci .cra_priority = 200, 29162306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 29262306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 29362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct des3_ede_x86_ctx), 29462306a36Sopenharmony_ci .cra_alignmask = 0, 29562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 29662306a36Sopenharmony_ci .cra_u = { 29762306a36Sopenharmony_ci .cipher = { 29862306a36Sopenharmony_ci .cia_min_keysize = DES3_EDE_KEY_SIZE, 29962306a36Sopenharmony_ci .cia_max_keysize = DES3_EDE_KEY_SIZE, 30062306a36Sopenharmony_ci .cia_setkey = des3_ede_x86_setkey, 30162306a36Sopenharmony_ci .cia_encrypt = des3_ede_x86_encrypt, 30262306a36Sopenharmony_ci .cia_decrypt = des3_ede_x86_decrypt, 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic struct skcipher_alg des3_ede_skciphers[] = { 30862306a36Sopenharmony_ci { 30962306a36Sopenharmony_ci .base.cra_name = "ecb(des3_ede)", 31062306a36Sopenharmony_ci .base.cra_driver_name = "ecb-des3_ede-asm", 31162306a36Sopenharmony_ci .base.cra_priority = 300, 31262306a36Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 31362306a36Sopenharmony_ci .base.cra_ctxsize = sizeof(struct des3_ede_x86_ctx), 31462306a36Sopenharmony_ci .base.cra_module = THIS_MODULE, 31562306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 31662306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 31762306a36Sopenharmony_ci .setkey = des3_ede_x86_setkey_skcipher, 31862306a36Sopenharmony_ci .encrypt = ecb_encrypt, 31962306a36Sopenharmony_ci .decrypt = ecb_decrypt, 32062306a36Sopenharmony_ci }, { 32162306a36Sopenharmony_ci .base.cra_name = "cbc(des3_ede)", 32262306a36Sopenharmony_ci .base.cra_driver_name = "cbc-des3_ede-asm", 32362306a36Sopenharmony_ci .base.cra_priority = 300, 32462306a36Sopenharmony_ci .base.cra_blocksize = DES3_EDE_BLOCK_SIZE, 32562306a36Sopenharmony_ci .base.cra_ctxsize = sizeof(struct des3_ede_x86_ctx), 32662306a36Sopenharmony_ci .base.cra_module = THIS_MODULE, 32762306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 32862306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 32962306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 33062306a36Sopenharmony_ci .setkey = des3_ede_x86_setkey_skcipher, 33162306a36Sopenharmony_ci .encrypt = cbc_encrypt, 33262306a36Sopenharmony_ci .decrypt = cbc_decrypt, 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic bool is_blacklisted_cpu(void) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) 33962306a36Sopenharmony_ci return false; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci if (boot_cpu_data.x86 == 0x0f) { 34262306a36Sopenharmony_ci /* 34362306a36Sopenharmony_ci * On Pentium 4, des3_ede-x86_64 is slower than generic C 34462306a36Sopenharmony_ci * implementation because use of 64bit rotates (which are really 34562306a36Sopenharmony_ci * slow on P4). Therefore blacklist P4s. 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_ci return true; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci return false; 35162306a36Sopenharmony_ci} 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_cistatic int force; 35462306a36Sopenharmony_cimodule_param(force, int, 0); 35562306a36Sopenharmony_ciMODULE_PARM_DESC(force, "Force module load, ignore CPU blacklist"); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_cistatic int __init des3_ede_x86_init(void) 35862306a36Sopenharmony_ci{ 35962306a36Sopenharmony_ci int err; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci if (!force && is_blacklisted_cpu()) { 36262306a36Sopenharmony_ci pr_info("des3_ede-x86_64: performance on this CPU would be suboptimal: disabling des3_ede-x86_64.\n"); 36362306a36Sopenharmony_ci return -ENODEV; 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci err = crypto_register_alg(&des3_ede_cipher); 36762306a36Sopenharmony_ci if (err) 36862306a36Sopenharmony_ci return err; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci err = crypto_register_skciphers(des3_ede_skciphers, 37162306a36Sopenharmony_ci ARRAY_SIZE(des3_ede_skciphers)); 37262306a36Sopenharmony_ci if (err) 37362306a36Sopenharmony_ci crypto_unregister_alg(&des3_ede_cipher); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci return err; 37662306a36Sopenharmony_ci} 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistatic void __exit des3_ede_x86_fini(void) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci crypto_unregister_alg(&des3_ede_cipher); 38162306a36Sopenharmony_ci crypto_unregister_skciphers(des3_ede_skciphers, 38262306a36Sopenharmony_ci ARRAY_SIZE(des3_ede_skciphers)); 38362306a36Sopenharmony_ci} 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cimodule_init(des3_ede_x86_init); 38662306a36Sopenharmony_cimodule_exit(des3_ede_x86_fini); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 38962306a36Sopenharmony_ciMODULE_DESCRIPTION("Triple DES EDE Cipher Algorithm, asm optimized"); 39062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("des3_ede"); 39162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("des3_ede-asm"); 39262306a36Sopenharmony_ciMODULE_AUTHOR("Jussi Kivilinna <jussi.kivilinna@iki.fi>"); 393