Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
cx_ecdh.c
Go to the documentation of this file.
1
2/*******************************************************************************
3 * Ledger Nano S - Secure firmware
4 * (c) 2022 Ledger
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 ********************************************************************************/
18
19#if defined(HAVE_ECDH) || defined(HAVE_X25519) || defined(HAVE_X448)
20
21#include "cx_ecfp.h"
22#include "cx_utils.h"
23#include "cx_ram.h"
24
25#include <string.h>
26
27#if defined(HAVE_ECDH)
28cx_err_t cx_ecdh_no_throw(const cx_ecfp_private_key_t *key,
29 uint32_t mode,
30 const uint8_t *public_point,
31 size_t P_len,
32 uint8_t *secret,
33 size_t secret_len)
34{
35 size_t sz;
36 cx_curve_t curve;
37 cx_err_t error;
38 cx_ecpoint_t W;
39
40 curve = key->curve;
41 CX_CHECK(cx_ecdomain_parameters_length(curve, &sz));
42
43 if (false
44#ifdef HAVE_ECC_WEIERSTRASS
45 || CX_CURVE_RANGE(curve, WEIERSTRASS)
46#endif
47#ifdef HAVE_ECC_MONTGOMERY
48 || CX_CURVE_RANGE(curve, MONTGOMERY)
49#endif
50 ) {
51 if (P_len != (1 + sz * 2)) {
52 error = CX_INVALID_PARAMETER;
53 goto end;
54 }
55 if (!(((mode & CX_MASK_EC) == CX_ECDH_X) || ((mode & CX_MASK_EC) == CX_ECDH_POINT))) {
56 error = CX_INVALID_PARAMETER;
57 goto end;
58 }
59 }
60 else {
61 error = INVALID_PARAMETER;
62 goto end;
63 }
64
65 switch (mode & CX_MASK_EC) {
66 case CX_ECDH_POINT:
67 if (secret_len < P_len) {
68 error = INVALID_PARAMETER;
69 goto end;
70 }
71 break;
72 case CX_ECDH_X:
73 if (secret_len < sz) {
74 error = INVALID_PARAMETER;
75 goto end;
76 }
77 break;
78 default:
79 error = INVALID_PARAMETER;
80 goto end;
81 break;
82 }
83
84 CX_CHECK(cx_bn_lock(sz, 0));
85 CX_CHECK(cx_ecpoint_alloc(&W, curve));
86 CX_CHECK(cx_ecpoint_init(&W, public_point + 1, sz, public_point + 1 + sz, sz));
87 // Scalar multiplication with random projective coordinates and additive splitting
88 if (CX_CURVE_RANGE(curve, WEIERSTRASS)) {
89 CX_CHECK(cx_ecpoint_rnd_fixed_scalarmul(&W, key->d, key->d_len));
90 }
91 else {
92 CX_CHECK(cx_ecpoint_rnd_scalarmul(&W, key->d, key->d_len));
93 }
94 switch (mode & CX_MASK_EC) {
95 case CX_ECDH_POINT:
96 secret[0] = 0x04;
97 CX_CHECK(cx_ecpoint_export(&W, secret + 1, sz, secret + 1 + sz, sz));
98 break;
99 case CX_ECDH_X:
100 CX_CHECK(cx_ecpoint_export(&W, secret, sz, NULL, 0));
101 break;
102 }
103
104end:
105 cx_bn_unlock();
106 return error;
107}
108
109#endif // HAVE_ECDH
110
111#if defined(HAVE_X25519)
112cx_err_t cx_x25519(uint8_t *u, const uint8_t *k, size_t k_len)
113{
114 cx_bn_t bn_u;
115 size_t domain_length;
116 cx_err_t error;
117
118 CX_CHECK(cx_ecdomain_parameters_length(CX_CURVE_Curve25519, &domain_length));
119 CX_CHECK(cx_bn_lock(domain_length, 0));
120 CX_CHECK(cx_bn_alloc(&bn_u, domain_length));
121 CX_CHECK(cx_bn_init(bn_u, u, domain_length));
122 CX_CHECK(cx_ecpoint_x25519(bn_u, k, k_len));
123 CX_CHECK(cx_bn_export(bn_u, u, domain_length));
124
125end:
126 cx_bn_unlock();
127 return error;
128}
129#endif // HAVE_X25519
130
131#if defined(HAVE_X448)
132cx_err_t cx_x448(uint8_t *u, const uint8_t *k, size_t k_len)
133{
134 cx_bn_t bn_u;
135 size_t domain_length;
136 cx_err_t error;
137
138 CX_CHECK(cx_ecdomain_parameters_length(CX_CURVE_Curve448, &domain_length));
139 CX_CHECK(cx_bn_lock(domain_length, 0));
140 CX_CHECK(cx_bn_alloc(&bn_u, domain_length));
141 CX_CHECK(cx_bn_init(bn_u, u, domain_length));
142 CX_CHECK(cx_ecpoint_x448(bn_u, k, k_len));
143 CX_CHECK(cx_bn_export(bn_u, u, domain_length));
144
145end:
146 cx_bn_unlock();
147 return error;
148}
149#endif // HAVE_X448
150
151#endif // HAVE_ECDH || HAVE_X25519 || HAVE_X448
#define CX_ECDH_X
Definition lcx_common.h:173
#define CX_ECDH_POINT
Definition lcx_common.h:172
#define CX_MASK_EC
Definition lcx_common.h:170
unsigned char uint8_t
Definition usbd_conf.h:53