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>
11*14386d47SHerbert Xu #include <crypto/algapi.h>
12c5a511f1SSebastian Siewior #include <linux/bitops.h>
13c5a511f1SSebastian Siewior #include <linux/init.h>
14c5a511f1SSebastian Siewior #include <linux/module.h>
15c5a511f1SSebastian Siewior #include <linux/errno.h>
16c5a511f1SSebastian Siewior
1704007b0eSArd Biesheuvel #include <crypto/internal/des.h>
18c5a511f1SSebastian Siewior
des_setkey(struct crypto_tfm * tfm,const u8 * key,unsigned int keylen)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 }
32c4c4db0dSEric Biggers if (err)
3304007b0eSArd Biesheuvel memset(dctx, 0, sizeof(*dctx));
3404007b0eSArd Biesheuvel return err;
35c5a511f1SSebastian Siewior }
36c5a511f1SSebastian Siewior
crypto_des_encrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)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
crypto_des_decrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)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
des3_ede_setkey(struct crypto_tfm * tfm,const u8 * key,unsigned int keylen)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 }
64c4c4db0dSEric Biggers if (err)
6504007b0eSArd Biesheuvel memset(dctx, 0, sizeof(*dctx));
664fd4be05SArd Biesheuvel return err;
676574e6c6SJussi Kivilinna }
68c5a511f1SSebastian Siewior
crypto_des3_ede_encrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)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
crypto_des3_ede_decrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)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
des_generic_mod_init(void)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
des_generic_mod_fini(void)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