Blame view

crypto/xcbc.c 6.66 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>
   */
3106caab6   Herbert Xu   crypto: xcbc - Sw...
8
  #include <crypto/internal/hash.h>
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
9
10
  #include <linux/err.h>
  #include <linux/kernel.h>
4bb33cc89   Paul Gortmaker   crypto: add modul...
11
  #include <linux/module.h>
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
12

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

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

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

ac95301f2   Herbert Xu   crypto: xcbc - Fi...
60
61
62
  	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...
63
64
  
  	return crypto_cipher_setkey(ctx->child, key1, bs);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
65

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

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

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

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

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

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

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

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

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

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

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

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

36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
209
210
  	alignmask = alg->cra_alignmask | 3;
  	inst->alg.base.cra_alignmask = alignmask;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
211
212
  	inst->alg.base.cra_priority = alg->cra_priority;
  	inst->alg.base.cra_blocksize = alg->cra_blocksize;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
213
214
  
  	inst->alg.digestsize = alg->cra_blocksize;
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
215
216
  	inst->alg.descsize = ALIGN(sizeof(struct xcbc_desc_ctx),
  				   crypto_tfm_ctx_alignment()) +
36f87a4a2   Steffen Klassert   crypto: xcbc - Fi...
217
  			     (alignmask &
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
218
219
220
221
  			      ~(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...
222
  					   alignmask + 1) +
ac95301f2   Herbert Xu   crypto: xcbc - Fi...
223
  				     alg->cra_blocksize * 2;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
224
225
226
227
228
229
230
  	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...
231
  	inst->free = shash_free_singlespawn_instance;
3106caab6   Herbert Xu   crypto: xcbc - Sw...
232
233
  	err = shash_register_instance(tmpl, inst);
  	if (err) {
1e212a6a5   Eric Biggers   crypto: xcbc - us...
234
  err_free_inst:
a39c66cc2   Eric Biggers   crypto: shash - c...
235
  		shash_free_singlespawn_instance(inst);
3106caab6   Herbert Xu   crypto: xcbc - Sw...
236
  	}
3106caab6   Herbert Xu   crypto: xcbc - Sw...
237
  	return err;
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
238
239
240
241
  }
  
  static struct crypto_template crypto_xcbc_tmpl = {
  	.name = "xcbc",
3106caab6   Herbert Xu   crypto: xcbc - Sw...
242
  	.create = xcbc_create,
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
243
244
245
246
247
248
249
250
251
252
253
254
  	.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...
255
  subsys_initcall(crypto_xcbc_module_init);
333b0d7ee   Kazunori MIYAZAWA   [CRYPTO] xcbc: Ne...
256
257
258
259
  module_exit(crypto_xcbc_module_exit);
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("XCBC keyed hash algorithm");
4943ba16b   Kees Cook   crypto: include c...
260
  MODULE_ALIAS_CRYPTO("xcbc");