1c2c877dbSJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2c2c877dbSJerome Forissier /*
3c2c877dbSJerome Forissier * Copyright (c) 2020 Huawei Technologies Co., Ltd
4c2c877dbSJerome Forissier */
5c2c877dbSJerome Forissier
6c2c877dbSJerome Forissier #include <crypto/crypto.h>
7*1e149c24SJerome Forissier #include <crypto/sm2-kdf.h>
8c2c877dbSJerome Forissier #include <stdlib.h>
9c2c877dbSJerome Forissier #include <string.h>
10c2c877dbSJerome Forissier #include <string_ext.h>
11c2c877dbSJerome Forissier #include <tee_api_types.h>
12c2c877dbSJerome Forissier #include <tee/tee_cryp_utl.h>
13c2c877dbSJerome Forissier #include <util.h>
14c2c877dbSJerome Forissier #include <utee_defines.h>
15c2c877dbSJerome Forissier
16c2c877dbSJerome Forissier #include "acipher_helpers.h"
17c2c877dbSJerome Forissier
18c2c877dbSJerome Forissier /* SM2 uses 256 bit unsigned integers in big endian format */
19c2c877dbSJerome Forissier #define SM2_INT_SIZE_BYTES 32
20c2c877dbSJerome Forissier
21c2c877dbSJerome Forissier /*
22c2c877dbSJerome Forissier * Compute a hash of a user's identity and public key
23c2c877dbSJerome Forissier * For user A: ZA = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA)
24c2c877dbSJerome Forissier */
sm2_kep_compute_Z(uint8_t * Z,size_t Zlen,const uint8_t * id,size_t idlen,const ecc_key * key)25c2c877dbSJerome Forissier static TEE_Result sm2_kep_compute_Z(uint8_t *Z, size_t Zlen, const uint8_t *id,
26c2c877dbSJerome Forissier size_t idlen, const ecc_key *key)
27c2c877dbSJerome Forissier {
28c2c877dbSJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
29c2c877dbSJerome Forissier uint8_t ENTLEN[2] = { };
30c2c877dbSJerome Forissier uint8_t buf[SM2_INT_SIZE_BYTES];
31c2c877dbSJerome Forissier void *ctx = NULL;
32c2c877dbSJerome Forissier
33c2c877dbSJerome Forissier if (Zlen < TEE_SM3_HASH_SIZE)
34c2c877dbSJerome Forissier return TEE_ERROR_SHORT_BUFFER;
35c2c877dbSJerome Forissier
36c2c877dbSJerome Forissier /*
37c2c877dbSJerome Forissier * ENTLEN is the length in bits if the user's distinguished identifier
38c2c877dbSJerome Forissier * encoded over 16 bits in big endian format.
39c2c877dbSJerome Forissier */
40c2c877dbSJerome Forissier ENTLEN[0] = (idlen * 8) >> 8;
41c2c877dbSJerome Forissier ENTLEN[1] = idlen * 8;
42c2c877dbSJerome Forissier
43c2c877dbSJerome Forissier res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
44c2c877dbSJerome Forissier if (res)
45c2c877dbSJerome Forissier goto out;
46c2c877dbSJerome Forissier
47c2c877dbSJerome Forissier res = crypto_hash_init(ctx);
48c2c877dbSJerome Forissier if (res)
49c2c877dbSJerome Forissier goto out;
50c2c877dbSJerome Forissier
51c2c877dbSJerome Forissier res = crypto_hash_update(ctx, ENTLEN, sizeof(ENTLEN));
52c2c877dbSJerome Forissier if (res)
53c2c877dbSJerome Forissier goto out;
54c2c877dbSJerome Forissier
55c2c877dbSJerome Forissier res = crypto_hash_update(ctx, id, idlen);
56c2c877dbSJerome Forissier if (res)
57c2c877dbSJerome Forissier goto out;
58c2c877dbSJerome Forissier
59c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->dp.A, buf, SM2_INT_SIZE_BYTES);
60c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
61c2c877dbSJerome Forissier if (res)
62c2c877dbSJerome Forissier goto out;
63c2c877dbSJerome Forissier
64c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->dp.B, buf, SM2_INT_SIZE_BYTES);
65c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
66c2c877dbSJerome Forissier if (res)
67c2c877dbSJerome Forissier goto out;
68c2c877dbSJerome Forissier
69c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->dp.base.x, buf, SM2_INT_SIZE_BYTES);
70c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
71c2c877dbSJerome Forissier if (res)
72c2c877dbSJerome Forissier goto out;
73c2c877dbSJerome Forissier
74c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->dp.base.y, buf, SM2_INT_SIZE_BYTES);
75c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
76c2c877dbSJerome Forissier if (res)
77c2c877dbSJerome Forissier goto out;
78c2c877dbSJerome Forissier
79c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->pubkey.x, buf, SM2_INT_SIZE_BYTES);
80c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
81c2c877dbSJerome Forissier if (res)
82c2c877dbSJerome Forissier goto out;
83c2c877dbSJerome Forissier
84c2c877dbSJerome Forissier mp_to_unsigned_bin2(key->pubkey.y, buf, SM2_INT_SIZE_BYTES);
85c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
86c2c877dbSJerome Forissier if (res)
87c2c877dbSJerome Forissier goto out;
88c2c877dbSJerome Forissier
89c2c877dbSJerome Forissier res = crypto_hash_final(ctx, Z, TEE_SM3_HASH_SIZE);
90c2c877dbSJerome Forissier out:
91c2c877dbSJerome Forissier crypto_hash_free_ctx(ctx);
92c2c877dbSJerome Forissier return res;
93c2c877dbSJerome Forissier }
94c2c877dbSJerome Forissier
95c2c877dbSJerome Forissier /*
96c2c877dbSJerome Forissier * Compute a verification value, to be checked against the value sent by the
97c2c877dbSJerome Forissier * peer.
98c2c877dbSJerome Forissier * On the initiator's side:
99c2c877dbSJerome Forissier * S1 = SM3(0x02 || yU || SM3(xU || ZA || ZB || x1 || y1 || x2 || y2))
100c2c877dbSJerome Forissier * On the responder's side:
101c2c877dbSJerome Forissier * S2 = SM3(0x03 || yV || SM3(xV || ZA || ZB || x1 || y1 || x2 || y2))
102c2c877dbSJerome Forissier */
sm2_kep_compute_S(uint8_t * S,size_t S_len,uint8_t flag,ecc_point * UV,const uint8_t * ZAZB,size_t ZAZB_len,ecc_key * initiator_eph_key,ecc_key * responder_eph_key)103c2c877dbSJerome Forissier static TEE_Result sm2_kep_compute_S(uint8_t *S, size_t S_len, uint8_t flag,
104c2c877dbSJerome Forissier ecc_point *UV, const uint8_t *ZAZB,
105c2c877dbSJerome Forissier size_t ZAZB_len, ecc_key *initiator_eph_key,
106c2c877dbSJerome Forissier ecc_key *responder_eph_key)
107c2c877dbSJerome Forissier {
108c2c877dbSJerome Forissier uint8_t hash[TEE_SM3_HASH_SIZE] = { };
109c2c877dbSJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
110c2c877dbSJerome Forissier uint8_t buf[SM2_INT_SIZE_BYTES];
111c2c877dbSJerome Forissier void *ctx = NULL;
112c2c877dbSJerome Forissier
113c2c877dbSJerome Forissier if (S_len < TEE_SM3_HASH_SIZE)
114c2c877dbSJerome Forissier return TEE_ERROR_SHORT_BUFFER;
115c2c877dbSJerome Forissier
116c2c877dbSJerome Forissier res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
117c2c877dbSJerome Forissier if (res)
118c2c877dbSJerome Forissier goto out;
119c2c877dbSJerome Forissier
120c2c877dbSJerome Forissier /* Compute the inner hash */
121c2c877dbSJerome Forissier
122c2c877dbSJerome Forissier res = crypto_hash_init(ctx);
123c2c877dbSJerome Forissier if (res)
124c2c877dbSJerome Forissier goto out;
125c2c877dbSJerome Forissier
126c2c877dbSJerome Forissier /* xU or xV */
127c2c877dbSJerome Forissier mp_to_unsigned_bin2(UV->x, buf, SM2_INT_SIZE_BYTES);
128c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
129c2c877dbSJerome Forissier if (res)
130c2c877dbSJerome Forissier goto out;
131c2c877dbSJerome Forissier
132c2c877dbSJerome Forissier /* ZA || ZB */
133c2c877dbSJerome Forissier res = crypto_hash_update(ctx, ZAZB, ZAZB_len);
134c2c877dbSJerome Forissier if (res)
135c2c877dbSJerome Forissier goto out;
136c2c877dbSJerome Forissier
137c2c877dbSJerome Forissier /* x1 */
138c2c877dbSJerome Forissier mp_to_unsigned_bin2(initiator_eph_key->pubkey.x, buf,
139c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES);
140c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
141c2c877dbSJerome Forissier if (res)
142c2c877dbSJerome Forissier goto out;
143c2c877dbSJerome Forissier
144c2c877dbSJerome Forissier /* y1 */
145c2c877dbSJerome Forissier mp_to_unsigned_bin2(initiator_eph_key->pubkey.y, buf,
146c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES);
147c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
148c2c877dbSJerome Forissier if (res)
149c2c877dbSJerome Forissier goto out;
150c2c877dbSJerome Forissier
151c2c877dbSJerome Forissier /* x2 */
152c2c877dbSJerome Forissier mp_to_unsigned_bin2(responder_eph_key->pubkey.x, buf,
153c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES);
154c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
155c2c877dbSJerome Forissier if (res)
156c2c877dbSJerome Forissier goto out;
157c2c877dbSJerome Forissier
158c2c877dbSJerome Forissier /* y2 */
159c2c877dbSJerome Forissier mp_to_unsigned_bin2(responder_eph_key->pubkey.y, buf,
160c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES);
161c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
162c2c877dbSJerome Forissier if (res)
163c2c877dbSJerome Forissier goto out;
164c2c877dbSJerome Forissier
165c2c877dbSJerome Forissier res = crypto_hash_final(ctx, hash, sizeof(hash));
166c2c877dbSJerome Forissier if (res)
167c2c877dbSJerome Forissier goto out;
168c2c877dbSJerome Forissier
169c2c877dbSJerome Forissier /* Now compute S */
170c2c877dbSJerome Forissier
171c2c877dbSJerome Forissier res = crypto_hash_init(ctx);
172c2c877dbSJerome Forissier if (res)
173c2c877dbSJerome Forissier goto out;
174c2c877dbSJerome Forissier
175c2c877dbSJerome Forissier /* 0x02 or 0x03 */
176c2c877dbSJerome Forissier res = crypto_hash_update(ctx, &flag, sizeof(flag));
177c2c877dbSJerome Forissier if (res)
178c2c877dbSJerome Forissier goto out;
179c2c877dbSJerome Forissier
180c2c877dbSJerome Forissier /* yU or yV */
181c2c877dbSJerome Forissier mp_to_unsigned_bin2(UV->y, buf, SM2_INT_SIZE_BYTES);
182c2c877dbSJerome Forissier res = crypto_hash_update(ctx, buf, sizeof(buf));
183c2c877dbSJerome Forissier if (res)
184c2c877dbSJerome Forissier goto out;
185c2c877dbSJerome Forissier
186c2c877dbSJerome Forissier /* Inner SM3(...) */
187c2c877dbSJerome Forissier res = crypto_hash_update(ctx, hash, sizeof(hash));
188c2c877dbSJerome Forissier if (res)
189c2c877dbSJerome Forissier goto out;
190c2c877dbSJerome Forissier
191c2c877dbSJerome Forissier res = crypto_hash_final(ctx, S, TEE_SM3_HASH_SIZE);
192c2c877dbSJerome Forissier
193c2c877dbSJerome Forissier out:
194c2c877dbSJerome Forissier crypto_hash_free_ctx(ctx);
195c2c877dbSJerome Forissier return res;
196c2c877dbSJerome Forissier
197c2c877dbSJerome Forissier }
198c2c877dbSJerome Forissier
199c2c877dbSJerome Forissier /*
200c2c877dbSJerome Forissier * GM/T 0003.1‒2012 Part 3 Section 6.1
201c2c877dbSJerome Forissier * Key exchange protocol
202c2c877dbSJerome Forissier */
sm2_kep_derive(ecc_key * my_key,ecc_key * my_eph_key,ecc_key * peer_key,ecc_key * peer_eph_key,struct sm2_kep_parms * p)203c2c877dbSJerome Forissier static TEE_Result sm2_kep_derive(ecc_key *my_key, ecc_key *my_eph_key,
204c2c877dbSJerome Forissier ecc_key *peer_key, ecc_key *peer_eph_key,
205c2c877dbSJerome Forissier struct sm2_kep_parms *p)
206c2c877dbSJerome Forissier {
207c2c877dbSJerome Forissier /*
208c2c877dbSJerome Forissier * Variable names and documented steps reflect the initator side (user A
209c2c877dbSJerome Forissier * in the spec), but the other side is quite similar hence only one
210c2c877dbSJerome Forissier * function.
211c2c877dbSJerome Forissier */
212c2c877dbSJerome Forissier uint8_t xUyUZAZB[2 * SM2_INT_SIZE_BYTES + 2 * TEE_SM3_HASH_SIZE] = { };
213c2c877dbSJerome Forissier ecc_key *initiator_eph_key = p->is_initiator ? my_eph_key :
214c2c877dbSJerome Forissier peer_eph_key;
215c2c877dbSJerome Forissier ecc_key *responder_eph_key = p->is_initiator ? peer_eph_key :
216c2c877dbSJerome Forissier my_eph_key;
217c2c877dbSJerome Forissier ecc_key *initiator_key = p->is_initiator ? my_key : peer_key;
218c2c877dbSJerome Forissier ecc_key *responder_key = p->is_initiator ? peer_key : my_key;
219c2c877dbSJerome Forissier TEE_Result res = TEE_ERROR_BAD_STATE;
220c2c877dbSJerome Forissier uint8_t tmp[SM2_INT_SIZE_BYTES];
221c2c877dbSJerome Forissier void *n = my_key->dp.order;
222c2c877dbSJerome Forissier ecc_point *U = NULL;
223c2c877dbSJerome Forissier void *x1bar = NULL;
224c2c877dbSJerome Forissier void *x2bar = NULL;
225c2c877dbSJerome Forissier void *tA = NULL;
226c2c877dbSJerome Forissier void *h = NULL;
227c2c877dbSJerome Forissier void *htA = NULL;
228c2c877dbSJerome Forissier void *mp = NULL;
229c2c877dbSJerome Forissier void *mu = NULL;
230c2c877dbSJerome Forissier void *ma = NULL;
231c2c877dbSJerome Forissier void *one = NULL;
232c2c877dbSJerome Forissier int ltc_res = 0;
233c2c877dbSJerome Forissier int inf = 0;
234c2c877dbSJerome Forissier
235c2c877dbSJerome Forissier ltc_res = mp_init_multi(&x1bar, &x2bar, &tA, &h, &htA, &mu, &ma, &one,
236c2c877dbSJerome Forissier NULL);
237c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK) {
238c2c877dbSJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY;
239c2c877dbSJerome Forissier goto out;
240c2c877dbSJerome Forissier }
241c2c877dbSJerome Forissier
242c2c877dbSJerome Forissier U = ltc_ecc_new_point();
243c2c877dbSJerome Forissier if (!U) {
244c2c877dbSJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY;
245c2c877dbSJerome Forissier goto out;
246c2c877dbSJerome Forissier }
247c2c877dbSJerome Forissier
248c2c877dbSJerome Forissier /*
249c2c877dbSJerome Forissier * Steps A1-A3 are supposedly done already (generate ephemeral key, send
250c2c877dbSJerome Forissier * it to peer).
251c2c877dbSJerome Forissier * Step A4: (x1, y1) = RA; x1bar = 2^w + (x1 & (2^w - 1))
252c2c877dbSJerome Forissier */
253c2c877dbSJerome Forissier
254c2c877dbSJerome Forissier mp_to_unsigned_bin2(my_eph_key->pubkey.x, tmp, SM2_INT_SIZE_BYTES);
255c2c877dbSJerome Forissier tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80;
256c2c877dbSJerome Forissier mp_read_unsigned_bin(x1bar, tmp + SM2_INT_SIZE_BYTES / 2,
257c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES / 2);
258c2c877dbSJerome Forissier
259c2c877dbSJerome Forissier /* Step A5: tA = (dA + x1bar * rA) mod n */
260c2c877dbSJerome Forissier
261c2c877dbSJerome Forissier ltc_res = mp_mulmod(x1bar, my_eph_key->k, n, tA);
262c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
263c2c877dbSJerome Forissier goto out;
264c2c877dbSJerome Forissier
265c2c877dbSJerome Forissier ltc_res = mp_addmod(tA, my_key->k, n, tA);
266c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
267c2c877dbSJerome Forissier goto out;
268c2c877dbSJerome Forissier
269c2c877dbSJerome Forissier /* Step A6: verify whether RB verifies the curve equation */
270c2c877dbSJerome Forissier
271c2c877dbSJerome Forissier ltc_res = ltc_ecc_is_point(&peer_eph_key->dp, peer_eph_key->pubkey.x,
272c2c877dbSJerome Forissier peer_eph_key->pubkey.y);
273c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
274c2c877dbSJerome Forissier goto out;
275c2c877dbSJerome Forissier
276c2c877dbSJerome Forissier /* Step A6 (continued): (x2, y2) = RB; x2bar = 2^w + (x2 & (2^w - 1)) */
277c2c877dbSJerome Forissier
278c2c877dbSJerome Forissier mp_to_unsigned_bin2(peer_eph_key->pubkey.x, tmp, SM2_INT_SIZE_BYTES);
279c2c877dbSJerome Forissier tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80;
280c2c877dbSJerome Forissier mp_read_unsigned_bin(x2bar, tmp + SM2_INT_SIZE_BYTES / 2,
281c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES / 2);
282c2c877dbSJerome Forissier
283c2c877dbSJerome Forissier
284c2c877dbSJerome Forissier /* Step A7: compute U = [h.tA](PB + [x2bar]RB) and check for infinity */
285c2c877dbSJerome Forissier
286c2c877dbSJerome Forissier ltc_res = mp_montgomery_setup(peer_key->dp.prime, &mp);
287c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
288c2c877dbSJerome Forissier goto out;
289c2c877dbSJerome Forissier
290c2c877dbSJerome Forissier ltc_res = mp_montgomery_normalization(mu, peer_key->dp.prime);
291c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
292c2c877dbSJerome Forissier goto out;
293c2c877dbSJerome Forissier
294c2c877dbSJerome Forissier ltc_res = mp_mulmod(peer_key->dp.A, mu, peer_key->dp.prime, ma);
295c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
296c2c877dbSJerome Forissier goto out;
297c2c877dbSJerome Forissier
298c2c877dbSJerome Forissier ltc_res = mp_set_int(one, 1);
299c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
300c2c877dbSJerome Forissier goto out;
301c2c877dbSJerome Forissier
302c2c877dbSJerome Forissier ltc_res = ltc_ecc_mul2add(&peer_key->pubkey, one, &peer_eph_key->pubkey,
303c2c877dbSJerome Forissier x2bar, U, ma, peer_key->dp.prime);
304c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
305c2c877dbSJerome Forissier goto out;
306c2c877dbSJerome Forissier
307c2c877dbSJerome Forissier ltc_res = mp_set_int(h, peer_key->dp.cofactor);
308c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
309c2c877dbSJerome Forissier goto out;
310c2c877dbSJerome Forissier
311c2c877dbSJerome Forissier ltc_res = mp_mul(h, tA, htA);
312c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
313c2c877dbSJerome Forissier goto out;
314c2c877dbSJerome Forissier
315c2c877dbSJerome Forissier ltc_res = ltc_ecc_mulmod(htA, U, U, peer_key->dp.A, peer_key->dp.prime,
316c2c877dbSJerome Forissier 1);
317c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
318c2c877dbSJerome Forissier goto out;
319c2c877dbSJerome Forissier
320c2c877dbSJerome Forissier ltc_res = ltc_ecc_is_point_at_infinity(U, peer_key->dp.prime, &inf);
321c2c877dbSJerome Forissier if (ltc_res != CRYPT_OK)
322c2c877dbSJerome Forissier goto out;
323c2c877dbSJerome Forissier
324c2c877dbSJerome Forissier if (inf)
325c2c877dbSJerome Forissier goto out;
326c2c877dbSJerome Forissier
327c2c877dbSJerome Forissier /* Step A8: compute KA = KDF(xU || yU || ZA || ZB, klen) */
328c2c877dbSJerome Forissier
329c2c877dbSJerome Forissier /* xU */
330c2c877dbSJerome Forissier mp_to_unsigned_bin2(U->x, xUyUZAZB, SM2_INT_SIZE_BYTES);
331c2c877dbSJerome Forissier
332c2c877dbSJerome Forissier /* yU */
333c2c877dbSJerome Forissier mp_to_unsigned_bin2(U->y, xUyUZAZB + SM2_INT_SIZE_BYTES,
334c2c877dbSJerome Forissier SM2_INT_SIZE_BYTES);
335c2c877dbSJerome Forissier
336c2c877dbSJerome Forissier /* ZA */
337c2c877dbSJerome Forissier res = sm2_kep_compute_Z(xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
338c2c877dbSJerome Forissier TEE_SM3_HASH_SIZE, p->initiator_id,
339c2c877dbSJerome Forissier p->initiator_id_len, initiator_key);
340c2c877dbSJerome Forissier if (res)
341c2c877dbSJerome Forissier goto out;
342c2c877dbSJerome Forissier
343c2c877dbSJerome Forissier /* ZB */
344c2c877dbSJerome Forissier res = sm2_kep_compute_Z(xUyUZAZB + 2 * SM2_INT_SIZE_BYTES +
345c2c877dbSJerome Forissier TEE_SM3_HASH_SIZE,
346c2c877dbSJerome Forissier TEE_SM3_HASH_SIZE, p->responder_id,
347c2c877dbSJerome Forissier p->responder_id_len, responder_key);
348c2c877dbSJerome Forissier if (res)
349c2c877dbSJerome Forissier goto out;
350c2c877dbSJerome Forissier
351c2c877dbSJerome Forissier res = sm2_kdf(xUyUZAZB, sizeof(xUyUZAZB), p->out, p->out_len);
352c2c877dbSJerome Forissier if (res)
353c2c877dbSJerome Forissier goto out;
354c2c877dbSJerome Forissier
355c2c877dbSJerome Forissier /* Step A9: compute S1 and check S1 == SB */
356c2c877dbSJerome Forissier
357c2c877dbSJerome Forissier if (p->conf_in) {
358c2c877dbSJerome Forissier uint8_t S1[TEE_SM3_HASH_SIZE];
359c2c877dbSJerome Forissier uint8_t flag = p->is_initiator ? 0x02 : 0x03;
360c2c877dbSJerome Forissier
361c2c877dbSJerome Forissier if (p->conf_in_len < TEE_SM3_HASH_SIZE) {
362c2c877dbSJerome Forissier res = TEE_ERROR_BAD_PARAMETERS;
363c2c877dbSJerome Forissier goto out;
364c2c877dbSJerome Forissier }
365c2c877dbSJerome Forissier res = sm2_kep_compute_S(S1, sizeof(S1), flag, U,
366c2c877dbSJerome Forissier xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
367c2c877dbSJerome Forissier 2 * SM2_INT_SIZE_BYTES,
368c2c877dbSJerome Forissier initiator_eph_key, responder_eph_key);
369c2c877dbSJerome Forissier if (res)
370c2c877dbSJerome Forissier goto out;
371c2c877dbSJerome Forissier
372c2c877dbSJerome Forissier if (consttime_memcmp(S1, p->conf_in, sizeof(S1))) {
373c2c877dbSJerome Forissier /* Verification failed */
374c2c877dbSJerome Forissier res = TEE_ERROR_BAD_STATE;
375c2c877dbSJerome Forissier goto out;
376c2c877dbSJerome Forissier }
377c2c877dbSJerome Forissier }
378c2c877dbSJerome Forissier
379c2c877dbSJerome Forissier /* Step A10: compute SA */
380c2c877dbSJerome Forissier
381c2c877dbSJerome Forissier if (p->conf_out) {
382c2c877dbSJerome Forissier uint8_t flag = p->is_initiator ? 0x03 : 0x02;
383c2c877dbSJerome Forissier
384c2c877dbSJerome Forissier if (p->conf_out_len < TEE_SM3_HASH_SIZE) {
385c2c877dbSJerome Forissier res = TEE_ERROR_BAD_PARAMETERS;
386c2c877dbSJerome Forissier goto out;
387c2c877dbSJerome Forissier }
388c2c877dbSJerome Forissier
389c2c877dbSJerome Forissier res = sm2_kep_compute_S(p->conf_out, TEE_SM3_HASH_SIZE, flag, U,
390c2c877dbSJerome Forissier xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
391c2c877dbSJerome Forissier 2 * SM2_INT_SIZE_BYTES,
392c2c877dbSJerome Forissier initiator_eph_key, responder_eph_key);
393c2c877dbSJerome Forissier if (res)
394c2c877dbSJerome Forissier goto out;
395c2c877dbSJerome Forissier }
396c2c877dbSJerome Forissier out:
397c2c877dbSJerome Forissier mp_montgomery_free(mp);
398c2c877dbSJerome Forissier ltc_ecc_del_point(U);
399c2c877dbSJerome Forissier mp_clear_multi(x1bar, x2bar, tA, h, htA, mu, ma, one, NULL);
400c2c877dbSJerome Forissier return res;
401c2c877dbSJerome Forissier }
402c2c877dbSJerome Forissier
crypto_acipher_sm2_kep_derive(struct ecc_keypair * my_key,struct ecc_keypair * my_eph_key,struct ecc_public_key * peer_key,struct ecc_public_key * peer_eph_key,struct sm2_kep_parms * p)403c2c877dbSJerome Forissier TEE_Result crypto_acipher_sm2_kep_derive(struct ecc_keypair *my_key,
404c2c877dbSJerome Forissier struct ecc_keypair *my_eph_key,
405c2c877dbSJerome Forissier struct ecc_public_key *peer_key,
406c2c877dbSJerome Forissier struct ecc_public_key *peer_eph_key,
407c2c877dbSJerome Forissier struct sm2_kep_parms *p)
408c2c877dbSJerome Forissier {
409c2c877dbSJerome Forissier TEE_Result res = TEE_SUCCESS;
410c2c877dbSJerome Forissier ecc_key ltc_my_key = { };
411c2c877dbSJerome Forissier ecc_key ltc_my_eph_key = { };
412c2c877dbSJerome Forissier ecc_key ltc_peer_key = { };
413c2c877dbSJerome Forissier ecc_key ltc_peer_eph_key = { };
414c2c877dbSJerome Forissier
415c2c877dbSJerome Forissier res = ecc_populate_ltc_private_key(<c_my_key, my_key,
416c2c877dbSJerome Forissier TEE_ALG_SM2_KEP, NULL);
417c2c877dbSJerome Forissier if (res)
418c2c877dbSJerome Forissier goto out;
419c2c877dbSJerome Forissier
420c2c877dbSJerome Forissier res = ecc_populate_ltc_private_key(<c_my_eph_key, my_eph_key,
421c2c877dbSJerome Forissier TEE_ALG_SM2_KEP, NULL);
422c2c877dbSJerome Forissier if (res)
423c2c877dbSJerome Forissier goto out;
424c2c877dbSJerome Forissier
425c2c877dbSJerome Forissier res = ecc_populate_ltc_public_key(<c_peer_key, peer_key,
426c2c877dbSJerome Forissier TEE_ALG_SM2_KEP, NULL);
427c2c877dbSJerome Forissier if (res)
428c2c877dbSJerome Forissier goto out;
429c2c877dbSJerome Forissier
430c2c877dbSJerome Forissier res = ecc_populate_ltc_public_key(<c_peer_eph_key, peer_eph_key,
431c2c877dbSJerome Forissier TEE_ALG_SM2_KEP, NULL);
432c2c877dbSJerome Forissier if (res)
433c2c877dbSJerome Forissier goto out;
434c2c877dbSJerome Forissier
435c2c877dbSJerome Forissier res = sm2_kep_derive(<c_my_key, <c_my_eph_key, <c_peer_key,
436c2c877dbSJerome Forissier <c_peer_eph_key, p);
437c2c877dbSJerome Forissier out:
438c2c877dbSJerome Forissier ecc_free(<c_peer_eph_key);
439c2c877dbSJerome Forissier ecc_free(<c_peer_key);
440c2c877dbSJerome Forissier ecc_free(<c_my_eph_key);
441c2c877dbSJerome Forissier ecc_free(<c_my_key);
442c2c877dbSJerome Forissier return res;
443c2c877dbSJerome Forissier }
444