18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Cryptographic API. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * DES & Triple DES EDE Cipher Algorithms. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <asm/byteorder.h> 118c2ecf20Sopenharmony_ci#include <linux/bitops.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/errno.h> 158c2ecf20Sopenharmony_ci#include <linux/crypto.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <crypto/internal/des.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic int des_setkey(struct crypto_tfm *tfm, const u8 *key, 208c2ecf20Sopenharmony_ci unsigned int keylen) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct des_ctx *dctx = crypto_tfm_ctx(tfm); 238c2ecf20Sopenharmony_ci int err; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci err = des_expand_key(dctx, key, keylen); 268c2ecf20Sopenharmony_ci if (err == -ENOKEY) { 278c2ecf20Sopenharmony_ci if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 288c2ecf20Sopenharmony_ci err = -EINVAL; 298c2ecf20Sopenharmony_ci else 308c2ecf20Sopenharmony_ci err = 0; 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci if (err) 338c2ecf20Sopenharmony_ci memset(dctx, 0, sizeof(*dctx)); 348c2ecf20Sopenharmony_ci return err; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic void crypto_des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci const struct des_ctx *dctx = crypto_tfm_ctx(tfm); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci des_encrypt(dctx, dst, src); 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic void crypto_des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci const struct des_ctx *dctx = crypto_tfm_ctx(tfm); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci des_decrypt(dctx, dst, src); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, 528c2ecf20Sopenharmony_ci unsigned int keylen) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 558c2ecf20Sopenharmony_ci int err; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci err = des3_ede_expand_key(dctx, key, keylen); 588c2ecf20Sopenharmony_ci if (err == -ENOKEY) { 598c2ecf20Sopenharmony_ci if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 608c2ecf20Sopenharmony_ci err = -EINVAL; 618c2ecf20Sopenharmony_ci else 628c2ecf20Sopenharmony_ci err = 0; 638c2ecf20Sopenharmony_ci } 648c2ecf20Sopenharmony_ci if (err) 658c2ecf20Sopenharmony_ci memset(dctx, 0, sizeof(*dctx)); 668c2ecf20Sopenharmony_ci return err; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic void crypto_des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, 708c2ecf20Sopenharmony_ci const u8 *src) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci const struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci des3_ede_encrypt(dctx, dst, src); 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic void crypto_des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, 788c2ecf20Sopenharmony_ci const u8 *src) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci const struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci des3_ede_decrypt(dctx, dst, src); 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic struct crypto_alg des_algs[2] = { { 868c2ecf20Sopenharmony_ci .cra_name = "des", 878c2ecf20Sopenharmony_ci .cra_driver_name = "des-generic", 888c2ecf20Sopenharmony_ci .cra_priority = 100, 898c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 908c2ecf20Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 918c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct des_ctx), 928c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 938c2ecf20Sopenharmony_ci .cra_u = { .cipher = { 948c2ecf20Sopenharmony_ci .cia_min_keysize = DES_KEY_SIZE, 958c2ecf20Sopenharmony_ci .cia_max_keysize = DES_KEY_SIZE, 968c2ecf20Sopenharmony_ci .cia_setkey = des_setkey, 978c2ecf20Sopenharmony_ci .cia_encrypt = crypto_des_encrypt, 988c2ecf20Sopenharmony_ci .cia_decrypt = crypto_des_decrypt } } 998c2ecf20Sopenharmony_ci}, { 1008c2ecf20Sopenharmony_ci .cra_name = "des3_ede", 1018c2ecf20Sopenharmony_ci .cra_driver_name = "des3_ede-generic", 1028c2ecf20Sopenharmony_ci .cra_priority = 100, 1038c2ecf20Sopenharmony_ci .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 1048c2ecf20Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 1058c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct des3_ede_ctx), 1068c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 1078c2ecf20Sopenharmony_ci .cra_u = { .cipher = { 1088c2ecf20Sopenharmony_ci .cia_min_keysize = DES3_EDE_KEY_SIZE, 1098c2ecf20Sopenharmony_ci .cia_max_keysize = DES3_EDE_KEY_SIZE, 1108c2ecf20Sopenharmony_ci .cia_setkey = des3_ede_setkey, 1118c2ecf20Sopenharmony_ci .cia_encrypt = crypto_des3_ede_encrypt, 1128c2ecf20Sopenharmony_ci .cia_decrypt = crypto_des3_ede_decrypt } } 1138c2ecf20Sopenharmony_ci} }; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic int __init des_generic_mod_init(void) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs)); 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic void __exit des_generic_mod_fini(void) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs)); 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cisubsys_initcall(des_generic_mod_init); 1268c2ecf20Sopenharmony_cimodule_exit(des_generic_mod_fini); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1298c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); 1308c2ecf20Sopenharmony_ciMODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>"); 1318c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("des"); 1328c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("des-generic"); 1338c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("des3_ede"); 1348c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("des3_ede-generic"); 135