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