xref: /linux/crypto/des_generic.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
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