Skip to content
Open
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 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
score/iav_primula/src/*.rs text eol=lf
score/iav_primula/tests/*.rs text eol=lf
score/iav_primula/tests/BUILD text eol=lf
score/tests/test_vectors/hash/*.bin binary
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,136 @@ When used with macros like `dash_license_checker`, it allows dynamic selection o

## DevContainer Setup

The supported development environment is defined by
`.devcontainer/devcontainer.json` and `.devcontainer/Dockerfile`. It currently
uses `ghcr.io/eclipse-score/devcontainer:v1.11.0` and enables Docker-in-Docker
for integration tests.

### Prerequisites

- Docker Desktop or a compatible Docker Engine
- Visual Studio Code with the **Dev Containers** extension
- A local clone of this repository

The `code` and `devcontainer` terminal commands are optional and are not
installed automatically with the macOS applications.

Create the host paths that are mounted by the devcontainer before opening it:

```bash
touch ~/.netrc
mkdir -p ~/.cache/bazel ~/.qnx/license
```

The QNX license directory may remain empty when only Linux targets are built.
The `.netrc` file may also remain empty when no authenticated dependency source
is required, but it must exist because the devcontainer mounts it as a file.

### Open the official environment

On macOS, open the repository without requiring the optional `code` command:

```bash
open -a "Visual Studio Code" .
```

Alternatively, open Visual Studio Code from Applications and select
**File → Open Folder**. To enable `code .` later, open the Command Palette and
run **Shell Command: Install 'code' command in PATH**.

1. Open the repository root in Visual Studio Code using either method above.
2. Run **Dev Containers: Reopen in Container** from the Command Palette.
3. Wait for the image build and the `onCreateCommand` setup to finish.
4. Open a new VS Code terminal. The terminal is now running inside the official
development container.

Confirm the expected tools are available:

```bash
bazel --version
clang-format --version
docker version
uname -m
```

The separate Dev Container CLI is only needed for terminal-based startup. Since
Node.js and npm are already available, it can be installed and verified with:

```bash
npm install -g @devcontainers/cli
rehash
devcontainer --version
```

After the optional CLI is installed, the same environment can be started with:

```bash
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . bash
```

The PR Linux workflow runs on x86_64. On Apple Silicon, the multi-architecture
image starts as `aarch64`; the crypto targets and focused tests below run in
that environment, but the repository-wide `//score/...` set currently reaches
an upstream `score_logging` Rust bridge that has no native aarch64 layout
configuration. Run the full CI-equivalent suite in an x86_64 Linux devcontainer
or CI runner. With the Dev Container CLI, an x86_64 container can be requested
from Apple Silicon as follows when Docker emulation is enabled:

```bash
DOCKER_DEFAULT_PLATFORM=linux/amd64 devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . bash
```

### Build and test inside the devcontainer

Run all commands below from the devcontainer terminal:

```bash
# Build the crypto component (also usable in the native Apple Silicon container).
bazel build //score/crypto/...

# Build every Linux target on the x86_64 CI architecture.
bazel build //score/...

# Run the provider-level hash tests used by the Baselibs hash migration.
bazel test \
//score/crypto/src/daemon/provider/tests/provider_test:test_provider \
//score/crypto/src/daemon/provider/tests/provider_test:test_pkcs11_provider \
--test_output=errors

# The Docker-based integration test needs this image in the devcontainer's
# Docker daemon. Pull it once after creating or rebuilding the devcontainer.
docker pull ubuntu:24.04
bazel test //score/tests/integration_tests:integration_test \
--test_output=all \
--cache_test_results=no

# Run the complete PR test scope on the x86_64 CI architecture.
bazel test //score/... --test_output=errors

# Build the project documentation.
bazel run //:docs
```

`bazel run //examples:hashing_example` is a client-only example. It expects a
configured crypto daemon already listening on
`unix:///tmp/crypto_daemon.sock`; use the Docker integration target above for a
self-contained daemon-and-client execution.

### Formatting and repository checks

The repository's pre-commit configuration runs Bazel metadata checks,
`clang-format`, `clang-tidy`, and the Eclipse copyright checker:

```bash
pre-commit run --all-files
```

The current upstream workflow temporarily skips pre-commit in the common PR
job because the repository-wide clang-tidy baseline is not yet clean. Changed
C++ files must still follow the checked-in `.clang-format` configuration.

### Known Issue: Pre-commit Hook Not Running
**Problem:** The pre-commit hook does not run when using `git commit` inside the DevContainer.

Expand Down
170 changes: 115 additions & 55 deletions docs/features/crypto/architecture/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

.. _feature_architecture_example:
.. _crypto_feature_architecture:

Feature Architecture
====================
Expand All @@ -21,92 +21,152 @@ Feature Architecture
:id: doc__crypto_feat_architecture
:version: 1
:status: draft
:safety: ASIL_B
:safety: QM
:security: YES
:realizes: wp__feature_arch
:tags: template

.. feat:: Security & Crypto
:id: feat__security_crypto
:version: 1
:security: YES
:safety: QM
:status: valid



Overview
--------
<Brief summary>

Description
-----------
The Security & Crypto feature provides applications with a provider-independent
way to execute cryptographic operations without coupling application code to a
specific software library, PKCS#11 token, HSM, or TEE. The current implementation
uses a client-daemon split: applications use the C++ API, while a dedicated daemon
selects providers, owns operation contexts, and executes cryptographic jobs.

<General Description>
The feature is security-relevant but currently classified as QM. In particular,
the complete client, IPC/shared-memory, daemon, and provider path is not presented
as an ISO 26262-qualified replacement for safety-certified Baselibs hashing.

<Design Decisions - For the documentation of the decision the :need:`gd_temp__change_decision_record` can be used.>
Description
-----------

<Design Constraints>
The feature is decomposed into the following responsibilities:

* The public API creates a crypto stack, logical crypto contexts, and typed
operation contexts such as hash and MAC contexts.
* The control plane serializes lifecycle and operation requests and transports
them to the daemon.
* The data plane selects in-band, pooled shared-memory, or registered bulk
shared-memory transport based on the supplied buffers.
* The daemon validates requests, maintains context state, selects a provider,
and dispatches the requested job.
* Provider adapters translate the common operation contract to a concrete
backend. The implemented provider families include OpenSSL and PKCS#11.
* Key-management services resolve key slots and provider-owned key objects
without exposing provider-specific handles through the application API.

Important design decisions are:

* Provider-independent algorithm identifiers are part of the API and wire
contract. Provider-native identifiers are resolved only inside the daemon.
* Operation contexts are explicit resources with a daemon-managed lifecycle.
* Large buffers use validated shared-memory references to avoid unnecessary
copies while keeping ownership with the caller.
* Provider selection is performed during context creation; an operation does
not silently change providers after the context has been created.
* Streaming jobs use an explicit state machine so invalid ordering is rejected
before a provider call is made.

The design is constrained by provider capability differences, PKCS#11 token and
session limits, process-boundary failure modes, and the lifetime of caller-owned
buffers. Applications must handle unavailable providers and unsupported
algorithms explicitly. Algorithms with variable output or provider-specific
parameters require an API-level contract before they can be exposed portably.

Requirements
------------

The requirements for the feature architecture are defined in the `requirements` section of the feature documentation in the project repository.
Component requirements and assumptions of use are maintained with the Crypto
component documentation. Feature-level ownership and cross-repository consumer
migration for the Baselibs hash transition remain tracked by
`inc_security_crypto issue #125 <https://github.com/eclipse-score/inc_security_crypto/issues/125>`_.
The consumer migration and removal of Baselibs algorithms are deliberately not
claimed by this repository's component requirements.

Rationale Behind Architecture Decomposition
*******************************************

Mandatory: A motivation for the decomposition

.. note:: Common decisions across features / cross cutting concepts is at the high level.
The process boundary isolates applications from provider initialization,
credentials, sessions, and provider-specific failure handling. Separating the
control and data planes permits small requests to remain simple while large data
can use shared memory. A common handler contract lets OpenSSL serve development
and software deployments while PKCS#11 connects the same API to hardware-backed
implementations. Keeping key and operation resources in the daemon also reduces
the amount of provider-specific state exposed to clients.

Static Architecture
-------------------

<The static architecture of the feature can be described here. It includes the feature architecture diagrams and some descriptions.>

.. note::
The Architecture can be split into multiple files, it is an high level architecture design
which can be shown without actual c++/rust interfaces and data types
and there will be link to internal architecture till code to get actual api descriptions.

.. code-block:: rst

.. feat_arc_sta:: Feature Static View
:id: feat_arc_sta__feature_name__static_view
:security: YES
:safety: ASIL_B
:status: invalid
:fulfils: feat_req__feature_name__some_title
:includes: logic_arc_int__feature_name__interface_name1
:belongs_to: feat__feature_name

.. needarch::
:scale: 50
:align: center

{{ draw_feature(need(), needs) }}
The principal static dependencies are:

.. code-block:: text

Application
|
v
Crypto C++ API -- Control plane client -- IPC -- Crypto daemon
| |
+-- Buffer/SHM data plane -------------+
|
v
Provider manager
/ \
v v
OpenSSL provider PKCS#11 provider
|
v
Token / HSM / TEE

Detailed component, interface, data-plane, provider, and key-management views
are available in the ``score/crypto/docs/architecture`` documentation.

Dynamic Architecture
--------------------

<The dynamic architecture of the feature can be described here. That can include sequence diagrams, state machines, and other dynamic views of the feature.>

.. code-block:: rst

.. feat_arc_dyn:: Dynamic View
:id: feat_arc_dyn__feature_name__dynamic_view
:security: YES
:safety: ASIL_B
:status: invalid
:fulfils: feat_req__feature_name__some_title
:belongs_to: feat__feature_name

Put here a sequence diagram
A typical operation follows this sequence:

#. The application creates a stack and connects to the configured daemon
endpoint.
#. It creates a crypto context and requests a typed operation context with an
algorithm and optional provider selection.
#. The daemon resolves and validates the provider, creates a handler, and
returns an opaque context identifier.
#. Each operation request carries control metadata and either in-band data or
validated shared-memory references.
#. The handler validates the operation state and dispatches to the selected
provider.
#. The daemon returns a status and output length; output bytes are written to
the caller-owned buffer.
#. Reset returns a reusable operation context to its idle state, while context
destruction releases daemon and provider resources.

For hashing, valid flows are ``SingleShot`` or ``Init`` followed by zero or more
``Update`` calls and ``Finalize``. A retryable validation error such as an
undersized final output buffer does not consume the active stream.

Logical Interfaces
------------------

The logical interfaces of the feature are defined in the `logical interfaces` section of the feature documentation in the project repository.

See `SCORE Features <https://eclipse-score.github.io/score/main/features/index.html>`_ for more information.
The public logical interface is the provider-independent Crypto C++ API. The
client-daemon protocol and provider handler interfaces are internal logical
interfaces and are versioned with the component implementation. Provider-native
APIs, including OpenSSL EVP and PKCS#11 Cryptoki, terminate at their respective
daemon adapters and are not exposed to applications.

Used Components
---------------

The components used by the feature are defined in the `components` section of the module documentation.

See :ref:`component_template` for an example component.
The feature is currently realized by the ``Crypto`` component
(``comp__crypto``). External consumers and the eventual Baselibs cleanup are
separate repository changes and are outside this component's implementation
boundary.
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@

The example source files are only kept for reference.
For an actual executable or sample application refer to the tests/integration_tests folder.

The hashing example uses the canonical, case-sensitive API identifier `SHA256`.
The corresponding standard algorithm name is SHA-256. The other migration-target
identifiers are `SHA384` and `SHA512`; hyphenated API aliases are not currently supported.
Loading
Loading