Tools: Add asset policy table generation tool
This patch adds the SST asset policy table generation tool. The tool
generates the asset definition files, required for SST service to
build the policy table, based on the asset information and permissions
described in a YAML file.
This patch also updates the SST integration guide to explain how to
describe the asset information and permissions in the YAML file and
how to run the tool. It also changes the asset IDs to start from 1.
Change-Id: I64b3064a966821c825f457fe5110deb5e1f9ff7b
Signed-off-by: Marc Moreno <marc.morenoberengue@arm.com>
diff --git a/docs/user_guides/services/tfm_sst_integration_guide.md b/docs/user_guides/services/tfm_sst_integration_guide.md
index d808778..54c62b7 100644
--- a/docs/user_guides/services/tfm_sst_integration_guide.md
+++ b/docs/user_guides/services/tfm_sst_integration_guide.md
@@ -237,65 +237,56 @@
#### Policy Database Definition
-`sst_asset_defs.h` **must** define the list of asset IDs, maximum size of each
-asset, the number of clients allowed to access to each asset, the number of
-assets defined, the size of the largest asset and the list of clients IDs.
+`sst_asset_defs.h` defines the list of asset IDs, maximum size of each asset,
+the client IDs allowed to access one or more assets, the number of assets
+defined and the size of the largest asset.
The naming convention for those definition is as follows:
- `SST_ASSET_ID_<ASSET NAME>` - To define an asset ID.
- `SST_ASSET_MAX_SIZE_<ASSET NAME>` - To define the maximum size of the asset.
- - `SST_ASSET_PERMS_COUNT_<ASSET NAME>` - To define the number of clients
- defined in the `asset_perms_modes` vector to have access to this object in a
- direct or referenced way.
- `SST_MAX_ASSET_SIZE` - To define the size of the largest asset defined in
the file.
- `SST_NUM_ASSETS` - To define the number of assets defined in the file.
- - `SST_CLIENT_ID_<APP NAME>` - To define a client ID.
+ - `SST_CLIENT_ID_<N>` - To define a client ID number N which is allowed to
+ access one or more assets.
-The asset ID **must** not be lower than 2 and **must** be unique in the
-definition. The client ID must be unique in the definition as well.
-
-The `SST_ASSET_ID_NO_ASSET` and `SST_ASSET_ID_DELETED_ASSET` defines **must**
-remain as they are defined in `sst_asset_defs.h`.
+The asset IDs and client IDs are unique in the definitions.
An example of `sst_asset_defs.h` definition is:
```
...
+/* SST service reserved IDs */
#define SST_ASSET_ID_NO_ASSET 0
-#define SST_ASSET_ID_DELETED_ASSET 1
-/**********************************/
-#define SST_ASSET_ID_AES_KEY_128 2
-#define SST_ASSET_ID_AES_KEY_192 3
+/* End SST service reserved IDs */
+/* Asset IDs */
+#define SST_ASSET_ID_AES_KEY_128 1
+#define SST_ASSET_ID_AES_KEY_192 2
+
+/* Asset sizes */
#define SST_ASSET_MAX_SIZE_AES_KEY_128 16
#define SST_ASSET_MAX_SIZE_AES_KEY_192 24
-#define SST_ASSET_PERMS_COUNT_AES_KEY_128 1
-#define SST_ASSET_PERMS_COUNT_AES_KEY_192 1
+/* Client IDs which have access rights in one or more assets */
+#define SST_CLIENT_ID_1 1
+#define SST_CLIENT_ID_2 2
-#define SST_CLIENT_ID_1 10
-#define SST_CLIENT_ID_2 11
-
-/* Maximum number of assets that can be stored in the cache */
+/* Number of assets that can be stored in SST area */
#define SST_NUM_ASSETS 2
+
/* Largest defined asset size */
#define SST_MAX_ASSET_SIZE 24
...
```
-To define a new policy table, it is required to define an asset information
-vector (`asset_perms`) and an asset permissions mode vector
-(`asset_perms_modes`), in `sst_asset_defs.c`. The asset information vector
-defines the assets' properties, while the asset permissions mode vector defines
-the assets' access permissions for each client. By default, if an
-client ID is not defined for an specific asset in the `asset_perms_modes`,
-the asset is not accessible for that client in any direct or referenced
-way.
-
-The `struct sst_asset_info_t asset_perms[]` and `struct sst_asset_perm_t
-asset_perms_modes[]` vectors **must** be named as they are in
-`sst_asset_defs.c`.
+The policy table is composed by the asset information vector (`asset_perms`)
+and the asset permissions mode vector (`asset_perms_modes`), in
+`sst_asset_defs.c`. The asset information vector defines the properties of
+all assets, while the asset permissions mode vector defines the access
+permissions to those assets for each client. By default, if a client ID is
+not defined for an specific asset in the `asset_perms_modes`, the asset is
+not accessible for that client in any direct or referenced way.
The asset information structure (`struct sst_asset_policy_t`) contains the
following items:
@@ -313,8 +304,9 @@
`secure_fw/services/secure_storage/sst_asset_management.h`
An example of `asset_perms` definition can be found below:
+
```
-struct sst_asset_policy_t asset_perms[] = {
+const struct sst_asset_policy_t asset_perms[] = {
{
.type = PSA_SST_ASSET_KEY_AES,
.asset_uuid = SST_ASSET_ID_AES_KEY_128,
@@ -333,40 +325,109 @@
The asset permission structure (`struct sst_asset_perm_t`) is defined as
follows:
- - `client_id` - Client ID.
- - `perm` - Access permissions types, as a bitfield, allowed for this
+ - `client_id` - Client ID. ID for secure partitions is always bigger
+ than 0. Non-secure clients use ID lower than 0. ID cannot be 0.
+ - `perm` - Access permissions types, as a bit-field, allowed for this
client.
The available access permission types are:
- - `SST_PERM_REFERENCE` - The client can request to a service, which may
- have read and/or write access to the asset, to manipulate the asset's
- content in its behalfs.
- - `SST_PERM_READ` - The client can read the asset's content.
+ - `SST_PERM_REFERENCE` - The client can request to a service to
+ manipulate the asset content in its behalf.
+ - `SST_PERM_READ` - The client can read the asset content.
- `SST_PERM_WRITE` - The client can create, write and delete the asset.
-It is **mandatory** to define the client's permissions for each asset in
-order. It means, add the client's permissions for the first asset. Then,
-the client's permissions for the second asset, etc.
-By design, the policy manager manages the client's permissions for each
-asset using the `.perms_modes_start_idx` and `.perms_count` asset's properties.
+The client permissions are defined in order for each asset. It means,
+the first entries in the vector define the access permissions for all
+the clients which have access to the first asset in `asset_perms`.
+Then, the access permissions for the clients which have access to the
+second asset, etc.
+The policy manager retrieves the client permissions for each asset by
+reading the proper entry in `asset_perms_modes` vector, based on
+`.perms_modes_start_idx` and `.perms_count` asset properties in
+`asset_perms`.
The `struct sst_asset_perm_t` definition can be found in
`secure_fw/services/secure_storage/sst_asset_management.h`
An example of `asset_perms_modes` definition can be found below:
+
```
-struct sst_asset_perm_t asset_perms_modes[] = {
+const struct sst_asset_perm_t asset_perms_modes[] = {
{
.client_id = SST_CLIENT_ID_1,
.perm = SST_PERM_REFERENCE | SST_PERM_READ,
}, {
- .client = SST_CLIENT_ID_2,
+ .client_id = SST_CLIENT_ID_2,
.perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}};
+} };
```
-### Client Identification
+#### Generate a new policy database
+
+The Python script `gen_policy_db.py` can be used to generate a new policy
+DB based on the policy DB description in YAML format. The script is
+available in `tools/services/sst/policy_db`. This Python script generates
+automatically the `sst_asset_defs.h` and `sst_asset_defs.c` files which will be
+used in the SST service build process to compile in the policy DB.
+
+To define a policy for an asset, the asset definition must contain the
+following fields in the YAML file:
+
+ - `type` - PSA asset type define name defined as a string.
+ - `name` - Asset name defined as a string.
+ - `uuid` - Asset unique ID defined as an integer.
+ - `max_size` - Asset maximum size defined as an integer.
+ - `client_perms` - List of client IDs which have access to this asset.
+ - `client_id` - Client ID defined as an integer.
+ - `perms` - List of access permissions types allowed for this client. Each
+ permission defined as a string.
+
+The available access permission strings are:
+
+ - `REFERENCE` - The client can request to a service to
+ manipulate the asset content in its behalf.
+ - `READ` - The client can read the asset content.
+ - `WRITE` - The client can create, write and delete the asset.
+
+An example of asset definition in YAML format can be found below:
+
+```
+...
+{
+ "type": "PSA_SST_ASSET_KEY_HMAC",
+ "name": "AES_KEY_128",
+ "uuid": 1,
+ "max_size": 16,
+ "client_perms": [
+ {
+ "client_id": 1,
+ "perms": ["REFERENCE","READ"]
+ }, {
+ "client_id": 2,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},
+...
+```
+
+The following command can be executed to generate the new policy DB files based
+on a new YAML file description with `gen_policy_db.py`.
+```
+python gen_policy_db.py -i new_policy_db.yaml
+```
+
+Detailed information about how to use `gen_policy_db.py` can be found by
+executing the script with -h parameter.
+```
+python gen_policy_db.py -h
+```
+
+The current policy DB is defined in `tfm_sst_policy_db_definition.yaml`
+located in `tools/services/sst/policy_db` folder.
+
+### Non-Secure Identity Manager
TF-M core tracks the current client IDs running in the secure or non-secure
processing environment. It provides a dedicated API to retrieve the client ID
diff --git a/docs/user_guides/tfm_sw_requirement.md b/docs/user_guides/tfm_sw_requirement.md
index 4fc6e9e..a12cc49 100755
--- a/docs/user_guides/tfm_sw_requirement.md
+++ b/docs/user_guides/tfm_sw_requirement.md
@@ -28,7 +28,8 @@
- Python3, with the following libraries:
- pycrypto
- pyasn1
- - sudo apt-get install python3-crypto python3-pyasn1
+ - yaml
+ - sudo apt-get install python3-crypto python3-pyasn1 python3-yaml
- SRecord v1.58 (for Musca-A1 test chip board)
### Setup a shell to enable compiler toolchain and cmake after installation.
@@ -60,6 +61,7 @@
- Python3(native Windows version), with the following libraries:
- pycryptodome (pip3 install --user pycryptodome)
- pyasn1 (pip3 install --user pyasn1)
+ - pyyaml (pip3 install --user pyyaml)
- Python3 pip
- SRecord v1.63 (for Musca-A1 test chip board)
@@ -103,4 +105,4 @@
~~~
--------------
-*Copyright (c) 2017, Arm Limited. All rights reserved.*
+*Copyright (c) 2017-2018, Arm Limited. All rights reserved.*
diff --git a/secure_fw/services/secure_storage/assets/sst_asset_defs.c b/secure_fw/services/secure_storage/assets/sst_asset_defs.c
index 55b98a5..32e2b3e 100644
--- a/secure_fw/services/secure_storage/assets/sst_asset_defs.c
+++ b/secure_fw/services/secure_storage/assets/sst_asset_defs.c
@@ -5,6 +5,10 @@
*
*/
+/**********************************************/
+/* Automatically-generated file. Do not edit! */
+/**********************************************/
+
#include "sst_asset_defs.h"
#include "secure_fw/services/secure_storage/sst_asset_management.h"
@@ -13,101 +17,105 @@
.type = PSA_SST_ASSET_KEY_AES,
.asset_uuid = SST_ASSET_ID_AES_KEY_128,
.max_size = SST_ASSET_MAX_SIZE_AES_KEY_128,
- .perms_count = SST_ASSET_PERMS_COUNT_AES_KEY_128,
+ .perms_count = 1,
.perms_modes_start_idx = 0,
-}, {
- .type = PSA_SST_ASSET_KEY_AES,
- .asset_uuid = SST_ASSET_ID_AES_KEY_256,
- .max_size = SST_ASSET_MAX_SIZE_AES_KEY_256,
- .perms_count = SST_ASSET_PERMS_COUNT_AES_KEY_256,
- .perms_modes_start_idx = 2,
-}, {
- .type = PSA_SST_ASSET_KEY_RSA_PUBLIC,
- .asset_uuid = SST_ASSET_ID_RSA_KEY_1024,
- .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_1024,
- .perms_count = SST_ASSET_PERMS_COUNT_RSA_KEY_1024,
- .perms_modes_start_idx = 3,
-}, {
- .type = PSA_SST_ASSET_KEY_RSA_PUBLIC,
- .asset_uuid = SST_ASSET_ID_RSA_KEY_2048,
- .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_2048,
- .perms_count = SST_ASSET_PERMS_COUNT_RSA_KEY_2048,
- .perms_modes_start_idx = 4,
-}, {
- .type = PSA_SST_ASSET_KEY_RSA_PRIVATE,
- .asset_uuid = SST_ASSET_ID_RSA_KEY_4096,
- .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_4096,
- .perms_count = SST_ASSET_PERMS_COUNT_RSA_KEY_4096,
- .perms_modes_start_idx = 5,
-}, {
- .type = PSA_SST_ASSET_CERT_X_509,
- .asset_uuid = SST_ASSET_ID_X509_CERT_SMALL,
- .max_size = SST_ASSET_MAX_SIZE_X509_CERT_SMALL,
- .perms_count = SST_ASSET_PERMS_COUNT_X509_CERT_SMALL,
- .perms_modes_start_idx = 6,
-}, {
-/* The following assets are used by the SST testsuite */
- .type = PSA_SST_ASSET_CERT_X_509,
- .asset_uuid = SST_ASSET_ID_X509_CERT_LARGE,
- .max_size = SST_ASSET_MAX_SIZE_X509_CERT_LARGE,
- .perms_count = SST_ASSET_PERMS_COUNT_X509_CERT_LARGE,
- .perms_modes_start_idx = 7,
-}, {
+},{
.type = PSA_SST_ASSET_KEY_AES,
.asset_uuid = SST_ASSET_ID_AES_KEY_192,
.max_size = SST_ASSET_MAX_SIZE_AES_KEY_192,
- .perms_count = SST_ASSET_PERMS_COUNT_AES_KEY_192,
+ .perms_count = 3,
+ .perms_modes_start_idx = 1,
+},{
+ .type = PSA_SST_ASSET_KEY_AES,
+ .asset_uuid = SST_ASSET_ID_AES_KEY_256,
+ .max_size = SST_ASSET_MAX_SIZE_AES_KEY_256,
+ .perms_count = 1,
+ .perms_modes_start_idx = 4,
+},{
+ .type = PSA_SST_ASSET_KEY_RSA_PUBLIC,
+ .asset_uuid = SST_ASSET_ID_RSA_KEY_1024,
+ .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_1024,
+ .perms_count = 1,
+ .perms_modes_start_idx = 5,
+},{
+ .type = PSA_SST_ASSET_KEY_RSA_PUBLIC,
+ .asset_uuid = SST_ASSET_ID_RSA_KEY_2048,
+ .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_2048,
+ .perms_count = 1,
+ .perms_modes_start_idx = 6,
+},{
+ .type = PSA_SST_ASSET_KEY_RSA_PRIVATE,
+ .asset_uuid = SST_ASSET_ID_RSA_KEY_4096,
+ .max_size = SST_ASSET_MAX_SIZE_RSA_KEY_4096,
+ .perms_count = 1,
.perms_modes_start_idx = 7,
-}, {
+},{
+ .type = PSA_SST_ASSET_CERT_X_509,
+ .asset_uuid = SST_ASSET_ID_X509_CERT_SMALL,
+ .max_size = SST_ASSET_MAX_SIZE_X509_CERT_SMALL,
+ .perms_count = 1,
+ .perms_modes_start_idx = 8,
+},{
+ .type = PSA_SST_ASSET_CERT_X_509,
+ .asset_uuid = SST_ASSET_ID_X509_CERT_LARGE,
+ .max_size = SST_ASSET_MAX_SIZE_X509_CERT_LARGE,
+ .perms_count = 3,
+ .perms_modes_start_idx = 9,
+},{
.type = PSA_SST_ASSET_KEY_HMAC,
.asset_uuid = SST_ASSET_ID_SHA224_HASH,
.max_size = SST_ASSET_MAX_SIZE_SHA224_HASH,
- .perms_count = SST_ASSET_PERMS_COUNT_SHA224_HASH,
- .perms_modes_start_idx = 10,
-}, {
+ .perms_count = 1,
+ .perms_modes_start_idx = 12,
+},{
.type = PSA_SST_ASSET_KEY_HMAC,
.asset_uuid = SST_ASSET_ID_SHA384_HASH,
.max_size = SST_ASSET_MAX_SIZE_SHA384_HASH,
- .perms_count = SST_ASSET_PERMS_COUNT_SHA384_HASH,
- .perms_modes_start_idx = 11,
-}, };
+ .perms_count = 1,
+ .perms_modes_start_idx = 13,
+} };
const struct sst_asset_perm_t asset_perms_modes[] = {
{
.client_id = SST_CLIENT_ID_3,
.perm = SST_PERM_REFERENCE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
- .client_id = SST_CLIENT_ID_3,
- .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
-/* The following asset permissions are used by the SST testsuite */
+},{
.client_id = SST_CLIENT_ID_2,
.perm = SST_PERM_REFERENCE,
-}, {
+},{
.client_id = SST_CLIENT_ID_1,
.perm = SST_PERM_REFERENCE | SST_PERM_READ,
-}, {
+},{
.client_id = SST_CLIENT_ID_0,
.perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
+},{
+ .client_id = SST_CLIENT_ID_3,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
+ .client_id = SST_CLIENT_ID_3,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
+ .client_id = SST_CLIENT_ID_3,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
+ .client_id = SST_CLIENT_ID_3,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
+ .client_id = SST_CLIENT_ID_3,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
+ .client_id = SST_CLIENT_ID_2,
+ .perm = SST_PERM_REFERENCE,
+},{
+ .client_id = SST_CLIENT_ID_1,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ,
+},{
+ .client_id = SST_CLIENT_ID_0,
+ .perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
+},{
.client_id = SST_CLIENT_ID_1,
.perm = SST_PERM_REFERENCE | SST_PERM_READ | SST_PERM_WRITE,
-}, {
+},{
.client_id = SST_CLIENT_ID_0,
.perm = SST_PERM_REFERENCE | SST_PERM_WRITE,
-}, };
+} };
diff --git a/secure_fw/services/secure_storage/assets/sst_asset_defs.h b/secure_fw/services/secure_storage/assets/sst_asset_defs.h
index cf63b42..147aa46 100644
--- a/secure_fw/services/secure_storage/assets/sst_asset_defs.h
+++ b/secure_fw/services/secure_storage/assets/sst_asset_defs.h
@@ -5,6 +5,10 @@
*
*/
+/**********************************************/
+/* Automatically-generated file. Do not edit! */
+/**********************************************/
+
#ifndef __SST_ASSET_DEFS_H__
#define __SST_ASSET_DEFS_H__
@@ -16,18 +20,19 @@
#define SST_ASSET_ID_NO_ASSET 0
/* End SST service reserved IDs */
-/**********************************/
-#define SST_ASSET_ID_AES_KEY_128 3
-#define SST_ASSET_ID_AES_KEY_192 4
-#define SST_ASSET_ID_AES_KEY_256 5
-#define SST_ASSET_ID_RSA_KEY_1024 6
-#define SST_ASSET_ID_RSA_KEY_2048 7
-#define SST_ASSET_ID_RSA_KEY_4096 8
-#define SST_ASSET_ID_X509_CERT_SMALL 9
-#define SST_ASSET_ID_X509_CERT_LARGE 10
-#define SST_ASSET_ID_SHA224_HASH 11
-#define SST_ASSET_ID_SHA384_HASH 12
+/* Asset IDs */
+#define SST_ASSET_ID_AES_KEY_128 1
+#define SST_ASSET_ID_AES_KEY_192 2
+#define SST_ASSET_ID_AES_KEY_256 3
+#define SST_ASSET_ID_RSA_KEY_1024 4
+#define SST_ASSET_ID_RSA_KEY_2048 5
+#define SST_ASSET_ID_RSA_KEY_4096 6
+#define SST_ASSET_ID_X509_CERT_SMALL 7
+#define SST_ASSET_ID_X509_CERT_LARGE 8
+#define SST_ASSET_ID_SHA224_HASH 9
+#define SST_ASSET_ID_SHA384_HASH 10
+/* Asset sizes */
#define SST_ASSET_MAX_SIZE_AES_KEY_128 16
#define SST_ASSET_MAX_SIZE_AES_KEY_192 24
#define SST_ASSET_MAX_SIZE_AES_KEY_256 32
@@ -39,24 +44,15 @@
#define SST_ASSET_MAX_SIZE_SHA224_HASH 28
#define SST_ASSET_MAX_SIZE_SHA384_HASH 48
-#define SST_ASSET_PERMS_COUNT_AES_KEY_128 1
-#define SST_ASSET_PERMS_COUNT_AES_KEY_192 3
-#define SST_ASSET_PERMS_COUNT_AES_KEY_256 1
-#define SST_ASSET_PERMS_COUNT_RSA_KEY_1024 1
-#define SST_ASSET_PERMS_COUNT_RSA_KEY_2048 1
-#define SST_ASSET_PERMS_COUNT_RSA_KEY_4096 1
-#define SST_ASSET_PERMS_COUNT_X509_CERT_SMALL 1
-#define SST_ASSET_PERMS_COUNT_X509_CERT_LARGE 3
-#define SST_ASSET_PERMS_COUNT_SHA224_HASH 1
-#define SST_ASSET_PERMS_COUNT_SHA384_HASH 1
-
+/* Client IDs which have access rights in one or more assets */
#define SST_CLIENT_ID_0 -1
#define SST_CLIENT_ID_1 -2
#define SST_CLIENT_ID_2 -3
#define SST_CLIENT_ID_3 -4
-/* Maximum number of assets that can be stored in the cache */
+/* Number of assets that can be stored in SST area */
#define SST_NUM_ASSETS 10
+
/* Largest defined asset size */
#define SST_MAX_ASSET_SIZE 2048
diff --git a/tools/services/sst/policy_db/gen_policy_db.py b/tools/services/sst/policy_db/gen_policy_db.py
new file mode 100644
index 0000000..a38cbb4
--- /dev/null
+++ b/tools/services/sst/policy_db/gen_policy_db.py
@@ -0,0 +1,376 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+import argparse
+import datetime
+import os
+import types
+import yaml
+from string import Template
+
+# Set default values
+py_app_path = os.path.abspath(__file__).split(os.path.basename(__file__))[0]
+py_app_version = "1.0"
+default_yaml_file = "tfm_sst_policy_db_definition.yaml"
+default_output_path = "secure_fw/services/secure_storage/assets"
+default_output_filename = "sst_asset_defs"
+
+def write_asset_file(file_type, asset_tpl_data, output_filename):
+ """Writes asset definition file.
+
+ file_type -- Type of file to write (header or source)
+ asset_tpl_data -- Assets data to populate the template and write in the
+ file
+ output_filename -- Filename of the output files <output_filename>.c/h
+ """
+
+ # Select template and set output file extension
+ if file_type == "header":
+ tpl_filename = "sst_asset_defs.h.template"
+ output_filename += ".h"
+ else:
+ tpl_filename = "sst_asset_defs.c.template"
+ output_filename += ".c"
+
+ # Read template from file
+ fd = open(py_app_path + tpl_filename, 'r')
+
+ file_template = Template(fd.read().replace("(c) 2018","(c) ${gen_year}"))
+
+ # Open output file
+ fd = open(output_filename, 'w')
+
+ # Add year in which the file is generated
+ gen_year = datetime.datetime.now().year
+
+ if default_output_path and default_output_filename in output_filename:
+ gen_year = "2017-" + str(gen_year)
+
+ asset_tpl_data['gen_year'] = gen_year
+
+ auto_gen_notice_str = ("/**********************************************/\n"
+ "/* Automatically-generated file. Do not edit! */\n"
+ "/**********************************************/")
+
+ asset_tpl_data['auto_gen_notice'] = auto_gen_notice_str
+
+ # Write content in output file
+ fd.write(file_template.substitute(asset_tpl_data))
+
+
+def validate_asset_fields(asset, field_list, asset_name=""):
+ """Validates if a set of fields exist in an asset definition, and the fields
+ types are correct.
+
+ asset -- Asset definitions with the fields to check
+ field_list -- List of fields which must be present in the asset definition
+ asset_name -- Asset name to be used in error messages only
+ """
+
+ # Define error message templates
+ tpl_missing_field = "[Error] Missing \"{}\" field in asset {}"
+ tpl_bad_type = ("[Error] Incorrect \"{}\" field type in asset {}. "
+ "Current type {}, correct type {}")
+
+ if asset_name == "" and 'name' in asset:
+ asset_name = asset['name']
+
+ for field in field_list:
+ if field['fname'] not in asset:
+ raise Exception(tpl_missing_field.format(field['fname'],
+ asset_name))
+ if not isinstance(asset[field['fname']], field['ptype']):
+ raise Exception(tpl_bad_type.format(field['fname'],
+ asset_name,
+ type(asset[field['fname']]),
+ field['ptype']))
+
+def validate_asset_perms_fields(asset_perms_list, asset_name):
+ """Validates asset permissions from YAML file.
+
+ asset_perms_list -- List of asset permissions to validate
+ asset_name -- Asset name to be used in error messages only
+ """
+
+ # Define list of available asset permissions
+ asset_perms = ["REFERENCE","READ","WRITE"]
+
+ # Define error message templates
+ tpl_bad_client = ("[Error] The asset {} has a bad \"{}\". "
+ "It must be different from 0. The current value is {}")
+ tpl_bad_perm = ("[Error] The asset {} has invalid permissions for client ID"
+ " {}. Only {} perms can be used; got {}")
+
+ # Set of fields and types which define the client permission over an asset
+ asset_perms_fields = [{'fname': "client_id", 'ptype': int},
+ {'fname': "perms", 'ptype': list}]
+
+ for client in asset_perms_list:
+ validate_asset_fields(client, asset_perms_fields, asset_name)
+
+ if client['client_id'] == 0:
+ raise Exception(tpl_bad_client.format(asset_name,
+ "client_id",
+ client['client_id']))
+
+ for flag in client['perms']:
+ if flag not in asset_perms:
+ raise Exception(tpl_bad_perm.format(asset_name,
+ client['client_id'],
+ perm_perms,
+ flag))
+
+def validate_asset_defs(asset_defs):
+ """Validates asset definitions from YAML file.
+
+ asset_defs -- Asset definitions to validate
+ """
+
+ # Define error message templates
+ tpl_bad_value = ("[Error] The asset {} has a bad \"{}\". It must be bigger "
+ "than 0. The current value is {}")
+
+ tpl_uuid_in_use = "The asset {} uses an uuid taken by {}"
+
+ # Set of fields and types which define an asset
+ asset_fields = [{'fname': "name", 'ptype': str},
+ {'fname': "type", 'ptype': str},
+ {'fname': "uuid", 'ptype': int},
+ {'fname': "max_size", 'ptype': int},
+ {'fname': "client_perms", 'ptype': list}]
+
+ # Variable to store the valid asset UUIDs to check that it is unique in the
+ # asset definition file
+ used_uuids = {}
+
+ for asset in asset_defs:
+ validate_asset_fields(asset, asset_fields)
+
+ if asset['uuid'] <= 0:
+ raise Exception(tpl_bad_value.format(asset['name'], "uuid",
+ asset['uuid']))
+
+ if asset['uuid'] in used_uuids:
+ raise Exception(tpl_uuid_in_use.format(asset['name'],
+ used_uuids[asset['uuid']]))
+ if asset['max_size'] <= 0:
+ raise Exception(tpl_bad_value.format(asset['name'], "max_size",
+ asset['max_size']))
+
+ validate_asset_perms_fields(asset['client_perms'], asset['name'])
+
+ # Store valid asset UUID to check that it is unique in the asset
+ # definition file
+ used_uuids[asset['uuid']] = asset['name']
+
+def generate_asset_header(asset_defs, output_filename):
+ """Generates C header file of asset definitions.
+
+ asset_defs -- Asset definitions
+ output_filename -- Filename of the output file <output_filename>.h
+
+ Returns client_id_list
+ """
+
+ # Generate defines for asset UUIDs, asset maximum sizes
+ max_size = 0
+ client_id_list = []
+ asset_ids_str = ""
+ asset_sizes_str = ""
+ id_tpl_str = "#define SST_ASSET_ID_{} {}\n"
+ max_tpl_str = "#define SST_ASSET_MAX_SIZE_{} {}\n"
+ for asset in asset_defs:
+ asset_ids_str += id_tpl_str.format(asset['name'], asset['uuid'])
+ asset_sizes_str += max_tpl_str.format(asset['name'], asset['max_size'])
+ if asset['max_size'] > max_size:
+ max_size = asset['max_size']
+
+ for client in asset['client_perms']:
+ if not client['client_id'] in client_id_list:
+ client_id_list.append(client['client_id'])
+
+ # Remove last '\n'
+ asset_ids_str = asset_ids_str[:-1]
+ asset_sizes_str = asset_sizes_str[:-1]
+
+ # Sort list in descending order
+ client_id_list.sort(reverse=True)
+
+ # Generate defines for client IDs
+ client_id_tpl_str = "#define SST_CLIENT_ID_{} {}\n"
+ client_ids_str = ""
+ count = 0
+ for client_id in client_id_list:
+ client_ids_str += client_id_tpl_str.format(count, client_id)
+ count += 1
+
+ # Remove last '\n'
+ client_ids_str = client_ids_str[:-1]
+
+ # Create dictionary with the keys and content to replace in the template
+ tpl_dict = {'asset_ids': asset_ids_str,
+ 'asset_sizes': asset_sizes_str,
+ 'client_ids': client_ids_str,
+ 'number_of_assets': str(len(asset_defs)),
+ 'max_asset_size': str(max_size) }
+
+ write_asset_file("header", tpl_dict, output_filename)
+
+ return client_id_list
+
+def generate_asset_source(asset_defs, client_id_list, output_filename):
+ """Generates C source file of asset definitions.
+
+ asset_defs -- Asset definitions
+ output_filename -- Filename of the output file <output_filename>.c
+ """
+
+ # Template to define an asset
+ tpl_asset_def = ("{\n"
+ " .type = %s,\n"
+ " .asset_uuid = SST_ASSET_ID_%s,\n"
+ " .max_size = SST_ASSET_MAX_SIZE_%s,\n"
+ " .perms_count = %d,\n"
+ " .perms_modes_start_idx = %d,\n"
+ "},")
+
+ start_idx = 0
+ asset_defs_str = ""
+ for asset in asset_defs:
+ asset_defs_str += tpl_asset_def % (asset['type'],
+ asset['name'],
+ asset['name'],
+ len(asset['client_perms']),
+ start_idx)
+ start_idx = start_idx + len(asset['client_perms'])
+
+ # Remove last comma
+ asset_defs_str = asset_defs_str[:-1]
+
+ # Template to define the asset permissions
+ tpl_asset_perms = ("{\n"
+ " .client_id = SST_CLIENT_ID_%d,\n"
+ " .perm = %s,\n"
+ "},")
+
+ asset_perms_str = ""
+ for asset in asset_defs:
+ for client in asset['client_perms']:
+ client_perms = ""
+ count = 1
+ for flag in client['perms']:
+ client_perms = client_perms + "SST_PERM_{}".format(flag)
+ if count < len(client['perms']):
+ client_perms = client_perms + " | "
+ count += 1
+
+ asset_perms_str += tpl_asset_perms % (
+ client_id_list.index(client['client_id']),
+ client_perms)
+ # Remove last comma
+ asset_perms_str = asset_perms_str[:-1]
+
+ # Create dictionary with the keys and content to replace in the template
+ tpl_dict = {'asset_defs': asset_defs_str,
+ 'asset_perms': asset_perms_str }
+
+ write_asset_file("source", tpl_dict, output_filename)
+
+def generate_c_assets_files(yaml_file, output_filename):
+ """Generates asset files based on the asset definitions in YAML format.
+
+ yaml_file -- YAML file with the asset definitions
+ output_filename -- Filename of the output files <output_filename>.c/h
+ """
+
+ # Open YAML file
+ pFile = open(yaml_file, 'r')
+
+ # Parse YAML file
+ asset_defs = yaml.load(pFile.read())
+
+ # Validate asset definitions from YAML file
+ validate_asset_defs(asset_defs)
+
+ # Generate header and source files
+ client_id_list = generate_asset_header(asset_defs, output_filename)
+ generate_asset_source(asset_defs, client_id_list, output_filename)
+
+ print ("SST policy DB files (sst_asset_defs.c/h) have been generated "
+ "correctly")
+
+def get_cmd_arguments():
+ """Gets command line arguments
+ """
+
+ # Define help descriptions
+ app_desc = ("Generates the SST policy DB based on the SST asset definitions"
+ " described in a YAML file.")
+ yaml_file_desc = ("YAML filename which contains the asset definitions. "
+ "Default: {}".format(os.path.basename(default_yaml_file)))
+ path_desc = ("Directory to store the generated files. "
+ "Default: {}".format(default_output_path))
+ ofile_desc = ("Output filename without path. "
+ "Default: {}".format(default_output_filename))
+
+ parser = argparse.ArgumentParser(description=app_desc)
+
+ # Set optional parameters
+ parser.add_argument('-v', '--version', action='version',
+ version= "%(prog)s " + py_app_version)
+ parser.add_argument('-i', '--ifile', default = default_yaml_file,
+ help = yaml_file_desc)
+ parser.add_argument('-d', '--dir', default = default_output_path,
+ help = path_desc)
+ parser.add_argument('-o', '--ofile', default = default_output_filename,
+ help = ofile_desc)
+
+ # Parse arguments
+ args = parser.parse_args()
+
+ # Validate input arguments
+ if not ".yaml" in args.ifile or not os.path.exists(args.ifile):
+ print ("[Error] Missing YAML file extension: '%s'" % args.ifile)
+ exit(1)
+
+ if not os.path.exists(args.ifile):
+ print ("[Error] No such file: '%s'" % args.ifile)
+ exit(1)
+
+ if not os.path.isdir(args.dir):
+ print ("[Error] No such directory: '%s'" % args.dir)
+ exit(1)
+
+ if "/" in args.ofile:
+ print ("[Error] Bad filename format: '%s'. The filename must not "
+ "contain the output path and either extension" % args.ofile)
+ exit(1)
+
+ return args
+
+if __name__ == '__main__':
+ # Get absolute paths
+ root_path = py_app_path.split("tools")[0]
+
+ # Add absolute paths to the default values
+ default_yaml_file = py_app_path + default_yaml_file
+ default_output_path = root_path + default_output_path
+
+ # Get arguments
+ args = get_cmd_arguments()
+
+ # Create output filename
+ output_filename = os.path.normcase(args.dir + "/" + args.ofile)
+
+ # Generate files
+ try:
+ generate_c_assets_files(args.ifile, output_filename)
+ except yaml.YAMLError as exc:
+ print ("[Error] YAML format issue " + str(exc))
+ except BaseException as exc:
+ print (exc)
+ exit(1)
diff --git a/tools/services/sst/policy_db/sst_asset_defs.c.template b/tools/services/sst/policy_db/sst_asset_defs.c.template
new file mode 100644
index 0000000..8981da2
--- /dev/null
+++ b/tools/services/sst/policy_db/sst_asset_defs.c.template
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+${auto_gen_notice}
+
+#include "sst_asset_defs.h"
+#include "secure_fw/services/secure_storage/sst_asset_management.h"
+
+const struct sst_asset_policy_t asset_perms[] = {
+${asset_defs} };
+
+const struct sst_asset_perm_t asset_perms_modes[] = {
+${asset_perms} };
diff --git a/tools/services/sst/policy_db/sst_asset_defs.h.template b/tools/services/sst/policy_db/sst_asset_defs.h.template
new file mode 100644
index 0000000..ecb0d18
--- /dev/null
+++ b/tools/services/sst/policy_db/sst_asset_defs.h.template
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+${auto_gen_notice}
+
+#ifndef __SST_ASSET_DEFS_H__
+#define __SST_ASSET_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SST service reserved IDs */
+#define SST_ASSET_ID_NO_ASSET 0
+/* End SST service reserved IDs */
+
+/* Asset IDs */
+${asset_ids}
+
+/* Asset sizes */
+${asset_sizes}
+
+/* Client IDs which have access rights in one or more assets */
+${client_ids}
+
+/* Number of assets that can be stored in SST area */
+#define SST_NUM_ASSETS ${number_of_assets}
+
+/* Largest defined asset size */
+#define SST_MAX_ASSET_SIZE ${max_asset_size}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SST_ASSET_DEFS_H__ */
diff --git a/tools/services/sst/policy_db/tfm_sst_policy_db_definition.yaml b/tools/services/sst/policy_db/tfm_sst_policy_db_definition.yaml
new file mode 100644
index 0000000..cd41d7e
--- /dev/null
+++ b/tools/services/sst/policy_db/tfm_sst_policy_db_definition.yaml
@@ -0,0 +1,132 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+[
+{
+ "type": "PSA_SST_ASSET_KEY_AES",
+ "name": "AES_KEY_128",
+ "uuid": 1,
+ "max_size": 16,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_AES",
+ "name": "AES_KEY_192",
+ "uuid": 2,
+ "max_size": 24,
+ "client_perms": [
+ {
+ "client_id": -3,
+ "perms": ["REFERENCE"]
+ }, {
+ "client_id": -2,
+ "perms": ["REFERENCE","READ"]
+ }, {
+ "client_id": -1,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_AES",
+ "name": "AES_KEY_256",
+ "uuid": 3,
+ "max_size": 32,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_RSA_PUBLIC",
+ "name": "RSA_KEY_1024",
+ "uuid": 4,
+ "max_size": 128,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_RSA_PUBLIC",
+ "name": "RSA_KEY_2048",
+ "uuid": 5,
+ "max_size": 256,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_RSA_PRIVATE",
+ "name": "RSA_KEY_4096",
+ "uuid": 6,
+ "max_size": 512,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_CERT_X_509",
+ "name": "X509_CERT_SMALL",
+ "uuid": 7,
+ "max_size": 512,
+ "client_perms": [
+ {
+ "client_id": -4,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_CERT_X_509",
+ "name": "X509_CERT_LARGE",
+ "uuid": 8,
+ "max_size": 2048,
+ "client_perms": [
+ {
+ "client_id": -3,
+ "perms": ["REFERENCE"]
+ }, {
+ "client_id": -2,
+ "perms": ["REFERENCE","READ"]
+ }, {
+ "client_id": -1,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_HMAC",
+ "name": "SHA224_HASH",
+ "uuid": 9,
+ "max_size": 28,
+ "client_perms": [
+ {
+ "client_id": -2,
+ "perms": ["REFERENCE","READ","WRITE"]
+ }
+ ]
+},{
+ "type": "PSA_SST_ASSET_KEY_HMAC",
+ "name": "SHA384_HASH",
+ "uuid": 10,
+ "max_size": 48,
+ "client_perms": [
+ {
+ "client_id": -1,
+ "perms": ["REFERENCE","WRITE"]
+ }
+ ]
+}
+]