1 /*
2    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3    file at the top-level directory of this distribution.
4 
5    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8    option. This file may not be copied, modified, or distributed
9    except according to those terms.
10 */
11 #include <string.h>
12 
13 #include "edhoc.h"
14 
15 #include "common/crypto_wrapper.h"
16 #include "common/byte_array.h"
17 #include "common/oscore_edhoc_error.h"
18 #include "common/print_util.h"
19 #include "common/memcpy_s.h"
20 
21 #include "edhoc/suites.h"
22 
23 //#define MBEDTLS
24 
25 #ifdef MBEDTLS
26 /*
27 IMPORTANT!!!!
28 make sure MBEDTLS_PSA_CRYPTO_CONFIG is defined in include/mbedtls/mbedtls_config.h
29 
30 
31 modify setting in include/psa/crypto_config.h
32 */
33 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
34 
35 #include <psa/crypto.h>
36 
37 #include "mbedtls/ecp.h"
38 #include "mbedtls/platform.h"
39 #include "mbedtls/entropy.h"
40 #include "mbedtls/ctr_drbg.h"
41 #include "mbedtls/ecdsa.h"
42 #include "mbedtls/error.h"
43 #include "mbedtls/rsa.h"
44 #include "mbedtls/x509.h"
45 
46 #endif
47 
48 #ifdef COMPACT25519
49 #include <c25519.h>
50 #include <edsign.h>
51 #include <compact_x25519.h>
52 #endif
53 
54 #ifdef TINYCRYPT
55 #include <tinycrypt/aes.h>
56 #include <tinycrypt/ccm_mode.h>
57 #include <tinycrypt/constants.h>
58 #include <tinycrypt/hmac.h>
59 #include <tinycrypt/ecc_dsa.h>
60 #include <tinycrypt/ecc_dh.h>
61 #endif
62 
63 
64 #ifdef MBEDTLS
65 #define TRY_EXPECT_PSA(x, expected_result, key_id, err_code)                \
66 	do {                                                                    \
67 		int retval = (int)(x);                                              \
68 		if ((expected_result) != retval) {                                  \
69 			if(PSA_KEY_HANDLE_INIT != (key_id)) {                           \
70 				psa_destroy_key(key_id);                                    \
71 			}                                                               \
72 			PRINTF(RED                                                      \
73 			       "Runtime error: %s error code %d at %s:%d\n\n" RESET,    \
74 			       #x, retval, __FILE__, __LINE__);                         \
75 			return err_code;                                                \
76 		}                                                                   \
77 	} while (0)
78 
79 /**
80  * @brief Decompresses an elliptic curve point.
81  *
82  *
83  * @param grp elliptic curve group point
84  * @param input the compressed key
85  * @param ilen the lenhgt if the compressed key
86  * @param output the uncopressed key
87  * @param olen the lenhgt of the output
88  * @param osize the actual available size of the out buffer
89  * @return 0 on success
90  */
mbedtls_ecp_decompress(const mbedtls_ecp_group * grp,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize)91 static inline int mbedtls_ecp_decompress(const mbedtls_ecp_group *grp,
92 					 const unsigned char *input,
93 					 size_t ilen, unsigned char *output,
94 					 size_t *olen, size_t osize)
95 {
96 	int ret;
97 	size_t plen;
98 	mbedtls_mpi r;
99 	mbedtls_mpi x;
100 	mbedtls_mpi n;
101 
102 	plen = mbedtls_mpi_size(&grp->P);
103 
104 	*olen = 2 * plen + 1;
105 
106 	if (osize < *olen)
107 		return (MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
108 
109 	if (ilen != plen + 1)
110 		return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
111 
112 	if (input[0] != 0x02 && input[0] != 0x03)
113 		return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
114 
115 	// output will consist of 0x04|X|Y
116 	memcpy(output, input, ilen);
117 	output[0] = 0x04;
118 
119 	mbedtls_mpi_init(&r);
120 	mbedtls_mpi_init(&x);
121 	mbedtls_mpi_init(&n);
122 
123 	// x <= input
124 	MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&x, input + 1, plen));
125 
126 	// r = x^2
127 	MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &x, &x));
128 
129 	// r = x^2 + a
130 	if (grp->A.p == NULL) {
131 		// Special case where a is -3
132 		MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&r, &r, 3));
133 	} else {
134 		MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->A));
135 	}
136 
137 	// r = x^3 + ax
138 	MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&r, &r, &x));
139 
140 	// r = x^3 + ax + b
141 	MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&r, &r, &grp->B));
142 
143 	// Calculate square root of r over finite field P:
144 	//   r = sqrt(x^3 + ax + b) = (x^3 + ax + b) ^ ((P + 1) / 4) (mod P)
145 
146 	// n = P + 1
147 	MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&n, &grp->P, 1));
148 
149 	// n = (P + 1) / 4
150 	MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&n, 2));
151 
152 	// r ^ ((P + 1) / 4) (mod p)
153 	MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r, &r, &n, &grp->P, NULL));
154 
155 	// Select solution that has the correct "sign" (equals odd/even solution in finite group)
156 	if ((input[0] == 0x03) != mbedtls_mpi_get_bit(&r, 0)) {
157 		// r = p - r
158 		MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&r, &grp->P, &r));
159 	}
160 
161 	// y => output
162 	ret = mbedtls_mpi_write_binary(&r, output + 1 + plen, plen);
163 
164 cleanup:
165 	mbedtls_mpi_free(&r);
166 	mbedtls_mpi_free(&x);
167 	mbedtls_mpi_free(&n);
168 
169 	return (ret);
170 }
171 
172 #endif
173 
174 enum err __attribute__((weak))
aead(enum aes_operation op,const uint8_t * in,const uint32_t in_len,const uint8_t * key,const uint32_t key_len,uint8_t * nonce,const uint32_t nonce_len,const uint8_t * aad,const uint32_t aad_len,uint8_t * out,const uint32_t out_len,uint8_t * tag,const uint32_t tag_len)175 aead(enum aes_operation op, const uint8_t *in, const uint32_t in_len,
176      const uint8_t *key, const uint32_t key_len, uint8_t *nonce,
177      const uint32_t nonce_len, const uint8_t *aad, const uint32_t aad_len,
178      uint8_t *out, const uint32_t out_len, uint8_t *tag, const uint32_t tag_len)
179 {
180 #ifdef TINYCRYPT
181 	struct tc_ccm_mode_struct c;
182 	struct tc_aes_key_sched_struct sched;
183 	TRY_EXPECT(tc_aes128_set_encrypt_key(&sched, key), 1);
184 	TRY_EXPECT(tc_ccm_config(&c, &sched, nonce, nonce_len, tag_len), 1);
185 
186 	if (op == DECRYPT) {
187 		TRY_EXPECT(tc_ccm_decryption_verification(
188 				   out, out_len, aad, aad_len, in, in_len, &c),
189 			   1);
190 
191 	} else {
192 		TRY_EXPECT(tc_ccm_generation_encryption(
193 				   out, (out_len + tag_len), aad, aad_len, in,
194 				   in_len, &c),
195 			   1);
196 		memcpy(tag, out + out_len, tag_len);
197 	}
198 #endif
199 #ifdef MBEDTLS
200 	psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
201 
202 	TRY_EXPECT_PSA(psa_crypto_init(),
203 				   PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
204 
205 	psa_algorithm_t alg =
206 		PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, (uint32_t)tag_len);
207 
208 	psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
209 	psa_set_key_usage_flags(&attr,
210 				PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT);
211 	psa_set_key_algorithm(&attr, alg);
212 	psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
213 	psa_set_key_bits(&attr, ((size_t)key_len << 3));
214 	psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
215 	TRY_EXPECT_PSA(psa_import_key(&attr, key, key_len, &key_id),
216 				   PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
217 
218 	if (op == DECRYPT) {
219 		size_t out_len_re = 0;
220 		TRY_EXPECT_PSA(psa_aead_decrypt(key_id, alg, nonce, nonce_len, aad,
221 					    aad_len, in, in_len, out, out_len,
222 					    &out_len_re),
223 						PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
224 	} else {
225 		size_t out_len_re;
226 		TRY_EXPECT_PSA(psa_aead_encrypt(key_id, alg, nonce, nonce_len, aad,
227 					    aad_len, in, in_len, out,
228 					    (size_t)(in_len + tag_len),
229 					    &out_len_re),
230 						PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
231 		memcpy(tag, out + out_len_re - tag_len, tag_len);
232 	}
233 	TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
234 
235 #endif
236 	return ok;
237 }
238 
239 enum err __attribute__((weak))
sign(enum sign_alg alg,const uint8_t * sk,const uint32_t sk_len,const uint8_t * pk,const uint8_t * msg,const uint32_t msg_len,uint8_t * out)240 sign(enum sign_alg alg, const uint8_t *sk, const uint32_t sk_len,
241      const uint8_t *pk, const uint8_t *msg, const uint32_t msg_len,
242      uint8_t *out)
243 {
244 	if (alg == EdDSA) {
245 #if defined(COMPACT25519)
246 		edsign_sign(out, pk, sk, msg, msg_len);
247 		return ok;
248 #endif
249 	} else if (alg == ES256) {
250 #if defined(MBEDTLS)
251 		psa_algorithm_t psa_alg;
252 		size_t bits;
253 		psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
254 
255 		psa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
256 		bits = PSA_BYTES_TO_BITS((size_t)sk_len);
257 
258 		TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
259 
260 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
261 		psa_set_key_usage_flags(&attributes,
262 						PSA_KEY_USAGE_VERIFY_MESSAGE |
263 						PSA_KEY_USAGE_VERIFY_HASH |
264 						PSA_KEY_USAGE_SIGN_MESSAGE |
265 						PSA_KEY_USAGE_SIGN_HASH);
266 		psa_set_key_algorithm(&attributes, psa_alg);
267 		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(
268 						      PSA_ECC_FAMILY_SECP_R1));
269 		psa_set_key_bits(&attributes, bits);
270 		psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
271 
272 		TRY_EXPECT_PSA(psa_import_key(&attributes, sk, sk_len, &key_id),
273 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
274 
275 		size_t signature_length;
276 		TRY_EXPECT_PSA(psa_sign_message(key_id, psa_alg, msg, msg_len, out,
277 						SIGNATURE_DEFAULT_SIZE,
278 					    &signature_length),
279 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
280 
281 		TRY_EXPECT_PSA(signature_length, SIGNATURE_DEFAULT_SIZE, key_id, sign_failed);
282 		TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
283 		return ok;
284 #endif
285 	}
286 	return unsupported_ecdh_curve;
287 }
288 
289 enum err __attribute__((weak))
verify(enum sign_alg alg,const uint8_t * pk,const uint32_t pk_len,const uint8_t * msg,const uint32_t msg_len,const uint8_t * sgn,const uint32_t sgn_len,bool * result)290 verify(enum sign_alg alg, const uint8_t *pk, const uint32_t pk_len,
291        const uint8_t *msg, const uint32_t msg_len, const uint8_t *sgn,
292        const uint32_t sgn_len, bool *result)
293 {
294 	if (alg == EdDSA) {
295 #ifdef COMPACT25519
296 		int verified = edsign_verify(sgn, pk, msg, msg_len);
297 		if (verified) {
298 			*result = true;
299 		} else {
300 			*result = false;
301 		}
302 		return ok;
303 #endif
304 	}
305 	if (alg == ES256) {
306 #ifdef MBEDTLS
307 		psa_status_t status;
308 		psa_algorithm_t psa_alg;
309 		size_t bits;
310 		psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
311 
312 		psa_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
313 		bits = PSA_BYTES_TO_BITS(P_256_PRIV_KEY_DEFAULT_SIZE);
314 
315 		TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
316 
317 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
318 
319 		psa_set_key_usage_flags(&attributes,
320 					PSA_KEY_USAGE_VERIFY_MESSAGE |
321 						PSA_KEY_USAGE_VERIFY_HASH);
322 		psa_set_key_algorithm(&attributes, psa_alg);
323 		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(
324 						      PSA_ECC_FAMILY_SECP_R1));
325 		psa_set_key_bits(&attributes, bits);
326 		TRY_EXPECT_PSA(psa_import_key(&attributes, pk, pk_len, &key_id),
327 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
328 
329 		status = psa_verify_message(key_id, psa_alg, msg, msg_len, sgn,
330 					    sgn_len);
331 		if (PSA_SUCCESS == status) {
332 			*result = true;
333 		} else {
334 			*result = false;
335 		}
336 		TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
337 		return ok;
338 #endif
339 	}
340 	return crypto_operation_not_implemented;
341 }
342 
343 enum err __attribute__((weak))
hkdf_extract(enum hash_alg alg,const uint8_t * salt,uint32_t salt_len,uint8_t * ikm,uint32_t ikm_len,uint8_t * out)344 hkdf_extract(enum hash_alg alg, const uint8_t *salt, uint32_t salt_len,
345 	     uint8_t *ikm, uint32_t ikm_len, uint8_t *out)
346 {
347 	/*"Note that [RFC5869] specifies that if the salt is not provided,
348 	it is set to a string of zeros.  For implementation purposes, not providing the salt is the same as setting the salt to the empty byte
349 	string. OSCORE sets the salt default value to empty byte string, which
350 	is converted to a string of zeroes (see Section 2.2 of [RFC5869])".*/
351 
352 	/*all currently prosed suites use hmac-sha256*/
353 	if (alg != SHA_256) {
354 		return crypto_operation_not_implemented;
355 	}
356 #ifdef TINYCRYPT
357 	struct tc_hmac_state_struct h;
358 	memset(&h, 0x00, sizeof(h));
359 	if (salt == NULL || salt_len == 0) {
360 		uint8_t zero_salt[32] = { 0 };
361 		TRY_EXPECT(tc_hmac_set_key(&h, zero_salt, 32), 1);
362 	} else {
363 		TRY_EXPECT(tc_hmac_set_key(&h, salt, salt_len), 1);
364 	}
365 	TRY_EXPECT(tc_hmac_init(&h), 1);
366 	TRY_EXPECT(tc_hmac_update(&h, ikm, ikm_len), 1);
367 	TRY_EXPECT(tc_hmac_final(out, TC_SHA256_DIGEST_SIZE, &h), 1);
368 #endif
369 #ifdef MBEDTLS
370 	psa_algorithm_t psa_alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
371 	psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
372 	psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
373 
374 	TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
375 
376 	psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
377 	psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_HASH);
378 	psa_set_key_algorithm(&attr, psa_alg);
379 	psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
380 
381 	if (salt && salt_len) {
382 		TRY_EXPECT_PSA(psa_import_key(&attr, salt, salt_len, &key_id),
383 					PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
384 	} else {
385 		uint8_t zero_salt[32] = { 0 };
386 
387 		TRY_EXPECT_PSA(psa_import_key(&attr, zero_salt, 32, &key_id),
388 						PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
389 	}
390 	size_t out_len;
391 	TRY_EXPECT_PSA(psa_mac_compute(key_id, psa_alg, ikm, ikm_len, out, 32, &out_len),
392 					PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
393 
394 	TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
395 #endif
396 	return ok;
397 }
398 
399 enum err __attribute__((weak))
hkdf_expand(enum hash_alg alg,const uint8_t * prk,const uint32_t prk_len,const uint8_t * info,const uint32_t info_len,uint8_t * out,uint32_t out_len)400 hkdf_expand(enum hash_alg alg, const uint8_t *prk, const uint32_t prk_len,
401 	    const uint8_t *info, const uint32_t info_len, uint8_t *out,
402 	    uint32_t out_len)
403 {
404 	if (alg != SHA_256) {
405 		return crypto_operation_not_implemented;
406 	}
407 	/* "N = ceil(L/HashLen)" */
408 	uint32_t iterations = (out_len + 31) / 32;
409 	/* "L length of output keying material in octets (<= 255*HashLen)"*/
410 	if (iterations > 255) {
411 		return hkdf_fialed;
412 	}
413 
414 #ifdef TINYCRYPT
415 	uint8_t t[32] = { 0 };
416 	struct tc_hmac_state_struct h;
417 	for (uint8_t i = 1; i <= iterations; i++) {
418 		memset(&h, 0x00, sizeof(h));
419 		TRY_EXPECT(tc_hmac_set_key(&h, prk, prk_len), 1);
420 		tc_hmac_init(&h);
421 		if (i > 1) {
422 			TRY_EXPECT(tc_hmac_update(&h, t, 32), 1);
423 		}
424 		TRY_EXPECT(tc_hmac_update(&h, info, info_len), 1);
425 		TRY_EXPECT(tc_hmac_update(&h, &i, 1), 1);
426 		TRY_EXPECT(tc_hmac_final(t, TC_SHA256_DIGEST_SIZE, &h),
427 				1);
428 		if (out_len < i * 32) {
429 			memcpy(&out[(i - 1) * 32], t, out_len % 32);
430 		} else {
431 			memcpy(&out[(i - 1) * 32], t, 32);
432 		}
433 	}
434 #endif
435 #ifdef MBEDTLS
436 	psa_status_t status;
437 	psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
438 	psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
439 
440 	TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
441 	psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
442 	psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_HASH);
443 	psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
444 	psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
445 
446 	TRY_EXPECT_PSA(psa_import_key(&attr, prk, prk_len, &key_id),
447 					PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
448 
449 	size_t combo_len = (32 + (size_t)info_len + 1);
450 
451 	TRY_EXPECT_PSA(check_buffer_size(INFO_DEFAULT_SIZE, (uint32_t)combo_len),
452 					ok, key_id, unexpected_result_from_ext_lib);
453 
454 	uint8_t combo[INFO_DEFAULT_SIZE];
455 	uint8_t tmp_out[32];
456 	memset(tmp_out, 0, 32);
457 	memcpy(combo + 32, info, info_len);
458 	size_t offset = 32;
459 	for (uint32_t i = 1; i <= iterations; i++) {
460 		memcpy(combo, tmp_out, 32);
461 		combo[combo_len - 1] = (uint8_t)i;
462 		size_t tmp_out_len;
463 		status = psa_mac_compute(key_id,
464 						PSA_ALG_HMAC(PSA_ALG_SHA_256),
465 						combo + offset,
466 						combo_len - offset, tmp_out,
467 						32, &tmp_out_len);
468 		TRY_EXPECT_PSA(status, PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
469 		offset = 0;
470 		uint8_t *dest = out + ((i - 1) << 5);
471 		if (out_len < (uint32_t)(i << 5)) {
472 			memcpy(dest, tmp_out, out_len & 31);
473 		} else {
474 			memcpy(dest, tmp_out, 32);
475 		}
476 	}
477 	TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
478 #endif
479 	return ok;
480 }
481 
482 enum err __attribute__((weak))
hkdf_sha_256(struct byte_array * master_secret,struct byte_array * master_salt,struct byte_array * info,struct byte_array * out)483 hkdf_sha_256(struct byte_array *master_secret, struct byte_array *master_salt,
484 	     struct byte_array *info, struct byte_array *out)
485 {
486 	uint8_t prk[SHA_DEFAULT_SIZE];
487 	TRY(hkdf_extract(SHA_256, master_salt->ptr, master_salt->len,
488 			 master_secret->ptr, master_secret->len, prk));
489 
490 	TRY(hkdf_expand(SHA_256, prk, sizeof(prk), info->ptr, info->len,
491 			out->ptr, out->len));
492 	return ok;
493 }
494 
495 enum err __attribute__((weak))
shared_secret_derive(enum ecdh_alg alg,const uint8_t * sk,const uint32_t sk_len,const uint8_t * pk,const uint32_t pk_len,uint8_t * shared_secret)496 shared_secret_derive(enum ecdh_alg alg, const uint8_t *sk,
497 		     const uint32_t sk_len, const uint8_t *pk,
498 		     const uint32_t pk_len, uint8_t *shared_secret)
499 {
500 	if (alg == X25519) {
501 #ifdef COMPACT25519
502 		uint8_t e[F25519_SIZE];
503 		f25519_copy(e, sk);
504 		c25519_prepare(e);
505 		c25519_smult(shared_secret, pk, e);
506 		return ok;
507 #endif
508 	}
509 	if (alg == P256) {
510 #ifdef MBEDTLS
511 		psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
512 		psa_algorithm_t psa_alg;
513 		size_t bits;
514 		psa_status_t result = ok;
515 
516 		psa_alg = PSA_ALG_ECDH;
517 		bits = PSA_BYTES_TO_BITS(sk_len);
518 
519 		TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
520 
521 		psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
522 		psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_VOLATILE);
523 		psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE);
524 		psa_set_key_algorithm(&attr, psa_alg);
525 		psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(
526 						PSA_ECC_FAMILY_SECP_R1));
527 
528         TRY_EXPECT_PSA(psa_import_key(&attr, sk, (size_t)sk_len, &key_id),
529 					PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
530 		psa_key_type_t type = psa_get_key_type(&attr);
531 		size_t shared_size =
532 			PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(type, bits);
533 
534 		size_t shared_secret_len = 0;
535 		PRINT_ARRAY("pk", pk, pk_len);
536 
537 		size_t pk_decompressed_len;
538 		uint8_t pk_decompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
539 
540 		mbedtls_pk_context ctx_verify = {0};
541 		mbedtls_pk_init(&ctx_verify);
542 		if(PSA_SUCCESS != mbedtls_pk_setup(
543 						&ctx_verify,
544 						mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY))) {
545 			result = unexpected_result_from_ext_lib;
546 			goto cleanup;
547 		}
548 		if(PSA_SUCCESS != mbedtls_ecp_group_load(&mbedtls_pk_ec(ctx_verify)->grp,
549 												MBEDTLS_ECP_DP_SECP256R1)){
550 			result = unexpected_result_from_ext_lib;
551 			goto cleanup;
552 		}
553 		if(PSA_SUCCESS != mbedtls_ecp_decompress(
554 						&mbedtls_pk_ec(ctx_verify)->grp, pk, pk_len,
555 						pk_decompressed, &pk_decompressed_len,
556 						sizeof(pk_decompressed))){
557 			result = unexpected_result_from_ext_lib;
558 			goto cleanup;
559 		}
560 
561 		PRINT_ARRAY("pk_decompressed", pk_decompressed,
562 			    (uint32_t)pk_decompressed_len);
563 
564 		if(PSA_SUCCESS != psa_raw_key_agreement(
565 						PSA_ALG_ECDH, key_id, pk_decompressed,
566 						pk_decompressed_len, shared_secret,
567 						shared_size, &shared_secret_len)){
568 			result = unexpected_result_from_ext_lib;
569 			goto cleanup;
570 		}
571 cleanup:
572 	if(PSA_KEY_HANDLE_INIT != key_id) {
573 		TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
574 	}
575 	mbedtls_pk_free(&ctx_verify);
576 	return result;
577 #endif
578 	}
579 	return crypto_operation_not_implemented;
580 }
581 
582 enum err __attribute__((weak))
ephemeral_dh_key_gen(enum ecdh_alg alg,uint32_t seed,uint8_t * sk,uint8_t * pk,uint32_t * pk_size)583 ephemeral_dh_key_gen(enum ecdh_alg alg, uint32_t seed, uint8_t *sk,
584 	uint8_t *pk, uint32_t *pk_size)
585 {
586 	if (alg == X25519) {
587 #ifdef COMPACT25519
588 		uint8_t extended_seed[32];
589 #ifdef TINYCRYPT
590 		struct tc_sha256_state_struct s;
591 		TRY_EXPECT(tc_sha256_init(&s), 1);
592 		TRY_EXPECT(tc_sha256_update(&s, (uint8_t *)&seed, sizeof(seed)),
593 			   1);
594 		TRY_EXPECT(tc_sha256_final(extended_seed, &s), 1);
595 #endif
596 #ifdef MBEDTLS
597 		size_t length;
598 		TRY_EXPECT(psa_hash_compute(PSA_ALG_SHA_256, (uint8_t *)&seed,
599 					    sizeof(seed), sk, SHA_DEFAULT_SIZE,
600 					    &length),
601 			   0);
602 		if (length != 32) {
603 			return sha_failed;
604 		}
605 #endif
606 		compact_x25519_keygen(sk, pk, extended_seed);
607 		*pk_size = X25519_KEY_SIZE;
608 #endif
609 	} else if (alg == P256) {
610 #ifdef MBEDTLS
611 		psa_key_id_t key_id = PSA_KEY_HANDLE_INIT;
612 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
613 		psa_algorithm_t psa_alg = PSA_ALG_ECDH;
614 		uint8_t priv_key_size = P_256_PRIV_KEY_DEFAULT_SIZE;
615 		size_t bits = PSA_BYTES_TO_BITS((size_t)priv_key_size);
616 		size_t pub_key_uncompressed_size = P_256_PUB_KEY_UNCOMPRESSED_SIZE;
617 		uint8_t pub_key_uncompressed[P_256_PUB_KEY_UNCOMPRESSED_SIZE];
618 
619 		if (P_256_PUB_KEY_COMPRESSED_SIZE > *pk_size) {
620 			return buffer_to_small;
621 		}
622 		TRY_EXPECT_PSA(psa_crypto_init(), PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
623 
624 		psa_set_key_usage_flags(&attributes,
625 						PSA_KEY_USAGE_EXPORT |
626 						PSA_KEY_USAGE_DERIVE |
627 						PSA_KEY_USAGE_SIGN_MESSAGE |
628 						PSA_KEY_USAGE_SIGN_HASH);
629 		psa_set_key_algorithm(&attributes, psa_alg);
630 		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(
631 						      PSA_ECC_FAMILY_SECP_R1));
632 		psa_set_key_bits(&attributes, bits);
633 
634 		TRY_EXPECT_PSA(psa_generate_key(&attributes, &key_id),
635 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
636 
637 		size_t key_len = 0;
638 		size_t public_key_len = 0;
639 
640 		TRY_EXPECT_PSA(psa_export_key(key_id, sk, priv_key_size, &key_len),
641 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
642 		TRY_EXPECT_PSA(psa_export_public_key(key_id, pub_key_uncompressed, pub_key_uncompressed_size, &public_key_len),
643 		               PSA_SUCCESS, key_id, unexpected_result_from_ext_lib);
644 		TRY_EXPECT_PSA(public_key_len, P_256_PUB_KEY_UNCOMPRESSED_SIZE, key_id, unexpected_result_from_ext_lib);
645 		/* Prepare output format - compressed public key with X */
646 		pk[0] = 0x02;	/* key format tag - commpressed for with X */
647 		memcpy((pk + 1), (pub_key_uncompressed + 1), 32);
648 		TRY_EXPECT(psa_destroy_key(key_id), PSA_SUCCESS);
649 		*pk_size = P_256_PUB_KEY_COMPRESSED_SIZE;
650 #endif
651 	} else {
652 		return unsupported_ecdh_curve;
653 	}
654 	return ok;
655 }
656 
657 enum err __attribute__((weak))
hash(enum hash_alg alg,const uint8_t * in,const uint32_t in_len,uint8_t * out)658 hash(enum hash_alg alg, const uint8_t *in, const uint32_t in_len, uint8_t *out)
659 {
660 	if (alg == SHA_256) {
661 #ifdef TINYCRYPT
662 		struct tc_sha256_state_struct s;
663 		TRY_EXPECT(tc_sha256_init(&s), 1);
664 		TRY_EXPECT(tc_sha256_update(&s, in, in_len), 1);
665 		TRY_EXPECT(tc_sha256_final(out, &s), 1);
666 		return ok;
667 #endif
668 #ifdef MBEDTLS
669 		size_t length;
670 		TRY_EXPECT(psa_hash_compute(PSA_ALG_SHA_256, in, in_len, out,
671 					    SHA_DEFAULT_SIZE, &length),
672 				  PSA_SUCCESS);
673 		if (length != SHA_DEFAULT_SIZE) {
674 			return sha_failed;
675 		}
676 		return ok;
677 #endif
678 	}
679 
680 	return crypto_operation_not_implemented;
681 }
682