blob: f7279fa213d08d805199ebbe0a3b64bef3584f1a [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>
14#include <service_locator.h>
15
16/* Build-time default configuration */
17
18/* Default to using the Protected Storage SP */
19#ifndef SMM_GATEWAY_NV_STORE_SN
20#define SMM_GATEWAY_NV_STORE_SN "sn:ffa:751bf801-3dde-4768-a514-0f10aeed1790:0"
21#endif
22
Gabor Tothbdc11a72023-12-13 09:02:15 +010023#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020024/* Default to using the Crypto SP */
25#ifndef SMM_GATEWAY_CRYPTO_SN
26#define SMM_GATEWAY_CRYPTO_SN "sn:ffa:d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0:0"
27#endif
28#endif
29
Julian Hallead5b622021-11-23 17:31:07 +010030/* Default maximum number of UEFI variables */
31#ifndef SMM_GATEWAY_MAX_UEFI_VARIABLES
32#define SMM_GATEWAY_MAX_UEFI_VARIABLES (40)
33#endif
34
35/* The smm_gateway instance - it's a singleton */
36static struct smm_gateway
37{
38 struct smm_variable_provider smm_variable_provider;
39 struct secure_storage_client nv_store_client;
40 struct mock_store volatile_store;
41 struct service_context *nv_storage_service_context;
Imre Kis64721422023-07-28 15:18:30 +020042 struct rpc_caller_session *nv_storage_session;
Gabor Tothbdc11a72023-12-13 09:02:15 +010043#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020044 struct service_context *crypto_service_context;
45 struct rpc_caller_session *crypto_session;
46#endif
Julian Hallead5b622021-11-23 17:31:07 +010047
48} smm_gateway_instance;
49
Gabor Tothbdc11a72023-12-13 09:02:15 +010050#if defined(UEFI_AUTH_VAR) && !defined(UEFI_INTERNAL_CRYPTO)
Gabor Toth75951632023-09-06 09:17:28 +020051bool create_crypto_binding(void)
52{
53 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
54
55 smm_gateway_instance.crypto_service_context = NULL;
56 smm_gateway_instance.crypto_session = NULL;
57
58 smm_gateway_instance.crypto_service_context = service_locator_query(SMM_GATEWAY_CRYPTO_SN);
59 if (!smm_gateway_instance.crypto_service_context)
60 goto err;
61
62 smm_gateway_instance.crypto_session =
63 service_context_open(smm_gateway_instance.crypto_service_context);
64 if (!smm_gateway_instance.crypto_session)
65 goto err;
66
67 /* Initialize the crypto client */
68 psa_status = psa_crypto_client_init(smm_gateway_instance.crypto_session);
69 if (psa_status != PSA_SUCCESS)
70 goto err;
71
72 psa_status = psa_crypto_init();
73 if (psa_status != PSA_SUCCESS)
74 goto err;
75
76 return true;
77
78err:
79 if (smm_gateway_instance.crypto_session != NULL)
80 {
81 service_context_close(smm_gateway_instance.crypto_service_context, smm_gateway_instance.crypto_session);
82 smm_gateway_instance.crypto_session = NULL;
83 }
84
85 if (smm_gateway_instance.crypto_service_context != NULL)
86 {
87 service_context_relinquish(smm_gateway_instance.crypto_service_context);
88 smm_gateway_instance.crypto_service_context = NULL;
89 }
90
91 return false;
92}
93#else
94#define create_crypto_binding(a) (true)
95#endif
Julian Hallead5b622021-11-23 17:31:07 +010096
Imre Kis64721422023-07-28 15:18:30 +020097struct rpc_service_interface *smm_gateway_create(uint32_t owner_id)
Julian Hallead5b622021-11-23 17:31:07 +010098{
Imre Kis64721422023-07-28 15:18:30 +020099 service_locator_envinit();
Julian Hallead5b622021-11-23 17:31:07 +0100100
101 /* todo - add option to use configurable service location */
102 smm_gateway_instance.nv_storage_service_context =
Imre Kis64721422023-07-28 15:18:30 +0200103 service_locator_query(SMM_GATEWAY_NV_STORE_SN);
Julian Hallead5b622021-11-23 17:31:07 +0100104
Imre Kis64721422023-07-28 15:18:30 +0200105 if (!smm_gateway_instance.nv_storage_service_context)
106 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100107
Imre Kis64721422023-07-28 15:18:30 +0200108 smm_gateway_instance.nv_storage_session = service_context_open(
109 smm_gateway_instance.nv_storage_service_context);
Julian Hallead5b622021-11-23 17:31:07 +0100110
Imre Kis64721422023-07-28 15:18:30 +0200111 if (!smm_gateway_instance.nv_storage_session)
112 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100113
114 /* Initialize a storage client to access the remote NV store */
Julian Hallead5b622021-11-23 17:31:07 +0100115 struct storage_backend *persistent_backend = secure_storage_client_init(
116 &smm_gateway_instance.nv_store_client,
Imre Kis64721422023-07-28 15:18:30 +0200117 smm_gateway_instance.nv_storage_session);
118 if (!persistent_backend)
119 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100120
121 /* Initialize the volatile storage backend */
122 struct storage_backend *volatile_backend = mock_store_init(
123 &smm_gateway_instance.volatile_store);
Imre Kis64721422023-07-28 15:18:30 +0200124 if (!volatile_backend)
125 return NULL;
Julian Hallead5b622021-11-23 17:31:07 +0100126
127 /* Initialize the smm_variable service provider */
Imre Kis64721422023-07-28 15:18:30 +0200128 struct rpc_service_interface *service_iface = smm_variable_provider_init(
Julian Hallead5b622021-11-23 17:31:07 +0100129 &smm_gateway_instance.smm_variable_provider,
130 owner_id,
131 SMM_GATEWAY_MAX_UEFI_VARIABLES,
132 persistent_backend,
133 volatile_backend);
134
Gabor Toth75951632023-09-06 09:17:28 +0200135 if (!create_crypto_binding())
136 return NULL;
137
Julian Hallead5b622021-11-23 17:31:07 +0100138 return service_iface;
139}