diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9337843c..4ab1faca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,18 +180,21 @@ jobs: needs: [build-and-export-cross-compile-docker] steps: - uses: actions/checkout@v3 - - name: Load Docker - uses: ./.github/actions/load_docker - if: ${{ env.TEST_CROSS_DOCKER_IMAGE == 'parsec-service-test-cross-compile' }} - with: - image-name: "${{ env.TEST_CROSS_DOCKER_IMAGE }}" - image-path: "/tmp" + # - name: Load Docker + # uses: ./.github/actions/load_docker + # if: ${{ env.TEST_CROSS_DOCKER_IMAGE == 'parsec-service-test-cross-compile' }} + # with: + # image-name: "${{ env.TEST_CROSS_DOCKER_IMAGE }}" + # image-path: "/tmp" + # Use the following step when updating the `parsec-service-test-all` image + - name: Build the container + run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-cross-compile -f parsec-service-test-cross-compile.Dockerfile . && popd - name: Run the cross compiler tests using pre-built docker image - if: ${{ env.TEST_CROSS_DOCKER_IMAGE != 'parsec-service-test-cross-compile' }} - run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-cross-compile /tmp/parsec/test/cross-compile.sh - - name: Run the cross compiler tests using image built on the CI if: ${{ env.TEST_CROSS_DOCKER_IMAGE == 'parsec-service-test-cross-compile' }} - run: docker run -v $(pwd):/tmp/parsec -w "${{ env.TEST_CROSS_DOCKER_IMAGE }}" /tmp/parsec/test/cross-compile.sh + run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-cross-compile /tmp/parsec/test/cross-compile.sh + - name: Run the cross compiler tests using image built on the CI + if: ${{ env.TEST_CROSS_DOCKER_IMAGE != 'parsec-service-test-cross-compile' }} + run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-cross-compile /tmp/parsec/test/cross-compile.sh links: name: Check links diff --git a/build.rs b/build.rs index ad94c795..ceebda77 100644 --- a/build.rs +++ b/build.rs @@ -19,6 +19,7 @@ fn generate_ts_bindings(ts_include_dir: String) -> Result<()> { println!("cargo:rerun-if-changed={}", header); let bindings = bindgen::Builder::default() + .clang_arg(format!("-I{}", ts_include_dir)) .clang_arg(format!( "-I{}", ts_include_dir + "/components/rpc/common/interface" diff --git a/ci.sh b/ci.sh index c3a5cc02..1f8f30c8 100755 --- a/ci.sh +++ b/ci.sh @@ -120,7 +120,9 @@ run_old_e2e_tests() { run_key_mappings_tests() { # There is no keys generated for CryptoAuthLib yet. # This condition should be removed when the keys are generated for the CAL provider - if ! [[ "$PROVIDER_NAME" = "cryptoauthlib" ]]; then + # The v1.0.0 version of libts required for testing trusted-services does not generate keys + # in the form of 00*.psa_its. Hence we skip this test for the TS provider. + if ! [[ "$PROVIDER_NAME" = "cryptoauthlib" || "$PROVIDER_NAME" = "trusted-service" ]]; then echo "Execute key mappings tests" RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml key_mappings fi diff --git a/e2e_tests/docker_image/parsec-service-test-all.Dockerfile b/e2e_tests/docker_image/parsec-service-test-all.Dockerfile index f545b0fd..2678443a 100644 --- a/e2e_tests/docker_image/parsec-service-test-all.Dockerfile +++ b/e2e_tests/docker_image/parsec-service-test-all.Dockerfile @@ -161,3 +161,18 @@ ENV SPIFFE_ENDPOINT_SOCKET="unix:///tmp/agent.sock" # Add safe.directory configuration to access repos freely RUN git config --global --add safe.directory '*' + +# Install latest Trusted Services libraries. The previously installed +# libraries are old and necessary for ./generate-keys.sh which uses +# Parsec 1.0.0 version that is incompatible with newer libts APIs. +RUN rm /usr/local/lib/libts.so* /usr/local/lib/libprotobuf-nanopb.a /usr/local/lib/libmbedcrypto.a +RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch main \ + && cd trusted-services \ + && git reset --hard b27d4163e01065d1203bd71ffa6562a651f77a13 +# Install correct python dependencies +RUN pip3 install -r trusted-services/requirements.txt +RUN cd trusted-services/deployments/libts/linux-pc/ \ + && cmake . \ + && make \ + && cp libts.so* nanopb_install/lib/libprotobuf-nanopb.a mbedtls_install/lib/libmbedcrypto.a /usr/local/lib/ +RUN rm -rf trusted-services diff --git a/e2e_tests/docker_image/parsec-service-test-cross-compile.Dockerfile b/e2e_tests/docker_image/parsec-service-test-cross-compile.Dockerfile index 92e7caf8..f550f0dc 100644 --- a/e2e_tests/docker_image/parsec-service-test-cross-compile.Dockerfile +++ b/e2e_tests/docker_image/parsec-service-test-cross-compile.Dockerfile @@ -11,9 +11,9 @@ RUN rm aarch64-gcc.tar.xz # Setup git config for patching dependencies RUN git config --global user.email "some@email.com" RUN git config --global user.name "Parsec Team" -RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch integration \ +RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch main \ && cd trusted-services \ - && git reset --hard 389b50624f25dae860bbbf8b16f75b32f1589c8d + && git reset --hard b27d4163e01065d1203bd71ffa6562a651f77a13 # Install correct python dependencies RUN pip3 install -r trusted-services/requirements.txt RUN cd trusted-services/deployments/libts/arm-linux/ \ diff --git a/src/providers/trusted_service/context/mod.rs b/src/providers/trusted_service/context/mod.rs index 05a53e7a..aa5ed498 100644 --- a/src/providers/trusted_service/context/mod.rs +++ b/src/providers/trusted_service/context/mod.rs @@ -4,7 +4,7 @@ use error::{Error, WrapperError}; use log::{error, info, trace}; use prost::Message; use std::convert::{TryFrom, TryInto}; -use std::ffi::{c_void, CString}; +use std::ffi::CString; use std::io::{self}; use std::ptr::null_mut; use std::slice; @@ -61,9 +61,8 @@ mod ts_protobuf; /// is required from the caller. #[derive(Debug)] pub struct Context { - rpc_caller: *mut rpc_caller, + rpc_caller_session: *mut rpc_caller_session, service_context: *mut service_context, - rpc_session_handle: *mut c_void, call_mutex: Mutex<()>, } @@ -75,33 +74,20 @@ impl Context { unsafe { service_locator_init() }; info!("Obtaining a crypto Trusted Service context."); - let mut status = 0; - let service_name = CString::new("sn:trustedfirmware.org:crypto:0").unwrap(); - let service_context = unsafe { service_locator_query(service_name.as_ptr(), &mut status) }; + let service_name = CString::new("sn:trustedfirmware.org:crypto-protobuf:0").unwrap(); + let service_context = unsafe { service_locator_query(service_name.as_ptr()) }; if service_context.is_null() { - error!("Locating crypto Trusted Service failed, status: {}", status); + error!("Locating crypto Trusted Service failed"); return Err(io::Error::new( io::ErrorKind::Other, "Failed to obtain a Trusted Service context", ) .into()); - } else if status != 0 { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "Failed to connect to Trusted Service; status code: {}", - status - ), - ) - .into()); } info!("Starting crypto Trusted Service context"); - let mut rpc_caller = null_mut(); - let rpc_session_handle = unsafe { - service_context_open(service_context, TS_RPC_ENCODING_PROTOBUF, &mut rpc_caller) - }; - if rpc_caller.is_null() || rpc_session_handle.is_null() { + let rpc_caller_session = unsafe { service_context_open(service_context) }; + if rpc_caller_session.is_null() { return Err(io::Error::new( io::ErrorKind::Other, "Failed to start Trusted Service context", @@ -109,9 +95,8 @@ impl Context { .into()); } let ctx = Context { - rpc_caller, + rpc_caller_session, service_context, - rpc_session_handle, call_mutex: Mutex::new(()), }; @@ -129,8 +114,19 @@ impl Context { trace!("Beginning call to Trusted Service"); let mut buf_out = null_mut(); - let call_handle = - unsafe { rpc_caller_begin(self.rpc_caller, &mut buf_out, req.encoded_len()) }; + // The response buffer length is set to 4096 as a common buffer length + // for all operations. In case of the session memory policy being "alloc_for_session" + // which is dependant on the platform, this value doesnt impact but for + // platforms with memory policy "alloc_for_each_call" the buffer length should be + // sufficient enough to hold the entire response. + let call_handle = unsafe { + rpc_caller_session_begin( + self.rpc_caller_session, + &mut buf_out, + req.encoded_len(), + 4096, + ) + }; if call_handle.is_null() { error!("Call handle was null"); return Err(WrapperError::CallHandleNull.into()); @@ -140,7 +136,9 @@ impl Context { } let mut buf_out = unsafe { slice::from_raw_parts_mut(buf_out, req.encoded_len()) }; req.encode(&mut buf_out).map_err(|e| { - unsafe { rpc_caller_end(self.rpc_caller, call_handle) }; + unsafe { + let _ = rpc_caller_session_end(call_handle); + }; format_error!("Failed to serialize Protobuf request", e); WrapperError::FailedPbConversion })?; @@ -151,13 +149,12 @@ impl Context { let mut resp_buf = null_mut(); let mut resp_buf_size = 0; let status = unsafe { - rpc_caller_invoke( - self.rpc_caller, + rpc_caller_session_invoke( call_handle, i32::from(req.opcode()).try_into().unwrap(), - &mut opstatus, &mut resp_buf, &mut resp_buf_size, + &mut opstatus, ) }; Error::from_status_opstatus( @@ -165,16 +162,23 @@ impl Context { i32::try_from(opstatus).map_err(|_| Error::Wrapper(WrapperError::InvalidOpStatus))?, ) .map_err(|e| { - unsafe { rpc_caller_end(self.rpc_caller, call_handle) }; + unsafe { + let _ = rpc_caller_session_end(call_handle); + }; e })?; let resp_buf = unsafe { slice::from_raw_parts_mut(resp_buf, resp_buf_size) }; resp.merge(&*resp_buf).map_err(|e| { - unsafe { rpc_caller_end(self.rpc_caller, call_handle) }; + unsafe { + let _ = rpc_caller_session_end(call_handle); + }; format_error!("Failed to serialize Protobuf request", e); WrapperError::FailedPbConversion })?; - unsafe { rpc_caller_end(self.rpc_caller, call_handle) }; + unsafe { + let status = rpc_caller_session_end(call_handle); + Error::from_status_opstatus(status, 0)?; + }; Ok(resp) } @@ -182,7 +186,7 @@ impl Context { impl Drop for Context { fn drop(&mut self) { - unsafe { service_context_close(self.service_context, self.rpc_session_handle) }; + unsafe { service_context_close(self.service_context, self.rpc_caller_session) }; unsafe { service_context_relinquish(self.service_context) }; } diff --git a/trusted-services-vendor b/trusted-services-vendor index 389b5062..b27d4163 160000 --- a/trusted-services-vendor +++ b/trusted-services-vendor @@ -1 +1 @@ -Subproject commit 389b50624f25dae860bbbf8b16f75b32f1589c8d +Subproject commit b27d4163e01065d1203bd71ffa6562a651f77a13