blob: eaa8613703b16407135f745287368f5e14853bef [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
43_Static_assert(SMM_UEFI_VARIABLE_STORE_INDEX_SIZE < RPC_CALLER_SESSION_SHARED_MEMORY_SIZE,
44 "The UEFI variable index does not fit into the RPC shared memory, please increase " \
45 "RPC_CALLER_SESSION_SHARED_MEMORY_SIZE");
46
47/**
48 * The SP heap must be large enough for storing the UEFI variable index, the RPC shared memory and
49 * ~16kB of miscellaneous data.
50 */
51#define SMM_MIN_HEAP_SIZE \
52 SMM_UEFI_VARIABLE_STORE_INDEX_SIZE + RPC_CALLER_SESSION_SHARED_MEMORY_SIZE + 16 * 1024
53
54_Static_assert(SP_HEAP_SIZE > SMM_MIN_HEAP_SIZE, "Please increase SP_HEAP_SIZE");
55
Julian Hallead5b622021-11-23 17:31:07 +010056/* The smm_gateway instance - it's a singleton */
57static struct smm_gateway
58{
59 struct smm_variable_provider smm_variable_provider;
60 struct secure_storage_client nv_store_client;
61 struct mock_store volatile_store;
62 struct service_context *nv_storage_service_context;
Imre Kis64721422023-07-28 15:18:30 +020063 struct rpc_caller_session *nv_storage_session;
Gabor Tothbdc11a72023-12-13 09:02:15 +010064#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020065 struct service_context *crypto_service_context;
66 struct rpc_caller_session *crypto_session;
67#endif
Julian Hallead5b622021-11-23 17:31:07 +010068
69} smm_gateway_instance;
70
Gabor Tothbdc11a72023-12-13 09:02:15 +010071#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020072bool create_crypto_binding(void)
73{
74 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
75
76 smm_gateway_instance.crypto_service_context = NULL;
77 smm_gateway_instance.crypto_session = NULL;
78
79 smm_gateway_instance.crypto_service_context = service_locator_query(SMM_GATEWAY_CRYPTO_SN);
80 if (!smm_gateway_instance.crypto_service_context)
81 goto err;
82
83 smm_gateway_instance.crypto_session =
84 service_context_open(smm_gateway_instance.crypto_service_context);
85 if (!smm_gateway_instance.crypto_session)
86 goto err;
87
88 /* Initialize the crypto client */
89 psa_status = psa_crypto_client_init(smm_gateway_instance.crypto_session);
90 if (psa_status != PSA_SUCCESS)
91 goto err;
92
93 psa_status = psa_crypto_init();
94 if (psa_status != PSA_SUCCESS)
95 goto err;
96
97 return true;
98
99err:
100 if (smm_gateway_instance.crypto_session != NULL)
101 {
102 service_context_close(smm_gateway_instance.crypto_service_context, smm_gateway_instance.crypto_session);
103 smm_gateway_instance.crypto_session = NULL;
104 }
105
106 if (smm_gateway_instance.crypto_service_context != NULL)
107 {
108 service_context_relinquish(smm_gateway_instance.crypto_service_context);
109 smm_gateway_instance.crypto_service_context = NULL;
110 }
111
112 return false;
113}
114#else
115#define create_crypto_binding(a) (true)
116#endif
Julian Hallead5b622021-11-23 17:31:07 +0100117
Imre Kis64721422023-07-28 15:18:30 +0200118struct rpc_service_interface *smm_gateway_create(uint32_t owner_id)
Julian Hallead5b622021-11-23 17:31:07 +0100119{
Imre Kis64721422023-07-28 15:18:30 +0200120 service_locator_envinit();
Julian Hallead5b622021-11-23 17:31:07 +0100121
122 /* todo - add option to use configurable service location */
123 smm_gateway_instance.nv_storage_service_context =
Imre Kis64721422023-07-28 15:18:30 +0200124 service_locator_query(SMM_GATEWAY_NV_STORE_SN);
Julian Hallead5b622021-11-23 17:31:07 +0100125
Imre Kis64721422023-07-28 15:18:30 +0200126 if (!smm_gateway_instance.nv_storage_service_context)
127 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100128
Imre Kis64721422023-07-28 15:18:30 +0200129 smm_gateway_instance.nv_storage_session = service_context_open(
130 smm_gateway_instance.nv_storage_service_context);
Julian Hallead5b622021-11-23 17:31:07 +0100131
Imre Kis64721422023-07-28 15:18:30 +0200132 if (!smm_gateway_instance.nv_storage_session)
133 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100134
135 /* Initialize a storage client to access the remote NV store */
Julian Hallead5b622021-11-23 17:31:07 +0100136 struct storage_backend *persistent_backend = secure_storage_client_init(
137 &smm_gateway_instance.nv_store_client,
Imre Kis64721422023-07-28 15:18:30 +0200138 smm_gateway_instance.nv_storage_session);
139 if (!persistent_backend)
140 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100141
142 /* Initialize the volatile storage backend */
143 struct storage_backend *volatile_backend = mock_store_init(
144 &smm_gateway_instance.volatile_store);
Imre Kis64721422023-07-28 15:18:30 +0200145 if (!volatile_backend)
146 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100147
148 /* Initialize the smm_variable service provider */
Imre Kis64721422023-07-28 15:18:30 +0200149 struct rpc_service_interface *service_iface = smm_variable_provider_init(
Julian Hallead5b622021-11-23 17:31:07 +0100150 &smm_gateway_instance.smm_variable_provider,
151 owner_id,
152 SMM_GATEWAY_MAX_UEFI_VARIABLES,
153 persistent_backend,
154 volatile_backend);
155
Gabor Toth75951632023-09-06 09:17:28 +0200156 if (!create_crypto_binding())
157 return NULL;
158
Julian Hallead5b622021-11-23 17:31:07 +0100159 return service_iface;
160}