From 5f4860967941ac50711056471dc5db7dce2d5d0c Mon Sep 17 00:00:00 2001 From: Edmund Grimley Evans Date: Tue, 28 Apr 2020 10:40:41 +0100 Subject: [PATCH] First draft of rust-psa-crypto, Rust wrapper for (some of) mbed-crypto. Currently this depends on an old version of mbed-crypto. These files are adapted from Parsec: build-conf.toml, build.rs, setup_mbed_crypto.sh Signed-off-by: Edmund Grimley Evans --- Cargo.toml | 13 +- build-conf.toml | 19 +++ build.rs | 279 +++++++++++++++++++++++++++++++++++++++++++ setup_mbed_crypto.sh | 69 +++++++++++ src/c/shim.c | 52 ++++++++ src/c/shim.h | 171 ++++++++++++++++++++++++++ src/constants.rs | 154 ++++++++++++++++++++++++ src/lib.rs | 272 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1028 insertions(+), 1 deletion(-) create mode 100644 build-conf.toml create mode 100644 build.rs create mode 100755 setup_mbed_crypto.sh create mode 100644 src/c/shim.c create mode 100644 src/c/shim.h create mode 100644 src/constants.rs diff --git a/Cargo.toml b/Cargo.toml index 982e08c..0d01a93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "psa-crypto" version = "0.1.0" -authors = ["Paul Howard ", +authors = ["Edmund Grimley Evans ", + "Paul Howard ", "Ionut Mihalcea ", "Hugues de Valon "] edition = "2018" @@ -13,3 +14,13 @@ license = "Apache-2.0" repository = "https://github.com/parallaxsecond/rust-psa-crypto" [dependencies] +lazy_static = "1.4.0" + +[build-dependencies] +bindgen = "0.50.0" +cargo_toml = "0.7.0" +serde = { version = "1.0", features = ["derive"] } +toml = "0.4.2" + +[package.metadata.config] +mbed-crypto-version = "mbedcrypto-2.0.0" diff --git a/build-conf.toml b/build-conf.toml new file mode 100644 index 0000000..1b91783 --- /dev/null +++ b/build-conf.toml @@ -0,0 +1,19 @@ +# Configuration values for setting up and building the Mbed Crypto library that +# psa-crypto currently depends on +[mbed_config] + # Path (either relative or absolute) where the Mbed Crypto source code will be + # persisted. + # This value default to the OUT_DIR environment variable. + mbed_path = "/tmp/" + + # When compiling natively + [mbed_config.native] + # The compiler to use when building the Mbed Crypto library + # mbed_compiler = "clang" + # The archiver to use when building the Mbed Crypto library + # mbed_archiver = "ar" + + # When cross-compiling for aarch64-unknown-linux-gnu target + [mbed_config.aarch64_unknown_linux_gnu] + # mbed_compiler = "aarch64-linux-gnu-gcc" + # mbed_archiver = "aarch64-linux-gnu-ar" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..30d3bf2 --- /dev/null +++ b/build.rs @@ -0,0 +1,279 @@ +// Copyright 2020 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +#![deny( + nonstandard_style, + const_err, + dead_code, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused, + unused_allocation, + unused_comparisons, + unused_parens, + while_true, + missing_debug_implementations, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_qualifications, + unused_results, + missing_copy_implementations +)] +// This one is hard to avoid. +#![allow(clippy::multiple_crate_versions)] + +use cargo_toml::{Manifest, Value}; +use serde::Deserialize; +use std::env; +use std::io::{Error, ErrorKind, Result}; +use std::path::{Path, PathBuf}; + +const CONFIG_TABLE_NAME: &str = "config"; +const MBED_CRYPTO_VERSION_KEY: &str = "mbed-crypto-version"; + +const SETUP_MBED_SCRIPT_PATH: &str = "./setup_mbed_crypto.sh"; +const BUILD_CONFIG_FILE_PATH: &str = "./build-conf.toml"; + +const DEFAULT_NATIVE_MBED_COMPILER: &str = "clang"; +const DEFAULT_NATIVE_MBED_ARCHIVER: &str = "ar"; +const DEFAULT_ARM64_MBED_COMPILER: &str = "aarch64-linux-gnu-gcc"; +const DEFAULT_ARM64_MBED_ARCHIVER: &str = "aarch64-linux-gnu-ar"; + +#[derive(Debug, Deserialize)] +struct Configuration { + mbed_config: Option, +} + +#[derive(Debug, Deserialize)] +struct MbedConfig { + mbed_path: Option, + native: Option, + aarch64_unknown_linux_gnu: Option, +} + +#[derive(Debug, Deserialize)] +struct Toolchain { + mbed_compiler: Option, + mbed_archiver: Option, +} + +fn get_configuration_string(parsec_config: &Value, key: &str) -> Result { + let config_value = get_value_from_table(parsec_config, key)?; + match config_value { + Value::String(string) => Ok(string.clone()), + _ => Err(Error::new( + ErrorKind::InvalidInput, + "Configuration key missing", + )), + } +} + +fn get_value_from_table<'a>(table: &'a Value, key: &str) -> Result<&'a Value> { + match table { + Value::Table(table) => table.get(key).ok_or_else(|| { + println!("Config table does not contain configuration key: {}", key); + Error::new(ErrorKind::InvalidInput, "Configuration key missing.") + }), + _ => Err(Error::new( + ErrorKind::InvalidInput, + "Value provided is not a TOML table", + )), + } +} + +// Get the Mbed Crypto version to branch on from Cargo.toml file. Use that and MbedConfig to pass +// parameters to the setup_mbed_crypto.sh script which clones and builds Mbed Crypto and create +// a static library. +fn setup_mbed_crypto(mbed_config: &MbedConfig, mbed_version: &str) -> Result<()> { + let (mbed_compiler, mbed_archiver) = + if std::env::var("TARGET").unwrap() == "aarch64-unknown-linux-gnu" { + let toolchain; + toolchain = mbed_config + .aarch64_unknown_linux_gnu + .as_ref() + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidInput, + "The aarch64_unknown_linux_gnu subtable of mbed_config should exist", + ) + })?; + ( + toolchain + .mbed_compiler + .clone() + .unwrap_or_else(|| DEFAULT_ARM64_MBED_COMPILER.to_string()), + toolchain + .mbed_archiver + .clone() + .unwrap_or_else(|| DEFAULT_ARM64_MBED_ARCHIVER.to_string()), + ) + } else { + let toolchain; + toolchain = mbed_config.native.as_ref().ok_or_else(|| { + Error::new( + ErrorKind::InvalidInput, + "The native subtable of mbed_config should exist", + ) + })?; + ( + toolchain + .mbed_compiler + .clone() + .unwrap_or_else(|| DEFAULT_NATIVE_MBED_COMPILER.to_string()), + toolchain + .mbed_archiver + .clone() + .unwrap_or_else(|| DEFAULT_NATIVE_MBED_ARCHIVER.to_string()), + ) + }; + + let script_fail = |_| { + Err(Error::new( + ErrorKind::Other, + "setup_mbed_crypto.sh script failed", + )) + }; + + println!("cargo:rerun-if-changed={}", SETUP_MBED_SCRIPT_PATH); + println!("cargo:rerun-if-changed={}", "src/c/Makefile"); + println!("cargo:rerun-if-changed={}", "src/c/shim.c"); + println!("cargo:rerun-if-changed={}", "src/c/shim.h"); + + if !::std::process::Command::new(SETUP_MBED_SCRIPT_PATH) + .arg(mbed_version) + .arg( + mbed_config + .mbed_path + .clone() + .unwrap_or_else(|| env::var("OUT_DIR").unwrap()), + ) + .arg(format!("CC={}", mbed_compiler)) + .arg(format!("AR={}", mbed_archiver)) + .status() + .or_else(script_fail)? + .success() + { + Err(Error::new( + ErrorKind::Other, + "setup_mbed_crypto.sh returned an error status.", + )) + } else { + Ok(()) + } +} + +fn generate_mbed_bindings(mbed_config: &MbedConfig, mbed_version: &str) -> Result<()> { + let mbed_include_dir = mbed_config + .mbed_path + .clone() + .unwrap_or_else(|| env::var("OUT_DIR").unwrap()) + + "/mbed-crypto-" + + mbed_version + + "/include"; + let header = mbed_include_dir.clone() + "/psa/crypto.h"; + + println!("cargo:rerun-if-changed={}", header); + + let shim_bindings = bindgen::Builder::default() + .clang_arg(format!("-I{}", mbed_include_dir)) + .rustfmt_bindings(true) + .header("src/c/shim.h") + .generate_comments(false) + .generate() + .or_else(|_| { + Err(Error::new( + ErrorKind::Other, + "Unable to generate bindings to mbed crypto", + )) + })?; + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + shim_bindings.write_to_file(out_path.join("shim_bindings.rs")) +} + +// Get the compiler, the archiver and the location where to clone the Mbed Crypto repository. +fn parse_config_file() -> Result { + let config_str = ::std::fs::read_to_string(Path::new(BUILD_CONFIG_FILE_PATH))?; + Ok(toml::from_str(&config_str).or_else(|e| { + println!("Error parsing build configuration file ({}).", e); + Err(Error::new( + ErrorKind::InvalidInput, + "Could not parse build configuration file.", + )) + })?) +} + +fn main() -> Result<()> { + // Parsing build-conf.toml + let config = parse_config_file()?; + + // Parsing Cargo.toml + let toml_path = std::path::Path::new("./Cargo.toml"); + if !toml_path.exists() { + return Err(Error::new( + ErrorKind::InvalidInput, + "Could not find Cargo.toml.", + )); + } + let manifest = Manifest::from_path(&toml_path).or_else(|e| { + println!("Error parsing Cargo.toml ({}).", e); + Err(Error::new( + ErrorKind::InvalidInput, + "Could not parse Cargo.toml.", + )) + })?; + + let package = manifest.package.ok_or_else(|| { + Error::new( + ErrorKind::InvalidInput, + "Cargo.toml does not contain package information.", + ) + })?; + let metadata = package.metadata.ok_or_else(|| { + Error::new( + ErrorKind::InvalidInput, + "Cargo.toml does not contain package metadata.", + ) + })?; + let parsec_config = get_value_from_table(&metadata, CONFIG_TABLE_NAME)?; + + if true { + let mbed_config = config.mbed_config.ok_or_else(|| { + Error::new( + ErrorKind::InvalidInput, + "Could not find mbed_config table in the config file.", + ) + })?; + + let mbed_version = get_configuration_string(&parsec_config, MBED_CRYPTO_VERSION_KEY)?; + + setup_mbed_crypto(&mbed_config, &mbed_version)?; + generate_mbed_bindings(&mbed_config, &mbed_version)?; + + // Request rustc to link the Mbed Crypto static library + println!( + "cargo:rustc-link-search=native={}/mbed-crypto-{}/library/", + mbed_config + .mbed_path + .unwrap_or_else(|| env::var("OUT_DIR").unwrap()), + mbed_version, + ); + println!("cargo:rustc-link-lib=static=mbedcrypto"); + + // Also link shim library + println!( + "cargo:rustc-link-search=native={}", + env::var("OUT_DIR").unwrap() + ); + println!("cargo:rustc-link-lib=static=shim"); + } + + Ok(()) +} diff --git a/setup_mbed_crypto.sh b/setup_mbed_crypto.sh new file mode 100755 index 0000000..a193963 --- /dev/null +++ b/setup_mbed_crypto.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# ------------------------------------------------------------------------------ +# Copyright 2020 Contributors to the Parsec project. +# SPDX-License-Identifier: Apache-2.0 +# ------------------------------------------------------------------------------ + +MBED_VERSION=$1 +if [[ -z "$MBED_VERSION" ]]; then + >&2 echo "No mbed version provided." + exit 1 +fi + +MBED_GITHUB_URL="https://github.com/ARMmbed/mbed-crypto" +MBED_ROOT_FOLDER_NAME="mbed-crypto-$MBED_VERSION" +MBED_LIB_FILENAME="libmbedcrypto.a" +MBED_SHIMLIB_DIR="src/c" + +# Where to clone the Mbed Crypto library +TEMP_FOLDER=$2 +if [[ -z "$TEMP_FOLDER" ]]; then + >&2 echo "No temporary folder for mbed provided." + exit 1 +fi + +# These options refer to CC and AR +OPTIONS="$3 $4" + +if [[ -z "$(type git 2> /dev/null)" ]]; then + >&2 echo "Git not installed." + exit 1 +fi + +get_mbed_repo() { + echo "No mbed-crypto present locally. Cloning." + wget $MBED_GITHUB_URL/archive/$MBED_VERSION.tar.gz + tar xf $MBED_VERSION.tar.gz + pushd $MBED_ROOT_FOLDER_NAME +} + +setup_mbed_library() { + echo "Building libmbedcrypto." + #TODO: explain the bug with SHARED, it is needed for correct linking on some Linux machine + make SHARED=0 $OPTIONS > /dev/null +} + +# Fetch mbed-crypto source code +mkdir -p $TEMP_FOLDER +pushd $TEMP_FOLDER +if [[ -d "$MBED_ROOT_FOLDER_NAME" ]]; then + pushd $MBED_ROOT_FOLDER_NAME +else + get_mbed_repo +fi + +# Set up lib +if [[ -e "library/$MBED_LIB_FILENAME" ]]; then + echo "Library is set up." +else + setup_mbed_library +fi + +# Build shimlib +INCLUDE="`pwd`/include" +SRCDIR="$CARGO_MANIFEST_DIR/$MBED_SHIMLIB_DIR" +pushd "$OUT_DIR" || exit 1 +#xx Some config may be needed here, and what about cross-compilation? +cc -I"$INCLUDE" -Wall -Werror -O2 -c "$SRCDIR"/shim.c -o shim.o +ar rv libshim.a shim.o diff --git a/src/c/shim.c b/src/c/shim.c new file mode 100644 index 0000000..a8b4ff7 --- /dev/null +++ b/src/c/shim.c @@ -0,0 +1,52 @@ +// Copyright 2020 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +#include "shim.h" + +psa_key_attributes_t +shim_key_attributes_init(void) +{ + return psa_key_attributes_init(); +} + +void +shim_set_key_algorithm(psa_key_attributes_t *attributes, + psa_algorithm_t alg) +{ + psa_set_key_algorithm(attributes, alg); +} + +void +shim_set_key_bits(psa_key_attributes_t *attributes, + size_t bits) +{ + psa_set_key_bits(attributes, bits); +} + +void +shim_set_key_id(psa_key_attributes_t *attributes, + psa_key_id_t id) +{ + psa_set_key_id(attributes, id); +} + +void +shim_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime) +{ + psa_set_key_lifetime(attributes, lifetime); +} + +void +shim_set_key_type(psa_key_attributes_t *attributes, + psa_key_type_t type_) +{ + psa_set_key_type(attributes, type_); +} + +void +shim_set_key_usage_flags(psa_key_attributes_t *attributes, + psa_key_usage_t usage_flags) +{ + psa_set_key_usage_flags(attributes, usage_flags); +} diff --git a/src/c/shim.h b/src/c/shim.h new file mode 100644 index 0000000..7bc67ae --- /dev/null +++ b/src/c/shim.h @@ -0,0 +1,171 @@ +// Copyright 2020 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +#include + +const psa_status_t shim_PSA_SUCCESS = PSA_SUCCESS; +const psa_status_t shim_PSA_ERROR_GENERIC_ERROR = PSA_ERROR_GENERIC_ERROR; +const psa_status_t shim_PSA_ERROR_NOT_SUPPORTED = PSA_ERROR_NOT_SUPPORTED; +const psa_status_t shim_PSA_ERROR_NOT_PERMITTED = PSA_ERROR_NOT_PERMITTED; +const psa_status_t shim_PSA_ERROR_BUFFER_TOO_SMALL = PSA_ERROR_BUFFER_TOO_SMALL; +const psa_status_t shim_PSA_ERROR_ALREADY_EXISTS = PSA_ERROR_ALREADY_EXISTS; +const psa_status_t shim_PSA_ERROR_DOES_NOT_EXIST = PSA_ERROR_DOES_NOT_EXIST; +const psa_status_t shim_PSA_ERROR_BAD_STATE = PSA_ERROR_BAD_STATE; +const psa_status_t shim_PSA_ERROR_INVALID_ARGUMENT = PSA_ERROR_INVALID_ARGUMENT; +const psa_status_t shim_PSA_ERROR_INSUFFICIENT_MEMORY = PSA_ERROR_INSUFFICIENT_MEMORY; +const psa_status_t shim_PSA_ERROR_INSUFFICIENT_STORAGE = PSA_ERROR_INSUFFICIENT_STORAGE; +const psa_status_t shim_PSA_ERROR_COMMUNICATION_FAILURE = PSA_ERROR_COMMUNICATION_FAILURE; +const psa_status_t shim_PSA_ERROR_STORAGE_FAILURE = PSA_ERROR_STORAGE_FAILURE; +const psa_status_t shim_PSA_ERROR_HARDWARE_FAILURE = PSA_ERROR_HARDWARE_FAILURE; +const psa_status_t shim_PSA_ERROR_INSUFFICIENT_ENTROPY = PSA_ERROR_INSUFFICIENT_ENTROPY; +const psa_status_t shim_PSA_ERROR_INVALID_SIGNATURE = PSA_ERROR_INVALID_SIGNATURE; +const psa_status_t shim_PSA_ERROR_INVALID_PADDING = PSA_ERROR_INVALID_PADDING; +const psa_status_t shim_PSA_ERROR_INSUFFICIENT_DATA = PSA_ERROR_INSUFFICIENT_DATA; +const psa_status_t shim_PSA_ERROR_INVALID_HANDLE = PSA_ERROR_INVALID_HANDLE; + +const size_t shim_PSA_MAX_KEY_BITS = PSA_MAX_KEY_BITS; +const psa_key_bits_t shim_PSA_KEY_BITS_TOO_LARGE = PSA_KEY_BITS_TOO_LARGE; +const psa_key_type_t shim_PSA_KEY_TYPE_NONE = PSA_KEY_TYPE_NONE; +const psa_key_type_t shim_PSA_KEY_TYPE_VENDOR_FLAG = PSA_KEY_TYPE_VENDOR_FLAG; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_MASK = PSA_KEY_TYPE_CATEGORY_MASK; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_SYMMETRIC = PSA_KEY_TYPE_CATEGORY_SYMMETRIC; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_RAW = PSA_KEY_TYPE_CATEGORY_RAW; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY = PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_KEY_PAIR = PSA_KEY_TYPE_CATEGORY_KEY_PAIR; +const psa_key_type_t shim_PSA_KEY_TYPE_CATEGORY_FLAG_PAIR = PSA_KEY_TYPE_CATEGORY_FLAG_PAIR; +const psa_key_type_t shim_PSA_KEY_TYPE_RAW_DATA = PSA_KEY_TYPE_RAW_DATA; +const psa_key_type_t shim_PSA_KEY_TYPE_HMAC = PSA_KEY_TYPE_HMAC; +const psa_key_type_t shim_PSA_KEY_TYPE_DERIVE = PSA_KEY_TYPE_DERIVE; +const psa_key_type_t shim_PSA_KEY_TYPE_AES = PSA_KEY_TYPE_AES; +const psa_key_type_t shim_PSA_KEY_TYPE_DES = PSA_KEY_TYPE_DES; +const psa_key_type_t shim_PSA_KEY_TYPE_CAMELLIA = PSA_KEY_TYPE_CAMELLIA; +const psa_key_type_t shim_PSA_KEY_TYPE_ARC4 = PSA_KEY_TYPE_ARC4; +const psa_key_type_t shim_PSA_KEY_TYPE_RSA_PUBLIC_KEY = PSA_KEY_TYPE_RSA_PUBLIC_KEY; +const psa_key_type_t shim_PSA_KEY_TYPE_RSA_KEY_PAIR = PSA_KEY_TYPE_RSA_KEY_PAIR; +const psa_key_type_t shim_PSA_KEY_TYPE_DSA_PUBLIC_KEY = PSA_KEY_TYPE_DSA_PUBLIC_KEY; +const psa_key_type_t shim_PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE = PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE; +const psa_key_type_t shim_PSA_KEY_TYPE_ECC_KEY_PAIR_BASE = PSA_KEY_TYPE_ECC_KEY_PAIR_BASE; +const psa_key_type_t shim_PSA_KEY_TYPE_ECC_CURVE_MASK = PSA_KEY_TYPE_ECC_CURVE_MASK; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT163K1 = PSA_ECC_CURVE_SECT163K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT163R1 = PSA_ECC_CURVE_SECT163R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT163R2 = PSA_ECC_CURVE_SECT163R2; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT193R1 = PSA_ECC_CURVE_SECT193R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT193R2 = PSA_ECC_CURVE_SECT193R2; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT233K1 = PSA_ECC_CURVE_SECT233K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT233R1 = PSA_ECC_CURVE_SECT233R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT239K1 = PSA_ECC_CURVE_SECT239K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT283K1 = PSA_ECC_CURVE_SECT283K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT283R1 = PSA_ECC_CURVE_SECT283R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT409K1 = PSA_ECC_CURVE_SECT409K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT409R1 = PSA_ECC_CURVE_SECT409R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT571K1 = PSA_ECC_CURVE_SECT571K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECT571R1 = PSA_ECC_CURVE_SECT571R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP160K1 = PSA_ECC_CURVE_SECP160K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP160R1 = PSA_ECC_CURVE_SECP160R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP160R2 = PSA_ECC_CURVE_SECP160R2; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP192K1 = PSA_ECC_CURVE_SECP192K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP192R1 = PSA_ECC_CURVE_SECP192R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP224K1 = PSA_ECC_CURVE_SECP224K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP224R1 = PSA_ECC_CURVE_SECP224R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP256K1 = PSA_ECC_CURVE_SECP256K1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP256R1 = PSA_ECC_CURVE_SECP256R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP384R1 = PSA_ECC_CURVE_SECP384R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_SECP521R1 = PSA_ECC_CURVE_SECP521R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_BRAINPOOL_P256R1 = PSA_ECC_CURVE_BRAINPOOL_P256R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_BRAINPOOL_P384R1 = PSA_ECC_CURVE_BRAINPOOL_P384R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_BRAINPOOL_P512R1 = PSA_ECC_CURVE_BRAINPOOL_P512R1; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_CURVE25519 = PSA_ECC_CURVE_CURVE25519; +const psa_ecc_curve_t shim_PSA_ECC_CURVE_CURVE448 = PSA_ECC_CURVE_CURVE448; +const psa_algorithm_t shim_PSA_ALG_VENDOR_FLAG = PSA_ALG_VENDOR_FLAG; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_MASK = PSA_ALG_CATEGORY_MASK; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_HASH = PSA_ALG_CATEGORY_HASH; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_MAC = PSA_ALG_CATEGORY_MAC; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_CIPHER = PSA_ALG_CATEGORY_CIPHER; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_AEAD = PSA_ALG_CATEGORY_AEAD; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_SIGN = PSA_ALG_CATEGORY_SIGN; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION = PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_KEY_AGREEMENT = PSA_ALG_CATEGORY_KEY_AGREEMENT; +const psa_algorithm_t shim_PSA_ALG_CATEGORY_KEY_DERIVATION = PSA_ALG_CATEGORY_KEY_DERIVATION; +const psa_algorithm_t shim_PSA_ALG_HASH_MASK = PSA_ALG_HASH_MASK; +const psa_algorithm_t shim_PSA_ALG_MD2 = PSA_ALG_MD2; +const psa_algorithm_t shim_PSA_ALG_MD4 = PSA_ALG_MD4; +const psa_algorithm_t shim_PSA_ALG_MD5 = PSA_ALG_MD5; +const psa_algorithm_t shim_PSA_ALG_RIPEMD160 = PSA_ALG_RIPEMD160; +const psa_algorithm_t shim_PSA_ALG_SHA_1 = PSA_ALG_SHA_1; +const psa_algorithm_t shim_PSA_ALG_SHA_224 = PSA_ALG_SHA_224; +const psa_algorithm_t shim_PSA_ALG_SHA_256 = PSA_ALG_SHA_256; +const psa_algorithm_t shim_PSA_ALG_SHA_384 = PSA_ALG_SHA_384; +const psa_algorithm_t shim_PSA_ALG_SHA_512 = PSA_ALG_SHA_512; +const psa_algorithm_t shim_PSA_ALG_SHA_512_224 = PSA_ALG_SHA_512_224; +const psa_algorithm_t shim_PSA_ALG_SHA_512_256 = PSA_ALG_SHA_512_256; +const psa_algorithm_t shim_PSA_ALG_SHA3_224 = PSA_ALG_SHA3_224; +const psa_algorithm_t shim_PSA_ALG_SHA3_256 = PSA_ALG_SHA3_256; +const psa_algorithm_t shim_PSA_ALG_SHA3_384 = PSA_ALG_SHA3_384; +const psa_algorithm_t shim_PSA_ALG_SHA3_512 = PSA_ALG_SHA3_512; +const psa_algorithm_t shim_PSA_ALG_ANY_HASH = PSA_ALG_ANY_HASH; +const psa_algorithm_t shim_PSA_ALG_MAC_SUBCATEGORY_MASK = PSA_ALG_MAC_SUBCATEGORY_MASK; +const psa_algorithm_t shim_PSA_ALG_HMAC_BASE = PSA_ALG_HMAC_BASE; +const psa_algorithm_t shim_PSA_ALG_MAC_TRUNCATION_MASK = PSA_ALG_MAC_TRUNCATION_MASK; +const psa_algorithm_t shim_PSA_ALG_CIPHER_MAC_BASE = PSA_ALG_CIPHER_MAC_BASE; +const psa_algorithm_t shim_PSA_ALG_CBC_MAC = PSA_ALG_CBC_MAC; +const psa_algorithm_t shim_PSA_ALG_CMAC = PSA_ALG_CMAC; +const psa_algorithm_t shim_PSA_ALG_CIPHER_STREAM_FLAG = PSA_ALG_CIPHER_STREAM_FLAG; +const psa_algorithm_t shim_PSA_ALG_CIPHER_FROM_BLOCK_FLAG = PSA_ALG_CIPHER_FROM_BLOCK_FLAG; +const psa_algorithm_t shim_PSA_ALG_ARC4 = PSA_ALG_ARC4; +const psa_algorithm_t shim_PSA_ALG_CTR = PSA_ALG_CTR; +const psa_algorithm_t shim_PSA_ALG_CFB = PSA_ALG_CFB; +const psa_algorithm_t shim_PSA_ALG_OFB = PSA_ALG_OFB; +const psa_algorithm_t shim_PSA_ALG_XTS = PSA_ALG_XTS; +const psa_algorithm_t shim_PSA_ALG_CBC_NO_PADDING = PSA_ALG_CBC_NO_PADDING; +const psa_algorithm_t shim_PSA_ALG_CBC_PKCS7 = PSA_ALG_CBC_PKCS7; +const psa_algorithm_t shim_PSA_ALG_CCM = PSA_ALG_CCM; +const psa_algorithm_t shim_PSA_ALG_GCM = PSA_ALG_GCM; +const psa_algorithm_t shim_PSA_ALG_AEAD_TAG_LENGTH_MASK = PSA_ALG_AEAD_TAG_LENGTH_MASK; +const psa_algorithm_t shim_PSA_ALG_RSA_PKCS1V15_SIGN_BASE = PSA_ALG_RSA_PKCS1V15_SIGN_BASE; +const psa_algorithm_t shim_PSA_ALG_RSA_PSS_BASE = PSA_ALG_RSA_PSS_BASE; +const psa_algorithm_t shim_PSA_ALG_DSA_BASE = PSA_ALG_DSA_BASE; +const psa_algorithm_t shim_PSA_ALG_DETERMINISTIC_DSA_BASE = PSA_ALG_DETERMINISTIC_DSA_BASE; +const psa_algorithm_t shim_PSA_ALG_DSA_DETERMINISTIC_FLAG = PSA_ALG_DSA_DETERMINISTIC_FLAG; +const psa_algorithm_t shim_PSA_ALG_ECDSA_BASE = PSA_ALG_ECDSA_BASE; +const psa_algorithm_t shim_PSA_ALG_DETERMINISTIC_ECDSA_BASE = PSA_ALG_DETERMINISTIC_ECDSA_BASE; +const psa_algorithm_t shim_PSA_ALG_RSA_PKCS1V15_CRYPT = PSA_ALG_RSA_PKCS1V15_CRYPT; +const psa_algorithm_t shim_PSA_ALG_RSA_OAEP_BASE = PSA_ALG_RSA_OAEP_BASE; +const psa_algorithm_t shim_PSA_ALG_HKDF_BASE = PSA_ALG_HKDF_BASE; +const psa_algorithm_t shim_PSA_ALG_TLS12_PRF_BASE = PSA_ALG_TLS12_PRF_BASE; +const psa_algorithm_t shim_PSA_ALG_TLS12_PSK_TO_MS_BASE = PSA_ALG_TLS12_PSK_TO_MS_BASE; +const psa_algorithm_t shim_PSA_ALG_KEY_DERIVATION_MASK = PSA_ALG_KEY_DERIVATION_MASK; +const psa_key_lifetime_t shim_PSA_KEY_LIFETIME_VOLATILE = PSA_KEY_LIFETIME_VOLATILE; +const psa_key_lifetime_t shim_PSA_KEY_LIFETIME_PERSISTENT = PSA_KEY_LIFETIME_PERSISTENT; +const psa_key_usage_t shim_PSA_KEY_USAGE_EXPORT = PSA_KEY_USAGE_EXPORT; +const psa_key_usage_t shim_PSA_KEY_USAGE_ENCRYPT = PSA_KEY_USAGE_ENCRYPT; +const psa_key_usage_t shim_PSA_KEY_USAGE_DECRYPT = PSA_KEY_USAGE_DECRYPT; +const psa_key_usage_t shim_PSA_KEY_USAGE_SIGN = PSA_KEY_USAGE_SIGN; +const psa_key_usage_t shim_PSA_KEY_USAGE_VERIFY = PSA_KEY_USAGE_VERIFY; +const psa_key_usage_t shim_PSA_KEY_USAGE_DERIVE = PSA_KEY_USAGE_DERIVE; + +psa_key_attributes_t +shim_key_attributes_init(void); + +void +shim_set_key_algorithm(psa_key_attributes_t *attributes, + psa_algorithm_t alg); + +void +shim_set_key_bits(psa_key_attributes_t *attributes, + size_t bits); + +void +shim_set_key_id(psa_key_attributes_t *attributes, + psa_key_id_t id); + +void +shim_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime); + +void +shim_set_key_type(psa_key_attributes_t *attributes, + psa_key_type_t type_); + +void +shim_set_key_usage_flags(psa_key_attributes_t *attributes, + psa_key_usage_t usage_flags); diff --git a/src/constants.rs b/src/constants.rs new file mode 100644 index 0000000..18ae2bf --- /dev/null +++ b/src/constants.rs @@ -0,0 +1,154 @@ +// Copyright 2020 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +//! Constants used by the Mbed Provider for interaction with the Mbed Crypto C library. + +#![allow(missing_docs)] + +use super::psa_crypto_binding::*; + +// xx There are not part of the public PSA API and should be removed: +pub const PSA_KEY_SLOT_COUNT: isize = 32; +pub const PSA_MAX_PERSISTENT_KEY_IDENTIFIER: psa_key_id_t = 0x3fff_ffff; + +// PSA error codes +pub const PSA_SUCCESS: psa_status_t = shim_PSA_SUCCESS; +pub const PSA_ERROR_GENERIC_ERROR: psa_status_t = shim_PSA_ERROR_GENERIC_ERROR; +pub const PSA_ERROR_NOT_SUPPORTED: psa_status_t = shim_PSA_ERROR_NOT_SUPPORTED; +pub const PSA_ERROR_NOT_PERMITTED: psa_status_t = shim_PSA_ERROR_NOT_PERMITTED; +pub const PSA_ERROR_BUFFER_TOO_SMALL: psa_status_t = shim_PSA_ERROR_BUFFER_TOO_SMALL; +pub const PSA_ERROR_ALREADY_EXISTS: psa_status_t = shim_PSA_ERROR_ALREADY_EXISTS; +pub const PSA_ERROR_DOES_NOT_EXIST: psa_status_t = shim_PSA_ERROR_DOES_NOT_EXIST; +pub const PSA_ERROR_BAD_STATE: psa_status_t = shim_PSA_ERROR_BAD_STATE; +pub const PSA_ERROR_INVALID_ARGUMENT: psa_status_t = shim_PSA_ERROR_INVALID_ARGUMENT; +pub const PSA_ERROR_INSUFFICIENT_MEMORY: psa_status_t = shim_PSA_ERROR_INSUFFICIENT_MEMORY; +pub const PSA_ERROR_INSUFFICIENT_STORAGE: psa_status_t = shim_PSA_ERROR_INSUFFICIENT_STORAGE; +pub const PSA_ERROR_COMMUNICATION_FAILURE: psa_status_t = shim_PSA_ERROR_COMMUNICATION_FAILURE; +pub const PSA_ERROR_STORAGE_FAILURE: psa_status_t = shim_PSA_ERROR_STORAGE_FAILURE; +pub const PSA_ERROR_HARDWARE_FAILURE: psa_status_t = shim_PSA_ERROR_HARDWARE_FAILURE; +pub const PSA_ERROR_INSUFFICIENT_ENTROPY: psa_status_t = shim_PSA_ERROR_INSUFFICIENT_ENTROPY; +pub const PSA_ERROR_INVALID_SIGNATURE: psa_status_t = shim_PSA_ERROR_INVALID_SIGNATURE; +pub const PSA_ERROR_INVALID_PADDING: psa_status_t = shim_PSA_ERROR_INVALID_PADDING; +pub const PSA_ERROR_INSUFFICIENT_DATA: psa_status_t = shim_PSA_ERROR_INSUFFICIENT_DATA; +pub const PSA_ERROR_INVALID_HANDLE: psa_status_t = shim_PSA_ERROR_INVALID_HANDLE; + +pub const PSA_MAX_KEY_BITS: usize = shim_PSA_MAX_KEY_BITS; +pub const PSA_KEY_BITS_TOO_LARGE: psa_key_bits_t = shim_PSA_KEY_BITS_TOO_LARGE; +pub const PSA_KEY_TYPE_NONE: psa_key_type_t = shim_PSA_KEY_TYPE_NONE; +pub const PSA_KEY_TYPE_VENDOR_FLAG: psa_key_type_t = shim_PSA_KEY_TYPE_VENDOR_FLAG; +pub const PSA_KEY_TYPE_CATEGORY_MASK: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_MASK; +pub const PSA_KEY_TYPE_CATEGORY_SYMMETRIC: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_SYMMETRIC; +pub const PSA_KEY_TYPE_CATEGORY_RAW: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_RAW; +pub const PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY; +pub const PSA_KEY_TYPE_CATEGORY_KEY_PAIR: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_KEY_PAIR; +pub const PSA_KEY_TYPE_CATEGORY_FLAG_PAIR: psa_key_type_t = shim_PSA_KEY_TYPE_CATEGORY_FLAG_PAIR; +pub const PSA_KEY_TYPE_RAW_DATA: psa_key_type_t = shim_PSA_KEY_TYPE_RAW_DATA; +pub const PSA_KEY_TYPE_HMAC: psa_key_type_t = shim_PSA_KEY_TYPE_HMAC; +pub const PSA_KEY_TYPE_DERIVE: psa_key_type_t = shim_PSA_KEY_TYPE_DERIVE; +pub const PSA_KEY_TYPE_AES: psa_key_type_t = shim_PSA_KEY_TYPE_AES; +pub const PSA_KEY_TYPE_DES: psa_key_type_t = shim_PSA_KEY_TYPE_DES; +pub const PSA_KEY_TYPE_CAMELLIA: psa_key_type_t = shim_PSA_KEY_TYPE_CAMELLIA; +pub const PSA_KEY_TYPE_ARC4: psa_key_type_t = shim_PSA_KEY_TYPE_ARC4; +pub const PSA_KEY_TYPE_RSA_PUBLIC_KEY: psa_key_type_t = shim_PSA_KEY_TYPE_RSA_PUBLIC_KEY; +pub const PSA_KEY_TYPE_RSA_KEY_PAIR: psa_key_type_t = shim_PSA_KEY_TYPE_RSA_KEY_PAIR; +pub const PSA_KEY_TYPE_DSA_PUBLIC_KEY: psa_key_type_t = shim_PSA_KEY_TYPE_DSA_PUBLIC_KEY; +pub const PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE: psa_key_type_t = shim_PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE; +pub const PSA_KEY_TYPE_ECC_KEY_PAIR_BASE: psa_key_type_t = shim_PSA_KEY_TYPE_ECC_KEY_PAIR_BASE; +pub const PSA_KEY_TYPE_ECC_CURVE_MASK: psa_key_type_t = shim_PSA_KEY_TYPE_ECC_CURVE_MASK; +pub const PSA_ECC_CURVE_SECT163K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT163K1; +pub const PSA_ECC_CURVE_SECT163R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT163R1; +pub const PSA_ECC_CURVE_SECT163R2: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT163R2; +pub const PSA_ECC_CURVE_SECT193R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT193R1; +pub const PSA_ECC_CURVE_SECT193R2: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT193R2; +pub const PSA_ECC_CURVE_SECT233K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT233K1; +pub const PSA_ECC_CURVE_SECT233R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT233R1; +pub const PSA_ECC_CURVE_SECT239K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT239K1; +pub const PSA_ECC_CURVE_SECT283K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT283K1; +pub const PSA_ECC_CURVE_SECT283R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT283R1; +pub const PSA_ECC_CURVE_SECT409K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT409K1; +pub const PSA_ECC_CURVE_SECT409R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT409R1; +pub const PSA_ECC_CURVE_SECT571K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT571K1; +pub const PSA_ECC_CURVE_SECT571R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECT571R1; +pub const PSA_ECC_CURVE_SECP160K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP160K1; +pub const PSA_ECC_CURVE_SECP160R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP160R1; +pub const PSA_ECC_CURVE_SECP160R2: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP160R2; +pub const PSA_ECC_CURVE_SECP192K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP192K1; +pub const PSA_ECC_CURVE_SECP192R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP192R1; +pub const PSA_ECC_CURVE_SECP224K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP224K1; +pub const PSA_ECC_CURVE_SECP224R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP224R1; +pub const PSA_ECC_CURVE_SECP256K1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP256K1; +pub const PSA_ECC_CURVE_SECP256R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP256R1; +pub const PSA_ECC_CURVE_SECP384R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP384R1; +pub const PSA_ECC_CURVE_SECP521R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_SECP521R1; +pub const PSA_ECC_CURVE_BRAINPOOL_P256R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_BRAINPOOL_P256R1; +pub const PSA_ECC_CURVE_BRAINPOOL_P384R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_BRAINPOOL_P384R1; +pub const PSA_ECC_CURVE_BRAINPOOL_P512R1: psa_ecc_curve_t = shim_PSA_ECC_CURVE_BRAINPOOL_P512R1; +pub const PSA_ECC_CURVE_CURVE25519: psa_ecc_curve_t = shim_PSA_ECC_CURVE_CURVE25519; +pub const PSA_ECC_CURVE_CURVE448: psa_ecc_curve_t = shim_PSA_ECC_CURVE_CURVE448; +pub const PSA_ALG_VENDOR_FLAG: psa_algorithm_t = shim_PSA_ALG_VENDOR_FLAG; +pub const PSA_ALG_CATEGORY_MASK: psa_algorithm_t = shim_PSA_ALG_CATEGORY_MASK; +pub const PSA_ALG_CATEGORY_HASH: psa_algorithm_t = shim_PSA_ALG_CATEGORY_HASH; +pub const PSA_ALG_CATEGORY_MAC: psa_algorithm_t = shim_PSA_ALG_CATEGORY_MAC; +pub const PSA_ALG_CATEGORY_CIPHER: psa_algorithm_t = shim_PSA_ALG_CATEGORY_CIPHER; +pub const PSA_ALG_CATEGORY_AEAD: psa_algorithm_t = shim_PSA_ALG_CATEGORY_AEAD; +pub const PSA_ALG_CATEGORY_SIGN: psa_algorithm_t = shim_PSA_ALG_CATEGORY_SIGN; +pub const PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION: psa_algorithm_t = + shim_PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION; +pub const PSA_ALG_CATEGORY_KEY_AGREEMENT: psa_algorithm_t = shim_PSA_ALG_CATEGORY_KEY_AGREEMENT; +pub const PSA_ALG_CATEGORY_KEY_DERIVATION: psa_algorithm_t = shim_PSA_ALG_CATEGORY_KEY_DERIVATION; +pub const PSA_ALG_HASH_MASK: psa_algorithm_t = shim_PSA_ALG_HASH_MASK; +pub const PSA_ALG_MD2: psa_algorithm_t = shim_PSA_ALG_MD2; +pub const PSA_ALG_MD4: psa_algorithm_t = shim_PSA_ALG_MD4; +pub const PSA_ALG_MD5: psa_algorithm_t = shim_PSA_ALG_MD5; +pub const PSA_ALG_RIPEMD160: psa_algorithm_t = shim_PSA_ALG_RIPEMD160; +pub const PSA_ALG_SHA_1: psa_algorithm_t = shim_PSA_ALG_SHA_1; +pub const PSA_ALG_SHA_224: psa_algorithm_t = shim_PSA_ALG_SHA_224; +pub const PSA_ALG_SHA_256: psa_algorithm_t = shim_PSA_ALG_SHA_256; +pub const PSA_ALG_SHA_384: psa_algorithm_t = shim_PSA_ALG_SHA_384; +pub const PSA_ALG_SHA_512: psa_algorithm_t = shim_PSA_ALG_SHA_512; +pub const PSA_ALG_SHA_512_224: psa_algorithm_t = shim_PSA_ALG_SHA_512_224; +pub const PSA_ALG_SHA_512_256: psa_algorithm_t = shim_PSA_ALG_SHA_512_256; +pub const PSA_ALG_SHA3_224: psa_algorithm_t = shim_PSA_ALG_SHA3_224; +pub const PSA_ALG_SHA3_256: psa_algorithm_t = shim_PSA_ALG_SHA3_256; +pub const PSA_ALG_SHA3_384: psa_algorithm_t = shim_PSA_ALG_SHA3_384; +pub const PSA_ALG_SHA3_512: psa_algorithm_t = shim_PSA_ALG_SHA3_512; +pub const PSA_ALG_ANY_HASH: psa_algorithm_t = shim_PSA_ALG_ANY_HASH; +pub const PSA_ALG_MAC_SUBCATEGORY_MASK: psa_algorithm_t = shim_PSA_ALG_MAC_SUBCATEGORY_MASK; +pub const PSA_ALG_HMAC_BASE: psa_algorithm_t = shim_PSA_ALG_HMAC_BASE; +pub const PSA_ALG_MAC_TRUNCATION_MASK: psa_algorithm_t = shim_PSA_ALG_MAC_TRUNCATION_MASK; +pub const PSA_ALG_CIPHER_MAC_BASE: psa_algorithm_t = shim_PSA_ALG_CIPHER_MAC_BASE; +pub const PSA_ALG_CBC_MAC: psa_algorithm_t = shim_PSA_ALG_CBC_MAC; +pub const PSA_ALG_CMAC: psa_algorithm_t = shim_PSA_ALG_CMAC; +pub const PSA_ALG_CIPHER_STREAM_FLAG: psa_algorithm_t = shim_PSA_ALG_CIPHER_STREAM_FLAG; +pub const PSA_ALG_CIPHER_FROM_BLOCK_FLAG: psa_algorithm_t = shim_PSA_ALG_CIPHER_FROM_BLOCK_FLAG; +pub const PSA_ALG_ARC4: psa_algorithm_t = shim_PSA_ALG_ARC4; +pub const PSA_ALG_CTR: psa_algorithm_t = shim_PSA_ALG_CTR; +pub const PSA_ALG_CFB: psa_algorithm_t = shim_PSA_ALG_CFB; +pub const PSA_ALG_OFB: psa_algorithm_t = shim_PSA_ALG_OFB; +pub const PSA_ALG_XTS: psa_algorithm_t = shim_PSA_ALG_XTS; +pub const PSA_ALG_CBC_NO_PADDING: psa_algorithm_t = shim_PSA_ALG_CBC_NO_PADDING; +pub const PSA_ALG_CBC_PKCS7: psa_algorithm_t = shim_PSA_ALG_CBC_PKCS7; +pub const PSA_ALG_CCM: psa_algorithm_t = shim_PSA_ALG_CCM; +pub const PSA_ALG_GCM: psa_algorithm_t = shim_PSA_ALG_GCM; +pub const PSA_ALG_AEAD_TAG_LENGTH_MASK: psa_algorithm_t = shim_PSA_ALG_AEAD_TAG_LENGTH_MASK; +pub const PSA_ALG_RSA_PKCS1V15_SIGN_BASE: psa_algorithm_t = shim_PSA_ALG_RSA_PKCS1V15_SIGN_BASE; +pub const PSA_ALG_RSA_PSS_BASE: psa_algorithm_t = shim_PSA_ALG_RSA_PSS_BASE; +pub const PSA_ALG_DSA_BASE: psa_algorithm_t = shim_PSA_ALG_DSA_BASE; +pub const PSA_ALG_DETERMINISTIC_DSA_BASE: psa_algorithm_t = shim_PSA_ALG_DETERMINISTIC_DSA_BASE; +pub const PSA_ALG_DSA_DETERMINISTIC_FLAG: psa_algorithm_t = shim_PSA_ALG_DSA_DETERMINISTIC_FLAG; +pub const PSA_ALG_ECDSA_BASE: psa_algorithm_t = shim_PSA_ALG_ECDSA_BASE; +pub const PSA_ALG_DETERMINISTIC_ECDSA_BASE: psa_algorithm_t = shim_PSA_ALG_DETERMINISTIC_ECDSA_BASE; +pub const PSA_ALG_RSA_PKCS1V15_CRYPT: psa_algorithm_t = shim_PSA_ALG_RSA_PKCS1V15_CRYPT; +pub const PSA_ALG_RSA_OAEP_BASE: psa_algorithm_t = shim_PSA_ALG_RSA_OAEP_BASE; +pub const PSA_ALG_HKDF_BASE: psa_algorithm_t = shim_PSA_ALG_HKDF_BASE; +pub const PSA_ALG_TLS12_PRF_BASE: psa_algorithm_t = shim_PSA_ALG_TLS12_PRF_BASE; +pub const PSA_ALG_TLS12_PSK_TO_MS_BASE: psa_algorithm_t = shim_PSA_ALG_TLS12_PSK_TO_MS_BASE; +pub const PSA_ALG_KEY_DERIVATION_MASK: psa_algorithm_t = shim_PSA_ALG_KEY_DERIVATION_MASK; +pub const PSA_KEY_LIFETIME_VOLATILE: psa_key_lifetime_t = shim_PSA_KEY_LIFETIME_VOLATILE; +pub const PSA_KEY_LIFETIME_PERSISTENT: psa_key_lifetime_t = shim_PSA_KEY_LIFETIME_PERSISTENT; +pub const PSA_KEY_USAGE_EXPORT: psa_key_usage_t = shim_PSA_KEY_USAGE_EXPORT; +pub const PSA_KEY_USAGE_ENCRYPT: psa_key_usage_t = shim_PSA_KEY_USAGE_ENCRYPT; +pub const PSA_KEY_USAGE_DECRYPT: psa_key_usage_t = shim_PSA_KEY_USAGE_DECRYPT; +pub const PSA_KEY_USAGE_SIGN: psa_key_usage_t = shim_PSA_KEY_USAGE_SIGN; +pub const PSA_KEY_USAGE_VERIFY: psa_key_usage_t = shim_PSA_KEY_USAGE_VERIFY; +pub const PSA_KEY_USAGE_DERIVE: psa_key_usage_t = shim_PSA_KEY_USAGE_DERIVE; diff --git a/src/lib.rs b/src/lib.rs index fc6fd14..23cf67b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,278 @@ )] // This one is hard to avoid. #![allow(clippy::multiple_crate_versions)] +//xx For now: +#![allow(missing_debug_implementations)] +#![allow(missing_docs)] + +use lazy_static::lazy_static; +use std::sync::Mutex; + +#[allow( + non_snake_case, + non_camel_case_types, + non_upper_case_globals, + dead_code, + trivial_casts +)] +#[allow(clippy::all)] +mod psa_crypto_binding { + include!(concat!(env!("OUT_DIR"), "/shim_bindings.rs")); +} + +#[allow(dead_code)] +mod constants; +pub use constants::*; + +struct Global { + init_succeeded: bool, + // Calls to psa_open_key, psa_generate_key and psa_destroy_key + // are not thread safe. We work around this bug with the key_mutex. + // Mbed issue: https://github.com/ARMmbed/mbed-crypto/issues/266 + key_mutex: Mutex<()>, +} + +impl Global { + fn new() -> Global { + return Global { + init_succeeded: false, + key_mutex: Mutex::new(()), + }; + } +} + +lazy_static! { + static ref GLOBAL: Mutex = Mutex::new(Global::new()); +} + +fn init() -> bool { + if GLOBAL.lock().unwrap().init_succeeded { + return true; + } + let status = unsafe { psa_crypto_binding::psa_crypto_init() }; + if status != PSA_SUCCESS { + return false; + } + GLOBAL.lock().unwrap().init_succeeded = true; + return true; +} + +macro_rules! wrap_any { + ($x:expr) => { + if !init() { + panic!("Error when initialising PSA Crypto") + } else { + #[allow(unused_unsafe)] + unsafe { + $x + } + } + }; +} + +macro_rules! wrap_status { + ($x:expr) => { + if !init() { + PSA_ERROR_BAD_STATE + } else { + unsafe { $x } + } + }; +} + +macro_rules! key_lock { + ($x:expr) => {{ + let mutex = &GLOBAL.lock().unwrap().key_mutex; + let _guard = mutex.lock().unwrap(); + $x + }}; +} + +// Reexported types: + +pub use psa_crypto_binding::psa_algorithm_t; +pub use psa_crypto_binding::psa_key_handle_t; +pub use psa_crypto_binding::psa_key_id_t; +pub use psa_crypto_binding::psa_key_lifetime_t; +pub use psa_crypto_binding::psa_key_type_t; +pub use psa_crypto_binding::psa_key_usage_t; +pub use psa_crypto_binding::psa_status_t; + +// Wrapped types: + +#[allow(non_camel_case_types)] +pub struct psa_key_attributes_t { + x: psa_crypto_binding::psa_key_attributes_t, +} + +impl Drop for psa_key_attributes_t { + fn drop(&mut self) { + wrap_any!(psa_crypto_binding::psa_reset_key_attributes(&mut self.x)); + } +} + +// Wrapped linkable functions: + +pub fn psa_asymmetric_sign( + handle: psa_key_handle_t, + alg: psa_algorithm_t, + hash: *const u8, + hash_length: usize, + signature: *mut u8, + signature_size: usize, + signature_length: *mut usize, +) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_asymmetric_sign( + handle, + alg, + hash, + hash_length, + signature, + signature_size, + signature_length + )) +} + +pub fn psa_asymmetric_verify( + handle: psa_key_handle_t, + alg: psa_algorithm_t, + hash: *const u8, + hash_length: usize, + signature: *const u8, + signature_length: usize, +) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_asymmetric_verify( + handle, + alg, + hash, + hash_length, + signature, + signature_length + )) +} + +pub fn psa_close_key(handle: psa_key_handle_t) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_close_key(handle)) +} + +pub fn psa_destroy_key(handle: psa_key_handle_t) -> psa_status_t { + wrap_status!(key_lock!(psa_crypto_binding::psa_destroy_key(handle))) +} + +pub fn psa_export_public_key( + handle: psa_key_handle_t, + data: *mut u8, + data_size: usize, + data_length: *mut usize, +) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_export_public_key( + handle, + data, + data_size, + data_length + )) +} + +pub fn psa_generate_key( + attributes: *const psa_key_attributes_t, + handle: *mut psa_key_handle_t, +) -> psa_status_t { + wrap_status!(key_lock!(psa_crypto_binding::psa_generate_key( + &(*attributes).x, + handle + ))) +} + +pub fn psa_get_key_attributes( + handle: psa_key_handle_t, + attributes: *mut psa_key_attributes_t, +) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_get_key_attributes( + handle, + &mut (*attributes).x + )) +} + +pub fn psa_get_key_bits(attributes: &psa_key_attributes_t) -> usize { + wrap_any!((*attributes).x.core.bits as usize) +} + +pub fn psa_get_key_type(attributes: &psa_key_attributes_t) -> psa_key_type_t { + wrap_any!((*attributes).x.core.type_) +} + +pub fn psa_import_key( + attributes: *const psa_key_attributes_t, + data: *const u8, + data_length: usize, + handle: *mut psa_key_handle_t, +) -> psa_status_t { + wrap_status!(psa_crypto_binding::psa_import_key( + &(*attributes).x, + data, + data_length, + handle + )) +} + +pub fn psa_open_key(id: psa_key_id_t, handle: *mut psa_key_handle_t) -> psa_status_t { + wrap_status!(key_lock!(psa_crypto_binding::psa_open_key(id, handle))) +} + +pub fn psa_reset_key_attributes(attributes: *mut psa_key_attributes_t) { + wrap_any!(psa_crypto_binding::psa_reset_key_attributes( + &mut (*attributes).x + )) +} + +// Wrapped shims: + +pub fn psa_key_attributes_init() -> psa_key_attributes_t { + let attr = wrap_any!(psa_crypto_binding::shim_key_attributes_init()); + return psa_key_attributes_t { x: attr }; +} + +pub fn psa_set_key_algorithm(attributes: &mut psa_key_attributes_t, alg: psa_algorithm_t) { + wrap_any!(psa_crypto_binding::shim_set_key_algorithm( + &mut attributes.x, + alg + )); +} + +pub fn psa_set_key_bits(attributes: &mut psa_key_attributes_t, bits: usize) { + wrap_any!(psa_crypto_binding::shim_set_key_bits( + &mut attributes.x, + bits + )); +} + +pub fn psa_set_key_id(attributes: &mut psa_key_attributes_t, id: psa_key_id_t) { + wrap_any!(psa_crypto_binding::shim_set_key_id(&mut attributes.x, id)); +} + +pub fn psa_set_key_lifetime(attributes: &mut psa_key_attributes_t, lifetime: psa_key_lifetime_t) { + wrap_any!(psa_crypto_binding::shim_set_key_lifetime( + &mut attributes.x, + lifetime + )); +} + +pub fn psa_set_key_type(attributes: &mut psa_key_attributes_t, type_: psa_key_type_t) { + wrap_any!(psa_crypto_binding::shim_set_key_type( + &mut attributes.x, + type_ + )); +} + +pub fn psa_set_key_usage_flags( + attributes: &mut psa_key_attributes_t, + usage_flags: psa_key_usage_t, +) { + wrap_any!(psa_crypto_binding::shim_set_key_usage_flags( + &mut attributes.x, + usage_flags + )); +} #[cfg(test)] mod tests {