Skip to content

[crypto] Manual backport from eg100 to master#30284

Merged
nasahlpa merged 28 commits into
lowRISC:masterfrom
nasahlpa:backport_cl_prs_7
Jun 8, 2026
Merged

[crypto] Manual backport from eg100 to master#30284
nasahlpa merged 28 commits into
lowRISC:masterfrom
nasahlpa:backport_cl_prs_7

Conversation

@nasahlpa

@nasahlpa nasahlpa commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

nasahlpa and others added 24 commits June 4, 2026 07:19
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 1fbc38d)
This firmware receives the public and private key and creates the
shared secret. The firmware automatically blinds and unblinds the
secrets.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 588f296)
For valid test vectors, the CL needs to return the correct shared secret.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 567855c)
…check

This commit allows to build libotcrypto as a position-independent, relocatable
binary blob. This enables FIPS-compliant runtime self-integrity checking while
allowing applications to link to the cryptolib without requiring jump tables or
custom ELF header parsing.

Key additions:

Build: Added a Bazel rule (opentitan_binary_blob) and configuration flags to
easily toggle between standard static builds (crypto_dev) and the standalone
FIPS module (crypto_fips_all), other configurations can be added later.

Linker scripts: Added static and partial linker scripts (otcrypto_blob.ld,
otcrypto_partial.ld) to pack the cryptolib into a contiguous memory block and
expose the start, end, and hash symbols.

Self-integrity check: Implemented runtime self-hashing in self_integrity.c to
verify the module's own code region. Extended otcrypto_hash_test to validate
the new mechanism.

What is not in:

Currently, the new compilation (--config=crypto_fips_all) can not yet be
guaranteed to work for every crypto test and integration will follow up.
However, the regular static rule still applies to all CI tests.

With thanks to elievap@google.com, yhdeng@google.com,
cfrantz@google.com, and amaury.pouly@lowrisc.org

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit bb40700)
Resolved three distinct issues preventing the generation of a
relocatable cryptolib:

1. OTBN Addressing: Replaced `OTBN_ADDR_T_INIT` with inline
   assembly to force absolute loads.
   - Root Cause: Under `-mcmodel=medany`, C assumes external symbols
     are relocatable and emits PC-relative `auipc` instructions. Because
     OTBN coprocessor addresses are fixed MMIO locations, shifting the
     `.text` origin stretches the distance, forcing the linker to alter
     the instruction bytes. The inline assembly forces an absolute load,
     bypassing PC-relative relocation entirely.

2. Data Pointers: Moved global `static const` configuration strings
   (e.g., in kmac.c) to local block scope.
   - Root Cause: File-scope constant arrays are allocated in the `.rodata`
     section, forcing the compiler to generate pointers (and subsequent
     linker relocations) to pass them to functions like `memcpy`. By
     moving them to block scope as automatic variables, the compiler
     synthesizes the data dynamically on the stack using immediate
     instructions (e.g., `li`), completely eliminating `.rodata` pointer
     dependencies.

3. Jump Tables: Applied `-fno-jump-tables` to cryptolib driver BUILD targets.
   - Root Cause: To optimize execution, GCC heuristically lowers dense
     `switch` statements (e.g., in `kmac.c` and `entropy.c`) into anonymous
     jump tables stored in `.rodata`, populated with absolute `.text`
     function pointers. Because PIC lacks a dynamic linker to
     fix up these pointers at runtime, binary relocation fatally breaks
     them. Injecting `-fno-jump-tables` via shared `PIC_COPTS` forces
     the compiler to emit inherently position-independent relative branches
     (`beq`, `bne`).

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 5276207)
Add a Python test that receives the binary blob and a shifted version of
the binary blob (shifted in memory). It verifies both elf files to find
differences in the addresses of symbols. If it finds those, it means the
blob is not position independent (PIC) and gives back the symbols which
are absolute.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 9aea48e)
Verify the output buffers of otcrypto calls using the OTCRYPTO_CHECK_BUF
macro.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 5c6bfdc)
Use the HARDENED_TRY call from status instead of TRY to use the hardened
control flow integrity from the pentest framework.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 68c85d2)
Add a magic value that indicates whether the called pentest function
executed correctly in the json output structure. This is mainly a
countermeasure against fault attacks.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit edeafc9)
We had x25519 point mult calling the pentest ecdh in order to simulate
the point multiplication. Instead, call the cryptolibrary ecdh directly
and write out the point multiplication.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 0620020)
Add markers for GDB tests to hook to for fault simulation testing.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 7c4859e)
Add two functions to detect partial collisions and to detect if an
output is mainly consistsing of zeros. Use those functions to detect
whether an instruction skip is effective.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 92a8256)
Add an instruction skip routine for p384 sign.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit ca6fc9f)
Add an instruction skip routine for cmac.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit a0f6f56)
To save some code size, return directly from the clean static function.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 75db591)
Add a laundered OTCRYPTO_OK status and use it on "leaf nodes".
These are nodes that can only return OTCRYPTO_OK as a
status_t (specifically, the function should not call a HARDENED_TRY to
another function).
Concerning control flow integrity the compiler will circumvent the
status call if this is not used in such functions.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 4096961)
The check-hardened-comparison.py tool (upcoming in master at the time of
writing) found several code patterns which indicate compiler
optimizations such as beq a0, a0. Address those findings in the
cryptolib.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 617c6d5)
Previously, we simply set the shared secret to 0 but did not notify the
caller that this check failed. Now, instead, report the error back to the
C code.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit f992a5c)
Mark them as invalid and check if our CL also responses with an error.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 3801cd8)
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit acbc8ef)
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 154cfaf)
This enables us to add more new command handlers in the future.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 600d24c)
The new handler:
- Receives the public key from the host
- Computes an own public and private key
- Derives the shared secret using its own private key and the
  hosts public key
- Returns the own public key and the shared secret

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 211b362)
This harness reads the ACVP HJSON file, sends the test vector
to the device and writes the response into a JSON file that can
be submitted to the ACVP server for validation.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
(cherry picked from commit 81739c5)
@nasahlpa nasahlpa force-pushed the backport_cl_prs_7 branch from d6fa7a3 to cddef2d Compare June 4, 2026 05:19
The earlgrey_1.0.0 and master implementation of SpiConsoleDevice
are different in terms of function arguments. Fix the usage of
this function that was cherry-picked from eg100 to master.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
@nasahlpa nasahlpa force-pushed the backport_cl_prs_7 branch 3 times, most recently from f004818 to 6f7ec36 Compare June 4, 2026 08:42
@nasahlpa nasahlpa marked this pull request as ready for review June 4, 2026 10:50
@nasahlpa nasahlpa requested review from a team and cfrantz as code owners June 4, 2026 10:50
@nasahlpa nasahlpa requested review from a team, alees24, andrea-caforio, siemen11 and timothytrippel and removed request for a team, alees24, cfrantz and timothytrippel June 4, 2026 10:50
Comment thread sw/device/lib/base/BUILD Outdated
The master branch automatically computes a module ID if none is
provided. Currently, X25519 does not have one, creating a conflicting
module ID. Hence, manually assign one to resolve the conflict.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
@nasahlpa nasahlpa force-pushed the backport_cl_prs_7 branch from 6f7ec36 to d835212 Compare June 8, 2026 06:14
Create a new Bazel target to run tests (including opentitan_tests) with
the configs defined in //sw/device/lib/crypto/configs, i.e., to run a
test with the --config=crypto_fips_all flag.
This puts the new binary blob and self-tests in CI.

Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
(cherry picked from commit 9d242b5)
@nasahlpa nasahlpa force-pushed the backport_cl_prs_7 branch from d835212 to f665061 Compare June 8, 2026 07:09
Do not build this in CI as it fails. The reason is that we should only
compile this target when adding the --config=crypto_fips_all flag, which
does not happen in the CI job.

Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
@nasahlpa nasahlpa force-pushed the backport_cl_prs_7 branch from 64cc8f1 to e99e090 Compare June 8, 2026 12:10

@siemen11 siemen11 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for all the work Pascal!

@andrea-caforio andrea-caforio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @nasahlpa.

@nasahlpa

nasahlpa commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Merging as the failing DV tests are unrelated.

@nasahlpa nasahlpa added this pull request to the merge queue Jun 8, 2026
Merged via the queue into lowRISC:master with commit d730ff6 Jun 8, 2026
42 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants