1 /*
2 * Copyright (c) 2024, The TrustedFirmware-M Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8
9 #include "cc3xx_ecdh.h"
10
11 #include "cc3xx_ec.h"
12 #include "cc3xx_config.h"
13
14 #include <stdint.h>
15 #include <stddef.h>
16
17 #ifdef CC3XX_CONFIG_ECDH_ENABLE
cc3xx_lowlevel_ecdh(cc3xx_ec_curve_id_t curve_id,const uint32_t * private_key,size_t private_key_len,const uint32_t * public_key_x,size_t public_key_x_len,const uint32_t * public_key_y,size_t public_key_y_len,uint32_t * shared_secret,size_t shared_secret_len,size_t * shared_secret_size)18 cc3xx_err_t cc3xx_lowlevel_ecdh(cc3xx_ec_curve_id_t curve_id,
19 const uint32_t *private_key, size_t private_key_len,
20 const uint32_t *public_key_x, size_t public_key_x_len,
21 const uint32_t *public_key_y, size_t public_key_y_len,
22 uint32_t *shared_secret, size_t shared_secret_len,
23 size_t *shared_secret_size)
24 {
25 cc3xx_ec_curve_t curve;
26 cc3xx_pka_reg_id_t private_key_reg;
27 cc3xx_ec_point_affine shared_key_point, public_key_point;
28 cc3xx_err_t err;
29
30 /* This sets up various curve parameters into PKA registers */
31 err = cc3xx_lowlevel_ec_init(curve_id, &curve);
32 if (err != CC3XX_ERR_SUCCESS) {
33 goto out;
34 }
35
36 if (private_key_len > curve.modulus_size) {
37 err = CC3XX_ERR_ECDSA_INVALID_KEY;
38 goto out;
39 }
40
41 if (public_key_x_len > curve.modulus_size) {
42 err = CC3XX_ERR_ECDSA_INVALID_KEY;
43 goto out;
44 }
45
46 if (public_key_y_len > curve.modulus_size) {
47 err = CC3XX_ERR_ECDSA_INVALID_KEY;
48 goto out;
49 }
50
51 if (shared_secret_len < curve.modulus_size) {
52 err = CC3XX_ERR_BUFFER_OVERFLOW;
53 goto out;
54 }
55
56 shared_key_point = cc3xx_lowlevel_ec_allocate_point();
57 public_key_point = cc3xx_lowlevel_ec_allocate_point();
58 private_key_reg = cc3xx_lowlevel_pka_allocate_reg();
59
60 cc3xx_lowlevel_pka_write_reg_swap_endian(private_key_reg, private_key, private_key_len);
61 cc3xx_lowlevel_pka_write_reg_swap_endian(public_key_point.x, public_key_x, curve.modulus_size);
62 cc3xx_lowlevel_pka_write_reg_swap_endian(public_key_point.y, public_key_y, curve.modulus_size);
63
64 err = cc3xx_lowlevel_ec_multipy_point_by_scalar(&curve, &public_key_point, private_key_reg,
65 &shared_key_point);
66
67 /* SEC1 paragraph 3.3.1: Output the x coordinate only as the shared secret */
68 cc3xx_lowlevel_pka_read_reg_swap_endian(shared_key_point.x, shared_secret, curve.modulus_size);
69 *shared_secret_size = curve.modulus_size;
70
71 out:
72 cc3xx_lowlevel_ec_uninit();
73
74 return err;
75 }
76 #endif /* CC3XX_CONFIG_ECDH_ENABLE */
77