mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-08-15 15:47:47 +00:00
Merge pull request #238 from minosgalanakis/rework/move-psasim
Move psasim into framework
This commit is contained in:
+69
-52
@@ -1,64 +1,81 @@
|
||||
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
|
||||
CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -DDEBUG -g
|
||||
override CFLAGS += -DDEBUG -O0 -g
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)
|
||||
rm -f *.so *.o
|
||||
rm -rf test/*dSYM
|
||||
cd test && make clean
|
||||
CLIENT_LIBS := -Lclient_libs -lpsaclient -lmbedtls -lmbedx509 -lmbedcrypto
|
||||
SERVER_LIBS := -Lserver_libs -lmbedcrypto
|
||||
|
||||
test:
|
||||
cd test && make
|
||||
MBEDTLS_ROOT_PATH = ../..
|
||||
COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include \
|
||||
-I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include \
|
||||
-I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include
|
||||
|
||||
test/partition:
|
||||
cd test && make
|
||||
GENERATED_H_FILES = include/psa_manifest/manifest.h \
|
||||
include/psa_manifest/pid.h \
|
||||
include/psa_manifest/sid.h
|
||||
|
||||
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
|
||||
LIBPSACLIENT_SRC = src/psa_ff_client.c \
|
||||
src/psa_sim_crypto_client.c \
|
||||
src/psa_sim_serialise.c
|
||||
LIBPSACLIENT_OBJS=$(LIBPSACLIENT_SRC:.c=.o)
|
||||
|
||||
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
|
||||
PSA_CLIENT_BASE_SRC = $(LIBPSACLIENT_SRC) src/client.c
|
||||
|
||||
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"
|
||||
PSA_CLIENT_FULL_SRC = $(LIBPSACLIENT_SRC) \
|
||||
$(wildcard src/aut_*.c)
|
||||
|
||||
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/
|
||||
PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c
|
||||
|
||||
uninstall:
|
||||
rm $(DESTDIR)/lib/libpsaff.so
|
||||
rm -rf $(DESTDIR)/include/psa
|
||||
rm -rf $(DESTDIR)/include/psasim
|
||||
rm -f /usr/local/bin/psa_autogen
|
||||
PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \
|
||||
src/psa_ff_server.c \
|
||||
src/psa_sim_crypto_server.c \
|
||||
src/psa_sim_serialise.c
|
||||
|
||||
.PHONY: all clean client_libs server_libs
|
||||
|
||||
all:
|
||||
|
||||
test/seedfile:
|
||||
dd if=/dev/urandom of=./test/seedfile bs=64 count=1
|
||||
|
||||
src/%.o: src/%.c $(GENERATED_H_FILES)
|
||||
$(CC) $(COMMON_INCLUDE) $(CFLAGS) -c $< $(LDFLAGS) -o $@
|
||||
|
||||
client_libs/libpsaclient: $(LIBPSACLIENT_OBJS)
|
||||
mkdir -p client_libs
|
||||
$(AR) -src client_libs/libpsaclient.a $(LIBPSACLIENT_OBJS)
|
||||
|
||||
test/psa_client_base: $(PSA_CLIENT_BASE_SRC) $(GENERATED_H_FILES) test/seedfile
|
||||
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_BASE_SRC) $(CLIENT_LIBS) $(LDFLAGS) -o $@
|
||||
|
||||
test/psa_client_full: $(PSA_CLIENT_FULL_SRC) $(GENERATED_H_FILES) test/seedfile
|
||||
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_FULL_SRC) $(CLIENT_LIBS) $(LDFLAGS) -o $@
|
||||
|
||||
test/psa_server: $(PSA_SERVER_SRC) $(GENERATED_H_FILES)
|
||||
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(SERVER_LIBS) $(LDFLAGS) -o $@
|
||||
|
||||
$(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): src/manifest.json src/server.c
|
||||
tools/psa_autogen.py src/manifest.json
|
||||
|
||||
# Build MbedTLS libraries (crypto, x509 and tls) and copy them locally to
|
||||
# build client/server applications.
|
||||
#
|
||||
# Note: these rules assume that mbedtls_config.h is already configured by all.sh.
|
||||
# If not using all.sh then the user must do it manually.
|
||||
client_libs: client_libs/libpsaclient
|
||||
client_libs server_libs:
|
||||
$(MAKE) -C $(MBEDTLS_ROOT_PATH)/library CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" libmbedcrypto.a libmbedx509.a libmbedtls.a
|
||||
mkdir -p $@
|
||||
cp $(MBEDTLS_ROOT_PATH)/library/libmbed*.a $@/
|
||||
|
||||
clean_server_intermediate_files:
|
||||
rm -f $(PARTITION_SERVER_BOOTSTRAP)
|
||||
rm -rf include/psa_manifest
|
||||
|
||||
clean: clean_server_intermediate_files
|
||||
rm -f test/psa_client_base test/psa_client_full test/psa_server
|
||||
rm -rf client_libs server_libs
|
||||
rm -f test/psa_service_* test/psa_notify_* test/*.log
|
||||
rm -f test/seedfile
|
||||
|
||||
+29
-47
@@ -1,60 +1,42 @@
|
||||
# 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.
|
||||
PSASIM holds necessary C source and header files which allows to test Mbed TLS in a "pure crypto client" scenario, i.e `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`.
|
||||
In practical terms it means that this allow to build PSASIM with Mbed TLS sources and get 2 Linux applications, a client and a server, which are connected through Linux's shared memeory, and in which the client relies on the server to perform all PSA Crypto operations.
|
||||
|
||||
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:
|
||||
The goal of PSASIM is _not_ to provide a ready-to-use solution for anyone looking to implement the pure crypto client structure (see [Limitations](#limitations) for details), but to provide an example of TF-PSA-Crypto RPC (Remote Procedure Call) implementation using Mbed TLS.
|
||||
## Limitations
|
||||
|
||||
* 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.
|
||||
In the current implementation:
|
||||
|
||||
## Building
|
||||
- Only Linux PC is supported.
|
||||
- There can be only 1 client connected to 1 server.
|
||||
- Shared memory is the only communication medium allowed. Others can be implemented (ex: net sockets), but in terms of simulation speed shared memory proved to be the fastest.
|
||||
- Server is not secure at all: keys and operation structs are stored on the RAM, so they can easily be dumped.
|
||||
|
||||
To build and run the test program make sure you have `make`, `python` and a
|
||||
C compiler installed and then enter the following commands:
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
make install
|
||||
make run
|
||||
```
|
||||
Please refer to `tests/scripts/components-psasim.sh` for guidance on how to build & test PSASIM:
|
||||
|
||||
On Linux you may need to run `ldconfig` to ensure the library is properly installed.
|
||||
- `component_test_psasim()`: builds the server and a couple of test clients which are used to evaluate some basic PSA Crypto API commands.
|
||||
- `component_test_suite_with_psasim()`: builds the server and _all_ the usual test suites (those found under the `<mbedtls-root>/tests/suites/*` folder) which are used by the CI and runs them. A small subset of test suites (`test_suite_constant_time_hmac`,`test_suite_lmots`,`test_suite_lms`) are being skipped, for CI turnover time optimization. They can be run locally if required.
|
||||
|
||||
An example pair of programs is included in the `test` directory.
|
||||
## How to update automatically generated files
|
||||
|
||||
## Features
|
||||
A significant portion of the intermediate code of PSASIM is auto-generated using Perl. In particular:
|
||||
|
||||
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_sim_serialise.[c|h]`:
|
||||
- Generated by `psa_sim_serialise.pl`.
|
||||
- These files provide the serialisation/deserialisation support that is required to pass functions' parameters between client and server.
|
||||
- `psa_sim_crypto_[client|server].c` and `psa_functions_codes.h`:
|
||||
- Generated by `psa_sim_generate.pl`.
|
||||
- `psa_sim_crypto_[client|server].c` provide interfaces for PSA Crypto APIs on client and server sides, while `psa_functions_codes.h` simply enumerates all PSA Crypto APIs.
|
||||
|
||||
* `psa_notify` support
|
||||
* "strict" policy in manifest
|
||||
These files need to be regenerated whenever some PSA Crypto API is added/deleted/modified. The procedure is as follows:
|
||||
|
||||
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.
|
||||
- `psa_sim_serialise.[c|h]`:
|
||||
- go to `<mbedtls-root>/tests/psa-client-server/psasim/src/`
|
||||
- run `./psa_sim_serialise.pl h > psa_sim_serialise.h`
|
||||
- run `./psa_sim_serialise.pl c > psa_sim_serialise.c`
|
||||
- `psa_sim_crypto_[client|server].c` and `psa_functions_codes.h`:
|
||||
- go to Mbed TLS' root folder
|
||||
- run `./tests/psa-client-server/psasim/src/psa_sim_generate.pl`
|
||||
|
||||
@@ -14,7 +14,10 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <psa/error.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "error_ext.h"
|
||||
/*********************** PSA Client Macros and Types *************************/
|
||||
|
||||
#define PSA_FRAMEWORK_VERSION (0x0100)
|
||||
@@ -32,12 +35,6 @@ extern "C" {
|
||||
#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.
|
||||
*/
|
||||
@@ -0,0 +1,52 @@
|
||||
/* Common definitions used for clients and services */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Increasing this might break on some platforms */
|
||||
#define MAX_FRAGMENT_SIZE 200
|
||||
|
||||
#define CONNECT_REQUEST 1
|
||||
#define CALL_REQUEST 2
|
||||
#define CLOSE_REQUEST 3
|
||||
#define VERSION_REQUEST 4
|
||||
#define READ_REQUEST 5
|
||||
#define READ_RESPONSE 6
|
||||
#define WRITE_REQUEST 7
|
||||
#define WRITE_RESPONSE 8
|
||||
#define SKIP_REQUEST 9
|
||||
#define PSA_REPLY 10
|
||||
|
||||
#define NON_SECURE (1 << 30)
|
||||
|
||||
typedef int32_t psa_handle_t;
|
||||
|
||||
#define PSA_MAX_IOVEC (4u)
|
||||
|
||||
#define PSA_IPC_CALL (0)
|
||||
|
||||
struct message_text {
|
||||
int qid;
|
||||
int32_t psa_type;
|
||||
char buf[MAX_FRAGMENT_SIZE];
|
||||
};
|
||||
|
||||
struct message {
|
||||
long message_type;
|
||||
struct message_text message_text;
|
||||
};
|
||||
|
||||
typedef struct vector_sizes {
|
||||
size_t invec_sizes[PSA_MAX_IOVEC];
|
||||
size_t outvec_sizes[PSA_MAX_IOVEC];
|
||||
} vector_sizes_t;
|
||||
|
||||
#endif /* _COMMON_H_ */
|
||||
@@ -0,0 +1,19 @@
|
||||
/* 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>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#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)
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <psa/service.h>
|
||||
#include <service.h>
|
||||
void raise_signal(psa_signal_t signal);
|
||||
void __init_psasim(const char **array,
|
||||
int size,
|
||||
@@ -1,36 +0,0 @@
|
||||
/* 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
|
||||
@@ -14,7 +14,11 @@ extern "C" {
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <psa/client.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/********************** PSA Secure Partition Macros and Types ****************/
|
||||
|
||||
/* PSA wait timeouts */
|
||||
@@ -0,0 +1,33 @@
|
||||
/* Common definitions used for clients and services */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "service.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define PRINT(fmt, ...) \
|
||||
fprintf(stdout, fmt "\n", ##__VA_ARGS__)
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define INFO(fmt, ...) \
|
||||
fprintf(stdout, "Info (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
#else /* !DEBUG */
|
||||
#define INFO(...)
|
||||
#endif /* DEBUG*/
|
||||
|
||||
#define ERROR(fmt, ...) \
|
||||
fprintf(stderr, "Error (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define FATAL(fmt, ...) \
|
||||
{ \
|
||||
fprintf(stderr, "Fatal (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#define PROJECT_ID 'M'
|
||||
#define PATHNAMESIZE 256
|
||||
#define TMP_FILE_BASE_PATH "./"
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* This is the base AUT that exectues all other AUTs meant to test PSA APIs
|
||||
* through PSASIM.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* First include Mbed TLS headers to get the Mbed TLS configuration and
|
||||
* platform definitions that we'll use in this program. Also include
|
||||
* standard C headers for functions we'll use here. */
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int psa_hash_compute_main(void);
|
||||
int psa_hash_main(void);
|
||||
int psa_aead_encrypt_main(char *cipher_name);
|
||||
int psa_aead_encrypt_decrypt_main(void);
|
||||
int psa_cipher_encrypt_decrypt_main(void);
|
||||
int psa_asymmetric_encrypt_decrypt_main(void);
|
||||
int psa_random_main(void);
|
||||
int psa_mac_main(void);
|
||||
int psa_key_agreement_main(void);
|
||||
int psa_sign_verify_main(void);
|
||||
int psa_hkdf_main(void);
|
||||
|
||||
#define TEST_MODULE(main_func) \
|
||||
do { \
|
||||
char title[128] = { 0 }; \
|
||||
char separator[128] = { 0 }; \
|
||||
int title_len = snprintf(title, sizeof(title), "=== Test: %s ===", #main_func); \
|
||||
memset(separator, '=', title_len); \
|
||||
printf("%s\n%s\n%s\n", separator, title, separator); \
|
||||
ret = main_func; \
|
||||
if (ret != 0) { \
|
||||
goto exit; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main()
|
||||
{
|
||||
int ret;
|
||||
|
||||
TEST_MODULE(psa_hash_compute_main());
|
||||
TEST_MODULE(psa_hash_main());
|
||||
|
||||
TEST_MODULE(psa_aead_encrypt_main("aes128-gcm"));
|
||||
TEST_MODULE(psa_aead_encrypt_main("aes256-gcm"));
|
||||
TEST_MODULE(psa_aead_encrypt_main("aes128-gcm_8"));
|
||||
TEST_MODULE(psa_aead_encrypt_main("chachapoly"));
|
||||
TEST_MODULE(psa_aead_encrypt_decrypt_main());
|
||||
TEST_MODULE(psa_cipher_encrypt_decrypt_main());
|
||||
TEST_MODULE(psa_asymmetric_encrypt_decrypt_main());
|
||||
|
||||
TEST_MODULE(psa_random_main());
|
||||
|
||||
TEST_MODULE(psa_mac_main());
|
||||
TEST_MODULE(psa_key_agreement_main());
|
||||
TEST_MODULE(psa_sign_verify_main());
|
||||
TEST_MODULE(psa_hkdf_main());
|
||||
|
||||
exit:
|
||||
return (ret != 0) ? 1 : 0;
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
const char usage[] =
|
||||
"Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]";
|
||||
|
||||
/* Dummy data for encryption: IV/nonce, additional data, 2-part message */
|
||||
const unsigned char iv1[12] = { 0x00 };
|
||||
const unsigned char add_data1[] = { 0x01, 0x02 };
|
||||
const unsigned char msg1_part1[] = { 0x03, 0x04 };
|
||||
const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 };
|
||||
|
||||
/* Dummy data (2nd message) */
|
||||
const unsigned char iv2[12] = { 0x10 };
|
||||
const unsigned char add_data2[] = { 0x11, 0x12 };
|
||||
const unsigned char msg2_part1[] = { 0x13, 0x14 };
|
||||
const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 };
|
||||
|
||||
/* Maximum total size of the messages */
|
||||
#define MSG1_SIZE (sizeof(msg1_part1) + sizeof(msg1_part2))
|
||||
#define MSG2_SIZE (sizeof(msg2_part1) + sizeof(msg2_part2))
|
||||
#define MSG_MAX_SIZE (MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE)
|
||||
|
||||
/* Dummy key material - never do this in production!
|
||||
* 32-byte is enough to all the key size supported by this program. */
|
||||
const unsigned char key_bytes[32] = { 0x2a };
|
||||
|
||||
/* Print the contents of a buffer in hex */
|
||||
void print_buf(const char *title, uint8_t *buf, size_t len)
|
||||
{
|
||||
printf("%s:", title);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
printf(" %02x", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Run a PSA function and bail out if it fails.
|
||||
* The symbolic name of the error code can be recovered using:
|
||||
* programs/psa/psa_constant_name status <value> */
|
||||
#define PSA_CHECK(expr) \
|
||||
do \
|
||||
{ \
|
||||
status = (expr); \
|
||||
if (status != PSA_SUCCESS) \
|
||||
{ \
|
||||
printf("Error %d at line %d: %s\n", \
|
||||
(int) status, \
|
||||
__LINE__, \
|
||||
#expr); \
|
||||
goto exit; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*
|
||||
* Prepare encryption material:
|
||||
* - interpret command-line argument
|
||||
* - set up key
|
||||
* - outputs: key and algorithm, which together hold all the information
|
||||
*/
|
||||
static psa_status_t aead_prepare(const char *info,
|
||||
psa_key_id_t *key,
|
||||
psa_algorithm_t *alg)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* Convert arg to alg + key_bits + key_type */
|
||||
size_t key_bits;
|
||||
psa_key_type_t key_type;
|
||||
if (strcmp(info, "aes128-gcm") == 0) {
|
||||
*alg = PSA_ALG_GCM;
|
||||
key_bits = 128;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "aes256-gcm") == 0) {
|
||||
*alg = PSA_ALG_GCM;
|
||||
key_bits = 256;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "aes128-gcm_8") == 0) {
|
||||
*alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8);
|
||||
key_bits = 128;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "chachapoly") == 0) {
|
||||
*alg = PSA_ALG_CHACHA20_POLY1305;
|
||||
key_bits = 256;
|
||||
key_type = PSA_KEY_TYPE_CHACHA20;
|
||||
} else {
|
||||
puts(usage);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Prepare key attributes */
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, *alg);
|
||||
psa_set_key_type(&attributes, key_type);
|
||||
psa_set_key_bits(&attributes, key_bits); // optional
|
||||
|
||||
/* Import key */
|
||||
PSA_CHECK(psa_import_key(&attributes, key_bytes, key_bits / 8, key));
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out some information.
|
||||
*
|
||||
* All of this information was present in the command line argument, but his
|
||||
* function demonstrates how each piece can be recovered from (key, alg).
|
||||
*/
|
||||
static void aead_info(psa_key_id_t key, psa_algorithm_t alg)
|
||||
{
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
(void) psa_get_key_attributes(key, &attr);
|
||||
psa_key_type_t key_type = psa_get_key_type(&attr);
|
||||
size_t key_bits = psa_get_key_bits(&attr);
|
||||
psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg);
|
||||
size_t tag_len = PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg);
|
||||
|
||||
const char *type_str = key_type == PSA_KEY_TYPE_AES ? "AES"
|
||||
: key_type == PSA_KEY_TYPE_CHACHA20 ? "Chacha"
|
||||
: "???";
|
||||
const char *base_str = base_alg == PSA_ALG_GCM ? "GCM"
|
||||
: base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly"
|
||||
: "???";
|
||||
|
||||
printf("%s, %u, %s, %u\n",
|
||||
type_str, (unsigned) key_bits, base_str, (unsigned) tag_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt a 2-part message.
|
||||
*/
|
||||
static int aead_encrypt(psa_key_id_t key, psa_algorithm_t alg,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *part1, size_t part1_len,
|
||||
const unsigned char *part2, size_t part2_len)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t olen, olen_tag;
|
||||
unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(MSG_MAX_SIZE)];
|
||||
unsigned char *p = out, *end = out + sizeof(out);
|
||||
unsigned char tag[PSA_AEAD_TAG_MAX_SIZE];
|
||||
|
||||
psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT;
|
||||
PSA_CHECK(psa_aead_encrypt_setup(&op, key, alg));
|
||||
|
||||
PSA_CHECK(psa_aead_set_nonce(&op, iv, iv_len));
|
||||
PSA_CHECK(psa_aead_update_ad(&op, ad, ad_len));
|
||||
PSA_CHECK(psa_aead_update(&op, part1, part1_len, p, end - p, &olen));
|
||||
p += olen;
|
||||
PSA_CHECK(psa_aead_update(&op, part2, part2_len, p, end - p, &olen));
|
||||
p += olen;
|
||||
PSA_CHECK(psa_aead_finish(&op, p, end - p, &olen,
|
||||
tag, sizeof(tag), &olen_tag));
|
||||
p += olen;
|
||||
memcpy(p, tag, olen_tag);
|
||||
p += olen_tag;
|
||||
|
||||
olen = p - out;
|
||||
print_buf("out", out, olen);
|
||||
|
||||
exit:
|
||||
psa_aead_abort(&op); // required on errors, harmless on success
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* AEAD demo: set up key/alg, print out info, encrypt messages.
|
||||
*/
|
||||
static psa_status_t aead_demo(const char *info)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
psa_key_id_t key;
|
||||
psa_algorithm_t alg;
|
||||
|
||||
PSA_CHECK(aead_prepare(info, &key, &alg));
|
||||
|
||||
aead_info(key, alg);
|
||||
|
||||
PSA_CHECK(aead_encrypt(key, alg,
|
||||
iv1, sizeof(iv1), add_data1, sizeof(add_data1),
|
||||
msg1_part1, sizeof(msg1_part1),
|
||||
msg1_part2, sizeof(msg1_part2)));
|
||||
PSA_CHECK(aead_encrypt(key, alg,
|
||||
iv2, sizeof(iv2), add_data2, sizeof(add_data2),
|
||||
msg2_part1, sizeof(msg2_part1),
|
||||
msg2_part2, sizeof(msg2_part2)));
|
||||
|
||||
exit:
|
||||
psa_destroy_key(key);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main function
|
||||
*/
|
||||
int psa_aead_encrypt_main(char *cipher_name)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
|
||||
/* Initialize the PSA crypto library. */
|
||||
PSA_CHECK(psa_crypto_init());
|
||||
|
||||
/* Run the demo */
|
||||
PSA_CHECK(aead_demo(cipher_name));
|
||||
|
||||
/* Deinitialize the PSA crypto library. */
|
||||
mbedtls_psa_crypto_free();
|
||||
|
||||
exit:
|
||||
return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
/*
|
||||
* Temporary hack: psasim’s Makefile only does:
|
||||
* -Itests/psa-client-server/psasim/include
|
||||
* -I$(MBEDTLS_ROOT_PATH)/include
|
||||
* -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include
|
||||
* -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include
|
||||
* None of those cover tf-psa-crypto/core, so we rely on the
|
||||
* “-I$(MBEDTLS_ROOT_PATH)/include” entry plus a parent-relative
|
||||
* include "../tf-psa-crypto/core/tf_psa_crypto_common.h" in order to pull in tf_psa_crypto_common.h here,
|
||||
* which in turn gets MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING (to silence the
|
||||
* new GCC-15 unterminated-string-initialization warning).
|
||||
* See GitHub issue #10223 for the proper long-term fix.
|
||||
* https://github.com/Mbed-TLS/mbedtls/issues/10223
|
||||
*/
|
||||
#include "../tf-psa-crypto/core/tf_psa_crypto_common.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BUFFER_SIZE 500
|
||||
|
||||
static void print_bytestr(const uint8_t *bytes, size_t len)
|
||||
{
|
||||
for (unsigned int idx = 0; idx < len; idx++) {
|
||||
printf("%02X", bytes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
int psa_aead_encrypt_decrypt_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
uint8_t encrypt[BUFFER_SIZE] = { 0 };
|
||||
uint8_t decrypt[BUFFER_SIZE] = { 0 };
|
||||
const uint8_t plaintext[] = "Hello World!";
|
||||
/* We need to tell the compiler that we meant to leave out the null character. */
|
||||
const uint8_t key_bytes[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
uint8_t nonce[PSA_AEAD_NONCE_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CCM)];
|
||||
size_t nonce_length = sizeof(nonce);
|
||||
size_t ciphertext_length;
|
||||
size_t plaintext_length;
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_generate_random(nonce, nonce_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_generate_random failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_aead_encrypt(key_id, // key
|
||||
PSA_ALG_CCM, // algorithm
|
||||
nonce, nonce_length, // nonce
|
||||
NULL, 0, // additional data
|
||||
plaintext, sizeof(plaintext), // plaintext
|
||||
encrypt, sizeof(encrypt), // ciphertext
|
||||
&ciphertext_length); // length of output
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_aead_encrypt failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("AES-CCM encryption:\n");
|
||||
printf("- Plaintext: '%s':\n", plaintext);
|
||||
printf("- Key: ");
|
||||
print_bytestr(key_bytes, sizeof(key_bytes));
|
||||
printf("\n- Nonce: ");
|
||||
print_bytestr(nonce, nonce_length);
|
||||
printf("\n- No additional data\n");
|
||||
printf("- Ciphertext:\n");
|
||||
|
||||
for (size_t j = 0; j < ciphertext_length; j++) {
|
||||
if (j % 8 == 0) {
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%02x ", encrypt[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
status = psa_aead_decrypt(key_id, // key
|
||||
PSA_ALG_CCM, // algorithm
|
||||
nonce, nonce_length, // nonce
|
||||
NULL, 0, // additional data
|
||||
encrypt, ciphertext_length, // ciphertext
|
||||
decrypt, sizeof(decrypt), // plaintext
|
||||
&plaintext_length); // length of output
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_aead_decrypt failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (memcmp(plaintext, decrypt, sizeof(plaintext)) != 0) {
|
||||
printf("\nEncryption/Decryption failed!\n");
|
||||
} else {
|
||||
printf("\nEncryption/Decryption successful!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define KEY_BITS 4096
|
||||
#define BUFFER_SIZE PSA_BITS_TO_BYTES(KEY_BITS)
|
||||
|
||||
static void print_bytestr(const uint8_t *bytes, size_t len)
|
||||
{
|
||||
for (unsigned int idx = 0; idx < len; idx++) {
|
||||
printf("%02X", bytes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
int psa_asymmetric_encrypt_decrypt_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
uint8_t original[BUFFER_SIZE/2] = { 0 };
|
||||
uint8_t encrypt[BUFFER_SIZE] = { 0 };
|
||||
uint8_t decrypt[BUFFER_SIZE] = { 0 };
|
||||
size_t encrypted_length;
|
||||
size_t decrypted_length;
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_generate_random(original, sizeof(original));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_generate_random() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_bits(&attributes, KEY_BITS);
|
||||
|
||||
status = psa_generate_key(&attributes, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_generate_key failed (%d)\n", status);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
original, sizeof(original), NULL, 0,
|
||||
encrypt, sizeof(encrypt), &encrypted_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_asymmetric_encrypt failed (%d)\n", status);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
encrypt, encrypted_length, NULL, 0,
|
||||
decrypt, sizeof(decrypt), &decrypted_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_cipher_decrypt failed (%d)\n", status);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (memcmp(original, decrypt, sizeof(original)) != 0) {
|
||||
printf("\nEncryption/Decryption failed!\n");
|
||||
} else {
|
||||
printf("\nEncryption/Decryption successful!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "../tf-psa-crypto/core/tf_psa_crypto_common.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
static void print_bytestr(const uint8_t *bytes, size_t len)
|
||||
{
|
||||
for (unsigned int idx = 0; idx < len; idx++) {
|
||||
printf("%02X", bytes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
int psa_cipher_encrypt_decrypt_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
uint8_t original[BUFFER_SIZE] = { 0 };
|
||||
uint8_t encrypt[BUFFER_SIZE] = { 0 };
|
||||
uint8_t decrypt[BUFFER_SIZE] = { 0 };
|
||||
/* We need to tell the compiler that we meant to leave out the null character. */
|
||||
const uint8_t key_bytes[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
size_t encrypted_length;
|
||||
size_t decrypted_length;
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_generate_random(original, sizeof(original));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_generate_random() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
original, sizeof(original),
|
||||
encrypt, sizeof(encrypt), &encrypted_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_cipher_encrypt failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
encrypt, encrypted_length,
|
||||
decrypt, sizeof(decrypt), &decrypted_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_cipher_decrypt failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (memcmp(original, decrypt, sizeof(original)) != 0) {
|
||||
printf("\nEncryption/Decryption failed!\n");
|
||||
} else {
|
||||
printf("\nEncryption/Decryption successful!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define HASH_ALG PSA_ALG_SHA_256
|
||||
|
||||
static const uint8_t sample_message[] = "Hello World!";
|
||||
/* sample_message is terminated with a null byte which is not part of
|
||||
* the message itself so we make sure to subtract it in order to get
|
||||
* the message length. */
|
||||
static const size_t sample_message_length = sizeof(sample_message) - 1;
|
||||
|
||||
#define EXPECTED_HASH_VALUE { \
|
||||
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
|
||||
0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \
|
||||
0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
|
||||
}
|
||||
|
||||
static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
|
||||
static const size_t expected_hash_len = sizeof(expected_hash);
|
||||
|
||||
int psa_hash_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
|
||||
size_t hash_length;
|
||||
psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_hash_operation_t cloned_hash_operation = PSA_HASH_OPERATION_INIT;
|
||||
|
||||
mbedtls_printf("PSA Crypto API: SHA-256 example\n\n");
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Compute hash using multi-part operation */
|
||||
status = psa_hash_setup(&hash_operation, HASH_ALG);
|
||||
if (status == PSA_ERROR_NOT_SUPPORTED) {
|
||||
mbedtls_printf("unknown hash algorithm supplied\n");
|
||||
return EXIT_FAILURE;
|
||||
} else if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_setup failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hash_operation, sample_message, sample_message_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_update failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_clone(&hash_operation, &cloned_hash_operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("PSA hash clone failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&hash_operation, hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_finish failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Check the result of the operation against the sample */
|
||||
if (hash_length != expected_hash_len ||
|
||||
(memcmp(hash, expected_hash, expected_hash_len) != 0)) {
|
||||
mbedtls_printf("Multi-part hash operation gave the wrong result!\n\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status =
|
||||
psa_hash_verify(&cloned_hash_operation, expected_hash,
|
||||
expected_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_verify failed\n");
|
||||
goto cleanup;
|
||||
} else {
|
||||
mbedtls_printf("Multi-part hash operation successful!\n");
|
||||
}
|
||||
|
||||
/* A bit of white-box testing: ensure that we can abort an operation more
|
||||
* times than there are operation slots on the simulator server.
|
||||
*/
|
||||
for (int i = 0; i < 200; i++) {
|
||||
/* This should be a no-op */
|
||||
status = psa_hash_abort(&hash_operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_abort failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute hash using multi-part operation using the same operation struct */
|
||||
status = psa_hash_setup(&hash_operation, HASH_ALG);
|
||||
if (status == PSA_ERROR_NOT_SUPPORTED) {
|
||||
mbedtls_printf("unknown hash algorithm supplied\n");
|
||||
goto cleanup;
|
||||
} else if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_setup failed: %d\n", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hash_operation, sample_message, sample_message_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_update failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Don't use psa_hash_finish() when going to check against an expected result */
|
||||
status = psa_hash_verify(&hash_operation, expected_hash, expected_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_verify failed: %d\n", status);
|
||||
goto cleanup;
|
||||
} else {
|
||||
mbedtls_printf("Second multi-part hash operation successful!\n");
|
||||
}
|
||||
|
||||
/* Clear local variables prior to one-shot hash demo */
|
||||
memset(hash, 0, sizeof(hash));
|
||||
hash_length = 0;
|
||||
|
||||
/* Compute hash using one-shot function call */
|
||||
status = psa_hash_compute(HASH_ALG,
|
||||
sample_message, sample_message_length,
|
||||
hash, sizeof(hash),
|
||||
&hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_compute failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (hash_length != expected_hash_len ||
|
||||
(memcmp(hash, expected_hash, expected_hash_len) != 0)) {
|
||||
mbedtls_printf("One-shot hash operation gave the wrong result!\n\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mbedtls_printf("One-shot hash operation successful!\n\n");
|
||||
|
||||
/* Print out result */
|
||||
mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message);
|
||||
|
||||
for (size_t j = 0; j < expected_hash_len; j++) {
|
||||
mbedtls_printf("%02x", hash[j]);
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
psa_hash_abort(&hash_operation);
|
||||
psa_hash_abort(&cloned_hash_operation);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define HASH_ALG PSA_ALG_SHA_256
|
||||
|
||||
static const uint8_t sample_message[] = "Hello World!";
|
||||
/* sample_message is terminated with a null byte which is not part of
|
||||
* the message itself so we make sure to subtract it in order to get
|
||||
* the message length. */
|
||||
static const size_t sample_message_length = sizeof(sample_message) - 1;
|
||||
|
||||
#define EXPECTED_HASH_VALUE { \
|
||||
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
|
||||
0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \
|
||||
0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
|
||||
}
|
||||
|
||||
static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
|
||||
static const size_t expected_hash_len = sizeof(expected_hash);
|
||||
|
||||
int psa_hash_compute_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
|
||||
size_t hash_length;
|
||||
|
||||
mbedtls_printf("PSA Crypto API: SHA-256 example\n\n");
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Clear local variables prior to one-shot hash demo */
|
||||
memset(hash, 0, sizeof(hash));
|
||||
hash_length = 0;
|
||||
|
||||
/* Compute hash using one-shot function call */
|
||||
status = psa_hash_compute(HASH_ALG,
|
||||
sample_message, sample_message_length,
|
||||
hash, sizeof(hash),
|
||||
&hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_compute failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (hash_length != expected_hash_len ||
|
||||
(memcmp(hash, expected_hash, expected_hash_len) != 0)) {
|
||||
mbedtls_printf("One-shot hash operation gave the wrong result!\n\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mbedtls_printf("One-shot hash operation successful!\n\n");
|
||||
|
||||
/* Print out result */
|
||||
mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message);
|
||||
|
||||
for (size_t j = 0; j < expected_hash_len; j++) {
|
||||
mbedtls_printf("%02x", hash[j]);
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
int psa_hkdf_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
/* Example test vector from RFC 5869 */
|
||||
|
||||
/* Input keying material (IKM) */
|
||||
unsigned char ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
|
||||
|
||||
unsigned char salt[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
|
||||
|
||||
/* Context and application specific information, which can be of zero length */
|
||||
unsigned char info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 };
|
||||
|
||||
/* Expected OKM based on the RFC 5869-provided test vector */
|
||||
unsigned char expected_okm[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43,
|
||||
0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90,
|
||||
0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4,
|
||||
0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
|
||||
0x58, 0x65 };
|
||||
|
||||
/* The output size of the HKDF function depends on the hash function used.
|
||||
* In our case we use SHA-256, which produces a 32 byte fingerprint.
|
||||
* Therefore, we allocate a buffer of 32 bytes to hold the output keying
|
||||
* material (OKM).
|
||||
*/
|
||||
unsigned char output[32];
|
||||
|
||||
psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
|
||||
|
||||
printf("PSA Crypto API: HKDF SHA-256 example\n\n");
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_HKDF(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE);
|
||||
|
||||
status = psa_import_key(&attributes, ikm, sizeof(ikm), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_setup(&operation, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_setup failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT,
|
||||
salt, sizeof(salt));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_input_bytes (salt) failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_input_key failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_INFO,
|
||||
info, sizeof(info));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_input_bytes (info) failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_output_bytes(&operation, output, sizeof(output));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_output_bytes failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_key_derivation_abort(&operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_key_derivation_abort failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("OKM: \n");
|
||||
|
||||
for (size_t j = 0; j < sizeof(output); j++) {
|
||||
if (output[j] != expected_okm[j]) {
|
||||
printf("\n --- Unexpected outcome!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (j % 8 == 0) {
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%02x ", output[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define BUFFER_SIZE 500
|
||||
|
||||
#define SERVER_PK_VALUE { \
|
||||
0x04, 0xde, 0xa5, 0xe4, 0x5d, 0x0e, 0xa3, 0x7f, 0xc5, \
|
||||
0x66, 0x23, 0x2a, 0x50, 0x8f, 0x4a, 0xd2, 0x0e, 0xa1, \
|
||||
0x3d, 0x47, 0xe4, 0xbf, 0x5f, 0xa4, 0xd5, 0x4a, 0x57, \
|
||||
0xa0, 0xba, 0x01, 0x20, 0x42, 0x08, 0x70, 0x97, 0x49, \
|
||||
0x6e, 0xfc, 0x58, 0x3f, 0xed, 0x8b, 0x24, 0xa5, 0xb9, \
|
||||
0xbe, 0x9a, 0x51, 0xde, 0x06, 0x3f, 0x5a, 0x00, 0xa8, \
|
||||
0xb6, 0x98, 0xa1, 0x6f, 0xd7, 0xf2, 0x9b, 0x54, 0x85, \
|
||||
0xf3, 0x20 \
|
||||
}
|
||||
|
||||
#define KEY_BITS 256
|
||||
|
||||
int psa_key_agreement_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t client_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_attributes_t server_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t client_key_id = 0;
|
||||
psa_key_id_t server_key_id = 0;
|
||||
uint8_t client_pk[BUFFER_SIZE] = { 0 };
|
||||
size_t client_pk_len;
|
||||
size_t key_bits;
|
||||
psa_key_type_t key_type;
|
||||
|
||||
const uint8_t server_pk[] = SERVER_PK_VALUE;
|
||||
uint8_t derived_key[BUFFER_SIZE] = { 0 };
|
||||
size_t derived_key_len;
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&client_attributes, PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&client_attributes, PSA_ALG_ECDH);
|
||||
psa_set_key_type(&client_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(&client_attributes, KEY_BITS);
|
||||
|
||||
/* Generate ephemeral key pair */
|
||||
status = psa_generate_key(&client_attributes, &client_key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_generate_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
status = psa_export_public_key(client_key_id,
|
||||
client_pk, sizeof(client_pk),
|
||||
&client_pk_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_export_public_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
mbedtls_printf("Client Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", client_pk_len);
|
||||
|
||||
for (size_t j = 0; j < client_pk_len; j++) {
|
||||
if (j % 8 == 0) {
|
||||
mbedtls_printf("\n ");
|
||||
}
|
||||
mbedtls_printf("%02x ", client_pk[j]);
|
||||
}
|
||||
mbedtls_printf("\n\n");
|
||||
|
||||
psa_set_key_usage_flags(&server_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
|
||||
psa_set_key_algorithm(&server_attributes, PSA_ALG_ECDSA_ANY);
|
||||
psa_set_key_type(&server_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
/* Import server public key */
|
||||
status = psa_import_key(&server_attributes, server_pk, sizeof(server_pk), &server_key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_get_key_attributes(server_key_id, &check_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_get_key_attributes failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
key_bits = psa_get_key_bits(&check_attributes);
|
||||
if (key_bits != 256) {
|
||||
mbedtls_printf("Incompatible key size!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
key_type = psa_get_key_type(&check_attributes);
|
||||
if (key_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
mbedtls_printf("Unsupported key type!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
mbedtls_printf("Server Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", sizeof(server_pk));
|
||||
|
||||
for (size_t j = 0; j < sizeof(server_pk); j++) {
|
||||
if (j % 8 == 0) {
|
||||
mbedtls_printf("\n ");
|
||||
}
|
||||
mbedtls_printf("%02x ", server_pk[j]);
|
||||
}
|
||||
mbedtls_printf("\n\n");
|
||||
|
||||
/* Generate ECDHE derived key */
|
||||
status = psa_raw_key_agreement(PSA_ALG_ECDH, // algorithm
|
||||
client_key_id, // client secret key
|
||||
server_pk, sizeof(server_pk), // server public key
|
||||
derived_key, sizeof(derived_key), // buffer to store derived key
|
||||
&derived_key_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_raw_key_agreement failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
mbedtls_printf("Derived Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", derived_key_len);
|
||||
|
||||
for (size_t j = 0; j < derived_key_len; j++) {
|
||||
if (j % 8 == 0) {
|
||||
mbedtls_printf("\n ");
|
||||
}
|
||||
mbedtls_printf("%02x ", derived_key[j]);
|
||||
}
|
||||
mbedtls_printf("\n");
|
||||
|
||||
psa_destroy_key(server_key_id);
|
||||
psa_destroy_key(client_key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
/* constant-time buffer comparison */
|
||||
static inline int safer_memcmp(const void *a, const void *b, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
volatile const unsigned char *A = (volatile const unsigned char *) a;
|
||||
volatile const unsigned char *B = (volatile const unsigned char *) b;
|
||||
volatile unsigned char diff = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
/* Read volatile data in order before computing diff.
|
||||
* This avoids IAR compiler warning:
|
||||
* 'the order of volatile accesses is undefined ..' */
|
||||
unsigned char x = A[i], y = B[i];
|
||||
diff |= x ^ y;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
int psa_mac_main(void)
|
||||
{
|
||||
uint8_t input[] = "Hello World!";
|
||||
psa_status_t status;
|
||||
size_t mac_size_real = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
uint8_t mac[PSA_MAC_MAX_SIZE];
|
||||
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||
const uint8_t key_bytes[16] = "kkkkkkkkkkkkkkkk";
|
||||
const uint8_t mbedtls_test_hmac_sha256[] = {
|
||||
0xae, 0x72, 0x34, 0x5a, 0x10, 0x36, 0xfb, 0x71,
|
||||
0x35, 0x3c, 0x7d, 0x6c, 0x81, 0x98, 0x52, 0x86,
|
||||
0x00, 0x4a, 0x43, 0x7c, 0x2d, 0xb3, 0x1a, 0xd8,
|
||||
0x67, 0xb1, 0xad, 0x11, 0x4d, 0x18, 0x49, 0x8b
|
||||
};
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE |
|
||||
PSA_KEY_USAGE_SIGN_HASH |
|
||||
PSA_KEY_USAGE_SIGN_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Single-part MAC operation with psa_mac_compute() */
|
||||
status = psa_mac_compute(key_id,
|
||||
PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
input,
|
||||
sizeof(input),
|
||||
mac,
|
||||
sizeof(mac),
|
||||
&mac_size_real);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_mac_compute failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("HMAC-SHA-256(%s) with psa_mac_compute():\n", input);
|
||||
|
||||
for (size_t j = 0; j < mac_size_real; j++) {
|
||||
if (j % 8 == 0) {
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%02x ", mac[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (safer_memcmp(mac,
|
||||
mbedtls_test_hmac_sha256,
|
||||
mac_size_real
|
||||
) != 0) {
|
||||
printf("\nMAC verified incorrectly!\n");
|
||||
} else {
|
||||
printf("\nMAC verified correctly!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Single-part MAC operation with psa_mac_verify() */
|
||||
status = psa_mac_verify(key_id,
|
||||
PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
input,
|
||||
sizeof(input),
|
||||
mbedtls_test_hmac_sha256,
|
||||
sizeof(mbedtls_test_hmac_sha256));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_mac_verify failed\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
printf("psa_mac_verify passed successfully\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Multi-part MAC operation */
|
||||
status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_mac_sign_setup failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_mac_update(&operation, input, sizeof(input));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_mac_update failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_mac_sign_finish(&operation, mac, sizeof(mac), &mac_size_real);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_mac_sign_finish failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (safer_memcmp(mac,
|
||||
mbedtls_test_hmac_sha256,
|
||||
mac_size_real
|
||||
) != 0) {
|
||||
printf("MAC, calculated with multi-part MAC operation, verified incorrectly!\n");
|
||||
} else {
|
||||
printf("MAC, calculated with multi-part MAC operation, verified correctly!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/private/entropy.h"
|
||||
|
||||
#define BUFFER_SIZE 100
|
||||
|
||||
int psa_random_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
uint8_t output[BUFFER_SIZE] = { 0 };
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_generate_random(output, BUFFER_SIZE);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("psa_generate_random failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Random bytes generated:\n");
|
||||
|
||||
for (size_t j = 0; j < BUFFER_SIZE; j++) {
|
||||
if (j % 8 == 0) {
|
||||
printf("\n ");
|
||||
}
|
||||
printf("%02x ", output[j]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define KEY_BYTES_VALUE { \
|
||||
0x49, 0xc9, 0xa8, 0xc1, 0x8c, 0x4b, 0x88, 0x56, 0x38, 0xc4, 0x31, 0xcf, \
|
||||
0x1d, 0xf1, 0xc9, 0x94, 0x13, 0x16, 0x09, 0xb5, 0x80, 0xd4, 0xfd, 0x43, \
|
||||
0xa0, 0xca, 0xb1, 0x7d, 0xb2, 0xf1, 0x3e, 0xee \
|
||||
}
|
||||
|
||||
#define PLAINTEXT_VALUE "Hello World!"
|
||||
|
||||
/* SHA-256(plaintext) */
|
||||
#define HASH_VALUE { \
|
||||
0x5a, 0x09, 0xe8, 0xfa, 0x9c, 0x77, 0x80, 0x7b, 0x24, 0xe9, 0x9c, 0x9c, \
|
||||
0xf9, 0x99, 0xde, 0xbf, 0xad, 0x84, 0x41, 0xe2, 0x69, 0xeb, 0x96, 0x0e, \
|
||||
0x20, 0x1f, 0x61, 0xfc, 0x3d, 0xe2, 0x0d, 0x5a \
|
||||
}
|
||||
|
||||
int psa_sign_verify_main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
|
||||
size_t signature_length;
|
||||
const uint8_t key_bytes[] = KEY_BYTES_VALUE;
|
||||
const uint8_t plaintext[] = PLAINTEXT_VALUE;
|
||||
const uint8_t hash[] = HASH_VALUE;
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_import_key failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_sign_hash(key_id, // key handle
|
||||
PSA_ALG_ECDSA(PSA_ALG_SHA_256), // signature algorithm
|
||||
hash, sizeof(hash), // hash of the message
|
||||
signature, sizeof(signature), // signature (as output)
|
||||
&signature_length); // length of signature output
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_sign_hash failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
mbedtls_printf("ECDSA-SHA256 signature of SHA-256('%s'):\n", plaintext);
|
||||
|
||||
for (size_t j = 0; j < signature_length; j++) {
|
||||
if (j % 8 == 0) {
|
||||
mbedtls_printf("\n ");
|
||||
}
|
||||
mbedtls_printf("%02x ", signature[j]);
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
|
||||
status = psa_verify_hash(key_id, // key handle
|
||||
PSA_ALG_ECDSA(PSA_ALG_SHA_256), // signature algorithm
|
||||
hash, sizeof(hash), // hash of message
|
||||
signature, signature_length); // signature
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_verify_hash failed\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
mbedtls_printf("\nSignature verification successful!\n");
|
||||
}
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
+11
-368
@@ -1,380 +1,23 @@
|
||||
/* PSA firmware framework client API */
|
||||
/* psasim test client */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <psa/error.h>
|
||||
/* Includes from mbedtls */
|
||||
#include "psa/crypto.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef struct internal_handle {
|
||||
int server_qid;
|
||||
int client_qid;
|
||||
int internal_server_qid;
|
||||
int valid;
|
||||
} internal_handle_t;
|
||||
|
||||
/* Access to this global is not thread safe */
|
||||
#define MAX_HANDLES 32
|
||||
static internal_handle_t handles[MAX_HANDLES] = { { 0 } };
|
||||
|
||||
static int get_next_free_handle()
|
||||
int main()
|
||||
{
|
||||
/* Never return handle 0 as it's a special null handle */
|
||||
for (int i = 1; i < MAX_HANDLES; i++) {
|
||||
if (handles[i].valid == 0) {
|
||||
return i;
|
||||
}
|
||||
/* psa_crypto_init() connects to the server */
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
ERROR("psa_crypto_init returned %d", status);
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_is_valid(psa_handle_t handle)
|
||||
{
|
||||
if (handle > 0 && handle < MAX_HANDLES) {
|
||||
if (handles[handle].valid == 1) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
PROGRAMMER_ERROR("ERROR: Invalid handle");
|
||||
mbedtls_psa_crypto_free();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_queue_info(char *path, int *cqid, int *sqid)
|
||||
{
|
||||
|
||||
key_t server_queue_key;
|
||||
int rx_qid, server_qid;
|
||||
|
||||
INFO("Attempting to contact a RoT service queue");
|
||||
|
||||
if ((rx_qid = msgget(IPC_PRIVATE, 0660)) == -1) {
|
||||
INFO("msgget: rx_qid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((server_queue_key = ftok(path, PROJECT_ID)) == -1) {
|
||||
INFO("ftok");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((server_qid = msgget(server_queue_key, 0)) == -1) {
|
||||
INFO("msgget: server_qid");
|
||||
return -3;
|
||||
}
|
||||
|
||||
*cqid = rx_qid;
|
||||
*sqid = server_qid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type,
|
||||
int *internal_server_qid)
|
||||
{
|
||||
|
||||
struct message response, request;
|
||||
psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED;
|
||||
size_t invec_seek[4] = { 0 };
|
||||
size_t data_size;
|
||||
psa_status_t invec, outvec; /* TODO: Should these be size_t ? */
|
||||
|
||||
assert(internal_server_qid > 0);
|
||||
|
||||
while (1) {
|
||||
data_size = 0;
|
||||
invec = 0;
|
||||
outvec = 0;
|
||||
|
||||
// read response from server
|
||||
if (msgrcv(rx_qid, &response, sizeof(struct message_text), 0, 0) == -1) {
|
||||
puts(" msgrcv failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// process return message from server
|
||||
switch (response.message_type) {
|
||||
case PSA_REPLY:
|
||||
memcpy(&ret, response.message_text.buf, sizeof(psa_status_t));
|
||||
printf(" Message received from server: %d\n", ret);
|
||||
if (type == PSA_IPC_CONNECT && ret > 0) {
|
||||
*internal_server_qid = ret;
|
||||
INFO(" ASSSIGNED q ID %d", *internal_server_qid);
|
||||
ret = PSA_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
break;
|
||||
case READ_REQUEST:
|
||||
/* read data request */
|
||||
request.message_type = READ_RESPONSE;
|
||||
|
||||
assert(vecs != 0);
|
||||
|
||||
memcpy(&invec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition asked for %lu bytes from invec %d", data_size, invec);
|
||||
|
||||
/* need to add more checks here */
|
||||
assert(invec >= 0 && invec < PSA_MAX_IOVEC);
|
||||
|
||||
if (data_size > MAX_FRAGMENT_SIZE) {
|
||||
data_size = MAX_FRAGMENT_SIZE;
|
||||
}
|
||||
|
||||
/* send response */
|
||||
INFO(" invec_seek[invec] is %lu", invec_seek[invec]);
|
||||
INFO(" Reading from offset %p", vecs->in_vec[invec].base + invec_seek[invec]);
|
||||
memcpy(request.message_text.buf,
|
||||
(vecs->in_vec[invec].base + invec_seek[invec]),
|
||||
data_size);
|
||||
|
||||
/* update invec base TODO: check me */
|
||||
invec_seek[invec] = invec_seek[invec] + data_size;
|
||||
|
||||
INFO(" Sending message of type %li", request.message_type);
|
||||
INFO(" with content %s\n", request.message_text.buf);
|
||||
|
||||
if (msgsnd(*internal_server_qid, &request,
|
||||
sizeof(int) + sizeof(uint32_t) + data_size, 0) == -1) {
|
||||
INFO("Internal error: failed to respond to read request");
|
||||
}
|
||||
break;
|
||||
case WRITE_REQUEST:
|
||||
assert(vecs != 0);
|
||||
|
||||
request.message_type = WRITE_RESPONSE;
|
||||
|
||||
memcpy(&outvec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf + sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition wants to write %lu bytes to outvec %d", data_size, outvec);
|
||||
|
||||
assert(outvec >= 0 && outvec < PSA_MAX_IOVEC);
|
||||
|
||||
/* copy memory into message and send back amount written */
|
||||
size_t sofar = vecs->out_vec[outvec].len;
|
||||
memcpy(vecs->out_vec[outvec].base + sofar,
|
||||
response.message_text.buf+(sizeof(size_t)*2), data_size);
|
||||
INFO(" Data size is %lu\n", data_size);
|
||||
vecs->out_vec[outvec].len += data_size;
|
||||
|
||||
INFO(" Sending message of type %li\n", request.message_type);
|
||||
|
||||
/* send response */
|
||||
if (msgsnd(*internal_server_qid, &request, sizeof(int) + data_size, 0) == -1) {
|
||||
INFO("Internal error: failed to respond to write request");
|
||||
}
|
||||
break;
|
||||
case SKIP_REQUEST:
|
||||
memcpy(&invec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition asked to skip %lu bytes in invec %d", data_size, invec);
|
||||
assert(invec >= 0 && invec < PSA_MAX_IOVEC);
|
||||
/* update invec base TODO: check me */
|
||||
invec_seek[invec] = invec_seek[invec] + data_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
FATAL(" ERROR: unknown internal message type: %ld\n",
|
||||
response.message_type);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static psa_status_t send(int rx_qid, int server_qid, int *internal_server_qid,
|
||||
int32_t type, uint32_t minor_version, vectors_t *vecs)
|
||||
{
|
||||
{
|
||||
psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED;
|
||||
size_t request_msg_size = (sizeof(int) + sizeof(long)); /* msg type plus queue id */
|
||||
struct message request;
|
||||
request.message_type = 1; /* TODO: change this */
|
||||
request.message_text.psa_type = type;
|
||||
vector_sizes_t vec_sizes;
|
||||
|
||||
/* If the client is non-secure then set the NS bit */
|
||||
if (__psa_ff_client_security_state != 0) {
|
||||
request.message_type |= NON_SECURE;
|
||||
}
|
||||
|
||||
assert(request.message_type >= 0);
|
||||
|
||||
INFO("SEND: Sending message of type %ld with psa_type %d", request.message_type, type);
|
||||
INFO(" internal_server_qid = %i", *internal_server_qid);
|
||||
|
||||
request.message_text.qid = rx_qid;
|
||||
|
||||
if (type == PSA_IPC_CONNECT) {
|
||||
memcpy(request.message_text.buf, &minor_version, sizeof(minor_version));
|
||||
request_msg_size = request_msg_size + sizeof(minor_version);
|
||||
INFO(" Request msg size is %lu", request_msg_size);
|
||||
} else {
|
||||
assert(internal_server_qid > 0);
|
||||
}
|
||||
|
||||
if (vecs != NULL && type >= PSA_IPC_CALL) {
|
||||
|
||||
bzero(&vec_sizes, sizeof(vec_sizes));
|
||||
|
||||
/* Copy invec sizes */
|
||||
for (size_t i = 0; i < (vecs->in_len); i++) {
|
||||
vec_sizes.invec_sizes[i] = vecs->in_vec[i].len;
|
||||
INFO(" Client sending vector %lu: %lu", i, vec_sizes.invec_sizes[i]);
|
||||
}
|
||||
|
||||
/* Copy outvec sizes */
|
||||
for (size_t i = 0; i < (vecs->out_len); i++) {
|
||||
vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len;
|
||||
|
||||
/* Reset to 0 since we need to eventually fill in with bytes written */
|
||||
vecs->out_vec[i].len = 0;
|
||||
}
|
||||
|
||||
memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes));
|
||||
request_msg_size = request_msg_size + sizeof(vec_sizes);
|
||||
}
|
||||
|
||||
INFO(" Sending and then waiting");
|
||||
|
||||
// send message to server
|
||||
if (msgsnd(server_qid, &request, request_msg_size, 0) == -1) {
|
||||
puts(" msgsnd failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return process_response(rx_qid, vecs, type, internal_server_qid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t psa_framework_version(void)
|
||||
{
|
||||
return PSA_FRAMEWORK_VERSION;
|
||||
}
|
||||
|
||||
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
|
||||
{
|
||||
|
||||
int idx;
|
||||
psa_status_t ret;
|
||||
char pathname[PATHNAMESIZE] = { 0 };
|
||||
|
||||
idx = get_next_free_handle();
|
||||
|
||||
/* if there's a free handle available */
|
||||
if (idx >= 0) {
|
||||
snprintf(pathname, PATHNAMESIZE - 1, "/tmp/psa_service_%u", sid);
|
||||
INFO("Attempting to contact RoT service at %s", pathname);
|
||||
|
||||
/* if communication is possible */
|
||||
if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) {
|
||||
|
||||
ret = send(handles[idx].client_qid,
|
||||
handles[idx].server_qid,
|
||||
&handles[idx].internal_server_qid,
|
||||
PSA_IPC_CONNECT,
|
||||
minor_version,
|
||||
NULL);
|
||||
|
||||
/* if connection accepted by RoT service */
|
||||
if (ret >= 0) {
|
||||
handles[idx].valid = 1;
|
||||
return idx;
|
||||
} else {
|
||||
INFO("Server didn't like you");
|
||||
}
|
||||
} else {
|
||||
INFO("Couldn't contact RoT service. Does it exist?");
|
||||
|
||||
if (__psa_ff_client_security_state == 0) {
|
||||
PROGRAMMER_ERROR("Invalid SID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Couldn't obtain a free handle");
|
||||
return PSA_ERROR_CONNECTION_REFUSED;
|
||||
}
|
||||
|
||||
uint32_t psa_version(uint32_t sid)
|
||||
{
|
||||
int idx;
|
||||
psa_status_t ret;
|
||||
char pathname[PATHNAMESIZE] = { 0 };
|
||||
|
||||
idx = get_next_free_handle();
|
||||
|
||||
if (idx >= 0) {
|
||||
snprintf(pathname, PATHNAMESIZE, "/tmp/psa_service_%u", sid);
|
||||
if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) {
|
||||
ret = send(handles[idx].client_qid,
|
||||
handles[idx].server_qid,
|
||||
&handles[idx].internal_server_qid,
|
||||
VERSION_REQUEST,
|
||||
0,
|
||||
NULL);
|
||||
INFO("psa_version: Recieved from server %d\n", ret);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
INFO("psa_version failed: does the service exist?");
|
||||
return PSA_VERSION_NONE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
handle_is_valid(handle);
|
||||
|
||||
if ((in_len + out_len) > PSA_MAX_IOVEC) {
|
||||
PROGRAMMER_ERROR("Too many iovecs: %lu + %lu", in_len, out_len);
|
||||
}
|
||||
|
||||
vectors_t vecs = { 0 };
|
||||
vecs.in_vec = in_vec;
|
||||
vecs.in_len = in_len;
|
||||
vecs.out_vec = out_vec;
|
||||
vecs.out_len = out_len;
|
||||
|
||||
return send(handles[handle].client_qid,
|
||||
handles[handle].server_qid,
|
||||
&handles[handle].internal_server_qid,
|
||||
type,
|
||||
0,
|
||||
&vecs);
|
||||
}
|
||||
|
||||
void psa_close(psa_handle_t handle)
|
||||
{
|
||||
handle_is_valid(handle);
|
||||
if (send(handles[handle].client_qid, handles[handle].server_qid,
|
||||
&handles[handle].internal_server_qid, PSA_IPC_DISCONNECT, 0, NULL)) {
|
||||
puts("ERROR: Couldn't send disconnect msg");
|
||||
} else {
|
||||
if (msgctl(handles[handle].client_qid, IPC_RMID, NULL) != 0) {
|
||||
puts("ERROR: Failed to delete msg queue");
|
||||
}
|
||||
}
|
||||
INFO("Closing handle %u", handle);
|
||||
handles[handle].valid = 0;
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/* Common code between clients and services */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
int __psa_ff_client_security_state = NON_SECURE;
|
||||
|
||||
#if 0
|
||||
static void _printbits(uint32_t num)
|
||||
{
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((num >> (31-i) & 0x1)) {
|
||||
INFO("1");
|
||||
} else {
|
||||
INFO("0");
|
||||
}
|
||||
}
|
||||
INFO("\n");
|
||||
}
|
||||
#endif
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Common definitions used for clients and services */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <psa/service.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_TEST 1
|
||||
#else
|
||||
#define DEBUG_TEST 0
|
||||
#endif
|
||||
|
||||
#define PRINT(...) \
|
||||
do { if (DEBUG_TEST) fprintf(stderr, __VA_ARGS__); } while (0)
|
||||
#define INFO(...) \
|
||||
do { if (DEBUG_TEST) { PRINT("%s", __FILE__); PRINT(" INFO: " __VA_ARGS__); printf("\n"); \
|
||||
} } while (0)
|
||||
|
||||
#define PROGRAMMER_ERROR(...) \
|
||||
do { if (DEBUG_TEST) { PRINT("%s:%d:%s(): PROGRAMMER ERROR", __FILE__, __LINE__, __func__); \
|
||||
PRINT(__VA_ARGS__); } abort(); } while (0)
|
||||
|
||||
#define FATAL(...) \
|
||||
do { if (DEBUG_TEST) { PRINT("%s:%d:%s(): INTERNAL ERROR", __FILE__, __LINE__, __func__); PRINT( \
|
||||
__VA_ARGS__); } abort(); } while (0)
|
||||
|
||||
|
||||
#define PROJECT_ID 'M'
|
||||
#define PATHNAMESIZE 64
|
||||
|
||||
/* Increasing this might break on some platforms */
|
||||
#define MAX_FRAGMENT_SIZE 200
|
||||
|
||||
#define CONNECT_REQUEST 1
|
||||
#define CALL_REQUEST 2
|
||||
#define CLOSE_REQUEST 3
|
||||
#define VERSION_REQUEST 4
|
||||
#define READ_REQUEST 5
|
||||
#define READ_RESPONSE 6
|
||||
#define WRITE_REQUEST 7
|
||||
#define WRITE_RESPONSE 8
|
||||
#define SKIP_REQUEST 9
|
||||
#define PSA_REPLY 10
|
||||
|
||||
#define NON_SECURE (1 << 30)
|
||||
|
||||
/* Note that this implementation is functional and not secure */
|
||||
extern int __psa_ff_client_security_state;
|
||||
|
||||
struct message_text {
|
||||
int qid;
|
||||
int32_t psa_type;
|
||||
char buf[MAX_FRAGMENT_SIZE];
|
||||
};
|
||||
|
||||
|
||||
struct message {
|
||||
long message_type;
|
||||
struct message_text message_text;
|
||||
};
|
||||
|
||||
struct request_msg_internal {
|
||||
psa_invec invec;
|
||||
size_t skip_num;
|
||||
};
|
||||
|
||||
struct skip_request_msg {
|
||||
long message_type;
|
||||
struct request_msg_internal message_text;
|
||||
};
|
||||
|
||||
typedef struct vectors {
|
||||
const psa_invec *in_vec;
|
||||
size_t in_len;
|
||||
psa_outvec *out_vec;
|
||||
size_t out_len;
|
||||
} vectors_t;
|
||||
|
||||
typedef struct vector_sizes {
|
||||
size_t invec_sizes[PSA_MAX_IOVEC];
|
||||
size_t outvec_sizes[PSA_MAX_IOVEC];
|
||||
} vector_sizes_t;
|
||||
@@ -3,14 +3,14 @@
|
||||
"name":"TEST_PARTITION",
|
||||
"type":"PSA-ROT",
|
||||
"priority":"LOW",
|
||||
"entry_point":"psa_sha256_main",
|
||||
"entry_point":"psa_server_main",
|
||||
"stack_size":"0x400",
|
||||
"heap_size":"0x100",
|
||||
"services":[
|
||||
{
|
||||
"name":"PSA_SID_SHA256",
|
||||
"name":"PSA_SID_CRYPTO",
|
||||
"sid":"0x0000F000",
|
||||
"signal":"PSA_SHA256",
|
||||
"signal":"PSA_CRYPTO",
|
||||
"non_secure_clients": "true",
|
||||
"minor_version":1,
|
||||
"minor_policy":"STRICT"
|
||||
@@ -0,0 +1,385 @@
|
||||
/* PSA firmware framework client API */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "common.h"
|
||||
#include "error_ext.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct internal_handle {
|
||||
int server_qid;
|
||||
int client_qid;
|
||||
int internal_server_qid;
|
||||
int valid;
|
||||
} internal_handle_t;
|
||||
|
||||
typedef struct vectors {
|
||||
const psa_invec *in_vec;
|
||||
size_t in_len;
|
||||
psa_outvec *out_vec;
|
||||
size_t out_len;
|
||||
} vectors_t;
|
||||
|
||||
/* Note that this implementation is functional and not secure */
|
||||
int __psa_ff_client_security_state = NON_SECURE;
|
||||
|
||||
/* Access to this global is not thread safe */
|
||||
#define MAX_HANDLES 32
|
||||
static internal_handle_t handles[MAX_HANDLES] = { { 0 } };
|
||||
|
||||
static int get_next_free_handle()
|
||||
{
|
||||
/* Never return handle 0 as it's a special null handle */
|
||||
for (int i = 1; i < MAX_HANDLES; i++) {
|
||||
if (handles[i].valid == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_is_valid(psa_handle_t handle)
|
||||
{
|
||||
if (handle > 0 && handle < MAX_HANDLES) {
|
||||
if (handles[handle].valid == 1) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ERROR("ERROR: Invalid handle");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_queue_info(char *path, int *cqid, int *sqid)
|
||||
{
|
||||
key_t server_queue_key;
|
||||
int rx_qid, server_qid;
|
||||
|
||||
INFO("Attempting to contact a RoT service queue");
|
||||
|
||||
if ((rx_qid = msgget(IPC_PRIVATE, 0660)) == -1) {
|
||||
ERROR("msgget: rx_qid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((server_queue_key = ftok(path, PROJECT_ID)) == -1) {
|
||||
ERROR("ftok");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((server_qid = msgget(server_queue_key, 0)) == -1) {
|
||||
ERROR("msgget: server_qid");
|
||||
return -3;
|
||||
}
|
||||
|
||||
*cqid = rx_qid;
|
||||
*sqid = server_qid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type,
|
||||
int *internal_server_qid)
|
||||
{
|
||||
struct message response, request;
|
||||
psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED;
|
||||
size_t invec_seek[4] = { 0 };
|
||||
size_t data_size;
|
||||
psa_status_t invec, outvec; /* TODO: Should these be size_t ? */
|
||||
|
||||
assert(internal_server_qid > 0);
|
||||
|
||||
while (1) {
|
||||
data_size = 0;
|
||||
invec = 0;
|
||||
outvec = 0;
|
||||
|
||||
/* read response from server */
|
||||
if (msgrcv(rx_qid, &response, sizeof(struct message_text), 0, 0) == -1) {
|
||||
ERROR(" msgrcv failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* process return message from server */
|
||||
switch (response.message_type) {
|
||||
case PSA_REPLY:
|
||||
memcpy(&ret, response.message_text.buf, sizeof(psa_status_t));
|
||||
INFO(" Message received from server: %d", ret);
|
||||
if (type == PSA_IPC_CONNECT && ret > 0) {
|
||||
*internal_server_qid = ret;
|
||||
INFO(" ASSSIGNED q ID %d", *internal_server_qid);
|
||||
ret = PSA_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
break;
|
||||
case READ_REQUEST:
|
||||
/* read data request */
|
||||
request.message_type = READ_RESPONSE;
|
||||
|
||||
assert(vecs != 0);
|
||||
|
||||
memcpy(&invec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition asked for %lu bytes from invec %d", data_size, invec);
|
||||
|
||||
/* need to add more checks here */
|
||||
assert(invec >= 0 && invec < PSA_MAX_IOVEC);
|
||||
|
||||
if (data_size > MAX_FRAGMENT_SIZE) {
|
||||
data_size = MAX_FRAGMENT_SIZE;
|
||||
}
|
||||
|
||||
/* send response */
|
||||
INFO(" invec_seek[invec] is %lu", invec_seek[invec]);
|
||||
INFO(" Reading from offset %p", vecs->in_vec[invec].base + invec_seek[invec]);
|
||||
memcpy(request.message_text.buf,
|
||||
(vecs->in_vec[invec].base + invec_seek[invec]),
|
||||
data_size);
|
||||
|
||||
/* update invec base TODO: check me */
|
||||
invec_seek[invec] = invec_seek[invec] + data_size;
|
||||
|
||||
INFO(" Sending message of type %li", request.message_type);
|
||||
INFO(" with content %s", request.message_text.buf);
|
||||
|
||||
if (msgsnd(*internal_server_qid, &request,
|
||||
sizeof(int) + sizeof(uint32_t) + data_size, 0) == -1) {
|
||||
ERROR("Internal error: failed to respond to read request");
|
||||
}
|
||||
break;
|
||||
case WRITE_REQUEST:
|
||||
assert(vecs != 0);
|
||||
|
||||
request.message_type = WRITE_RESPONSE;
|
||||
|
||||
memcpy(&outvec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf + sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition wants to write %lu bytes to outvec %d", data_size, outvec);
|
||||
|
||||
assert(outvec >= 0 && outvec < PSA_MAX_IOVEC);
|
||||
|
||||
/* copy memory into message and send back amount written */
|
||||
size_t sofar = vecs->out_vec[outvec].len;
|
||||
memcpy(vecs->out_vec[outvec].base + sofar,
|
||||
response.message_text.buf+(sizeof(size_t)*2), data_size);
|
||||
INFO(" Data size is %lu", data_size);
|
||||
vecs->out_vec[outvec].len += data_size;
|
||||
|
||||
INFO(" Sending message of type %li", request.message_type);
|
||||
|
||||
/* send response */
|
||||
if (msgsnd(*internal_server_qid, &request, sizeof(int) + data_size, 0) == -1) {
|
||||
ERROR("Internal error: failed to respond to write request");
|
||||
}
|
||||
break;
|
||||
case SKIP_REQUEST:
|
||||
memcpy(&invec, response.message_text.buf, sizeof(psa_status_t));
|
||||
memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t));
|
||||
INFO(" Partition asked to skip %lu bytes in invec %d", data_size, invec);
|
||||
assert(invec >= 0 && invec < PSA_MAX_IOVEC);
|
||||
/* update invec base TODO: check me */
|
||||
invec_seek[invec] = invec_seek[invec] + data_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
FATAL(" ERROR: unknown internal message type: %ld",
|
||||
response.message_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static psa_status_t send(int rx_qid, int server_qid, int *internal_server_qid,
|
||||
int32_t type, uint32_t minor_version, vectors_t *vecs)
|
||||
{
|
||||
psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED;
|
||||
size_t request_msg_size = (sizeof(int) + sizeof(long)); /* msg type plus queue id */
|
||||
struct message request;
|
||||
request.message_type = 1; /* TODO: change this */
|
||||
request.message_text.psa_type = type;
|
||||
vector_sizes_t vec_sizes;
|
||||
|
||||
/* If the client is non-secure then set the NS bit */
|
||||
if (__psa_ff_client_security_state != 0) {
|
||||
request.message_type |= NON_SECURE;
|
||||
}
|
||||
|
||||
assert(request.message_type >= 0);
|
||||
|
||||
INFO("SEND: Sending message of type %ld with psa_type %d", request.message_type, type);
|
||||
INFO(" internal_server_qid = %i", *internal_server_qid);
|
||||
|
||||
request.message_text.qid = rx_qid;
|
||||
|
||||
if (type == PSA_IPC_CONNECT) {
|
||||
memcpy(request.message_text.buf, &minor_version, sizeof(minor_version));
|
||||
request_msg_size = request_msg_size + sizeof(minor_version);
|
||||
INFO(" Request msg size is %lu", request_msg_size);
|
||||
} else {
|
||||
assert(internal_server_qid > 0);
|
||||
}
|
||||
|
||||
if (vecs != NULL && type >= PSA_IPC_CALL) {
|
||||
|
||||
memset(&vec_sizes, 0, sizeof(vec_sizes));
|
||||
|
||||
/* Copy invec sizes */
|
||||
for (size_t i = 0; i < (vecs->in_len); i++) {
|
||||
vec_sizes.invec_sizes[i] = vecs->in_vec[i].len;
|
||||
INFO(" Client sending vector %lu: %lu", i, vec_sizes.invec_sizes[i]);
|
||||
}
|
||||
|
||||
/* Copy outvec sizes */
|
||||
for (size_t i = 0; i < (vecs->out_len); i++) {
|
||||
vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len;
|
||||
|
||||
/* Reset to 0 since we need to eventually fill in with bytes written */
|
||||
vecs->out_vec[i].len = 0;
|
||||
}
|
||||
|
||||
memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes));
|
||||
request_msg_size = request_msg_size + sizeof(vec_sizes);
|
||||
}
|
||||
|
||||
INFO(" Sending and then waiting");
|
||||
|
||||
/* send message to server */
|
||||
if (msgsnd(server_qid, &request, request_msg_size, 0) == -1) {
|
||||
ERROR(" msgsnd failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return process_response(rx_qid, vecs, type, internal_server_qid);
|
||||
}
|
||||
|
||||
|
||||
uint32_t psa_framework_version(void)
|
||||
{
|
||||
return PSA_FRAMEWORK_VERSION;
|
||||
}
|
||||
|
||||
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
|
||||
{
|
||||
int idx;
|
||||
psa_status_t ret;
|
||||
char pathname[PATHNAMESIZE] = { 0 };
|
||||
|
||||
idx = get_next_free_handle();
|
||||
|
||||
/* if there's a free handle available */
|
||||
if (idx >= 0) {
|
||||
snprintf(pathname, PATHNAMESIZE - 1, TMP_FILE_BASE_PATH "psa_service_%u", sid);
|
||||
INFO("Attempting to contact RoT service at %s", pathname);
|
||||
|
||||
/* if communication is possible */
|
||||
if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) {
|
||||
|
||||
ret = send(handles[idx].client_qid,
|
||||
handles[idx].server_qid,
|
||||
&handles[idx].internal_server_qid,
|
||||
PSA_IPC_CONNECT,
|
||||
minor_version,
|
||||
NULL);
|
||||
|
||||
/* if connection accepted by RoT service */
|
||||
if (ret >= 0) {
|
||||
handles[idx].valid = 1;
|
||||
return idx;
|
||||
} else {
|
||||
ERROR("Server didn't like you");
|
||||
}
|
||||
} else {
|
||||
ERROR("Couldn't contact RoT service. Does it exist?");
|
||||
|
||||
if (__psa_ff_client_security_state == 0) {
|
||||
ERROR("Invalid SID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Couldn't obtain a free handle");
|
||||
return PSA_ERROR_CONNECTION_REFUSED;
|
||||
}
|
||||
|
||||
uint32_t psa_version(uint32_t sid)
|
||||
{
|
||||
int idx;
|
||||
psa_status_t ret;
|
||||
char pathname[PATHNAMESIZE] = { 0 };
|
||||
|
||||
idx = get_next_free_handle();
|
||||
|
||||
if (idx >= 0) {
|
||||
snprintf(pathname, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_service_%u", sid);
|
||||
if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) {
|
||||
ret = send(handles[idx].client_qid,
|
||||
handles[idx].server_qid,
|
||||
&handles[idx].internal_server_qid,
|
||||
VERSION_REQUEST,
|
||||
0,
|
||||
NULL);
|
||||
INFO("psa_version: Recieved from server %d", ret);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
ERROR("psa_version failed: does the service exist?");
|
||||
return PSA_VERSION_NONE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
handle_is_valid(handle);
|
||||
|
||||
if ((in_len + out_len) > PSA_MAX_IOVEC) {
|
||||
ERROR("Too many iovecs: %lu + %lu", in_len, out_len);
|
||||
}
|
||||
|
||||
vectors_t vecs = { 0 };
|
||||
vecs.in_vec = in_vec;
|
||||
vecs.in_len = in_len;
|
||||
vecs.out_vec = out_vec;
|
||||
vecs.out_len = out_len;
|
||||
|
||||
return send(handles[handle].client_qid,
|
||||
handles[handle].server_qid,
|
||||
&handles[handle].internal_server_qid,
|
||||
type,
|
||||
0,
|
||||
&vecs);
|
||||
}
|
||||
|
||||
void psa_close(psa_handle_t handle)
|
||||
{
|
||||
handle_is_valid(handle);
|
||||
if (send(handles[handle].client_qid, handles[handle].server_qid,
|
||||
&handles[handle].internal_server_qid, PSA_IPC_DISCONNECT, 0, NULL)) {
|
||||
ERROR("ERROR: Couldn't send disconnect msg");
|
||||
} else {
|
||||
if (msgctl(handles[handle].client_qid, IPC_RMID, NULL) != 0) {
|
||||
ERROR("ERROR: Failed to delete msg queue");
|
||||
}
|
||||
}
|
||||
INFO("Closing handle %u", handle);
|
||||
handles[handle].valid = 0;
|
||||
}
|
||||
@@ -5,10 +5,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <psa/service.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -16,8 +16,12 @@
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <psasim/init.h>
|
||||
|
||||
#include "service.h"
|
||||
#include "init.h"
|
||||
#include "error_ext.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAX_CLIENTS 128
|
||||
#define MAX_MESSAGES 32
|
||||
@@ -25,9 +29,12 @@
|
||||
struct connection {
|
||||
uint32_t client;
|
||||
void *rhandle;
|
||||
int client_to_server_q; // this should be called client to server
|
||||
int client_to_server_q;
|
||||
};
|
||||
|
||||
/* Note that this implementation is functional and not secure. */
|
||||
int __psa_ff_client_security_state = NON_SECURE;
|
||||
|
||||
static psa_msg_t messages[MAX_MESSAGES]; /* Message slots */
|
||||
static uint8_t pending_message[MAX_MESSAGES] = { 0 }; /* Booleans indicating active message slots */
|
||||
static uint32_t message_client[MAX_MESSAGES] = { 0 }; /* Each client's response queue */
|
||||
@@ -69,7 +76,7 @@ void destroy_connection(uint32_t client)
|
||||
connections[idx].rhandle = 0;
|
||||
INFO("Destroying connection");
|
||||
} else {
|
||||
INFO("Couldn't destroy connection for %u", client);
|
||||
ERROR("Couldn't destroy connection for %u", client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +95,6 @@ static void reply(psa_handle_t msg_handle, psa_status_t status)
|
||||
|
||||
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
{
|
||||
|
||||
psa_signal_t mask;
|
||||
struct message msg;
|
||||
vector_sizes_t sizes;
|
||||
@@ -112,7 +118,6 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
} else if (i == 3) {
|
||||
// this must be psa doorbell
|
||||
} else {
|
||||
|
||||
/* Check if this signal corresponds to a queue */
|
||||
if (rot_svc_incoming_queue[i] >= 0 && (pending_message[i] == 0)) {
|
||||
|
||||
@@ -124,8 +129,8 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
IPC_NOWAIT);
|
||||
if (len > 0) {
|
||||
|
||||
INFO("Storing that QID in message_client[%d]\n", i);
|
||||
INFO("The message handle will be %d\n", i);
|
||||
INFO("Storing that QID in message_client[%d]", i);
|
||||
INFO("The message handle will be %d", i);
|
||||
|
||||
msgctl(rot_svc_incoming_queue[i], IPC_STAT, &qinfo);
|
||||
messages[i].client_id = qinfo.msg_lspid; /* PID of last msgsnd(2) call */
|
||||
@@ -149,9 +154,9 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
messages[i].client_id = messages[i].client_id * -1;
|
||||
}
|
||||
|
||||
INFO("Got a message from client ID %d\n", messages[i].client_id);
|
||||
INFO("Message type is %lu\n", msg.message_type);
|
||||
INFO("PSA message type is %d\n", msg.message_text.psa_type);
|
||||
INFO("Got a message from client ID %d", messages[i].client_id);
|
||||
INFO("Message type is %lu", msg.message_type);
|
||||
INFO("PSA message type is %d", msg.message_text.psa_type);
|
||||
|
||||
messages[i].handle = i;
|
||||
|
||||
@@ -161,8 +166,8 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
if (len >= 16) {
|
||||
memcpy(&requested_version, msg.message_text.buf,
|
||||
sizeof(requested_version));
|
||||
INFO("Requesting version %u\n", requested_version);
|
||||
INFO("Implemented version %u\n", rot_svc_versions[i]);
|
||||
INFO("Requesting version %u", requested_version);
|
||||
INFO("Implemented version %u", rot_svc_versions[i]);
|
||||
/* TODO: need to check whether the policy is strict,
|
||||
* and if so, then reject the client if the number doesn't match */
|
||||
|
||||
@@ -195,7 +200,7 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
} else {
|
||||
/* We've run out of system wide connections */
|
||||
reply(i, PSA_ERROR_CONNECTION_BUSY);
|
||||
INFO("Ran out of free connections");
|
||||
ERROR("Ran out of free connections");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -221,7 +226,7 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
memcpy(&messages[i].out_size, &sizes.outvec_sizes,
|
||||
(sizeof(size_t) * PSA_MAX_IOVEC));
|
||||
} else {
|
||||
FATAL("UNKNOWN MESSAGE TYPE RECEIVED %li\n",
|
||||
FATAL("UNKNOWN MESSAGE TYPE RECEIVED %li",
|
||||
msg.message_type);
|
||||
}
|
||||
break;
|
||||
@@ -251,19 +256,15 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
break;
|
||||
} else {
|
||||
/* There is no 'select' function in SysV to block on multiple queues, so busy-wait :( */
|
||||
usleep(50000);
|
||||
}
|
||||
} while (timeout == PSA_BLOCK);
|
||||
|
||||
INFO("\n");
|
||||
|
||||
/* Assert signals */
|
||||
return signal_mask & exposed_signals;
|
||||
}
|
||||
|
||||
static int signal_to_index(psa_signal_t signal)
|
||||
{
|
||||
|
||||
int i;
|
||||
int count = 0;
|
||||
int ret = -1;
|
||||
@@ -277,7 +278,7 @@ static int signal_to_index(psa_signal_t signal)
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
INFO("ERROR: Too many signals");
|
||||
ERROR("ERROR: Too many signals");
|
||||
return -1; /* Too many signals */
|
||||
}
|
||||
return ret;
|
||||
@@ -297,7 +298,7 @@ psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
|
||||
{
|
||||
int index = signal_to_index(signal);
|
||||
if (index < 0) {
|
||||
PROGRAMMER_ERROR("Bad signal\n");
|
||||
ERROR("Bad signal");
|
||||
}
|
||||
|
||||
clear_signal(signal);
|
||||
@@ -316,12 +317,13 @@ psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
static int is_valid_msg_handle(psa_handle_t h)
|
||||
static inline int is_valid_msg_handle(psa_handle_t h)
|
||||
{
|
||||
if (h > 0 && h < MAX_MESSAGES) {
|
||||
return 1;
|
||||
}
|
||||
PROGRAMMER_ERROR("Not a valid message handle");
|
||||
ERROR("Not a valid message handle");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_call_msg(psa_handle_t h)
|
||||
@@ -347,7 +349,6 @@ static void send_msg(psa_handle_t msg_handle,
|
||||
const void *data,
|
||||
size_t data_amount)
|
||||
{
|
||||
|
||||
struct message response;
|
||||
int flags = 0;
|
||||
|
||||
@@ -367,7 +368,7 @@ static void send_msg(psa_handle_t msg_handle,
|
||||
|
||||
/* TODO: sizeof doesn't need to be so big here for small responses */
|
||||
if (msgsnd(message_client[msg_handle], &response, sizeof(response.message_text), flags) == -1) {
|
||||
INFO("Failed to reply");
|
||||
ERROR("Failed to reply");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +401,7 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
||||
is_call_msg(msg_handle);
|
||||
|
||||
if (invec_idx >= PSA_MAX_IOVEC) {
|
||||
PROGRAMMER_ERROR("Invalid iovec number");
|
||||
ERROR("Invalid iovec number");
|
||||
}
|
||||
|
||||
/* If user wants more data than what's available, truncate their request */
|
||||
@@ -409,14 +410,14 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
||||
}
|
||||
|
||||
while (sofar < num_bytes) {
|
||||
INFO("Server: requesting %lu bytes from client\n", (num_bytes - sofar));
|
||||
INFO("Server: requesting %lu bytes from client", (num_bytes - sofar));
|
||||
send_msg(msg_handle, READ_REQUEST, invec_idx, (num_bytes - sofar), NULL, 0);
|
||||
|
||||
idx = find_connection(message_client[msg_handle]);
|
||||
assert(idx >= 0);
|
||||
|
||||
len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0);
|
||||
len = (len - sizeof(msg.message_text.qid));
|
||||
len = (len - offsetof(struct message_text, buf));
|
||||
|
||||
if (len < 0) {
|
||||
FATAL("Internal error: failed to dispatch read request to the client");
|
||||
@@ -430,7 +431,7 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
||||
memcpy(buffer + sofar, msg.message_text.buf, len);
|
||||
}
|
||||
|
||||
INFO("Printing what i got so far: %s\n", msg.message_text.buf);
|
||||
INFO("Printing what i got so far: %s", msg.message_text.buf);
|
||||
|
||||
sofar = sofar + len;
|
||||
}
|
||||
@@ -444,7 +445,6 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
||||
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
||||
const void *buffer, size_t num_bytes)
|
||||
{
|
||||
|
||||
size_t sofar = 0;
|
||||
struct message msg = { 0 };
|
||||
int idx;
|
||||
@@ -454,23 +454,23 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
||||
is_call_msg(msg_handle);
|
||||
|
||||
if (outvec_idx >= PSA_MAX_IOVEC) {
|
||||
PROGRAMMER_ERROR("Invalid iovec number");
|
||||
ERROR("Invalid iovec number");
|
||||
}
|
||||
|
||||
if (num_bytes > messages[msg_handle].out_size[outvec_idx]) {
|
||||
PROGRAMMER_ERROR("Program tried to write too much data %lu/%lu", num_bytes,
|
||||
messages[msg_handle].out_size[outvec_idx]);
|
||||
ERROR("Program tried to write too much data %lu/%lu", num_bytes,
|
||||
messages[msg_handle].out_size[outvec_idx]);
|
||||
}
|
||||
|
||||
while (sofar < num_bytes) {
|
||||
size_t sending = (num_bytes - sofar);
|
||||
if (sending >= MAX_FRAGMENT_SIZE) {
|
||||
if (sending > (MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2))) {
|
||||
sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2);
|
||||
}
|
||||
|
||||
INFO("Server: sending %lu bytes to client\n", sending);
|
||||
INFO("Server: sending %lu bytes to client, sofar = %lu", sending, (long) sofar);
|
||||
|
||||
send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer, sending);
|
||||
send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer + sofar, sending);
|
||||
|
||||
idx = find_connection(message_client[msg_handle]);
|
||||
assert(idx >= 0);
|
||||
@@ -479,7 +479,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
||||
if (len < 1) {
|
||||
FATAL("Client didn't give me a full response");
|
||||
}
|
||||
sofar = sofar + len;
|
||||
sofar = sofar + sending;
|
||||
}
|
||||
|
||||
/* Update the seek count */
|
||||
@@ -488,7 +488,6 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
||||
|
||||
size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
|
||||
{
|
||||
|
||||
is_valid_msg_handle(msg_handle);
|
||||
is_call_msg(msg_handle);
|
||||
|
||||
@@ -501,7 +500,6 @@ size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
|
||||
|
||||
static void destroy_temporary_queue(int myqid)
|
||||
{
|
||||
|
||||
if (msgctl(myqid, IPC_RMID, NULL) != 0) {
|
||||
INFO("ERROR: Failed to delete msg queue %d", myqid);
|
||||
}
|
||||
@@ -526,7 +524,7 @@ void psa_reply(psa_handle_t msg_handle, psa_status_t status)
|
||||
is_valid_msg_handle(msg_handle);
|
||||
|
||||
if (pending_message[msg_handle] != 1) {
|
||||
PROGRAMMER_ERROR("Not a valid message handle");
|
||||
ERROR("Not a valid message handle");
|
||||
}
|
||||
|
||||
if (messages[msg_handle].type == PSA_IPC_CONNECT) {
|
||||
@@ -551,7 +549,7 @@ void psa_reply(psa_handle_t msg_handle, psa_status_t status)
|
||||
destroy_connection(message_client[msg_handle]);
|
||||
break;
|
||||
default:
|
||||
PROGRAMMER_ERROR("Not a valid reply %d\n", status);
|
||||
ERROR("Not a valid reply %d", status);
|
||||
}
|
||||
} else if (messages[msg_handle].type == PSA_IPC_DISCONNECT) {
|
||||
idx = find_connection(message_client[msg_handle]);
|
||||
@@ -574,7 +572,7 @@ void psa_eoi(psa_signal_t signal)
|
||||
if (index >= 0 && (rot_svc_incoming_queue[index] >= 0)) {
|
||||
clear_signal(signal);
|
||||
} else {
|
||||
PROGRAMMER_ERROR("Tried to EOI a signal that isn't an interrupt");
|
||||
ERROR("Tried to EOI a signal that isn't an interrupt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +581,7 @@ void psa_notify(int32_t partition_id)
|
||||
char pathname[PATHNAMESIZE] = { 0 };
|
||||
|
||||
if (partition_id < 0) {
|
||||
PROGRAMMER_ERROR("Not a valid secure partition");
|
||||
ERROR("Not a valid secure partition");
|
||||
}
|
||||
|
||||
snprintf(pathname, PATHNAMESIZE, "/tmp/psa_notify_%u", partition_id);
|
||||
@@ -603,13 +601,13 @@ void __init_psasim(const char **array,
|
||||
const uint32_t versions[32],
|
||||
const int strict_policy_array[32])
|
||||
{
|
||||
|
||||
static uint8_t library_initialised = 0;
|
||||
key_t key;
|
||||
int qid;
|
||||
FILE *fp;
|
||||
char doorbell_path[PATHNAMESIZE] = { 0 };
|
||||
snprintf(doorbell_path, PATHNAMESIZE, "/tmp/psa_notify_%u", getpid());
|
||||
char doorbell_file[PATHNAMESIZE] = { 0 };
|
||||
char queue_path[PATHNAMESIZE];
|
||||
snprintf(doorbell_file, PATHNAMESIZE, "psa_notify_%u", getpid());
|
||||
|
||||
if (library_initialised > 0) {
|
||||
return;
|
||||
@@ -621,19 +619,21 @@ void __init_psasim(const char **array,
|
||||
FATAL("Unsupported value. Aborting.");
|
||||
}
|
||||
|
||||
array[3] = doorbell_path;
|
||||
array[3] = doorbell_file;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (strncmp(array[i], "", 1) != 0) {
|
||||
INFO("Setting up %s", array[i]);
|
||||
memset(queue_path, 0, sizeof(queue_path));
|
||||
snprintf(queue_path, sizeof(queue_path), "%s%s", TMP_FILE_BASE_PATH, array[i]);
|
||||
|
||||
/* Create file if doesn't exist */
|
||||
fp = fopen(array[i], "ab+");
|
||||
fp = fopen(queue_path, "ab+");
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if ((key = ftok(array[i], PROJECT_ID)) == -1) {
|
||||
if ((key = ftok(queue_path, PROJECT_ID)) == -1) {
|
||||
FATAL("Error finding message queue during initialisation");
|
||||
}
|
||||
|
||||
@@ -649,7 +649,7 @@ void __init_psasim(const char **array,
|
||||
memcpy(nsacl, allow_ns_clients_array, sizeof(int) * 32);
|
||||
memcpy(strict_policy, strict_policy_array, sizeof(int) * 32);
|
||||
memcpy(rot_svc_versions, versions, sizeof(uint32_t) * 32);
|
||||
bzero(&connections, sizeof(struct connection) * MAX_CLIENTS);
|
||||
memset(&connections, 0, sizeof(struct connection) * MAX_CLIENTS);
|
||||
|
||||
__psa_ff_client_security_state = 0; /* Set the client status to SECURE */
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef _PSA_FUNCTIONS_CODES_H_
|
||||
#define _PSA_FUNCTIONS_CODES_H_
|
||||
|
||||
enum {
|
||||
/* Start here to avoid overlap with PSA_IPC_CONNECT, PSA_IPC_DISCONNECT
|
||||
* and VERSION_REQUEST */
|
||||
PSA_CRYPTO_INIT = 100,
|
||||
PSA_AEAD_ABORT,
|
||||
PSA_AEAD_DECRYPT,
|
||||
PSA_AEAD_DECRYPT_SETUP,
|
||||
PSA_AEAD_ENCRYPT,
|
||||
PSA_AEAD_ENCRYPT_SETUP,
|
||||
PSA_AEAD_FINISH,
|
||||
PSA_AEAD_GENERATE_NONCE,
|
||||
PSA_AEAD_SET_LENGTHS,
|
||||
PSA_AEAD_SET_NONCE,
|
||||
PSA_AEAD_UPDATE,
|
||||
PSA_AEAD_UPDATE_AD,
|
||||
PSA_AEAD_VERIFY,
|
||||
PSA_ASYMMETRIC_DECRYPT,
|
||||
PSA_ASYMMETRIC_ENCRYPT,
|
||||
PSA_CAN_DO_HASH,
|
||||
PSA_CIPHER_ABORT,
|
||||
PSA_CIPHER_DECRYPT,
|
||||
PSA_CIPHER_DECRYPT_SETUP,
|
||||
PSA_CIPHER_ENCRYPT,
|
||||
PSA_CIPHER_ENCRYPT_SETUP,
|
||||
PSA_CIPHER_FINISH,
|
||||
PSA_CIPHER_GENERATE_IV,
|
||||
PSA_CIPHER_SET_IV,
|
||||
PSA_CIPHER_UPDATE,
|
||||
PSA_COPY_KEY,
|
||||
PSA_DESTROY_KEY,
|
||||
PSA_EXPORT_KEY,
|
||||
PSA_EXPORT_PUBLIC_KEY,
|
||||
PSA_EXPORT_PUBLIC_KEY_IOP_ABORT,
|
||||
PSA_EXPORT_PUBLIC_KEY_IOP_COMPLETE,
|
||||
PSA_EXPORT_PUBLIC_KEY_IOP_GET_NUM_OPS,
|
||||
PSA_EXPORT_PUBLIC_KEY_IOP_SETUP,
|
||||
PSA_GENERATE_KEY,
|
||||
PSA_GENERATE_KEY_CUSTOM,
|
||||
PSA_GENERATE_KEY_IOP_ABORT,
|
||||
PSA_GENERATE_KEY_IOP_COMPLETE,
|
||||
PSA_GENERATE_KEY_IOP_GET_NUM_OPS,
|
||||
PSA_GENERATE_KEY_IOP_SETUP,
|
||||
PSA_GENERATE_RANDOM,
|
||||
PSA_GET_KEY_ATTRIBUTES,
|
||||
PSA_HASH_ABORT,
|
||||
PSA_HASH_CLONE,
|
||||
PSA_HASH_COMPARE,
|
||||
PSA_HASH_COMPUTE,
|
||||
PSA_HASH_FINISH,
|
||||
PSA_HASH_SETUP,
|
||||
PSA_HASH_UPDATE,
|
||||
PSA_HASH_VERIFY,
|
||||
PSA_IMPORT_KEY,
|
||||
PSA_INTERRUPTIBLE_GET_MAX_OPS,
|
||||
PSA_INTERRUPTIBLE_SET_MAX_OPS,
|
||||
PSA_KEY_AGREEMENT,
|
||||
PSA_KEY_AGREEMENT_IOP_ABORT,
|
||||
PSA_KEY_AGREEMENT_IOP_COMPLETE,
|
||||
PSA_KEY_AGREEMENT_IOP_GET_NUM_OPS,
|
||||
PSA_KEY_AGREEMENT_IOP_SETUP,
|
||||
PSA_KEY_DERIVATION_ABORT,
|
||||
PSA_KEY_DERIVATION_GET_CAPACITY,
|
||||
PSA_KEY_DERIVATION_INPUT_BYTES,
|
||||
PSA_KEY_DERIVATION_INPUT_INTEGER,
|
||||
PSA_KEY_DERIVATION_INPUT_KEY,
|
||||
PSA_KEY_DERIVATION_KEY_AGREEMENT,
|
||||
PSA_KEY_DERIVATION_OUTPUT_BYTES,
|
||||
PSA_KEY_DERIVATION_OUTPUT_KEY,
|
||||
PSA_KEY_DERIVATION_OUTPUT_KEY_CUSTOM,
|
||||
PSA_KEY_DERIVATION_SET_CAPACITY,
|
||||
PSA_KEY_DERIVATION_SETUP,
|
||||
PSA_MAC_ABORT,
|
||||
PSA_MAC_COMPUTE,
|
||||
PSA_MAC_SIGN_FINISH,
|
||||
PSA_MAC_SIGN_SETUP,
|
||||
PSA_MAC_UPDATE,
|
||||
PSA_MAC_VERIFY,
|
||||
PSA_MAC_VERIFY_FINISH,
|
||||
PSA_MAC_VERIFY_SETUP,
|
||||
PSA_PURGE_KEY,
|
||||
PSA_RAW_KEY_AGREEMENT,
|
||||
PSA_RESET_KEY_ATTRIBUTES,
|
||||
PSA_SIGN_HASH,
|
||||
PSA_SIGN_HASH_ABORT,
|
||||
PSA_SIGN_HASH_COMPLETE,
|
||||
PSA_SIGN_HASH_GET_NUM_OPS,
|
||||
PSA_SIGN_HASH_START,
|
||||
PSA_SIGN_MESSAGE,
|
||||
PSA_VERIFY_HASH,
|
||||
PSA_VERIFY_HASH_ABORT,
|
||||
PSA_VERIFY_HASH_COMPLETE,
|
||||
PSA_VERIFY_HASH_GET_NUM_OPS,
|
||||
PSA_VERIFY_HASH_START,
|
||||
PSA_VERIFY_MESSAGE,
|
||||
};
|
||||
|
||||
#endif /* _PSA_FUNCTIONS_CODES_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+1208
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+1048
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
/* psasim test server */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Includes from psasim */
|
||||
#include "service.h"
|
||||
#include "error_ext.h"
|
||||
#include "util.h"
|
||||
#include "psa_manifest/manifest.h"
|
||||
#include "psa_functions_codes.h"
|
||||
|
||||
/* Includes from mbedtls */
|
||||
#include "mbedtls/version.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define SERVER_PRINT(fmt, ...) \
|
||||
PRINT("Server: " fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define SERVER_PRINT(...)
|
||||
#endif
|
||||
|
||||
#define BUF_SIZE 25
|
||||
|
||||
static int kill_on_disconnect = 0; /* Kill the server on client disconnection. */
|
||||
|
||||
void parse_input_args(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "k")) != -1) {
|
||||
switch (opt) {
|
||||
case 'k':
|
||||
kill_on_disconnect = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-k]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int psa_server_main(int argc, char *argv[])
|
||||
{
|
||||
psa_status_t ret = PSA_ERROR_PROGRAMMER_ERROR;
|
||||
psa_msg_t msg = { -1 };
|
||||
const int magic_num = 66;
|
||||
int client_disconnected = 0;
|
||||
extern psa_status_t psa_crypto_call(psa_msg_t msg);
|
||||
extern psa_status_t psa_crypto_close(void);
|
||||
|
||||
#if defined(MBEDTLS_VERSION_C)
|
||||
const char *mbedtls_version = mbedtls_version_get_string_full();
|
||||
SERVER_PRINT("%s", mbedtls_version);
|
||||
#endif
|
||||
|
||||
parse_input_args(argc, argv);
|
||||
SERVER_PRINT("Starting");
|
||||
|
||||
while (!(kill_on_disconnect && client_disconnected)) {
|
||||
psa_signal_t signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
|
||||
|
||||
if (signals > 0) {
|
||||
SERVER_PRINT("Signals: 0x%08x", signals);
|
||||
}
|
||||
|
||||
if (signals & PSA_CRYPTO_SIGNAL) {
|
||||
if (PSA_SUCCESS == psa_get(PSA_CRYPTO_SIGNAL, &msg)) {
|
||||
SERVER_PRINT("handle: %d - rhandle: %p", msg.handle, (int *) msg.rhandle);
|
||||
switch (msg.type) {
|
||||
case PSA_IPC_CONNECT:
|
||||
SERVER_PRINT("Got a connection message");
|
||||
psa_set_rhandle(msg.handle, (void *) &magic_num);
|
||||
ret = PSA_SUCCESS;
|
||||
break;
|
||||
case PSA_IPC_DISCONNECT:
|
||||
SERVER_PRINT("Got a disconnection message");
|
||||
ret = PSA_SUCCESS;
|
||||
client_disconnected = 1;
|
||||
psa_crypto_close();
|
||||
break;
|
||||
default:
|
||||
SERVER_PRINT("Got an IPC call of type %d", msg.type);
|
||||
ret = psa_crypto_call(msg);
|
||||
SERVER_PRINT("Internal function call returned %d", ret);
|
||||
|
||||
if (msg.client_id > 0) {
|
||||
psa_notify(msg.client_id);
|
||||
} else {
|
||||
SERVER_PRINT("Client is non-secure, so won't notify");
|
||||
}
|
||||
}
|
||||
|
||||
psa_reply(msg.handle, ret);
|
||||
} else {
|
||||
SERVER_PRINT("Failed to retrieve message");
|
||||
}
|
||||
} else if (SIGSTP_SIG & signals) {
|
||||
SERVER_PRINT("Recieved SIGSTP signal. Gonna EOI it.");
|
||||
psa_eoi(SIGSTP_SIG);
|
||||
} else if (SIGINT_SIG & signals) {
|
||||
SERVER_PRINT("Handling interrupt!");
|
||||
SERVER_PRINT("Gracefully quitting");
|
||||
psa_panic();
|
||||
} else {
|
||||
SERVER_PRINT("No signal asserted");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
INCLUDE := -I../include/ -I./psa_manifest
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
psa_autogen manifest.json
|
||||
$(CC) psa_ff_bootstrap_TEST_PARTITION.c -lpsaff -o partition
|
||||
$(CC) client.c -lpsaff -o client
|
||||
|
||||
clean:
|
||||
rm -rf psa_manifest
|
||||
rm -f client partition psa_ff_bootstrap_TEST_PARTITION.c
|
||||
@@ -1,48 +0,0 @@
|
||||
/* psasim test client */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <psa/client.h>
|
||||
#include "psa_manifest/sid.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
const char *text = "FOOBARCOOL!!";
|
||||
|
||||
char output[100] = { 0 };
|
||||
printf("My PID is %d\n", getpid());
|
||||
|
||||
printf("The version of the service is %u\n", psa_version(PSA_SID_SHA256_SID));
|
||||
psa_handle_t h = psa_connect(PSA_SID_SHA256_SID, 1);
|
||||
|
||||
if (h < 0) {
|
||||
printf("Couldn't connect %d\n", h);
|
||||
return 1;
|
||||
} else {
|
||||
int type = 2;
|
||||
puts("Calling!");
|
||||
puts("Trying without invec");
|
||||
printf("Answer to my call was %d (no invec)\n", psa_call(h, type, NULL, 0, NULL, 0));
|
||||
psa_invec invecs[1];
|
||||
psa_outvec outvecs[1];
|
||||
invecs[0].base = text;
|
||||
invecs[0].len = 24;
|
||||
outvecs[0].base = output;
|
||||
outvecs[0].len = 99;
|
||||
|
||||
printf("My iovec size should be %lu\n", invecs[0].len);
|
||||
printf("Answer to my call was %d (with invec)\n", psa_call(h, type, invecs, 1, outvecs, 1));
|
||||
printf("Here's the payload I recieved: %s\n", output);
|
||||
printf("Apparently the server wrote %lu bytes in outvec %d\n", outvecs[0].len, 0);
|
||||
puts("Closing handle");
|
||||
psa_close(h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
set -e
|
||||
|
||||
pkill psa_server || true
|
||||
|
||||
# Remove temporary files
|
||||
rm -f psa_notify_*
|
||||
|
||||
# Remove all IPCs
|
||||
# Not just ipcrm -all=msg as it is not supported on macOS.
|
||||
# Filter out header and empty lines, choosing to select based on keys being
|
||||
# output in hex.
|
||||
ipcs -q | fgrep 0x | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
# This is a simple bash script that tests psa_client/psa_server interaction.
|
||||
# This script is automatically executed when "make run" is launched by the
|
||||
# "psasim" root folder. The script can also be launched manually once
|
||||
# binary files are built (i.e. after "make test" is executed from the "psasim"
|
||||
# root folder).
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
CLIENT_BIN=$1
|
||||
shift
|
||||
|
||||
./kill_servers.sh
|
||||
|
||||
./start_server.sh
|
||||
./$CLIENT_BIN "$@"
|
||||
|
||||
./kill_servers.sh
|
||||
@@ -1,105 +0,0 @@
|
||||
/* psasim test server */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <psa/service.h>
|
||||
#include "psa_manifest/manifest.h"
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void printbits(uint32_t num)
|
||||
{
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((num >> (31-i) & 0x1)) {
|
||||
printf("1");
|
||||
} else {
|
||||
printf("0");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#define BUF_SIZE 25
|
||||
|
||||
int psa_sha256_main()
|
||||
{
|
||||
psa_status_t ret = PSA_ERROR_PROGRAMMER_ERROR;
|
||||
psa_msg_t msg = { -1 };
|
||||
char foo[BUF_SIZE] = { 0 };
|
||||
const int magic_num = 66;
|
||||
|
||||
puts("Starting");
|
||||
|
||||
while (1) {
|
||||
puts("Calling psa_wait");
|
||||
psa_signal_t signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
|
||||
|
||||
if (signals > 0) {
|
||||
printbits(signals);
|
||||
}
|
||||
|
||||
if (signals & PSA_SHA256_SIGNAL) {
|
||||
puts("Oooh a signal!");
|
||||
|
||||
if (PSA_SUCCESS == psa_get(PSA_SHA256_SIGNAL, &msg)) {
|
||||
printf("My handle is %d\n", msg.handle);
|
||||
printf("My rhandle is %p\n", (int *) msg.rhandle);
|
||||
switch (msg.type) {
|
||||
case PSA_IPC_CONNECT:
|
||||
puts("Got a connection message");
|
||||
psa_set_rhandle(msg.handle, (void *) &magic_num);
|
||||
ret = PSA_SUCCESS;
|
||||
break;
|
||||
case PSA_IPC_DISCONNECT:
|
||||
puts("Got a disconnection message");
|
||||
ret = PSA_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Got an IPC call of type %d\n", msg.type);
|
||||
ret = 42;
|
||||
size_t size = msg.in_size[0];
|
||||
|
||||
if ((size > 0) && (size <= sizeof(foo))) {
|
||||
psa_read(msg.handle, 0, foo, 6);
|
||||
foo[(BUF_SIZE-1)] = '\0';
|
||||
printf("Reading payload: %s\n", foo);
|
||||
psa_read(msg.handle, 0, foo+6, 6);
|
||||
foo[(BUF_SIZE-1)] = '\0';
|
||||
printf("Reading payload: %s\n", foo);
|
||||
}
|
||||
|
||||
size = msg.out_size[0];
|
||||
if ((size > 0)) {
|
||||
puts("Writing response");
|
||||
psa_write(msg.handle, 0, "RESP", 4);
|
||||
psa_write(msg.handle, 0, "ONSE", 4);
|
||||
}
|
||||
|
||||
if (msg.client_id > 0) {
|
||||
psa_notify(msg.client_id);
|
||||
} else {
|
||||
puts("Client is non-secure, so won't notify");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
psa_reply(msg.handle, ret);
|
||||
} else {
|
||||
puts("Failed to retrieve message");
|
||||
}
|
||||
} else if (SIGSTP_SIG & signals) {
|
||||
puts("Recieved SIGSTP signal. Gonna EOI it.");
|
||||
psa_eoi(SIGSTP_SIG);
|
||||
} else if (SIGINT_SIG & signals) {
|
||||
puts("Handling interrupt!\n");
|
||||
puts("Gracefully quitting");
|
||||
psa_panic();
|
||||
} else {
|
||||
puts("No signal asserted");
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
set -e
|
||||
|
||||
# The server creates some local files when it starts up so we can wait for this
|
||||
# event as signal that the server is ready so that we can start client(s).
|
||||
function wait_for_server_startup() {
|
||||
SECONDS=0
|
||||
TIMEOUT=10
|
||||
|
||||
while [ $(find . -name "psa_notify_*" | wc -l) -eq 0 ]; do
|
||||
if [ "$SECONDS" -ge "$TIMEOUT" ]; then
|
||||
echo "Timeout: psa_server not started within $TIMEOUT seconds."
|
||||
return 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
|
||||
$(dirname "$0")/psa_server &
|
||||
wait_for_server_startup
|
||||
+65
-54
@@ -15,6 +15,13 @@ if len(sys.argv) != 2:
|
||||
|
||||
FILENAME = str(sys.argv[1])
|
||||
|
||||
SCRIPT_PATH = os.path.dirname(__file__)
|
||||
GENERATED_H_PATH = os.path.join(SCRIPT_PATH, "..", "include", "psa_manifest")
|
||||
GENERATED_C_PATH = os.path.join(SCRIPT_PATH, "..", "src")
|
||||
|
||||
MANIFEST_FILE = os.path.join(GENERATED_H_PATH, "manifest.h")
|
||||
PID_FILE = os.path.join(GENERATED_H_PATH, "pid.h")
|
||||
SID_FILE = os.path.join(GENERATED_H_PATH, "sid.h")
|
||||
|
||||
with open(str(FILENAME), "r") as read_file:
|
||||
data = json.load(read_file)
|
||||
@@ -32,58 +39,58 @@ with open(str(FILENAME), "r") as read_file:
|
||||
irqs = []
|
||||
|
||||
try:
|
||||
os.mkdir("psa_manifest")
|
||||
os.mkdir(GENERATED_H_PATH)
|
||||
print("Generating psa_manifest directory")
|
||||
except OSError:
|
||||
print ("PSA manifest directory already exists")
|
||||
print("PSA manifest directory already exists")
|
||||
|
||||
man = open(str("psa_manifest/" + FILENAME + ".h"), "w")
|
||||
pids = open("psa_manifest/pid.h", "a")
|
||||
sids = open("psa_manifest/sid.h", "a")
|
||||
manifest_content = []
|
||||
pids_content = []
|
||||
sids_content = []
|
||||
|
||||
if len(services) > 28:
|
||||
print ("Unsupported number of services")
|
||||
|
||||
count = 4 # For creating SID array
|
||||
nsacl = "const int ns_allowed[32] = {"
|
||||
policy = "const int strict_policy[32] = {"
|
||||
qcode = "const char * psa_queues[] = { "
|
||||
versions = "const uint32_t versions[32] = {"
|
||||
queue_path = "/tmp/psa_service_"
|
||||
nsacl = "const int ns_allowed[32] = { "
|
||||
policy = "const int strict_policy[32] = { "
|
||||
qcode = "const char *psa_queues[] = { "
|
||||
versions = "const uint32_t versions[32] = { "
|
||||
queue_path = "psa_service_"
|
||||
start = False
|
||||
|
||||
for x in range(0, count):
|
||||
qcode = qcode + "\"\", "
|
||||
nsacl = nsacl + " 0,"
|
||||
policy = policy + "0,"
|
||||
versions = versions + " 0,"
|
||||
nsacl = nsacl + "0, "
|
||||
policy = policy + "0, "
|
||||
versions = versions + "0, "
|
||||
|
||||
# Go through all the services to make sid.h and pid.h
|
||||
for svc in services:
|
||||
man.write("#define " + str(svc['signal']) + "_SIGNAL " + str(2 ** (count)) + 'u\n')
|
||||
sids.write("#define " + str(svc['name']) + "_SID " + str(svc['sid'] + '\n'))
|
||||
manifest_content.append("#define {}_SIGNAL 0x{:08x}".format(svc['signal'], 2**count))
|
||||
sids_content.append("#define {}_SID {}".format(svc['name'], svc['sid']))
|
||||
qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\","
|
||||
ns_clients = svc['non_secure_clients']
|
||||
print(str(svc))
|
||||
if ns_clients == "true":
|
||||
nsacl = nsacl + " 1,"
|
||||
nsacl = nsacl + "1, "
|
||||
else:
|
||||
nsacl = nsacl + " 0,"
|
||||
nsacl = nsacl + "0, "
|
||||
try:
|
||||
versions = versions + str(svc['minor_version']) + ","
|
||||
versions = versions + str(svc['minor_version']) + ", "
|
||||
except KeyError:
|
||||
versions = versions + "1,"
|
||||
versions = versions + "1, "
|
||||
|
||||
strict = 0
|
||||
try:
|
||||
if str(svc['minor_policy']).lower() == "strict":
|
||||
strict = 1
|
||||
policy = policy + "1,"
|
||||
policy = policy + "1, "
|
||||
else:
|
||||
policy = policy + "0,"
|
||||
policy = policy + "0, "
|
||||
except KeyError:
|
||||
strict = 0
|
||||
policy = policy + "0,"
|
||||
policy = policy + "0, "
|
||||
|
||||
count = count+1
|
||||
|
||||
@@ -91,18 +98,19 @@ with open(str(FILENAME), "r") as read_file:
|
||||
handlercode = "void __sig_handler(int signo) {\n"
|
||||
irqcount = count
|
||||
for irq in irqs:
|
||||
man.write("#define " + str(irq['signal']) + " " + str(2 ** (irqcount)) + 'u\n')
|
||||
sigcode = sigcode + " signal(" + str(irq['source']) + ", __sig_handler);\n"
|
||||
handlercode = handlercode + " if (signo == " + str(irq['source']) + ") { raise_signal(" + str(2 ** (irqcount)) + 'u);' + " };\n"
|
||||
manifest_content.append("#define {} 0x{:08x}".format(irq['signal'], 2**irqcount))
|
||||
sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source'])
|
||||
handlercode = handlercode + \
|
||||
" if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount)
|
||||
irqcount = irqcount+1
|
||||
|
||||
handlercode = handlercode + "}\n"
|
||||
|
||||
while (count < 32):
|
||||
qcode = qcode + "\"\","
|
||||
nsacl = nsacl + "0,"
|
||||
versions = versions + "0,"
|
||||
policy = policy + "0,"
|
||||
qcode = qcode + "\"\", "
|
||||
nsacl = nsacl + "0, "
|
||||
versions = versions + "0, "
|
||||
policy = policy + "0, "
|
||||
count = count + 1
|
||||
|
||||
qcode = qcode + "};\n"
|
||||
@@ -110,28 +118,28 @@ with open(str(FILENAME), "r") as read_file:
|
||||
versions = versions + "};\n"
|
||||
policy = policy + "};\n"
|
||||
|
||||
pids.close()
|
||||
sids.close()
|
||||
man.close()
|
||||
with open(MANIFEST_FILE, "wt") as output:
|
||||
output.write("\n".join(manifest_content))
|
||||
with open(SID_FILE, "wt") as output:
|
||||
output.write("\n".join(sids_content))
|
||||
with open(PID_FILE, "wt") as output:
|
||||
output.write("\n".join(pids_content))
|
||||
|
||||
symbols = []
|
||||
# Go through all the files in the current directory and look for the entrypoint
|
||||
|
||||
for root, directories, filenames in os.walk('.'):
|
||||
# Go through source files and look for the entrypoint
|
||||
for root, directories, filenames in os.walk(GENERATED_C_PATH):
|
||||
for filename in filenames:
|
||||
|
||||
if "psa_ff_bootstrap" in filename or filename == "psa_manifest":
|
||||
continue
|
||||
|
||||
try:
|
||||
fullpath = os.path.join(root,filename)
|
||||
with open(fullpath, encoding='utf-8') as currentFile:
|
||||
text = currentFile.read()
|
||||
if str(entry_point + "(") in text:
|
||||
symbols.append(fullpath)
|
||||
symbols.append(filename)
|
||||
except IOError:
|
||||
print("Couldn't open " + filename)
|
||||
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
|
||||
@@ -143,21 +151,24 @@ with open(str(FILENAME), "r") as read_file:
|
||||
print("Duplicate entrypoint symbol detected: " + str(symbols))
|
||||
sys.exit(2)
|
||||
else:
|
||||
bs = open(str("psa_ff_bootstrap_" + str(partition_name) + ".c"), "w")
|
||||
bs.write("#include <psasim/init.h>\n")
|
||||
bs.write("#include \"" + symbols[0] + "\"\n")
|
||||
bs.write("#include <signal.h>\n")
|
||||
bs.write(qcode)
|
||||
bs.write("\n")
|
||||
bs.write(nsacl + "\n")
|
||||
bs.write(policy + "\n")
|
||||
bs.write(versions + "\n")
|
||||
bs.write(handlercode)
|
||||
bs.write("\n")
|
||||
bs.write("int main() {\n")
|
||||
bs.write(sigcode)
|
||||
bs.write(" __init_psasim(psa_queues, 32, ns_allowed, versions, strict_policy);\n")
|
||||
bs.write(" " + entry_point + "();\nfor(;;);\n}\n")
|
||||
bs.close()
|
||||
C_FILENAME = os.path.join(GENERATED_C_PATH, "psa_ff_bootstrap_" + partition_name + ".c")
|
||||
c_content = []
|
||||
c_content.append("#include <init.h>")
|
||||
c_content.append("#include \"" + symbols[0] + "\"")
|
||||
c_content.append("#include <signal.h>")
|
||||
c_content.append(qcode)
|
||||
c_content.append(nsacl)
|
||||
c_content.append(policy)
|
||||
c_content.append(versions)
|
||||
c_content.append(handlercode)
|
||||
c_content.append("int main(int argc, char *argv[]) {")
|
||||
c_content.append(" (void) argc;")
|
||||
c_content.append(sigcode)
|
||||
c_content.append(" __init_psasim(psa_queues, 32, ns_allowed, versions,"
|
||||
"strict_policy);")
|
||||
c_content.append(" " + entry_point + "(argc, argv);")
|
||||
c_content.append("}")
|
||||
with open(C_FILENAME, "wt") as output:
|
||||
output.write("\n".join(c_content))
|
||||
|
||||
print("Success")
|
||||
|
||||
+12
-1
@@ -267,7 +267,18 @@ pre_initialize_variables () {
|
||||
# defined in this script whose name starts with "component_".
|
||||
ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//')
|
||||
|
||||
PSASIM_PATH='tests/psa-client-server/psasim/'
|
||||
|
||||
# Allow overriding PSASIM_PATH with the following priority:
|
||||
# 1) Environment override
|
||||
# 2) Mbed TLS's version of psa-client-server
|
||||
# 3) Fallback to the framework location (default after move)
|
||||
if [ -z "${PSASIM_PATH+set}" ]; then
|
||||
if [ -d tests/psa-client-server ]; then
|
||||
PSASIM_PATH='tests/psa-client-server/psasim/'
|
||||
else
|
||||
PSASIM_PATH='framework/psasim/'
|
||||
fi
|
||||
fi
|
||||
|
||||
# Delay determining SUPPORTED_COMPONENTS until the command line options have a chance to override
|
||||
# the commands set by the environment
|
||||
|
||||
Reference in New Issue
Block a user