xref: /openbmc/linux/arch/s390/crypto/des_s390.c (revision a9e62fad)
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  */
16a9e62fadSHerbert Xu 
17a9e62fadSHerbert Xu #include <crypto/algapi.h>
18c1e26e1eSJan Glauber #include <linux/init.h>
19c1e26e1eSJan Glauber #include <linux/module.h>
20c1357833SJan Glauber 
21c1e26e1eSJan Glauber #include "crypt_s390.h"
22c1e26e1eSJan Glauber #include "crypto_des.h"
23c1e26e1eSJan Glauber 
24c1e26e1eSJan Glauber #define DES_BLOCK_SIZE 8
25c1e26e1eSJan Glauber #define DES_KEY_SIZE 8
26c1e26e1eSJan Glauber 
27c1e26e1eSJan Glauber #define DES3_128_KEY_SIZE	(2 * DES_KEY_SIZE)
28c1e26e1eSJan Glauber #define DES3_128_BLOCK_SIZE	DES_BLOCK_SIZE
29c1e26e1eSJan Glauber 
30c1e26e1eSJan Glauber #define DES3_192_KEY_SIZE	(3 * DES_KEY_SIZE)
31c1e26e1eSJan Glauber #define DES3_192_BLOCK_SIZE	DES_BLOCK_SIZE
32c1e26e1eSJan Glauber 
33c1e26e1eSJan Glauber struct crypt_s390_des_ctx {
34c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
35c1e26e1eSJan Glauber 	u8 key[DES_KEY_SIZE];
36c1e26e1eSJan Glauber };
37c1e26e1eSJan Glauber 
38c1e26e1eSJan Glauber struct crypt_s390_des3_128_ctx {
39c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
40c1e26e1eSJan Glauber 	u8 key[DES3_128_KEY_SIZE];
41c1e26e1eSJan Glauber };
42c1e26e1eSJan Glauber 
43c1e26e1eSJan Glauber struct crypt_s390_des3_192_ctx {
44c1e26e1eSJan Glauber 	u8 iv[DES_BLOCK_SIZE];
45c1e26e1eSJan Glauber 	u8 key[DES3_192_KEY_SIZE];
46c1e26e1eSJan Glauber };
47c1e26e1eSJan Glauber 
486c2bb98bSHerbert Xu static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
49560c06aeSHerbert Xu 		      unsigned int keylen)
50c1e26e1eSJan Glauber {
516c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
52560c06aeSHerbert Xu 	u32 *flags = &tfm->crt_flags;
53c1e26e1eSJan Glauber 	int ret;
54c1e26e1eSJan Glauber 
55c1357833SJan Glauber 	/* test if key is valid (not a weak key) */
56c1e26e1eSJan Glauber 	ret = crypto_des_check_key(key, keylen, flags);
57c1357833SJan Glauber 	if (ret == 0)
58c1e26e1eSJan Glauber 		memcpy(dctx->key, key, keylen);
59c1e26e1eSJan Glauber 	return ret;
60c1e26e1eSJan Glauber }
61c1e26e1eSJan Glauber 
626c2bb98bSHerbert Xu static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
63c1e26e1eSJan Glauber {
646c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
65c1e26e1eSJan Glauber 
66b8dc6038SJan Glauber 	crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
67c1e26e1eSJan Glauber }
68c1e26e1eSJan Glauber 
696c2bb98bSHerbert Xu static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
70c1e26e1eSJan Glauber {
716c2bb98bSHerbert Xu 	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
72c1e26e1eSJan Glauber 
73b8dc6038SJan Glauber 	crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
74b8dc6038SJan Glauber }
75b8dc6038SJan Glauber 
76b8dc6038SJan Glauber static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
77b8dc6038SJan Glauber 				    const u8 *in, unsigned int nbytes)
78b8dc6038SJan Glauber {
79b8dc6038SJan Glauber 	struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
80b8dc6038SJan Glauber 	int ret;
81b8dc6038SJan Glauber 
82b8dc6038SJan Glauber 	/* only use complete blocks */
83b8dc6038SJan Glauber 	nbytes &= ~(DES_BLOCK_SIZE - 1);
84b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
85b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
86b8dc6038SJan Glauber 
87b8dc6038SJan Glauber 	return nbytes;
88b8dc6038SJan Glauber }
89b8dc6038SJan Glauber 
90b8dc6038SJan Glauber static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
91b8dc6038SJan Glauber 				    const u8 *in, unsigned int nbytes)
92b8dc6038SJan Glauber {
93b8dc6038SJan Glauber 	struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
94b8dc6038SJan Glauber 	int ret;
95b8dc6038SJan Glauber 
96b8dc6038SJan Glauber 	/* only use complete blocks */
97b8dc6038SJan Glauber 	nbytes &= ~(DES_BLOCK_SIZE - 1);
98b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
99b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
100b8dc6038SJan Glauber 
101b8dc6038SJan Glauber 	return nbytes;
102b8dc6038SJan Glauber }
103b8dc6038SJan Glauber 
104b8dc6038SJan Glauber static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
105b8dc6038SJan Glauber 				    const u8 *in, unsigned int nbytes)
106b8dc6038SJan Glauber {
107b8dc6038SJan Glauber 	struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
108b8dc6038SJan Glauber 	int ret;
109b8dc6038SJan Glauber 
110b8dc6038SJan Glauber 	/* only use complete blocks */
111b8dc6038SJan Glauber 	nbytes &= ~(DES_BLOCK_SIZE - 1);
112b8dc6038SJan Glauber 
113b8dc6038SJan Glauber 	memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
114b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
115b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
116b8dc6038SJan Glauber 
117b8dc6038SJan Glauber 	memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
118b8dc6038SJan Glauber 	return nbytes;
119b8dc6038SJan Glauber }
120b8dc6038SJan Glauber 
121b8dc6038SJan Glauber static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
122b8dc6038SJan Glauber 				    const u8 *in, unsigned int nbytes)
123b8dc6038SJan Glauber {
124b8dc6038SJan Glauber 	struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
125b8dc6038SJan Glauber 	int ret;
126b8dc6038SJan Glauber 
127b8dc6038SJan Glauber 	/* only use complete blocks */
128b8dc6038SJan Glauber 	nbytes &= ~(DES_BLOCK_SIZE - 1);
129b8dc6038SJan Glauber 
130b8dc6038SJan Glauber 	memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
131b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
132b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
133b8dc6038SJan Glauber 
134b8dc6038SJan Glauber 	return nbytes;
135c1e26e1eSJan Glauber }
136c1e26e1eSJan Glauber 
137c1e26e1eSJan Glauber static struct crypto_alg des_alg = {
138c1e26e1eSJan Glauber 	.cra_name		=	"des",
13965b75c36SHerbert Xu 	.cra_driver_name	=	"des-s390",
14065b75c36SHerbert Xu 	.cra_priority		=	CRYPT_S390_PRIORITY,
141c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
142c1e26e1eSJan Glauber 	.cra_blocksize		=	DES_BLOCK_SIZE,
143c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
144c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
145c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
146c1357833SJan Glauber 	.cra_u			=	{
147c1357833SJan Glauber 		.cipher = {
148c1e26e1eSJan Glauber 			.cia_min_keysize	=	DES_KEY_SIZE,
149c1e26e1eSJan Glauber 			.cia_max_keysize	=	DES_KEY_SIZE,
150c1e26e1eSJan Glauber 			.cia_setkey		=	des_setkey,
151c1e26e1eSJan Glauber 			.cia_encrypt		=	des_encrypt,
152b8dc6038SJan Glauber 			.cia_decrypt		=	des_decrypt,
153b8dc6038SJan Glauber 			.cia_encrypt_ecb	=	des_encrypt_ecb,
154b8dc6038SJan Glauber 			.cia_decrypt_ecb	=	des_decrypt_ecb,
155b8dc6038SJan Glauber 			.cia_encrypt_cbc	=	des_encrypt_cbc,
156b8dc6038SJan Glauber 			.cia_decrypt_cbc	=	des_decrypt_cbc,
157c1357833SJan Glauber 		}
158c1357833SJan Glauber 	}
159c1e26e1eSJan Glauber };
160c1e26e1eSJan Glauber 
161a9e62fadSHerbert Xu static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
162a9e62fadSHerbert Xu 			    void *param, struct blkcipher_walk *walk)
163a9e62fadSHerbert Xu {
164a9e62fadSHerbert Xu 	int ret = blkcipher_walk_virt(desc, walk);
165a9e62fadSHerbert Xu 	unsigned int nbytes;
166a9e62fadSHerbert Xu 
167a9e62fadSHerbert Xu 	while ((nbytes = walk->nbytes)) {
168a9e62fadSHerbert Xu 		/* only use complete blocks */
169a9e62fadSHerbert Xu 		unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
170a9e62fadSHerbert Xu 		u8 *out = walk->dst.virt.addr;
171a9e62fadSHerbert Xu 		u8 *in = walk->src.virt.addr;
172a9e62fadSHerbert Xu 
173a9e62fadSHerbert Xu 		ret = crypt_s390_km(func, param, out, in, n);
174a9e62fadSHerbert Xu 		BUG_ON((ret < 0) || (ret != n));
175a9e62fadSHerbert Xu 
176a9e62fadSHerbert Xu 		nbytes &= DES_BLOCK_SIZE - 1;
177a9e62fadSHerbert Xu 		ret = blkcipher_walk_done(desc, walk, nbytes);
178a9e62fadSHerbert Xu 	}
179a9e62fadSHerbert Xu 
180a9e62fadSHerbert Xu 	return ret;
181a9e62fadSHerbert Xu }
182a9e62fadSHerbert Xu 
183a9e62fadSHerbert Xu static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
184a9e62fadSHerbert Xu 			    void *param, struct blkcipher_walk *walk)
185a9e62fadSHerbert Xu {
186a9e62fadSHerbert Xu 	int ret = blkcipher_walk_virt(desc, walk);
187a9e62fadSHerbert Xu 	unsigned int nbytes = walk->nbytes;
188a9e62fadSHerbert Xu 
189a9e62fadSHerbert Xu 	if (!nbytes)
190a9e62fadSHerbert Xu 		goto out;
191a9e62fadSHerbert Xu 
192a9e62fadSHerbert Xu 	memcpy(param, walk->iv, DES_BLOCK_SIZE);
193a9e62fadSHerbert Xu 	do {
194a9e62fadSHerbert Xu 		/* only use complete blocks */
195a9e62fadSHerbert Xu 		unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
196a9e62fadSHerbert Xu 		u8 *out = walk->dst.virt.addr;
197a9e62fadSHerbert Xu 		u8 *in = walk->src.virt.addr;
198a9e62fadSHerbert Xu 
199a9e62fadSHerbert Xu 		ret = crypt_s390_kmc(func, param, out, in, n);
200a9e62fadSHerbert Xu 		BUG_ON((ret < 0) || (ret != n));
201a9e62fadSHerbert Xu 
202a9e62fadSHerbert Xu 		nbytes &= DES_BLOCK_SIZE - 1;
203a9e62fadSHerbert Xu 		ret = blkcipher_walk_done(desc, walk, nbytes);
204a9e62fadSHerbert Xu 	} while ((nbytes = walk->nbytes));
205a9e62fadSHerbert Xu 	memcpy(walk->iv, param, DES_BLOCK_SIZE);
206a9e62fadSHerbert Xu 
207a9e62fadSHerbert Xu out:
208a9e62fadSHerbert Xu 	return ret;
209a9e62fadSHerbert Xu }
210a9e62fadSHerbert Xu 
211a9e62fadSHerbert Xu static int ecb_des_encrypt(struct blkcipher_desc *desc,
212a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
213a9e62fadSHerbert Xu 			   unsigned int nbytes)
214a9e62fadSHerbert Xu {
215a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
216a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
217a9e62fadSHerbert Xu 
218a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
219a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
220a9e62fadSHerbert Xu }
221a9e62fadSHerbert Xu 
222a9e62fadSHerbert Xu static int ecb_des_decrypt(struct blkcipher_desc *desc,
223a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
224a9e62fadSHerbert Xu 			   unsigned int nbytes)
225a9e62fadSHerbert Xu {
226a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
227a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
228a9e62fadSHerbert Xu 
229a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
230a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
231a9e62fadSHerbert Xu }
232a9e62fadSHerbert Xu 
233a9e62fadSHerbert Xu static struct crypto_alg ecb_des_alg = {
234a9e62fadSHerbert Xu 	.cra_name		=	"ecb(des)",
235a9e62fadSHerbert Xu 	.cra_driver_name	=	"ecb-des-s390",
236a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
237a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
238a9e62fadSHerbert Xu 	.cra_blocksize		=	DES_BLOCK_SIZE,
239a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
240a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
241a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
242a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(ecb_des_alg.cra_list),
243a9e62fadSHerbert Xu 	.cra_u			=	{
244a9e62fadSHerbert Xu 		.blkcipher = {
245a9e62fadSHerbert Xu 			.min_keysize		=	DES_KEY_SIZE,
246a9e62fadSHerbert Xu 			.max_keysize		=	DES_KEY_SIZE,
247a9e62fadSHerbert Xu 			.setkey			=	des_setkey,
248a9e62fadSHerbert Xu 			.encrypt		=	ecb_des_encrypt,
249a9e62fadSHerbert Xu 			.decrypt		=	ecb_des_decrypt,
250a9e62fadSHerbert Xu 		}
251a9e62fadSHerbert Xu 	}
252a9e62fadSHerbert Xu };
253a9e62fadSHerbert Xu 
254a9e62fadSHerbert Xu static int cbc_des_encrypt(struct blkcipher_desc *desc,
255a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
256a9e62fadSHerbert Xu 			   unsigned int nbytes)
257a9e62fadSHerbert Xu {
258a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
259a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
260a9e62fadSHerbert Xu 
261a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
262a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
263a9e62fadSHerbert Xu }
264a9e62fadSHerbert Xu 
265a9e62fadSHerbert Xu static int cbc_des_decrypt(struct blkcipher_desc *desc,
266a9e62fadSHerbert Xu 			   struct scatterlist *dst, struct scatterlist *src,
267a9e62fadSHerbert Xu 			   unsigned int nbytes)
268a9e62fadSHerbert Xu {
269a9e62fadSHerbert Xu 	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
270a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
271a9e62fadSHerbert Xu 
272a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
273a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
274a9e62fadSHerbert Xu }
275a9e62fadSHerbert Xu 
276a9e62fadSHerbert Xu static struct crypto_alg cbc_des_alg = {
277a9e62fadSHerbert Xu 	.cra_name		=	"cbc(des)",
278a9e62fadSHerbert Xu 	.cra_driver_name	=	"cbc-des-s390",
279a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
280a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
281a9e62fadSHerbert Xu 	.cra_blocksize		=	DES_BLOCK_SIZE,
282a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
283a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
284a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
285a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(cbc_des_alg.cra_list),
286a9e62fadSHerbert Xu 	.cra_u			=	{
287a9e62fadSHerbert Xu 		.blkcipher = {
288a9e62fadSHerbert Xu 			.min_keysize		=	DES_KEY_SIZE,
289a9e62fadSHerbert Xu 			.max_keysize		=	DES_KEY_SIZE,
290a9e62fadSHerbert Xu 			.ivsize			=	DES_BLOCK_SIZE,
291a9e62fadSHerbert Xu 			.setkey			=	des_setkey,
292a9e62fadSHerbert Xu 			.encrypt		=	cbc_des_encrypt,
293a9e62fadSHerbert Xu 			.decrypt		=	cbc_des_decrypt,
294a9e62fadSHerbert Xu 		}
295a9e62fadSHerbert Xu 	}
296a9e62fadSHerbert Xu };
297a9e62fadSHerbert Xu 
298c1e26e1eSJan Glauber /*
299c1e26e1eSJan Glauber  * RFC2451:
300c1e26e1eSJan Glauber  *
301c1e26e1eSJan Glauber  *   For DES-EDE3, there is no known need to reject weak or
302c1e26e1eSJan Glauber  *   complementation keys.  Any weakness is obviated by the use of
303c1e26e1eSJan Glauber  *   multiple keys.
304c1e26e1eSJan Glauber  *
305c1e26e1eSJan Glauber  *   However, if the two  independent 64-bit keys are equal,
306c1e26e1eSJan Glauber  *   then the DES3 operation is simply the same as DES.
307c1e26e1eSJan Glauber  *   Implementers MUST reject keys that exhibit this property.
308c1e26e1eSJan Glauber  *
309c1e26e1eSJan Glauber  */
3106c2bb98bSHerbert Xu static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
311560c06aeSHerbert Xu 			   unsigned int keylen)
312c1e26e1eSJan Glauber {
313c1e26e1eSJan Glauber 	int i, ret;
3146c2bb98bSHerbert Xu 	struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
315c1e26e1eSJan Glauber 	const u8 *temp_key = key;
316560c06aeSHerbert Xu 	u32 *flags = &tfm->crt_flags;
317c1e26e1eSJan Glauber 
318c1e26e1eSJan Glauber 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
319c1e26e1eSJan Glauber 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
320c1e26e1eSJan Glauber 		return -EINVAL;
321c1e26e1eSJan Glauber 	}
322c1e26e1eSJan Glauber 	for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
323c1e26e1eSJan Glauber 		ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
324c1e26e1eSJan Glauber 		if (ret < 0)
325c1e26e1eSJan Glauber 			return ret;
326c1e26e1eSJan Glauber 	}
327c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
328c1e26e1eSJan Glauber 	return 0;
329c1e26e1eSJan Glauber }
330c1e26e1eSJan Glauber 
3316c2bb98bSHerbert Xu static void des3_128_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
332c1e26e1eSJan Glauber {
3336c2bb98bSHerbert Xu 	struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
334c1e26e1eSJan Glauber 
335c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
336c1e26e1eSJan Glauber 		      DES3_128_BLOCK_SIZE);
337c1e26e1eSJan Glauber }
338c1e26e1eSJan Glauber 
3396c2bb98bSHerbert Xu static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
340c1e26e1eSJan Glauber {
3416c2bb98bSHerbert Xu 	struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
342c1e26e1eSJan Glauber 
343c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
344c1e26e1eSJan Glauber 		      DES3_128_BLOCK_SIZE);
345c1e26e1eSJan Glauber }
346c1e26e1eSJan Glauber 
347b8dc6038SJan Glauber static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
348b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
349b8dc6038SJan Glauber 					 unsigned int nbytes)
350b8dc6038SJan Glauber {
351b8dc6038SJan Glauber 	struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
352b8dc6038SJan Glauber 	int ret;
353b8dc6038SJan Glauber 
354b8dc6038SJan Glauber 	/* only use complete blocks */
355b8dc6038SJan Glauber 	nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
356b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
357b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
358b8dc6038SJan Glauber 
359b8dc6038SJan Glauber 	return nbytes;
360b8dc6038SJan Glauber }
361b8dc6038SJan Glauber 
362b8dc6038SJan Glauber static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
363b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
364b8dc6038SJan Glauber 					 unsigned int nbytes)
365b8dc6038SJan Glauber {
366b8dc6038SJan Glauber 	struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
367b8dc6038SJan Glauber 	int ret;
368b8dc6038SJan Glauber 
369b8dc6038SJan Glauber 	/* only use complete blocks */
370b8dc6038SJan Glauber 	nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
371b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
372b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
373b8dc6038SJan Glauber 
374b8dc6038SJan Glauber 	return nbytes;
375b8dc6038SJan Glauber }
376b8dc6038SJan Glauber 
377b8dc6038SJan Glauber static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
378b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
379b8dc6038SJan Glauber 					 unsigned int nbytes)
380b8dc6038SJan Glauber {
381b8dc6038SJan Glauber 	struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
382b8dc6038SJan Glauber 	int ret;
383b8dc6038SJan Glauber 
384b8dc6038SJan Glauber 	/* only use complete blocks */
385b8dc6038SJan Glauber 	nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
386b8dc6038SJan Glauber 
387b8dc6038SJan Glauber 	memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
388b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
389b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
390b8dc6038SJan Glauber 
391b8dc6038SJan Glauber 	memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
392b8dc6038SJan Glauber 	return nbytes;
393b8dc6038SJan Glauber }
394b8dc6038SJan Glauber 
395b8dc6038SJan Glauber static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
396b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
397b8dc6038SJan Glauber 					 unsigned int nbytes)
398b8dc6038SJan Glauber {
399b8dc6038SJan Glauber 	struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
400b8dc6038SJan Glauber 	int ret;
401b8dc6038SJan Glauber 
402b8dc6038SJan Glauber 	/* only use complete blocks */
403b8dc6038SJan Glauber 	nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
404b8dc6038SJan Glauber 
405b8dc6038SJan Glauber 	memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
406b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
407b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
408b8dc6038SJan Glauber 
409b8dc6038SJan Glauber 	return nbytes;
410b8dc6038SJan Glauber }
411b8dc6038SJan Glauber 
412c1e26e1eSJan Glauber static struct crypto_alg des3_128_alg = {
413c1e26e1eSJan Glauber 	.cra_name		=	"des3_ede128",
41465b75c36SHerbert Xu 	.cra_driver_name	=	"des3_ede128-s390",
41565b75c36SHerbert Xu 	.cra_priority		=	CRYPT_S390_PRIORITY,
416c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
417c1e26e1eSJan Glauber 	.cra_blocksize		=	DES3_128_BLOCK_SIZE,
418c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_128_ctx),
419c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
420c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des3_128_alg.cra_list),
421c1357833SJan Glauber 	.cra_u			=	{
422c1357833SJan Glauber 		.cipher = {
423c1e26e1eSJan Glauber 			.cia_min_keysize	=	DES3_128_KEY_SIZE,
424c1e26e1eSJan Glauber 			.cia_max_keysize	=	DES3_128_KEY_SIZE,
425c1e26e1eSJan Glauber 			.cia_setkey		=	des3_128_setkey,
426c1e26e1eSJan Glauber 			.cia_encrypt		=	des3_128_encrypt,
427b8dc6038SJan Glauber 			.cia_decrypt		=	des3_128_decrypt,
428b8dc6038SJan Glauber 			.cia_encrypt_ecb	=	des3_128_encrypt_ecb,
429b8dc6038SJan Glauber 			.cia_decrypt_ecb	=	des3_128_decrypt_ecb,
430b8dc6038SJan Glauber 			.cia_encrypt_cbc	=	des3_128_encrypt_cbc,
431b8dc6038SJan Glauber 			.cia_decrypt_cbc	=	des3_128_decrypt_cbc,
432c1357833SJan Glauber 		}
433c1357833SJan Glauber 	}
434c1e26e1eSJan Glauber };
435c1e26e1eSJan Glauber 
436a9e62fadSHerbert Xu static int ecb_des3_128_encrypt(struct blkcipher_desc *desc,
437a9e62fadSHerbert Xu 				struct scatterlist *dst,
438a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
439a9e62fadSHerbert Xu {
440a9e62fadSHerbert Xu 	struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
441a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
442a9e62fadSHerbert Xu 
443a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
444a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_128_ENCRYPT, sctx->key, &walk);
445a9e62fadSHerbert Xu }
446a9e62fadSHerbert Xu 
447a9e62fadSHerbert Xu static int ecb_des3_128_decrypt(struct blkcipher_desc *desc,
448a9e62fadSHerbert Xu 				struct scatterlist *dst,
449a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
450a9e62fadSHerbert Xu {
451a9e62fadSHerbert Xu 	struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
452a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
453a9e62fadSHerbert Xu 
454a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
455a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_128_DECRYPT, sctx->key, &walk);
456a9e62fadSHerbert Xu }
457a9e62fadSHerbert Xu 
458a9e62fadSHerbert Xu static struct crypto_alg ecb_des3_128_alg = {
459a9e62fadSHerbert Xu 	.cra_name		=	"ecb(des3_ede128)",
460a9e62fadSHerbert Xu 	.cra_driver_name	=	"ecb-des3_ede128-s390",
461a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
462a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
463a9e62fadSHerbert Xu 	.cra_blocksize		=	DES3_128_BLOCK_SIZE,
464a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_128_ctx),
465a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
466a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
467a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
468a9e62fadSHerbert Xu 						ecb_des3_128_alg.cra_list),
469a9e62fadSHerbert Xu 	.cra_u			=	{
470a9e62fadSHerbert Xu 		.blkcipher = {
471a9e62fadSHerbert Xu 			.min_keysize		=	DES3_128_KEY_SIZE,
472a9e62fadSHerbert Xu 			.max_keysize		=	DES3_128_KEY_SIZE,
473a9e62fadSHerbert Xu 			.setkey			=	des3_128_setkey,
474a9e62fadSHerbert Xu 			.encrypt		=	ecb_des3_128_encrypt,
475a9e62fadSHerbert Xu 			.decrypt		=	ecb_des3_128_decrypt,
476a9e62fadSHerbert Xu 		}
477a9e62fadSHerbert Xu 	}
478a9e62fadSHerbert Xu };
479a9e62fadSHerbert Xu 
480a9e62fadSHerbert Xu static int cbc_des3_128_encrypt(struct blkcipher_desc *desc,
481a9e62fadSHerbert Xu 				struct scatterlist *dst,
482a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
483a9e62fadSHerbert Xu {
484a9e62fadSHerbert Xu 	struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
485a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
486a9e62fadSHerbert Xu 
487a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
488a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_128_ENCRYPT, sctx->iv, &walk);
489a9e62fadSHerbert Xu }
490a9e62fadSHerbert Xu 
491a9e62fadSHerbert Xu static int cbc_des3_128_decrypt(struct blkcipher_desc *desc,
492a9e62fadSHerbert Xu 				struct scatterlist *dst,
493a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
494a9e62fadSHerbert Xu {
495a9e62fadSHerbert Xu 	struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
496a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
497a9e62fadSHerbert Xu 
498a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
499a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_128_DECRYPT, sctx->iv, &walk);
500a9e62fadSHerbert Xu }
501a9e62fadSHerbert Xu 
502a9e62fadSHerbert Xu static struct crypto_alg cbc_des3_128_alg = {
503a9e62fadSHerbert Xu 	.cra_name		=	"cbc(des3_ede128)",
504a9e62fadSHerbert Xu 	.cra_driver_name	=	"cbc-des3_ede128-s390",
505a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
506a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
507a9e62fadSHerbert Xu 	.cra_blocksize		=	DES3_128_BLOCK_SIZE,
508a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_128_ctx),
509a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
510a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
511a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
512a9e62fadSHerbert Xu 						cbc_des3_128_alg.cra_list),
513a9e62fadSHerbert Xu 	.cra_u			=	{
514a9e62fadSHerbert Xu 		.blkcipher = {
515a9e62fadSHerbert Xu 			.min_keysize		=	DES3_128_KEY_SIZE,
516a9e62fadSHerbert Xu 			.max_keysize		=	DES3_128_KEY_SIZE,
517a9e62fadSHerbert Xu 			.ivsize			=	DES3_128_BLOCK_SIZE,
518a9e62fadSHerbert Xu 			.setkey			=	des3_128_setkey,
519a9e62fadSHerbert Xu 			.encrypt		=	cbc_des3_128_encrypt,
520a9e62fadSHerbert Xu 			.decrypt		=	cbc_des3_128_decrypt,
521a9e62fadSHerbert Xu 		}
522a9e62fadSHerbert Xu 	}
523a9e62fadSHerbert Xu };
524a9e62fadSHerbert Xu 
525c1e26e1eSJan Glauber /*
526c1e26e1eSJan Glauber  * RFC2451:
527c1e26e1eSJan Glauber  *
528c1e26e1eSJan Glauber  *   For DES-EDE3, there is no known need to reject weak or
529c1e26e1eSJan Glauber  *   complementation keys.  Any weakness is obviated by the use of
530c1e26e1eSJan Glauber  *   multiple keys.
531c1e26e1eSJan Glauber  *
532c1e26e1eSJan Glauber  *   However, if the first two or last two independent 64-bit keys are
533c1e26e1eSJan Glauber  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
534c1e26e1eSJan Glauber  *   same as DES.  Implementers MUST reject keys that exhibit this
535c1e26e1eSJan Glauber  *   property.
536c1e26e1eSJan Glauber  *
537c1e26e1eSJan Glauber  */
5386c2bb98bSHerbert Xu static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
539560c06aeSHerbert Xu 			   unsigned int keylen)
540c1e26e1eSJan Glauber {
541c1e26e1eSJan Glauber 	int i, ret;
5426c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
543c1357833SJan Glauber 	const u8 *temp_key = key;
544560c06aeSHerbert Xu 	u32 *flags = &tfm->crt_flags;
545c1e26e1eSJan Glauber 
546c1e26e1eSJan Glauber 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
547c1e26e1eSJan Glauber 	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
548c1e26e1eSJan Glauber 		   DES_KEY_SIZE))) {
549c1e26e1eSJan Glauber 
550c1e26e1eSJan Glauber 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
551c1e26e1eSJan Glauber 		return -EINVAL;
552c1e26e1eSJan Glauber 	}
553c1e26e1eSJan Glauber 	for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
554c1e26e1eSJan Glauber 		ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
555c1357833SJan Glauber 		if (ret < 0)
556c1e26e1eSJan Glauber 			return ret;
557c1e26e1eSJan Glauber 	}
558c1e26e1eSJan Glauber 	memcpy(dctx->key, key, keylen);
559c1e26e1eSJan Glauber 	return 0;
560c1e26e1eSJan Glauber }
561c1e26e1eSJan Glauber 
5626c2bb98bSHerbert Xu static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
563c1e26e1eSJan Glauber {
5646c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
565c1e26e1eSJan Glauber 
566c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
567c1e26e1eSJan Glauber 		      DES3_192_BLOCK_SIZE);
568c1e26e1eSJan Glauber }
569c1e26e1eSJan Glauber 
5706c2bb98bSHerbert Xu static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
571c1e26e1eSJan Glauber {
5726c2bb98bSHerbert Xu 	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
573c1e26e1eSJan Glauber 
574c1e26e1eSJan Glauber 	crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
575c1e26e1eSJan Glauber 		      DES3_192_BLOCK_SIZE);
576c1e26e1eSJan Glauber }
577c1e26e1eSJan Glauber 
578b8dc6038SJan Glauber static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
579b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
580b8dc6038SJan Glauber 					 unsigned int nbytes)
581b8dc6038SJan Glauber {
582b8dc6038SJan Glauber 	struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
583b8dc6038SJan Glauber 	int ret;
584b8dc6038SJan Glauber 
585b8dc6038SJan Glauber 	/* only use complete blocks */
586b8dc6038SJan Glauber 	nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
587b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
588b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
589b8dc6038SJan Glauber 
590b8dc6038SJan Glauber 	return nbytes;
591b8dc6038SJan Glauber }
592b8dc6038SJan Glauber 
593b8dc6038SJan Glauber static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
594b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
595b8dc6038SJan Glauber 					 unsigned int nbytes)
596b8dc6038SJan Glauber {
597b8dc6038SJan Glauber 	struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
598b8dc6038SJan Glauber 	int ret;
599b8dc6038SJan Glauber 
600b8dc6038SJan Glauber 	/* only use complete blocks */
601b8dc6038SJan Glauber 	nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
602b8dc6038SJan Glauber 	ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
603b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
604b8dc6038SJan Glauber 
605b8dc6038SJan Glauber 	return nbytes;
606b8dc6038SJan Glauber }
607b8dc6038SJan Glauber 
608b8dc6038SJan Glauber static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
609b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
610b8dc6038SJan Glauber 					 unsigned int nbytes)
611b8dc6038SJan Glauber {
612b8dc6038SJan Glauber 	struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
613b8dc6038SJan Glauber 	int ret;
614b8dc6038SJan Glauber 
615b8dc6038SJan Glauber 	/* only use complete blocks */
616b8dc6038SJan Glauber 	nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
617b8dc6038SJan Glauber 
618b8dc6038SJan Glauber 	memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
619b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
620b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
621b8dc6038SJan Glauber 
622b8dc6038SJan Glauber 	memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
623b8dc6038SJan Glauber 	return nbytes;
624b8dc6038SJan Glauber }
625b8dc6038SJan Glauber 
626b8dc6038SJan Glauber static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
627b8dc6038SJan Glauber 					 u8 *out, const u8 *in,
628b8dc6038SJan Glauber 					 unsigned int nbytes)
629b8dc6038SJan Glauber {
630b8dc6038SJan Glauber 	struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
631b8dc6038SJan Glauber 	int ret;
632b8dc6038SJan Glauber 
633b8dc6038SJan Glauber 	/* only use complete blocks */
634b8dc6038SJan Glauber 	nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
635b8dc6038SJan Glauber 
636b8dc6038SJan Glauber 	memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
637b8dc6038SJan Glauber 	ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
638b8dc6038SJan Glauber 	BUG_ON((ret < 0) || (ret != nbytes));
639b8dc6038SJan Glauber 
640b8dc6038SJan Glauber 	return nbytes;
641b8dc6038SJan Glauber }
642b8dc6038SJan Glauber 
643c1e26e1eSJan Glauber static struct crypto_alg des3_192_alg = {
644c1e26e1eSJan Glauber 	.cra_name		=	"des3_ede",
64565b75c36SHerbert Xu 	.cra_driver_name	=	"des3_ede-s390",
64665b75c36SHerbert Xu 	.cra_priority		=	CRYPT_S390_PRIORITY,
647c1e26e1eSJan Glauber 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
648c1e26e1eSJan Glauber 	.cra_blocksize		=	DES3_192_BLOCK_SIZE,
649c1e26e1eSJan Glauber 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
650c1e26e1eSJan Glauber 	.cra_module		=	THIS_MODULE,
651c1e26e1eSJan Glauber 	.cra_list		=	LIST_HEAD_INIT(des3_192_alg.cra_list),
652c1357833SJan Glauber 	.cra_u			=	{
653c1357833SJan Glauber 		.cipher = {
654c1e26e1eSJan Glauber 			.cia_min_keysize	=	DES3_192_KEY_SIZE,
655c1e26e1eSJan Glauber 			.cia_max_keysize	=	DES3_192_KEY_SIZE,
656c1e26e1eSJan Glauber 			.cia_setkey		=	des3_192_setkey,
657c1e26e1eSJan Glauber 			.cia_encrypt		=	des3_192_encrypt,
658b8dc6038SJan Glauber 			.cia_decrypt		=	des3_192_decrypt,
659b8dc6038SJan Glauber 			.cia_encrypt_ecb	=	des3_192_encrypt_ecb,
660b8dc6038SJan Glauber 			.cia_decrypt_ecb	=	des3_192_decrypt_ecb,
661b8dc6038SJan Glauber 			.cia_encrypt_cbc	=	des3_192_encrypt_cbc,
662b8dc6038SJan Glauber 			.cia_decrypt_cbc	=	des3_192_decrypt_cbc,
663c1357833SJan Glauber 		}
664c1357833SJan Glauber 	}
665c1e26e1eSJan Glauber };
666c1e26e1eSJan Glauber 
667a9e62fadSHerbert Xu static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
668a9e62fadSHerbert Xu 				struct scatterlist *dst,
669a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
670a9e62fadSHerbert Xu {
671a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
672a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
673a9e62fadSHerbert Xu 
674a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
675a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
676a9e62fadSHerbert Xu }
677a9e62fadSHerbert Xu 
678a9e62fadSHerbert Xu static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
679a9e62fadSHerbert Xu 				struct scatterlist *dst,
680a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
681a9e62fadSHerbert Xu {
682a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
683a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
684a9e62fadSHerbert Xu 
685a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
686a9e62fadSHerbert Xu 	return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
687a9e62fadSHerbert Xu }
688a9e62fadSHerbert Xu 
689a9e62fadSHerbert Xu static struct crypto_alg ecb_des3_192_alg = {
690a9e62fadSHerbert Xu 	.cra_name		=	"ecb(des3_ede)",
691a9e62fadSHerbert Xu 	.cra_driver_name	=	"ecb-des3_ede-s390",
692a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
693a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
694a9e62fadSHerbert Xu 	.cra_blocksize		=	DES3_192_BLOCK_SIZE,
695a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
696a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
697a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
698a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
699a9e62fadSHerbert Xu 						ecb_des3_192_alg.cra_list),
700a9e62fadSHerbert Xu 	.cra_u			=	{
701a9e62fadSHerbert Xu 		.blkcipher = {
702a9e62fadSHerbert Xu 			.min_keysize		=	DES3_192_KEY_SIZE,
703a9e62fadSHerbert Xu 			.max_keysize		=	DES3_192_KEY_SIZE,
704a9e62fadSHerbert Xu 			.setkey			=	des3_192_setkey,
705a9e62fadSHerbert Xu 			.encrypt		=	ecb_des3_192_encrypt,
706a9e62fadSHerbert Xu 			.decrypt		=	ecb_des3_192_decrypt,
707a9e62fadSHerbert Xu 		}
708a9e62fadSHerbert Xu 	}
709a9e62fadSHerbert Xu };
710a9e62fadSHerbert Xu 
711a9e62fadSHerbert Xu static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
712a9e62fadSHerbert Xu 				struct scatterlist *dst,
713a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
714a9e62fadSHerbert Xu {
715a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
716a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
717a9e62fadSHerbert Xu 
718a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
719a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
720a9e62fadSHerbert Xu }
721a9e62fadSHerbert Xu 
722a9e62fadSHerbert Xu static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
723a9e62fadSHerbert Xu 				struct scatterlist *dst,
724a9e62fadSHerbert Xu 				struct scatterlist *src, unsigned int nbytes)
725a9e62fadSHerbert Xu {
726a9e62fadSHerbert Xu 	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
727a9e62fadSHerbert Xu 	struct blkcipher_walk walk;
728a9e62fadSHerbert Xu 
729a9e62fadSHerbert Xu 	blkcipher_walk_init(&walk, dst, src, nbytes);
730a9e62fadSHerbert Xu 	return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
731a9e62fadSHerbert Xu }
732a9e62fadSHerbert Xu 
733a9e62fadSHerbert Xu static struct crypto_alg cbc_des3_192_alg = {
734a9e62fadSHerbert Xu 	.cra_name		=	"cbc(des3_ede)",
735a9e62fadSHerbert Xu 	.cra_driver_name	=	"cbc-des3_ede-s390",
736a9e62fadSHerbert Xu 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
737a9e62fadSHerbert Xu 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
738a9e62fadSHerbert Xu 	.cra_blocksize		=	DES3_192_BLOCK_SIZE,
739a9e62fadSHerbert Xu 	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
740a9e62fadSHerbert Xu 	.cra_type		=	&crypto_blkcipher_type,
741a9e62fadSHerbert Xu 	.cra_module		=	THIS_MODULE,
742a9e62fadSHerbert Xu 	.cra_list		=	LIST_HEAD_INIT(
743a9e62fadSHerbert Xu 						cbc_des3_192_alg.cra_list),
744a9e62fadSHerbert Xu 	.cra_u			=	{
745a9e62fadSHerbert Xu 		.blkcipher = {
746a9e62fadSHerbert Xu 			.min_keysize		=	DES3_192_KEY_SIZE,
747a9e62fadSHerbert Xu 			.max_keysize		=	DES3_192_KEY_SIZE,
748a9e62fadSHerbert Xu 			.ivsize			=	DES3_192_BLOCK_SIZE,
749a9e62fadSHerbert Xu 			.setkey			=	des3_192_setkey,
750a9e62fadSHerbert Xu 			.encrypt		=	cbc_des3_192_encrypt,
751a9e62fadSHerbert Xu 			.decrypt		=	cbc_des3_192_decrypt,
752a9e62fadSHerbert Xu 		}
753a9e62fadSHerbert Xu 	}
754a9e62fadSHerbert Xu };
755a9e62fadSHerbert Xu 
756c1357833SJan Glauber static int init(void)
757c1e26e1eSJan Glauber {
758c1357833SJan Glauber 	int ret = 0;
759c1e26e1eSJan Glauber 
760c1e26e1eSJan Glauber 	if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
761c1e26e1eSJan Glauber 	    !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
762c1357833SJan Glauber 	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
763c1e26e1eSJan Glauber 		return -ENOSYS;
764c1e26e1eSJan Glauber 
765a9e62fadSHerbert Xu 	ret = crypto_register_alg(&des_alg);
766a9e62fadSHerbert Xu 	if (ret)
767a9e62fadSHerbert Xu 		goto des_err;
768a9e62fadSHerbert Xu 	ret = crypto_register_alg(&ecb_des_alg);
769a9e62fadSHerbert Xu 	if (ret)
770a9e62fadSHerbert Xu 		goto ecb_des_err;
771a9e62fadSHerbert Xu 	ret = crypto_register_alg(&cbc_des_alg);
772a9e62fadSHerbert Xu 	if (ret)
773a9e62fadSHerbert Xu 		goto cbc_des_err;
774a9e62fadSHerbert Xu 
775a9e62fadSHerbert Xu 	ret = crypto_register_alg(&des3_128_alg);
776a9e62fadSHerbert Xu 	if (ret)
777a9e62fadSHerbert Xu 		goto des3_128_err;
778a9e62fadSHerbert Xu 	ret = crypto_register_alg(&ecb_des3_128_alg);
779a9e62fadSHerbert Xu 	if (ret)
780a9e62fadSHerbert Xu 		goto ecb_des3_128_err;
781a9e62fadSHerbert Xu 	ret = crypto_register_alg(&cbc_des3_128_alg);
782a9e62fadSHerbert Xu 	if (ret)
783a9e62fadSHerbert Xu 		goto cbc_des3_128_err;
784a9e62fadSHerbert Xu 
785a9e62fadSHerbert Xu 	ret = crypto_register_alg(&des3_192_alg);
786a9e62fadSHerbert Xu 	if (ret)
787a9e62fadSHerbert Xu 		goto des3_192_err;
788a9e62fadSHerbert Xu 	ret = crypto_register_alg(&ecb_des3_192_alg);
789a9e62fadSHerbert Xu 	if (ret)
790a9e62fadSHerbert Xu 		goto ecb_des3_192_err;
791a9e62fadSHerbert Xu 	ret = crypto_register_alg(&cbc_des3_192_alg);
792a9e62fadSHerbert Xu 	if (ret)
793a9e62fadSHerbert Xu 		goto cbc_des3_192_err;
794a9e62fadSHerbert Xu 
795a9e62fadSHerbert Xu out:
796a9e62fadSHerbert Xu 	return ret;
797a9e62fadSHerbert Xu 
798a9e62fadSHerbert Xu cbc_des3_192_err:
799a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_192_alg);
800a9e62fadSHerbert Xu ecb_des3_192_err:
801c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_192_alg);
802a9e62fadSHerbert Xu des3_192_err:
803a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des3_128_alg);
804a9e62fadSHerbert Xu cbc_des3_128_err:
805a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_128_alg);
806a9e62fadSHerbert Xu ecb_des3_128_err:
807c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_128_alg);
808a9e62fadSHerbert Xu des3_128_err:
809a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des_alg);
810a9e62fadSHerbert Xu cbc_des_err:
811a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des_alg);
812a9e62fadSHerbert Xu ecb_des_err:
813c1e26e1eSJan Glauber 	crypto_unregister_alg(&des_alg);
814a9e62fadSHerbert Xu des_err:
815a9e62fadSHerbert Xu 	goto out;
816c1e26e1eSJan Glauber }
817c1e26e1eSJan Glauber 
818c1357833SJan Glauber static void __exit fini(void)
819c1e26e1eSJan Glauber {
820a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des3_192_alg);
821a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_192_alg);
822c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_192_alg);
823a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des3_128_alg);
824a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des3_128_alg);
825c1e26e1eSJan Glauber 	crypto_unregister_alg(&des3_128_alg);
826a9e62fadSHerbert Xu 	crypto_unregister_alg(&cbc_des_alg);
827a9e62fadSHerbert Xu 	crypto_unregister_alg(&ecb_des_alg);
828c1e26e1eSJan Glauber 	crypto_unregister_alg(&des_alg);
829c1e26e1eSJan Glauber }
830c1e26e1eSJan Glauber 
831c1e26e1eSJan Glauber module_init(init);
832c1e26e1eSJan Glauber module_exit(fini);
833c1e26e1eSJan Glauber 
834c1e26e1eSJan Glauber MODULE_ALIAS("des");
835c1e26e1eSJan Glauber MODULE_ALIAS("des3_ede");
836c1e26e1eSJan Glauber 
837c1e26e1eSJan Glauber MODULE_LICENSE("GPL");
838c1e26e1eSJan Glauber MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
839