xref: /linux/drivers/crypto/atmel-ecc.c (revision 5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Microchip / Atmel ECC (I2C) driver.
4  *
5  * Copyright (c) 2017, Microchip Technology Inc.
6  * Author: Tudor Ambarus
7  */
8 
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/errno.h>
13 #include <linux/i2c.h>
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/scatterlist.h>
19 #include <linux/slab.h>
20 #include <linux/workqueue.h>
21 #include <crypto/internal/kpp.h>
22 #include <crypto/ecdh.h>
23 #include <crypto/kpp.h>
24 #include "atmel-i2c.h"
25 
26 static struct atmel_ecc_driver_data driver_data;
27 
28 /**
29  * struct atmel_ecdh_ctx - transformation context
30  * @client: I2C client device
31  * @fallback: ECDH fallback used for caller-provided private keys
32  * @public_key: cached public key for the device-generated private key
33  * @do_fallback: true when ECDH operations should use @fallback
34  *
35  * The caller must not invoke set_secret() while generate_public_key()
36  * or compute_shared_secret() are in flight.
37  */
38 struct atmel_ecdh_ctx {
39 	struct i2c_client *client;
40 	struct crypto_kpp *fallback;
41 	const u8 *public_key;
42 	bool do_fallback;
43 };
44 
45 static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
46 			    int status)
47 {
48 	struct kpp_request *req = areq;
49 	struct atmel_i2c_cmd *cmd = &work_data->cmd;
50 	size_t copied, n_sz;
51 
52 	if (status)
53 		goto free_work_data;
54 
55 	/* copy only as much as requested, capped at 32 bytes */
56 	n_sz = min(ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
57 
58 	/* copy the shared secret */
59 	copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, n_sz),
60 				     &cmd->data[RSP_DATA_IDX], n_sz);
61 	if (copied != n_sz)
62 		status = -EINVAL;
63 
64 free_work_data:
65 	kfree_sensitive(work_data);
66 	kpp_request_complete(req, status);
67 }
68 
69 /*
70  * If no private key is provided, generate one in the device and cache
71  * the corresponding public key. The generated private key never leaves
72  * the device.
73  */
74 static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
75 				 unsigned int len)
76 {
77 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
78 	struct atmel_i2c_cmd *cmd;
79 	void *public_key;
80 	struct ecdh params;
81 	int ret = -ENOMEM;
82 
83 	kfree(ctx->public_key);
84 	ctx->public_key = NULL;
85 	ctx->do_fallback = false;
86 
87 	if (crypto_ecdh_decode_key(buf, len, &params) < 0) {
88 		dev_err(&ctx->client->dev, "crypto_ecdh_decode_key failed\n");
89 		return -EINVAL;
90 	}
91 
92 	if (params.key_size) {
93 		ret = crypto_kpp_set_secret(ctx->fallback, buf, len);
94 		ctx->do_fallback = !ret;
95 		return ret;
96 	}
97 
98 	cmd = kmalloc_obj(*cmd);
99 	if (!cmd)
100 		return -ENOMEM;
101 
102 	public_key = kmalloc(ATMEL_ECC_PUBKEY_SIZE, GFP_KERNEL);
103 	if (!public_key)
104 		goto free_cmd;
105 
106 	atmel_i2c_init_genkey_cmd(cmd, DATA_SLOT_2);
107 
108 	ret = atmel_i2c_send_receive(ctx->client, cmd);
109 	if (ret) {
110 		kfree(public_key);
111 		goto free_cmd;
112 	}
113 
114 	memcpy(public_key, &cmd->data[RSP_DATA_IDX], ATMEL_ECC_PUBKEY_SIZE);
115 	ctx->public_key = public_key;
116 
117 free_cmd:
118 	kfree(cmd);
119 	return ret;
120 }
121 
122 static int atmel_ecdh_generate_public_key(struct kpp_request *req)
123 {
124 	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
125 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
126 	size_t copied, nbytes;
127 
128 	if (ctx->do_fallback) {
129 		kpp_request_set_tfm(req, ctx->fallback);
130 		return crypto_kpp_generate_public_key(req);
131 	}
132 
133 	if (!ctx->public_key)
134 		return -EINVAL;
135 
136 	/* copy only as much as requested, capped at 64 bytes */
137 	nbytes = min(ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
138 
139 	/* public key was saved at private key generation */
140 	copied = sg_copy_from_buffer(req->dst,
141 				     sg_nents_for_len(req->dst, nbytes),
142 				     ctx->public_key, nbytes);
143 	if (copied != nbytes)
144 		return -EINVAL;
145 
146 	return 0;
147 }
148 
149 static int atmel_ecdh_compute_shared_secret(struct kpp_request *req)
150 {
151 	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
152 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
153 	struct atmel_i2c_work_data *work_data;
154 	gfp_t gfp;
155 	int ret;
156 
157 	if (ctx->do_fallback) {
158 		kpp_request_set_tfm(req, ctx->fallback);
159 		return crypto_kpp_compute_shared_secret(req);
160 	}
161 
162 	if (!ctx->public_key)
163 		return -EINVAL;
164 
165 	/* A P-256 public key must contain two 32-byte coordinates */
166 	if (req->src_len != ATMEL_ECC_PUBKEY_SIZE)
167 		return -EINVAL;
168 
169 	gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL :
170 							     GFP_ATOMIC;
171 
172 	work_data = kmalloc_obj(*work_data, gfp);
173 	if (!work_data)
174 		return -ENOMEM;
175 
176 	work_data->ctx = ctx;
177 	work_data->client = ctx->client;
178 
179 	ret = atmel_i2c_init_ecdh_cmd(&work_data->cmd, req->src);
180 	if (ret) {
181 		kfree(work_data);
182 		return ret;
183 	}
184 
185 	atmel_i2c_enqueue(work_data, atmel_ecdh_done, req);
186 
187 	return -EINPROGRESS;
188 }
189 
190 static struct i2c_client *atmel_ecc_i2c_client_alloc(void)
191 {
192 	struct atmel_i2c_client_priv *i2c_priv, *min_i2c_priv = NULL;
193 	struct i2c_client *client = ERR_PTR(-ENODEV);
194 	int min_tfm_cnt = INT_MAX;
195 	int tfm_cnt;
196 
197 	spin_lock(&driver_data.i2c_list_lock);
198 
199 	if (list_empty(&driver_data.i2c_client_list)) {
200 		spin_unlock(&driver_data.i2c_list_lock);
201 		return ERR_PTR(-ENODEV);
202 	}
203 
204 	list_for_each_entry(i2c_priv, &driver_data.i2c_client_list,
205 			    i2c_client_list_node) {
206 		tfm_cnt = atomic_read(&i2c_priv->tfm_count);
207 		if (tfm_cnt < min_tfm_cnt) {
208 			min_tfm_cnt = tfm_cnt;
209 			min_i2c_priv = i2c_priv;
210 		}
211 		if (!min_tfm_cnt)
212 			break;
213 	}
214 
215 	if (min_i2c_priv) {
216 		atomic_inc(&min_i2c_priv->tfm_count);
217 		client = min_i2c_priv->client;
218 	}
219 
220 	spin_unlock(&driver_data.i2c_list_lock);
221 
222 	return client;
223 }
224 
225 static void atmel_ecc_i2c_client_free(struct i2c_client *client)
226 {
227 	struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
228 
229 	atomic_dec(&i2c_priv->tfm_count);
230 }
231 
232 static int atmel_ecdh_init_tfm(struct crypto_kpp *tfm)
233 {
234 	const char *alg = kpp_alg_name(tfm);
235 	struct crypto_kpp *fallback;
236 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
237 
238 	ctx->client = atmel_ecc_i2c_client_alloc();
239 	if (IS_ERR(ctx->client)) {
240 		pr_err("tfm - i2c_client binding failed\n");
241 		return PTR_ERR(ctx->client);
242 	}
243 
244 	fallback = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
245 	if (IS_ERR(fallback)) {
246 		dev_err(&ctx->client->dev, "Failed to allocate transformation for '%s': %ld\n",
247 			alg, PTR_ERR(fallback));
248 		atmel_ecc_i2c_client_free(ctx->client);
249 		return PTR_ERR(fallback);
250 	}
251 
252 	crypto_kpp_set_flags(fallback, crypto_kpp_get_flags(tfm));
253 	ctx->fallback = fallback;
254 
255 	return 0;
256 }
257 
258 static void atmel_ecdh_exit_tfm(struct crypto_kpp *tfm)
259 {
260 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
261 
262 	kfree(ctx->public_key);
263 	crypto_free_kpp(ctx->fallback);
264 	atmel_ecc_i2c_client_free(ctx->client);
265 }
266 
267 static unsigned int atmel_ecdh_max_size(struct crypto_kpp *tfm)
268 {
269 	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
270 
271 	return crypto_kpp_maxsize(ctx->fallback);
272 }
273 
274 static struct kpp_alg atmel_ecdh_nist_p256 = {
275 	.set_secret = atmel_ecdh_set_secret,
276 	.generate_public_key = atmel_ecdh_generate_public_key,
277 	.compute_shared_secret = atmel_ecdh_compute_shared_secret,
278 	.init = atmel_ecdh_init_tfm,
279 	.exit = atmel_ecdh_exit_tfm,
280 	.max_size = atmel_ecdh_max_size,
281 	.base = {
282 		.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
283 		.cra_name = "ecdh-nist-p256",
284 		.cra_driver_name = "atmel-ecdh",
285 		.cra_priority = ATMEL_ECC_PRIORITY,
286 		.cra_module = THIS_MODULE,
287 		.cra_ctxsize = sizeof(struct atmel_ecdh_ctx),
288 	},
289 };
290 
291 static int atmel_ecc_probe(struct i2c_client *client)
292 {
293 	struct atmel_i2c_client_priv *i2c_priv;
294 	int ret;
295 
296 	ret = atmel_i2c_probe(client);
297 	if (ret)
298 		return ret;
299 
300 	i2c_priv = i2c_get_clientdata(client);
301 
302 	spin_lock(&driver_data.i2c_list_lock);
303 	list_add_tail(&i2c_priv->i2c_client_list_node,
304 		      &driver_data.i2c_client_list);
305 	spin_unlock(&driver_data.i2c_list_lock);
306 
307 	ret = crypto_register_kpp(&atmel_ecdh_nist_p256);
308 	if (ret) {
309 		spin_lock(&driver_data.i2c_list_lock);
310 		list_del(&i2c_priv->i2c_client_list_node);
311 		spin_unlock(&driver_data.i2c_list_lock);
312 
313 		dev_err(&client->dev, "%s alg registration failed\n",
314 			atmel_ecdh_nist_p256.base.cra_driver_name);
315 	} else {
316 		dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n");
317 	}
318 
319 	return ret;
320 }
321 
322 static void atmel_ecc_remove(struct i2c_client *client)
323 {
324 	struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
325 
326 	/* Return EBUSY if i2c client already allocated. */
327 	if (atomic_read(&i2c_priv->tfm_count)) {
328 		/*
329 		 * After we return here, the memory backing the device is freed.
330 		 * That happens no matter what the return value of this function
331 		 * is because in the Linux device model there is no error
332 		 * handling for unbinding a driver.
333 		 * If there is still some action pending, it probably involves
334 		 * accessing the freed memory.
335 		 */
336 		dev_emerg(&client->dev, "Device is busy, expect memory corruption.\n");
337 		return;
338 	}
339 
340 	crypto_unregister_kpp(&atmel_ecdh_nist_p256);
341 
342 	spin_lock(&driver_data.i2c_list_lock);
343 	list_del(&i2c_priv->i2c_client_list_node);
344 	spin_unlock(&driver_data.i2c_list_lock);
345 }
346 
347 static const struct of_device_id atmel_ecc_dt_ids[] = {
348 	{ .compatible = "atmel,atecc508a", },
349 	{ .compatible = "atmel,atecc608a", },
350 	{ .compatible = "atmel,atecc608b", },
351 	{ }
352 };
353 MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids);
354 
355 static const struct i2c_device_id atmel_ecc_id[] = {
356 	{ .name = "atecc508a" },
357 	{ .name = "atecc608a" },
358 	{ .name = "atecc608b" },
359 	{ }
360 };
361 MODULE_DEVICE_TABLE(i2c, atmel_ecc_id);
362 
363 static struct i2c_driver atmel_ecc_driver = {
364 	.driver = {
365 		.name	= "atmel-ecc",
366 		.of_match_table = atmel_ecc_dt_ids,
367 	},
368 	.probe		= atmel_ecc_probe,
369 	.remove		= atmel_ecc_remove,
370 	.id_table	= atmel_ecc_id,
371 };
372 
373 static int __init atmel_ecc_init(void)
374 {
375 	spin_lock_init(&driver_data.i2c_list_lock);
376 	INIT_LIST_HEAD(&driver_data.i2c_client_list);
377 	return i2c_add_driver(&atmel_ecc_driver);
378 }
379 
380 static void __exit atmel_ecc_exit(void)
381 {
382 	atmel_i2c_flush_queue();
383 	i2c_del_driver(&atmel_ecc_driver);
384 }
385 
386 module_init(atmel_ecc_init);
387 module_exit(atmel_ecc_exit);
388 
389 MODULE_AUTHOR("Tudor Ambarus");
390 MODULE_DESCRIPTION("Microchip / Atmel ECC (I2C) driver");
391 MODULE_LICENSE("GPL v2");
392