microsoft/mu_feature_ffa
Publicmirrored fromhttps://github.com/microsoft/mu_feature_ffaAvailable
FfaFeaturePkg/Docs/PartitionGuide.md
157lines · modecode
| 1 | # Secure Partition & Service Guide |
| 2 | |
| 3 | ## Secure Partitions Overview |
| 4 | |
| 5 | Secure partitions are isolated environments which are used to instantiate management or security services |
| 6 | in a trusted environment. They are managed by a Secure Partition Manager (SPM) which ensures that each |
| 7 | partition operates independently and securely. A secure partition can have multiple services which it |
| 8 | manages. Secure partitions can be set to run at S-EL0 or S-EL1 with S-EL1 providing higher privileges. |
| 9 | |
| 10 | ## Secure Partitions Implementation |
| 11 | |
| 12 | The following are the steps needed to create a secure partition: |
| 13 | |
| 14 | 1. Create a new folder for your secure partition in the Platforms/QemuSbsaPkg directory making sure to give it a relevant |
| 15 | name. |
| 16 | 2. Create the two necessary files: a .c which will contain the implementation for the secure partition and a .inf which |
| 17 | will be used to launch the secure partition similar to a DXE driver. |
| 18 | 3. Generate a UUID/GUID for your secure partition, this will distinguish it from other secure partitions. |
| 19 | 4. Add the .inf to the QemuSbsaPkg.dsc and .fdf files. If overriding the MsSecurePartition, just replace all instances |
| 20 | with your secure partition. If wanting to add another secure partition, you will need to add new sections to the .fdf |
| 21 | and PlatformBuild.py script to generate a new FV for your secure partition similar to [\FV.FV_STANDALONE_MM_SECURE_PARTITION1]. |
| 22 | |
| 23 | .dsc example: |
| 24 | |
| 25 | ```bash |
| 26 | QemuSbsaPkg/MsSecurePartition/MsSecurePartition.inf { |
| 27 | <LibraryClasses> |
| 28 | MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf |
| 29 | StandaloneMmCoreEntryPoint|ArmPkg/Library/SecurePartitionEntryPoint/SecurePartitionEntryPoint.inf |
| 30 | Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmStandaloneMm.inf |
| 31 | Tpm2DebugLib|SecurityPkg/Library/Tpm2DebugLib/Tpm2DebugLibVerbose.inf |
| 32 | TimerLib|ArmPkg/Library/ArmArchTimerLibEx/ArmArchTimerLibEx.inf |
| 33 | <PcdsFixedAtBuild> |
| 34 | gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x60030000 |
| 35 | gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x60120000 |
| 36 | gEfiSecurityPkgTokenSpaceGuid.PcdTpmInternalBaseAddress|0x10000200000 |
| 37 | gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|62500000 |
| 38 | <PcdsPatchableInModule> |
| 39 | gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc|FALSE |
| 40 | } |
| 41 | ``` |
| 42 | |
| 43 | .fdf example: |
| 44 | |
| 45 | ```bash |
| 46 | [FV.FV_STANDALONE_MM_SECURE_PARTITION1] |
| 47 | FvAlignment = 16 |
| 48 | ERASE_POLARITY = 1 |
| 49 | MEMORY_MAPPED = TRUE |
| 50 | STICKY_WRITE = TRUE |
| 51 | LOCK_CAP = TRUE |
| 52 | LOCK_STATUS = TRUE |
| 53 | WRITE_DISABLED_CAP = TRUE |
| 54 | WRITE_ENABLED_CAP = TRUE |
| 55 | WRITE_STATUS = TRUE |
| 56 | WRITE_LOCK_CAP = TRUE |
| 57 | WRITE_LOCK_STATUS = TRUE |
| 58 | READ_DISABLED_CAP = TRUE |
| 59 | READ_ENABLED_CAP = TRUE |
| 60 | READ_STATUS = TRUE |
| 61 | READ_LOCK_CAP = TRUE |
| 62 | READ_LOCK_STATUS = TRUE |
| 63 | |
| 64 | INF QemuSbsaPkg/MsSecurePartition/MsSecurePartition.inf |
| 65 | ``` |
| 66 | |
| 67 | 5. Create the .dts file for your secure partition and place it in the Platforms/QemuSbsa/Pkg/fdts directory. If overriding |
| 68 | the MsSecurePartition, the qemu_sbsa_mssp_config.dts can be updated with the settings related to your secure partition |
| 69 | Note that only S-EL0 partitions are supported at this time. |
| 70 | 6. Update the .dts in TFA to include your secure partition and its info. The file can be found at Silicon/Arm/TFA/plat/qemu/qemu_sbsa/fdts. |
| 71 | |
| 72 | ```text |
| 73 | secure-partitions { |
| 74 | compatible = "arm,sp"; |
| 75 | stmm { |
| 76 | uuid = "eaba83d8-baaf-4eaf-8144-f7fdcbe544a7"; |
| 77 | load-address = <0x20002000>; |
| 78 | owner = "Plat"; |
| 79 | }; |
| 80 | mssp { |
| 81 | uuid = "b8bcbd0c-8e8f-4ebe-99eb-3cbbdd0cd412"; |
| 82 | load-address = <0x20400000>; |
| 83 | owner = "Plat"; |
| 84 | }; |
| 85 | }; |
| 86 | ``` |
| 87 | |
| 88 | 7. Build and run the firmware, you should see Hafnium dispatching your secure partition. |
| 89 | |
| 90 | ## Services Overview |
| 91 | |
| 92 | A service which runs in a secure partition is designed to provide specific functionality similar to a |
| 93 | library. A service will have a UUID associated with it which is used to distinguish it from other |
| 94 | services that may be running within a secure partition. In FF-A, a DIRECT_REQ2 message will contain |
| 95 | the service UUID that the message is meant for in the ARG2 and ARG3 registers. This is how the secure |
| 96 | partition is able to figure out which service to pass along the message to. |
| 97 | |
| 98 | ## Services Implementation |
| 99 | |
| 100 | The following are steps needed to create a service for a secure partition: |
| 101 | |
| 102 | 1. Create a new folder for your service in the Path/To/Pkg/Library directory making sure to give it a |
| 103 | relevant name. |
| 104 | 2. Create the two necessary files: a .c which will contain the implementation for the service and a .inf which will be |
| 105 | used to link in your service library to your secure partition. |
| 106 | 3. Generate a UUID/GUID for your service, this will be used by FF-A DIRECT_REQ2 to route the message correctly to the |
| 107 | secure partition and the proper service. |
| 108 | 4. Place this UUID/GUID in a .h file which will be added to the Path/To/Pkg/Include/Guid directory. This file should also |
| 109 | contain the OPCODES your service will support. |
| 110 | 5. Create a global EFI_GUID extern which will hold the UUID/GUID of your service. Make sure it is initialized in the .dec |
| 111 | file. This will give you an easy way to compare the UUID/GUID against other UUIDs/GUIDs received through FF-A. |
| 112 | |
| 113 | ```bash |
| 114 | ## TPM Service over FF-A |
| 115 | # Include/Guid/Tpm2ServiceFfa.h |
| 116 | gTpm2ServiceFfaGuid = { 0x17b862a4, 0x1806, 0x4faf, { 0x86, 0xb3, 0x08, 0x9a, 0x58, 0x35, 0x38, 0x61 } } |
| 117 | ``` |
| 118 | |
| 119 | 6. Create a .h file that will contain all of the global functions related to your service. Place this file in the Path/To/Pkg/Include/Library |
| 120 | directory. Note that a service should have an Init, Deinit, and Handler function. Make sure to update the .dec to include |
| 121 | the path to this header. |
| 122 | |
| 123 | ```bash |
| 124 | ## @libraryclass Provides an implementation of the TPM Service |
| 125 | # |
| 126 | TpmServiceLib|Include/Library/TpmServiceLib.h |
| 127 | ``` |
| 128 | |
| 129 | 7. Add the UUID/GUID to the uuid variable in the secure partition .dts file. A secure partition can support multiple |
| 130 | services, each service can be added as a list. (i.e. <\UUID_1>, <\UUID_2>, <\UUID_3>) |
| 131 | |
| 132 | ```bash |
| 133 | uuid = <0xb510b3a3 0x59f64054 0xba7aff2e 0xb1eac765>, <0x17b862a4 0x18064faf 0x86b3089a 0x58353861>, <0xe0fad9b3 0x7f5c42c5 0xb2eeb7a8 0x2313cdb2>; |
| 134 | ``` |
| 135 | |
| 136 | 8. Link the service into your secure partition by adding the .inf to the [\LibraryClasses] section of the secure partition's |
| 137 | .inf file. |
| 138 | |
| 139 | ```bash |
| 140 | [LibraryClasses] |
| 141 | TpmServiceLib |
| 142 | ``` |
| 143 | |
| 144 | 9. In the secure partition .c file, include the headers for the service library. From there you should be able to access |
| 145 | the Init, Deinit, and handler functions for your service. Note that you will need to extract the UUID from the |
| 146 | DIRECT_REQ2 message and route it to the correct service. Including the UUID/GUID header from step 4 will allow you to |
| 147 | use the variable you created in step 5. |
| 148 | |
| 149 | ## Rust Based Secure Partition |
| 150 | |
| 151 | This repo provides a Rust based secure partition implementation [example](../../FfaFeaturePkg/SecurePartitions/MsSecurePartitionRust/Cargo.toml), |
| 152 | which can be used to host FF-A services. |
| 153 | |
| 154 | The Rust based services are implemented based on `haf-ec-service` and its underlying embassy framework. For platforms |
| 155 | targeting Rust, this provides a more ergonomic and safe way to implement secure partition services. |
| 156 | |
| 157 | Building instruction for the configured Rust secure partition can be found at [the document at its directory](../../FfaFeaturePkg/SecurePartitions/MsSecurePartitionRust/README.md) |