Blame view

crypto/xcbc.c 6.73 KB
1ccea77e2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
2
3
4
  /*
   * Copyright (C)2006 USAGI/WIDE Project
   *
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
5
6
7
   * Author:
   * 	Kazunori Miyazawa <miyazawa@linux-ipv6.org>
   */
0eb76ba29   Ard Biesheuvel   crypto: remove ci...
8
  #include <crypto/internal/cipher.h>
3106caab6   Herbert Xu   crypto: xcbc - Sw...
9
  #include <crypto/internal/hash.h>
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
10
11
  #include <linux/err.h>
  #include <linux/kernel.h>
4bb33cc89   Paul Gortmaker   crypto: add modul...
12
  #include <linux/module.h>
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
13

5b37538a5   Adrian Bunk   [CRYPTO] xcbc: Ma...
14
15
16
  static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
  			   0x02020202, 0x02020202, 0x02020202, 0x02020202,
  			   0x03030303, 0x03030303, 0x03030303, 0x03030303};
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
17

333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
18
19
20
21
  /*
   * +------------------------
   * | <parent tfm>
   * +------------------------
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
22
   * | xcbc_tfm_ctx
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
23
   * +------------------------
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
24
   * | consts (block size * 2)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
25
   * +------------------------
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
26
27
28
29
30
31
32
   */
  struct xcbc_tfm_ctx {
  	struct crypto_cipher *child;
  	u8 ctx[];
  };
  
  /*
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
33
   * +------------------------
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
34
   * | <shash desc>
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
35
   * +------------------------
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
36
37
38
39
40
   * | xcbc_desc_ctx
   * +------------------------
   * | odds (block size)
   * +------------------------
   * | prev (block size)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
41
42
   * +------------------------
   */
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
43
  struct xcbc_desc_ctx {
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
44
  	unsigned int len;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
45
  	u8 ctx[];
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
46
  };
3bdd23f88   Kees Cook   crypto: xcbc - Re...
47
  #define XCBC_BLOCKSIZE	16
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
48
49
  static int crypto_xcbc_digest_setkey(struct crypto_shash *parent,
  				     const u8 *inkey, unsigned int keylen)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
50
  {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
51
52
  	unsigned long alignmask = crypto_shash_alignmask(parent);
  	struct xcbc_tfm_ctx *ctx = crypto_shash_ctx(parent);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
53
  	u8 *consts = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
54
  	int err = 0;
3bdd23f88   Kees Cook   crypto: xcbc - Re...
55
56
  	u8 key1[XCBC_BLOCKSIZE];
  	int bs = sizeof(key1);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
57

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
58
59
  	if ((err = crypto_cipher_setkey(ctx->child, inkey, keylen)))
  		return err;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
60

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
61
62
63
  	crypto_cipher_encrypt_one(ctx->child, consts, (u8 *)ks + bs);
  	crypto_cipher_encrypt_one(ctx->child, consts + bs, (u8 *)ks + bs * 2);
  	crypto_cipher_encrypt_one(ctx->child, key1, (u8 *)ks);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
64
65
  
  	return crypto_cipher_setkey(ctx->child, key1, bs);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
66

333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
67
  }
3106caab6   Herbert Xu   crypto: xcbc - Sw...
68
  static int crypto_xcbc_digest_init(struct shash_desc *pdesc)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
69
  {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
70
71
  	unsigned long alignmask = crypto_shash_alignmask(pdesc->tfm);
  	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
72
  	int bs = crypto_shash_blocksize(pdesc->tfm);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
73
  	u8 *prev = PTR_ALIGN(&ctx->ctx[0], alignmask + 1) + bs;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
74
75
  
  	ctx->len = 0;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
76
  	memset(prev, 0, bs);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
77
78
79
  
  	return 0;
  }
3106caab6   Herbert Xu   crypto: xcbc - Sw...
80
81
  static int crypto_xcbc_digest_update(struct shash_desc *pdesc, const u8 *p,
  				     unsigned int len)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
82
  {
3106caab6   Herbert Xu   crypto: xcbc - Sw...
83
  	struct crypto_shash *parent = pdesc->tfm;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
84
85
86
87
  	unsigned long alignmask = crypto_shash_alignmask(parent);
  	struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
  	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
  	struct crypto_cipher *tfm = tctx->child;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
88
  	int bs = crypto_shash_blocksize(parent);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
89
90
  	u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
  	u8 *prev = odds + bs;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
91
92
93
  
  	/* checking the data can fill the block */
  	if ((ctx->len + len) <= bs) {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
94
  		memcpy(odds + ctx->len, p, len);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
95
96
  		ctx->len += len;
  		return 0;
1edcf2e1e   Joy Latten   [CRYPTO] xcbc: Fi...
97
  	}
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
98

3106caab6   Herbert Xu   crypto: xcbc - Sw...
99
  	/* filling odds with new data and encrypting it */
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
100
  	memcpy(odds + ctx->len, p, bs - ctx->len);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
101
102
  	len -= bs - ctx->len;
  	p += bs - ctx->len;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
103

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
104
105
  	crypto_xor(prev, odds, bs);
  	crypto_cipher_encrypt_one(tfm, prev, prev);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
106
107
108
109
110
111
  
  	/* clearing the length */
  	ctx->len = 0;
  
  	/* encrypting the rest of data */
  	while (len > bs) {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
112
113
  		crypto_xor(prev, p, bs);
  		crypto_cipher_encrypt_one(tfm, prev, prev);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
114
115
116
117
118
119
  		p += bs;
  		len -= bs;
  	}
  
  	/* keeping the surplus of blocksize */
  	if (len) {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
120
  		memcpy(odds, p, len);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
121
122
123
124
  		ctx->len = len;
  	}
  
  	return 0;
fb469840b   Herbert Xu   [CRYPTO] all: Che...
125
  }
3106caab6   Herbert Xu   crypto: xcbc - Sw...
126
  static int crypto_xcbc_digest_final(struct shash_desc *pdesc, u8 *out)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
127
  {
3106caab6   Herbert Xu   crypto: xcbc - Sw...
128
  	struct crypto_shash *parent = pdesc->tfm;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
129
130
131
132
  	unsigned long alignmask = crypto_shash_alignmask(parent);
  	struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
  	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
  	struct crypto_cipher *tfm = tctx->child;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
133
  	int bs = crypto_shash_blocksize(parent);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
134
135
136
137
  	u8 *consts = PTR_ALIGN(&tctx->ctx[0], alignmask + 1);
  	u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
  	u8 *prev = odds + bs;
  	unsigned int offset = 0;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
138

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
139
  	if (ctx->len != bs) {
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
140
  		unsigned int rlen;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
141
  		u8 *p = odds + ctx->len;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
142
143
144
145
146
147
  		*p = 0x80;
  		p++;
  
  		rlen = bs - ctx->len -1;
  		if (rlen)
  			memset(p, 0, rlen);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
148
149
  		offset += bs;
  	}
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
150

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
151
152
  	crypto_xor(prev, odds, bs);
  	crypto_xor(prev, consts + offset, bs);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
153

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
154
  	crypto_cipher_encrypt_one(tfm, out, prev);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
155
156
157
  
  	return 0;
  }
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
158
159
  static int xcbc_init_tfm(struct crypto_tfm *tfm)
  {
2e306ee01   Herbert Xu   [CRYPTO] api: Add...
160
  	struct crypto_cipher *cipher;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
161
  	struct crypto_instance *inst = (void *)tfm->__crt_alg;
d5ed3b65f   Eric Biggers   crypto: cipher - ...
162
  	struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst);
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
163
  	struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
164

2e306ee01   Herbert Xu   [CRYPTO] api: Add...
165
166
167
  	cipher = crypto_spawn_cipher(spawn);
  	if (IS_ERR(cipher))
  		return PTR_ERR(cipher);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
168

2e306ee01   Herbert Xu   [CRYPTO] api: Add...
169
  	ctx->child = cipher;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
170
171
172
173
174
175
  
  	return 0;
  };
  
  static void xcbc_exit_tfm(struct crypto_tfm *tfm)
  {
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
176
  	struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
177
178
  	crypto_free_cipher(ctx->child);
  }
3106caab6   Herbert Xu   crypto: xcbc - Sw...
179
  static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
180
  {
3106caab6   Herbert Xu   crypto: xcbc - Sw...
181
  	struct shash_instance *inst;
1e212a6a5   Eric Biggers   crypto: xcbc - us...
182
  	struct crypto_cipher_spawn *spawn;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
183
  	struct crypto_alg *alg;
36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
184
  	unsigned long alignmask;
7bcb2c99f   Eric Biggers   crypto: algapi - ...
185
  	u32 mask;
ebc610e5b   Herbert Xu   [CRYPTO] template...
186
  	int err;
7bcb2c99f   Eric Biggers   crypto: algapi - ...
187
  	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
ebc610e5b   Herbert Xu   [CRYPTO] template...
188
  	if (err)
3106caab6   Herbert Xu   crypto: xcbc - Sw...
189
  		return err;
ebc610e5b   Herbert Xu   [CRYPTO] template...
190

1e212a6a5   Eric Biggers   crypto: xcbc - us...
191
192
193
194
  	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
  	if (!inst)
  		return -ENOMEM;
  	spawn = shash_instance_ctx(inst);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
195

1e212a6a5   Eric Biggers   crypto: xcbc - us...
196
  	err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
7bcb2c99f   Eric Biggers   crypto: algapi - ...
197
  				 crypto_attr_alg_name(tb[1]), 0, mask);
1e212a6a5   Eric Biggers   crypto: xcbc - us...
198
199
200
  	if (err)
  		goto err_free_inst;
  	alg = crypto_spawn_cipher_alg(spawn);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
201

1e212a6a5   Eric Biggers   crypto: xcbc - us...
202
203
204
  	err = -EINVAL;
  	if (alg->cra_blocksize != XCBC_BLOCKSIZE)
  		goto err_free_inst;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
205

1e212a6a5   Eric Biggers   crypto: xcbc - us...
206
  	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
207
  	if (err)
1e212a6a5   Eric Biggers   crypto: xcbc - us...
208
  		goto err_free_inst;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
209

36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
210
211
  	alignmask = alg->cra_alignmask | 3;
  	inst->alg.base.cra_alignmask = alignmask;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
212
213
  	inst->alg.base.cra_priority = alg->cra_priority;
  	inst->alg.base.cra_blocksize = alg->cra_blocksize;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
214
215
  
  	inst->alg.digestsize = alg->cra_blocksize;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
216
217
  	inst->alg.descsize = ALIGN(sizeof(struct xcbc_desc_ctx),
  				   crypto_tfm_ctx_alignment()) +
36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
218
  			     (alignmask &
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
219
220
221
222
  			      ~(crypto_tfm_ctx_alignment() - 1)) +
  			     alg->cra_blocksize * 2;
  
  	inst->alg.base.cra_ctxsize = ALIGN(sizeof(struct xcbc_tfm_ctx),
36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
223
  					   alignmask + 1) +
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
224
  				     alg->cra_blocksize * 2;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
225
226
227
228
229
230
231
  	inst->alg.base.cra_init = xcbc_init_tfm;
  	inst->alg.base.cra_exit = xcbc_exit_tfm;
  
  	inst->alg.init = crypto_xcbc_digest_init;
  	inst->alg.update = crypto_xcbc_digest_update;
  	inst->alg.final = crypto_xcbc_digest_final;
  	inst->alg.setkey = crypto_xcbc_digest_setkey;
a39c66cc2   Eric Biggers   crypto: shash - c...
232
  	inst->free = shash_free_singlespawn_instance;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
233
234
  	err = shash_register_instance(tmpl, inst);
  	if (err) {
1e212a6a5   Eric Biggers   crypto: xcbc - us...
235
  err_free_inst:
a39c66cc2   Eric Biggers   crypto: shash - c...
236
  		shash_free_singlespawn_instance(inst);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
237
  	}
3106caab6   Herbert Xu   crypto: xcbc - Sw...
238
  	return err;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
239
240
241
242
  }
  
  static struct crypto_template crypto_xcbc_tmpl = {
  	.name = "xcbc",
3106caab6   Herbert Xu   crypto: xcbc - Sw...
243
  	.create = xcbc_create,
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
244
245
246
247
248
249
250
251
252
253
254
255
  	.module = THIS_MODULE,
  };
  
  static int __init crypto_xcbc_module_init(void)
  {
  	return crypto_register_template(&crypto_xcbc_tmpl);
  }
  
  static void __exit crypto_xcbc_module_exit(void)
  {
  	crypto_unregister_template(&crypto_xcbc_tmpl);
  }
c4741b230   Eric Biggers   crypto: run initc...
256
  subsys_initcall(crypto_xcbc_module_init);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
257
258
259
260
  module_exit(crypto_xcbc_module_exit);
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("XCBC keyed hash algorithm");
4943ba16b   Kees Cook   crypto: include c...
261
  MODULE_ALIAS_CRYPTO("xcbc");
0eb76ba29   Ard Biesheuvel   crypto: remove ci...
262
  MODULE_IMPORT_NS(CRYPTO_INTERNAL);