blob: 3ab45ccf52dd415748975a256c8ce1eb06731656 [file] [log] [blame]
Julian Hallead5b622021-11-23 17:31:07 +01001/*
Gabor Toth75951632023-09-06 09:17:28 +02002 * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
Julian Hallead5b622021-11-23 17:31:07 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8#include <protocols/rpc/common/packed-c/encoding.h>
Julian Hall98656d52022-05-05 11:09:21 +01009#include <service/uefi/smm_variable/provider/smm_variable_provider.h>
Gabor Toth983264f2024-01-23 09:16:24 +010010#include <service/crypto/client/psa/psa_crypto_client.h>
11#include "psa/crypto.h"
Julian Hallead5b622021-11-23 17:31:07 +010012#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
13#include <service/secure_storage/backend/mock_store/mock_store.h>
Imre Kisa26774f2024-02-21 14:27:49 +010014#include <service/locator/sp/ffa/spffa_service_context.h>
Julian Hallead5b622021-11-23 17:31:07 +010015#include <service_locator.h>
16
17/* Build-time default configuration */
18
19/* Default to using the Protected Storage SP */
20#ifndef SMM_GATEWAY_NV_STORE_SN
21#define SMM_GATEWAY_NV_STORE_SN "sn:ffa:751bf801-3dde-4768-a514-0f10aeed1790:0"
22#endif
23
Gabor Tothbdc11a72023-12-13 09:02:15 +010024#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020025/* Default to using the Crypto SP */
26#ifndef SMM_GATEWAY_CRYPTO_SN
27#define SMM_GATEWAY_CRYPTO_SN "sn:ffa:d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0:0"
28#endif
29#endif
30
Julian Hallead5b622021-11-23 17:31:07 +010031/* Default maximum number of UEFI variables */
32#ifndef SMM_GATEWAY_MAX_UEFI_VARIABLES
33#define SMM_GATEWAY_MAX_UEFI_VARIABLES (40)
34#endif
35
Imre Kisa26774f2024-02-21 14:27:49 +010036/**
37 * The UEFI variable store index must fit into the RPC shared memory, otherwise
38 * load_variable_index/sync_variable_index will fail.
39 */
40#define SMM_UEFI_VARIABLE_STORE_INDEX_SIZE \
41 UEFI_VARIABLE_STORE_INDEX_SIZE(SMM_GATEWAY_MAX_UEFI_VARIABLES)
42
Imre Kisa26774f2024-02-21 14:27:49 +010043/**
44 * The SP heap must be large enough for storing the UEFI variable index, the RPC shared memory and
45 * ~16kB of miscellaneous data.
46 */
47#define SMM_MIN_HEAP_SIZE \
48 SMM_UEFI_VARIABLE_STORE_INDEX_SIZE + RPC_CALLER_SESSION_SHARED_MEMORY_SIZE + 16 * 1024
49
50_Static_assert(SP_HEAP_SIZE > SMM_MIN_HEAP_SIZE, "Please increase SP_HEAP_SIZE");
51
Julian Hallead5b622021-11-23 17:31:07 +010052/* The smm_gateway instance - it's a singleton */
53static struct smm_gateway
54{
55 struct smm_variable_provider smm_variable_provider;
56 struct secure_storage_client nv_store_client;
57 struct mock_store volatile_store;
58 struct service_context *nv_storage_service_context;
Imre Kis64721422023-07-28 15:18:30 +020059 struct rpc_caller_session *nv_storage_session;
Gabor Tothbdc11a72023-12-13 09:02:15 +010060#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020061 struct service_context *crypto_service_context;
62 struct rpc_caller_session *crypto_session;
63#endif
Julian Hallead5b622021-11-23 17:31:07 +010064
65} smm_gateway_instance;
66
Gabor Tothbdc11a72023-12-13 09:02:15 +010067#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020068bool create_crypto_binding(void)
69{
70 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
71
72 smm_gateway_instance.crypto_service_context = NULL;
73 smm_gateway_instance.crypto_session = NULL;
74
75 smm_gateway_instance.crypto_service_context = service_locator_query(SMM_GATEWAY_CRYPTO_SN);
76 if (!smm_gateway_instance.crypto_service_context)
77 goto err;
78
79 smm_gateway_instance.crypto_session =
80 service_context_open(smm_gateway_instance.crypto_service_context);
81 if (!smm_gateway_instance.crypto_session)
82 goto err;
83
84 /* Initialize the crypto client */
85 psa_status = psa_crypto_client_init(smm_gateway_instance.crypto_session);
86 if (psa_status != PSA_SUCCESS)
87 goto err;
88
89 psa_status = psa_crypto_init();
90 if (psa_status != PSA_SUCCESS)
91 goto err;
92
93 return true;
94
95err:
96 if (smm_gateway_instance.crypto_session != NULL)
97 {
98 service_context_close(smm_gateway_instance.crypto_service_context, smm_gateway_instance.crypto_session);
99 smm_gateway_instance.crypto_session = NULL;
100 }
101
102 if (smm_gateway_instance.crypto_service_context != NULL)
103 {
104 service_context_relinquish(smm_gateway_instance.crypto_service_context);
105 smm_gateway_instance.crypto_service_context = NULL;
106 }
107
108 return false;
109}
110#else
111#define create_crypto_binding(a) (true)
112#endif
Julian Hallead5b622021-11-23 17:31:07 +0100113
Imre Kis64721422023-07-28 15:18:30 +0200114struct rpc_service_interface *smm_gateway_create(uint32_t owner_id)
Julian Hallead5b622021-11-23 17:31:07 +0100115{
Imre Kis64721422023-07-28 15:18:30 +0200116 service_locator_envinit();
Julian Hallead5b622021-11-23 17:31:07 +0100117
118 /* todo - add option to use configurable service location */
119 smm_gateway_instance.nv_storage_service_context =
Imre Kis64721422023-07-28 15:18:30 +0200120 service_locator_query(SMM_GATEWAY_NV_STORE_SN);
Julian Hallead5b622021-11-23 17:31:07 +0100121
Imre Kis64721422023-07-28 15:18:30 +0200122 if (!smm_gateway_instance.nv_storage_service_context)
123 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100124
Imre Kis64721422023-07-28 15:18:30 +0200125 smm_gateway_instance.nv_storage_session = service_context_open(
126 smm_gateway_instance.nv_storage_service_context);
Julian Hallead5b622021-11-23 17:31:07 +0100127
Imre Kis64721422023-07-28 15:18:30 +0200128 if (!smm_gateway_instance.nv_storage_session)
129 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100130
131 /* Initialize a storage client to access the remote NV store */
Julian Hallead5b622021-11-23 17:31:07 +0100132 struct storage_backend *persistent_backend = secure_storage_client_init(
133 &smm_gateway_instance.nv_store_client,
Imre Kis64721422023-07-28 15:18:30 +0200134 smm_gateway_instance.nv_storage_session);
135 if (!persistent_backend)
136 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100137
138 /* Initialize the volatile storage backend */
139 struct storage_backend *volatile_backend = mock_store_init(
140 &smm_gateway_instance.volatile_store);
Imre Kis64721422023-07-28 15:18:30 +0200141 if (!volatile_backend)
142 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100143
144 /* Initialize the smm_variable service provider */
Imre Kis64721422023-07-28 15:18:30 +0200145 struct rpc_service_interface *service_iface = smm_variable_provider_init(
Julian Hallead5b622021-11-23 17:31:07 +0100146 &smm_gateway_instance.smm_variable_provider,
147 owner_id,
148 SMM_GATEWAY_MAX_UEFI_VARIABLES,
149 persistent_backend,
150 volatile_backend);
151
Gabor Toth75951632023-09-06 09:17:28 +0200152 if (!create_crypto_binding())
153 return NULL;
154
Julian Hallead5b622021-11-23 17:31:07 +0100155 return service_iface;
156}