xref: /openbmc/linux/arch/s390/crypto/des_s390.c (revision 1822bc90)
1c1e26e1eSJan Glauber /*
2c1e26e1eSJan Glauber  * Cryptographic API.
3c1e26e1eSJan Glauber  *
4c1e26e1eSJan Glauber  * s390 implementation of the DES Cipher Algorithm.
5c1e26e1eSJan Glauber  *
686aa9fc2SJan Glauber  * Copyright IBM Corp. 2003,2007
786aa9fc2SJan Glauber  * Author(s): Thomas Spatzier
886aa9fc2SJan Glauber  *	      Jan Glauber (jan.glauber@de.ibm.com)
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  */
16a9e62fadSHerbert Xu 
17c1e26e1eSJan Glauber #include <linux/init.h>
18c1e26e1eSJan Glauber #include <linux/module.h>
191efbd15cSJan Glauber #include <linux/crypto.h>
201efbd15cSJan Glauber #include <crypto/algapi.h>
211efbd15cSJan Glauber #include <crypto/des.h>
22c1357833SJan Glauber 
23c1e26e1eSJan Glauber #include "crypt_s390.h"
24c1e26e1eSJan Glauber 
25c1e26e1eSJan Glauber #define DES3_192_KEY_SIZE	(3 * DES_KEY_SIZE)
26c1e26e1eSJan Glauber 
27c1e26e1eSJan Glauber struct crypt_s390_des_ctx {
28c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
29c1e26e1eSJan Glauber 	u8 key[DES_KEY_SIZE];
30c1e26e1eSJan Glauber };
31c1e26e1eSJan Glauber 
32c1e26e1eSJan Glauber struct crypt_s390_des3_192_ctx {
33c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
34c1e26e1eSJan Glauber 	u8 key[DES3_192_KEY_SIZE];
35c1e26e1eSJan Glauber };
36c1e26e1eSJan Glauber 
376c2bb98bSHerbert Xu static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
38560c06aeSHerbert Xu 		      unsigned int keylen)
39c1e26e1eSJan Glauber {
406c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
41560c06aeSHerbert Xu 	u32 *flags = &tfm->crt_flags;
421efbd15cSJan Glauber 	u32 tmp[DES_EXPKEY_WORDS];
43c1e26e1eSJan Glauber 
441efbd15cSJan Glauber 	/* check for weak keys */
451efbd15cSJan Glauber 	if (!des_ekey(tmp, key) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
461efbd15cSJan Glauber 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
471efbd15cSJan Glauber 		return -EINVAL;
481efbd15cSJan Glauber 	}
491efbd15cSJan Glauber 
50c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
511efbd15cSJan Glauber 	return 0;
52c1e26e1eSJan Glauber }
53c1e26e1eSJan Glauber 
546c2bb98bSHerbert Xu static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
55c1e26e1eSJan Glauber {
566c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
57c1e26e1eSJan Glauber 
58b8dc6038SJan Glauber 	crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
59c1e26e1eSJan Glauber }
60c1e26e1eSJan Glauber 
616c2bb98bSHerbert Xu static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
62c1e26e1eSJan Glauber {
636c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
64c1e26e1eSJan Glauber 
65b8dc6038SJan Glauber 	crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
66b8dc6038SJan Glauber }
67b8dc6038SJan Glauber 
68c1e26e1eSJan Glauber static struct crypto_alg des_alg = {
69c1e26e1eSJan Glauber 	.cra_name		=	"des",
7065b75c36SHerbert Xu 	.cra_driver_name	=	"des-s390",
7165b75c36SHerbert Xu 	.cra_priority		=	CRYPT_S390_PRIORITY,
72c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
73c1e26e1eSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
74c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
75c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
76c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
77c1357833SJan Glauber 	.cra_u			=	{
78c1357833SJan Glauber 		.cipher = {
79c1e26e1eSJan Glauber 			.cia_min_keysize	=	DES_KEY_SIZE,
80c1e26e1eSJan Glauber 			.cia_max_keysize	=	DES_KEY_SIZE,
81c1e26e1eSJan Glauber 			.cia_setkey		=	des_setkey,
82c1e26e1eSJan Glauber 			.cia_encrypt		=	des_encrypt,
83b8dc6038SJan Glauber 			.cia_decrypt		=	des_decrypt,
84c1357833SJan Glauber 		}
85c1357833SJan Glauber 	}
86c1e26e1eSJan Glauber };
87c1e26e1eSJan Glauber 
88a9e62fadSHerbert Xu static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
89a9e62fadSHerbert Xu 			    void *param, struct blkcipher_walk *walk)
90a9e62fadSHerbert Xu {
91a9e62fadSHerbert Xu 	int ret = blkcipher_walk_virt(desc, walk);
92a9e62fadSHerbert Xu 	unsigned int nbytes;
93a9e62fadSHerbert Xu 
94a9e62fadSHerbert Xu 	while ((nbytes = walk->nbytes)) {
95a9e62fadSHerbert Xu 		/* only use complete blocks */
96a9e62fadSHerbert Xu 		unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
97a9e62fadSHerbert Xu 		u8 *out = walk->dst.virt.addr;
98a9e62fadSHerbert Xu 		u8 *in = walk->src.virt.addr;
99a9e62fadSHerbert Xu 
100a9e62fadSHerbert Xu 		ret = crypt_s390_km(func, param, out, in, n);
101a9e62fadSHerbert Xu 		BUG_ON((ret < 0) || (ret != n));
102a9e62fadSHerbert Xu 
103a9e62fadSHerbert Xu 		nbytes &= DES_BLOCK_SIZE - 1;
104a9e62fadSHerbert Xu 		ret = blkcipher_walk_done(desc, walk, nbytes);
105a9e62fadSHerbert Xu 	}
106a9e62fadSHerbert Xu 
107a9e62fadSHerbert Xu 	return ret;
108a9e62fadSHerbert Xu }
109a9e62fadSHerbert Xu 
110a9e62fadSHerbert Xu static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
111a9e62fadSHerbert Xu 			    void *param, struct blkcipher_walk *walk)
112a9e62fadSHerbert Xu {
113a9e62fadSHerbert Xu 	int ret = blkcipher_walk_virt(desc, walk);
114a9e62fadSHerbert Xu 	unsigned int nbytes = walk->nbytes;
115a9e62fadSHerbert Xu 
116a9e62fadSHerbert Xu 	if (!nbytes)
117a9e62fadSHerbert Xu 		goto out;
118a9e62fadSHerbert Xu 
119a9e62fadSHerbert Xu 	memcpy(param, walk->iv, DES_BLOCK_SIZE);
120a9e62fadSHerbert Xu 	do {
121a9e62fadSHerbert Xu 		/* only use complete blocks */
122a9e62fadSHerbert Xu 		unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
123a9e62fadSHerbert Xu 		u8 *out = walk->dst.virt.addr;
124a9e62fadSHerbert Xu 		u8 *in = walk->src.virt.addr;
125a9e62fadSHerbert Xu 
126a9e62fadSHerbert Xu 		ret = crypt_s390_kmc(func, param, out, in, n);
127a9e62fadSHerbert Xu 		BUG_ON((ret < 0) || (ret != n));
128a9e62fadSHerbert Xu 
129a9e62fadSHerbert Xu 		nbytes &= DES_BLOCK_SIZE - 1;
130a9e62fadSHerbert Xu 		ret = blkcipher_walk_done(desc, walk, nbytes);
131a9e62fadSHerbert Xu 	} while ((nbytes = walk->nbytes));
132a9e62fadSHerbert Xu 	memcpy(walk->iv, param, DES_BLOCK_SIZE);
133a9e62fadSHerbert Xu 
134a9e62fadSHerbert Xu out:
135a9e62fadSHerbert Xu 	return ret;
136a9e62fadSHerbert Xu }
137a9e62fadSHerbert Xu 
138a9e62fadSHerbert Xu static int ecb_des_encrypt(struct blkcipher_desc *desc,
139a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
140a9e62fadSHerbert Xu 			   unsigned int nbytes)
141a9e62fadSHerbert Xu {
142a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
143a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
144a9e62fadSHerbert Xu 
145a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
146a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
147a9e62fadSHerbert Xu }
148a9e62fadSHerbert Xu 
149a9e62fadSHerbert Xu static int ecb_des_decrypt(struct blkcipher_desc *desc,
150a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
151a9e62fadSHerbert Xu 			   unsigned int nbytes)
152a9e62fadSHerbert Xu {
153a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
154a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
155a9e62fadSHerbert Xu 
156a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
157a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
158a9e62fadSHerbert Xu }
159a9e62fadSHerbert Xu 
160a9e62fadSHerbert Xu static struct crypto_alg ecb_des_alg = {
161a9e62fadSHerbert Xu 	.cra_name		=	"ecb(des)",
162a9e62fadSHerbert Xu 	.cra_driver_name	=	"ecb-des-s390",
163a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
164a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
165a9e62fadSHerbert Xu 	.cra_blocksize		=	DES_BLOCK_SIZE,
166a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
167a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
168a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
169a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(ecb_des_alg.cra_list),
170a9e62fadSHerbert Xu 	.cra_u			=	{
171a9e62fadSHerbert Xu 		.blkcipher = {
172a9e62fadSHerbert Xu 			.min_keysize		=	DES_KEY_SIZE,
173a9e62fadSHerbert Xu 			.max_keysize		=	DES_KEY_SIZE,
174a9e62fadSHerbert Xu 			.setkey			=	des_setkey,
175a9e62fadSHerbert Xu 			.encrypt		=	ecb_des_encrypt,
176a9e62fadSHerbert Xu 			.decrypt		=	ecb_des_decrypt,
177a9e62fadSHerbert Xu 		}
178a9e62fadSHerbert Xu 	}
179a9e62fadSHerbert Xu };
180a9e62fadSHerbert Xu 
181a9e62fadSHerbert Xu static int cbc_des_encrypt(struct blkcipher_desc *desc,
182a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
183a9e62fadSHerbert Xu 			   unsigned int nbytes)
184a9e62fadSHerbert Xu {
185a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
186a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
187a9e62fadSHerbert Xu 
188a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
189a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
190a9e62fadSHerbert Xu }
191a9e62fadSHerbert Xu 
192a9e62fadSHerbert Xu static int cbc_des_decrypt(struct blkcipher_desc *desc,
193a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
194a9e62fadSHerbert Xu 			   unsigned int nbytes)
195a9e62fadSHerbert Xu {
196a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
197a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
198a9e62fadSHerbert Xu 
199a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
200a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
201a9e62fadSHerbert Xu }
202a9e62fadSHerbert Xu 
203a9e62fadSHerbert Xu static struct crypto_alg cbc_des_alg = {
204a9e62fadSHerbert Xu 	.cra_name		=	"cbc(des)",
205a9e62fadSHerbert Xu 	.cra_driver_name	=	"cbc-des-s390",
206a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
207a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
208a9e62fadSHerbert Xu 	.cra_blocksize		=	DES_BLOCK_SIZE,
209a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
210a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
211a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
212a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(cbc_des_alg.cra_list),
213a9e62fadSHerbert Xu 	.cra_u			=	{
214a9e62fadSHerbert Xu 		.blkcipher = {
215a9e62fadSHerbert Xu 			.min_keysize		=	DES_KEY_SIZE,
216a9e62fadSHerbert Xu 			.max_keysize		=	DES_KEY_SIZE,
217a9e62fadSHerbert Xu 			.ivsize			=	DES_BLOCK_SIZE,
218a9e62fadSHerbert Xu 			.setkey			=	des_setkey,
219a9e62fadSHerbert Xu 			.encrypt		=	cbc_des_encrypt,
220a9e62fadSHerbert Xu 			.decrypt		=	cbc_des_decrypt,
221a9e62fadSHerbert Xu 		}
222a9e62fadSHerbert Xu 	}
223a9e62fadSHerbert Xu };
224a9e62fadSHerbert Xu 
225c1e26e1eSJan Glauber /*
226c1e26e1eSJan Glauber  * RFC2451:
227c1e26e1eSJan Glauber  *
228c1e26e1eSJan Glauber  *   For DES-EDE3, there is no known need to reject weak or
229c1e26e1eSJan Glauber  *   complementation keys.  Any weakness is obviated by the use of
230c1e26e1eSJan Glauber  *   multiple keys.
231c1e26e1eSJan Glauber  *
232c1e26e1eSJan Glauber  *   However, if the first two or last two independent 64-bit keys are
233c1e26e1eSJan Glauber  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
234c1e26e1eSJan Glauber  *   same as DES.  Implementers MUST reject keys that exhibit this
235c1e26e1eSJan Glauber  *   property.
236c1e26e1eSJan Glauber  *
237c1e26e1eSJan Glauber  */
2386c2bb98bSHerbert Xu static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
239560c06aeSHerbert Xu 			   unsigned int keylen)
240c1e26e1eSJan Glauber {
2416c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
242560c06aeSHerbert Xu 	u32 *flags = &tfm->crt_flags;
243c1e26e1eSJan Glauber 
244c1e26e1eSJan Glauber 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
245c1e26e1eSJan Glauber 	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
24603b56ce5SJarod Wilson 		   DES_KEY_SIZE)) &&
24703b56ce5SJarod Wilson 	    (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
24803b56ce5SJarod Wilson 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
249c1e26e1eSJan Glauber 		return -EINVAL;
250c1e26e1eSJan Glauber 	}
251c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
252c1e26e1eSJan Glauber 	return 0;
253c1e26e1eSJan Glauber }
254c1e26e1eSJan Glauber 
2556c2bb98bSHerbert Xu static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
256c1e26e1eSJan Glauber {
2576c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
258c1e26e1eSJan Glauber 
259c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
2601efbd15cSJan Glauber 		      DES_BLOCK_SIZE);
261c1e26e1eSJan Glauber }
262c1e26e1eSJan Glauber 
2636c2bb98bSHerbert Xu static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
264c1e26e1eSJan Glauber {
2656c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
266c1e26e1eSJan Glauber 
267c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
2681efbd15cSJan Glauber 		      DES_BLOCK_SIZE);
269c1e26e1eSJan Glauber }
270c1e26e1eSJan Glauber 
271c1e26e1eSJan Glauber static struct crypto_alg des3_192_alg = {
272c1e26e1eSJan Glauber 	.cra_name		=	"des3_ede",
27365b75c36SHerbert Xu 	.cra_driver_name	=	"des3_ede-s390",
27465b75c36SHerbert Xu 	.cra_priority		=	CRYPT_S390_PRIORITY,
275c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
2761efbd15cSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
277c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
278c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
279c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des3_192_alg.cra_list),
280c1357833SJan Glauber 	.cra_u			=	{
281c1357833SJan Glauber 		.cipher = {
282c1e26e1eSJan Glauber 			.cia_min_keysize	=	DES3_192_KEY_SIZE,
283c1e26e1eSJan Glauber 			.cia_max_keysize	=	DES3_192_KEY_SIZE,
284c1e26e1eSJan Glauber 			.cia_setkey		=	des3_192_setkey,
285c1e26e1eSJan Glauber 			.cia_encrypt		=	des3_192_encrypt,
286b8dc6038SJan Glauber 			.cia_decrypt		=	des3_192_decrypt,
287c1357833SJan Glauber 		}
288c1357833SJan Glauber 	}
289c1e26e1eSJan Glauber };
290c1e26e1eSJan Glauber 
291a9e62fadSHerbert Xu static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
292a9e62fadSHerbert Xu 				struct scatterlist *dst,
293a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
294a9e62fadSHerbert Xu {
295a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
296a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
297a9e62fadSHerbert Xu 
298a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
299a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
300a9e62fadSHerbert Xu }
301a9e62fadSHerbert Xu 
302a9e62fadSHerbert Xu static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
303a9e62fadSHerbert Xu 				struct scatterlist *dst,
304a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
305a9e62fadSHerbert Xu {
306a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
307a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
308a9e62fadSHerbert Xu 
309a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
310a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
311a9e62fadSHerbert Xu }
312a9e62fadSHerbert Xu 
313a9e62fadSHerbert Xu static struct crypto_alg ecb_des3_192_alg = {
314a9e62fadSHerbert Xu 	.cra_name		=	"ecb(des3_ede)",
315a9e62fadSHerbert Xu 	.cra_driver_name	=	"ecb-des3_ede-s390",
316a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
317a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
3181efbd15cSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
319a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
320a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
321a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
322a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
323a9e62fadSHerbert Xu 						ecb_des3_192_alg.cra_list),
324a9e62fadSHerbert Xu 	.cra_u			=	{
325a9e62fadSHerbert Xu 		.blkcipher = {
326a9e62fadSHerbert Xu 			.min_keysize		=	DES3_192_KEY_SIZE,
327a9e62fadSHerbert Xu 			.max_keysize		=	DES3_192_KEY_SIZE,
328a9e62fadSHerbert Xu 			.setkey			=	des3_192_setkey,
329a9e62fadSHerbert Xu 			.encrypt		=	ecb_des3_192_encrypt,
330a9e62fadSHerbert Xu 			.decrypt		=	ecb_des3_192_decrypt,
331a9e62fadSHerbert Xu 		}
332a9e62fadSHerbert Xu 	}
333a9e62fadSHerbert Xu };
334a9e62fadSHerbert Xu 
335a9e62fadSHerbert Xu static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
336a9e62fadSHerbert Xu 				struct scatterlist *dst,
337a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
338a9e62fadSHerbert Xu {
339a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
340a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
341a9e62fadSHerbert Xu 
342a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
343a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
344a9e62fadSHerbert Xu }
345a9e62fadSHerbert Xu 
346a9e62fadSHerbert Xu static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
347a9e62fadSHerbert Xu 				struct scatterlist *dst,
348a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
349a9e62fadSHerbert Xu {
350a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
351a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
352a9e62fadSHerbert Xu 
353a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
354a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
355a9e62fadSHerbert Xu }
356a9e62fadSHerbert Xu 
357a9e62fadSHerbert Xu static struct crypto_alg cbc_des3_192_alg = {
358a9e62fadSHerbert Xu 	.cra_name		=	"cbc(des3_ede)",
359a9e62fadSHerbert Xu 	.cra_driver_name	=	"cbc-des3_ede-s390",
360a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
361a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
3621efbd15cSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
363a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
364a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
365a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
366a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
367a9e62fadSHerbert Xu 						cbc_des3_192_alg.cra_list),
368a9e62fadSHerbert Xu 	.cra_u			=	{
369a9e62fadSHerbert Xu 		.blkcipher = {
370a9e62fadSHerbert Xu 			.min_keysize		=	DES3_192_KEY_SIZE,
371a9e62fadSHerbert Xu 			.max_keysize		=	DES3_192_KEY_SIZE,
3721efbd15cSJan Glauber 			.ivsize			=	DES_BLOCK_SIZE,
373a9e62fadSHerbert Xu 			.setkey			=	des3_192_setkey,
374a9e62fadSHerbert Xu 			.encrypt		=	cbc_des3_192_encrypt,
375a9e62fadSHerbert Xu 			.decrypt		=	cbc_des3_192_decrypt,
376a9e62fadSHerbert Xu 		}
377a9e62fadSHerbert Xu 	}
378a9e62fadSHerbert Xu };
379a9e62fadSHerbert Xu 
3809f7819c1SHeiko Carstens static int des_s390_init(void)
381c1e26e1eSJan Glauber {
38280d663a4SJan Glauber 	int ret;
383c1e26e1eSJan Glauber 
3841822bc90SJan Glauber 	if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) ||
3851822bc90SJan Glauber 	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA))
38686aa9fc2SJan Glauber 		return -EOPNOTSUPP;
387c1e26e1eSJan Glauber 
388a9e62fadSHerbert Xu 	ret = crypto_register_alg(&des_alg);
389a9e62fadSHerbert Xu 	if (ret)
390a9e62fadSHerbert Xu 		goto des_err;
391a9e62fadSHerbert Xu 	ret = crypto_register_alg(&ecb_des_alg);
392a9e62fadSHerbert Xu 	if (ret)
393a9e62fadSHerbert Xu 		goto ecb_des_err;
394a9e62fadSHerbert Xu 	ret = crypto_register_alg(&cbc_des_alg);
395a9e62fadSHerbert Xu 	if (ret)
396a9e62fadSHerbert Xu 		goto cbc_des_err;
397a9e62fadSHerbert Xu 	ret = crypto_register_alg(&des3_192_alg);
398a9e62fadSHerbert Xu 	if (ret)
399a9e62fadSHerbert Xu 		goto des3_192_err;
400a9e62fadSHerbert Xu 	ret = crypto_register_alg(&ecb_des3_192_alg);
401a9e62fadSHerbert Xu 	if (ret)
402a9e62fadSHerbert Xu 		goto ecb_des3_192_err;
403a9e62fadSHerbert Xu 	ret = crypto_register_alg(&cbc_des3_192_alg);
404a9e62fadSHerbert Xu 	if (ret)
405a9e62fadSHerbert Xu 		goto cbc_des3_192_err;
406a9e62fadSHerbert Xu out:
407a9e62fadSHerbert Xu 	return ret;
408a9e62fadSHerbert Xu 
409a9e62fadSHerbert Xu cbc_des3_192_err:
410a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_192_alg);
411a9e62fadSHerbert Xu ecb_des3_192_err:
412c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_192_alg);
413a9e62fadSHerbert Xu des3_192_err:
414a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des_alg);
415a9e62fadSHerbert Xu cbc_des_err:
416a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des_alg);
417a9e62fadSHerbert Xu ecb_des_err:
418c1e26e1eSJan Glauber 	crypto_unregister_alg(&des_alg);
419a9e62fadSHerbert Xu des_err:
420a9e62fadSHerbert Xu 	goto out;
421c1e26e1eSJan Glauber }
422c1e26e1eSJan Glauber 
4231efbd15cSJan Glauber static void __exit des_s390_exit(void)
424c1e26e1eSJan Glauber {
425a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des3_192_alg);
426a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_192_alg);
427c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_192_alg);
428a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des_alg);
429a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des_alg);
430c1e26e1eSJan Glauber 	crypto_unregister_alg(&des_alg);
431c1e26e1eSJan Glauber }
432c1e26e1eSJan Glauber 
4339f7819c1SHeiko Carstens module_init(des_s390_init);
4341efbd15cSJan Glauber module_exit(des_s390_exit);
435c1e26e1eSJan Glauber 
436c1e26e1eSJan Glauber MODULE_ALIAS("des");
437c1e26e1eSJan Glauber MODULE_ALIAS("des3_ede");
438c1e26e1eSJan Glauber 
439c1e26e1eSJan Glauber MODULE_LICENSE("GPL");
440c1e26e1eSJan Glauber MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
441