Skip to content

Commit

Permalink
Initial PR for MAX32665 and MAX32666 TPU HW Support
Browse files Browse the repository at this point in the history
  • Loading branch information
msi-debian authored and night1rider committed Jul 25, 2024
1 parent 7c6eb7c commit caee76b
Show file tree
Hide file tree
Showing 15 changed files with 1,479 additions and 17 deletions.
8 changes: 8 additions & 0 deletions wolfcrypt/benchmark/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -14236,6 +14236,14 @@ void bench_sphincsKeySign(byte level, byte optim)
return (double)tv.SECONDS + (double)tv.MILLISECONDS / 1000;
}

#elif (defined(WOLFSSL_MAX3266X_OLD) || defined(WOLFSSL_MAX3266X)) \
&& defined(MAX3266X_RTC)

double current_time(int reset)
{
return wc_MXC_RTC_Time();
}

#elif defined(FREESCALE_KSDK_BM)

double current_time(int reset)
Expand Down
103 changes: 100 additions & 3 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#include <wolfssl/wolfcrypt/port/psa/psa.h>
#endif

#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
#include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
#endif

#if defined(WOLFSSL_TI_CRYPT)
#include <wolfcrypt/src/port/ti/ti-aes.c>
#else
Expand Down Expand Up @@ -2888,6 +2892,15 @@ static WARN_UNUSED_RESULT int wc_AesEncrypt(
}
#endif

#if defined(MAX3266X_AES)
word32 keySize;
if (wc_AesGetKeySize(aes, &keySize) == 0) {
return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
MXC_TPU_MODE_ECB, MXC_AES_DATA_LEN,
outBlock, (unsigned int)keySize);
}
#endif

AesEncrypt_C(aes, inBlock, outBlock, r);

return 0;
Expand Down Expand Up @@ -3611,6 +3624,15 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
} /* else !wc_esp32AesSupportedKeyLen for ESP32 */
#endif

#if defined(MAX3266X_AES)
word32 keySize;
if (wc_AesGetKeySize(aes, &keySize) == 0) {
return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
MXC_TPU_MODE_ECB, MXC_AES_DATA_LEN,
outBlock, (unsigned int)keySize);
}
#endif

AesDecrypt_C(aes, inBlock, outBlock, r);

return 0;
Expand Down Expand Up @@ -4537,13 +4559,12 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
return ret;
}
#endif

XMEMCPY(aes->key, userKey, keylen);

#ifndef WC_AES_BITSLICED
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
(!defined(WOLFSSL_ESP32_CRYPT) || \
defined(NO_WOLFSSL_ESP32_CRYPT_AES))
(!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
&& !defined(MAX3266X_AES)

/* software */
ByteReverseWords(aes->key, aes->key, keylen);
Expand Down Expand Up @@ -5374,6 +5395,82 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
}
#endif /* HAVE_AES_DECRYPT */

#elif defined(MAX3266X_AES)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 keySize;
int status;
byte *iv;

#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
if (sz % AES_BLOCK_SIZE) {
return BAD_LENGTH_E;
}
#endif
if (sz == 0)
return 0;

iv = (byte*)aes->reg;

status = wc_AesGetKeySize(aes, &keySize);
if (status != 0) {
return status;
}

status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
MXC_TPU_MODE_CBC, MXC_AES_DATA_LEN, out,
(unsigned int)keySize);

/* store iv for next call */
if (status == E_SUCCESS) {
XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}

return (status == E_SUCCESS) ? 0 : -1;
}

#ifdef HAVE_AES_DECRYPT
int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 keySize;
int status;
byte *iv;
byte temp_block[AES_BLOCK_SIZE];

#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
if (sz % AES_BLOCK_SIZE) {
return BAD_LENGTH_E;
}
#endif
if (sz == 0)
return 0;

iv = (byte*)aes->reg;

status = wc_AesGetKeySize(aes, &keySize);
if (status != 0) {
return status;
}

/* get IV for next call */
XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);

status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
MXC_TPU_MODE_CBC, MXC_AES_DATA_LEN, out,
keySize);


/* store iv for next call */
if (status == E_SUCCESS) {
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
}

return (status == E_SUCCESS) ? 0 : -1;
}
#endif /* HAVE_AES_DECRYPT */



#elif defined(WOLFSSL_PIC32MZ_CRYPT)

int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
Expand Down
3 changes: 2 additions & 1 deletion wolfcrypt/src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c \
wolfcrypt/src/port/Renesas/README.md \
wolfcrypt/src/port/cypress/psoc6_crypto.c \
wolfcrypt/src/port/liboqs/liboqs.c
wolfcrypt/src/port/liboqs/liboqs.c \
wolfcrypt/src/port/maxim/max3266x.c

$(ASYNC_FILES):
$(AM_V_at)touch $(srcdir)/$@
Expand Down
104 changes: 102 additions & 2 deletions wolfcrypt/src/port/maxim/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,114 @@
wolfSSL using Analog Devices MAXQ1065 or MAX1080
wolfSSL using Analog Devices MAXQ1065, MAX1080, MAX32665 or MAX32666
================================================

## Overview

wolfSSL can be configured to use the MAXQ1065 or MAX1080 cryptographic
controllers. Product datasheets, user guides and other resources can be found at
controllers. wolfSSL can also be configure to utilize the TPU
(crypto accelerator), MAA (math accelerator), and TRNG available on select
MAX32665 and MAX32666 microcontrollers.

Product datasheets, user guides and other resources can be found at
Analog Devices website:

https://www.analog.com

# MAX32665/MAX32666
## Build and Usage

wolfSSL supports the [Maxim SDK](https://github.com/analogdevicesinc/msdk), to
utilize the TPU and MAA located on the devices.

Building is supported by adding `#define WOLFSSL_MAX3266X` to `user_settings.h`.
wolfSSL supports the usage of the older style API Maxim provides with the
`#define WOLFSSL_MAX3266X_OLD` to `user_settings.h`.

When using `WOLFSSL_MAX3266X` or `WOLFSSL_MAX3266X_OLD` you will also need to
add `#define WC_C_DYNAMIC_FALLBACK` and `#define WOLFSSL_SP_MATH_ALL` to
`user_settings.h`.

If you want to be more specific on what hardware acceleration you want to use,
this can be done by adding any combination of these defines:
```
#define MAX3266X_RNG - Allows usage of TRNG device
#define MAX3266X_AES - Allows usage of TPU for AES Acceleration
#define MAX3266X_SHA - Allows usage of TPU for Hash Acceleration
#define MAX3266X_MATH - Allows usage of MAA for MOD based Math Acceleration
```
For this you will still need to use `#define WOLFSSL_MAX3266X` or `#define WOLFSSL_MAX3266X_OLD`. When you use a specific hardware define like
`#define MAX3266X_RNG` this will mean only the TRNG device is being used, and
all other operations will use the default software implementations.

The other prerequisite is that a change needs to be made to the Maxim SDK. This
is to use the MAA Math Accelerator, this change only needs to be made if you are
using `#define WOLFSSL_MAX3266X` or `define WOLFSSL_MAX3266X_OLD` by themselves
or you are specifing `#define MAX3266X_MATH`.

In the SDK you will need to find the underlying function that
`MXC_TPU_MAA_Compute()` from `tpu.h` compute calls in the newer SDK. In the
older SDK this function is called `MAA_Compute()` in `maa.h`. In the underlying
function you will need to change this error check:

```
// Check that we're performing a valid operation
if (clc >= 0x6) {
return E_INVALID;
}
```
to
```
// Check that we're performing a valid operation
if (clc >= 0b1111) {
return E_INVALID;
}
```

This bug has been reported to Analog Devices
[here](https://github.com/analogdevicesinc/msdk/issues/1089)
if you want to know more details on the issue.


## Supported Algos
Using these defines will replace software implentations with a call to the
hardware.

`#define MAX3266X_RNG`
- Uses entropy from TRNG to seed HASHDRBG

`#define MAX3266X_AES`:

- AES-CBC: 128, 192, 256
- AES-ECB: 128, 192, 256

`#define MAX3266X_SHA`:

- SHA-256

`#define MAX3266X_MATH` (Replaces math operation calls for algos
like RSA and ECC key generation):

- mod - `a mod m = r`
- addmod - `(a+b)mod m = r`
- submod - `(a-b)mod m = r`
- mulmod - `(a*b)mod m = r`
- sqrmod - `(b^2)mod m = r`
- exptmod - `(b^e)mod m = r`

## Extra Information
For more Verbose info you can use `#define DEBUG_WOLFSSL` in combination with
`#define MAX3266X_VERBOSE` to see if errors are occuring during the hardware
setup/

To reproduce benchmark numbers you can use `#define MAX3266X_RTC`.
Do note that this will only work with `#define WOLFSSL_MAX3266X` and not
`#define WOLFSSL_MAX3266X_OLD`. This is only meant for benchmark reproduction
and not for any other application. Please implement your own rtc/time code for
anything else.

For more infromation about the TPU, MAA, and TRNG please refer to the
[MAX32665/MAX32666 User Guide: UG6971](https://www.analog.com/media/en/technical-documentation/user-guides/max32665max32666-user-guide.pdf)

# MAXQ1065/MAX1080
## Build and Usage

Please use the appropriate SDK or Evkit to build wolfSSL.
Expand Down
Loading

0 comments on commit caee76b

Please sign in to comment.