1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 
9 #include <zephyr/bluetooth/mesh.h>
10 #include <zephyr/sys/check.h>
11 
12 #define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(bt_mesh_crypto_psa);
15 
16 #include "mesh.h"
17 #include "crypto.h"
18 #include "prov.h"
19 
20 /* Mesh requires to keep in persistent memory network keys (2 keys per subnetwork),
21  * application keys (2 real keys per 1 configured) and device key + device key candidate.
22  */
23 #if defined CONFIG_BT_MESH_CDB
24 #define BT_MESH_CDB_KEY_ID_RANGE_SIZE (2 * SUBNET_COUNT + \
25 		2 * APP_KEY_COUNT + NODE_COUNT)
26 #else
27 #define BT_MESH_CDB_KEY_ID_RANGE_SIZE  0
28 #endif
29 #define BT_MESH_KEY_ID_RANGE_SIZE (2 * CONFIG_BT_MESH_SUBNET_COUNT + \
30 		2 * CONFIG_BT_MESH_APP_KEY_COUNT + 2 + BT_MESH_CDB_KEY_ID_RANGE_SIZE)
31 #define BT_MESH_PSA_KEY_ID_USER_MIN (PSA_KEY_ID_USER_MIN + \
32 		CONFIG_BT_MESH_PSA_KEY_ID_USER_MIN_OFFSET)
33 
34 BUILD_ASSERT(BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE <= PSA_KEY_ID_USER_MAX,
35 	"BLE Mesh PSA key id range overlaps maximum allowed boundary.");
36 
37 BUILD_ASSERT(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) == 16,
38 	"MAC length should be 16 bytes for 128-bits key for CMAC-AES");
39 
40 BUILD_ASSERT(PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 256, PSA_ALG_HMAC(PSA_ALG_SHA_256)) == 32,
41 	"MAC length should be 32 bytes for 256-bits key for HMAC-SHA");
42 
43 static struct {
44 	bool is_ready;
45 	psa_key_id_t priv_key_id;
46 	uint8_t public_key_be[PUB_KEY_SIZE + 1];
47 } dh_pair;
48 
49 static ATOMIC_DEFINE(pst_keys, BT_MESH_KEY_ID_RANGE_SIZE);
50 
bt_mesh_crypto_init(void)51 int bt_mesh_crypto_init(void)
52 {
53 	if (psa_crypto_init() != PSA_SUCCESS) {
54 		return -EIO;
55 	}
56 
57 	return 0;
58 }
59 
bt_mesh_encrypt(const struct bt_mesh_key * key,const uint8_t plaintext[16],uint8_t enc_data[16])60 int bt_mesh_encrypt(const struct bt_mesh_key *key, const uint8_t plaintext[16],
61 		    uint8_t enc_data[16])
62 {
63 	uint32_t output_len;
64 	psa_status_t status;
65 	int err = 0;
66 
67 	status = psa_cipher_encrypt(key->key, PSA_ALG_ECB_NO_PADDING,
68 				    plaintext, 16,
69 				    enc_data, 16,
70 				    &output_len);
71 
72 	if (status != PSA_SUCCESS || output_len != 16) {
73 		err = -EIO;
74 	}
75 
76 	return err;
77 }
78 
bt_mesh_ccm_encrypt(const struct bt_mesh_key * key,uint8_t nonce[13],const uint8_t * plaintext,size_t len,const uint8_t * aad,size_t aad_len,uint8_t * enc_data,size_t mic_size)79 int bt_mesh_ccm_encrypt(const struct bt_mesh_key *key, uint8_t nonce[13],
80 			const uint8_t *plaintext, size_t len, const uint8_t *aad,
81 			size_t aad_len, uint8_t *enc_data, size_t mic_size)
82 {
83 	uint32_t output_len;
84 	psa_status_t status;
85 	int err = 0;
86 	psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size);
87 
88 	status = psa_aead_encrypt(key->key, alg,
89 				  nonce, 13,
90 				  aad, aad_len,
91 				  plaintext, len,
92 				  enc_data, len + mic_size,
93 				  &output_len);
94 
95 	if (status != PSA_SUCCESS || output_len != len + mic_size) {
96 		err = -EIO;
97 	}
98 
99 	return err;
100 }
101 
bt_mesh_ccm_decrypt(const struct bt_mesh_key * key,uint8_t nonce[13],const uint8_t * enc_data,size_t len,const uint8_t * aad,size_t aad_len,uint8_t * plaintext,size_t mic_size)102 int bt_mesh_ccm_decrypt(const struct bt_mesh_key *key, uint8_t nonce[13],
103 			const uint8_t *enc_data, size_t len, const uint8_t *aad,
104 			size_t aad_len, uint8_t *plaintext, size_t mic_size)
105 {
106 	uint32_t output_len;
107 	psa_status_t status;
108 	int err = 0;
109 	psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size);
110 
111 	status = psa_aead_decrypt(key->key, alg,
112 				  nonce, 13,
113 				  aad, aad_len,
114 				  enc_data, len + mic_size,
115 				  plaintext, len,
116 				  &output_len);
117 
118 	if (status != PSA_SUCCESS || output_len != len) {
119 		err = -EIO;
120 	}
121 
122 	return err;
123 }
124 
bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key * key,struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[16])125 int bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key *key, struct bt_mesh_sg *sg,
126 			size_t sg_len, uint8_t mac[16])
127 {
128 	psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
129 	psa_algorithm_t alg = PSA_ALG_CMAC;
130 	psa_status_t status;
131 
132 	status = psa_mac_sign_setup(&operation, key->key, alg);
133 	if (status != PSA_SUCCESS) {
134 		return -EIO;
135 	}
136 
137 	for (; sg_len; sg_len--, sg++) {
138 		status = psa_mac_update(&operation, sg->data, sg->len);
139 		if (status != PSA_SUCCESS) {
140 			psa_mac_abort(&operation);
141 			return -EIO;
142 		}
143 	}
144 
145 	size_t mac_len;
146 
147 	status = psa_mac_sign_finish(&operation, mac, 16, &mac_len);
148 	if (status != PSA_SUCCESS) {
149 		return -EIO;
150 	}
151 
152 	if (mac_len != 16) {
153 		return -ERANGE;
154 	}
155 
156 	return 0;
157 }
158 
bt_mesh_aes_cmac_raw_key(const uint8_t key[16],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[16])159 int bt_mesh_aes_cmac_raw_key(const uint8_t key[16], struct bt_mesh_sg *sg,
160 			size_t sg_len, uint8_t mac[16])
161 {
162 	struct bt_mesh_key key_id;
163 	int err;
164 
165 	err = bt_mesh_key_import(BT_MESH_KEY_TYPE_CMAC, key, &key_id);
166 	if (err) {
167 		return err;
168 	}
169 
170 	err = bt_mesh_aes_cmac_mesh_key(&key_id, sg, sg_len, mac);
171 
172 	psa_destroy_key(key_id.key);
173 
174 	return err;
175 }
176 
bt_mesh_sha256_hmac_raw_key(const uint8_t key[32],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[32])177 int bt_mesh_sha256_hmac_raw_key(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
178 			uint8_t mac[32])
179 {
180 	psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
181 	psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);
182 
183 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
184 	psa_key_id_t key_id;
185 
186 	psa_status_t status;
187 	int err = 0;
188 
189 	/* Import a key */
190 	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
191 	psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
192 	psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
193 	psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
194 	psa_set_key_bits(&attributes, 256);
195 
196 	status = psa_import_key(&attributes, key, 32, &key_id);
197 	if (status != PSA_SUCCESS) {
198 		err = -EIO;
199 		goto end;
200 	}
201 
202 	psa_reset_key_attributes(&attributes);
203 
204 	status = psa_mac_sign_setup(&operation, key_id, alg);
205 	if (status != PSA_SUCCESS) {
206 		err = -EIO;
207 		goto end;
208 	}
209 
210 	for (; sg_len; sg_len--, sg++) {
211 		status = psa_mac_update(&operation, sg->data, sg->len);
212 		if (status != PSA_SUCCESS) {
213 			psa_mac_abort(&operation);
214 			err = -EIO;
215 			goto end;
216 		}
217 	}
218 
219 	size_t mac_len;
220 
221 	status = psa_mac_sign_finish(&operation, mac, 32, &mac_len);
222 	if (status != PSA_SUCCESS) {
223 		err = -EIO;
224 		goto end;
225 	}
226 
227 	if (mac_len != 32) {
228 		err = -ERANGE;
229 	}
230 
231 end:
232 	/* Destroy the key */
233 	psa_destroy_key(key_id);
234 
235 	return err;
236 }
237 
bt_mesh_pub_key_gen(void)238 int bt_mesh_pub_key_gen(void)
239 {
240 	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
241 	psa_status_t status;
242 	int err = 0;
243 	size_t key_len;
244 
245 	psa_destroy_key(dh_pair.priv_key_id);
246 	dh_pair.is_ready = false;
247 
248 	/* Crypto settings for ECDH using the SHA256 hashing algorithm,
249 	 * the secp256r1 curve
250 	 */
251 	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
252 	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
253 	psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
254 	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
255 	psa_set_key_bits(&key_attributes, 256);
256 
257 	/* Generate a key pair */
258 	status = psa_generate_key(&key_attributes, &dh_pair.priv_key_id);
259 	if (status != PSA_SUCCESS) {
260 		err = -EIO;
261 		goto end;
262 	}
263 
264 	status = psa_export_public_key(dh_pair.priv_key_id, dh_pair.public_key_be,
265 				sizeof(dh_pair.public_key_be), &key_len);
266 	if (status != PSA_SUCCESS) {
267 		err = -EIO;
268 		goto end;
269 	}
270 
271 	if (key_len != PUB_KEY_SIZE + 1) {
272 		err = -ERANGE;
273 		goto end;
274 	}
275 
276 	dh_pair.is_ready = true;
277 
278 end:
279 	psa_reset_key_attributes(&key_attributes);
280 
281 	return err;
282 }
283 
bt_mesh_pub_key_get(void)284 const uint8_t *bt_mesh_pub_key_get(void)
285 {
286 	return dh_pair.is_ready ? dh_pair.public_key_be + 1 : NULL;
287 }
288 
289 BUILD_ASSERT(PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(
290 	PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256) == DH_KEY_SIZE,
291 	"Diffie-Hellman shared secret size should be the same in PSA and BLE Mesh");
292 
293 BUILD_ASSERT(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256) == PUB_KEY_SIZE + 1,
294 	"Exported PSA public key should be 1 byte larger than BLE Mesh public key");
295 
bt_mesh_dhkey_gen(const uint8_t * pub_key,const uint8_t * priv_key,uint8_t * dhkey)296 int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
297 {
298 	int err = 0;
299 	psa_key_id_t priv_key_id  = PSA_KEY_ID_NULL;
300 	uint8_t public_key_repr[PUB_KEY_SIZE + 1];
301 	psa_status_t status;
302 	size_t dh_key_len;
303 
304 	if (priv_key) {
305 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
306 
307 		/* Import a custom private key */
308 		psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
309 		psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
310 		psa_set_key_algorithm(&attributes, PSA_ALG_ECDH);
311 		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
312 		psa_set_key_bits(&attributes, 256);
313 
314 		status = psa_import_key(&attributes, priv_key, PRIV_KEY_SIZE, &priv_key_id);
315 		if (status != PSA_SUCCESS) {
316 			err = -EIO;
317 			goto end;
318 		}
319 
320 		psa_reset_key_attributes(&attributes);
321 	} else {
322 		priv_key_id = dh_pair.priv_key_id;
323 	}
324 
325 	/* For elliptic curve key pairs for Weierstrass curve families (PSA_ECC_FAMILY_SECP_R1)
326 	 *  the representations of public key is:
327 	 *  - The byte 0x04;
328 	 *  - x_P as a ceiling(m/8)-byte string, big-endian;
329 	 *  - y_P as a ceiling(m/8)-byte string, big-endian.
330 	 */
331 	public_key_repr[0] = 0x04;
332 	memcpy(public_key_repr + 1, pub_key, PUB_KEY_SIZE);
333 
334 	/* Calculate the secret */
335 	status = psa_raw_key_agreement(PSA_ALG_ECDH, priv_key_id, public_key_repr,
336 			PUB_KEY_SIZE + 1, dhkey, DH_KEY_SIZE, &dh_key_len);
337 	if (status != PSA_SUCCESS) {
338 		err = -EIO;
339 		goto end;
340 	}
341 
342 	if (dh_key_len != DH_KEY_SIZE) {
343 		err = -ERANGE;
344 	}
345 
346 end:
347 
348 	if (priv_key) {
349 		psa_destroy_key(priv_key_id);
350 	}
351 
352 	return err;
353 }
354 
bt_mesh_user_keyid_alloc(void)355 __weak psa_key_id_t bt_mesh_user_keyid_alloc(void)
356 {
357 	for (int i = 0; i < BT_MESH_KEY_ID_RANGE_SIZE; i++) {
358 		if (!atomic_test_bit(pst_keys, i)) {
359 			atomic_set_bit(pst_keys, i);
360 			return BT_MESH_PSA_KEY_ID_USER_MIN + i;
361 		}
362 	}
363 
364 	return PSA_KEY_ID_NULL;
365 }
366 
bt_mesh_user_keyid_free(psa_key_id_t key_id)367 __weak int bt_mesh_user_keyid_free(psa_key_id_t key_id)
368 {
369 	if (IN_RANGE(key_id, BT_MESH_PSA_KEY_ID_USER_MIN,
370 			BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
371 		atomic_clear_bit(pst_keys, key_id - BT_MESH_PSA_KEY_ID_USER_MIN);
372 		return 0;
373 	}
374 
375 	return -EIO;
376 }
377 
bt_mesh_user_keyid_assign(psa_key_id_t key_id)378 __weak void bt_mesh_user_keyid_assign(psa_key_id_t key_id)
379 {
380 	if (IN_RANGE(key_id, BT_MESH_PSA_KEY_ID_USER_MIN,
381 				BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
382 		atomic_set_bit(pst_keys, key_id - BT_MESH_PSA_KEY_ID_USER_MIN);
383 	}
384 }
385 
bt_mesh_key_import(enum bt_mesh_key_type type,const uint8_t in[16],struct bt_mesh_key * out)386 int bt_mesh_key_import(enum bt_mesh_key_type type, const uint8_t in[16], struct bt_mesh_key *out)
387 {
388 	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
389 	psa_status_t status;
390 	psa_key_id_t key_id = PSA_KEY_ID_NULL;
391 	int err = 0;
392 
393 	switch (type) {
394 	case BT_MESH_KEY_TYPE_ECB:
395 		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
396 		psa_set_key_usage_flags(&key_attributes,
397 			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
398 		psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING);
399 		break;
400 	case BT_MESH_KEY_TYPE_CCM:
401 		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
402 		psa_set_key_usage_flags(&key_attributes,
403 			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
404 		psa_set_key_algorithm(&key_attributes,
405 			PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 4));
406 		break;
407 	case BT_MESH_KEY_TYPE_CMAC:
408 		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
409 		psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
410 		psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC);
411 		break;
412 	case BT_MESH_KEY_TYPE_NET:
413 		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
414 			key_id = bt_mesh_user_keyid_alloc();
415 
416 			if (key_id == PSA_KEY_ID_NULL) {
417 				return -ENOMEM;
418 			}
419 
420 			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
421 			psa_set_key_id(&key_attributes, key_id);
422 		} else {
423 			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
424 		}
425 		psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT);
426 		break;
427 	case BT_MESH_KEY_TYPE_APP:
428 	case BT_MESH_KEY_TYPE_DEV:
429 		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
430 			key_id = bt_mesh_user_keyid_alloc();
431 
432 			if (key_id == PSA_KEY_ID_NULL) {
433 				return -ENOMEM;
434 			}
435 
436 			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
437 			psa_set_key_id(&key_attributes, key_id);
438 		} else {
439 			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
440 		}
441 		psa_set_key_usage_flags(&key_attributes,
442 			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT);
443 		psa_set_key_algorithm(&key_attributes,
444 			PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 4));
445 		break;
446 	default:
447 		return -EIO;
448 	}
449 
450 	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
451 	psa_set_key_bits(&key_attributes, 128);
452 
453 	status = psa_import_key(&key_attributes, in, 16, &out->key);
454 	err = status == PSA_SUCCESS ? 0 :
455 		status == PSA_ERROR_ALREADY_EXISTS ? -EALREADY : -EIO;
456 
457 	if (err && key_id != PSA_KEY_ID_NULL) {
458 		bt_mesh_user_keyid_free(key_id);
459 	}
460 
461 	psa_reset_key_attributes(&key_attributes);
462 
463 	return err;
464 }
465 
bt_mesh_key_export(uint8_t out[16],const struct bt_mesh_key * in)466 int bt_mesh_key_export(uint8_t out[16], const struct bt_mesh_key *in)
467 {
468 	size_t data_length;
469 
470 	if (psa_export_key(in->key, out, 16, &data_length) != PSA_SUCCESS) {
471 		return -EIO;
472 	}
473 
474 	if (data_length != 16) {
475 		return -EIO;
476 	}
477 
478 	return 0;
479 }
480 
bt_mesh_key_assign(struct bt_mesh_key * dst,const struct bt_mesh_key * src)481 void bt_mesh_key_assign(struct bt_mesh_key *dst, const struct bt_mesh_key *src)
482 {
483 	memcpy(dst, src, sizeof(struct bt_mesh_key));
484 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
485 		bt_mesh_user_keyid_assign(dst->key);
486 	}
487 }
488 
bt_mesh_key_destroy(const struct bt_mesh_key * key)489 int bt_mesh_key_destroy(const struct bt_mesh_key *key)
490 {
491 	if (psa_destroy_key(key->key) != PSA_SUCCESS) {
492 		return -EIO;
493 	}
494 
495 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
496 		return bt_mesh_user_keyid_free(key->key);
497 	}
498 
499 	return 0;
500 }
501 
bt_mesh_key_compare(const uint8_t raw_key[16],const struct bt_mesh_key * key)502 int bt_mesh_key_compare(const uint8_t raw_key[16], const struct bt_mesh_key *key)
503 {
504 	uint8_t out[16];
505 	int err;
506 
507 	err = bt_mesh_key_export(out, key);
508 	if (err) {
509 		return err;
510 	}
511 
512 	return memcmp(out, raw_key, 16);
513 }
514 
bt_rand(void * buf,size_t len)515 __weak int bt_rand(void *buf, size_t len)
516 {
517 	CHECKIF(buf == NULL || len == 0) {
518 		return -EINVAL;
519 	}
520 
521 	return psa_generate_random(buf, len) == PSA_SUCCESS ? 0 : -EIO;
522 }
523