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
26static struct atmel_ecc_driver_data driver_data;
27
28/**
29 * struct atmel_ecdh_ctx - transformation context
30 * @client     : pointer to i2c client device
31 * @fallback   : used for unsupported curves or when user wants to use its own
32 *               private key.
33 * @public_key : generated when calling set_secret(). It's the responsibility
34 *               of the user to not call set_secret() while
35 *               generate_public_key() or compute_shared_secret() are in flight.
36 * @curve_id   : elliptic curve id
37 * @do_fallback: true when the device doesn't support the curve or when the user
38 *               wants to use its own private key.
39 */
40struct atmel_ecdh_ctx {
41	struct i2c_client *client;
42	struct crypto_kpp *fallback;
43	const u8 *public_key;
44	unsigned int curve_id;
45	bool do_fallback;
46};
47
48static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
49			    int status)
50{
51	struct kpp_request *req = areq;
52	struct atmel_i2c_cmd *cmd = &work_data->cmd;
53	size_t copied, n_sz;
54
55	if (status)
56		goto free_work_data;
57
58	/* might want less than we've got */
59	n_sz = min_t(size_t, ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
60
61	/* copy the shared secret */
62	copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, n_sz),
63				     &cmd->data[RSP_DATA_IDX], n_sz);
64	if (copied != n_sz)
65		status = -EINVAL;
66
67	/* fall through */
68free_work_data:
69	kfree_sensitive(work_data);
70	kpp_request_complete(req, status);
71}
72
73/*
74 * A random private key is generated and stored in the device. The device
75 * returns the pair public key.
76 */
77static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
78				 unsigned int len)
79{
80	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
81	struct atmel_i2c_cmd *cmd;
82	void *public_key;
83	struct ecdh params;
84	int ret = -ENOMEM;
85
86	/* free the old public key, if any */
87	kfree(ctx->public_key);
88	/* make sure you don't free the old public key twice */
89	ctx->public_key = NULL;
90
91	if (crypto_ecdh_decode_key(buf, len, &params) < 0) {
92		dev_err(&ctx->client->dev, "crypto_ecdh_decode_key failed\n");
93		return -EINVAL;
94	}
95
96	if (params.key_size) {
97		/* fallback to ecdh software implementation */
98		ctx->do_fallback = true;
99		return crypto_kpp_set_secret(ctx->fallback, buf, len);
100	}
101
102	cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
103	if (!cmd)
104		return -ENOMEM;
105
106	/*
107	 * The device only supports NIST P256 ECC keys. The public key size will
108	 * always be the same. Use a macro for the key size to avoid unnecessary
109	 * computations.
110	 */
111	public_key = kmalloc(ATMEL_ECC_PUBKEY_SIZE, GFP_KERNEL);
112	if (!public_key)
113		goto free_cmd;
114
115	ctx->do_fallback = false;
116
117	atmel_i2c_init_genkey_cmd(cmd, DATA_SLOT_2);
118
119	ret = atmel_i2c_send_receive(ctx->client, cmd);
120	if (ret)
121		goto free_public_key;
122
123	/* save the public key */
124	memcpy(public_key, &cmd->data[RSP_DATA_IDX], ATMEL_ECC_PUBKEY_SIZE);
125	ctx->public_key = public_key;
126
127	kfree(cmd);
128	return 0;
129
130free_public_key:
131	kfree(public_key);
132free_cmd:
133	kfree(cmd);
134	return ret;
135}
136
137static int atmel_ecdh_generate_public_key(struct kpp_request *req)
138{
139	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
140	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
141	size_t copied, nbytes;
142	int ret = 0;
143
144	if (ctx->do_fallback) {
145		kpp_request_set_tfm(req, ctx->fallback);
146		return crypto_kpp_generate_public_key(req);
147	}
148
149	if (!ctx->public_key)
150		return -EINVAL;
151
152	/* might want less than we've got */
153	nbytes = min_t(size_t, ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
154
155	/* public key was saved at private key generation */
156	copied = sg_copy_from_buffer(req->dst,
157				     sg_nents_for_len(req->dst, nbytes),
158				     ctx->public_key, nbytes);
159	if (copied != nbytes)
160		ret = -EINVAL;
161
162	return ret;
163}
164
165static int atmel_ecdh_compute_shared_secret(struct kpp_request *req)
166{
167	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
168	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
169	struct atmel_i2c_work_data *work_data;
170	gfp_t gfp;
171	int ret;
172
173	if (ctx->do_fallback) {
174		kpp_request_set_tfm(req, ctx->fallback);
175		return crypto_kpp_compute_shared_secret(req);
176	}
177
178	/* must have exactly two points to be on the curve */
179	if (req->src_len != ATMEL_ECC_PUBKEY_SIZE)
180		return -EINVAL;
181
182	gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL :
183							     GFP_ATOMIC;
184
185	work_data = kmalloc(sizeof(*work_data), gfp);
186	if (!work_data)
187		return -ENOMEM;
188
189	work_data->ctx = ctx;
190	work_data->client = ctx->client;
191
192	ret = atmel_i2c_init_ecdh_cmd(&work_data->cmd, req->src);
193	if (ret)
194		goto free_work_data;
195
196	atmel_i2c_enqueue(work_data, atmel_ecdh_done, req);
197
198	return -EINPROGRESS;
199
200free_work_data:
201	kfree(work_data);
202	return ret;
203}
204
205static struct i2c_client *atmel_ecc_i2c_client_alloc(void)
206{
207	struct atmel_i2c_client_priv *i2c_priv, *min_i2c_priv = NULL;
208	struct i2c_client *client = ERR_PTR(-ENODEV);
209	int min_tfm_cnt = INT_MAX;
210	int tfm_cnt;
211
212	spin_lock(&driver_data.i2c_list_lock);
213
214	if (list_empty(&driver_data.i2c_client_list)) {
215		spin_unlock(&driver_data.i2c_list_lock);
216		return ERR_PTR(-ENODEV);
217	}
218
219	list_for_each_entry(i2c_priv, &driver_data.i2c_client_list,
220			    i2c_client_list_node) {
221		tfm_cnt = atomic_read(&i2c_priv->tfm_count);
222		if (tfm_cnt < min_tfm_cnt) {
223			min_tfm_cnt = tfm_cnt;
224			min_i2c_priv = i2c_priv;
225		}
226		if (!min_tfm_cnt)
227			break;
228	}
229
230	if (min_i2c_priv) {
231		atomic_inc(&min_i2c_priv->tfm_count);
232		client = min_i2c_priv->client;
233	}
234
235	spin_unlock(&driver_data.i2c_list_lock);
236
237	return client;
238}
239
240static void atmel_ecc_i2c_client_free(struct i2c_client *client)
241{
242	struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
243
244	atomic_dec(&i2c_priv->tfm_count);
245}
246
247static int atmel_ecdh_init_tfm(struct crypto_kpp *tfm)
248{
249	const char *alg = kpp_alg_name(tfm);
250	struct crypto_kpp *fallback;
251	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
252
253	ctx->curve_id = ECC_CURVE_NIST_P256;
254	ctx->client = atmel_ecc_i2c_client_alloc();
255	if (IS_ERR(ctx->client)) {
256		pr_err("tfm - i2c_client binding failed\n");
257		return PTR_ERR(ctx->client);
258	}
259
260	fallback = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
261	if (IS_ERR(fallback)) {
262		dev_err(&ctx->client->dev, "Failed to allocate transformation for '%s': %ld\n",
263			alg, PTR_ERR(fallback));
264		return PTR_ERR(fallback);
265	}
266
267	crypto_kpp_set_flags(fallback, crypto_kpp_get_flags(tfm));
268	ctx->fallback = fallback;
269
270	return 0;
271}
272
273static void atmel_ecdh_exit_tfm(struct crypto_kpp *tfm)
274{
275	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
276
277	kfree(ctx->public_key);
278	crypto_free_kpp(ctx->fallback);
279	atmel_ecc_i2c_client_free(ctx->client);
280}
281
282static unsigned int atmel_ecdh_max_size(struct crypto_kpp *tfm)
283{
284	struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
285
286	if (ctx->fallback)
287		return crypto_kpp_maxsize(ctx->fallback);
288
289	/*
290	 * The device only supports NIST P256 ECC keys. The public key size will
291	 * always be the same. Use a macro for the key size to avoid unnecessary
292	 * computations.
293	 */
294	return ATMEL_ECC_PUBKEY_SIZE;
295}
296
297static struct kpp_alg atmel_ecdh_nist_p256 = {
298	.set_secret = atmel_ecdh_set_secret,
299	.generate_public_key = atmel_ecdh_generate_public_key,
300	.compute_shared_secret = atmel_ecdh_compute_shared_secret,
301	.init = atmel_ecdh_init_tfm,
302	.exit = atmel_ecdh_exit_tfm,
303	.max_size = atmel_ecdh_max_size,
304	.base = {
305		.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
306		.cra_name = "ecdh-nist-p256",
307		.cra_driver_name = "atmel-ecdh",
308		.cra_priority = ATMEL_ECC_PRIORITY,
309		.cra_module = THIS_MODULE,
310		.cra_ctxsize = sizeof(struct atmel_ecdh_ctx),
311	},
312};
313
314static int atmel_ecc_probe(struct i2c_client *client)
315{
316	struct atmel_i2c_client_priv *i2c_priv;
317	int ret;
318
319	ret = atmel_i2c_probe(client);
320	if (ret)
321		return ret;
322
323	i2c_priv = i2c_get_clientdata(client);
324
325	spin_lock(&driver_data.i2c_list_lock);
326	list_add_tail(&i2c_priv->i2c_client_list_node,
327		      &driver_data.i2c_client_list);
328	spin_unlock(&driver_data.i2c_list_lock);
329
330	ret = crypto_register_kpp(&atmel_ecdh_nist_p256);
331	if (ret) {
332		spin_lock(&driver_data.i2c_list_lock);
333		list_del(&i2c_priv->i2c_client_list_node);
334		spin_unlock(&driver_data.i2c_list_lock);
335
336		dev_err(&client->dev, "%s alg registration failed\n",
337			atmel_ecdh_nist_p256.base.cra_driver_name);
338	} else {
339		dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n");
340	}
341
342	return ret;
343}
344
345static void atmel_ecc_remove(struct i2c_client *client)
346{
347	struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
348
349	/* Return EBUSY if i2c client already allocated. */
350	if (atomic_read(&i2c_priv->tfm_count)) {
351		/*
352		 * After we return here, the memory backing the device is freed.
353		 * That happens no matter what the return value of this function
354		 * is because in the Linux device model there is no error
355		 * handling for unbinding a driver.
356		 * If there is still some action pending, it probably involves
357		 * accessing the freed memory.
358		 */
359		dev_emerg(&client->dev, "Device is busy, expect memory corruption.\n");
360		return;
361	}
362
363	crypto_unregister_kpp(&atmel_ecdh_nist_p256);
364
365	spin_lock(&driver_data.i2c_list_lock);
366	list_del(&i2c_priv->i2c_client_list_node);
367	spin_unlock(&driver_data.i2c_list_lock);
368}
369
370#ifdef CONFIG_OF
371static const struct of_device_id atmel_ecc_dt_ids[] = {
372	{
373		.compatible = "atmel,atecc508a",
374	}, {
375		/* sentinel */
376	}
377};
378MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids);
379#endif
380
381static const struct i2c_device_id atmel_ecc_id[] = {
382	{ "atecc508a", 0 },
383	{ }
384};
385MODULE_DEVICE_TABLE(i2c, atmel_ecc_id);
386
387static struct i2c_driver atmel_ecc_driver = {
388	.driver = {
389		.name	= "atmel-ecc",
390		.of_match_table = of_match_ptr(atmel_ecc_dt_ids),
391	},
392	.probe		= atmel_ecc_probe,
393	.remove		= atmel_ecc_remove,
394	.id_table	= atmel_ecc_id,
395};
396
397static int __init atmel_ecc_init(void)
398{
399	spin_lock_init(&driver_data.i2c_list_lock);
400	INIT_LIST_HEAD(&driver_data.i2c_client_list);
401	return i2c_add_driver(&atmel_ecc_driver);
402}
403
404static void __exit atmel_ecc_exit(void)
405{
406	atmel_i2c_flush_queue();
407	i2c_del_driver(&atmel_ecc_driver);
408}
409
410module_init(atmel_ecc_init);
411module_exit(atmel_ecc_exit);
412
413MODULE_AUTHOR("Tudor Ambarus");
414MODULE_DESCRIPTION("Microchip / Atmel ECC (I2C) driver");
415MODULE_LICENSE("GPL v2");
416