1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/psa/key_ids.h>
10 #include "psa/crypto.h"
11 
12 #include "wifi_credentials_internal.h"
13 
14 LOG_MODULE_REGISTER(wifi_credentials_backend, CONFIG_WIFI_CREDENTIALS_LOG_LEVEL);
15 
16 BUILD_ASSERT(CONFIG_WIFI_CREDENTIALS_MAX_ENTRIES <= ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_SIZE,
17 	     "Wi-Fi credentials management PSA key ID range exceeds officially allocated range.");
18 
wifi_credentials_backend_init(void)19 int wifi_credentials_backend_init(void)
20 {
21 	psa_status_t ret;
22 	uint8_t buf[ENTRY_MAX_LEN];
23 
24 	for (size_t i = 0; i < CONFIG_WIFI_CREDENTIALS_MAX_ENTRIES; ++i) {
25 		size_t length_read = 0;
26 		size_t key_id = i + ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_BEGIN;
27 
28 		ret = psa_export_key(key_id, buf, ARRAY_SIZE(buf), &length_read);
29 		if (ret == PSA_SUCCESS && length_read == ENTRY_MAX_LEN) {
30 			wifi_credentials_cache_ssid(i, (struct wifi_credentials_header *)buf);
31 		} else if (ret != PSA_ERROR_INVALID_HANDLE) {
32 			LOG_ERR("psa_export_key failed, err: %d", ret);
33 			return -EFAULT;
34 		}
35 	}
36 
37 	return 0;
38 }
39 
wifi_credentials_store_entry(size_t idx,const void * buf,size_t buf_len)40 int wifi_credentials_store_entry(size_t idx, const void *buf, size_t buf_len)
41 {
42 	psa_status_t ret;
43 	psa_key_attributes_t key_attributes = {0};
44 	psa_key_id_t key_id;
45 
46 	psa_set_key_id(&key_attributes, idx + ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_BEGIN);
47 	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT);
48 	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
49 	psa_set_key_algorithm(&key_attributes, PSA_ALG_NONE);
50 	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RAW_DATA);
51 	psa_set_key_bits(&key_attributes, buf_len * 8);
52 
53 	ret = psa_import_key(&key_attributes, buf, buf_len, &key_id);
54 	if (ret == PSA_ERROR_ALREADY_EXISTS) {
55 		LOG_ERR("psa_import_key failed, duplicate key: %d", ret);
56 		return -EEXIST;
57 	} else if (ret != PSA_SUCCESS) {
58 		LOG_ERR("psa_import_key failed, err: %d", ret);
59 		return -EFAULT;
60 	}
61 
62 	return 0;
63 }
64 
wifi_credentials_delete_entry(size_t idx)65 int wifi_credentials_delete_entry(size_t idx)
66 {
67 	psa_status_t ret = psa_destroy_key(idx + ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_BEGIN);
68 
69 	if (ret != PSA_SUCCESS) {
70 		LOG_ERR("psa_destroy_key failed, err: %d", ret);
71 		return -EFAULT;
72 	}
73 
74 	return 0;
75 }
76 
wifi_credentials_load_entry(size_t idx,void * buf,size_t buf_len)77 int wifi_credentials_load_entry(size_t idx, void *buf, size_t buf_len)
78 {
79 	size_t length_read = 0;
80 	size_t key_id = idx + ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_BEGIN;
81 	psa_status_t ret;
82 
83 	ret = psa_export_key(key_id, buf, buf_len, &length_read);
84 	if (ret != PSA_SUCCESS) {
85 		LOG_ERR("psa_export_key failed, err: %d", ret);
86 		return -EFAULT;
87 	}
88 
89 	if (buf_len != length_read) {
90 		return -EIO;
91 	}
92 
93 	return 0;
94 }
95