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
8 changes: 8 additions & 0 deletions .github/workflows/mpfs-athena-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ jobs:
extra: '-DWOLFSSL_AES_COUNTER'
- leg: sha384-only
extra: '-DWOLFSSL_SHA512 -DWOLFSSL_SHA384'
# The cipher case is shared by CTR and ECB, so each must build with
# the other gate off.
- leg: aesecb-only
extra: '-DHAVE_AES_ECB'
# The XTS build the ECB path exists for, with a raised minimum so the
# self-test takes its larger-buffer branch.
- leg: aesxts
extra: '-DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DWOLFSSL_AES_COUNTER -DHAVE_AES_ECB -DWOLFSSL_AES_XTS -DWOLFSSL_AES_DIRECT -DWC_MPFS_ATHENA_AES_MIN_SZ=512'
- leg: no-selftest
extra: '-DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DWOLFSSL_AES_COUNTER -DWC_MPFS_ATHENA_NO_SELFTEST'
steps:
Expand Down
8 changes: 8 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -12509,6 +12509,14 @@ then
if test "x$ENABLED_AESCTR" = "xno"; then
AC_MSG_ERROR([--with-mpfs-athena needs AES-CTR; add --enable-aesctr])
fi
# AES-XTS reaches the engine only through the bulk ECB call that
# HAVE_AES_ECB compiles in; without it every XTS block is its own engine
# transaction, slower than software.
if test "x$ENABLED_AESXTS" = "xyes" && test "x$ENABLED_AESECB" = "xno"; then
ENABLED_AESECB=yes
AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_ECB"
AM_CCASFLAGS="$AM_CCASFLAGS -DHAVE_AES_ECB"
fi
fi

if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "$ENABLED_SEC_QORIQ" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_SILABS_CRYPTOCB" != "xno" || test "x$ENABLED_VAULTIC" = "xyes" || test "x$ENABLED_ALTERA_FCS" = "xyes" || test "x$ENABLED_ELE" != "xno" || test "x$ENABLED_MPFS_ATHENA" = "xyes" || test "x$ENABLED_ELS_PKC" = "xyes"
Expand Down
21 changes: 21 additions & 0 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -9991,6 +9991,9 @@ static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE],
XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
#endif
#else
/* The 64-bit word path reads Z at odd offsets, so it needs unaligned loads
* just as the 32-bit one does. */
#ifndef WOLFSSL_USE_ALIGN
byte* Z = ws->b;
byte a;
word64* pZ;
Expand All @@ -10017,6 +10020,24 @@ static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE],
pZ = (word64*)(Z + 1);
pm = (word64*)(m[x[0]]);
px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
#else
byte* Z = ws->b;
byte a;
int i;

XMEMCPY(Z + 16, m[x[15]], WC_AES_BLOCK_SIZE);
a = Z[16 + 15];
Z[15] = R[a][0];
Z[16] ^= R[a][1];
for (i = 14; i > 0; i--) {
xorbuf(Z + i + 1, m[x[i]], WC_AES_BLOCK_SIZE);
a = Z[16 + i];
Z[i] = R[a][0];
Z[i+1] ^= R[a][1];
}
xorbuf(Z + 1, m[x[0]], WC_AES_BLOCK_SIZE);
XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
#endif
#endif
}
#endif
Expand Down
56 changes: 47 additions & 9 deletions wolfcrypt/src/port/microchip/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Microchip PolarFire SoC Athena F5200 (TeraFire)

SHA-384 and AES-256-CTR offload on the Athena F5200 "TeraFire" user
cryptoprocessor, through the wolfCrypt crypto callback.
SHA-384, AES-256-CTR and AES-256-ECB offload on the Athena F5200 "TeraFire"
user cryptoprocessor, through the wolfCrypt crypto callback. The ECB path is
what carries AES-256-XTS.

## Hardware

Expand Down Expand Up @@ -75,9 +76,39 @@ it by turning on `WOLF_CRYPTO_CB`,
stock `wolfcrypt_test()` and `benchmark()` drive the engine with no argument.

Which engines are offloaded follows the ordinary wolfCrypt feature gates rather
than port-specific ones: `WOLFSSL_SHA384` for the hash, and
`WOLFSSL_AES_COUNTER` with `!NO_AES` for AES-256-CTR. AES-128 and AES-192
requests are declined to software, as are all other hash types.
than port-specific ones: `WOLFSSL_SHA384` for the hash, `WOLFSSL_AES_COUNTER`
with `!NO_AES` for AES-256-CTR, and `HAVE_AES_ECB` with `!NO_AES` for
AES-256-ECB. AES-128 and AES-192 requests are declined to software, as are all
other hash types.

### AES-XTS

XTS is AES-ECB over tweak-masked data, and `_AesXtsHelper()` already issues one
bulk `wc_AesEcbEncrypt()`/`wc_AesEcbDecrypt()` per XTS call, which lands on this
port's ECB case. An `XtsAes` tagged with the port's devId is therefore offloaded
with no XTS code here, given:

- `HAVE_AES_ECB` (`--enable-aesecb`; configure adds it for `--with-mpfs-athena`
with `--enable-aesxts`). Without it XTS runs a block at a time through
`wc_AesEncryptDirect()`, slower than software.
- Distinct input and output buffers; the helper is not used in place.
- A 64-byte XTS key (AES-256). AES-128-XTS stays in software.

The tweak encrypt and the stealing tail arrive as single-block calls and stay in
software, as do the GF(2^128) tweak multiply and both XORs. XTS therefore gains
less than bulk CTR, and improves with call size since the engine setup is paid
once per call - measure at the size the application uses.

Stock benchmark, MPFS250TS Video Kit, E51 at 600 MHz, bare metal; the software
column is wolfCrypt's default cache-line-touch-hardened C AES for RISC-V:

| Call size | AES-256-XTS software | AES-256-XTS engine | AES-256-CTR engine | SHA-384 engine |
|---|---|---|---|---|
| 512 B | 48 KiB/s | 1.23 MiB/s | 12.9 MiB/s | 11.4 MiB/s |
| 1 KiB | 49 KiB/s | 2.06 MiB/s | 14.6 MiB/s | 13.2 MiB/s |
| 4 KiB | 49 KiB/s | 4.2 MiB/s | 16.1 MiB/s | 14.8 MiB/s |

Software SHA-384 is 5.8 MiB/s.

## Using it

Expand Down Expand Up @@ -115,6 +146,7 @@ except `WC_MPFS_ATHENA_DEVID`, which `settings.h` sets so it can also drive
|---|---|---|
| `WC_MPFS_ATHENA_DEVID` | `0xA7` | crypto callback device id |
| `WC_MPFS_ATHENA_HASH_SLOTS` | 4 | concurrent offloaded SHA-384 contexts when there is no heap |
| `WC_MPFS_ATHENA_AES_MIN_SZ` | 32 | smallest AES-ECB request the engine serves; self-test needs twice this as scratch |
| `WC_MPFS_ATHENA_BASE_ADDR` | `0x22000000` | user-crypto base, for `g_user_crypto_base_addr` |
| `WC_MPFS_ATHENA_REG_BASE` | `0x20127000` | `ATHENAREG` |
| `WC_MPFS_ATHENA_SYSREG_BASE` | `0x20002000` | MSS SYSREG |
Expand Down Expand Up @@ -146,6 +178,10 @@ None of this is in the CAL headers.
report success.
- **The AES counter is advanced in place**, so consecutive calls on one context
continue the keystream.
- **The engine's CTR counter is 32 bits wide.** It carries nothing past the low
word, where `wc_AesCtrEncrypt()` counts over all 128. The port stops each
transfer at that wrap and recomputes the counter itself; the self-test covers
a stream across it.
- **The DMA entry points do nothing.** `CALHashDMA()` and `aesf5200dma()` are
declared, but the shipped archive is built with `USE_X52EXEC_DMA 0` and they
return success without moving data. The port uses the non-DMA calls.
Expand Down Expand Up @@ -178,7 +214,9 @@ None of this is in the CAL headers.

## Not yet offloaded

The CAL also exposes SHA-1/224/256/512, AES-128/192, AES-GCM/CCM/key-wrap, HMAC,
DRBG/NRBG, ECDSA, ECDH, RSA, DSA and DH. None of those have been run on this
silicon, so they are left in software rather than shipped untested. ECDSA P-384
verify is the one most worth adding next.
The CAL also exposes SHA-1/224/256/512, AES-128/192, AES-CBC/CFB/OFB,
AES-GCM/CCM/key-wrap, HMAC, DRBG/NRBG, ECDSA, ECDH, RSA, DSA and DH. None of
those have been run on this silicon, so they are left in software rather than
shipped untested. ECDSA P-384 verify is the one most worth adding next;
AES-128-ECB (for AES-128-XTS) is a one-line `SATSYMTYPE_AES128` lookup once
wanted.
Loading
Loading