Loading...
Note: File does not exist in v5.4.
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Intel Keem Bay OCS ECC Crypto Driver.
4 *
5 * Copyright (C) 2019-2021 Intel Corporation
6 */
7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10#include <crypto/ecc_curve.h>
11#include <crypto/ecdh.h>
12#include <crypto/engine.h>
13#include <crypto/internal/ecc.h>
14#include <crypto/internal/kpp.h>
15#include <crypto/kpp.h>
16#include <crypto/rng.h>
17#include <linux/clk.h>
18#include <linux/completion.h>
19#include <linux/err.h>
20#include <linux/fips.h>
21#include <linux/interrupt.h>
22#include <linux/io.h>
23#include <linux/iopoll.h>
24#include <linux/irq.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/of.h>
28#include <linux/platform_device.h>
29#include <linux/scatterlist.h>
30#include <linux/string.h>
31
32#define DRV_NAME "keembay-ocs-ecc"
33
34#define KMB_OCS_ECC_PRIORITY 350
35
36#define HW_OFFS_OCS_ECC_COMMAND 0x00000000
37#define HW_OFFS_OCS_ECC_STATUS 0x00000004
38#define HW_OFFS_OCS_ECC_DATA_IN 0x00000080
39#define HW_OFFS_OCS_ECC_CX_DATA_OUT 0x00000100
40#define HW_OFFS_OCS_ECC_CY_DATA_OUT 0x00000180
41#define HW_OFFS_OCS_ECC_ISR 0x00000400
42#define HW_OFFS_OCS_ECC_IER 0x00000404
43
44#define HW_OCS_ECC_ISR_INT_STATUS_DONE BIT(0)
45#define HW_OCS_ECC_COMMAND_INS_BP BIT(0)
46
47#define HW_OCS_ECC_COMMAND_START_VAL BIT(0)
48
49#define OCS_ECC_OP_SIZE_384 BIT(8)
50#define OCS_ECC_OP_SIZE_256 0
51
52/* ECC Instruction : for ECC_COMMAND */
53#define OCS_ECC_INST_WRITE_AX (0x1 << HW_OCS_ECC_COMMAND_INS_BP)
54#define OCS_ECC_INST_WRITE_AY (0x2 << HW_OCS_ECC_COMMAND_INS_BP)
55#define OCS_ECC_INST_WRITE_BX_D (0x3 << HW_OCS_ECC_COMMAND_INS_BP)
56#define OCS_ECC_INST_WRITE_BY_L (0x4 << HW_OCS_ECC_COMMAND_INS_BP)
57#define OCS_ECC_INST_WRITE_P (0x5 << HW_OCS_ECC_COMMAND_INS_BP)
58#define OCS_ECC_INST_WRITE_A (0x6 << HW_OCS_ECC_COMMAND_INS_BP)
59#define OCS_ECC_INST_CALC_D_IDX_A (0x8 << HW_OCS_ECC_COMMAND_INS_BP)
60#define OCS_ECC_INST_CALC_A_POW_B_MODP (0xB << HW_OCS_ECC_COMMAND_INS_BP)
61#define OCS_ECC_INST_CALC_A_MUL_B_MODP (0xC << HW_OCS_ECC_COMMAND_INS_BP)
62#define OCS_ECC_INST_CALC_A_ADD_B_MODP (0xD << HW_OCS_ECC_COMMAND_INS_BP)
63
64#define ECC_ENABLE_INTR 1
65
66#define POLL_USEC 100
67#define TIMEOUT_USEC 10000
68
69#define KMB_ECC_VLI_MAX_DIGITS ECC_CURVE_NIST_P384_DIGITS
70#define KMB_ECC_VLI_MAX_BYTES (KMB_ECC_VLI_MAX_DIGITS \
71 << ECC_DIGITS_TO_BYTES_SHIFT)
72
73#define POW_CUBE 3
74
75/**
76 * struct ocs_ecc_dev - ECC device context
77 * @list: List of device contexts
78 * @dev: OCS ECC device
79 * @base_reg: IO base address of OCS ECC
80 * @engine: Crypto engine for the device
81 * @irq_done: IRQ done completion.
82 * @irq: IRQ number
83 */
84struct ocs_ecc_dev {
85 struct list_head list;
86 struct device *dev;
87 void __iomem *base_reg;
88 struct crypto_engine *engine;
89 struct completion irq_done;
90 int irq;
91};
92
93/**
94 * struct ocs_ecc_ctx - Transformation context.
95 * @ecc_dev: The ECC driver associated with this context.
96 * @curve: The elliptic curve used by this transformation.
97 * @private_key: The private key.
98 */
99struct ocs_ecc_ctx {
100 struct ocs_ecc_dev *ecc_dev;
101 const struct ecc_curve *curve;
102 u64 private_key[KMB_ECC_VLI_MAX_DIGITS];
103};
104
105/* Driver data. */
106struct ocs_ecc_drv {
107 struct list_head dev_list;
108 spinlock_t lock; /* Protects dev_list. */
109};
110
111/* Global variable holding the list of OCS ECC devices (only one expected). */
112static struct ocs_ecc_drv ocs_ecc = {
113 .dev_list = LIST_HEAD_INIT(ocs_ecc.dev_list),
114 .lock = __SPIN_LOCK_UNLOCKED(ocs_ecc.lock),
115};
116
117/* Get OCS ECC tfm context from kpp_request. */
118static inline struct ocs_ecc_ctx *kmb_ocs_ecc_tctx(struct kpp_request *req)
119{
120 return kpp_tfm_ctx(crypto_kpp_reqtfm(req));
121}
122
123/* Converts number of digits to number of bytes. */
124static inline unsigned int digits_to_bytes(unsigned int n)
125{
126 return n << ECC_DIGITS_TO_BYTES_SHIFT;
127}
128
129/*
130 * Wait for ECC idle i.e when an operation (other than write operations)
131 * is done.
132 */
133static inline int ocs_ecc_wait_idle(struct ocs_ecc_dev *dev)
134{
135 u32 value;
136
137 return readl_poll_timeout((dev->base_reg + HW_OFFS_OCS_ECC_STATUS),
138 value,
139 !(value & HW_OCS_ECC_ISR_INT_STATUS_DONE),
140 POLL_USEC, TIMEOUT_USEC);
141}
142
143static void ocs_ecc_cmd_start(struct ocs_ecc_dev *ecc_dev, u32 op_size)
144{
145 iowrite32(op_size | HW_OCS_ECC_COMMAND_START_VAL,
146 ecc_dev->base_reg + HW_OFFS_OCS_ECC_COMMAND);
147}
148
149/* Direct write of u32 buffer to ECC engine with associated instruction. */
150static void ocs_ecc_write_cmd_and_data(struct ocs_ecc_dev *dev,
151 u32 op_size,
152 u32 inst,
153 const void *data_in,
154 size_t data_size)
155{
156 iowrite32(op_size | inst, dev->base_reg + HW_OFFS_OCS_ECC_COMMAND);
157
158 /* MMIO Write src uint32 to dst. */
159 memcpy_toio(dev->base_reg + HW_OFFS_OCS_ECC_DATA_IN, data_in,
160 data_size);
161}
162
163/* Start OCS ECC operation and wait for its completion. */
164static int ocs_ecc_trigger_op(struct ocs_ecc_dev *ecc_dev, u32 op_size,
165 u32 inst)
166{
167 reinit_completion(&ecc_dev->irq_done);
168
169 iowrite32(ECC_ENABLE_INTR, ecc_dev->base_reg + HW_OFFS_OCS_ECC_IER);
170 iowrite32(op_size | inst, ecc_dev->base_reg + HW_OFFS_OCS_ECC_COMMAND);
171
172 return wait_for_completion_interruptible(&ecc_dev->irq_done);
173}
174
175/**
176 * ocs_ecc_read_cx_out() - Read the CX data output buffer.
177 * @dev: The OCS ECC device to read from.
178 * @cx_out: The buffer where to store the CX value. Must be at least
179 * @byte_count byte long.
180 * @byte_count: The amount of data to read.
181 */
182static inline void ocs_ecc_read_cx_out(struct ocs_ecc_dev *dev, void *cx_out,
183 size_t byte_count)
184{
185 memcpy_fromio(cx_out, dev->base_reg + HW_OFFS_OCS_ECC_CX_DATA_OUT,
186 byte_count);
187}
188
189/**
190 * ocs_ecc_read_cy_out() - Read the CX data output buffer.
191 * @dev: The OCS ECC device to read from.
192 * @cy_out: The buffer where to store the CY value. Must be at least
193 * @byte_count byte long.
194 * @byte_count: The amount of data to read.
195 */
196static inline void ocs_ecc_read_cy_out(struct ocs_ecc_dev *dev, void *cy_out,
197 size_t byte_count)
198{
199 memcpy_fromio(cy_out, dev->base_reg + HW_OFFS_OCS_ECC_CY_DATA_OUT,
200 byte_count);
201}
202
203static struct ocs_ecc_dev *kmb_ocs_ecc_find_dev(struct ocs_ecc_ctx *tctx)
204{
205 if (tctx->ecc_dev)
206 return tctx->ecc_dev;
207
208 spin_lock(&ocs_ecc.lock);
209
210 /* Only a single OCS device available. */
211 tctx->ecc_dev = list_first_entry(&ocs_ecc.dev_list, struct ocs_ecc_dev,
212 list);
213
214 spin_unlock(&ocs_ecc.lock);
215
216 return tctx->ecc_dev;
217}
218
219/* Do point multiplication using OCS ECC HW. */
220static int kmb_ecc_point_mult(struct ocs_ecc_dev *ecc_dev,
221 struct ecc_point *result,
222 const struct ecc_point *point,
223 u64 *scalar,
224 const struct ecc_curve *curve)
225{
226 u8 sca[KMB_ECC_VLI_MAX_BYTES]; /* Use the maximum data size. */
227 u32 op_size = (curve->g.ndigits > ECC_CURVE_NIST_P256_DIGITS) ?
228 OCS_ECC_OP_SIZE_384 : OCS_ECC_OP_SIZE_256;
229 size_t nbytes = digits_to_bytes(curve->g.ndigits);
230 int rc = 0;
231
232 /* Generate random nbytes for Simple and Differential SCA protection. */
233 rc = crypto_get_default_rng();
234 if (rc)
235 return rc;
236
237 rc = crypto_rng_get_bytes(crypto_default_rng, sca, nbytes);
238 crypto_put_default_rng();
239 if (rc)
240 return rc;
241
242 /* Wait engine to be idle before starting new operation. */
243 rc = ocs_ecc_wait_idle(ecc_dev);
244 if (rc)
245 return rc;
246
247 /* Send ecc_start pulse as well as indicating operation size. */
248 ocs_ecc_cmd_start(ecc_dev, op_size);
249
250 /* Write ax param; Base point (Gx). */
251 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_AX,
252 point->x, nbytes);
253
254 /* Write ay param; Base point (Gy). */
255 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_AY,
256 point->y, nbytes);
257
258 /*
259 * Write the private key into DATA_IN reg.
260 *
261 * Since DATA_IN register is used to write different values during the
262 * computation private Key value is overwritten with
263 * side-channel-resistance value.
264 */
265 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_BX_D,
266 scalar, nbytes);
267
268 /* Write operand by/l. */
269 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_BY_L,
270 sca, nbytes);
271 memzero_explicit(sca, sizeof(sca));
272
273 /* Write p = curve prime(GF modulus). */
274 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_P,
275 curve->p, nbytes);
276
277 /* Write a = curve coefficient. */
278 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_A,
279 curve->a, nbytes);
280
281 /* Make hardware perform the multiplication. */
282 rc = ocs_ecc_trigger_op(ecc_dev, op_size, OCS_ECC_INST_CALC_D_IDX_A);
283 if (rc)
284 return rc;
285
286 /* Read result. */
287 ocs_ecc_read_cx_out(ecc_dev, result->x, nbytes);
288 ocs_ecc_read_cy_out(ecc_dev, result->y, nbytes);
289
290 return 0;
291}
292
293/**
294 * kmb_ecc_do_scalar_op() - Perform Scalar operation using OCS ECC HW.
295 * @ecc_dev: The OCS ECC device to use.
296 * @scalar_out: Where to store the output scalar.
297 * @scalar_a: Input scalar operand 'a'.
298 * @scalar_b: Input scalar operand 'b'
299 * @curve: The curve on which the operation is performed.
300 * @ndigits: The size of the operands (in digits).
301 * @inst: The operation to perform (as an OCS ECC instruction).
302 *
303 * Return: 0 on success, negative error code otherwise.
304 */
305static int kmb_ecc_do_scalar_op(struct ocs_ecc_dev *ecc_dev, u64 *scalar_out,
306 const u64 *scalar_a, const u64 *scalar_b,
307 const struct ecc_curve *curve,
308 unsigned int ndigits, const u32 inst)
309{
310 u32 op_size = (ndigits > ECC_CURVE_NIST_P256_DIGITS) ?
311 OCS_ECC_OP_SIZE_384 : OCS_ECC_OP_SIZE_256;
312 size_t nbytes = digits_to_bytes(ndigits);
313 int rc;
314
315 /* Wait engine to be idle before starting new operation. */
316 rc = ocs_ecc_wait_idle(ecc_dev);
317 if (rc)
318 return rc;
319
320 /* Send ecc_start pulse as well as indicating operation size. */
321 ocs_ecc_cmd_start(ecc_dev, op_size);
322
323 /* Write ax param (Base point (Gx).*/
324 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_AX,
325 scalar_a, nbytes);
326
327 /* Write ay param Base point (Gy).*/
328 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_AY,
329 scalar_b, nbytes);
330
331 /* Write p = curve prime(GF modulus).*/
332 ocs_ecc_write_cmd_and_data(ecc_dev, op_size, OCS_ECC_INST_WRITE_P,
333 curve->p, nbytes);
334
335 /* Give instruction A.B or A+B to ECC engine. */
336 rc = ocs_ecc_trigger_op(ecc_dev, op_size, inst);
337 if (rc)
338 return rc;
339
340 ocs_ecc_read_cx_out(ecc_dev, scalar_out, nbytes);
341
342 if (vli_is_zero(scalar_out, ndigits))
343 return -EINVAL;
344
345 return 0;
346}
347
348/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
349static int kmb_ocs_ecc_is_pubkey_valid_partial(struct ocs_ecc_dev *ecc_dev,
350 const struct ecc_curve *curve,
351 struct ecc_point *pk)
352{
353 u64 xxx[KMB_ECC_VLI_MAX_DIGITS] = { 0 };
354 u64 yy[KMB_ECC_VLI_MAX_DIGITS] = { 0 };
355 u64 w[KMB_ECC_VLI_MAX_DIGITS] = { 0 };
356 int rc;
357
358 if (WARN_ON(pk->ndigits != curve->g.ndigits))
359 return -EINVAL;
360
361 /* Check 1: Verify key is not the zero point. */
362 if (ecc_point_is_zero(pk))
363 return -EINVAL;
364
365 /* Check 2: Verify key is in the range [0, p-1]. */
366 if (vli_cmp(curve->p, pk->x, pk->ndigits) != 1)
367 return -EINVAL;
368
369 if (vli_cmp(curve->p, pk->y, pk->ndigits) != 1)
370 return -EINVAL;
371
372 /* Check 3: Verify that y^2 == (x^3 + a·x + b) mod p */
373
374 /* y^2 */
375 /* Compute y^2 -> store in yy */
376 rc = kmb_ecc_do_scalar_op(ecc_dev, yy, pk->y, pk->y, curve, pk->ndigits,
377 OCS_ECC_INST_CALC_A_MUL_B_MODP);
378 if (rc)
379 goto exit;
380
381 /* x^3 */
382 /* Assigning w = 3, used for calculating x^3. */
383 w[0] = POW_CUBE;
384 /* Load the next stage.*/
385 rc = kmb_ecc_do_scalar_op(ecc_dev, xxx, pk->x, w, curve, pk->ndigits,
386 OCS_ECC_INST_CALC_A_POW_B_MODP);
387 if (rc)
388 goto exit;
389
390 /* Do a*x -> store in w. */
391 rc = kmb_ecc_do_scalar_op(ecc_dev, w, curve->a, pk->x, curve,
392 pk->ndigits,
393 OCS_ECC_INST_CALC_A_MUL_B_MODP);
394 if (rc)
395 goto exit;
396
397 /* Do ax + b == w + b; store in w. */
398 rc = kmb_ecc_do_scalar_op(ecc_dev, w, w, curve->b, curve,
399 pk->ndigits,
400 OCS_ECC_INST_CALC_A_ADD_B_MODP);
401 if (rc)
402 goto exit;
403
404 /* x^3 + ax + b == x^3 + w -> store in w. */
405 rc = kmb_ecc_do_scalar_op(ecc_dev, w, xxx, w, curve, pk->ndigits,
406 OCS_ECC_INST_CALC_A_ADD_B_MODP);
407 if (rc)
408 goto exit;
409
410 /* Compare y^2 == x^3 + a·x + b. */
411 rc = vli_cmp(yy, w, pk->ndigits);
412 if (rc)
413 rc = -EINVAL;
414
415exit:
416 memzero_explicit(xxx, sizeof(xxx));
417 memzero_explicit(yy, sizeof(yy));
418 memzero_explicit(w, sizeof(w));
419
420 return rc;
421}
422
423/* SP800-56A section 5.6.2.3.3 full verification */
424static int kmb_ocs_ecc_is_pubkey_valid_full(struct ocs_ecc_dev *ecc_dev,
425 const struct ecc_curve *curve,
426 struct ecc_point *pk)
427{
428 struct ecc_point *nQ;
429 int rc;
430
431 /* Checks 1 through 3 */
432 rc = kmb_ocs_ecc_is_pubkey_valid_partial(ecc_dev, curve, pk);
433 if (rc)
434 return rc;
435
436 /* Check 4: Verify that nQ is the zero point. */
437 nQ = ecc_alloc_point(pk->ndigits);
438 if (!nQ)
439 return -ENOMEM;
440
441 rc = kmb_ecc_point_mult(ecc_dev, nQ, pk, curve->n, curve);
442 if (rc)
443 goto exit;
444
445 if (!ecc_point_is_zero(nQ))
446 rc = -EINVAL;
447
448exit:
449 ecc_free_point(nQ);
450
451 return rc;
452}
453
454static int kmb_ecc_is_key_valid(const struct ecc_curve *curve,
455 const u64 *private_key, size_t private_key_len)
456{
457 size_t ndigits = curve->g.ndigits;
458 u64 one[KMB_ECC_VLI_MAX_DIGITS] = {1};
459 u64 res[KMB_ECC_VLI_MAX_DIGITS];
460
461 if (private_key_len != digits_to_bytes(ndigits))
462 return -EINVAL;
463
464 if (!private_key)
465 return -EINVAL;
466
467 /* Make sure the private key is in the range [2, n-3]. */
468 if (vli_cmp(one, private_key, ndigits) != -1)
469 return -EINVAL;
470
471 vli_sub(res, curve->n, one, ndigits);
472 vli_sub(res, res, one, ndigits);
473 if (vli_cmp(res, private_key, ndigits) != 1)
474 return -EINVAL;
475
476 return 0;
477}
478
479/*
480 * ECC private keys are generated using the method of extra random bits,
481 * equivalent to that described in FIPS 186-4, Appendix B.4.1.
482 *
483 * d = (c mod(n–1)) + 1 where c is a string of random bits, 64 bits longer
484 * than requested
485 * 0 <= c mod(n-1) <= n-2 and implies that
486 * 1 <= d <= n-1
487 *
488 * This method generates a private key uniformly distributed in the range
489 * [1, n-1].
490 */
491static int kmb_ecc_gen_privkey(const struct ecc_curve *curve, u64 *privkey)
492{
493 size_t nbytes = digits_to_bytes(curve->g.ndigits);
494 u64 priv[KMB_ECC_VLI_MAX_DIGITS];
495 size_t nbits;
496 int rc;
497
498 nbits = vli_num_bits(curve->n, curve->g.ndigits);
499
500 /* Check that N is included in Table 1 of FIPS 186-4, section 6.1.1 */
501 if (nbits < 160 || curve->g.ndigits > ARRAY_SIZE(priv))
502 return -EINVAL;
503
504 /*
505 * FIPS 186-4 recommends that the private key should be obtained from a
506 * RBG with a security strength equal to or greater than the security
507 * strength associated with N.
508 *
509 * The maximum security strength identified by NIST SP800-57pt1r4 for
510 * ECC is 256 (N >= 512).
511 *
512 * This condition is met by the default RNG because it selects a favored
513 * DRBG with a security strength of 256.
514 */
515 if (crypto_get_default_rng())
516 return -EFAULT;
517
518 rc = crypto_rng_get_bytes(crypto_default_rng, (u8 *)priv, nbytes);
519 crypto_put_default_rng();
520 if (rc)
521 goto cleanup;
522
523 rc = kmb_ecc_is_key_valid(curve, priv, nbytes);
524 if (rc)
525 goto cleanup;
526
527 ecc_swap_digits(priv, privkey, curve->g.ndigits);
528
529cleanup:
530 memzero_explicit(&priv, sizeof(priv));
531
532 return rc;
533}
534
535static int kmb_ocs_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
536 unsigned int len)
537{
538 struct ocs_ecc_ctx *tctx = kpp_tfm_ctx(tfm);
539 struct ecdh params;
540 int rc = 0;
541
542 rc = crypto_ecdh_decode_key(buf, len, ¶ms);
543 if (rc)
544 goto cleanup;
545
546 /* Ensure key size is not bigger then expected. */
547 if (params.key_size > digits_to_bytes(tctx->curve->g.ndigits)) {
548 rc = -EINVAL;
549 goto cleanup;
550 }
551
552 /* Auto-generate private key is not provided. */
553 if (!params.key || !params.key_size) {
554 rc = kmb_ecc_gen_privkey(tctx->curve, tctx->private_key);
555 goto cleanup;
556 }
557
558 rc = kmb_ecc_is_key_valid(tctx->curve, (const u64 *)params.key,
559 params.key_size);
560 if (rc)
561 goto cleanup;
562
563 ecc_swap_digits((const u64 *)params.key, tctx->private_key,
564 tctx->curve->g.ndigits);
565cleanup:
566 memzero_explicit(¶ms, sizeof(params));
567
568 if (rc)
569 tctx->curve = NULL;
570
571 return rc;
572}
573
574/* Compute shared secret. */
575static int kmb_ecc_do_shared_secret(struct ocs_ecc_ctx *tctx,
576 struct kpp_request *req)
577{
578 struct ocs_ecc_dev *ecc_dev = tctx->ecc_dev;
579 const struct ecc_curve *curve = tctx->curve;
580 u64 shared_secret[KMB_ECC_VLI_MAX_DIGITS];
581 u64 pubk_buf[KMB_ECC_VLI_MAX_DIGITS * 2];
582 size_t copied, nbytes, pubk_len;
583 struct ecc_point *pk, *result;
584 int rc;
585
586 nbytes = digits_to_bytes(curve->g.ndigits);
587
588 /* Public key is a point, thus it has two coordinates */
589 pubk_len = 2 * nbytes;
590
591 /* Copy public key from SG list to pubk_buf. */
592 copied = sg_copy_to_buffer(req->src,
593 sg_nents_for_len(req->src, pubk_len),
594 pubk_buf, pubk_len);
595 if (copied != pubk_len)
596 return -EINVAL;
597
598 /* Allocate and initialize public key point. */
599 pk = ecc_alloc_point(curve->g.ndigits);
600 if (!pk)
601 return -ENOMEM;
602
603 ecc_swap_digits(pubk_buf, pk->x, curve->g.ndigits);
604 ecc_swap_digits(&pubk_buf[curve->g.ndigits], pk->y, curve->g.ndigits);
605
606 /*
607 * Check the public key for following
608 * Check 1: Verify key is not the zero point.
609 * Check 2: Verify key is in the range [1, p-1].
610 * Check 3: Verify that y^2 == (x^3 + a·x + b) mod p
611 */
612 rc = kmb_ocs_ecc_is_pubkey_valid_partial(ecc_dev, curve, pk);
613 if (rc)
614 goto exit_free_pk;
615
616 /* Allocate point for storing computed shared secret. */
617 result = ecc_alloc_point(pk->ndigits);
618 if (!result) {
619 rc = -ENOMEM;
620 goto exit_free_pk;
621 }
622
623 /* Calculate the shared secret.*/
624 rc = kmb_ecc_point_mult(ecc_dev, result, pk, tctx->private_key, curve);
625 if (rc)
626 goto exit_free_result;
627
628 if (ecc_point_is_zero(result)) {
629 rc = -EFAULT;
630 goto exit_free_result;
631 }
632
633 /* Copy shared secret from point to buffer. */
634 ecc_swap_digits(result->x, shared_secret, result->ndigits);
635
636 /* Request might ask for less bytes than what we have. */
637 nbytes = min_t(size_t, nbytes, req->dst_len);
638
639 copied = sg_copy_from_buffer(req->dst,
640 sg_nents_for_len(req->dst, nbytes),
641 shared_secret, nbytes);
642
643 if (copied != nbytes)
644 rc = -EINVAL;
645
646 memzero_explicit(shared_secret, sizeof(shared_secret));
647
648exit_free_result:
649 ecc_free_point(result);
650
651exit_free_pk:
652 ecc_free_point(pk);
653
654 return rc;
655}
656
657/* Compute public key. */
658static int kmb_ecc_do_public_key(struct ocs_ecc_ctx *tctx,
659 struct kpp_request *req)
660{
661 const struct ecc_curve *curve = tctx->curve;
662 u64 pubk_buf[KMB_ECC_VLI_MAX_DIGITS * 2];
663 struct ecc_point *pk;
664 size_t pubk_len;
665 size_t copied;
666 int rc;
667
668 /* Public key is a point, so it has double the digits. */
669 pubk_len = 2 * digits_to_bytes(curve->g.ndigits);
670
671 pk = ecc_alloc_point(curve->g.ndigits);
672 if (!pk)
673 return -ENOMEM;
674
675 /* Public Key(pk) = priv * G. */
676 rc = kmb_ecc_point_mult(tctx->ecc_dev, pk, &curve->g, tctx->private_key,
677 curve);
678 if (rc)
679 goto exit;
680
681 /* SP800-56A rev 3 5.6.2.1.3 key check */
682 if (kmb_ocs_ecc_is_pubkey_valid_full(tctx->ecc_dev, curve, pk)) {
683 rc = -EAGAIN;
684 goto exit;
685 }
686
687 /* Copy public key from point to buffer. */
688 ecc_swap_digits(pk->x, pubk_buf, pk->ndigits);
689 ecc_swap_digits(pk->y, &pubk_buf[pk->ndigits], pk->ndigits);
690
691 /* Copy public key to req->dst. */
692 copied = sg_copy_from_buffer(req->dst,
693 sg_nents_for_len(req->dst, pubk_len),
694 pubk_buf, pubk_len);
695
696 if (copied != pubk_len)
697 rc = -EINVAL;
698
699exit:
700 ecc_free_point(pk);
701
702 return rc;
703}
704
705static int kmb_ocs_ecc_do_one_request(struct crypto_engine *engine,
706 void *areq)
707{
708 struct kpp_request *req = container_of(areq, struct kpp_request, base);
709 struct ocs_ecc_ctx *tctx = kmb_ocs_ecc_tctx(req);
710 struct ocs_ecc_dev *ecc_dev = tctx->ecc_dev;
711 int rc;
712
713 if (req->src)
714 rc = kmb_ecc_do_shared_secret(tctx, req);
715 else
716 rc = kmb_ecc_do_public_key(tctx, req);
717
718 crypto_finalize_kpp_request(ecc_dev->engine, req, rc);
719
720 return 0;
721}
722
723static int kmb_ocs_ecdh_generate_public_key(struct kpp_request *req)
724{
725 struct ocs_ecc_ctx *tctx = kmb_ocs_ecc_tctx(req);
726 const struct ecc_curve *curve = tctx->curve;
727
728 /* Ensure kmb_ocs_ecdh_set_secret() has been successfully called. */
729 if (!tctx->curve)
730 return -EINVAL;
731
732 /* Ensure dst is present. */
733 if (!req->dst)
734 return -EINVAL;
735
736 /* Check the request dst is big enough to hold the public key. */
737 if (req->dst_len < (2 * digits_to_bytes(curve->g.ndigits)))
738 return -EINVAL;
739
740 /* 'src' is not supposed to be present when generate pubk is called. */
741 if (req->src)
742 return -EINVAL;
743
744 return crypto_transfer_kpp_request_to_engine(tctx->ecc_dev->engine,
745 req);
746}
747
748static int kmb_ocs_ecdh_compute_shared_secret(struct kpp_request *req)
749{
750 struct ocs_ecc_ctx *tctx = kmb_ocs_ecc_tctx(req);
751 const struct ecc_curve *curve = tctx->curve;
752
753 /* Ensure kmb_ocs_ecdh_set_secret() has been successfully called. */
754 if (!tctx->curve)
755 return -EINVAL;
756
757 /* Ensure dst is present. */
758 if (!req->dst)
759 return -EINVAL;
760
761 /* Ensure src is present. */
762 if (!req->src)
763 return -EINVAL;
764
765 /*
766 * req->src is expected to the (other-side) public key, so its length
767 * must be 2 * coordinate size (in bytes).
768 */
769 if (req->src_len != 2 * digits_to_bytes(curve->g.ndigits))
770 return -EINVAL;
771
772 return crypto_transfer_kpp_request_to_engine(tctx->ecc_dev->engine,
773 req);
774}
775
776static int kmb_ecc_tctx_init(struct ocs_ecc_ctx *tctx, unsigned int curve_id)
777{
778 memset(tctx, 0, sizeof(*tctx));
779
780 tctx->ecc_dev = kmb_ocs_ecc_find_dev(tctx);
781
782 if (IS_ERR(tctx->ecc_dev)) {
783 pr_err("Failed to find the device : %ld\n",
784 PTR_ERR(tctx->ecc_dev));
785 return PTR_ERR(tctx->ecc_dev);
786 }
787
788 tctx->curve = ecc_get_curve(curve_id);
789 if (!tctx->curve)
790 return -EOPNOTSUPP;
791
792 return 0;
793}
794
795static int kmb_ocs_ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm)
796{
797 struct ocs_ecc_ctx *tctx = kpp_tfm_ctx(tfm);
798
799 return kmb_ecc_tctx_init(tctx, ECC_CURVE_NIST_P256);
800}
801
802static int kmb_ocs_ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm)
803{
804 struct ocs_ecc_ctx *tctx = kpp_tfm_ctx(tfm);
805
806 return kmb_ecc_tctx_init(tctx, ECC_CURVE_NIST_P384);
807}
808
809static void kmb_ocs_ecdh_exit_tfm(struct crypto_kpp *tfm)
810{
811 struct ocs_ecc_ctx *tctx = kpp_tfm_ctx(tfm);
812
813 memzero_explicit(tctx->private_key, sizeof(*tctx->private_key));
814}
815
816static unsigned int kmb_ocs_ecdh_max_size(struct crypto_kpp *tfm)
817{
818 struct ocs_ecc_ctx *tctx = kpp_tfm_ctx(tfm);
819
820 /* Public key is made of two coordinates, so double the digits. */
821 return digits_to_bytes(tctx->curve->g.ndigits) * 2;
822}
823
824static struct kpp_engine_alg ocs_ecdh_p256 = {
825 .base.set_secret = kmb_ocs_ecdh_set_secret,
826 .base.generate_public_key = kmb_ocs_ecdh_generate_public_key,
827 .base.compute_shared_secret = kmb_ocs_ecdh_compute_shared_secret,
828 .base.init = kmb_ocs_ecdh_nist_p256_init_tfm,
829 .base.exit = kmb_ocs_ecdh_exit_tfm,
830 .base.max_size = kmb_ocs_ecdh_max_size,
831 .base.base = {
832 .cra_name = "ecdh-nist-p256",
833 .cra_driver_name = "ecdh-nist-p256-keembay-ocs",
834 .cra_priority = KMB_OCS_ECC_PRIORITY,
835 .cra_module = THIS_MODULE,
836 .cra_ctxsize = sizeof(struct ocs_ecc_ctx),
837 },
838 .op.do_one_request = kmb_ocs_ecc_do_one_request,
839};
840
841static struct kpp_engine_alg ocs_ecdh_p384 = {
842 .base.set_secret = kmb_ocs_ecdh_set_secret,
843 .base.generate_public_key = kmb_ocs_ecdh_generate_public_key,
844 .base.compute_shared_secret = kmb_ocs_ecdh_compute_shared_secret,
845 .base.init = kmb_ocs_ecdh_nist_p384_init_tfm,
846 .base.exit = kmb_ocs_ecdh_exit_tfm,
847 .base.max_size = kmb_ocs_ecdh_max_size,
848 .base.base = {
849 .cra_name = "ecdh-nist-p384",
850 .cra_driver_name = "ecdh-nist-p384-keembay-ocs",
851 .cra_priority = KMB_OCS_ECC_PRIORITY,
852 .cra_module = THIS_MODULE,
853 .cra_ctxsize = sizeof(struct ocs_ecc_ctx),
854 },
855 .op.do_one_request = kmb_ocs_ecc_do_one_request,
856};
857
858static irqreturn_t ocs_ecc_irq_handler(int irq, void *dev_id)
859{
860 struct ocs_ecc_dev *ecc_dev = dev_id;
861 u32 status;
862
863 /*
864 * Read the status register and write it back to clear the
865 * DONE_INT_STATUS bit.
866 */
867 status = ioread32(ecc_dev->base_reg + HW_OFFS_OCS_ECC_ISR);
868 iowrite32(status, ecc_dev->base_reg + HW_OFFS_OCS_ECC_ISR);
869
870 if (!(status & HW_OCS_ECC_ISR_INT_STATUS_DONE))
871 return IRQ_NONE;
872
873 complete(&ecc_dev->irq_done);
874
875 return IRQ_HANDLED;
876}
877
878static int kmb_ocs_ecc_probe(struct platform_device *pdev)
879{
880 struct device *dev = &pdev->dev;
881 struct ocs_ecc_dev *ecc_dev;
882 int rc;
883
884 ecc_dev = devm_kzalloc(dev, sizeof(*ecc_dev), GFP_KERNEL);
885 if (!ecc_dev)
886 return -ENOMEM;
887
888 ecc_dev->dev = dev;
889
890 platform_set_drvdata(pdev, ecc_dev);
891
892 INIT_LIST_HEAD(&ecc_dev->list);
893 init_completion(&ecc_dev->irq_done);
894
895 /* Get base register address. */
896 ecc_dev->base_reg = devm_platform_ioremap_resource(pdev, 0);
897 if (IS_ERR(ecc_dev->base_reg)) {
898 dev_err(dev, "Failed to get base address\n");
899 rc = PTR_ERR(ecc_dev->base_reg);
900 goto list_del;
901 }
902
903 /* Get and request IRQ */
904 ecc_dev->irq = platform_get_irq(pdev, 0);
905 if (ecc_dev->irq < 0) {
906 rc = ecc_dev->irq;
907 goto list_del;
908 }
909
910 rc = devm_request_threaded_irq(dev, ecc_dev->irq, ocs_ecc_irq_handler,
911 NULL, 0, "keembay-ocs-ecc", ecc_dev);
912 if (rc < 0) {
913 dev_err(dev, "Could not request IRQ\n");
914 goto list_del;
915 }
916
917 /* Add device to the list of OCS ECC devices. */
918 spin_lock(&ocs_ecc.lock);
919 list_add_tail(&ecc_dev->list, &ocs_ecc.dev_list);
920 spin_unlock(&ocs_ecc.lock);
921
922 /* Initialize crypto engine. */
923 ecc_dev->engine = crypto_engine_alloc_init(dev, 1);
924 if (!ecc_dev->engine) {
925 dev_err(dev, "Could not allocate crypto engine\n");
926 rc = -ENOMEM;
927 goto list_del;
928 }
929
930 rc = crypto_engine_start(ecc_dev->engine);
931 if (rc) {
932 dev_err(dev, "Could not start crypto engine\n");
933 goto cleanup;
934 }
935
936 /* Register the KPP algo. */
937 rc = crypto_engine_register_kpp(&ocs_ecdh_p256);
938 if (rc) {
939 dev_err(dev,
940 "Could not register OCS algorithms with Crypto API\n");
941 goto cleanup;
942 }
943
944 rc = crypto_engine_register_kpp(&ocs_ecdh_p384);
945 if (rc) {
946 dev_err(dev,
947 "Could not register OCS algorithms with Crypto API\n");
948 goto ocs_ecdh_p384_error;
949 }
950
951 return 0;
952
953ocs_ecdh_p384_error:
954 crypto_engine_unregister_kpp(&ocs_ecdh_p256);
955
956cleanup:
957 crypto_engine_exit(ecc_dev->engine);
958
959list_del:
960 spin_lock(&ocs_ecc.lock);
961 list_del(&ecc_dev->list);
962 spin_unlock(&ocs_ecc.lock);
963
964 return rc;
965}
966
967static void kmb_ocs_ecc_remove(struct platform_device *pdev)
968{
969 struct ocs_ecc_dev *ecc_dev;
970
971 ecc_dev = platform_get_drvdata(pdev);
972
973 crypto_engine_unregister_kpp(&ocs_ecdh_p384);
974 crypto_engine_unregister_kpp(&ocs_ecdh_p256);
975
976 spin_lock(&ocs_ecc.lock);
977 list_del(&ecc_dev->list);
978 spin_unlock(&ocs_ecc.lock);
979
980 crypto_engine_exit(ecc_dev->engine);
981}
982
983/* Device tree driver match. */
984static const struct of_device_id kmb_ocs_ecc_of_match[] = {
985 {
986 .compatible = "intel,keembay-ocs-ecc",
987 },
988 {}
989};
990
991/* The OCS driver is a platform device. */
992static struct platform_driver kmb_ocs_ecc_driver = {
993 .probe = kmb_ocs_ecc_probe,
994 .remove_new = kmb_ocs_ecc_remove,
995 .driver = {
996 .name = DRV_NAME,
997 .of_match_table = kmb_ocs_ecc_of_match,
998 },
999};
1000module_platform_driver(kmb_ocs_ecc_driver);
1001
1002MODULE_LICENSE("GPL");
1003MODULE_DESCRIPTION("Intel Keem Bay OCS ECC Driver");
1004MODULE_ALIAS_CRYPTO("ecdh-nist-p256");
1005MODULE_ALIAS_CRYPTO("ecdh-nist-p384");
1006MODULE_ALIAS_CRYPTO("ecdh-nist-p256-keembay-ocs");
1007MODULE_ALIAS_CRYPTO("ecdh-nist-p384-keembay-ocs");