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
6 changes: 6 additions & 0 deletions wolfcrypt/src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/xilinx/xil-aesgcm.c \
wolfcrypt/src/port/xilinx/xil-versal-glue.c \
wolfcrypt/src/port/xilinx/xil-versal-trng.c \
wolfcrypt/src/port/xilinx/versal_gen2_asu/README.md \
wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_cryptocb.c \
wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_hash.c \
wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_hmac.c \
wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_rng.c \
wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_util.c \
wolfcrypt/src/port/caam/caam_aes.c \
wolfcrypt/src/port/caam/caam_driver.c \
wolfcrypt/src/port/caam/caam_error.c \
Expand Down
99 changes: 99 additions & 0 deletions wolfcrypt/src/port/xilinx/versal_gen2_asu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# wolfSSL AMD Versal Gen2 ASU Port

This port offloads wolfCrypt operations to the AMD Versal Gen2 **ASU**
(Application Security Unit) hardware crypto engine. It is built as part of an
AMD Vitis / SDT baremetal application (compiled with a `user_settings.h`, not
with `./configure`), and drives the ASU through AMD's `xilasu` client library.

Offload is wired through the wolfSSL crypto callback framework
(`WOLF_CRYPTO_CB`): the port registers a device callback during
`wolfCrypt_Init()`, and any operation the ASU does not support returns
`CRYPTOCB_UNAVAILABLE` so wolfCrypt transparently falls back to its software
implementation. Because everything routes through the callback, the unmodified
`wolfcrypt` test and benchmark exercise the hardware simply by using the ASU
device id.

## Supported operations

This initial contribution offloads:

- **TRNG**: hardware entropy. It seeds the wolfSSL Hash-DRBG
(`wc_GenerateSeed`). Because the ASU device id is used for RNG as well, it also
serves `wc_RNG_GenerateBlock` requests directly from the TRNG (raw hardware
entropy, not conditioned through the DRBG).
- **Hashing**: SHA-2 (SHA-256, SHA-384, SHA-512) and SHA-3 (SHA3-256,
SHA3-384, SHA3-512).
- **HMAC**: over the supported SHA-2 and SHA-3 digests.

Digests and variants the ASU does not implement (for example SHA-1, SHA-224,
and the truncated SHA-512/224 and SHA-512/256) automatically fall back to
software via the crypto callback.

## Enabling the port

Define `WOLFSSL_VERSAL_GEN2_ASU` in your `user_settings.h`. With only that
defined, every supported engine is offloaded. To offload a subset, additionally
define one or more of the engine macros (an engine macro on its own does **not**
enable the port):

| Macro | Engine |
|-------|--------|
| `WOLFSSL_VERSAL_GEN2_ASU_TRNG` | Hardware TRNG (RNG seed source) |
| `WOLFSSL_VERSAL_GEN2_ASU_HASH` | SHA-2 / SHA-3 hashing |
| `WOLFSSL_VERSAL_GEN2_ASU_HMAC` | HMAC |
| `WOLFSSL_VERSAL_GEN2_ASU_CIPHER` | AES ciphers |
| `WOLFSSL_VERSAL_GEN2_ASU_CMAC` | CMAC |
| `WOLFSSL_VERSAL_GEN2_ASU_RSA` | RSA |
| `WOLFSSL_VERSAL_GEN2_ASU_ECC` | ECC |

The crypto callback device id defaults to `0x4153` (`'AS'`); override it by
defining `WOLFSSL_VERSAL_GEN2_ASU_DEVID` (or `WC_USE_DEVID`) before
`settings.h`. See `asu_settings.h` for the full set of compile-time options,
including the RTC/timer hook (`WOLFSSL_VERSAL_GEN2_ASU_RTC`) and the data-cache
switch (`XASU_DISABLE_CACHE`); the diagnostic-trace switch
(`WOLFSSL_VERSAL_GEN2_ASU_DEBUG`) is documented in `asu_util.h`.

## Hash / HMAC update strategy (buffered vs streaming)

The ASU SHA core keeps its running hash state only inside the hardware and cannot
save or restore it, and it holds one in-progress hash at a time. How the port
handles multi-call `update()...final()` is a build-time choice; all streaming
macros are off by default (the buffered path).

| Mode | Macros | `update()` | `copy()` / `GetHash()` | Peak memory |
|------|--------|-----------|------------------------|-------------|
| Buffered (default) | none | accumulate the whole message per context, one ASU op at `final()` | deep-copy the buffered message | O(message) |
| Streaming | `WOLFSSL_VERSAL_GEN2_ASU_STREAMING` | fed straight to the ASU (START/UPDATE ... UPDATE/FINISH) | **rejected** (an in-progress hardware hash cannot be duplicated) | O(1) |
| Streaming + keep | `..._STREAMING` and `..._STREAMING_HASH_KEEP` | streamed **and** retained | rebuilt as a software context and replayed | O(message) |

Notes:

- Buffered is interleave-safe: each context keeps its own message buffer, so any
number of hashes can be in flight at once. It is the general-purpose default.
- `STREAMING` is the memory-saving mode (e.g. a bootloader hashing a large
image). Because the digest registers are read-only until FINISH, `copy()` and
`GetHash()` on a started hash are refused rather than silently corrupted, and
SHAKE (which may need a software fallback) is declined.
- `STREAMING_HASH_KEEP` restores `copy()`/`GetHash()` by replaying the retained
message into a software context (HMAC re-keys and replays one level up), at the
buffered path's memory footprint.
- **One hardware stream per priority:** in the streaming modes only one ASU hash
stream can be open at a time, so two independently created streamed contexts
cannot run concurrently. Builds that run the stock wolfCrypt hash KATs in a
streaming mode should define `NO_WOLFSSL_SHA256_INTERLEAVE` and
`NO_WOLFSSL_SHA512_INTERLEAVE` (those KATs drive a second concurrent context).

## Files

| File | Purpose |
|------|---------|
| `asu_settings.h` | Compile-time engine selection and device id (included by `settings.h`) |
| `asu_cryptocb.*` | Crypto callback registration and operation dispatch |
| `asu_rng.*` | TRNG seed source |
| `asu_hash.*` | SHA-2 / SHA-3 hashing |
| `asu_hmac.*` | HMAC |
| `asu_util.*` | Shared helpers (request submission, cache maintenance) |

## Support

For questions please email support@wolfssl.com
160 changes: 160 additions & 0 deletions wolfcrypt/src/port/xilinx/versal_gen2_asu/asu_cryptocb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* asu_cryptocb.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <wolfssl/wolfcrypt/settings.h>

#ifdef WOLFSSL_VERSAL_GEN2_ASU

#include <wolfssl/wolfcrypt/port/xilinx/versal_gen2_asu/asu_cryptocb.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>

#ifdef WOLFSSL_VERSAL_GEN2_ASU_TRNG
#include <wolfssl/wolfcrypt/port/xilinx/versal_gen2_asu/asu_rng.h>
#endif
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HASH
#include <wolfssl/wolfcrypt/port/xilinx/versal_gen2_asu/asu_hash.h>
#endif
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HMAC
#include <wolfssl/wolfcrypt/port/xilinx/versal_gen2_asu/asu_hmac.h>
#endif

#ifndef WOLF_CRYPTO_CB
#error "WOLFSSL_VERSAL_GEN2_ASU requires WOLF_CRYPTO_CB"
#endif

/* Route a context copy (WC_ALGO_TYPE_COPY) to the engine that owns the object,
* keyed on the copy sub-algo. HMAC has no case: wc_HmacCopy deep-copies its inner
* hashes, which routes the copy through WC_ALGO_TYPE_HASH below. */
static int wc_AsuCopy(wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

if (info == NULL) {
return BAD_FUNC_ARG;
}

switch (info->copy.algo) {
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HASH
case WC_ALGO_TYPE_HASH:
ret = wc_AsuHash(info);
break;
#endif
default:
break;
}

return ret;
}

/* Route a context free (WC_ALGO_TYPE_FREE) to the engine that owns the object,
* keyed on the free sub-algo, the same way as wc_AsuCopy. */
static int wc_AsuFree(wc_CryptoInfo* info)
{
int ret = CRYPTOCB_UNAVAILABLE;

if (info == NULL) {
return BAD_FUNC_ARG;
}

switch (info->free.algo) {
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HASH
case WC_ALGO_TYPE_HASH:
ret = wc_AsuHash(info);
break;
#endif
/* HMAC has no free case: its message buffer lives in the inner hash
* devCtx, so wc_HmacFree's free of that hash rides WC_ALGO_TYPE_HASH above
* (see asu_hmac.c). */
default:
break;
}

return ret;
}

/* Crypto callback dispatcher. Each engine handler runs the full operation
* (looping over ASU transactions as needed) and returns the wolfCrypt result:
* 0 when the ASU handled it, CRYPTOCB_UNAVAILABLE to fall back to software, or a
* negative error. Engine cases are filled in per milestone: M1 hash and rng,
* M2 aes, M3 public key. */
static int wc_AsuCryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
{
int ret = CRYPTOCB_UNAVAILABLE;

(void)devId;
(void)ctx;

if (info == NULL) {
return BAD_FUNC_ARG;
}

switch (info->algo_type) {
case WC_ALGO_TYPE_HASH: /* M1 asu_hash */
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HASH
ret = wc_AsuHash(info);
#endif
break;
case WC_ALGO_TYPE_HMAC: /* M1 asu_hmac */
#ifdef WOLFSSL_VERSAL_GEN2_ASU_HMAC
ret = wc_AsuHmac(info);
#endif
break;
case WC_ALGO_TYPE_SEED: /* M1 asu_rng */
case WC_ALGO_TYPE_RNG: /* M1 asu_rng */
#ifdef WOLFSSL_VERSAL_GEN2_ASU_TRNG
ret = wc_AsuRng(info);
#endif
break;
case WC_ALGO_TYPE_CIPHER: /* M2 asu_aes */
break;
case WC_ALGO_TYPE_CMAC: /* M2 asu_aes */
break;
case WC_ALGO_TYPE_PK: /* M3 asu_rsa and asu_ecc */
break;
case WC_ALGO_TYPE_COPY: /* context copy: route by sub-algo to its engine */
ret = wc_AsuCopy(info);
break;
case WC_ALGO_TYPE_FREE: /* context free: route by sub-algo to its engine */
ret = wc_AsuFree(info);
break;
default:
break;
}

return ret;
}

int wc_AsuCryptoCb_RegisterDevice(int devId)
{
return wc_CryptoCb_RegisterDevice(devId, wc_AsuCryptoDevCb, NULL);
}

void wc_AsuCryptoCb_UnRegisterDevice(int devId)
{
wc_CryptoCb_UnRegisterDevice(devId);
}

#endif /* WOLFSSL_VERSAL_GEN2_ASU */
Loading
Loading