1 /*
2  * Copyright (c) 2019,2020 Linaro Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <logging/log.h>
9 
10 #include "psa/error.h"
11 #include "psa/protected_storage.h"
12 #include "util_app_cfg.h"
13 #include "util_app_log.h"
14 
15 /** The 64-bit UID associated with the config record in secure storage. */
16 static psa_storage_uid_t cfg_data_uid = 0x0000000055CFDA7A;
17 
18 LOG_MODULE_DECLARE(app, CONFIG_LOG_DEFAULT_LEVEL);
19 
20 /**
21  * @brief Default config settings. These settings will be used when a new
22  *        config record is created, or when the config record is reset.
23  */
24 static struct cfg_data cfg_data_dflt = {
25 	.magic = 0x55CFDA7A,
26 	.version = 1,
27 	.scratch = { 0 }
28 };
29 
cfg_create_data(void)30 psa_status_t cfg_create_data(void)
31 {
32 	psa_status_t status;
33 
34 	LOG_INF("app_cfg: Creating new config file with UID 0x%llX",
35 		(uint64_t)cfg_data_uid);
36 
37 	/*
38 	 * psa_ps_create can also be used here, which enables to the use of
39 	 * the psa_ps_set_extended function, but this requires us to set a
40 	 * maximum file size for resource allocation. Since the upper limit
41 	 * isn't known at present, we opt here for the simpler psa_ps_set
42 	 * call which also creates the secure storage record if necessary,
43 	 * but precludes the use of psa_ps_set_extended.
44 	 */
45 	status = psa_ps_set(cfg_data_uid, sizeof(cfg_data_dflt),
46 			    (void *)&cfg_data_dflt, 0);
47 	if (status) {
48 		goto err;
49 	}
50 
51 err:
52 	return (status ? al_psa_status(status, __func__) : status);
53 }
54 
cfg_load_data(struct cfg_data * p_cfg_data)55 psa_status_t cfg_load_data(struct cfg_data *p_cfg_data)
56 {
57 	psa_status_t status;
58 	struct psa_storage_info_t p_info;
59 
60 	memset(&p_info, 0, sizeof(p_info));
61 
62 	/* Check if the config record exists, if not create it. */
63 	status = psa_ps_get_info(cfg_data_uid, &p_info);
64 	if (status == PSA_ERROR_DOES_NOT_EXIST) {
65 		/* Create a new config file. */
66 		status = cfg_create_data();
67 		/* Copy default values to the cfg_data placeholder. */
68 		memcpy(p_cfg_data, &cfg_data_dflt, sizeof(cfg_data_dflt));
69 	}
70 	if (status) {
71 		goto err;
72 	}
73 
74 err:
75 	return (status ? al_psa_status(status, __func__) : status);
76 }
77