Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Parsec over to psa-crypto #186

Merged
merged 8 commits into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,592 changes: 0 additions & 1,592 deletions Cargo.lock

This file was deleted.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ name = "parsec"
path = "src/bin/main.rs"

[dependencies]
parsec-interface = "0.15.0"
rand = "0.7.2"
parsec-interface = "0.16.0"
rand = { version = "0.7.2", features = ["small_rng"] }
base64 = "0.10.1"
uuid = "0.7.4"
threadpool = "1.7.1"
Expand All @@ -40,6 +40,7 @@ derivative = "2.1.1"
version = "3.0.0"
hex = "0.4.2"
picky = "5.0.0"
psa-crypto = { version = "0.2.0" , default-features = false, features = ["with-mbed-crypto"], optional = true }

[dev-dependencies]
ring = "0.16.12"
Expand All @@ -59,7 +60,7 @@ features = ["docs"]

[features]
default = []
mbed-crypto-provider = []
mbed-crypto-provider = ["psa-crypto"]
pkcs11-provider = ["pkcs11", "picky-asn1-der", "picky-asn1"]
tpm-provider = ["tss-esapi", "picky-asn1-der", "picky-asn1"]
all-providers = ["tpm-provider", "pkcs11-provider", "mbed-crypto-provider"]
Expand Down
19 changes: 0 additions & 19 deletions build-conf.toml

This file was deleted.

267 changes: 1 addition & 266 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,268 +1,3 @@
// Copyright 2019 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<MbedConfig>,
}

#[derive(Debug, Deserialize)]
struct MbedConfig {
mbed_path: Option<String>,
native: Option<Toolchain>,
aarch64_unknown_linux_gnu: Option<Toolchain>,
}

#[derive(Debug, Deserialize)]
struct Toolchain {
mbed_compiler: Option<String>,
mbed_archiver: Option<String>,
}

fn get_configuration_string(parsec_config: &Value, key: &str) -> Result<String> {
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",
))
};

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 bindings = bindgen::Builder::default()
.clang_arg(format!("-I{}", mbed_include_dir))
.rustfmt_bindings(true)
.header(header)
.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());
bindings.write_to_file(out_path.join("psa_crypto_bindings.rs"))
}

// Get the compiler, the archiver and the location where to clone the Mbed Crypto repository.
fn parse_config_file() -> Result<Configuration> {
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 cfg!(feature = "mbed-crypto-provider") {
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");
}

Ok(())
}
fn main() {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this file is empty we might as well delete it!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the reason we still have that file is that the OUT_DIR environment variable will only exist if that file exist.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I did remove it at first but ran into compilation errors. @hug-dev found this.

2 changes: 1 addition & 1 deletion e2e_tests/provider_cfg/all/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM tpm2software/tpm2-tss:ubuntu-18.04
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig

RUN apt-get update && \
apt-get install -y git make gcc python3 python curl wget && \
apt-get install -y git make gcc python3 python curl wget cmake && \
apt-get install -y automake autoconf libtool pkg-config libssl-dev && \
# These libraries are needed for bindgen as it uses libclang.so
apt-get install -y clang libclang-dev libc6-dev-i386
Expand Down
2 changes: 1 addition & 1 deletion e2e_tests/provider_cfg/mbed-crypto/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM ubuntu:18.04

RUN apt-get update && \
apt-get install -y git make gcc python3 python curl wget libgcc1 && \
apt-get install -y git make gcc python3 python curl wget libgcc1 cmake && \
# These libraries are needed for bindgen as it uses libclang.so
apt-get install -y clang libclang-dev && \
# Needed for Open SSL
Expand Down
38 changes: 5 additions & 33 deletions e2e_tests/tests/per_provider/normal_tests/create_destroy_key.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
// Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use e2e_tests::TestClient;
use parsec_client::core::interface::operations::psa_algorithm::{
Algorithm, AsymmetricSignature, Hash,
};
use parsec_client::core::interface::operations::psa_key_attributes::{
Attributes, Lifetime, Policy, Type, UsageFlags,
};
use parsec_client::core::interface::requests::ResponseStatus;
use parsec_client::core::interface::requests::Result;
use picky_asn1::wrapper::IntegerAsn1;
Expand Down Expand Up @@ -110,35 +104,13 @@ fn generate_public_rsa_check_modulus() -> Result<()> {
fn failed_created_key_should_be_removed() -> Result<()> {
let mut client = TestClient::new();
let key_name = String::from("failed_created_key_should_be_removed");
const GARBAGE_IMPORT_DATA: [u8; 1] = [
48,
];

let attributes = Attributes {
lifetime: Lifetime::Persistent,
key_type: Type::Arc4,
bits: 1024,
policy: Policy {
usage_flags: UsageFlags {
sign_hash: false,
verify_hash: true,
sign_message: false,
verify_message: true,
export: false,
encrypt: false,
decrypt: false,
cache: false,
copy: false,
derive: false,
},
permitted_algorithms: Algorithm::AsymmetricSignature(
AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha256.into(),
},
),
},
};

// Unsupported parameter, should fail
// The data being imported is garbage, should fail
let _ = client
.generate_key(key_name.clone(), attributes)
.import_rsa_public_key(key_name.clone(), GARBAGE_IMPORT_DATA.to_vec())
.unwrap_err();
// The key should not exist anymore in the KIM
client.generate_rsa_sign_key(key_name)?;
Expand Down
Loading