12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2c5a511f1SSebastian Siewior /* 3c5a511f1SSebastian Siewior * Cryptographic API. 4c5a511f1SSebastian Siewior * 5c5a511f1SSebastian Siewior * DES & Triple DES EDE Cipher Algorithms. 6c5a511f1SSebastian Siewior * 7c5a511f1SSebastian Siewior * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no> 8c5a511f1SSebastian Siewior */ 9c5a511f1SSebastian Siewior 10c5a511f1SSebastian Siewior #include <asm/byteorder.h> 11c5a511f1SSebastian Siewior #include <linux/bitops.h> 12c5a511f1SSebastian Siewior #include <linux/init.h> 13c5a511f1SSebastian Siewior #include <linux/module.h> 14c5a511f1SSebastian Siewior #include <linux/errno.h> 15c5a511f1SSebastian Siewior #include <linux/crypto.h> 16c5a511f1SSebastian Siewior 1704007b0eSArd Biesheuvel #include <crypto/internal/des.h> 18c5a511f1SSebastian Siewior 19c5a511f1SSebastian Siewior static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 20c5a511f1SSebastian Siewior unsigned int keylen) 21c5a511f1SSebastian Siewior { 22c5a511f1SSebastian Siewior struct des_ctx *dctx = crypto_tfm_ctx(tfm); 2304007b0eSArd Biesheuvel int err; 24c5a511f1SSebastian Siewior 2504007b0eSArd Biesheuvel err = des_expand_key(dctx, key, keylen); 2604007b0eSArd Biesheuvel if (err == -ENOKEY) { 2704007b0eSArd Biesheuvel if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 2804007b0eSArd Biesheuvel err = -EINVAL; 2904007b0eSArd Biesheuvel else 3004007b0eSArd Biesheuvel err = 0; 31c5a511f1SSebastian Siewior } 32*c4c4db0dSEric Biggers if (err) 3304007b0eSArd Biesheuvel memset(dctx, 0, sizeof(*dctx)); 3404007b0eSArd Biesheuvel return err; 35c5a511f1SSebastian Siewior } 36c5a511f1SSebastian Siewior 3704007b0eSArd Biesheuvel static void crypto_des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 38c5a511f1SSebastian Siewior { 3904007b0eSArd Biesheuvel const struct des_ctx *dctx = crypto_tfm_ctx(tfm); 40c5a511f1SSebastian Siewior 4104007b0eSArd Biesheuvel des_encrypt(dctx, dst, src); 42c5a511f1SSebastian Siewior } 43c5a511f1SSebastian Siewior 4404007b0eSArd Biesheuvel static void crypto_des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 45c5a511f1SSebastian Siewior { 4604007b0eSArd Biesheuvel const struct des_ctx *dctx = crypto_tfm_ctx(tfm); 47c5a511f1SSebastian Siewior 4804007b0eSArd Biesheuvel des_decrypt(dctx, dst, src); 49c5a511f1SSebastian Siewior } 50c5a511f1SSebastian Siewior 516574e6c6SJussi Kivilinna static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, 526574e6c6SJussi Kivilinna unsigned int keylen) 536574e6c6SJussi Kivilinna { 546574e6c6SJussi Kivilinna struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 554fd4be05SArd Biesheuvel int err; 564fd4be05SArd Biesheuvel 5704007b0eSArd Biesheuvel err = des3_ede_expand_key(dctx, key, keylen); 5804007b0eSArd Biesheuvel if (err == -ENOKEY) { 5904007b0eSArd Biesheuvel if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) 6004007b0eSArd Biesheuvel err = -EINVAL; 6104007b0eSArd Biesheuvel else 6204007b0eSArd Biesheuvel err = 0; 6304007b0eSArd Biesheuvel } 64*c4c4db0dSEric Biggers if (err) 6504007b0eSArd Biesheuvel memset(dctx, 0, sizeof(*dctx)); 664fd4be05SArd Biesheuvel return err; 676574e6c6SJussi Kivilinna } 68c5a511f1SSebastian Siewior 6904007b0eSArd Biesheuvel static void crypto_des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, 7004007b0eSArd Biesheuvel const u8 *src) 71c5a511f1SSebastian Siewior { 7204007b0eSArd Biesheuvel const struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 73c5a511f1SSebastian Siewior 7404007b0eSArd Biesheuvel des3_ede_encrypt(dctx, dst, src); 75c5a511f1SSebastian Siewior } 76c5a511f1SSebastian Siewior 7704007b0eSArd Biesheuvel static void crypto_des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, 7804007b0eSArd Biesheuvel const u8 *src) 79c5a511f1SSebastian Siewior { 8004007b0eSArd Biesheuvel const struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); 81c5a511f1SSebastian Siewior 8204007b0eSArd Biesheuvel des3_ede_decrypt(dctx, dst, src); 83c5a511f1SSebastian Siewior } 84c5a511f1SSebastian Siewior 859935e6d2SJussi Kivilinna static struct crypto_alg des_algs[2] = { { 86c5a511f1SSebastian Siewior .cra_name = "des", 876574e6c6SJussi Kivilinna .cra_driver_name = "des-generic", 886574e6c6SJussi Kivilinna .cra_priority = 100, 89c5a511f1SSebastian Siewior .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 90c5a511f1SSebastian Siewior .cra_blocksize = DES_BLOCK_SIZE, 91c5a511f1SSebastian Siewior .cra_ctxsize = sizeof(struct des_ctx), 92c5a511f1SSebastian Siewior .cra_module = THIS_MODULE, 93c5a511f1SSebastian Siewior .cra_u = { .cipher = { 94c5a511f1SSebastian Siewior .cia_min_keysize = DES_KEY_SIZE, 95c5a511f1SSebastian Siewior .cia_max_keysize = DES_KEY_SIZE, 96c5a511f1SSebastian Siewior .cia_setkey = des_setkey, 9704007b0eSArd Biesheuvel .cia_encrypt = crypto_des_encrypt, 9804007b0eSArd Biesheuvel .cia_decrypt = crypto_des_decrypt } } 999935e6d2SJussi Kivilinna }, { 100c5a511f1SSebastian Siewior .cra_name = "des3_ede", 1016574e6c6SJussi Kivilinna .cra_driver_name = "des3_ede-generic", 1026574e6c6SJussi Kivilinna .cra_priority = 100, 103c5a511f1SSebastian Siewior .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 104c5a511f1SSebastian Siewior .cra_blocksize = DES3_EDE_BLOCK_SIZE, 105c5a511f1SSebastian Siewior .cra_ctxsize = sizeof(struct des3_ede_ctx), 106c5a511f1SSebastian Siewior .cra_module = THIS_MODULE, 107c5a511f1SSebastian Siewior .cra_u = { .cipher = { 108c5a511f1SSebastian Siewior .cia_min_keysize = DES3_EDE_KEY_SIZE, 109c5a511f1SSebastian Siewior .cia_max_keysize = DES3_EDE_KEY_SIZE, 110c5a511f1SSebastian Siewior .cia_setkey = des3_ede_setkey, 11104007b0eSArd Biesheuvel .cia_encrypt = crypto_des3_ede_encrypt, 11204007b0eSArd Biesheuvel .cia_decrypt = crypto_des3_ede_decrypt } } 1139935e6d2SJussi Kivilinna } }; 114c5a511f1SSebastian Siewior 1153af5b90bSKamalesh Babulal static int __init des_generic_mod_init(void) 116c5a511f1SSebastian Siewior { 1179935e6d2SJussi Kivilinna return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs)); 118c5a511f1SSebastian Siewior } 119c5a511f1SSebastian Siewior 1203af5b90bSKamalesh Babulal static void __exit des_generic_mod_fini(void) 121c5a511f1SSebastian Siewior { 1229935e6d2SJussi Kivilinna crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs)); 123c5a511f1SSebastian Siewior } 124c5a511f1SSebastian Siewior 125c4741b23SEric Biggers subsys_initcall(des_generic_mod_init); 1263af5b90bSKamalesh Babulal module_exit(des_generic_mod_fini); 127c5a511f1SSebastian Siewior 128c5a511f1SSebastian Siewior MODULE_LICENSE("GPL"); 129c5a511f1SSebastian Siewior MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); 130c5a511f1SSebastian Siewior MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>"); 1313e14dcf7SMathias Krause MODULE_ALIAS_CRYPTO("des"); 1323e14dcf7SMathias Krause MODULE_ALIAS_CRYPTO("des-generic"); 1333e14dcf7SMathias Krause MODULE_ALIAS_CRYPTO("des3_ede"); 1343e14dcf7SMathias Krause MODULE_ALIAS_CRYPTO("des3_ede-generic"); 135