xref: /openbmc/linux/arch/s390/crypto/des_s390.c (revision c1e26e1e)
1c1e26e1eSJan Glauber /*
2c1e26e1eSJan Glauber  * Cryptographic API.
3c1e26e1eSJan Glauber  *
4c1e26e1eSJan Glauber  * s390 implementation of the DES Cipher Algorithm.
5c1e26e1eSJan Glauber  *
6c1e26e1eSJan Glauber  * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
7c1e26e1eSJan Glauber  * Author(s): Thomas Spatzier (tspat@de.ibm.com)
8c1e26e1eSJan Glauber  *
9c1e26e1eSJan Glauber  *
10c1e26e1eSJan Glauber  * This program is free software; you can redistribute it and/or modify
11c1e26e1eSJan Glauber  * it under the terms of the GNU General Public License as published by
12c1e26e1eSJan Glauber  * the Free Software Foundation; either version 2 of the License, or
13c1e26e1eSJan Glauber  * (at your option) any later version.
14c1e26e1eSJan Glauber  *
15c1e26e1eSJan Glauber  */
16c1e26e1eSJan Glauber #include <linux/init.h>
17c1e26e1eSJan Glauber #include <linux/module.h>
18c1e26e1eSJan Glauber #include <linux/mm.h>
19c1e26e1eSJan Glauber #include <linux/errno.h>
20c1e26e1eSJan Glauber #include <asm/scatterlist.h>
21c1e26e1eSJan Glauber #include <linux/crypto.h>
22c1e26e1eSJan Glauber #include "crypt_s390.h"
23c1e26e1eSJan Glauber #include "crypto_des.h"
24c1e26e1eSJan Glauber 
25c1e26e1eSJan Glauber #define DES_BLOCK_SIZE 8
26c1e26e1eSJan Glauber #define DES_KEY_SIZE 8
27c1e26e1eSJan Glauber 
28c1e26e1eSJan Glauber #define DES3_128_KEY_SIZE	(2 * DES_KEY_SIZE)
29c1e26e1eSJan Glauber #define DES3_128_BLOCK_SIZE	DES_BLOCK_SIZE
30c1e26e1eSJan Glauber 
31c1e26e1eSJan Glauber #define DES3_192_KEY_SIZE	(3 * DES_KEY_SIZE)
32c1e26e1eSJan Glauber #define DES3_192_BLOCK_SIZE	DES_BLOCK_SIZE
33c1e26e1eSJan Glauber 
34c1e26e1eSJan Glauber struct crypt_s390_des_ctx {
35c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
36c1e26e1eSJan Glauber 	u8 key[DES_KEY_SIZE];
37c1e26e1eSJan Glauber };
38c1e26e1eSJan Glauber 
39c1e26e1eSJan Glauber struct crypt_s390_des3_128_ctx {
40c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
41c1e26e1eSJan Glauber 	u8 key[DES3_128_KEY_SIZE];
42c1e26e1eSJan Glauber };
43c1e26e1eSJan Glauber 
44c1e26e1eSJan Glauber struct crypt_s390_des3_192_ctx {
45c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
46c1e26e1eSJan Glauber 	u8 key[DES3_192_KEY_SIZE];
47c1e26e1eSJan Glauber };
48c1e26e1eSJan Glauber 
49c1e26e1eSJan Glauber static int
50c1e26e1eSJan Glauber des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
51c1e26e1eSJan Glauber {
52c1e26e1eSJan Glauber 	struct crypt_s390_des_ctx *dctx;
53c1e26e1eSJan Glauber 	int ret;
54c1e26e1eSJan Glauber 
55c1e26e1eSJan Glauber 	dctx = ctx;
56c1e26e1eSJan Glauber 	//test if key is valid (not a weak key)
57c1e26e1eSJan Glauber 	ret = crypto_des_check_key(key, keylen, flags);
58c1e26e1eSJan Glauber 	if (ret == 0){
59c1e26e1eSJan Glauber 		memcpy(dctx->key, key, keylen);
60c1e26e1eSJan Glauber 	}
61c1e26e1eSJan Glauber 	return ret;
62c1e26e1eSJan Glauber }
63c1e26e1eSJan Glauber 
64c1e26e1eSJan Glauber 
65c1e26e1eSJan Glauber static void
66c1e26e1eSJan Glauber des_encrypt(void *ctx, u8 *dst, const u8 *src)
67c1e26e1eSJan Glauber {
68c1e26e1eSJan Glauber 	struct crypt_s390_des_ctx *dctx;
69c1e26e1eSJan Glauber 
70c1e26e1eSJan Glauber 	dctx = ctx;
71c1e26e1eSJan Glauber 	crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
72c1e26e1eSJan Glauber }
73c1e26e1eSJan Glauber 
74c1e26e1eSJan Glauber static void
75c1e26e1eSJan Glauber des_decrypt(void *ctx, u8 *dst, const u8 *src)
76c1e26e1eSJan Glauber {
77c1e26e1eSJan Glauber 	struct crypt_s390_des_ctx *dctx;
78c1e26e1eSJan Glauber 
79c1e26e1eSJan Glauber 	dctx = ctx;
80c1e26e1eSJan Glauber 	crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
81c1e26e1eSJan Glauber }
82c1e26e1eSJan Glauber 
83c1e26e1eSJan Glauber static struct crypto_alg des_alg = {
84c1e26e1eSJan Glauber 	.cra_name		=	"des",
85c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
86c1e26e1eSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
87c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
88c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
89c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
90c1e26e1eSJan Glauber 	.cra_u			=	{ .cipher = {
91c1e26e1eSJan Glauber 	.cia_min_keysize	=	DES_KEY_SIZE,
92c1e26e1eSJan Glauber 	.cia_max_keysize	=	DES_KEY_SIZE,
93c1e26e1eSJan Glauber 	.cia_setkey		= 	des_setkey,
94c1e26e1eSJan Glauber 	.cia_encrypt		=	des_encrypt,
95c1e26e1eSJan Glauber 	.cia_decrypt		=	des_decrypt } }
96c1e26e1eSJan Glauber };
97c1e26e1eSJan Glauber 
98c1e26e1eSJan Glauber /*
99c1e26e1eSJan Glauber  * RFC2451:
100c1e26e1eSJan Glauber  *
101c1e26e1eSJan Glauber  *   For DES-EDE3, there is no known need to reject weak or
102c1e26e1eSJan Glauber  *   complementation keys.  Any weakness is obviated by the use of
103c1e26e1eSJan Glauber  *   multiple keys.
104c1e26e1eSJan Glauber  *
105c1e26e1eSJan Glauber  *   However, if the two  independent 64-bit keys are equal,
106c1e26e1eSJan Glauber  *   then the DES3 operation is simply the same as DES.
107c1e26e1eSJan Glauber  *   Implementers MUST reject keys that exhibit this property.
108c1e26e1eSJan Glauber  *
109c1e26e1eSJan Glauber  */
110c1e26e1eSJan Glauber static int
111c1e26e1eSJan Glauber des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
112c1e26e1eSJan Glauber {
113c1e26e1eSJan Glauber 	int i, ret;
114c1e26e1eSJan Glauber 	struct crypt_s390_des3_128_ctx *dctx;
115c1e26e1eSJan Glauber 	const u8* temp_key = key;
116c1e26e1eSJan Glauber 
117c1e26e1eSJan Glauber 	dctx = ctx;
118c1e26e1eSJan Glauber 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
119c1e26e1eSJan Glauber 
120c1e26e1eSJan Glauber 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
121c1e26e1eSJan Glauber 		return -EINVAL;
122c1e26e1eSJan Glauber 	}
123c1e26e1eSJan Glauber 	for (i = 0; i < 2; i++,	temp_key += DES_KEY_SIZE) {
124c1e26e1eSJan Glauber 		ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
125c1e26e1eSJan Glauber 		if (ret < 0)
126c1e26e1eSJan Glauber 			return ret;
127c1e26e1eSJan Glauber 	}
128c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
129c1e26e1eSJan Glauber 	return 0;
130c1e26e1eSJan Glauber }
131c1e26e1eSJan Glauber 
132c1e26e1eSJan Glauber static void
133c1e26e1eSJan Glauber des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
134c1e26e1eSJan Glauber {
135c1e26e1eSJan Glauber 	struct crypt_s390_des3_128_ctx *dctx;
136c1e26e1eSJan Glauber 
137c1e26e1eSJan Glauber 	dctx = ctx;
138c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
139c1e26e1eSJan Glauber 			DES3_128_BLOCK_SIZE);
140c1e26e1eSJan Glauber }
141c1e26e1eSJan Glauber 
142c1e26e1eSJan Glauber static void
143c1e26e1eSJan Glauber des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
144c1e26e1eSJan Glauber {
145c1e26e1eSJan Glauber 	struct crypt_s390_des3_128_ctx *dctx;
146c1e26e1eSJan Glauber 
147c1e26e1eSJan Glauber 	dctx = ctx;
148c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
149c1e26e1eSJan Glauber 			DES3_128_BLOCK_SIZE);
150c1e26e1eSJan Glauber }
151c1e26e1eSJan Glauber 
152c1e26e1eSJan Glauber static struct crypto_alg des3_128_alg = {
153c1e26e1eSJan Glauber 	.cra_name		=	"des3_ede128",
154c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
155c1e26e1eSJan Glauber 	.cra_blocksize		=	DES3_128_BLOCK_SIZE,
156c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_128_ctx),
157c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
158c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des3_128_alg.cra_list),
159c1e26e1eSJan Glauber 	.cra_u			=	{ .cipher = {
160c1e26e1eSJan Glauber 	.cia_min_keysize	=	DES3_128_KEY_SIZE,
161c1e26e1eSJan Glauber 	.cia_max_keysize	=	DES3_128_KEY_SIZE,
162c1e26e1eSJan Glauber 	.cia_setkey		= 	des3_128_setkey,
163c1e26e1eSJan Glauber 	.cia_encrypt		=	des3_128_encrypt,
164c1e26e1eSJan Glauber 	.cia_decrypt		=	des3_128_decrypt } }
165c1e26e1eSJan Glauber };
166c1e26e1eSJan Glauber 
167c1e26e1eSJan Glauber /*
168c1e26e1eSJan Glauber  * RFC2451:
169c1e26e1eSJan Glauber  *
170c1e26e1eSJan Glauber  *   For DES-EDE3, there is no known need to reject weak or
171c1e26e1eSJan Glauber  *   complementation keys.  Any weakness is obviated by the use of
172c1e26e1eSJan Glauber  *   multiple keys.
173c1e26e1eSJan Glauber  *
174c1e26e1eSJan Glauber  *   However, if the first two or last two independent 64-bit keys are
175c1e26e1eSJan Glauber  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
176c1e26e1eSJan Glauber  *   same as DES.  Implementers MUST reject keys that exhibit this
177c1e26e1eSJan Glauber  *   property.
178c1e26e1eSJan Glauber  *
179c1e26e1eSJan Glauber  */
180c1e26e1eSJan Glauber static int
181c1e26e1eSJan Glauber des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
182c1e26e1eSJan Glauber {
183c1e26e1eSJan Glauber 	int i, ret;
184c1e26e1eSJan Glauber 	struct crypt_s390_des3_192_ctx *dctx;
185c1e26e1eSJan Glauber 	const u8* temp_key;
186c1e26e1eSJan Glauber 
187c1e26e1eSJan Glauber 	dctx = ctx;
188c1e26e1eSJan Glauber 	temp_key = key;
189c1e26e1eSJan Glauber 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
190c1e26e1eSJan Glauber 	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
191c1e26e1eSJan Glauber 	    					DES_KEY_SIZE))) {
192c1e26e1eSJan Glauber 
193c1e26e1eSJan Glauber 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
194c1e26e1eSJan Glauber 		return -EINVAL;
195c1e26e1eSJan Glauber 	}
196c1e26e1eSJan Glauber 	for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
197c1e26e1eSJan Glauber 		ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
198c1e26e1eSJan Glauber 		if (ret < 0){
199c1e26e1eSJan Glauber 			return ret;
200c1e26e1eSJan Glauber 		}
201c1e26e1eSJan Glauber 	}
202c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
203c1e26e1eSJan Glauber 	return 0;
204c1e26e1eSJan Glauber }
205c1e26e1eSJan Glauber 
206c1e26e1eSJan Glauber static void
207c1e26e1eSJan Glauber des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
208c1e26e1eSJan Glauber {
209c1e26e1eSJan Glauber 	struct crypt_s390_des3_192_ctx *dctx;
210c1e26e1eSJan Glauber 
211c1e26e1eSJan Glauber 	dctx = ctx;
212c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
213c1e26e1eSJan Glauber 			DES3_192_BLOCK_SIZE);
214c1e26e1eSJan Glauber }
215c1e26e1eSJan Glauber 
216c1e26e1eSJan Glauber static void
217c1e26e1eSJan Glauber des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
218c1e26e1eSJan Glauber {
219c1e26e1eSJan Glauber 	struct crypt_s390_des3_192_ctx *dctx;
220c1e26e1eSJan Glauber 
221c1e26e1eSJan Glauber 	dctx = ctx;
222c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
223c1e26e1eSJan Glauber 			DES3_192_BLOCK_SIZE);
224c1e26e1eSJan Glauber }
225c1e26e1eSJan Glauber 
226c1e26e1eSJan Glauber static struct crypto_alg des3_192_alg = {
227c1e26e1eSJan Glauber 	.cra_name		=	"des3_ede",
228c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
229c1e26e1eSJan Glauber 	.cra_blocksize		=	DES3_192_BLOCK_SIZE,
230c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
231c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
232c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des3_192_alg.cra_list),
233c1e26e1eSJan Glauber 	.cra_u			=	{ .cipher = {
234c1e26e1eSJan Glauber 	.cia_min_keysize	=	DES3_192_KEY_SIZE,
235c1e26e1eSJan Glauber 	.cia_max_keysize	=	DES3_192_KEY_SIZE,
236c1e26e1eSJan Glauber 	.cia_setkey		= 	des3_192_setkey,
237c1e26e1eSJan Glauber 	.cia_encrypt		=	des3_192_encrypt,
238c1e26e1eSJan Glauber 	.cia_decrypt		=	des3_192_decrypt } }
239c1e26e1eSJan Glauber };
240c1e26e1eSJan Glauber 
241c1e26e1eSJan Glauber 
242c1e26e1eSJan Glauber 
243c1e26e1eSJan Glauber static int
244c1e26e1eSJan Glauber init(void)
245c1e26e1eSJan Glauber {
246c1e26e1eSJan Glauber 	int ret;
247c1e26e1eSJan Glauber 
248c1e26e1eSJan Glauber 	if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
249c1e26e1eSJan Glauber 	    !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
250c1e26e1eSJan Glauber 	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){
251c1e26e1eSJan Glauber 		return -ENOSYS;
252c1e26e1eSJan Glauber 	}
253c1e26e1eSJan Glauber 
254c1e26e1eSJan Glauber 	ret = 0;
255c1e26e1eSJan Glauber 	ret |= (crypto_register_alg(&des_alg) == 0)? 0:1;
256c1e26e1eSJan Glauber 	ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2;
257c1e26e1eSJan Glauber 	ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4;
258c1e26e1eSJan Glauber 	if (ret){
259c1e26e1eSJan Glauber 		crypto_unregister_alg(&des3_192_alg);
260c1e26e1eSJan Glauber 		crypto_unregister_alg(&des3_128_alg);
261c1e26e1eSJan Glauber 		crypto_unregister_alg(&des_alg);
262c1e26e1eSJan Glauber 		return -EEXIST;
263c1e26e1eSJan Glauber 	}
264c1e26e1eSJan Glauber 
265c1e26e1eSJan Glauber 	printk(KERN_INFO "crypt_s390: des_s390 loaded.\n");
266c1e26e1eSJan Glauber 	return 0;
267c1e26e1eSJan Glauber }
268c1e26e1eSJan Glauber 
269c1e26e1eSJan Glauber static void __exit
270c1e26e1eSJan Glauber fini(void)
271c1e26e1eSJan Glauber {
272c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_192_alg);
273c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_128_alg);
274c1e26e1eSJan Glauber 	crypto_unregister_alg(&des_alg);
275c1e26e1eSJan Glauber }
276c1e26e1eSJan Glauber 
277c1e26e1eSJan Glauber module_init(init);
278c1e26e1eSJan Glauber module_exit(fini);
279c1e26e1eSJan Glauber 
280c1e26e1eSJan Glauber MODULE_ALIAS("des");
281c1e26e1eSJan Glauber MODULE_ALIAS("des3_ede");
282c1e26e1eSJan Glauber 
283c1e26e1eSJan Glauber MODULE_LICENSE("GPL");
284c1e26e1eSJan Glauber MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
285