Skip to content

Commit

Permalink
Merge pull request Mbed-TLS#8 from gilles-peskine-arm/psasim-publish
Browse files Browse the repository at this point in the history
Publish PSA framework simulator
  • Loading branch information
tom-cosgrove-arm authored Apr 19, 2024
2 parents 1a35cfa + 8ef1e0b commit ceab979
Show file tree
Hide file tree
Showing 17 changed files with 2,031 additions and 0 deletions.
12 changes: 12 additions & 0 deletions psasim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
bin/*
*.o
*.so
test/psa_ff_bootstrap.c
test/psa_manifest/*
test/client
test/partition
cscope.out
*.orig
*.swp
*.DS_Store
*psa_ff_bootstrap_*
64 changes: 64 additions & 0 deletions psasim/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
CFLAGS ?= -Wall -std=c99
INCLUDE := -I./include/
DESTDIR ?= /usr/local
PREFIX := libpsaff
BUILDDIR ?= bin

.PHONY: all install test uninstall run docker ci

all: libpsaff.so

libpsaff.so:
$(CC) $(INCLUDE) $(CFLAGS) -c -fpic src/common.c -o common.o
$(CC) $(INCLUDE) $(CFLAGS) -c -fpic src/client.c -o client.o
$(CC) $(INCLUDE) $(CFLAGS) -c -fpic src/service.c -o server.o
$(CC) -shared -o libpsaff.so common.o client.o server.o

ifeq ($(DEBUG),1)
CFLAGS += -DDEBUG -g
endif

clean:
rm -rf $(BUILDDIR)
rm -f *.so *.o
rm -rf test/*dSYM
cd test && make clean

test:
cd test && make

test/partition:
cd test && make

run: test/partition
pkill partition || true
pkill client || true
ipcs | grep q | awk '{ printf " -q " $$2 }' | xargs ipcrm > /dev/null 2>&1 || true
(sleep 3 && ./test/client)&
./test/partition

ci:
pkill client || true
ipcs | grep q | awk '{ printf " -q " $$2 }' | xargs ipcrm > /dev/null 2>&1 || true
./test/partition 2>&1 &
sleep 3 && ./test/client
pkill partition || true

docker:
@docker run --rm -ti -v $$PWD:/opt --entrypoint /bin/bash ubuntu \
-c "cd /opt && ls && apt-get update -qq && apt install \
-y gcc make gdb python -qq && make clean && make install && make test && ldconfig && make run"

install: libpsaff.so
mkdir -p $(DESTDIR)/lib
mkdir -p $(DESTDIR)/include
cp libpsaff.so $(DESTDIR)/lib/
cp -r include/* $(DESTDIR)/include/
cp tools/psa_autogen /usr/local/bin/

uninstall:
rm $(DESTDIR)/lib/libpsaff.so
rm -rf $(DESTDIR)/include/psa
rm -rf $(DESTDIR)/include/psasim
rm -f /usr/local/bin/psa_autogen

60 changes: 60 additions & 0 deletions psasim/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# psasim

This tool simulates a PSA Firmware Framework implementation.
It allows you to develop secure partitions and their clients on a desktop computer.
It should be able to run on all systems that support POSIX and System V IPC:
e.g. macOS, Linux, FreeBSD, and perhaps Windows 10 WSL2.

Please note that the code in this directory is maintained by the Mbed TLS / PSA Crypto project solely for the purpose of testing the use of Mbed TLS with client/service separation. We do not recommend using this code for any other purpose. In particular:

* This simulator is not intended to pass or demonstrate compliance.
* This code is only intended for simulation and does not have any security goals. It does not isolate services from clients.

## Building

To build and run the test program make sure you have `make`, `python` and a
C compiler installed and then enter the following commands:

```sh
make install
make run
```

On Linux you may need to run `ldconfig` to ensure the library is properly installed.

An example pair of programs is included in the `test` directory.

## Features

The implemented API is intended to be compliant with PSA-FF 1.0.0 with the exception of a couple of things that are a work in progress:

* `psa_notify` support
* "strict" policy in manifest

The only supported "interrupts" are POSIX signals, which act
as a "virtual interrupt".

The standard PSA RoT APIs are not included (e.g. cryptography, attestation, lifecycle etc).

## Design

The code is designed to be readable rather than fast or secure.
In this implementation only one message is delivered to a
RoT service at a time.
The code is not thread-safe.

To debug the simulator enable the debug flag:

```sh
make DEBUG=1 install
```

## Unsupported features

Because this is a simulator there are a few things that
can't be reasonably emulated:

* Manifest MMIO regions are unsupported
* Manifest priority field is ignored
* Partition IDs are in fact POSIX `pid_t`, which are only assigned at runtime,
making it infeasible to populate pid.h with correct values.
78 changes: 78 additions & 0 deletions psasim/include/psa/client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* PSA Firmware Framework client header for psasim. */

/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/

#ifndef __PSA_CLIENT_H__
#define __PSA_CLIENT_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stddef.h>
#include <psa/error.h>
/*********************** PSA Client Macros and Types *************************/

#define PSA_FRAMEWORK_VERSION (0x0100)

#define PSA_VERSION_NONE (0)

/* PSA response types */
#define PSA_CONNECTION_REFUSED PSA_ERROR_CONNECTION_REFUSED
#define PSA_CONNECTION_BUSY PSA_ERROR_CONNECTION_BUSY
#define PSA_DROP_CONNECTION PSA_ERROR_PROGRAMMER_ERROR

/* PSA message handles */
#define PSA_NULL_HANDLE ((psa_handle_t) 0)

#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t) (handle) > 0)
#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t) (handle))

#define PSA_MAX_IOVEC (4u)

#define PSA_IPC_CALL (0)

typedef int32_t psa_handle_t;

/**
* A read-only input memory region provided to an RoT Service.
*/
typedef struct psa_invec {
const void *base;
size_t len;
} psa_invec;

/**
* A writable output memory region provided to an RoT Service.
*/
typedef struct psa_outvec {
void *base;
size_t len;
} psa_outvec;

/*************************** PSA Client API **********************************/

uint32_t psa_framework_version(void);

uint32_t psa_version(uint32_t sid);

psa_handle_t psa_connect(uint32_t sid, uint32_t version);

psa_status_t psa_call(psa_handle_t handle,
int32_t type,
const psa_invec *in_vec,
size_t in_len,
psa_outvec *out_vec,
size_t out_len);

void psa_close(psa_handle_t handle);

#ifdef __cplusplus
}
#endif

#endif /* __PSA_CLIENT_H__ */
36 changes: 36 additions & 0 deletions psasim/include/psa/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* PSA status codes used by psasim. */

/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/

#ifndef PSA_ERROR_H
#define PSA_ERROR_H
#include <stdint.h>
typedef int32_t psa_status_t;

#define PSA_SUCCESS ((psa_status_t) 0)

#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129)
#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130)
#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t) -131)
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t) -132)
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t) -133)
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t) -134)
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t) -135)
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t) -136)
#define PSA_ERROR_BAD_STATE ((psa_status_t) -137)
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t) -138)
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t) -139)
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t) -140)
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t) -141)
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t) -142)
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t) -143)
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t) -144)
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t) -145)
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t) -146)
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t) -147)
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t) -149)

#endif
17 changes: 17 additions & 0 deletions psasim/include/psa/lifecycle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* PSA lifecycle states used by psasim. */

/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/

#define PSA_LIFECYCLE_PSA_STATE_MASK (0xff00u)
#define PSA_LIFECYCLE_IMP_STATE_MASK (0x00ffu)
#define PSA_LIFECYCLE_UNKNOWN (0x0000u)
#define PSA_LIFECYCLE_ASSEMBLY_AND_TEST (0x1000u)
#define PSA_LIFECYCLE_PSA_ROT_PROVISIONING (0x2000u)
#define PSA_LIFECYCLE_SECURED (0x3000u)
#define PSA_LIFECYCLE_NON_PSA_ROT_DEBUG (0x4000u)
#define PSA_LIFECYCLE_RECOVERABLE_PSA_ROT_DEBUG (0x5000u)
#define PSA_LIFECYCLE_DECOMMISSIONED (0x6000u)
#define psa_rot_lifecycle_state(void) PSA_LIFECYCLE_UNKNOWN
Loading

0 comments on commit ceab979

Please sign in to comment.