diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml b/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml
deleted file mode 100644
index 562fdb70f..000000000
--- a/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/README.md b/IDE/ROWLEY-CROSSWORKS-ARM/README.md
index 9fa89a27b..dc0b032b2 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/README.md
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/README.md
@@ -27,12 +27,23 @@ Also the "Target Processor" in each of the projects ("Project Properties" -> "Ta
## Hardware Crypto Acceleration
-To enable Freescale MMCAU:
+To enable NXP/Freescale MMCAU:
1. [Download the MMCAU library](http://www.freescale.com/products/arm-processors/kinetis-cortex-m/k-series/k7x-glcd-mcus/crypto-acceleration-unit-cau-and-mmcau-software-library:CAUAP).
2. Copy the `lib_mmcau.a` and `cau_api.h` files into the project.
-3. Enable the `FREESCALE_MMCAU` define in `user_settings.h` and make sure its value is `1`.
+3. Define `USE_NXP_MMCAU` to enable in `user_settings.h`.
4. Add the `lib_mmcau.a` file to `Source Files` in the application project.
+5. Open the wolfssl_ltc.hzp CrossWorks project
+6. Build and run
+
+To enable the NXP/Freescale MMCAU and/or LTC:
+
+1. [Download the NXP KSDK 2.0](https://nxp.flexnetoperations.com/control/frse/download?agree=Accept&element=7353807)
+2. Copy the following folders into IDE/ROWLEY-CROSSWORKS-ARM: drivers, mmcau_2.0.0 and CMSIS.
+3. Copy the following files into IDE/ROWLEY-CROSSWORKS-ARM: clock_config.c, clock_config.h, fsl_debug_console.c, fsl_debug_console.h, fsl_device_registers.h, system_MK82F25615.c, system_MK82F25615.h, MK82F25615.h and MK82F25615_features.h.
+4. Define `USE_NXP_LTX` to enable in `user_settings.h`.
+5. Open the wolfssl_ltc.hzp CrossWorks project
+6. Build and run
# Project Files
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c
index 358c0f2d7..28cdce3ea 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c
@@ -84,6 +84,8 @@ void reset_handler(void)
// Vector Exception/Interrupt Handlers
static void Default_Handler(void)
{
+ /* If we get here then need to implement real IRQ handler */
+ while(1);
}
void HardFault_HandlerC( uint32_t *hardfault_args )
@@ -93,48 +95,48 @@ void HardFault_HandlerC( uint32_t *hardfault_args )
values of the variables, make them global my moving their declaration outside
of this function. */
volatile uint32_t stacked_r0;
- volatile uint32_t stacked_r1;
- volatile uint32_t stacked_r2;
- volatile uint32_t stacked_r3;
- volatile uint32_t stacked_r12;
- volatile uint32_t stacked_lr;
+ volatile uint32_t stacked_r1;
+ volatile uint32_t stacked_r2;
+ volatile uint32_t stacked_r3;
+ volatile uint32_t stacked_r12;
+ volatile uint32_t stacked_lr;
volatile uint32_t stacked_pc;
- volatile uint32_t stacked_psr;
- volatile uint32_t _CFSR;
- volatile uint32_t _HFSR;
- volatile uint32_t _DFSR;
- volatile uint32_t _AFSR;
- volatile uint32_t _BFAR;
- volatile uint32_t _MMAR;
+ volatile uint32_t stacked_psr;
+ volatile uint32_t _CFSR;
+ volatile uint32_t _HFSR;
+ volatile uint32_t _DFSR;
+ volatile uint32_t _AFSR;
+ volatile uint32_t _BFAR;
+ volatile uint32_t _MMAR;
- stacked_r0 = ((uint32_t)hardfault_args[0]);
- stacked_r1 = ((uint32_t)hardfault_args[1]);
- stacked_r2 = ((uint32_t)hardfault_args[2]);
- stacked_r3 = ((uint32_t)hardfault_args[3]);
- stacked_r12 = ((uint32_t)hardfault_args[4]);
- stacked_lr = ((uint32_t)hardfault_args[5]);
- stacked_pc = ((uint32_t)hardfault_args[6]);
- stacked_psr = ((uint32_t)hardfault_args[7]);
+ stacked_r0 = ((uint32_t)hardfault_args[0]);
+ stacked_r1 = ((uint32_t)hardfault_args[1]);
+ stacked_r2 = ((uint32_t)hardfault_args[2]);
+ stacked_r3 = ((uint32_t)hardfault_args[3]);
+ stacked_r12 = ((uint32_t)hardfault_args[4]);
+ stacked_lr = ((uint32_t)hardfault_args[5]);
+ stacked_pc = ((uint32_t)hardfault_args[6]);
+ stacked_psr = ((uint32_t)hardfault_args[7]);
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
- _CFSR = (*((volatile uint32_t *)(0xE000ED28)));
-
- // Hard Fault Status Register
- _HFSR = (*((volatile uint32_t *)(0xE000ED2C)));
+ _CFSR = (*((volatile uint32_t *)(0xE000ED28)));
+
+ // Hard Fault Status Register
+ _HFSR = (*((volatile uint32_t *)(0xE000ED2C)));
- // Debug Fault Status Register
- _DFSR = (*((volatile uint32_t *)(0xE000ED30)));
+ // Debug Fault Status Register
+ _DFSR = (*((volatile uint32_t *)(0xE000ED30)));
- // Auxiliary Fault Status Register
- _AFSR = (*((volatile uint32_t *)(0xE000ED3C)));
+ // Auxiliary Fault Status Register
+ _AFSR = (*((volatile uint32_t *)(0xE000ED3C)));
- // Read the Fault Address Registers. These may not contain valid values.
- // Check BFARVALID/MMARVALID to see if they are valid values
- // MemManage Fault Address Register
- _MMAR = (*((volatile uint32_t *)(0xE000ED34)));
- // Bus Fault Address Register
- _BFAR = (*((volatile uint32_t *)(0xE000ED38)));
+ // Read the Fault Address Registers. These may not contain valid values.
+ // Check BFARVALID/MMARVALID to see if they are valid values
+ // MemManage Fault Address Register
+ _MMAR = (*((volatile uint32_t *)(0xE000ED34)));
+ // Bus Fault Address Register
+ _BFAR = (*((volatile uint32_t *)(0xE000ED38)));
printf ("\n\nHard fault handler (all numbers in hex):\n");
printf ("R0 = %x\n", stacked_r0);
@@ -195,5 +197,114 @@ const vector_entry vectors[] __attribute__ ((section(".vectors"),used)) =
Default_Handler, // 0x0000_0038 14 - ARM core Pendable request for system service (PendableSrvReq)
Default_Handler, // 0x0000_003C 15 - ARM core System tick timer (SysTick)
+#ifdef CPU_MK82FN256VLL15
// Add specific driver interrupt handlers below
+ Default_Handler, /* DMA0_DMA16_IRQn = 0, /**< DMA channel 0,16 transfer complete */
+ Default_Handler, /* DMA1_DMA17_IRQn = 1, /**< DMA channel 1,17 transfer complete */
+ Default_Handler, /* DMA2_DMA18_IRQn = 2, /**< DMA channel 2,18 transfer complete */
+ Default_Handler, /* DMA3_DMA19_IRQn = 3, /**< DMA channel 3,19 transfer complete */
+ Default_Handler, /* DMA4_DMA20_IRQn = 4, /**< DMA channel 4,20 transfer complete */
+ Default_Handler, /* DMA5_DMA21_IRQn = 5, /**< DMA channel 5,21 transfer complete */
+ Default_Handler, /* DMA6_DMA22_IRQn = 6, /**< DMA channel 6,22 transfer complete */
+ Default_Handler, /* DMA7_DMA23_IRQn = 7, /**< DMA channel 7,23 transfer complete */
+ Default_Handler, /* DMA8_DMA24_IRQn = 8, /**< DMA channel 8,24 transfer complete */
+ Default_Handler, /* DMA9_DMA25_IRQn = 9, /**< DMA channel 9,25 transfer complete */
+ Default_Handler, /* DMA10_DMA26_IRQn = 10, /**< DMA channel 10,26 transfer complete */
+ Default_Handler, /* DMA11_DMA27_IRQn = 11, /**< DMA channel 11,27 transfer complete */
+ Default_Handler, /* DMA12_DMA28_IRQn = 12, /**< DMA channel 12,28 transfer complete */
+ Default_Handler, /* DMA13_DMA29_IRQn = 13, /**< DMA channel 13,29 transfer complete */
+ Default_Handler, /* DMA14_DMA30_IRQn = 14, /**< DMA channel 14,30 transfer complete */
+ Default_Handler, /* DMA15_DMA31_IRQn = 15, /**< DMA channel 15,31 transfer complete */
+ Default_Handler, /* DMA_Error_IRQn = 16, /**< DMA channel 0 - 31 error */
+ Default_Handler, /* MCM_IRQn = 17, /**< MCM normal interrupt */
+ Default_Handler, /* FTFA_IRQn = 18, /**< FTFA command complete */
+ Default_Handler, /* Read_Collision_IRQn = 19, /**< FTFA read collision */
+ Default_Handler, /* LVD_LVW_IRQn = 20, /**< PMC controller low-voltage detect, low-voltage warning */
+ Default_Handler, /* LLWU_IRQn = 21, /**< Low leakage wakeup unit */
+ Default_Handler, /* WDOG_EWM_IRQn = 22, /**< Single interrupt vector for WDOG and EWM */
+ Default_Handler, /* TRNG0_IRQn = 23, /**< True randon number generator */
+ Default_Handler, /* I2C0_IRQn = 24, /**< Inter-integrated circuit 0 */
+ Default_Handler, /* I2C1_IRQn = 25, /**< Inter-integrated circuit 1 */
+ Default_Handler, /* SPI0_IRQn = 26, /**< Serial peripheral Interface 0 */
+ Default_Handler, /* SPI1_IRQn = 27, /**< Serial peripheral Interface 1 */
+ Default_Handler, /* I2S0_Tx_IRQn = 28, /**< Integrated interchip sound 0 transmit interrupt */
+ Default_Handler, /* I2S0_Rx_IRQn = 29, /**< Integrated interchip sound 0 receive interrupt */
+ Default_Handler, /* LPUART0_IRQn = 30, /**< LPUART0 receive/transmit/error interrupt */
+ Default_Handler, /* LPUART1_IRQn = 31, /**< LPUART1 receive/transmit/error interrupt */
+ Default_Handler, /* LPUART2_IRQn = 32, /**< LPUART2 receive/transmit/error interrupt */
+ Default_Handler, /* LPUART3_IRQn = 33, /**< LPUART3 receive/transmit/error interrupt */
+ Default_Handler, /* LPUART4_IRQn = 34, /**< LPUART4 receive/transmit/error interrupt */
+ Default_Handler, /* Reserved51_IRQn = 35, /**< Reserved interrupt */
+ Default_Handler, /* Reserved52_IRQn = 36, /**< Reserved interrupt */
+ Default_Handler, /* EMVSIM0_IRQn = 37, /**< EMVSIM0 common interrupt */
+ Default_Handler, /* EMVSIM1_IRQn = 38, /**< EMVSIM1 common interrupt */
+ Default_Handler, /* ADC0_IRQn = 39, /**< Analog-to-digital converter 0 */
+ Default_Handler, /* CMP0_IRQn = 40, /**< Comparator 0 */
+ Default_Handler, /* CMP1_IRQn = 41, /**< Comparator 1 */
+ Default_Handler, /* FTM0_IRQn = 42, /**< FlexTimer module 0 fault, overflow and channels interrupt */
+ Default_Handler, /* FTM1_IRQn = 43, /**< FlexTimer module 1 fault, overflow and channels interrupt */
+ Default_Handler, /* FTM2_IRQn = 44, /**< FlexTimer module 2 fault, overflow and channels interrupt */
+ Default_Handler, /* CMT_IRQn = 45, /**< Carrier modulator transmitter */
+ Default_Handler, /* RTC_IRQn = 46, /**< Real time clock */
+ Default_Handler, /* RTC_Seconds_IRQn = 47, /**< Real time clock seconds */
+ Default_Handler, /* PIT0CH0_IRQn = 48, /**< Periodic interrupt timer 0 channel 0 */
+ Default_Handler, /* PIT0CH1_IRQn = 49, /**< Periodic interrupt timer 0 channel 1 */
+ Default_Handler, /* PIT0CH2_IRQn = 50, /**< Periodic interrupt timer 0 channel 2 */
+ Default_Handler, /* PIT0CH3_IRQn = 51, /**< Periodic interrupt timer 0 channel 3 */
+ Default_Handler, /* PDB0_IRQn = 52, /**< Programmable delay block */
+ Default_Handler, /* USB0_IRQn = 53, /**< USB OTG interrupt */
+ Default_Handler, /* USBDCD_IRQn = 54, /**< USB charger detect */
+ Default_Handler, /* Reserved71_IRQn = 55, /**< Reserved interrupt */
+ Default_Handler, /* DAC0_IRQn = 56, /**< Digital-to-analog converter 0 */
+ Default_Handler, /* MCG_IRQn = 57, /**< Multipurpose clock generator */
+ Default_Handler, /* LPTMR0_LPTMR1_IRQn = 58, /**< Single interrupt vector for Low Power Timer 0 and 1 */
+ Default_Handler, /* PORTA_IRQn = 59, /**< Port A pin detect interrupt */
+ Default_Handler, /* PORTB_IRQn = 60, /**< Port B pin detect interrupt */
+ Default_Handler, /* PORTC_IRQn = 61, /**< Port C pin detect interrupt */
+ Default_Handler, /* PORTD_IRQn = 62, /**< Port D pin detect interrupt */
+ Default_Handler, /* PORTE_IRQn = 63, /**< Port E pin detect interrupt */
+ Default_Handler, /* SWI_IRQn = 64, /**< Software interrupt */
+ Default_Handler, /* SPI2_IRQn = 65, /**< Serial peripheral Interface 2 */
+ Default_Handler, /* Reserved82_IRQn = 66, /**< Reserved interrupt */
+ Default_Handler, /* Reserved83_IRQn = 67, /**< Reserved interrupt */
+ Default_Handler, /* Reserved84_IRQn = 68, /**< Reserved interrupt */
+ Default_Handler, /* Reserved85_IRQn = 69, /**< Reserved interrupt */
+ Default_Handler, /* FLEXIO0_IRQn = 70, /**< FLEXIO0 */
+ Default_Handler, /* FTM3_IRQn = 71, /**< FlexTimer module 3 fault, overflow and channels interrupt */
+ Default_Handler, /* Reserved88_IRQn = 72, /**< Reserved interrupt */
+ Default_Handler, /* Reserved89_IRQn = 73, /**< Reserved interrupt */
+ Default_Handler, /* I2C2_IRQn = 74, /**< Inter-integrated circuit 2 */
+ Default_Handler, /* Reserved91_IRQn = 75, /**< Reserved interrupt */
+ Default_Handler, /* Reserved92_IRQn = 76, /**< Reserved interrupt */
+ Default_Handler, /* Reserved93_IRQn = 77, /**< Reserved interrupt */
+ Default_Handler, /* Reserved94_IRQn = 78, /**< Reserved interrupt */
+ Default_Handler, /* Reserved95_IRQn = 79, /**< Reserved interrupt */
+ Default_Handler, /* Reserved96_IRQn = 80, /**< Reserved interrupt */
+ Default_Handler, /* SDHC_IRQn = 81, /**< Secured digital host controller */
+ Default_Handler, /* Reserved98_IRQn = 82, /**< Reserved interrupt */
+ Default_Handler, /* Reserved99_IRQn = 83, /**< Reserved interrupt */
+ Default_Handler, /* Reserved100_IRQn = 84, /**< Reserved interrupt */
+ Default_Handler, /* Reserved101_IRQn = 85, /**< Reserved interrupt */
+ Default_Handler, /* Reserved102_IRQn = 86, /**< Reserved interrupt */
+ Default_Handler, /* TSI0_IRQn = 87, /**< Touch Sensing Input */
+ Default_Handler, /* TPM1_IRQn = 88, /**< TPM1 single interrupt vector for all sources */
+ Default_Handler, /* TPM2_IRQn = 89, /**< TPM2 single interrupt vector for all sources */
+ Default_Handler, /* Reserved106_IRQn = 90, /**< Reserved interrupt */
+ Default_Handler, /* I2C3_IRQn = 91, /**< Inter-integrated circuit 3 */
+ Default_Handler, /* Reserved108_IRQn = 92, /**< Reserved interrupt */
+ Default_Handler, /* Reserved109_IRQn = 93, /**< Reserved interrupt */
+ Default_Handler, /* Reserved110_IRQn = 94, /**< Reserved interrupt */
+ Default_Handler, /* Reserved111_IRQn = 95, /**< Reserved interrupt */
+ Default_Handler, /* Reserved112_IRQn = 96, /**< Reserved interrupt */
+ Default_Handler, /* Reserved113_IRQn = 97, /**< Reserved interrupt */
+ Default_Handler, /* Reserved114_IRQn = 98, /**< Reserved interrupt */
+ Default_Handler, /* Reserved115_IRQn = 99, /**< Reserved interrupt */
+ Default_Handler, /* QuadSPI0_IRQn = 100, /**< qspi */
+ Default_Handler, /* Reserved117_IRQn = 101, /**< Reserved interrupt */
+ Default_Handler, /* Reserved118_IRQn = 102, /**< Reserved interrupt */
+ Default_Handler, /* Reserved119_IRQn = 103, /**< Reserved interrupt */
+ Default_Handler, /* LTC0_IRQn = 104, /**< LP Trusted Cryptography */
+ Default_Handler, /* Reserved121_IRQn = 105, /**< Reserved interrupt */
+ Default_Handler, /* Reserved122_IRQn = 106 /**< Reserved interrupt */
+#endif /* CPU_MK82FN256VLL15 */
};
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c b/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c
index cdeda8570..efc82f685 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c
@@ -54,7 +54,7 @@ void main(void)
/*
SAMPLE OUTPUT: Freescale K64 running at 96MHz with no MMCAU:
-Benchmark Test 1:
+Benchmark Test 0:
AES 25 kB took 0.073 seconds, 0.334 MB/s
ARC4 25 kB took 0.033 seconds, 0.740 MB/s
RABBIT 25 kB took 0.027 seconds, 0.904 MB/s
@@ -66,10 +66,10 @@ RSA 1024 encryption took 91.000 milliseconds, avg over 1 iterations
RSA 1024 decryption took 573.000 milliseconds, avg over 1 iterations
DH 1024 key generation 253.000 milliseconds, avg over 1 iterations
DH 1024 key agreement 311.000 milliseconds, avg over 1 iterations
-Benchmark Test 1: Return code 0
+Benchmark Test 0: Return code 0
SAMPLE OUTPUT: Freescale K64 running at 96MHz with MMCAU enabled:
-Benchmark Test 1:
+Benchmark Test 0:
AES 25 kB took 0.019 seconds, 1.285 MB/s
ARC4 25 kB took 0.033 seconds, 0.740 MB/s
RABBIT 25 kB took 0.028 seconds, 0.872 MB/s
@@ -81,5 +81,74 @@ RSA 1024 encryption took 89.000 milliseconds, avg over 1 iterations
RSA 1024 decryption took 573.000 milliseconds, avg over 1 iterations
DH 1024 key generation 250.000 milliseconds, avg over 1 iterations
DH 1024 key agreement 308.000 milliseconds, avg over 1 iterations
-Benchmark Test 1: Return code 0
+Benchmark Test 0: Return code 0
+
+
+SAMPLE OUTPUT: NXP K82 running at 150Mhz w/MMCAU and LTC
+Benchmark Test 0:
+RNG 25 kB took 0.026 seconds, 0.939 MB/s
+AES enc 25 kB took 0.002 seconds, 12.207 MB/s
+AES dec 25 kB took 0.002 seconds, 12.207 MB/s
+AES-GCM 25 kB took 0.002 seconds, 12.207 MB/s
+AES-CTR 25 kB took 0.003 seconds, 8.138 MB/s
+AES-CCM 25 kB took 0.004 seconds, 6.104 MB/s
+CHACHA 25 kB took 0.008 seconds, 3.052 MB/s
+CHA-POLY 25 kB took 0.013 seconds, 1.878 MB/s
+
+POLY1305 25 kB took 0.003 seconds, 8.138 MB/s
+SHA 25 kB took 0.006 seconds, 4.069 MB/s
+SHA-256 25 kB took 0.009 seconds, 2.713 MB/s
+SHA-384 25 kB took 0.032 seconds, 0.763 MB/s
+SHA-512 25 kB took 0.035 seconds, 0.698 MB/s
+
+RSA 2048 public 12.000 milliseconds, avg over 1 iterations
+RSA 2048 private 135.000 milliseconds, avg over 1 iterations
+
+ECC 256 key generation 17.400 milliseconds, avg over 5 iterations
+EC-DHE key agreement 15.200 milliseconds, avg over 5 iterations
+EC-DSA sign time 20.200 milliseconds, avg over 5 iterations
+EC-DSA verify time 33.000 milliseconds, avg over 5 iterations
+
+CURVE25519 256 key generation 14.400 milliseconds, avg over 5 iterations
+CURVE25519 key agreement 14.400 milliseconds, avg over 5 iterations
+
+ED25519 key generation 14.800 milliseconds, avg over 5 iterations
+ED25519 sign time 16.800 milliseconds, avg over 5 iterations
+ED25519 verify time 30.400 milliseconds, avg over 5 iterations
+Benchmark Test 0: Return code 0
+
+SAMPLE OUTPUT: NXP K82 running at 150Mhz software only
+Benchmark Test 0:
+RNG 25 kB took 0.035 seconds, 0.698 MB/s
+AES enc 25 kB took 0.038 seconds, 0.642 MB/s
+AES dec 25 kB took 0.036 seconds, 0.678 MB/s
+AES-GCM 25 kB took 0.485 seconds, 0.050 MB/s
+AES-CTR 25 kB took 0.038 seconds, 0.642 MB/s
+AES-CCM 25 kB took 0.077 seconds, 0.317 MB/s
+CHACHA 25 kB took 0.009 seconds, 2.713 MB/s
+CHA-POLY 25 kB took 0.013 seconds, 1.878 MB/s
+
+POLY1305 25 kB took 0.003 seconds, 8.138 MB/s
+SHA 25 kB took 0.006 seconds, 4.069 MB/s
+SHA-256 25 kB took 0.014 seconds, 1.744 MB/s
+SHA-384 25 kB took 0.032 seconds, 0.763 MB/s
+SHA-512 25 kB took 0.034 seconds, 0.718 MB/s
+
+RSA 1024 encryption took 18.000 milliseconds, avg over 1 iterations
+RSA 1024 decryption took 123.000 milliseconds, avg over 1 iterations
+RSA 2048 encryption took 63.000 milliseconds, avg over 1 iterations
+RSA 2048 decryption took 1011.000 milliseconds, avg over 1 iterations
+
+ECC 256 key generation 180.800 milliseconds, avg over 5 iterations
+EC-DHE key agreement 178.600 milliseconds, avg over 5 iterations
+EC-DSA sign time 184.600 milliseconds, avg over 5 iterations
+EC-DSA verify time 130.200 milliseconds, avg over 5 iterations
+
+CURVE25519 256 key generation 41.800 milliseconds, avg over 5 iterations
+CURVE25519 key agreement 41.600 milliseconds, avg over 5 iterations
+
+ED25519 key generation 14.800 milliseconds, avg over 5 iterations
+ED25519 sign time 16.600 milliseconds, avg over 5 iterations
+ED25519 verify time 48.000 milliseconds, avg over 5 iterations
+Benchmark Test 0: Return code 0
*/
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/include.am b/IDE/ROWLEY-CROSSWORKS-ARM/include.am
index e812cc7e6..c58c76192 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/include.am
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/include.am
@@ -6,10 +6,10 @@ EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/hw.h
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c
-EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_FlashPlacement.xml
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/README.md
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/test_main.c
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/retarget.c
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h
EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp
+EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/wolfssl_ltc.hzp
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c
index 961e181d8..35b62fd41 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c
@@ -21,10 +21,10 @@
#include "hw.h"
+#include "user_settings.h"
#if defined(FREESCALE) && defined(K_SERIES)
-
/**********************************************
* NOTE: Customize for actual hardware
**********************************************/
@@ -33,27 +33,53 @@
// $(TargetsDir) location:
// On Mac OS/X: Users/USERNAME/Library/Rowley Associates Limited/CrossWorks for ARM/packages/targets/
// On Windows: C:/Users/USERNAME/Application Data/Local/Rowley Associates Limited/CrossWorks for ARM/packages/targets/
-#include // Located in $(TargetsDir)/Kinetis/CMSIS/
+
+// Located in $(TargetsDir)/Kinetis/CMSIS/
+#ifdef FREESCALE_KSDK_BM
+ #include "fsl_common.h"
+ #include "fsl_debug_console.h"
+ #include "fsl_rtc.h"
+ #include "fsl_trng.h"
+ #include "fsl_lpuart.h"
+ #include "fsl_port.h"
+ #include "clock_config.h"
+#else
+ #include // Located in $(TargetsDir)/Kinetis/CMSIS/
+#endif
+
// System clock
-#define SYS_CLK_KHZ 96000ul /* Core system clock in KHz */
-#define SYS_CLK_DRS MCG_C4_DRST_DRS(0x03) /* DRS 0=24MHz, 1=48MHz, 2=72MHz, 3=96MHz */
-#define SYS_CLK_DMX MCG_C4_DMX32_MASK /* 0=Disable DMX32 (lower actual speed), MCG_C4_DMX32_MASK=Enable DMX32 */
-#define SYS_CLK_DIV 1 /* System clock divisor */
-#define BUS_CLK_DIV 2 /* Bus clock divisor */
-#define BUS_CLK_KHZ (SYS_CLK_KHZ/BUS_CLK_DIV) /* Helper to calculate bus speed for UART */
-#define FLASH_CLK_DIV 4 /* Flash clock divisor */
+#ifdef FREESCALE_KSDK_BM
+ #define SYS_CLK_HZ SystemCoreClock
+#else
+ #define SYS_CLK_HZ 96000000ul /* Core system clock in Hz */
+ #define SYS_CLK_DRS MCG_C4_DRST_DRS(0x03) /* DRS 0=24MHz, 1=48MHz, 2=72MHz, 3=96MHz */
+ #define SYS_CLK_DMX MCG_C4_DMX32_MASK /* 0=Disable DMX32 (lower actual speed), MCG_C4_DMX32_MASK=Enable DMX32 */
+ #define SYS_CLK_DIV 1 /* System clock divisor */
+ #define BUS_CLK_DIV 2 /* Bus clock divisor */
+ #define BUS_CLK_KHZ (SYS_CLK_HZ/BUS_CLK_DIV) /* Helper to calculate bus speed for UART */
+ #define FLASH_CLK_DIV 4 /* Flash clock divisor */
+#endif
// UART TX Port, Pin, Mux and Baud
-#define UART_PORT UART4 /* UART Port */
-#define UART_TX_PORT PORTE /* UART TX Port */
-#define UART_TX_PIN 24 /* UART TX Pin */
-#define UART_TX_MUX 0x3 /* Kinetis UART pin mux */
-#define UART_BAUD 115200 /* UART Baud Rate */
+#ifdef FREESCALE_KSDK_BM
+ #define UART_PORT LPUART0 /* UART Port */
+ #define UART_TX_PORT PORTA /* UART TX Port */
+ #define UART_TX_PIN 2U /* UART TX Pin */
+ #define UART_TX_MUX kPORT_MuxAlt2 /* Kinetis UART pin mux */
+#else
+ #define UART_PORT UART4 /* UART Port */
+ #define UART_TX_PORT PORTE /* UART TX Port */
+ #define UART_TX_PIN 24U /* UART TX Pin */
+ #define UART_TX_MUX 0x3 /* Kinetis UART pin mux */
+#endif
+#define UART_BAUD 115200 /* UART Baud Rate */
+
/* Note: You will also need to update the UART clock gate in hw_uart_init (SIM_SCGC1_UART5_MASK) */
/* Note: TWR-K60 is UART3, PTC17 */
/* Note: FRDM-K64 is UART4, PTE24 */
/* Note: TWR-K64 is UART5, PTE8 */
+/* Note: FRDM-K82F is LPUART0 A2, LPUART4 PTC15 */
/***********************************************/
@@ -70,6 +96,9 @@ static void delay_nop(uint32_t count)
static void hw_mcg_init(void)
{
+#ifdef FREESCALE_KSDK_BM
+ BOARD_BootClockHSRUN();
+#else
/* Adjust clock dividers (core/system=div/1, bus=div/2, flex bus=div/2, flash=div/4) */
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(SYS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV2(BUS_CLK_DIV-1) |
SIM_CLKDIV1_OUTDIV3(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV4(FLASH_CLK_DIV-1);
@@ -77,10 +106,18 @@ static void hw_mcg_init(void)
/* Configure FEI internal clock speed */
MCG->C4 = (SYS_CLK_DMX | SYS_CLK_DRS);
while((MCG->C4 & (MCG_C4_DRST_DRS_MASK | MCG_C4_DMX32_MASK)) != (SYS_CLK_DMX | SYS_CLK_DRS));
+#endif
}
static void hw_gpio_init(void)
{
+#ifdef FREESCALE_KSDK_BM
+ CLOCK_EnableClock(kCLOCK_PortA);
+ CLOCK_EnableClock(kCLOCK_PortB);
+ CLOCK_EnableClock(kCLOCK_PortC);
+ CLOCK_EnableClock(kCLOCK_PortD);
+ CLOCK_EnableClock(kCLOCK_PortE);
+#else
/* Enable clocks to all GPIO ports */
SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK
#ifdef SIM_SCGC5_PORTC_MASK
@@ -93,6 +130,7 @@ static void hw_gpio_init(void)
| SIM_SCGC5_PORTE_MASK
#endif
);
+#endif
}
static void hw_uart_init(void)
@@ -100,7 +138,13 @@ static void hw_uart_init(void)
register uint16_t sbr, brfa;
uint8_t temp;
+#ifdef FREESCALE_KSDK_BM
+ PORT_SetPinMux(UART_TX_PORT, UART_TX_PIN, UART_TX_MUX);
+ CLOCK_SetLpuartClock(1); /* MCGPLLCLK */
+ DbgConsole_Init((uint32_t)UART_PORT, UART_BAUD, DEBUG_CONSOLE_DEVICE_TYPE_LPUART, SYS_CLK_HZ);
+#else
/* Enable UART core clock */
+ /* Note: Remember to update me if UART_PORT changes */
SIM->SCGC1 |= SIM_SCGC1_UART4_MASK;
/* Configure UART TX pin */
@@ -125,12 +169,13 @@ static void hw_uart_init(void)
/* Enable receiver and transmitter */
UART_PORT->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK);
+#endif
}
static void hw_rtc_init(void)
{
/* Init nop delay */
- mDelayCyclesPerUs = (SYS_CLK_KHZ / 1000 / NOP_FOR_LOOP_INSTRUCTION_COUNT);
+ mDelayCyclesPerUs = (SYS_CLK_HZ / 1000000 / NOP_FOR_LOOP_INSTRUCTION_COUNT);
/* Enable RTC clock and oscillator */
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
@@ -145,7 +190,7 @@ static void hw_rtc_init(void)
}
/* Disable RTC Interrupts */
- RTC_IER = 0;
+ RTC->IER = 0;
/* Enable OSC */
if ((RTC->CR & RTC_CR_OSCE_MASK) == 0) {
@@ -164,6 +209,14 @@ static void hw_rtc_init(void)
static void hw_rand_init(void)
{
+#ifdef FREESCALE_KSDK_BM
+ trng_config_t trngConfig;
+ TRNG_GetDefaultConfig(&trngConfig);
+ /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/
+ trngConfig.sampleMode = kTRNG_SampleModeVonNeumann;
+ /* Initialize TRNG */
+ TRNG_Init(TRNG0, &trngConfig);
+#else
/* Enable RNG clocks */
SIM->SCGC6 |= SIM_SCGC6_RNGA_MASK;
SIM->SCGC3 |= SIM_SCGC3_RNGA_MASK;
@@ -176,6 +229,7 @@ static void hw_rand_init(void)
/* Enable RNG generation to RANDOUT FIFO */
RNG->CR |= RNG_CR_GO_MASK;
+#endif
}
@@ -204,14 +258,24 @@ uint32_t hw_get_time_msec(void)
void hw_uart_printchar(int c)
{
+#ifdef FREESCALE_KSDK_BM
+ LPUART_WriteBlocking(UART_PORT, (const uint8_t*)&c, 1); /* Send the character */
+#else
while(!(UART_PORT->S1 & UART_S1_TDRE_MASK)); /* Wait until space is available in the FIFO */
UART_PORT->D = (uint8_t)c; /* Send the character */
+#endif
}
uint32_t hw_rand(void)
{
+ uint32_t rng;
+#ifdef FREESCALE_KSDK_BM
+ TRNG_GetRandomData(TRNG0, &rng, sizeof(rng));
+#else
while((RNG->SR & RNG_SR_OREG_LVL(0xF)) == 0) {}; /* Wait until FIFO has a value available */
- return RNG->OR; /* Return next value in FIFO output register */
+ rng = RNG->OR; /* Return next value in FIFO output register */
+#endif
+ return rng;
}
void delay_us(uint32_t microseconds)
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c
index 6a4dac38f..958316381 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c
@@ -22,6 +22,17 @@
#include "hw.h"
#include "user_settings.h"
+#include
+
+void __assert(const char *__expression, const char *__filename, int __line)
+{
+ printf("Assert: %s, File %s (%d)\n", __expression, __filename, __line);
+}
+
+unsigned int LowResTimer(void)
+{
+ return hw_get_time_sec();
+}
double current_time(int reset)
{
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c b/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c
index aad67b819..af58769ed 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/test_main.c
@@ -54,24 +54,26 @@ void main(void)
/* SAMPLE OUTPUT:
-Crypt Test 1:
-MD5 test passed!
-MD4 test passed!
+Crypt Test 0:
SHA test passed!
SHA-256 test passed!
-HMAC-MD5 test passed!
+SHA-384 test passed!
+SHA-512 test passed!
HMAC-SHA test passed!
HMAC-SHA256 test passed!
-ARC4 test passed!
-HC-128 test passed!
-Rabbit test passed!
-DES test passed!
-DES3 test passed!
+HMAC-SHA384 test passed!
+HMAC-SHA512 test passed!
+GMAC test passed!
+Chacha test passed!
+POLY1305 test passed!
+ChaCha20-Poly1305 AEAD test passed!
AES test passed!
+AES-GCM test passed!
+AES-CCM test passed!
RANDOM test passed!
RSA test passed!
-DH test passed!
-DSA test passed!
-PWDBASED test passed!
-Crypt Test 1: Return code 0
+ECC test passed!
+CURVE25519 test passed!
+ED25519 test passed!
+Crypt Test 0: Return code 0
*/
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h b/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h
index f8d751ff0..afa6be793 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h
@@ -56,7 +56,9 @@ extern "C" {
#define HAVE_ECC224
#undef NO_ECC256
#define HAVE_ECC384
- #define HAVE_ECC521
+ #ifndef USE_NXP_LTC /* NXP LTC HW supports up to 512 */
+ #define HAVE_ECC521
+ #endif
/* Fixed point cache (speeds repeated operations against same private key) */
#undef FP_ECC
@@ -72,7 +74,9 @@ extern "C" {
/* Optional ECC calculation method */
/* Note: doubles heap usage, but slightly faster */
#undef ECC_SHAMIR
- #define ECC_SHAMIR
+ #ifndef USE_NXP_LTC /* Don't enable Shamir code for HW ECC */
+ #define ECC_SHAMIR
+ #endif
/* Reduces heap usage, but slower */
#undef ECC_TIMING_RESISTANT
@@ -83,16 +87,22 @@ extern "C" {
#undef ALT_ECC_SIZE
#define ALT_ECC_SIZE
- /* optionally override the default max ecc bits */
- #undef FP_MAX_BITS_ECC
- //#define FP_MAX_BITS_ECC 512
-
/* Enable TFM optimizations for ECC */
- #define TFM_ECC192
- #define TFM_ECC224
- #define TFM_ECC256
- #define TFM_ECC384
- #define TFM_ECC521
+ #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+ #define TFM_ECC192
+ #endif
+ #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+ #define TFM_ECC224
+ #endif
+ #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+ #define TFM_ECC256
+ #endif
+ #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+ #define TFM_ECC384
+ #endif
+ #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+ #define TFM_ECC521
+ #endif
#endif
#endif
@@ -140,7 +150,7 @@ extern "C" {
/* Ed25519 / Curve25519 */
#undef HAVE_CURVE25519
#undef HAVE_ED25519
-#if 0
+#if 1
#define HAVE_CURVE25519
#define HAVE_ED25519
@@ -195,9 +205,20 @@ extern "C" {
/* ------------------------------------------------------------------------- */
/* HW Crypto Acceleration */
/* ------------------------------------------------------------------------- */
-// See README.md for instructions
-//#define FREESCALE_MMCAU 1
-
+#define FSL_HW_CRYPTO_MANUAL_SELECTION
+#if 1
+ /* NXP MMCAU / LTC Support (See README.md for instructions) */
+ #if defined(USE_NXP_MMCAU) || defined(USE_NXP_LTC)
+ #ifdef USE_NXP_MMCAU
+ #define FREESCALE_USE_MMCAU
+ #endif
+ #ifdef USE_NXP_LTC
+ #define FREESCALE_USE_LTC
+ #define LTC_MAX_ECC_BITS (512)
+ #define LTC_MAX_INT_BYTES (256)
+ #endif
+ #endif
+#endif
/* ------------------------------------------------------------------------- */
/* Benchmark / Test */
@@ -243,6 +264,7 @@ extern "C" {
/* Override Current Time */
/* Allows custom "custom_time()" function to be used for benchmark */
#define WOLFSSL_USER_CURRTIME
+#define USER_TICKS
/* ------------------------------------------------------------------------- */
diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp b/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp
index 74a4eeaff..ad5c68af8 100644
--- a/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp
+++ b/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp
@@ -83,6 +83,9 @@
+
@@ -140,6 +143,8 @@
arm_target_loader_default_loader="Flash"
c_preprocessor_definitions="WOLFSSL_ROWLEY_ARM;WOLFSSL_USER_SETTINGS"
c_user_include_directories=".;../;../../;$(TargetsDir);$(TargetsDir)/Kinetis;$(TargetsDir)/Kinetis/CMSIS;$(TargetsDir)/Kinetis/CMSIS/include;$(TargetsDir)/CMSIS_3/CMSIS/include"
+ debug_register_definition_file="$(TargetsDir)/Kinetis/MK64F12_Peripherals.xml"
+ linker_memory_map_file="$(TargetsDir)/Kinetis/MK64FN1M0xxx12_MemoryMap.xml"
linker_memory_map_macros="FLASHSIZE=0x80000;SRAMSIZE=0x20000"
linker_output_format="bin"
project_dependencies="libwolfssl"
@@ -161,7 +166,6 @@
-
@@ -169,16 +173,21 @@
Name="Common"
Placement="Flash"
Target="MK64FN1M0xxx12"
+ arm_architecture="v7EM"
+ arm_core_type="Cortex-M4"
+ arm_fpu_type="FPv4-SP-D16"
arm_linker_fiq_stack_size="0"
arm_linker_heap_size="91136"
arm_linker_irq_stack_size="0"
arm_linker_stack_size="30720"
arm_simulator_memory_simulation_filename="$(TargetsDir)/Kinetis/KinetisSimulatorMemory.dll"
- arm_simulator_memory_simulation_parameter="MK64FN1M0xxx12;0x100000;0x0;0x0;0x40000"
+ arm_simulator_memory_simulation_parameter="MK64FN1M0xxx12;0x100000;0x0;0x0;0x40000;4"
arm_target_loader_applicable_loaders="Flash"
arm_target_loader_default_loader="Flash"
c_preprocessor_definitions="WOLFSSL_ROWLEY_ARM;WOLFSSL_USER_SETTINGS"
c_user_include_directories=".;../;../../;$(TargetsDir);$(TargetsDir)/Kinetis;$(TargetsDir)/Kinetis/CMSIS;$(TargetsDir)/Kinetis/CMSIS/include;$(TargetsDir)/CMSIS_3/CMSIS/include"
+ debug_register_definition_file="$(TargetsDir)/Kinetis/MK64F12_Peripherals.xml"
+ linker_memory_map_file="$(TargetsDir)/Kinetis/MK64FN1M0xxx12_MemoryMap.xml"
linker_memory_map_macros="FLASHSIZE=0x80000;SRAMSIZE=0x20000"
linker_output_format="bin"
project_dependencies="libwolfssl"
@@ -200,8 +209,11 @@
-
+
+ inherited_configurations="ARM;V7EM;Debug;Kinetis;THUMB;Flash" />
+ inherited_configurations="ARM;V7EM;Release;Kinetis;Flash;THUMB" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/configure.ac b/configure.ac
index ee8d9822c..e59c210f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -474,6 +474,8 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_PK_CALLBACKS"
fi
+AM_CONDITIONAL([BUILD_PKCALLBACKS], [ test "x$ENABLED_PKCALLBACKS" = "xyes" ])
+
# SNIFFER
AC_ARG_ENABLE([sniffer],
diff --git a/scripts/include.am b/scripts/include.am
index 1701ad97e..0a49b14af 100644
--- a/scripts/include.am
+++ b/scripts/include.am
@@ -47,6 +47,11 @@ if BUILD_TRUST_PEER_CERT
dist_noinst_SCRIPTS+= scripts/trusted_peer.test
endif
+if BUILD_PKCALLBACKS
+dist_noinst_SCRIPTS+= scripts/pkcallbacks.test
+scripts/pkcallbacks.log: scripts/resume.log
+endif
+
endif # end of BUILD_EXAMPLE_SERVERS
if BUILD_EXAMPLE_CLIENTS
diff --git a/scripts/pkcallbacks.test b/scripts/pkcallbacks.test
new file mode 100755
index 000000000..24c9228f5
--- /dev/null
+++ b/scripts/pkcallbacks.test
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+#pkcallbacks.test
+
+exit_code=1
+counter=0
+# need a unique resume port since may run the same time as testsuite
+# use server port zero hack to get one
+pk_port=0
+#no_pid tells us process was never started if -1
+no_pid=-1
+#server_pid captured on startup, stores the id of the server process
+server_pid=$no_pid
+# let's use absolute path to a local dir (make distcheck may be in sub dir)
+# also let's add some randomness by adding pid in case multiple 'make check's
+# per source tree
+ready_file=`pwd`/wolfssl_pk_ready$$
+
+remove_ready_file() {
+ if test -e $ready_file; then
+ echo -e "removing existing ready file"
+ rm $ready_file
+ fi
+}
+
+do_cleanup() {
+ echo "in cleanup"
+
+ if [ $server_pid != $no_pid ]
+ then
+ echo "killing server"
+ kill -9 $server_pid
+ fi
+ remove_ready_file
+}
+
+# trap this function so if user aborts with ^C or other kill signal we still
+# get an exit that will in turn clean up the file system
+abort_trap() {
+ echo "script aborted"
+
+ if [ $server_pid != $no_pid ]
+ then
+ echo "killing server"
+ kill -9 $server_pid
+ fi
+
+ exit_code=2 #different exit code in case of user interrupt
+
+ echo "got abort signal, exiting with $exit_code"
+ exit $exit_code
+}
+trap abort_trap INT TERM
+
+
+# trap this function so that if we exit on an error the file system will still
+# be restored and the other tests may still pass. Never call this function
+# instead use "exit " and this function will run automatically
+restore_file_system() {
+ remove_ready_file
+}
+trap restore_file_system EXIT
+
+run_test() {
+ echo -e "\nStarting example server for pkcallbacks test...\n"
+
+ remove_ready_file
+
+ # starts the server on pk_port, -R generates ready file to be used as a
+ # mutex lock, -P does pkcallbacks. We capture the processid
+ # into the variable server_pid
+ ./examples/server/server -P -R $ready_file -p $pk_port &
+ server_pid=$!
+
+ while [ ! -s $ready_file -a "$counter" -lt 20 ]; do
+ echo -e "waiting for ready file..."
+ sleep 0.1
+ counter=$((counter+ 1))
+ done
+
+ if test -e $ready_file; then
+ echo -e "found ready file, starting client..."
+ else
+ echo -e "NO ready file ending test..."
+ exit 1
+ fi
+
+ # get created port 0 ephemeral port
+ pk_port=`cat $ready_file`
+
+ # starts client on pk_port with pkcallbacks, captures the output from client
+ capture_out=$(./examples/client/client -P -p $pk_port 2>&1)
+ client_result=$?
+
+ if [ $client_result != 0 ]
+ then
+ echo -e "client failed!"
+ do_cleanup
+ exit 1
+ fi
+
+ wait $server_pid
+ server_result=$?
+
+ if [ $server_result != 0 ]
+ then
+ echo -e "server failed!"
+ exit 1
+ fi
+
+}
+
+
+######### begin program #########
+
+# run the test
+run_test
+
+# If we get to this, success
+echo "Success!"
+exit 0
+########## end program ##########
+
diff --git a/src/internal.c b/src/internal.c
index 71924d2fd..ef62d7dc0 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -4507,7 +4507,32 @@ ProtocolVersion MakeDTLSv1_2(void)
-#ifdef USE_WINDOWS_API
+#if defined(USER_TICKS)
+#if 0
+ word32 LowResTimer(void)
+ {
+ /*
+ write your own clock tick function if don't want time(0)
+ needs second accuracy but doesn't have to correlated to EPOCH
+ */
+ }
+#endif
+
+#elif defined(TIME_OVERRIDES)
+
+ /* use same asn time overrides unless user wants tick override above */
+
+ #ifndef HAVE_TIME_T_TYPE
+ typedef long time_t;
+ #endif
+ extern time_t XTIME(time_t * timer);
+
+ word32 LowResTimer(void)
+ {
+ return (word32) XTIME(0);
+ }
+
+#elif defined(USE_WINDOWS_API)
word32 LowResTimer(void)
{
@@ -4587,14 +4612,21 @@ ProtocolVersion MakeDTLSv1_2(void)
return (word32) mqxTime.SECONDS;
}
+#elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
-#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
+ #include "include/task.h"
- #include "fsl_pit_driver.h"
+ unsigned int LowResTimer(void)
+ {
+ return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ);
+ }
+#elif defined(FREESCALE_KSDK_BM)
+
+ #include "lwip/sys.h" /* lwIP */
word32 LowResTimer(void)
{
- return PIT_DRV_GetUs();
+ return sys_now()/1000;
}
#elif defined(WOLFSSL_TIRTOS)
@@ -4611,33 +4643,8 @@ ProtocolVersion MakeDTLSv1_2(void)
return (word32)(uTaskerSystemTick / TICK_RESOLUTION);
}
-#elif defined(USER_TICKS)
-#if 0
- word32 LowResTimer(void)
- {
- /*
- write your own clock tick function if don't want time(0)
- needs second accuracy but doesn't have to correlated to EPOCH
- */
- }
-#endif
-
-#elif defined(TIME_OVERRIDES)
-
- /* use same asn time overrides unless user wants tick override above */
-
- #ifndef HAVE_TIME_T_TYPE
- typedef long time_t;
- #endif
- extern time_t XTIME(time_t * timer);
-
- word32 LowResTimer(void)
- {
- return (word32) XTIME(0);
- }
-
-#else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
-
+#else
+ /* Posix style time */
#include
word32 LowResTimer(void)
@@ -4646,7 +4653,7 @@ ProtocolVersion MakeDTLSv1_2(void)
}
-#endif /* USE_WINDOWS_API */
+#endif
#ifndef NO_CERTS
diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c
index 1821d632b..9837e9f29 100644
--- a/wolfcrypt/src/aes.c
+++ b/wolfcrypt/src/aes.c
@@ -299,19 +299,36 @@ void wc_AesAsyncFree(Aes* aes)
#include "sec.h"
#include "mcf5475_sec.h"
#include "mcf5475_siu.h"
+#elif defined(FREESCALE_LTC)
+ #include "fsl_ltc.h"
+ #if defined(FREESCALE_LTC_AES_GCM)
+ #undef NEED_AES_TABLES
+ #undef GCM_TABLE
+ #else
+ /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
+ static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+ {
+ wc_AesEncryptDirect(aes, outBlock, inBlock);
+ return 0;
+ }
+ static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
+ {
+ wc_AesDecryptDirect(aes, outBlock, inBlock);
+ return 0;
+ }
+ #endif
#elif defined(FREESCALE_MMCAU)
/* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
* through the CAU/mmCAU library. Documentation located in
* ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
- * Guide (See note in README).
- * NOTE: no support for AES-CTR */
- #include "cau_api.h"
+ * Guide (See note in README). */
+ #include "fsl_mmcau.h"
static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
{
int ret = wolfSSL_CryptHwMutexLock();
if(ret == 0) {
- cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+ MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds, outBlock);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
@@ -321,7 +338,7 @@ void wc_AesAsyncFree(Aes* aes)
{
int ret = wolfSSL_CryptHwMutexLock();
if(ret == 0) {
- cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
+ MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds, outBlock);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
@@ -1592,6 +1609,28 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
return 0;
}
+#elif defined(FREESCALE_LTC)
+ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
+ int dir)
+ {
+ if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
+ return BAD_FUNC_ARG;
+
+ aes->rounds = keylen/4 + 6;
+ XMEMCPY(aes->key, userKey, keylen);
+
+ #ifdef WOLFSSL_AES_COUNTER
+ aes->left = 0;
+ #endif /* WOLFSSL_AES_COUNTER */
+
+ return wc_AesSetIV(aes, iv);
+ }
+
+ int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
+ const byte* iv, int dir)
+ {
+ return wc_AesSetKey(aes, userKey, keylen, iv, dir);
+ }
#elif defined(FREESCALE_MMCAU)
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
@@ -1607,11 +1646,15 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
if (rk == NULL)
return BAD_FUNC_ARG;
+ #ifdef WOLFSSL_AES_COUNTER
+ aes->left = 0;
+ #endif /* WOLFSSL_AES_COUNTER */
+
aes->rounds = keylen/4 + 6;
ret = wolfSSL_CryptHwMutexLock();
if(ret == 0) {
- cau_aes_set_key(userKey, keylen*8, rk);
+ MMCAU_AES_SetKey(userKey, keylen, rk);
wolfSSL_CryptHwMutexUnLock();
ret = wc_AesSetIV(aes, iv);
@@ -1905,6 +1948,33 @@ int wc_InitAes_h(Aes* aes, void* h)
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
#error "PIC32MZ doesn't yet support AES direct"
+ #elif defined(FREESCALE_LTC)
+ /* Allow direct access to one block encrypt */
+ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
+ {
+ byte *key;
+ uint32_t keySize;
+
+ key = (byte*)aes->key;
+ wc_AesGetKeySize(aes, &keySize);
+
+ LTC_AES_EncryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
+ key, keySize);
+ }
+
+ /* Allow direct access to one block decrypt */
+ void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
+ {
+ byte *key;
+ uint32_t keySize;
+
+ key = (byte*)aes->key;
+ wc_AesGetKeySize(aes, &keySize);
+
+ LTC_AES_DecryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
+ key, keySize, kLTC_EncryptKey);
+ }
+
#else
/* Allow direct access to one block encrypt */
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
@@ -2019,9 +2089,9 @@ int wc_InitAes_h(Aes* aes, void* h)
/* store iv for next call */
XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
- sz -= 16;
- in += 16;
- out += 16;
+ sz -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
}
/* disable crypto processor */
@@ -2141,9 +2211,9 @@ int wc_InitAes_h(Aes* aes, void* h)
/* store iv for next call */
XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
- sz -= 16;
- in += 16;
- out += 16;
+ sz -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
}
/* disable crypto processor */
@@ -2257,6 +2327,48 @@ int wc_InitAes_h(Aes* aes, void* h)
return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
}
#endif /* HAVE_AES_DECRYPT */
+
+#elif defined(FREESCALE_LTC)
+ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+ {
+ uint32_t keySize;
+ status_t status;
+ byte *iv, *enc_key;
+
+ iv = (byte*)aes->reg;
+ enc_key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_EncryptCbc(LTC_BASE, in, out, sz,
+ iv, enc_key, keySize);
+ return (status == kStatus_Success) ? 0 : -1;
+ }
+
+ #ifdef HAVE_AES_DECRYPT
+ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+ {
+ uint32_t keySize;
+ status_t status;
+ byte* iv, *dec_key;
+
+ iv = (byte*)aes->reg;
+ dec_key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_DecryptCbc(LTC_BASE, in, out, sz,
+ iv, dec_key, keySize, kLTC_EncryptKey);
+ return (status == kStatus_Success) ? 0 : -1;
+ }
+ #endif /* HAVE_AES_DECRYPT */
+
#elif defined(FREESCALE_MMCAU)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
@@ -2269,11 +2381,6 @@ int wc_InitAes_h(Aes* aes, void* h)
iv = (byte*)aes->reg;
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
- return BAD_ALIGN_E;
- }
-
while (len > 0)
{
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
@@ -2305,10 +2412,6 @@ int wc_InitAes_h(Aes* aes, void* h)
iv = (byte*)aes->reg;
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
- return BAD_ALIGN_E;
- }
while (len > 0)
{
@@ -2661,9 +2764,9 @@ int wc_InitAes_h(Aes* aes, void* h)
/* store iv for next call */
XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
- sz -= 16;
- in += 16;
- out += 16;
+ sz -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
}
/* disable crypto processor */
@@ -2731,8 +2834,31 @@ int wc_InitAes_h(Aes* aes, void* h)
#elif defined(HAVE_COLDFIRE_SEC)
#error "Coldfire SEC doesn't currently support AES-CTR mode"
- #elif defined(FREESCALE_MMCAU)
- #error "Freescale mmCAU doesn't currently support AES-CTR mode"
+ #elif defined(FREESCALE_LTC)
+ void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
+ {
+ uint32_t keySize;
+ byte *iv, *enc_key;
+ byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
+
+ /* consume any unused bytes left in aes->tmp */
+ while (aes->left && sz) {
+ *(out++) = *(in++) ^ *(tmp++);
+ aes->left--;
+ sz--;
+ }
+
+ if (sz) {
+ iv = (byte*)aes->reg;
+ enc_key = (byte*)aes->key;
+
+ wc_AesGetKeySize(aes, &keySize);
+
+ LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
+ iv, enc_key, keySize, (byte*)aes->tmp,
+ (uint32_t*)&(aes->left));
+ }
+ }
#else
/* Increment AES counter */
@@ -2816,7 +2942,7 @@ enum {
CTR_SZ = 4
};
-
+#if !defined(FREESCALE_LTC_AES_GCM)
static INLINE void IncrementGcmCounter(byte* inOutCtr)
{
int i;
@@ -2827,7 +2953,7 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr)
return;
}
}
-
+#endif /* !FREESCALE_LTC_AES_GCM */
#if defined(GCM_SMALL) || defined(GCM_TABLE)
@@ -2911,12 +3037,14 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
return ret;
#endif /* WOLFSSL_AESNI */
+#if !defined(FREESCALE_LTC_AES_GCM)
if (ret == 0) {
wc_AesEncrypt(aes, iv, aes->H);
#ifdef GCM_TABLE
GenerateM0(aes);
#endif /* GCM_TABLE */
}
+#endif /* FREESCALE_LTC_AES_GCM */
return ret;
}
@@ -3588,6 +3716,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz,
/* end GCM_TABLE */
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
+#if !defined(FREESCALE_LTC_AES_GCM)
static void GMULT(word64* X, word64* Y)
{
word64 Z[2] = {0,0};
@@ -3623,7 +3752,6 @@ static void GMULT(word64* X, word64* Y)
X[1] = Z[1];
}
-
static void GHASH(Aes* aes, const byte* a, word32 aSz,
const byte* c, word32 cSz, byte* s, word32 sSz)
{
@@ -3708,6 +3836,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz,
#endif
XMEMCPY(s, x, sSz);
}
+#endif /* !FREESCALE_LTC_AES_GCM */
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
#else /* GCM_WORD32 */
@@ -3864,6 +3993,25 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
byte* authTag, word32 authTagSz,
const byte* authIn, word32 authInSz)
{
+#if defined(FREESCALE_LTC_AES_GCM)
+ byte *key;
+ uint32_t keySize;
+ status_t status;
+
+ key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz,
+ iv, ivSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+ return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
+
+#else /* FREESCALE_LTC_AES_GCM */
+
word32 blocks = sz / AES_BLOCK_SIZE;
word32 partial = sz % AES_BLOCK_SIZE;
const byte* p = in;
@@ -3930,6 +4078,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
xorbuf(authTag, scratch, authTagSz);
return 0;
+#endif /* FREESCALE_LTC_AES_GCM */
}
@@ -3939,6 +4088,25 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
const byte* authTag, word32 authTagSz,
const byte* authIn, word32 authInSz)
{
+#if defined(FREESCALE_LTC_AES_GCM)
+ byte *key;
+ uint32_t keySize;
+ status_t status;
+
+ key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz,
+ iv, ivSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+ return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
+
+#else /* FREESCALE_LTC_AES_GCM */
+
word32 blocks = sz / AES_BLOCK_SIZE;
word32 partial = sz % AES_BLOCK_SIZE;
const byte* c = in;
@@ -4015,6 +4183,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
XMEMCPY(p, scratch, partial);
}
return 0;
+#endif /* FREESCALE_LTC_AES_GCM */
}
#endif /* HAVE_AES_DECRYPT */
@@ -4058,6 +4227,7 @@ int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
}
+#ifndef FREESCALE_LTC
static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
{
/* process the bulk of the data */
@@ -4130,7 +4300,7 @@ static INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
}
}
-
+#endif /* !FREESCALE_LTC */
/* return 0 on success */
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
@@ -4138,6 +4308,23 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
byte* authTag, word32 authTagSz,
const byte* authIn, word32 authInSz)
{
+#ifdef FREESCALE_LTC
+ byte *key;
+ uint32_t keySize;
+ status_t status;
+
+ key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
+ nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+ return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
+#else
byte A[AES_BLOCK_SIZE];
byte B[AES_BLOCK_SIZE];
byte lenSz;
@@ -4196,6 +4383,7 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
ForceZero(B, AES_BLOCK_SIZE);
return 0;
+#endif /* FREESCALE_LTC */
}
#ifdef HAVE_AES_DECRYPT
@@ -4204,6 +4392,30 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
const byte* authTag, word32 authTagSz,
const byte* authIn, word32 authInSz)
{
+#ifdef FREESCALE_LTC
+ byte *key;
+ uint32_t keySize;
+ status_t status;
+
+ key = (byte*)aes->key;
+
+ status = wc_AesGetKeySize(aes, &keySize);
+ if (status != 0) {
+ return status;
+ }
+
+ status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
+ nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
+
+ if (status == kStatus_Success) {
+ return 0;
+ }
+ else {
+ XMEMSET(out, 0, inSz);
+ return AES_CCM_AUTH_E;
+ }
+#else /* FREESCALE_LTC */
+
byte A[AES_BLOCK_SIZE];
byte B[AES_BLOCK_SIZE];
byte* o;
@@ -4286,6 +4498,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
o = NULL;
return result;
+#endif /* FREESCALE_LTC */
}
#endif /* HAVE_AES_DECRYPT */
#endif /* HAVE_AESCCM */
@@ -4314,7 +4527,34 @@ void wc_AesAsyncFree(Aes* aes)
#endif /* WOLFSSL_ASYNC_CRYPT */
-#endif /* WOLFSSL_TI_CRYPT */
+
+int wc_AesGetKeySize(Aes* aes, word32* keySize)
+{
+ int ret = 0;
+
+ if (aes == NULL || keySize == NULL) {
+ return BAD_FUNC_ARG;
+ }
+
+ switch (aes->rounds) {
+ case 10:
+ *keySize = 16;
+ break;
+ case 12:
+ *keySize = 24;
+ break;
+ case 14:
+ *keySize = 32;
+ break;
+ default:
+ *keySize = 0;
+ ret = BAD_FUNC_ARG;
+ }
+
+ return ret;
+}
+
+#endif /* !WOLFSSL_TI_CRYPT */
#endif /* HAVE_FIPS */
diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c
index 92c725737..84b4d8813 100644
--- a/wolfcrypt/src/asn.c
+++ b/wolfcrypt/src/asn.c
@@ -104,7 +104,26 @@ ASN Options:
#endif
#ifndef NO_ASN_TIME
-#if defined(HAVE_RTP_SYS)
+#if defined(USER_TIME)
+ /* user time, and gmtime compatible functions, there is a gmtime
+ implementation here that WINCE uses, so really just need some ticks
+ since the EPOCH
+ */
+ #define WOLFSSL_GMTIME
+ #define USE_WOLF_TM
+ #define USE_WOLF_TIME_T
+
+#elif defined(TIME_OVERRIDES)
+ /* user would like to override time() and gmtime() functionality */
+ #ifndef HAVE_TIME_T_TYPE
+ #define USE_WOLF_TIME_T
+ #endif
+ #ifndef HAVE_TM_TYPE
+ #define USE_WOLF_TM
+ #endif
+ #define NEED_TMP_TIME
+
+#elif defined(HAVE_RTP_SYS)
/* uses parital structures */
#define XTIME(tl) (0)
#define XGMTIME(c, t) rtpsys_gmtime((c))
@@ -127,30 +146,13 @@ ASN Options:
#define XTIME(t1) mqx_time((t1))
#define HAVE_GMTIME_R
-#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
+#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
#include
- #define XTIME(t1) ksdk_time((t1))
+ #ifndef XTIME
+ #define XTIME(t1) 0
+ #endif
#define XGMTIME(c, t) gmtime((c))
-#elif defined(USER_TIME)
- /* user time, and gmtime compatible functions, there is a gmtime
- implementation here that WINCE uses, so really just need some ticks
- since the EPOCH
- */
- #define WOLFSSL_GMTIME
- #define USE_WOLF_TM
- #define USE_WOLF_TIME_T
-
-#elif defined(TIME_OVERRIDES)
- /* user would like to override time() and gmtime() functionality */
- #ifndef HAVE_TIME_T_TYPE
- #define USE_WOLF_TIME_T
- #endif
- #ifndef HAVE_TM_TYPE
- #define USE_WOLF_TM
- #endif
- #define NEED_TMP_TIME
-
#elif defined(IDIRECT_DEV_TIME)
/*Gets the timestamp from cloak software owned by VT iDirect
in place of time() from */
@@ -376,18 +378,8 @@ time_t mqx_time(time_t* timer)
#if defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
-#include "fsl_pit_driver.h"
-
-time_t ksdk_time(time_t* timer)
-{
- time_t localTime;
-
- if (timer == NULL)
- timer = &localTime;
-
- *timer = (PIT_DRV_ReadTimerUs(PIT_INSTANCE, PIT_CHANNEL)) / 1000000;
- return *timer;
-}
+/* */
+//extern time_t ksdk_time(time_t* timer);
#endif /* FREESCALE_KSDK_BM */
diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c
index 3e7b0f52a..6740cc536 100644
--- a/wolfcrypt/src/curve25519.c
+++ b/wolfcrypt/src/curve25519.c
@@ -40,6 +40,10 @@
#include
#endif
+#if defined(FREESCALE_LTC_ECC)
+ #include
+#endif
+
const curve25519_set_type curve25519_sets[] = {
{
32,
@@ -47,10 +51,13 @@ const curve25519_set_type curve25519_sets[] = {
}
};
-
int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
{
+#ifdef FREESCALE_LTC_ECC
+ const ECPoint* basepoint = wc_curve25519_GetBasePoint();
+#else
unsigned char basepoint[CURVE25519_KEYSIZE] = {9};
+#endif
int ret;
if (key == NULL || rng == NULL)
@@ -71,7 +78,11 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
key->k.point[CURVE25519_KEYSIZE-1] |= 64;
/* compute public key */
- ret = curve25519(key->p.point, key->k.point, basepoint);
+ #ifdef FREESCALE_LTC_ECC
+ ret = wc_curve25519(&key->p, key->k.point, basepoint, kLTC_Weierstrass); /* input basepoint on Weierstrass curve */
+ #else
+ ret = curve25519(key->p.point, key->k.point, basepoint);
+ #endif
if (ret != 0) {
ForceZero(key->k.point, keysize);
ForceZero(key->p.point, keysize);
@@ -95,21 +106,34 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
curve25519_key* public_key,
byte* out, word32* outlen, int endian)
{
- unsigned char o[CURVE25519_KEYSIZE];
+ #ifdef FREESCALE_LTC_ECC
+ ECPoint o = {{0}};
+ #else
+ unsigned char o[CURVE25519_KEYSIZE];
+ #endif
int ret = 0;
/* sanity check */
if (private_key == NULL || public_key == NULL ||
out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE)
return BAD_FUNC_ARG;
-
+
/* avoid implementation fingerprinting */
if (public_key->p.point[CURVE25519_KEYSIZE-1] > 0x7F)
return ECC_BAD_ARG_E;
- ret = curve25519(o, private_key->k.point, public_key->p.point);
+ #ifdef FREESCALE_LTC_ECC
+ ret = wc_curve25519(&o, private_key->k.point, &public_key->p, kLTC_Curve25519 /* input point P on Curve25519 */);
+ #else
+ ret = curve25519(o, private_key->k.point, public_key->p.point);
+ #endif
if (ret != 0) {
- ForceZero(o, CURVE25519_KEYSIZE);
+ #ifdef FREESCALE_LTC_ECC
+ ForceZero(o.point, CURVE25519_KEYSIZE);
+ ForceZero(o.pointY, CURVE25519_KEYSIZE);
+ #else
+ ForceZero(o, CURVE25519_KEYSIZE);
+ #endif
return ret;
}
@@ -117,14 +141,27 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
int i;
/* put shared secret key in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
- out[i] = o[CURVE25519_KEYSIZE - i -1];
+ #ifdef FREESCALE_LTC_ECC
+ out[i] = o.point[CURVE25519_KEYSIZE - i -1];
+ #else
+ out[i] = o[CURVE25519_KEYSIZE - i -1];
+ #endif
}
else /* put shared secret key in Little Endian format */
- XMEMCPY(out, o, CURVE25519_KEYSIZE);
+ #ifdef FREESCALE_LTC_ECC
+ XMEMCPY(out, o.point, CURVE25519_KEYSIZE);
+ #else
+ XMEMCPY(out, o, CURVE25519_KEYSIZE);
+ #endif
*outlen = CURVE25519_KEYSIZE;
- ForceZero(o, sizeof(o));
+ #ifdef FREESCALE_LTC_ECC
+ ForceZero(o.point, CURVE25519_KEYSIZE);
+ ForceZero(o.pointY, CURVE25519_KEYSIZE);
+ #else
+ ForceZero(o, CURVE25519_KEYSIZE);
+ #endif
return ret;
}
@@ -212,6 +249,15 @@ int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
XMEMCPY(key->p.point, in, inLen);
key->dp = &curve25519_sets[0];
+
+
+ /* LTC needs also Y coordinate - let's compute it */
+ #ifdef FREESCALE_LTC_ECC
+ ltc_pkha_ecc_point_t ltcPoint;
+ ltcPoint.X = &key->p.point[0];
+ ltcPoint.Y = &key->p.pointY[0];
+ LTC_PKHA_Curve25519ComputeY(<cPoint);
+ #endif
return 0;
}
@@ -378,9 +424,12 @@ int wc_curve25519_init(curve25519_key* key)
/* currently the format for curve25519 */
key->dp = &curve25519_sets[0];
- XMEMSET(key->k.point, 0, key->dp->size);
+ XMEMSET(key->k.point, 0, key->dp->size);
XMEMSET(key->p.point, 0, key->dp->size);
-
+ #ifdef FREESCALE_LTC_ECC
+ XMEMSET(key->k.pointY, 0, key->dp->size);
+ XMEMSET(key->p.pointY, 0, key->dp->size);
+ #endif
return 0;
}
@@ -394,6 +443,10 @@ void wc_curve25519_free(curve25519_key* key)
key->dp = NULL;
ForceZero(key->p.point, sizeof(key->p.point));
ForceZero(key->k.point, sizeof(key->k.point));
+ #ifdef FREESCALE_LTC_ECC
+ ForceZero(key->p.point, sizeof(key->p.pointY));
+ ForceZero(key->k.point, sizeof(key->k.pointY));
+ #endif
}
diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c
index 3f2147d88..cc27ab3c1 100644
--- a/wolfcrypt/src/des3.c
+++ b/wolfcrypt/src/des3.c
@@ -576,14 +576,99 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
return 0;
}
+#elif (defined FREESCALE_LTC_DES)
+ #include "fsl_ltc.h"
+ int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
+ {
+ byte* dkey = (byte*)des->key;
+
+ XMEMCPY(dkey, key, 8);
+
+ wc_Des_SetIV(des, iv);
+
+ return 0;
+ }
+
+ int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
+ {
+ int ret = 0;
+ byte* dkey1 = (byte*)des->key[0];
+ byte* dkey2 = (byte*)des->key[1];
+ byte* dkey3 = (byte*)des->key[2];
+
+ XMEMCPY(dkey1, key, 8); /* set key 1 */
+ XMEMCPY(dkey2, key + 8, 8); /* set key 2 */
+ XMEMCPY(dkey3, key + 16, 8); /* set key 3 */
+
+ ret = wc_Des3_SetIV(des, iv);
+ if (ret != 0)
+ return ret;
+
+ return ret;
+ }
+
+ int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
+ {
+ status_t status;
+ status = LTC_DES_EncryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
+ if (status == kStatus_Success)
+ return 0;
+ else
+ return -1;
+ }
+
+ int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
+ {
+ status_t status;
+ status = LTC_DES_DecryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
+ if (status == kStatus_Success)
+ return 0;
+ else
+ return -1;
+ }
+
+ int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
+ {
+ status_t status;
+ status = LTC_DES3_EncryptCbc(LTC_BASE,
+ in,
+ out,
+ sz,
+ (byte*)des->reg,
+ (byte*)des->key[0],
+ (byte*)des->key[1],
+ (byte*)des->key[2]);
+ if (status == kStatus_Success)
+ return 0;
+ else
+ return -1;
+ }
+
+ int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
+ {
+ status_t status;
+ status = LTC_DES3_DecryptCbc(LTC_BASE,
+ in,
+ out,
+ sz,
+ (byte*)des->reg,
+ (byte*)des->key[0],
+ (byte*)des->key[1],
+ (byte*)des->key[2]);
+ if (status == kStatus_Success)
+ return 0;
+ else
+ return -1;
+
+ }
#elif defined FREESCALE_MMCAU
/*
* Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
* Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
* Software Library User Guide (See note in README).
*/
- #include "cau_api.h"
+ #include "fsl_mmcau.h"
const unsigned char parityLookup[128] =
{
@@ -648,12 +733,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
-
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad cau_des_encrypt alignment");
- return BAD_ALIGN_E;
- }
-
+
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
@@ -666,7 +746,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
if(ret != 0) {
return ret;
}
- cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
+ MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset);
wolfSSL_CryptHwMutexUnLock();
len -= DES_BLOCK_SIZE;
@@ -690,11 +770,6 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
iv = (byte*)des->reg;
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad cau_des_decrypt alignment");
- return BAD_ALIGN_E;
- }
-
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
@@ -703,7 +778,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
if(ret != 0) {
return ret;
}
- cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
+ MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset);
wolfSSL_CryptHwMutexUnLock();
/* XOR block with IV for CBC */
@@ -731,12 +806,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
-
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment");
- return BAD_ALIGN_E;
- }
-
+
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
@@ -749,9 +819,9 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
if(ret != 0) {
return ret;
}
- cau_des_encrypt(temp_block , (byte*)des->key[0], out + offset);
- cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
- cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
+ MMCAU_DES_EncryptEcb(temp_block , (byte*)des->key[0], out + offset);
+ MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset);
+ MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset);
wolfSSL_CryptHwMutexUnLock();
len -= DES_BLOCK_SIZE;
@@ -776,11 +846,6 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
iv = (byte*)des->reg;
- if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
- WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment");
- return BAD_ALIGN_E;
- }
-
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
@@ -789,9 +854,9 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
if(ret != 0) {
return ret;
}
- cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset);
- cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
- cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
+ MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset);
+ MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset);
+ MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset);
wolfSSL_CryptHwMutexUnLock();
/* XOR block with IV for CBC */
diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c
index 1e339273a..d9ba8ac03 100644
--- a/wolfcrypt/src/dsa.c
+++ b/wolfcrypt/src/dsa.c
@@ -359,20 +359,26 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
byte* tmp = out; /* initial output pointer */
sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q));
-
- /* generate k */
- ret = wc_RNG_GenerateBlock(rng, buffer, sz);
- if (ret != 0)
- return ret;
-
- buffer[0] |= 0x0C;
-
+
if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
return MP_INIT_E;
- if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
- ret = MP_READ_E;
+ do {
+ /* generate k */
+ ret = wc_RNG_GenerateBlock(rng, buffer, sz);
+ if (ret != 0)
+ return ret;
+ buffer[0] |= 0x0C;
+
+ if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
+ ret = MP_READ_E;
+
+ /* k is a random numnber and it should be less than q
+ * if k greater than repeat
+ */
+ } while (mp_cmp(&k, &key->q) != MP_LT);
+
if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT)
ret = MP_CMP_E;
diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c
index 703f0f3df..4e53d8938 100644
--- a/wolfcrypt/src/ecc.c
+++ b/wolfcrypt/src/ecc.c
@@ -103,6 +103,10 @@ ECC Curve Sizes:
#include
#endif
+#if defined(FREESCALE_LTC_ECC)
+ #include
+#endif
+
#ifdef USE_FAST_MATH
#define GEN_MEM_ERR FP_MEM
#else
@@ -1645,6 +1649,7 @@ done:
return err;
}
+#if !defined(FREESCALE_LTC_ECC)
#ifndef ECC_TIMING_RESISTANT
@@ -2122,6 +2127,8 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
#endif /* ! FP_ECC */
#endif /* ECC_TIMING_RESISTANT */
+#endif /* !FREESCALE_LTC_ECC */
+
#ifdef ALT_ECC_SIZE
@@ -2424,7 +2431,8 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point,
err = mp_read_radix(&a, private_key->dp->Af, 16);
if (err == MP_OKAY)
- err = wc_ecc_mulmod(&private_key->k, point, result, &a, &prime, 1);
+ err = wc_ecc_mulmod_ex(&private_key->k, point, result, &a, &prime, 1,
+ private_key->heap);
if (err == MP_OKAY) {
x = mp_unsigned_bin_size(&prime);
@@ -2580,6 +2588,12 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
err = mp_mod(&key->k, &order, &key->k);
}
+ /* the key should be smaller than the order of base point */
+ if (err == MP_OKAY) {
+ if (mp_cmp(&key->k, &order) != MP_LT)
+ err = mp_mod(&key->k, &order, &key->k);
+ }
+
/* make the public key */
if (err == MP_OKAY)
err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey, &a, &prime, 1,
@@ -3363,6 +3377,15 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
if (err == MP_OKAY)
err = mp_copy(key->pubkey.z, mQ->z);
+#ifdef FREESCALE_LTC_ECC
+ /* use PKHA to compute u1*mG + u2*mQ */
+ if (err == MP_OKAY)
+ err = wc_ecc_mulmod_ex(&u1, mG, mG, &a, &modulus, 0, NULL);
+ if (err == MP_OKAY)
+ err = wc_ecc_mulmod_ex(&u2, mQ, mQ, &a, &modulus, 0, NULL);
+ if (err == MP_OKAY)
+ err = wc_ecc_point_add(mG, mQ, mG, &modulus);
+#else /* FREESCALE_LTC_ECC */
#ifndef ECC_SHAMIR
{
mp_digit mp;
@@ -3390,7 +3413,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
if (err == MP_OKAY)
err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &a, &modulus, key->heap);
#endif /* ECC_SHAMIR */
-
+#endif /* FREESCALE_LTC_ECC */
/* v = X_x1 mod n */
if (err == MP_OKAY)
err = mp_mod(mG->x, &order, &v);
@@ -5639,6 +5662,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
}
#endif /* ECC_SHAMIR */
+#if !defined(FREESCALE_LTC_TFM)
/** ECC Fixed Point mulmod global
k The multiplicand
G Base point to multiply
@@ -5654,7 +5678,7 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
{
return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
}
-
+#endif /* !FREESCALE_LTC_TFM */
/** ECC Fixed Point mulmod global
k The multiplicand
diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c
index 9eb86da23..310b6cfd6 100644
--- a/wolfcrypt/src/ed25519.c
+++ b/wolfcrypt/src/ed25519.c
@@ -41,6 +41,10 @@
#include
#endif
+#ifdef FREESCALE_LTC_ECC
+ #include
+#endif
+
/* generate an ed25519 key pair.
* returns 0 on success
*/
@@ -48,7 +52,9 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
{
byte az[ED25519_PRV_KEY_SIZE];
int ret;
+#if !defined(FREESCALE_LTC_ECC)
ge_p3 A;
+#endif
if (rng == NULL || key == NULL)
return BAD_FUNC_ARG;
@@ -71,9 +77,16 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
az[31] |= 64;
+#ifdef FREESCALE_LTC_ECC
+ ltc_pkha_ecc_point_t publicKey = {0};
+ publicKey.X = key->pointX;
+ publicKey.Y = key->pointY;
+ LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az, ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */);
+ LTC_PKHA_Ed25519_Compress(&publicKey, key->p);
+#else
ge_scalarmult_base(&A, az);
ge_p3_tobytes(key->p, &A);
-
+#endif
/* put public key after private key, on the same buffer */
XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
@@ -94,8 +107,12 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
word32 *outLen, ed25519_key* key)
{
+#ifdef FREESCALE_LTC_ECC
+ byte tempBuf[ED25519_PRV_KEY_SIZE];
+#else
ge_p3 R;
- byte nonce[SHA512_DIGEST_SIZE];
+#endif
+ byte nonce[SHA512_DIGEST_SIZE];
byte hram[SHA512_DIGEST_SIZE];
byte az[ED25519_PRV_KEY_SIZE];
Sha512 sha;
@@ -136,12 +153,21 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
if (ret != 0)
return ret;
+#ifdef FREESCALE_LTC_ECC
+ ltc_pkha_ecc_point_t ltcPoint = {0};
+ ltcPoint.X = &tempBuf[0];
+ ltcPoint.Y = &tempBuf[32];
+ LTC_PKHA_sc_reduce(nonce);
+ LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce, ED25519_KEY_SIZE, <cPoint, kLTC_Ed25519 /* result on Ed25519 */);
+ LTC_PKHA_Ed25519_Compress(<cPoint, out);
+#else
sc_reduce(nonce);
/* step 2: computing R = rB where rB is the scalar multiplication of
r and B */
ge_scalarmult_base(&R,nonce);
ge_p3_tobytes(out,&R);
+#endif
/* step 3: hash R + public key + message getting H(R,A,M) then
creating S = (r + H(R,A,M)a) mod l */
@@ -161,8 +187,13 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
if (ret != 0)
return ret;
+#ifdef FREESCALE_LTC_ECC
+ LTC_PKHA_sc_reduce(hram);
+ LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
+#else
sc_reduce(hram);
sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
+#endif
return ret;
}
@@ -184,8 +215,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
{
byte rcheck[ED25519_KEY_SIZE];
byte h[SHA512_DIGEST_SIZE];
+#ifndef FREESCALE_LTC_ECC
ge_p3 A;
ge_p2 R;
+#endif
int ret;
Sha512 sha;
@@ -201,8 +234,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
return BAD_FUNC_ARG;
/* uncompress A (public key), test if valid, and negate it */
+#ifndef FREESCALE_LTC_ECC
if (ge_frombytes_negate_vartime(&A, key->p) != 0)
return BAD_FUNC_ARG;
+#endif
/* find H(R,A,M) and store it as h */
ret = wc_InitSha512(&sha);
@@ -221,6 +256,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
if (ret != 0)
return ret;
+#ifdef FREESCALE_LTC_ECC
+ LTC_PKHA_sc_reduce(h);
+ LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key);
+#else
sc_reduce(h);
/*
@@ -232,6 +271,7 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
return ret;
ge_tobytes(rcheck, &R);
+#endif /* FREESCALE_LTC_ECC */
/* comparison of R created to R in sig */
ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
@@ -319,14 +359,32 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
if (in[0] == 0x40 && inLen > ED25519_PUB_KEY_SIZE) {
/* key is stored in compressed format so just copy in */
XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
+#ifdef FREESCALE_LTC_ECC
+ /* recover X coordinate */
+ ltc_pkha_ecc_point_t pubKey;
+ pubKey.X = key->pointX;
+ pubKey.Y = key->pointY;
+ LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
+#endif
return 0;
}
/* importing uncompressed public key */
if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
+#ifdef FREESCALE_LTC_ECC
+ /* reverse bytes for little endian byte order */
+ for (int i = 0; i < ED25519_KEY_SIZE; i++)
+ {
+ key->pointX[i] = *(in + ED25519_KEY_SIZE - i);
+ key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
+ }
+ XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
+ ret = 0;
+#else
/* pass in (x,y) and store compressed key */
ret = ge_compress_key(key->p, in+1,
in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
+#endif /* FREESCALE_LTC_ECC */
return ret;
}
@@ -334,6 +392,13 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
if key size is equal to compressed key size copy in key */
if (inLen == ED25519_PUB_KEY_SIZE) {
XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
+#ifdef FREESCALE_LTC_ECC
+ /* recover X coordinate */
+ ltc_pkha_ecc_point_t pubKey;
+ pubKey.X = key->pointX;
+ pubKey.Y = key->pointY;
+ LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
+#endif
return 0;
}
diff --git a/wolfcrypt/src/fe_low_mem.c b/wolfcrypt/src/fe_low_mem.c
index 0fe6158a0..9caffa81f 100644
--- a/wolfcrypt/src/fe_low_mem.c
+++ b/wolfcrypt/src/fe_low_mem.c
@@ -130,7 +130,7 @@ static void xc_diffadd(byte *x5, byte *z5,
fe_mul__distinct(z5, x1, b);
}
-
+#ifndef FREESCALE_LTC_ECC
int curve25519(byte *result, byte *e, byte *q)
{
/* Current point: P_m */
@@ -174,7 +174,7 @@ int curve25519(byte *result, byte *e, byte *q)
fe_normalize(result);
return 0;
}
-
+#endif /* !FREESCALE_LTC_ECC */
static void raw_add(byte *x, const byte *p)
{
diff --git a/wolfcrypt/src/fe_operations.c b/wolfcrypt/src/fe_operations.c
index 1a387ce37..9dfeab093 100644
--- a/wolfcrypt/src/fe_operations.c
+++ b/wolfcrypt/src/fe_operations.c
@@ -107,7 +107,7 @@ void fe_0(fe h)
h[9] = 0;
}
-
+#ifndef FREESCALE_LTC_ECC
int curve25519(byte* q, byte* n, byte* p)
{
#if 0
@@ -183,7 +183,7 @@ int curve25519(byte* q, byte* n, byte* p)
return 0;
}
-
+#endif /* !FREESCALE_LTC_ECC */
/*
h = f * f
diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am
index 111ad6331..5c76a03b6 100644
--- a/wolfcrypt/src/include.am
+++ b/wolfcrypt/src/include.am
@@ -45,8 +45,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/ti/ti-ccm.c \
wolfcrypt/src/port/pic32/pic32mz-hash.c \
wolfcrypt/src/port/nrf51.c \
+ wolfcrypt/src/port/arm/armv8-aes.c \
wolfcrypt/src/port/arm/armv8-sha256.c \
- wolfcrypt/src/port/arm/armv8-aes.c
+ wolfssl/wolfcrypt/port/nxp/ksdk_port.c
if BUILD_CAVIUM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c
diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c
index dfda77915..80ea23d8d 100644
--- a/wolfcrypt/src/md5.c
+++ b/wolfcrypt/src/md5.c
@@ -49,8 +49,8 @@
#include
#endif
-#ifdef FREESCALE_MMCAU
- #include "cau_api.h"
+#ifdef FREESCALE_MMCAU_SHA
+ #include "fsl_mmcau.h"
#define XTRANSFORM(S,B) Transform((S), (B))
#else
#define XTRANSFORM(S,B) Transform((S))
@@ -195,19 +195,19 @@ void wc_InitMd5(Md5* md5)
md5->hiLen = 0;
}
-#ifdef FREESCALE_MMCAU
+#ifdef FREESCALE_MMCAU_SHA
static int Transform(Md5* md5, byte* data)
{
int ret = wolfSSL_CryptHwMutexLock();
if(ret == 0) {
- cau_md5_hash_n(data, 1, (unsigned char*)md5->digest);
+ MMCAU_MD5_HashN(data, 1, (uint32_t*)(md5->digest));
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
-#endif /* FREESCALE_MMCAU */
+#endif /* FREESCALE_MMCAU_SHA */
-#ifndef FREESCALE_MMCAU
+#ifndef FREESCALE_MMCAU_SHA
static void Transform(Md5* md5)
{
@@ -325,7 +325,7 @@ void wc_Md5Update(Md5* md5, const byte* data, word32 len)
len -= add;
if (md5->buffLen == MD5_BLOCK_SIZE) {
- #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
#endif
XTRANSFORM(md5, local);
@@ -349,7 +349,7 @@ void wc_Md5Final(Md5* md5, byte* hash)
XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen);
md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen;
- #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
#endif
XTRANSFORM(md5, local);
@@ -363,7 +363,7 @@ void wc_Md5Final(Md5* md5, byte* hash)
md5->loLen = md5->loLen << 3;
/* store lengths */
- #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE);
#endif
/* ! length ordering dependent on digest endian type ! */
diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c
new file mode 100755
index 000000000..ac4d579b2
--- /dev/null
+++ b/wolfcrypt/src/port/nxp/ksdk_port.c
@@ -0,0 +1,1625 @@
+/* ksdk_port.c
+ *
+ * Copyright (C) 2006-2016 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 2 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
+#endif
+
+/* in case user set USE_FAST_MATH there */
+#include
+#ifdef NO_INLINE
+ #include
+#else
+ #define WOLFSSL_MISC_INCLUDED
+ #include
+#endif
+
+/* If FREESCALE_LTC_TFM or FREESCALE_LTC_ECC */
+#if (defined(USE_FAST_MATH) && defined(FREESCALE_LTC_TFM)) ||\
+ defined(FREESCALE_LTC_ECC)
+
+#include
+#include
+#include
+#include
+#include
+
+#define ERROR_OUT(err) { ret = (err); goto done; }
+
+
+int ksdk_port_init(void)
+{
+#if defined(USE_FAST_MATH) && defined(FREESCALE_LTC_TFM)
+ LTC_Init(LTC0);
+#endif
+
+ return 0;
+}
+
+
+/* LTC TFM */
+#if defined(USE_FAST_MATH) && defined(FREESCALE_LTC_TFM)
+#include
+
+/* Reverse array in memory (in place) */
+static void ltc_reverse_array(uint8_t *src, size_t src_len)
+{
+ int i;
+
+ for (i = 0; i < src_len / 2; i++) {
+ uint8_t tmp;
+
+ tmp = src[i];
+ src[i] = src[src_len - 1 - i];
+ src[src_len - 1 - i] = tmp;
+ }
+}
+
+/* same as fp_to_unsigned_bin() with fp_reverse() skipped */
+static void fp_to_unsigned_lsb_bin(fp_int *a, unsigned char *b)
+{
+ fp_int t;
+
+ fp_init_copy(&t, a);
+
+ (void)fp_to_unsigned_bin_at_pos(0, &t, b);
+}
+
+static void ltc_get_lsb_bin_from_mp_int(uint8_t *dst, mp_int *A, uint16_t *psz)
+{
+ uint16_t sz;
+
+ sz = mp_unsigned_bin_size(A);
+ fp_to_unsigned_lsb_bin(A, dst); /* result is lsbyte at lowest addr as required by LTC */
+ *psz = sz;
+}
+
+/* these function are used by wolfSSL upper layers (like RSA) */
+
+/* c = a * b */
+void fp_mul(fp_int *A, fp_int *B, fp_int *C)
+{
+ int szA, szB;
+ szA = fp_unsigned_bin_size(A);
+ szB = fp_unsigned_bin_size(B);
+
+ /* if unsigned mul can fit into LTC PKHA let's use it, otherwise call software mul */
+ if ((szA <= LTC_MAX_INT_BYTES / 2) && (szB <= LTC_MAX_INT_BYTES / 2)) {
+ int neg;
+
+ neg = (A->sign == B->sign) ? FP_ZPOS : FP_NEG;
+
+ /* unsigned multiply */
+ uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+
+ if (ptrA && ptrB && ptrC) {
+ uint16_t sizeA, sizeB;
+
+ ltc_get_lsb_bin_from_mp_int(ptrA, A, &sizeA);
+ ltc_get_lsb_bin_from_mp_int(ptrB, B, &sizeB);
+ XMEMSET(ptrC, 0xFF, LTC_MAX_INT_BYTES);
+
+ LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, LTC_MAX_INT_BYTES, ptrB, &sizeB,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+
+ ltc_reverse_array(ptrB, sizeB);
+ mp_read_unsigned_bin(C, ptrB, sizeB);
+ }
+
+ /* fix sign */
+ C->sign = neg;
+ if (ptrA) {
+ XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrB) {
+ XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrC) {
+ XFREE(ptrC, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ return;
+ }
+ else {
+ wolfcrypt_fp_mul(A, B, C);
+ }
+}
+
+/* c = a mod b, 0 <= c < b */
+int fp_mod(fp_int *a, fp_int *b, fp_int *c)
+{
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ int szA, szB;
+ szA = fp_unsigned_bin_size(a);
+ szB = fp_unsigned_bin_size(b);
+ if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES))
+ {
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+ int res = FP_OKAY;
+ int neg;
+
+ uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+
+ /* get sign for the result */
+ neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG;
+
+ /* get remainder of unsigned a divided by unsigned b */
+ if (ptrA && ptrB && ptrC) {
+ uint16_t sizeA, sizeB, sizeC;
+
+ ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA);
+ ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB);
+
+ if (kStatus_Success ==
+ LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith))
+ {
+ ltc_reverse_array(ptrC, sizeC);
+ mp_read_unsigned_bin(c, ptrC, sizeC);
+ }
+ else {
+ res = FP_VAL;
+ }
+ }
+ else {
+ res = FP_MEM;
+ }
+
+ /* fix sign */
+ c->sign = neg;
+
+ if (ptrA) {
+ XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrB) {
+ XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrC) {
+ XFREE(ptrC, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ return res;
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ }
+ else {
+ return wolfcrypt_fp_mod(a, b, c);
+ }
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+}
+
+/* c = 1/a (mod b) for odd b only */
+int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
+{
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ int szA, szB;
+ szA = fp_unsigned_bin_size(a);
+ szB = fp_unsigned_bin_size(b);
+ if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) {
+#endif
+ int res = FP_OKAY;
+
+ uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+
+ if (ptrA && ptrB && ptrC) {
+ uint16_t sizeA, sizeB, sizeC;
+
+ ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA);
+ ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB);
+
+ if (kStatus_Success ==
+ LTC_PKHA_ModInv(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith))
+ {
+ ltc_reverse_array(ptrC, sizeC);
+ mp_read_unsigned_bin(c, ptrC, sizeC);
+ }
+ else {
+ res = FP_VAL;
+ }
+ }
+ else {
+ res = FP_MEM;
+ }
+
+ c->sign = a->sign;
+ if (ptrA) {
+ XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrB) {
+ XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrC) {
+ XFREE(ptrC, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ return res;
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ }
+ else {
+ return wolfcrypt_fp_invmod(a, b, c);
+ }
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+}
+
+/* d = a * b (mod c) */
+int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
+{
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ int szA, szB, szC;
+ szA = fp_unsigned_bin_size(a);
+ szB = fp_unsigned_bin_size(b);
+ szC = fp_unsigned_bin_size(c);
+ if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) {
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+ int res = FP_OKAY;
+ fp_int t;
+
+ uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrD = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT);
+
+ /* if A or B is negative, substracta abs(A) or abs(B) from modulus to get positive integer representation of the
+ * same number */
+ fp_init(&t);
+ if (a->sign) {
+ fp_add(a, c, &t);
+ fp_copy(&t, a);
+ }
+ if (b->sign) {
+ fp_add(b, c, &t);
+ fp_copy(&t, b);
+ }
+
+ if (ptrA && ptrB && ptrC && ptrD) {
+ uint16_t sizeA, sizeB, sizeC, sizeD;
+
+ ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA);
+ ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB);
+ ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC);
+
+ /* (A*B)mod C = ((A mod C) * (B mod C)) mod C */
+ if (LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrC, sizeC) >= 0) {
+ if (kStatus_Success !=
+ LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrC, sizeC, ptrA, &sizeA, kLTC_PKHA_IntegerArith))
+ {
+ res = FP_VAL;
+ }
+ }
+ if ((FP_OKAY == res) && (LTC_PKHA_CompareBigNum(ptrB, sizeB, ptrC, sizeC) >= 0))
+ {
+ if (kStatus_Success !=
+ LTC_PKHA_ModRed(LTC_BASE, ptrB, sizeB, ptrC, sizeC, ptrB, &sizeB, kLTC_PKHA_IntegerArith))
+ {
+ res = FP_VAL;
+ }
+ }
+
+ if (FP_OKAY == res) {
+ if (kStatus_Success != LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, sizeC, ptrD, &sizeD,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized))
+ {
+ res = FP_VAL;
+ }
+ }
+
+ if (FP_OKAY == res) {
+ ltc_reverse_array(ptrD, sizeD);
+ mp_read_unsigned_bin(d, ptrD, sizeD);
+ }
+ }
+ else {
+ res = FP_MEM;
+ }
+
+ if (ptrA) {
+ XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrB) {
+ XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrC) {
+ XFREE(ptrC, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrD) {
+ XFREE(ptrD, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ return res;
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ }
+ else {
+ return wolfcrypt_fp_mulmod(a, b, c, d);
+ }
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+}
+
+/* Y = G^X mod P */
+int _fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y)
+{
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ int szA, szB, szC;
+ fp_int tmp;
+ int err;
+
+ /* if G cannot fit into LTC_PKHA, reduce it */
+ szA = fp_unsigned_bin_size(G);
+ if (szA > LTC_MAX_INT_BYTES) {
+ fp_init(&tmp);
+ if ((err = fp_mod(G, P, &tmp)) != FP_OKAY) {
+ return err;
+ }
+ G = &tmp;
+ szA = fp_unsigned_bin_size(G);
+ }
+
+ szB = fp_unsigned_bin_size(X);
+ szC = fp_unsigned_bin_size(P);
+
+ if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) {
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+ int res = FP_OKAY;
+ fp_int t;
+
+ uint16_t sizeG, sizeX, sizeP;
+ uint8_t *ptrG = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrX = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+ uint8_t *ptrP = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT);
+
+ /* if G is negative, add modulus to convert to positive number for LTC */
+ fp_init(&t);
+ if (G->sign) {
+ fp_add(G, P, &t);
+ fp_copy(&t, G);
+ }
+
+ if (ptrG && ptrX && ptrP) {
+ ltc_get_lsb_bin_from_mp_int(ptrG, G, &sizeG);
+ ltc_get_lsb_bin_from_mp_int(ptrX, X, &sizeX);
+ ltc_get_lsb_bin_from_mp_int(ptrP, P, &sizeP);
+
+ /* if number if greater that modulo, we must first reduce due to LTC requirement on modular exponentiaton */
+ /* it needs number less than modulus. */
+ /* we can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C
+ and so we do first (A mod N) : LTC does not give size requirement on A versus N,
+ and then the modular exponentiation.
+ */
+ /* if G >= P then */
+ if (LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, sizeP) >= 0) {
+ res = (int)LTC_PKHA_ModRed(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrG, &sizeG, kLTC_PKHA_IntegerArith);
+
+ if (res != kStatus_Success) {
+ res = FP_VAL;
+ }
+ }
+
+ if (FP_OKAY == res) {
+ res = (int)LTC_PKHA_ModExp(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrX, sizeX, ptrP, &sizeP,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+ if (res != kStatus_Success) {
+ res = FP_VAL;
+ }
+ else {
+ ltc_reverse_array(ptrP, sizeP);
+ mp_read_unsigned_bin(Y, ptrP, sizeP);
+ }
+ }
+ }
+ else {
+ res = FP_MEM;
+ }
+
+ if (ptrG) {
+ XFREE(ptrG, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrX) {
+ XFREE(ptrX, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ if (ptrP) {
+ XFREE(ptrP, NULL, DYNAMIC_TYPE_BIGINT);
+ }
+ return res;
+#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE)
+ }
+ else {
+ return _wolfcrypt_fp_exptmod(G, X, P, Y);
+ }
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+}
+
+#endif /* USE_FAST_MATH && FREESCALE_LTC_TFM */
+
+
+/* ECC */
+#if defined(HAVE_ECC) && defined(FREESCALE_LTC_ECC)
+
+/* convert from mp_int to LTC integer, as array of bytes of size sz.
+ * if mp_int has less bytes than sz, add zero bytes at most significant byte positions.
+ * This is when for example modulus is 32 bytes (P-256 curve)
+ * and mp_int has only 31 bytes, we add leading zeroes
+ * so that result array has 32 bytes, same as modulus (sz).
+ */
+static void ltc_get_from_mp_int(uint8_t *dst, mp_int *a, int sz)
+{
+ int szbin;
+ int offset;
+
+ /* check how many bytes are in the mp_int */
+ szbin = mp_unsigned_bin_size(a);
+
+ /* compute offset from dst */
+ offset = sz - szbin;
+ if (offset < 0)
+ offset = 0;
+ if (offset > sz)
+ offset = sz;
+
+ /* add leading zeroes */
+ if (offset)
+ XMEMSET(dst, 0, offset);
+
+ /* convert mp_int to array of bytes */
+ mp_to_unsigned_bin(a, dst + offset);
+
+ /* reverse array for LTC direct use */
+ ltc_reverse_array(dst, sz);
+}
+
+/* ECC specs in lsbyte at lowest address format for direct use by LTC PKHA driver functions */
+#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+#define ECC192
+#endif
+#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+#define ECC224
+#endif
+#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+#define ECC256
+#endif
+#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+#define ECC384
+#endif
+
+/* P-256 */
+#ifdef ECC256
+static const uint8_t ltc_ecc256_modulus[32] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc256_r2modn[32] = {
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00};
+static const uint8_t ltc_ecc256_aCurveParam[32] = {
+ 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc256_bCurveParam[32] = {
+ 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B, 0xF6, 0xB0, 0x53,
+ 0xCC, 0xB0, 0x06, 0x1D, 0x65, 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD,
+ 0xEB, 0xB3, 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A};
+#endif
+
+#ifdef ECC192
+static const uint8_t ltc_ecc192_modulus[24] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc192_r2modn[24] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t ltc_ecc192_aCurveParam[24] = {
+ 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc192_bCurveParam[24] = {
+ 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE, 0x49, 0x30, 0x24, 0x72,
+ 0xAB, 0xE9, 0xA7, 0x0F, 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64};
+#endif
+
+#ifdef ECC224
+static const uint8_t ltc_ecc224_modulus[28] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc224_r2modn[28] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t ltc_ecc224_aCurveParam[28] = {
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t ltc_ecc224_bCurveParam[28] = {
+ 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27, 0xBA, 0xD8,
+ 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50, 0x56, 0x32, 0x41, 0xF5,
+ 0xAB, 0xB3, 0x04, 0x0C, 0x85, 0x0A, 0x05, 0xB4};
+#endif
+
+#ifdef ECC384
+static const uint8_t ltc_ecc384_modulus[48] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+static const uint8_t ltc_ecc384_r2modn[48] = {
+ 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t ltc_ecc384_aCurveParam[48] = {
+ 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+static const uint8_t ltc_ecc384_bCurveParam[48] = {
+ 0xef, 0x2a, 0xec, 0xd3, 0xed, 0xc8, 0x85, 0x2a, 0x9d, 0xd1, 0x2e, 0x8a,
+ 0x8d, 0x39, 0x56, 0xc6, 0x5a, 0x87, 0x13, 0x50, 0x8f, 0x08, 0x14, 0x03,
+ 0x12, 0x41, 0x81, 0xfe, 0x6e, 0x9c, 0x1d, 0x18, 0x19, 0x2d, 0xf8, 0xe3,
+ 0x6b, 0x05, 0x8e, 0x98, 0xe4, 0xe7, 0x3e, 0xe2, 0xa7, 0x2f, 0x31, 0xb3};
+#endif
+
+static int ltc_get_ecc_specs(const uint8_t **modulus, const uint8_t **r2modn,
+ const uint8_t **aCurveParam, const uint8_t **bCurveParam, int size)
+{
+ switch(size) {
+ case 32:
+ *modulus = ltc_ecc256_modulus;
+ *r2modn = ltc_ecc256_r2modn;
+ *aCurveParam = ltc_ecc256_aCurveParam;
+ *bCurveParam = ltc_ecc256_bCurveParam;
+ break;
+#ifdef ECC224
+ case 28:
+ *modulus = ltc_ecc224_modulus;
+ *r2modn = ltc_ecc224_r2modn;
+ *aCurveParam = ltc_ecc224_aCurveParam;
+ *bCurveParam = ltc_ecc224_bCurveParam;
+ break;
+#endif
+#ifdef ECC192
+ case 24:
+ *modulus = ltc_ecc192_modulus;
+ *r2modn = ltc_ecc192_r2modn;
+ *aCurveParam = ltc_ecc192_aCurveParam;
+ *bCurveParam = ltc_ecc192_bCurveParam;
+ break;
+#endif
+#ifdef HAVE_ECC384
+ case 48:
+ *modulus = ltc_ecc384_modulus;
+ *r2modn = ltc_ecc384_r2modn;
+ *aCurveParam = ltc_ecc384_aCurveParam;
+ *bCurveParam = ltc_ecc384_bCurveParam;
+ break;
+#endif
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ Perform a point multiplication (timing resistant)
+ k The scalar to multiply by
+ G The base point
+ R [out] Destination for kG
+ modulus The modulus of the field the ECC curve is in
+ map Boolean whether to map back to affine or not
+ (1==map, 0 == leave in projective)
+ return MP_OKAY on success
+*/
+int wc_ecc_mulmod_ex(mp_int *k, ecc_point *G, ecc_point *R, mp_int* a,
+ mp_int *modulus, int map, void* heap)
+{
+ ltc_pkha_ecc_point_t B;
+ uint8_t size;
+ int szModulus;
+ int szkbin;
+ bool point_of_infinity;
+ status_t status;
+
+ (void)a;
+
+ uint8_t Gxbin[LTC_MAX_ECC_BITS / 8];
+ uint8_t Gybin[LTC_MAX_ECC_BITS / 8];
+ uint8_t kbin[LTC_MAX_INT_BYTES];
+
+ const uint8_t *modbin;
+ const uint8_t *aCurveParam;
+ const uint8_t *bCurveParam;
+ const uint8_t *r2modn;
+
+ if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
+ return ECC_BAD_ARG_E;
+ }
+
+ szModulus = mp_unsigned_bin_size(modulus);
+ szkbin = mp_unsigned_bin_size(k);
+
+ ltc_get_from_mp_int(kbin, k, szkbin);
+ ltc_get_from_mp_int(Gxbin, G->x, szModulus);
+ ltc_get_from_mp_int(Gybin, G->y, szModulus);
+
+ size = szModulus;
+ /* find LTC friendly parameters for the selected curve */
+ if (0 != ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size)) {
+ return ECC_BAD_ARG_E;
+ }
+
+ B.X = &Gxbin[0];
+ B.Y = &Gybin[0];
+
+ status = LTC_PKHA_ECC_PointMul(LTC_BASE, &B, kbin, szkbin, modbin, r2modn, aCurveParam, bCurveParam, size,
+ kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, &B, &point_of_infinity);
+ if (status != kStatus_Success) {
+ return FP_VAL;
+ }
+
+ ltc_reverse_array(Gxbin, size);
+ ltc_reverse_array(Gybin, size);
+ mp_read_unsigned_bin(R->x, Gxbin, size);
+ mp_read_unsigned_bin(R->y, Gybin, size);
+ /* if k is negative, we compute the multiplication with abs(-k)
+ * with result (x, y) and modify the result to (x, -y)
+ */
+ R->y->sign = k->sign;
+ mp_set(R->z, 1);
+
+ return MP_OKAY;
+}
+
+int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m)
+{
+ int err;
+ ltc_pkha_ecc_point_t A, B;
+ int size;
+ status_t status;
+
+ uint8_t Gxbin[LTC_MAX_ECC_BITS / 8];
+ uint8_t Gybin[LTC_MAX_ECC_BITS / 8];
+ uint8_t Qxbin[LTC_MAX_ECC_BITS / 8];
+ uint8_t Qybin[LTC_MAX_ECC_BITS / 8];
+ const uint8_t *modbin;
+ const uint8_t *aCurveParam;
+ const uint8_t *bCurveParam;
+ const uint8_t *r2modn;
+
+ size = mp_unsigned_bin_size(m);
+ /* find LTC friendly parameters for the selected curve */
+ if (0 != ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size)) {
+ err = ECC_BAD_ARG_E;
+ }
+ else {
+ ltc_get_from_mp_int(Gxbin, mG->x, size);
+ ltc_get_from_mp_int(Gybin, mG->y, size);
+ ltc_get_from_mp_int(Qxbin, mQ->x, size);
+ ltc_get_from_mp_int(Qybin, mQ->y, size);
+
+ A.X = Gxbin;
+ A.Y = Gybin;
+
+ B.X = Qxbin;
+ B.Y = Qybin;
+
+ status = LTC_PKHA_ECC_PointAdd(LTC_BASE, &A, &B, modbin, r2modn, aCurveParam, bCurveParam, size,
+ kLTC_PKHA_IntegerArith, &A);
+ if (status != kStatus_Success) {
+ err = FP_VAL;
+ }
+ else {
+ ltc_reverse_array(Gxbin, size);
+ ltc_reverse_array(Gybin, size);
+ mp_read_unsigned_bin(mR->x, Gxbin, size);
+ mp_read_unsigned_bin(mR->y, Gybin, size);
+ mp_set(mR->z, 1);
+ err = MP_OKAY;
+ }
+ }
+ return err;
+}
+
+#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519)
+/* Weierstrass parameters of prime 2^255 - 19 */
+static const uint8_t modbin[32] = {
+ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+/* precomputed R2modN for the curve25519 */
+static const uint8_t r2mod[32] = {
+ 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+/* invThree = ModInv(3,modbin) in LSB first */
+static const uint8_t invThree[32] = {
+ 0x49, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+
+/*
+ *
+ * finds square root in finite field when modulus congruent to 5 modulo 8
+ * this is fixed to curve25519 modulus 2^255 - 19 which is congruent to 5 modulo 8
+ *
+ * This function solves equation: res^2 = a mod (2^255 - 19)
+ *
+p = prime
+p % 8 must be 5
+
+v = ModularArithmetic.powmod(2*a, (p-5)/8, p)
+i = (2*a*v**2) % p
+r1 = 1*a*v*(i - 1) % p
+r2 = -1*a*v*(i - 1) % p
+puts "Gy=0x#{r2.to_s(16)}"
+ */
+status_t LTC_PKHA_Prime25519SquareRootMod(const uint8_t *A, size_t sizeA,
+ uint8_t *res, size_t *szRes, int sign)
+{
+ status_t status;
+ const uint8_t curve25519_param[] = {
+ 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f};
+ uint8_t twoA[sizeof(modbin)] = {0};
+ uint8_t V[sizeof(modbin)] = {0};
+ uint8_t I[sizeof(modbin)] = {0};
+ uint8_t VV[sizeof(modbin)] = {0};
+ uint16_t szTwoA = 0;
+ uint16_t szV = 0;
+ uint16_t szVV = 0;
+ uint16_t szI = 0;
+ uint16_t szRes16 = 0;
+ uint8_t one = 1;
+
+ /* twoA = 2*A % p */
+ status = LTC_PKHA_ModAdd(LTC_BASE, A, sizeA, A, sizeA, modbin,
+ sizeof(modbin), twoA, &szTwoA, kLTC_PKHA_IntegerArith);
+
+ /* V = ModularArithmetic.powmod(twoA, (p-5)/8, p) */
+ if (status == kStatus_Success) {
+ status =
+ LTC_PKHA_ModExp(LTC_BASE, twoA, szTwoA, modbin, sizeof(modbin),
+ curve25519_param, sizeof(curve25519_param), V, &szV,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* VV = V*V % p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, V, szV, V, szV, modbin,
+ sizeof(modbin), VV, &szVV, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* I = twoA * VV = 2*A*V*V % p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, twoA, szTwoA, VV, szVV, modbin,
+ sizeof(modbin), I, &szI, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* I = I - 1 */
+ XMEMSET(VV, 0xff, sizeof(VV)); /* just temp for maximum integer - for non-modular substract */
+ if (0 <= LTC_PKHA_CompareBigNum(I, szI, &one, sizeof(one))) {
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, I, szI, &one, sizeof(one),
+ VV, sizeof(VV), I, &szI);
+ }
+ }
+ else {
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), &one,
+ sizeof(one), VV, sizeof(VV), I, &szI);
+ }
+ }
+
+ /* res = a*v mod p */
+ status = LTC_PKHA_ModMul(LTC_BASE, A, sizeA, V, szV, modbin,
+ sizeof(modbin), res, &szRes16, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+
+ /* res = res * (i-1) mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, res, szRes16, I, szI, modbin,
+ sizeof(modbin), res, &szRes16, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* if X mod 2 != X_0 then we need the -X
+ *
+ * X mod 2 get from LSB bit0
+ */
+ if ((status == kStatus_Success) &&
+ ((bool)sign != (bool)(res[0] & 0x01u)))
+ {
+ status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), res,
+ szRes16, VV, sizeof(VV), res, &szRes16); /* -a = p - a */
+ }
+
+ if (status == kStatus_Success) {
+ *szRes = szRes16;
+ }
+
+ return status;
+}
+#endif /* HAVE_ED25519 || HAVE_CURVE25519 */
+
+
+#ifdef HAVE_CURVE25519
+
+/* for LTC we need Weierstrass format of curve25519 parameters
+ * these two are base point X and Y.
+ * in LSB first format (native for LTC)
+ */
+static const ECPoint ecBasePoint = {
+ {0x5a, 0x24, 0xad, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a},
+ {0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c,
+ 0x6d, 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd,
+ 0x1e, 0xe0, 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20},
+};
+
+const ECPoint *wc_curve25519_GetBasePoint(void)
+{
+ return &ecBasePoint;
+}
+
+static const uint8_t aCurveParam[CURVE25519_KEYSIZE] = {
+ 0x44, 0xa1, 0x14, 0x49, 0x98, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x2a};
+
+static const uint8_t bCurveParam[CURVE25519_KEYSIZE] = {
+ 0x64, 0xc8, 0x10, 0x77, 0x9c, 0x5e, 0x0b, 0x26, 0xb4, 0x97, 0xd0,
+ 0x5e, 0x42, 0x7b, 0x09, 0xed,
+ 0x25, 0xb4, 0x97, 0xd0, 0x5e, 0x42, 0x7b, 0x09, 0xed, 0x25, 0xb4,
+ 0x97, 0xd0, 0x5e, 0x42, 0x7b};
+
+/* transform a point on Montgomery curve to a point on Weierstrass curve */
+status_t LTC_PKHA_Curve25519ToWeierstrass(
+ const ltc_pkha_ecc_point_t *ltcPointIn,ltc_pkha_ecc_point_t *ltcPointOut)
+{
+ /* offset X point (in Montgomery) so that it becomes Weierstrass */
+ const uint8_t offset[] = {
+ 0x51, 0x24, 0xad, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a};
+ uint16_t sizeRes = 0;
+ status_t status;
+ status = LTC_PKHA_ModAdd(LTC_BASE, ltcPointIn->X, CURVE25519_KEYSIZE,
+ offset, sizeof(offset), modbin, CURVE25519_KEYSIZE, ltcPointOut->X,
+ &sizeRes, kLTC_PKHA_IntegerArith);
+
+ if (status == kStatus_Success) {
+ if (ltcPointOut->Y != ltcPointIn->Y) {
+ XMEMCPY(ltcPointOut->Y, ltcPointIn->Y, CURVE25519_KEYSIZE);
+ }
+ }
+
+ return status;
+}
+
+/* transform a point on Weierstrass curve to a point on Montgomery curve */
+status_t LTC_PKHA_WeierstrassToCurve25519(
+ const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut)
+{
+ status_t status;
+ uint16_t resultSize = 0;
+ const uint8_t three = 0x03;
+
+ status = LTC_PKHA_ModMul(LTC_BASE, &three, sizeof(three), ltcPointIn->X,
+ CURVE25519_KEYSIZE, modbin, CURVE25519_KEYSIZE, ltcPointOut->X,
+ &resultSize, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+ if (status == kStatus_Success) {
+ const uint8_t A[] = {0x06, 0x6d, 0x07};
+ if (LTC_PKHA_CompareBigNum(ltcPointOut->X, resultSize, A, sizeof(A))) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, ltcPointOut->X, resultSize, A,
+ sizeof(A), modbin, CURVE25519_KEYSIZE, ltcPointOut->X, &resultSize);
+ }
+ else {
+ status = LTC_PKHA_ModSub2(LTC_BASE, ltcPointOut->X, resultSize, A,
+ sizeof(A), modbin, CURVE25519_KEYSIZE, ltcPointOut->X, &resultSize);
+ }
+ }
+
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, invThree, CURVE25519_KEYSIZE,
+ ltcPointOut->X, resultSize, modbin, CURVE25519_KEYSIZE,
+ ltcPointOut->X, &resultSize, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ if (status == kStatus_Success) {
+ if (ltcPointOut->Y != ltcPointIn->Y) {
+ XMEMCPY(ltcPointOut->Y, ltcPointIn->Y, CURVE25519_KEYSIZE);
+ }
+ }
+
+ return status;
+}
+
+/* Y = square root (X^3 + 486662*X^2 + X) */
+status_t LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point_t *ltcPoint)
+{
+ uint8_t three = 3;
+ const uint8_t A[] = {0x06, 0x6d, 0x07};
+ uint8_t U[CURVE25519_KEYSIZE] = {0};
+ uint8_t X2[CURVE25519_KEYSIZE] = {0};
+ uint16_t sizeU = 0;
+ uint16_t sizeX2 = 0;
+ size_t szRes = 0;
+ status_t status;
+
+ /* X^3 */
+ status = LTC_PKHA_ModExp(LTC_BASE, ltcPoint->X, CURVE25519_KEYSIZE, modbin,
+ CURVE25519_KEYSIZE, &three, 1, U, &sizeU, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+
+ /* X^2 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, ltcPoint->X, CURVE25519_KEYSIZE,
+ ltcPoint->X, CURVE25519_KEYSIZE, modbin, CURVE25519_KEYSIZE, X2,
+ &sizeX2, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+
+ /* 486662*X^2 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, A, sizeof(A), X2, sizeX2, modbin,
+ CURVE25519_KEYSIZE, X2, &sizeX2, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* X^3 + 486662*X^2 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, U, sizeU, X2, sizeX2, modbin,
+ CURVE25519_KEYSIZE, U, &sizeU, kLTC_PKHA_IntegerArith);
+ }
+
+ /* U = X^3 + 486662*X^2 + X */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, U, sizeU, ltcPoint->X,
+ CURVE25519_KEYSIZE, modbin, CURVE25519_KEYSIZE, U, &sizeU,
+ kLTC_PKHA_IntegerArith);
+ }
+
+ /* Y = modular square root of U (U is Y^2) */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_Prime25519SquareRootMod(U, sizeU, ltcPoint->Y,
+ &szRes, 1);
+ }
+
+ return status;
+}
+
+/* Q = n*P */
+/* if type is set, the input point p is in Montgomery curve coordinates,
+ so there is a map to Weierstrass curve */
+/* q output point is always in Montgomery curve coordinates */
+int wc_curve25519(ECPoint *q, byte *n, const ECPoint *p, fsl_ltc_ecc_coordinate_system_t type)
+{
+ status_t status;
+ ltc_pkha_ecc_point_t ltcPoint;
+ ltc_pkha_ecc_point_t ltcPointOut;
+ ECPoint pIn = {{0}};
+
+ XMEMCPY(&pIn, p, sizeof(*p));
+ ltcPoint.X = &pIn.point[0];
+ ltcPoint.Y = &pIn.pointY[0];
+
+ /* if input point P is on Curve25519 Montgomery curve, transform
+ it to Weierstrass equivalent */
+ if (type == kLTC_Curve25519) {
+ LTC_PKHA_Curve25519ToWeierstrass(<cPoint, <cPoint);
+ }
+
+ ltcPointOut.X = &q->point[0];
+ ltcPointOut.Y = &q->pointY[0];
+ /* modbin, r2mod, aCurveParam, bCurveParam are Weierstrass equivalent
+ with Curve25519 */
+ status = LTC_PKHA_ECC_PointMul(LTC_BASE, <cPoint, n, CURVE25519_KEYSIZE,
+ modbin, r2mod, aCurveParam, bCurveParam, CURVE25519_KEYSIZE,
+ kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, <cPointOut, NULL);
+
+ /* now need to map from Weierstrass form to Montgomery form */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_WeierstrassToCurve25519(<cPointOut, <cPointOut);
+ }
+
+ return (status == kStatus_Success) ? 0 : IS_POINT_E;
+}
+
+#endif /* HAVE_CURVE25519 */
+
+
+#ifdef HAVE_ED25519
+/* a and d are Edwards curve parameters -1 and -121665/121666 prime is 2^255 - 19.
+ *
+ * https://en.wikipedia.org/wiki/Montgomery_curve#Equivalence_with_Edward_curves
+ */
+
+/* d parameter of ed25519 */
+static const uint8_t d_coefEd25519[] = {
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 0xab, 0xd8, 0x41,
+ 0x41, 0x4d, 0x0a, 0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40,
+ 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52};
+
+/* Montgomery curve parameter A for a Montgomery curve equivalent with ed25519 */
+static const uint8_t A_coefEd25519[] = {
+ 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+/* Montgomery curve parameter B for a Montgomery curve equivalent with ed25519 */
+static const uint8_t B_coefEd25519[] = {
+ 0xe5, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+
+/* these are pre-computed constants used in computations */
+
+/* = 3*B */
+static const uint8_t threeB_coefEd25519[] = {
+ 0xd5, 0xb8, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+
+/* = -A */
+static const uint8_t minus_A_coefEd25519[] = {
+ 0xe7, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
+
+/* = 1/B */
+static const uint8_t invB_coefEd25519[] = {
+0xc4, 0xa1, 0x29, 0x7b, 0x8d, 0x2c, 0x85, 0x22, 0xd5, 0x89, 0xaf,
+ 0xaf, 0x6c, 0xfd, 0xe3, 0xff, 0xd9, 0x85, 0x21, 0xa2, 0xe1, 0x2f,
+ 0xce, 0x1c, 0x63, 0x00, 0x24, 0x75, 0xc4, 0x24, 0x7f, 0x6b};
+
+/* = 1/(3*B) */
+static const uint8_t A_mul_invThreeB_coefEd25519[] = {
+ 0xb9, 0x3e, 0xe4, 0xad, 0xa1, 0x37, 0xa7, 0x93, 0x1c, 0xa4, 0x35,
+ 0xe0, 0x0c, 0x57, 0xbd, 0xaa, 0x6e, 0x51, 0x94, 0x3e, 0x14, 0xe0,
+ 0xcb, 0xec, 0xbd, 0xff, 0xe7, 0xb1, 0x27, 0x92, 0x00, 0x63};
+
+/* Weierstrass curve parameter a for a Weierstrass curve equivalent with ed25519 */
+static const uint8_t a_coefEd25519[] = {
+ 0x2d, 0x17, 0xbc, 0xf8, 0x8e, 0xe1, 0x71, 0xac, 0xf7, 0x2a, 0xa5,
+ 0x0c, 0x5d, 0xb6, 0xb8, 0x6b, 0xd6, 0x3d, 0x7b, 0x61, 0x0d, 0xe1,
+ 0x97, 0x31, 0xe6, 0xbe, 0xb9, 0xa5, 0xd3, 0xac, 0x4e, 0x5d};
+
+/* Weierstrass curve parameter b for a Weierstrass curve equivalent with ed25519 */
+static const uint8_t b_coefEd25519[] = {
+ 0xa4, 0xb2, 0x64, 0xf3, 0xc1, 0xeb, 0x04, 0x90, 0x32, 0xbc, 0x9f,
+ 0x6b, 0x97, 0x31, 0x48, 0xf5, 0xd5, 0x80, 0x57, 0x10, 0x06, 0xdb,
+ 0x0d, 0x55, 0xe0, 0xb3, 0xd0, 0xcf, 0x9b, 0xb2, 0x11, 0x1d};
+
+/* Ed25519 basepoint B mapped to Weierstrass equivalent */
+static uint8_t Wx_Ed25519[ED25519_KEY_SIZE] = {
+ 0x35, 0xef, 0x5a, 0x02, 0x9b, 0xc8, 0x55, 0xca, 0x9a, 0x7c, 0x61,
+ 0x0d, 0xdf, 0x3f, 0xc1, 0xa9, 0x18, 0x06, 0xc2, 0xf1, 0x02, 0x8f,
+ 0x0b, 0xf0, 0x39, 0x03, 0x2c, 0xd0, 0x0f, 0xdd, 0x78, 0x2a};
+static uint8_t Wy_Ed25519[ED25519_KEY_SIZE] = {
+ 0x14, 0x1d, 0x2c, 0xf6, 0xf3, 0x30, 0x78, 0x9b, 0x65, 0x31, 0x71,
+ 0x80, 0x61, 0xd0, 0x6f, 0xcf, 0x23, 0x83, 0x79, 0x63, 0xa5, 0x3b,
+ 0x48, 0xbe, 0x2e, 0xa2, 0x1d, 0xc7, 0xa5, 0x44, 0xc6, 0x29};
+
+static const ltc_pkha_ecc_point_t basepointEd25519 = {
+ Wx_Ed25519, Wy_Ed25519,
+};
+
+const ltc_pkha_ecc_point_t *LTC_PKHA_Ed25519_BasePoint(void)
+{
+ return &basepointEd25519;
+}
+
+/* input point is on Weierstrass curve, typeOut determines the coordinates
+ system of output point (either Weierstrass or Ed25519) */
+status_t LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point_t *ltcPointIn,
+ const uint8_t *N,
+ size_t sizeN,
+ ltc_pkha_ecc_point_t *ltcPointOut,
+ fsl_ltc_ecc_coordinate_system_t typeOut)
+{
+ uint16_t szN = (uint16_t)sizeN;
+ status_t status;
+ /* input on W, output in W, W parameters of ECC curve are Ed25519 curve
+ parameters mapped to Weierstrass curve */
+ status = LTC_PKHA_ECC_PointMul(LTC_BASE, ltcPointIn, N, szN, modbin,
+ r2mod, a_coefEd25519, b_coefEd25519, ED25519_KEY_SIZE,
+ kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, ltcPointOut, NULL);
+
+ /* Weierstrass coordinates to Ed25519 coordinates */
+ if ((status == kStatus_Success) && (typeOut == kLTC_Ed25519)) {
+ status = LTC_PKHA_WeierstrassToEd25519(ltcPointOut, ltcPointOut);
+ }
+ return status;
+}
+
+status_t LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn,
+ ltc_pkha_ecc_point_t *ltcPointOut)
+{
+ status_t status;
+ uint8_t Mx[ED25519_KEY_SIZE] = {0};
+ uint8_t My[ED25519_KEY_SIZE] = {0};
+ uint8_t temp[ED25519_KEY_SIZE] = {0};
+ uint8_t temp2[ED25519_KEY_SIZE] = {0};
+ const uint8_t max[32] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ const uint8_t *Ex;
+ const uint8_t *Ey;
+ uint8_t *Gx;
+ uint8_t *Gy;
+ uint16_t szMx = 0;
+ uint16_t szGx = 0;
+ uint16_t szMy = 0;
+ uint16_t szGy = 0;
+ uint16_t szTemp = 0;
+ uint16_t szTemp2 = 0;
+ uint8_t one = 1;
+
+ Ex = ltcPointIn->X;
+ Ey = ltcPointIn->Y;
+ Gx = ltcPointOut->X;
+ Gy = ltcPointOut->Y;
+ /* # (Ex, Ey) on Ed (a_ed, d) to (x, y) on M (A,B)
+ Mx = (1 + Ey) * ModularArithmetic.invert(1 - Ey, prime) % prime
+ My = (1 + Ey) * ModularArithmetic.invert((1 - Ey)*Ex, prime) % prime */
+
+ /* Gx = ((Mx * ModularArithmetic.invert(B, prime)) +
+ (A * ModularArithmetic.invert(3*B, prime))) % prime
+ Gy = (My * ModularArithmetic.invert(B, prime)) % prime */
+
+ /* temp = 1 + Ey */
+ status = LTC_PKHA_ModAdd(LTC_BASE, Ey, ED25519_KEY_SIZE, &one, sizeof(one),
+ modbin, sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith);
+
+ /* temp2 = 1 - Ey = 1 + (p - Ey) */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), Ey,
+ ED25519_KEY_SIZE, max, sizeof(max), temp2, &szTemp2);
+ }
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, temp2, szTemp2, &one, sizeof(one),
+ modbin, sizeof(modbin), temp2, &szTemp2, kLTC_PKHA_IntegerArith);
+ }
+
+ /* Mx = ModInv(temp2,prime) */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModInv(LTC_BASE, temp2, szTemp2, modbin,
+ sizeof(modbin), Mx, &szMx, kLTC_PKHA_IntegerArith);
+ }
+
+ /* Mx = Mx * temp */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, Mx, szMx, temp, szTemp, modbin,
+ ED25519_KEY_SIZE, Mx, &szMx, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* My = temp2 * Ex */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, Ex, ED25519_KEY_SIZE, temp2,
+ szTemp2, modbin, ED25519_KEY_SIZE, My, &szMy,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+
+ /* My = ModInv(My, prime) */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModInv(LTC_BASE, My, szMy, modbin, sizeof(modbin),
+ My, &szMy, kLTC_PKHA_IntegerArith);
+ }
+ /* My = My * temp */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, My, szMy, temp, szTemp, modbin,
+ ED25519_KEY_SIZE, My, &szMy, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* Gx = Mx * invB_coefEd25519 + A_mul_invThreeB_coefEd25519 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, Mx, szMx, invB_coefEd25519,
+ sizeof(invB_coefEd25519), modbin, ED25519_KEY_SIZE, Gx, &szGx,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, Gx, szGx,
+ A_mul_invThreeB_coefEd25519, sizeof(A_mul_invThreeB_coefEd25519),
+ modbin, sizeof(modbin), Gx, &szGx, kLTC_PKHA_IntegerArith);
+ }
+
+ /* Gy = My * invB_coefEd25519 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, My, szMy, invB_coefEd25519,
+ sizeof(invB_coefEd25519), modbin, ED25519_KEY_SIZE, Gy, &szGy,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+
+ return status;
+}
+
+/*
+# (Gx, Gy) on W to (Ex, Ey) on E
+My = (B*Gy) % prime
+Mx = ((3*B*Gx-A)*ModularArithmetic.invert(3, prime)) % prime
+Ex = Mx*ModularArithmetic.invert(My, prime) % prime
+Ey = (Mx - 1)*ModularArithmetic.invert(Mx + 1, prime) % prime
+*/
+status_t LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point_t *ltcPointIn,
+ ltc_pkha_ecc_point_t *ltcPointOut)
+{
+ status_t status;
+ uint8_t Mx[ED25519_KEY_SIZE] = {0};
+ uint8_t My[ED25519_KEY_SIZE] = {0};
+ uint8_t temp[ED25519_KEY_SIZE] = {0};
+ const uint8_t *Gx;
+ const uint8_t *Gy;
+ uint8_t *Ex;
+ uint8_t *Ey;
+ uint16_t szMx = 0;
+ uint16_t szEx = 0;
+ uint16_t szMy = 0;
+ uint16_t szEy = 0;
+ uint16_t szTemp = 0;
+ uint8_t one = 1;
+
+ Gx = ltcPointIn->X;
+ Gy = ltcPointIn->Y;
+ Ex = ltcPointOut->X;
+ Ey = ltcPointOut->Y;
+
+ /* My = (B*Gy) % prime */
+ status = LTC_PKHA_ModMul(LTC_BASE, B_coefEd25519, sizeof(B_coefEd25519),
+ Gy, ED25519_KEY_SIZE, modbin, ED25519_KEY_SIZE, My, &szMy,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+
+ /* temp = 3*B*Gx mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, threeB_coefEd25519,
+ sizeof(threeB_coefEd25519), Gx, ED25519_KEY_SIZE, modbin,
+ ED25519_KEY_SIZE, temp, &szTemp, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+ /* temp = (temp - A) mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, temp, szTemp, minus_A_coefEd25519,
+ sizeof(minus_A_coefEd25519), modbin, sizeof(modbin), temp, &szTemp,
+ kLTC_PKHA_IntegerArith);
+ }
+ /* Mx = (temp/3) mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, invThree,
+ sizeof(invThree), modbin, sizeof(modbin), Mx, &szMx,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+ /* temp = 1/My mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModInv(LTC_BASE, My, szMy, modbin, sizeof(modbin),
+ temp, &szTemp, kLTC_PKHA_IntegerArith);
+ }
+ /* Ex = Mx * temp mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, Mx, szMx, modbin,
+ sizeof(modbin), Ex, &szEx, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* temp = Mx + 1 mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, Mx, szMx, &one, sizeof(one),
+ modbin, sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith);
+ }
+ /* temp = 1/temp mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModInv(LTC_BASE, temp, szTemp, modbin,
+ sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith);
+ }
+ /* Mx = (Mx - 1) mod p */
+ if (status == kStatus_Success) {
+ if (LTC_PKHA_CompareBigNum(Mx, szMx, &one, sizeof(one)) >= 0) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, Mx, szMx, &one, sizeof(one),
+ modbin, sizeof(modbin), Mx, &szMx);
+ }
+ else {
+ /* Mx is zero, so it is modulus, thus we do modulus - 1 */
+ XMEMCPY(Mx, modbin, sizeof(modbin));
+ Mx[0]--;
+ }
+ }
+ /* Ey = Mx * temp mod p */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, Mx, szMx, modbin,
+ sizeof(modbin), Ey, &szEy, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ return status;
+}
+
+status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey,
+ size_t pubKeySize, ltc_pkha_ecc_point_t *ltcPointOut)
+{
+ status_t status;
+ const uint8_t one = 1;
+
+ /* pubkey contains the Y coordinate and a sign of X
+ */
+
+ /* x^2 = ((y^2 - 1) / (d*y^2 +1)) mod p */
+
+ /* decode Y from pubkey */
+ XMEMCPY(ltcPointOut->Y, pubkey, pubKeySize);
+ ltcPointOut->Y[pubKeySize - 1] &= ~0x80u;
+ int sign = (int)(bool)(pubkey[pubKeySize - 1] & 0x80u);
+
+ uint8_t U[ED25519_KEY_SIZE] = {0};
+ uint8_t V[ED25519_KEY_SIZE] = {0};
+ uint8_t *X = ltcPointOut->X;
+ uint8_t *Y = ltcPointOut->Y;
+ uint16_t szU = 0;
+ uint16_t szV = 0;
+ size_t szRes = 0;
+
+ /* decode X from pubkey */
+
+ /* U = y * y mod p */
+ status = LTC_PKHA_ModMul(LTC_BASE, Y, ED25519_KEY_SIZE, Y,
+ ED25519_KEY_SIZE, modbin, ED25519_KEY_SIZE, U, &szU,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ XMEMCPY(V, U, szU);
+ szV = szU;
+
+ /* U = U - 1 = y^2 - 1 */
+ if (status == kStatus_Success) {
+ if (LTC_PKHA_CompareBigNum(U, szU, &one, sizeof(one)) >= 0) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, U, szU, &one, sizeof(one),
+ modbin, sizeof(modbin), U, &szU);
+ }
+ else {
+ /* U is zero, so it is modulus, thus we do modulus - 1 */
+ XMEMCPY(U, modbin, sizeof(modbin));
+ U[0]--;
+ }
+ }
+
+ /* V = d*y*y + 1 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, V, szV, d_coefEd25519,
+ ED25519_KEY_SIZE, modbin, ED25519_KEY_SIZE, V, &szV,
+ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized);
+ }
+
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, V, szV, &one, sizeof(one),
+ modbin, sizeof(modbin), V, &szV, kLTC_PKHA_IntegerArith);
+ }
+
+ /* U = U / V (mod p) */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModInv(LTC_BASE, V, szV, modbin, sizeof(modbin),
+ V, &szV, kLTC_PKHA_IntegerArith);
+ }
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, V, szV, U, szU, modbin,
+ ED25519_KEY_SIZE, U, &szU, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ /* get square root */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_Prime25519SquareRootMod(U, szU, X, &szRes, sign);
+ }
+
+ return status;
+}
+
+/* LSByte first of Ed25519 parameter l = 2^252 + 27742317777372353535851937790883648493 */
+static const uint8_t l_coefEdDSA[] = {
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
+ 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+/*
+Input:
+ s[0]+256*s[1]+...+256^63*s[63] = s
+
+Output:
+ s[0]+256*s[1]+...+256^31*s[31] = s mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+ Overwrites s in place.
+*/
+status_t LTC_PKHA_sc_reduce(uint8_t *a)
+{
+ uint16_t szA = 0;
+ return LTC_PKHA_ModRed(LTC_BASE, a, 64, l_coefEdDSA, sizeof(l_coefEdDSA),
+ a, &szA, kLTC_PKHA_IntegerArith);
+}
+
+/*
+Input:
+ a[0]+256*a[1]+...+256^31*a[31] = a
+ b[0]+256*b[1]+...+256^31*b[31] = b
+ c[0]+256*c[1]+...+256^31*c[31] = c
+
+Output:
+ s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+*/
+status_t LTC_PKHA_sc_muladd(uint8_t *s, const uint8_t *a,
+ const uint8_t *b, const uint8_t *c)
+{
+ uint16_t szS = 0;
+ uint16_t szB = 0;
+ uint8_t tempB[32] = {0};
+ status_t status;
+
+ /* Assume only b can be larger than modulus. It is called durind
+ * wc_ed25519_sign_msg() where hram (=a) and nonce(=c)
+ * have been reduced by LTC_PKHA_sc_reduce()
+ * Thus reducing b only.
+ */
+ status = LTC_PKHA_ModRed(LTC_BASE, b, 32, l_coefEdDSA, sizeof(l_coefEdDSA),
+ tempB, &szB, kLTC_PKHA_IntegerArith);
+
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModMul(LTC_BASE, a, 32, tempB, szB, l_coefEdDSA,
+ sizeof(l_coefEdDSA), s, &szS, kLTC_PKHA_IntegerArith,
+ kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue,
+ kLTC_PKHA_TimingEqualized);
+ }
+
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModAdd(LTC_BASE, s, szS, c, 32, l_coefEdDSA, 32, s,
+ &szS, kLTC_PKHA_IntegerArith);
+ }
+
+ return status;
+}
+
+/*
+r = a * A + b * B
+where A is public key point, B is basepoint
+where a = a[0]+256*a[1]+...+256^31 a[31].
+and b = b[0]+256*b[1]+...+256^31 b[31].
+B is the Ed25519 base point (x,4/5) with x positive.
+*/
+status_t LTC_PKHA_SignatureForVerify(uint8_t *rcheck, const unsigned char *a,
+ const unsigned char *b, ed25519_key *key)
+{
+ /* To verify a signature on a message M, first split the signature
+ into two 32-octet halves. Decode the first half as a point R,
+ and the second half as an integer s, in the range 0 <= s < q. If
+ the decoding fails, the signature is invalid. */
+
+ /* Check the group equation 8s B = 8 R + 8k A. */
+
+ /*
+ Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
+ SB - H(R,A,M)A saving decompression of R
+ */
+ uint8_t X0[ED25519_PUB_KEY_SIZE] = {0};
+ uint8_t X1[ED25519_PUB_KEY_SIZE] = {0};
+ uint8_t Y0[ED25519_PUB_KEY_SIZE] = {0};
+ uint8_t Y1[ED25519_PUB_KEY_SIZE] = {0};
+ const uint8_t max[32] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ ltc_pkha_ecc_point_t ltc0;
+ ltc_pkha_ecc_point_t ltc1;
+ ltc_pkha_ecc_point_t pubKey;
+ status_t status;
+
+ /* The equality for the negative of a point P, in affine coordinates,
+ is -P = -(x,y) = (x, -y) */
+ uint16_t szY = 32;
+
+ ltc0.X = X0;
+ ltc1.X = X1;
+ ltc0.Y = Y0;
+ ltc1.Y = Y1;
+ pubKey.X = key->pointX;
+ pubKey.Y = key->pointY;
+
+ /* ltc0 = b*B */
+ status = LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), b,
+ ED25519_KEY_SIZE, <c0, kLTC_Weierstrass /* result in W */);
+
+ /* ltc1 = a*A */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_Ed25519ToWeierstrass(&pubKey, <c1);
+ }
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_Ed25519_PointMul(<c1, a, ED25519_KEY_SIZE, <c1,
+ kLTC_Weierstrass /* result in W */);
+ }
+
+ /* R = b*B - a*A */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), ltc1.Y,
+ szY, max, sizeof(max), ltc1.Y, &szY);
+ }
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_ECC_PointAdd(LTC_BASE, <c0, <c1, modbin, r2mod,
+ a_coefEd25519, b_coefEd25519, ED25519_KEY_SIZE,
+ kLTC_PKHA_IntegerArith, <c0);
+ }
+ /* map to Ed25519 */
+ if (status == kStatus_Success) {
+ status = LTC_PKHA_WeierstrassToEd25519(<c0, <c0);
+ }
+ if (((uint32_t)ltc0.X[0]) & 0x01u) {
+ ltc0.Y[ED25519_KEY_SIZE - 1] |= 0x80u;
+ }
+
+ XMEMCPY(rcheck, ltc0.Y, ED25519_KEY_SIZE);
+ return status;
+}
+
+status_t LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point_t *ltcPointIn,
+ uint8_t *p)
+{
+ /* compress */
+ /* get sign of X per https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02
+ * To form the encoding of the point, copy the least
+ significant bit of the x-coordinate to the most significant bit of
+ the final octet
+ */
+ XMEMCPY(p, ltcPointIn->Y, ED25519_KEY_SIZE);
+ if (((uint32_t)ltcPointIn->X[0]) & 0x01u) {
+ p[ED25519_KEY_SIZE - 1] |= 0x80u;
+ }
+ return kStatus_Success;
+}
+
+#endif /* HAVE_ED25519 */
+#endif /* FREESCALE_LTC_ECC */
+
+
+#undef ERROR_OUT
+
+#endif /* (USE_FAST_MATH && FREESCALE_LTC_TFM) || FREESCALE_LTC_ECC */
diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c
index bddbe80c4..b953e2dd7 100644
--- a/wolfcrypt/src/random.c
+++ b/wolfcrypt/src/random.c
@@ -157,6 +157,10 @@ int wc_FreeRng(WC_RNG* rng)
#ifndef EBSNET
#include
#endif
+ #elif defined(FREESCALE_KSDK_2_0_TRNG)
+ #include "fsl_trng.h"
+ #elif defined(FREESCALE_KSDK_2_0_RNGA)
+ #include "fsl_rnga.h"
#else
/* include headers that may be needed to get good seed */
#endif
@@ -1356,12 +1360,36 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
return 0;
}
- #elif defined(FREESCALE_TRNG)
+ #elif defined(FREESCALE_KSDK_2_0_TRNG)
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
- TRNG_DRV_GetRandomData(TRNG_INSTANCE, output, sz);
- return 0;
+ status_t status;
+ status = TRNG_GetRandomData(TRNG0, output, sz);
+ if (status == kStatus_Success)
+ {
+ return(0);
+ }
+ else
+ {
+ return RAN_BLOCK_E;
+ }
+ }
+
+ #elif defined(FREESCALE_KSDK_2_0_RNGA)
+
+ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+ {
+ status_t status;
+ status = RNGA_GetRandomData(RNG, output, sz);
+ if (status == kStatus_Success)
+ {
+ return(0);
+ }
+ else
+ {
+ return RAN_BLOCK_E;
+ }
}
diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c
index 29ab190b8..df475d800 100644
--- a/wolfcrypt/src/rsa.c
+++ b/wolfcrypt/src/rsa.c
@@ -1161,7 +1161,7 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
outLen: length of encrypted output buffer
key : wolfSSL initialized RSA key struct
rng : wolfSSL initialized random number struct
- rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
+ rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
@@ -1256,7 +1256,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
outLen: length of decrypted message in bytes
outPtr: optional inline output pointer (if provided doing inline)
key : wolfSSL initialized RSA key struct
- rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
+ rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
@@ -1403,7 +1403,7 @@ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
- return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
+ return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
}
@@ -1418,7 +1418,7 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
- return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
+ return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash,
mgf, label, labelSz, rng);
}
@@ -1461,7 +1461,7 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
- return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
+ return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
}
@@ -1473,7 +1473,7 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
- return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
+ return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
}
@@ -1619,16 +1619,16 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
err = mp_copy(&q, &key->q);
if (err == MP_OKAY)
- key->type = RSA_PRIVATE;
+ key->type = RSA_PRIVATE;
- mp_clear(&tmp3);
- mp_clear(&tmp2);
- mp_clear(&tmp1);
- mp_clear(&q);
+ mp_clear(&tmp3);
+ mp_clear(&tmp2);
+ mp_clear(&tmp1);
+ mp_clear(&q);
mp_clear(&p);
if (err != MP_OKAY) {
- wc_FreeRsaKey(key);
+ wc_FreeRsaKey(key);
return err;
}
diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c
index 9de702a45..e6fe9d396 100644
--- a/wolfcrypt/src/sha.c
+++ b/wolfcrypt/src/sha.c
@@ -20,13 +20,13 @@
*/
-
#ifdef HAVE_CONFIG_H
#include
#endif
#include
+
#if !defined(NO_SHA)
#include
@@ -40,6 +40,7 @@
#include
#endif
+
/* fips wrapper calls, user can call direct */
#ifdef HAVE_FIPS
int wc_InitSha(Sha* sha)
@@ -47,13 +48,11 @@
return InitSha_fips(sha);
}
-
int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
{
return ShaUpdate_fips(sha, data, len);
}
-
int wc_ShaFinal(Sha* sha, byte* out)
{
return ShaFinal_fips(sha,out);
@@ -61,292 +60,332 @@
#else /* else build without fips */
+
+/****************************************/
+/* SHA Hardware Variations */
+/****************************************/
#if defined(WOLFSSL_TI_HASH)
/* #include included by wc_port.c */
-#else
-#ifdef WOLFSSL_PIC32MZ_HASH
-#define wc_InitSha wc_InitSha_sw
-#define wc_ShaUpdate wc_ShaUpdate_sw
-#define wc_ShaFinal wc_ShaFinal_sw
-#endif
+#elif defined(WOLFSSL_PIC32MZ_HASH)
+ #define USE_SHA_SOFTWARE_IMPL
+ #define wc_InitSha wc_InitSha_sw
+ #define wc_ShaUpdate wc_ShaUpdate_sw
+ #define wc_ShaFinal wc_ShaFinal_sw
-
-#ifdef FREESCALE_MMCAU
- #include "cau_api.h"
- #define XTRANSFORM(S,B) Transform((S), (B))
-#else
- #define XTRANSFORM(S,B) Transform((S))
-#endif
-
-#ifdef STM32F2_HASH
-/*
- * STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
- * library. Documentation located in STM32F2xx Standard Peripheral Library
- * document (See note in README).
- */
-#include "stm32f2xx.h"
-#include "stm32f2xx_hash.h"
-
-int wc_InitSha(Sha* sha)
-{
- /* STM32F2 struct notes:
- * sha->buffer = first 4 bytes used to hold partial block if needed
- * sha->buffLen = num bytes currently stored in sha->buffer
- * sha->loLen = num bytes that have been written to STM32 FIFO
+#elif defined(STM32F2_HASH)
+ /*
+ * STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
+ * library. Documentation located in STM32F2xx Standard Peripheral Library
+ * document (See note in README).
*/
- XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
- sha->buffLen = 0;
- sha->loLen = 0;
+ #include "stm32f2xx.h"
+ #include "stm32f2xx_hash.h"
- /* initialize HASH peripheral */
- HASH_DeInit();
+ int wc_InitSha(Sha* sha)
+ {
+ /* STM32F2 struct notes:
+ * sha->buffer = first 4 bytes used to hold partial block if needed
+ * sha->buffLen = num bytes currently stored in sha->buffer
+ * sha->loLen = num bytes that have been written to STM32 FIFO
+ */
+ XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
+ sha->buffLen = 0;
+ sha->loLen = 0;
- /* configure algo used, algo mode, datatype */
- HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
- HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
- | HASH_DataType_8b);
+ /* initialize HASH peripheral */
+ HASH_DeInit();
- /* reset HASH processor */
- HASH->CR |= HASH_CR_INIT;
+ /* configure algo used, algo mode, datatype */
+ HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
+ HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
+ | HASH_DataType_8b);
- return 0;
-}
+ /* reset HASH processor */
+ HASH->CR |= HASH_CR_INIT;
-int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
-{
- word32 i = 0;
- word32 fill = 0;
- word32 diff = 0;
+ return 0;
+ }
- /* if saved partial block is available */
- if (sha->buffLen) {
- fill = 4 - sha->buffLen;
+ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
+ {
+ word32 i = 0;
+ word32 fill = 0;
+ word32 diff = 0;
- /* if enough data to fill, fill and push to FIFO */
- if (fill <= len) {
- XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
+ /* if saved partial block is available */
+ if (sha->buffLen) {
+ fill = 4 - sha->buffLen;
+
+ /* if enough data to fill, fill and push to FIFO */
+ if (fill <= len) {
+ XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
+ HASH_DataIn(*(uint32_t*)sha->buffer);
+
+ data += fill;
+ len -= fill;
+ sha->loLen += 4;
+ sha->buffLen = 0;
+ } else {
+ /* append partial to existing stored block */
+ XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
+ sha->buffLen += len;
+ return 0;
+ }
+ }
+
+ /* write input block in the IN FIFO */
+ for(i = 0; i < len; i += 4)
+ {
+ diff = len - i;
+ if ( diff < 4) {
+ /* store incomplete last block, not yet in FIFO */
+ XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
+ XMEMCPY((byte*)sha->buffer, data, diff);
+ sha->buffLen = diff;
+ } else {
+ HASH_DataIn(*(uint32_t*)data);
+ data+=4;
+ }
+ }
+
+ /* keep track of total data length thus far */
+ sha->loLen += (len - sha->buffLen);
+
+ return 0;
+ }
+
+ int wc_ShaFinal(Sha* sha, byte* hash)
+ {
+ __IO uint16_t nbvalidbitsdata = 0;
+
+ /* finish reading any trailing bytes into FIFO */
+ if (sha->buffLen) {
HASH_DataIn(*(uint32_t*)sha->buffer);
-
- data += fill;
- len -= fill;
- sha->loLen += 4;
- sha->buffLen = 0;
- } else {
- /* append partial to existing stored block */
- XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
- sha->buffLen += len;
- return 0;
+ sha->loLen += sha->buffLen;
}
+
+ /* calculate number of valid bits in last word of input data */
+ nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
+
+ /* configure number of valid bits in last word of the data */
+ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
+
+ /* start HASH processor */
+ HASH_StartDigest();
+
+ /* wait until Busy flag == RESET */
+ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
+
+ /* read message digest */
+ sha->digest[0] = HASH->HR[0];
+ sha->digest[1] = HASH->HR[1];
+ sha->digest[2] = HASH->HR[2];
+ sha->digest[3] = HASH->HR[3];
+ sha->digest[4] = HASH->HR[4];
+
+ ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
+
+ XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
+
+ return wc_InitSha(sha); /* reset state */
}
- /* write input block in the IN FIFO */
- for(i = 0; i < len; i += 4)
+
+#elif defined(FREESCALE_LTC_SHA)
+
+ #include "fsl_ltc.h"
+ int wc_InitSha(Sha* sha)
{
- diff = len - i;
- if ( diff < 4) {
- /* store incomplete last block, not yet in FIFO */
- XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
- XMEMCPY((byte*)sha->buffer, data, diff);
- sha->buffLen = diff;
- } else {
- HASH_DataIn(*(uint32_t*)data);
- data+=4;
+ LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0);
+ return 0;
+ }
+
+ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
+ {
+ LTC_HASH_Update(&sha->ctx, data, len);
+ return 0;
+ }
+
+ int wc_ShaFinal(Sha* sha, byte* hash)
+ {
+ uint32_t hashlen = SHA_DIGEST_SIZE;
+ LTC_HASH_Finish(&sha->ctx, hash, &hashlen);
+ return wc_InitSha(sha); /* reset state */
+ }
+
+
+#elif defined(FREESCALE_MMCAU_SHA)
+
+ #include "fsl_mmcau.h"
+ #define USE_SHA_SOFTWARE_IMPL /* Only for API's, actual transform is here */
+ #define XSHATRANSFORM ShaTransform
+
+ int wc_InitSha(Sha* sha)
+ {
+ int ret = 0;
+ ret = wolfSSL_CryptHwMutexLock();
+ if(ret != 0) {
+ return ret;
}
- }
+ MMCAU_SHA1_InitializeOutput((uint32_t*)sha->digest);
+ wolfSSL_CryptHwMutexUnLock();
- /* keep track of total data length thus far */
- sha->loLen += (len - sha->buffLen);
+ sha->buffLen = 0;
+ sha->loLen = 0;
+ sha->hiLen = 0;
- return 0;
-}
-
-int wc_ShaFinal(Sha* sha, byte* hash)
-{
- __IO uint16_t nbvalidbitsdata = 0;
-
- /* finish reading any trailing bytes into FIFO */
- if (sha->buffLen) {
- HASH_DataIn(*(uint32_t*)sha->buffer);
- sha->loLen += sha->buffLen;
- }
-
- /* calculate number of valid bits in last word of input data */
- nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
-
- /* configure number of valid bits in last word of the data */
- HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
-
- /* start HASH processor */
- HASH_StartDigest();
-
- /* wait until Busy flag == RESET */
- while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
-
- /* read message digest */
- sha->digest[0] = HASH->HR[0];
- sha->digest[1] = HASH->HR[1];
- sha->digest[2] = HASH->HR[2];
- sha->digest[3] = HASH->HR[3];
- sha->digest[4] = HASH->HR[4];
-
- ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
-
- XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
-
- return wc_InitSha(sha); /* reset state */
-}
-
-#else /* wc_ software implementation */
-
-#ifndef WOLFSSL_HAVE_MIN
-#define WOLFSSL_HAVE_MIN
-
- static INLINE word32 min(word32 a, word32 b)
- {
- return a > b ? b : a;
- }
-
-#endif /* WOLFSSL_HAVE_MIN */
-
-
-int wc_InitSha(Sha* sha)
-{
- int ret = 0;
-#ifdef FREESCALE_MMCAU
- ret = wolfSSL_CryptHwMutexLock();
- if(ret != 0) {
return ret;
}
- cau_sha1_initialize_output(sha->digest);
- wolfSSL_CryptHwMutexUnLock();
+
+ static int ShaTransform(Sha* sha, byte* data)
+ {
+ int ret = wolfSSL_CryptHwMutexLock();
+ if(ret == 0) {
+ MMCAU_SHA1_HashN(data, 1, (uint32_t*)sha->digest);
+ wolfSSL_CryptHwMutexUnLock();
+ }
+ return ret;
+ }
+
#else
- sha->digest[0] = 0x67452301L;
- sha->digest[1] = 0xEFCDAB89L;
- sha->digest[2] = 0x98BADCFEL;
- sha->digest[3] = 0x10325476L;
- sha->digest[4] = 0xC3D2E1F0L;
+
+ /* Software implementation */
+ #define USE_SHA_SOFTWARE_IMPL
+
+ int wc_InitSha(Sha* sha)
+ {
+ int ret = 0;
+
+ sha->digest[0] = 0x67452301L;
+ sha->digest[1] = 0xEFCDAB89L;
+ sha->digest[2] = 0x98BADCFEL;
+ sha->digest[3] = 0x10325476L;
+ sha->digest[4] = 0xC3D2E1F0L;
+
+ sha->buffLen = 0;
+ sha->loLen = 0;
+ sha->hiLen = 0;
+
+ return ret;
+ }
+
#endif
- sha->buffLen = 0;
- sha->loLen = 0;
- sha->hiLen = 0;
- return ret;
-}
+/* Software implementation */
+#ifdef USE_SHA_SOFTWARE_IMPL
-#ifdef FREESCALE_MMCAU
-static int Transform(Sha* sha, byte* data)
-{
- int ret = wolfSSL_CryptHwMutexLock();
- if(ret == 0) {
- cau_sha1_hash_n(data, 1, sha->digest);
- wolfSSL_CryptHwMutexUnLock();
+/* Check if custom Sha transform is used */
+#ifndef XSHATRANSFORM
+ #define XSHATRANSFORM ShaTransform
+
+ #define blk0(i) (W[i] = sha->buffer[i])
+ #define blk1(i) (W[(i)&15] = \
+ rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))
+
+ #define f1(x,y,z) ((z)^((x) &((y)^(z))))
+ #define f2(x,y,z) ((x)^(y)^(z))
+ #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
+ #define f4(x,y,z) ((x)^(y)^(z))
+
+ /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+ #define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
+ rotlFixed((v),5); (w) = rotlFixed((w),30);
+ #define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
+ rotlFixed((v),5); (w) = rotlFixed((w),30);
+ #define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
+ rotlFixed((v),5); (w) = rotlFixed((w),30);
+ #define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
+ rotlFixed((v),5); (w) = rotlFixed((w),30);
+ #define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
+ rotlFixed((v),5); (w) = rotlFixed((w),30);
+
+ static void ShaTransform(Sha* sha, byte* data)
+ {
+ word32 W[SHA_BLOCK_SIZE / sizeof(word32)];
+
+ /* Copy context->state[] to working vars */
+ word32 a = sha->digest[0];
+ word32 b = sha->digest[1];
+ word32 c = sha->digest[2];
+ word32 d = sha->digest[3];
+ word32 e = sha->digest[4];
+
+ #ifdef USE_SLOW_SHA
+ word32 t, i;
+
+ for (i = 0; i < 16; i++) {
+ R0(a, b, c, d, e, i);
+ t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 20; i++) {
+ R1(a, b, c, d, e, i);
+ t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 40; i++) {
+ R2(a, b, c, d, e, i);
+ t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 60; i++) {
+ R3(a, b, c, d, e, i);
+ t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+
+ for (; i < 80; i++) {
+ R4(a, b, c, d, e, i);
+ t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+ #else
+ /* nearly 1 K bigger in code size but 25% faster */
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ #endif
+
+ /* Add the working vars back into digest state[] */
+ sha->digest[0] += a;
+ sha->digest[1] += b;
+ sha->digest[2] += c;
+ sha->digest[3] += d;
+ sha->digest[4] += e;
+
+ (void)data; /* Not used */
}
- return ret;
-}
-#endif /* FREESCALE_MMCAU */
-
-#ifndef FREESCALE_MMCAU
+#endif /* !USE_CUSTOM_SHA_TRANSFORM */
-#define blk0(i) (W[i] = sha->buffer[i])
-#define blk1(i) (W[(i)&15] = \
-rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))
-#define f1(x,y,z) ((z)^((x) &((y)^(z))))
-#define f2(x,y,z) ((x)^(y)^(z))
-#define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
-#define f4(x,y,z) ((x)^(y)^(z))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
-rotlFixed((v),5); (w) = rotlFixed((w),30);
-#define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
-rotlFixed((v),5); (w) = rotlFixed((w),30);
-#define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
-rotlFixed((v),5); (w) = rotlFixed((w),30);
-#define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
-rotlFixed((v),5); (w) = rotlFixed((w),30);
-#define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
-rotlFixed((v),5); (w) = rotlFixed((w),30);
-
-static void Transform(Sha* sha)
-{
- word32 W[SHA_BLOCK_SIZE / sizeof(word32)];
-
- /* Copy context->state[] to working vars */
- word32 a = sha->digest[0];
- word32 b = sha->digest[1];
- word32 c = sha->digest[2];
- word32 d = sha->digest[3];
- word32 e = sha->digest[4];
-
-#ifdef USE_SLOW_SHA
- word32 t, i;
-
- for (i = 0; i < 16; i++) {
- R0(a, b, c, d, e, i);
- t = e; e = d; d = c; c = b; b = a; a = t;
+#ifndef WOLFSSL_HAVE_MIN
+ #define WOLFSSL_HAVE_MIN
+ static INLINE word32 min(word32 a, word32 b) {
+ return a > b ? b : a;
}
-
- for (; i < 20; i++) {
- R1(a, b, c, d, e, i);
- t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 40; i++) {
- R2(a, b, c, d, e, i);
- t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 60; i++) {
- R3(a, b, c, d, e, i);
- t = e; e = d; d = c; c = b; b = a; a = t;
- }
-
- for (; i < 80; i++) {
- R4(a, b, c, d, e, i);
- t = e; e = d; d = c; c = b; b = a; a = t;
- }
-#else
- /* nearly 1 K bigger in code size but 25% faster */
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-#endif
-
- /* Add the working vars back into digest state[] */
- sha->digest[0] += a;
- sha->digest[1] += b;
- sha->digest[2] += c;
- sha->digest[3] += d;
- sha->digest[4] += e;
-}
-
-#endif /* FREESCALE_MMCAU */
-
+#endif /* WOLFSSL_HAVE_MIN */
static INLINE void AddLength(Sha* sha, word32 len)
{
@@ -370,10 +409,10 @@ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
len -= add;
if (sha->buffLen == SHA_BLOCK_SIZE) {
-#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
#endif
- XTRANSFORM(sha, local);
+ XSHATRANSFORM(sha, local);
AddLength(sha, SHA_BLOCK_SIZE);
sha->buffLen = 0;
}
@@ -382,7 +421,6 @@ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len)
return 0;
}
-
int wc_ShaFinal(Sha* sha, byte* hash)
{
byte* local = (byte*)sha->buffer;
@@ -396,10 +434,10 @@ int wc_ShaFinal(Sha* sha, byte* hash)
XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
-#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
#endif
- XTRANSFORM(sha, local);
+ XSHATRANSFORM(sha, local);
sha->buffLen = 0;
}
XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
@@ -410,21 +448,21 @@ int wc_ShaFinal(Sha* sha, byte* hash)
sha->loLen = sha->loLen << 3;
/* store lengths */
-#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
#endif
/* ! length ordering dependent on digest endian type ! */
XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
-#ifdef FREESCALE_MMCAU
+#ifdef FREESCALE_MMCAU_SHA
/* Kinetis requires only these bytes reversed */
ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
2 * sizeof(word32));
#endif
- XTRANSFORM(sha, local);
+ XSHATRANSFORM(sha, local);
#ifdef LITTLE_ENDIAN_ORDER
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
#endif
@@ -433,11 +471,7 @@ int wc_ShaFinal(Sha* sha, byte* hash)
return wc_InitSha(sha); /* reset state */
}
-#endif /* STM32F2_HASH */
-
-
+#endif /* USE_SHA_SOFTWARE_IMPL */
#endif /* HAVE_FIPS */
-#endif /* WOLFSSL_TI_HASH */
-#endif /* NO_SHA */
-
+#endif /* !NO_SHA */
diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c
index 715b97176..97697c26b 100644
--- a/wolfcrypt/src/sha256.c
+++ b/wolfcrypt/src/sha256.c
@@ -250,7 +250,7 @@ static void set_Transform(void) {
}
#else
- #if defined(FREESCALE_MMCAU)
+ #if defined(FREESCALE_MMCAU_SHA)
#define XTRANSFORM(sha256, B) Transform(sha256, B)
#else
#define XTRANSFORM(sha256, B) Transform(sha256)
@@ -285,8 +285,8 @@ static void set_Transform(void) {
#include
#endif
-#ifdef FREESCALE_MMCAU
- #include "cau_api.h"
+#ifdef FREESCALE_MMCAU_SHA
+ #include "fsl_mmcau.h"
#endif
#ifndef WOLFSSL_HAVE_MIN
@@ -299,16 +299,22 @@ static void set_Transform(void) {
#endif /* WOLFSSL_HAVE_MIN */
-
+#ifdef FREESCALE_LTC_SHA
+int wc_InitSha256(Sha256* sha256)
+{
+ LTC_HASH_Init(LTC_BASE, &sha256->ctx, kLTC_Sha256, NULL, 0);
+ return 0;
+}
+#else
int wc_InitSha256(Sha256* sha256)
{
int ret = 0;
- #ifdef FREESCALE_MMCAU
+ #ifdef FREESCALE_MMCAU_SHA
ret = wolfSSL_CryptHwMutexLock();
if(ret != 0) {
return ret;
}
- cau_sha256_initialize_output(sha256->digest);
+ MMCAU_SHA256_InitializeOutput((uint32_t*)sha256->digest);
wolfSSL_CryptHwMutexUnLock();
#else
sha256->digest[0] = 0x6A09E667L;
@@ -331,9 +337,10 @@ int wc_InitSha256(Sha256* sha256)
return ret;
}
+#endif /* FREESCALE_LTC_SHA */
-
-#if !defined(FREESCALE_MMCAU)
+#if !defined(FREESCALE_LTC_SHA)
+#if !defined(FREESCALE_MMCAU_SHA)
static const ALIGN32 word32 K[64] = {
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
@@ -352,19 +359,19 @@ static const ALIGN32 word32 K[64] = {
#endif
-#if defined(FREESCALE_MMCAU)
+#if defined(FREESCALE_MMCAU_SHA)
static int Transform(Sha256* sha256, byte* buf)
{
int ret = wolfSSL_CryptHwMutexLock();
if(ret == 0) {
- cau_sha256_hash_n(buf, 1, sha256->digest);
+ MMCAU_SHA256_HashN(buf, 1, (uint32_t*)sha256->digest);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
-#endif /* FREESCALE_MMCAU */
+#endif /* FREESCALE_MMCAU_SHA */
#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y)))
@@ -382,7 +389,7 @@ static int Transform(Sha256* sha256, byte* buf)
(d) += t0; \
(h) = t0 + t1;
-#if !defined(FREESCALE_MMCAU)
+#if !defined(FREESCALE_MMCAU_SHA)
static int Transform(Sha256* sha256)
{
word32 S[8], t0, t1;
@@ -431,7 +438,7 @@ static int Transform(Sha256* sha256)
return 0;
}
-#endif /* #if !defined(FREESCALE_MMCAU) */
+#endif /* #if !defined(FREESCALE_MMCAU_SHA) */
static INLINE void AddLength(Sha256* sha256, word32 len)
{
@@ -439,7 +446,15 @@ static INLINE void AddLength(Sha256* sha256, word32 len)
if ( (sha256->loLen += len) < tmp)
sha256->hiLen++; /* carry low to high */
}
+#endif /* FREESCALE_LTC_SHA */
+#ifdef FREESCALE_LTC_SHA
+int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
+{
+ LTC_HASH_Update(&sha256->ctx, data, len);
+ return 0;
+}
+#else
static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len)
{
@@ -459,7 +474,7 @@ static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len)
if (sha256->buffLen == SHA256_BLOCK_SIZE) {
int ret;
- #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
#endif
@@ -483,6 +498,16 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
return Sha256Update(sha256, data, len);
}
+#endif /* FREESCALE_LTC_SHA */
+
+#ifdef FREESCALE_LTC_SHA
+int wc_Sha256Final(Sha256* sha256, byte* hash)
+{
+ uint32_t hashlen = SHA256_DIGEST_SIZE;
+ LTC_HASH_Finish(&sha256->ctx, hash, &hashlen);
+ return wc_InitSha256(sha256); /* reset state */
+}
+#else
static INLINE int Sha256Final(Sha256* sha256)
{
byte* local = (byte*)sha256->buffer;
@@ -499,7 +524,7 @@ static INLINE int Sha256Final(Sha256* sha256)
XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
- #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
#endif
@@ -520,7 +545,7 @@ static INLINE int Sha256Final(Sha256* sha256)
sha256->loLen = sha256->loLen << 3;
/* store lengths */
- #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
+ #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2)
#endif
@@ -531,7 +556,7 @@ static INLINE int Sha256Final(Sha256* sha256)
XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
sizeof(word32));
- #if defined(FREESCALE_MMCAU) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
+ #if defined(FREESCALE_MMCAU_SHA) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
/* Kinetis requires only these bytes reversed */
#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
if(IS_INTEL_AVX1 || IS_INTEL_AVX2)
@@ -559,6 +584,8 @@ int wc_Sha256Final(Sha256* sha256, byte* hash)
return wc_InitSha256(sha256); /* reset state */
}
+#endif /* FREESCALE_LTC_SHA */
+
#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c
index 59b809316..e73135a60 100644
--- a/wolfcrypt/src/tfm.c
+++ b/wolfcrypt/src/tfm.c
@@ -50,6 +50,9 @@
#include
#include /* will define asm MACROS or C ones */
+#if defined(FREESCALE_LTC_TFM)
+ #include
+#endif
#ifdef WOLFSSL_DEBUG_MATH
#include
#endif
@@ -194,7 +197,11 @@ void s_fp_sub(fp_int *a, fp_int *b, fp_int *c)
}
/* c = a * b */
+#if defined(FREESCALE_LTC_TFM)
+void wolfcrypt_fp_mul(fp_int *A, fp_int *B, fp_int *C)
+#else
void fp_mul(fp_int *A, fp_int *B, fp_int *C)
+#endif
{
int y, yy, oldused;
@@ -736,7 +743,11 @@ void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
}
/* c = a mod b, 0 <= c < b */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c)
+#else
int fp_mod(fp_int *a, fp_int *b, fp_int *c)
+#endif
{
fp_int t;
int err;
@@ -886,9 +897,12 @@ top:
return FP_OKAY;
}
-
/* c = 1/a (mod b) for odd b only */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_fp_invmod(fp_int *a, fp_int *b, fp_int *c)
+#else
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
+#endif
{
fp_int x, y, u, v, B, D;
int neg;
@@ -980,7 +994,11 @@ top:
}
/* d = a * b (mod c) */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
+#else
int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
+#endif
{
int err;
fp_int t;
@@ -1059,7 +1077,11 @@ const wolfssl_word wc_off_on_addr[2] =
Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
Cryptographic Hardware and Embedded Systems, CHES 2002
*/
+#if defined(FREESCALE_LTC_TFM)
+int _wolfcrypt_fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
+#else
static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
+#endif
{
#ifdef WC_NO_CACHE_RESISTANT
fp_int R[2];
@@ -1929,6 +1951,15 @@ void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c)
fp_clamp (a);
}
+int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b)
+{
+ while (fp_iszero (t) == FP_NO) {
+ b[x++] = (unsigned char) (t->dp[0] & 255);
+ fp_div_2d (t, 8, t, NULL);
+ }
+ return x;
+}
+
void fp_to_unsigned_bin(fp_int *a, unsigned char *b)
{
int x;
@@ -1936,11 +1967,7 @@ void fp_to_unsigned_bin(fp_int *a, unsigned char *b)
fp_init_copy(&t, a);
- x = 0;
- while (fp_iszero (&t) == FP_NO) {
- b[x++] = (unsigned char) (t.dp[0] & 255);
- fp_div_2d (&t, 8, &t, NULL);
- }
+ x = fp_to_unsigned_bin_at_pos(0, &t, b);
fp_reverse (b, x);
}
diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c
index 3080338cb..5e3c32a49 100644
--- a/wolfcrypt/src/wc_port.c
+++ b/wolfcrypt/src/wc_port.c
@@ -35,6 +35,10 @@
#include
#endif
+#if defined(FREESCALE_LTC_TFM)
+ #include
+#endif
+
#ifdef _MSC_VER
/* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
#pragma warning(disable: 4996)
@@ -69,6 +73,10 @@ int wolfCrypt_Init()
}
#endif
+ #if defined(FREESCALE_LTC_TFM) || defined(FREESCALE_LTC_ECC)
+ ksdk_port_init();
+ #endif
+
#ifdef WOLFSSL_ARMASM
WOLFSSL_MSG("Using ARM hardware acceleration");
#endif
diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h
index c691357c3..046f81b0d 100644
--- a/wolfssl/wolfcrypt/aes.h
+++ b/wolfssl/wolfcrypt/aes.h
@@ -167,6 +167,8 @@ WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out,
const byte* authIn, word32 authInSz);
#endif /* HAVE_AESCCM */
+WOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize);
+
#ifdef WOLFSSL_ASYNC_CRYPT
WOLFSSL_API int wc_AesAsyncInit(Aes*, int);
WOLFSSL_API void wc_AesAsyncFree(Aes*);
diff --git a/wolfssl/wolfcrypt/curve25519.h b/wolfssl/wolfcrypt/curve25519.h
index d775877bf..d3a39eafc 100644
--- a/wolfssl/wolfcrypt/curve25519.h
+++ b/wolfssl/wolfcrypt/curve25519.h
@@ -47,6 +47,9 @@ typedef struct {
* the mathematical functions used the endianess */
typedef struct {
byte point[CURVE25519_KEYSIZE];
+ #ifdef FREESCALE_LTC_ECC
+ byte pointY[CURVE25519_KEYSIZE];
+ #endif
}ECPoint;
/* A CURVE25519 Key */
diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h
index 103a06599..ea88603a3 100644
--- a/wolfssl/wolfcrypt/ed25519.h
+++ b/wolfssl/wolfcrypt/ed25519.h
@@ -58,6 +58,11 @@
typedef struct {
byte p[ED25519_PUB_KEY_SIZE]; /* compressed public key */
byte k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */
+#ifdef FREESCALE_LTC_ECC
+ /* uncompressed point coordinates */
+ byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */
+ byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */
+#endif
} ed25519_key;
diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h
index 1d0a801ef..ae15dab1f 100644
--- a/wolfssl/wolfcrypt/fe_operations.h
+++ b/wolfssl/wolfcrypt/fe_operations.h
@@ -47,7 +47,9 @@ Bounds on each t[i] vary depending on context.
typedef int32_t fe[10];
#endif
+#if! defined FREESCALE_LTC_ECC
WOLFSSL_LOCAL int curve25519(byte * q, byte * n, byte * p);
+#endif
WOLFSSL_LOCAL void fe_copy(fe, const fe);
WOLFSSL_LOCAL void fe_add(fe, const fe, const fe);
WOLFSSL_LOCAL void fe_neg(fe,const fe);
diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am
index bc94891a4..4dddbc687 100644
--- a/wolfssl/wolfcrypt/include.am
+++ b/wolfssl/wolfcrypt/include.am
@@ -64,7 +64,8 @@ noinst_HEADERS+= \
wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \
wolfssl/wolfcrypt/port/ti/ti-hash.h \
wolfssl/wolfcrypt/port/ti/ti-ccm.h \
- wolfssl/wolfcrypt/port/nrf51.h
+ wolfssl/wolfcrypt/port/nrf51.h \
+ wolfssl/wolfcrypt/port/nxp/ksdk_port.h
if BUILD_CAVIUM
noinst_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h
diff --git a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h
new file mode 100755
index 000000000..d6acdd764
--- /dev/null
+++ b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h
@@ -0,0 +1,88 @@
+/* ksdk_port.h
+ *
+ * Copyright (C) 2006-2016 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 2 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
+ */
+
+#ifndef _KSDK_PORT_H_
+#define _KSDK_PORT_H_
+
+#include
+#include
+#include
+#include
+#include
+
+
+/* API to init required hardware */
+int ksdk_port_init(void);
+
+/* software algorithm, by wolfcrypt */
+#if defined(FREESCALE_LTC_TFM)
+ void wolfcrypt_fp_mul(fp_int *A, fp_int *B, fp_int *C);
+ int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c);
+ int wolfcrypt_fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);
+ int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c);
+ int wolfcrypt_fp_invmod(fp_int *a, fp_int *b, fp_int *c);
+ int _wolfcrypt_fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y);
+ int _fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y);
+ #ifndef NO_RSA
+ #include
+ int wc_RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng);
+ #endif
+#endif /* FREESCALE_LTC_TFM */
+
+#if defined(FREESCALE_LTC_ECC)
+ #include "fsl_ltc.h"
+
+ typedef enum _fsl_ltc_ecc_coordinate_system
+ {
+ kLTC_Weierstrass = 0U, /*!< Point coordinates on an elliptic curve in Weierstrass form */
+ kLTC_Curve25519 = 1U, /*!< Point coordinates on an Curve25519 elliptic curve in Montgomery form */
+ kLTC_Ed25519 = 2U, /*!< Point coordinates on an Ed25519 elliptic curve in twisted Edwards form */
+ } fsl_ltc_ecc_coordinate_system_t;
+
+ int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m);
+
+ #ifdef HAVE_CURVE25519
+ int wc_curve25519(ECPoint *q, byte *n, const ECPoint *p, fsl_ltc_ecc_coordinate_system_t type);
+ const ECPoint *wc_curve25519_GetBasePoint(void);
+ status_t LTC_PKHA_Curve25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut);
+ status_t LTC_PKHA_WeierstrassToCurve25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut);
+ status_t LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point_t *ltcPoint);
+ #endif
+
+ #ifdef HAVE_ED25519
+ status_t LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut);
+ status_t LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut);
+ status_t LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point_t *ltcPointIn,
+ const uint8_t *N,
+ size_t sizeN,
+ ltc_pkha_ecc_point_t *ltcPointOut,
+ fsl_ltc_ecc_coordinate_system_t typeOut);
+ const ltc_pkha_ecc_point_t *LTC_PKHA_Ed25519_BasePoint(void);
+ status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey, size_t pubKeySize, ltc_pkha_ecc_point_t *ltcPointOut);
+ status_t LTC_PKHA_sc_reduce(uint8_t *a);
+ status_t LTC_PKHA_sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c);
+ status_t LTC_PKHA_SignatureForVerify(uint8_t *rcheck, const unsigned char *a, const unsigned char *b, ed25519_key *key);
+ status_t LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point_t *ltcPointIn, uint8_t *p);
+ #endif
+
+#endif /* FREESCALE_LTC_ECC */
+
+#endif /* _KSDK_PORT_H_ */
diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h
index 9db159ce0..d7f5ccaf9 100644
--- a/wolfssl/wolfcrypt/rsa.h
+++ b/wolfssl/wolfcrypt/rsa.h
@@ -76,6 +76,7 @@ enum {
RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */
};
+
/* RSA */
typedef struct RsaKey {
mp_int n, e, d, p, q, dP, dQ, u;
diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h
index 6550ca80d..6b609c49e 100644
--- a/wolfssl/wolfcrypt/settings.h
+++ b/wolfssl/wolfcrypt/settings.h
@@ -85,8 +85,8 @@
/* Uncomment next line if building for Freescale KSDK Bare Metal */
/* #define FREESCALE_KSDK_BM */
-/* Uncomment next line if building for Freescale FreeRTOS */
-/* #define FREESCALE_FREE_RTOS */
+/* Uncomment next line if building for Freescale KSDK FreeRTOS (old name FREESCALE_FREE_RTOS) */
+/* #define FREESCALE_KSDK_FREERTOS */
/* Uncomment next line if using STM32F2 */
/* #define WOLFSSL_STM32F2 */
@@ -188,7 +188,9 @@
#if defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_ROWLEY_ARM)
#define NO_MAIN_DRIVER
#define SINGLE_THREADED
- #define USE_CERT_BUFFERS_1024
+ #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096)
+ #define USE_CERT_BUFFERS_1024
+ #endif
#define BENCH_EMBEDDED
#define NO_FILESYSTEM
#define NO_WRITEV
@@ -240,7 +242,9 @@
#define WOLFSSL_USER_IO
#define NO_FILESYSTEM
#define NO_CERT
- #define USE_CERT_BUFFERS_1024
+ #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096)
+ #define USE_CERT_BUFFERS_1024
+ #endif
#define NO_WRITEV
#define NO_DEV_RANDOM
#define NO_SHA512
@@ -713,76 +717,214 @@ static char *fgets(char *buff, int sz, FILE *fp)
#define MQX_FILE_PTR FILE *
#define IO_SEEK_SET SEEK_SET
#define IO_SEEK_END SEEK_END
-#endif
+#endif /* FREESCALE_KSDK_MQX */
+
+#if defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
+ /* Allows use of DH with fixed points if uncommented and NO_DH is removed */
+ /* WOLFSSL_DH_CONST */
+ /* Allows use of DH with fixed points if uncommented and NO_DH is removed */
+ /* WOLFSSL_DH_CONST */
+ /* Allows use of DH with fixed points if uncommented and NO_DH is removed */
+ /* WOLFSSL_DH_CONST */
+ #define NO_FILESYSTEM
+ #define WOLFSSL_CRYPT_HW_MUTEX 1
+
+ #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY)
+ #define XMALLOC(s, h, type) pvPortMalloc((s))
+ #define XFREE(p, h, type) vPortFree((p))
+ #endif
+
+ //#define USER_TICKS
+ /* Allows use of DH with fixed points if uncommented and NO_DH is removed */
+ /* WOLFSSL_DH_CONST */
+ #define WOLFSSL_LWIP
+ #define FREERTOS_TCP
+
+ #define FREESCALE_FREE_RTOS
+ #define FREERTOS_SOCKET_ERROR ( -1 )
+ #define FREERTOS_EWOULDBLOCK ( -2 )
+ #define FREERTOS_EINVAL ( -4 )
+ #define FREERTOS_EADDRNOTAVAIL ( -5 )
+ #define FREERTOS_EADDRINUSE ( -6 )
+ #define FREERTOS_ENOBUFS ( -7 )
+ #define FREERTOS_ENOPROTOOPT ( -8 )
+#endif /* FREESCALE_FREE_RTOS || FREESCALE_KSDK_FREERTOS */
#ifdef FREESCALE_KSDK_BM
#define FREESCALE_COMMON
#define WOLFSSL_USER_IO
#define SINGLE_THREADED
#define NO_FILESYSTEM
- #define USE_WOLFSSL_MEMORY
-#endif
-
-#ifdef FREESCALE_FREE_RTOS
- #define FREESCALE_COMMON
- #define NO_FILESYSTEM
- #define NO_MAIN_DRIVER
- #define XMALLOC(s, h, t) OSA_MemAlloc(s);(void)h;(void)t;
- #define XFREE(p, h, t) {void* xp = (p); if((xp)) OSA_MemFree((xp));}
- #ifdef FREESCALE_KSDK_BM
- #error Baremetal and FreeRTOS cannot be both enabled at the same time!
- #endif
- #ifndef SINGLE_THREADED
- #include "FreeRTOS.h"
- #include "semphr.h"
- #endif
-#endif
+ #define USER_TICKS
+#endif /* FREESCALE_KSDK_BM */
#ifdef FREESCALE_COMMON
#define SIZEOF_LONG_LONG 8
/* disable features */
+ #undef NO_WRITEV
#define NO_WRITEV
+ #undef NO_DEV_RANDOM
#define NO_DEV_RANDOM
+ #undef NO_RABBIT
#define NO_RABBIT
+ #undef NO_WOLFSSL_DIR
#define NO_WOLFSSL_DIR
+ #undef NO_RC4
+ #define NO_RC4
/* enable features */
+ #undef USE_FAST_MATH
#define USE_FAST_MATH
- #define HAVE_ECC
- #define HAVE_AESGCM
- /* memory reduction */
+ #define USE_CERT_BUFFERS_2048
+ #define BENCH_EMBEDDED
+
#define TFM_TIMING_RESISTANT
#define ECC_TIMING_RESISTANT
- #define ALT_ECC_SIZE
- /* setting for PIT timer */
- #define PIT_INSTANCE 0
- #define PIT_CHANNEL 0
-
- #if defined(FREESCALE_KSDK_MQX) || defined(FREESCALE_KSDK_BM) || \
- defined(FREESCALE_FREE_RTOS)
- #include "fsl_device_registers.h"
+ #undef HAVE_ECC
+ #define HAVE_ECC
+ #ifndef NO_AES
+ #undef HAVE_AESCCM
+ #define HAVE_AESCCM
+ #undef HAVE_AESGCM
+ #define HAVE_AESGCM
+ #undef WOLFSSL_AES_COUNTER
+ #define WOLFSSL_AES_COUNTER
+ #undef WOLFSSL_AES_DIRECT
+ #define WOLFSSL_AES_DIRECT
#endif
+ #include "fsl_common.h"
+
/* random seed */
#define NO_OLD_RNGNAME
- #if (FSL_FEATURE_SOC_TRNG_COUNT > 0)
- #define FREESCALE_TRNG
- #define TRNG_INSTANCE (0)
- #elif (FSL_FEATURE_SOC_RNG_COUNT > 0)
- #include "fsl_rnga_driver.h"
+ #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
+ #define FREESCALE_KSDK_2_0_TRNG
+ #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
+ #define FREESCALE_KSDK_2_0_RNGA
+ #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS) && !defined(FREESCALE_KSDK_FREERTOS)
#define FREESCALE_RNGA
#define RNGA_INSTANCE (0)
- #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS)
/* defaulting to K70 RNGA, user should change if different */
/* #define FREESCALE_K53_RNGB */
#define FREESCALE_K70_RNGA
#endif
/* HW crypto */
- /* #define FREESCALE_MMCAU */
+ /* automatic enable based on Kinetis feature */
+ /* if case manual selection is required, for example for benchmarking purposes,
+ * just define FREESCALE_USE_MMCAU or FREESCALE_USE_LTC or none of these two macros (for software only)
+ * both can be enabled simultaneously as LTC has priority over MMCAU in source code.
+ */
+ /* #define FSL_HW_CRYPTO_MANUAL_SELECTION */
+ #ifndef FSL_HW_CRYPTO_MANUAL_SELECTION
+ #if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && FSL_FEATURE_SOC_MMCAU_COUNT
+ #define FREESCALE_USE_MMCAU
+ #endif
+
+ #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT
+ #define FREESCALE_USE_LTC
+ #endif
+ #else
+ /* #define FREESCALE_USE_MMCAU */
+ /* #define FREESCALE_USE_LTC */
+ #endif
+#endif /* FREESCALE_COMMON */
+
+#ifdef FREESCALE_USE_MMCAU
+ /* AES and DES */
+ #define FREESCALE_MMCAU
+ /* MD5, SHA-1 and SHA-256 */
+ #define FREESCALE_MMCAU_SHA
+#endif /* FREESCALE_USE_MMCAU */
+
+#ifdef FREESCALE_USE_LTC
+ #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT
+ #define FREESCALE_LTC
+ #define LTC_BASE LTC0
+
+ #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES
+ #define FREESCALE_LTC_DES
+ #endif
+
+ #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM
+ #define FREESCALE_LTC_AES_GCM
+ #endif
+
+ #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA
+ #define FREESCALE_LTC_SHA
+ #endif
+
+ #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA
+ #define FREESCALE_LTC_ECC
+ #define FREESCALE_LTC_TFM
+
+ /* the LTC PKHA hardware limit is 2048 bits (256 bytes) for integer arithmetic.
+ the LTC_MAX_INT_BYTES defines the size of local variables that hold big integers. */
+ #ifndef LTC_MAX_INT_BYTES
+ #define LTC_MAX_INT_BYTES (256)
+ #endif
+
+ /* This FREESCALE_LTC_TFM_RSA_4096_ENABLE macro can be defined.
+ * In such a case both software and hardware algorithm
+ * for TFM is linked in. The decision for which algorithm is used is determined at runtime
+ * from size of inputs. If inputs and result can fit into LTC (see LTC_MAX_INT_BYTES)
+ * then we call hardware algorithm, otherwise we call software algorithm.
+ *
+ * Chinese reminder theorem is used to break RSA 4096 exponentiations (both public and private key)
+ * into several computations with 2048-bit modulus and exponents.
+ */
+ /* #define FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+
+ /* ECC-384, ECC-256, ECC-224 and ECC-192 have been enabled with LTC PKHA acceleration */
+ #ifdef HAVE_ECC
+ #undef ECC_TIMING_RESISTANT
+ #define ECC_TIMING_RESISTANT
+
+ /* the LTC PKHA hardware limit is 512 bits (64 bytes) for ECC.
+ the LTC_MAX_ECC_BITS defines the size of local variables that hold ECC parameters
+ and point coordinates */
+ #ifndef LTC_MAX_ECC_BITS
+ #define LTC_MAX_ECC_BITS (384)
+ #endif
+
+ /* Enable curves up to 384 bits */
+ #if !defined(ECC_USER_CURVES) && !defined(HAVE_ALL_CURVES)
+ #define ECC_USER_CURVES
+ #define HAVE_ECC192
+ #define HAVE_ECC224
+ #undef NO_ECC256
+ #define HAVE_ECC384
+ #endif
+
+ /* enable features */
+ #undef HAVE_CURVE25519
+ #define HAVE_CURVE25519
+ #undef HAVE_ED25519
+ #define HAVE_ED25519
+ #undef WOLFSSL_SHA512
+ #define WOLFSSL_SHA512
+ #endif
+ #endif
+ #endif
+#endif /* FREESCALE_USE_LTC */
+
+#ifdef FREESCALE_LTC_TFM_RSA_4096_ENABLE
+ #undef USE_CERT_BUFFERS_2048
+ #define USE_CERT_BUFFERS_4096
+ #define FP_MAX_BITS (8192)
+
+ #undef NO_DH
+ #define NO_DH
+ #undef NO_DSA
+ #define NO_DSA
+#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */
+
+/* if LTC has AES engine but doesn't have GCM, use software with LTC AES ECB mode */
+#if defined(FREESCALE_USE_LTC) && !defined(FREESCALE_LTC_AES_GCM)
+ #define GCM_TABLE
#endif
#ifdef WOLFSSL_STM32F2
@@ -1044,9 +1186,10 @@ static char *fgets(char *buff, int sz, FILE *fp)
#endif
-/* FreeScale MMCAU hardware crypto has 4 byte alignment */
+/* FreeScale MMCAU hardware crypto has 4 byte alignment.
+ However, fsl_mmcau.h gives API with no alignment requirements (4 byte alignment is managed internally by fsl_mmcau.c) */
#ifdef FREESCALE_MMCAU
- #define WOLFSSL_MMCAU_ALIGNMENT 4
+ #define WOLFSSL_MMCAU_ALIGNMENT 0
#endif
/* if using hardware crypto and have alignment requirements, specify the
diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h
index c65b0e52c..b107f08b5 100644
--- a/wolfssl/wolfcrypt/sha.h
+++ b/wolfssl/wolfcrypt/sha.h
@@ -32,6 +32,10 @@
#include
#endif
+#ifdef FREESCALE_LTC_SHA
+ #include "fsl_ltc.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -56,16 +60,20 @@ enum {
/* Sha digest */
typedef struct Sha {
- word32 buffLen; /* in bytes */
- word32 loLen; /* length in bytes */
- word32 hiLen; /* length in bytes */
- word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)];
- #ifndef WOLFSSL_PIC32MZ_HASH
- word32 digest[SHA_DIGEST_SIZE / sizeof(word32)];
+ #ifdef FREESCALE_LTC_SHA
+ ltc_hash_ctx_t ctx;
#else
- word32 digest[PIC32_HASH_SIZE / sizeof(word32)];
- pic32mz_desc desc; /* Crypt Engine descriptor */
- #endif
+ word32 buffLen; /* in bytes */
+ word32 loLen; /* length in bytes */
+ word32 hiLen; /* length in bytes */
+ word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)];
+ #ifndef WOLFSSL_PIC32MZ_HASH
+ word32 digest[SHA_DIGEST_SIZE / sizeof(word32)];
+ #else
+ word32 digest[PIC32_HASH_SIZE / sizeof(word32)];
+ pic32mz_desc desc; /* Crypt Engine descriptor */
+ #endif
+ #endif /* FREESCALE_LTC_SHA */
} Sha;
#else /* WOLFSSL_TI_HASH */
diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h
index f0109c4ea..790d87c94 100644
--- a/wolfssl/wolfcrypt/sha256.h
+++ b/wolfssl/wolfcrypt/sha256.h
@@ -34,6 +34,10 @@
#include
#endif
+#ifdef FREESCALE_LTC_SHA
+ #include "fsl_ltc.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
@@ -56,6 +60,9 @@ enum {
/* Sha256 digest */
typedef struct Sha256 {
+#ifdef FREESCALE_LTC_SHA
+ ltc_hash_ctx_t ctx;
+#else
word32 buffLen; /* in bytes */
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
@@ -64,6 +71,7 @@ typedef struct Sha256 {
#ifdef WOLFSSL_PIC32MZ_HASH
pic32mz_desc desc ; /* Crypt Engine descriptor */
#endif
+#endif /* FREESCALE_LTC_SHA */
} Sha256;
#else /* WOLFSSL_TI_HASH */
diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h
index 79de9bc72..c7cf9fa06 100644
--- a/wolfssl/wolfcrypt/tfm.h
+++ b/wolfssl/wolfcrypt/tfm.h
@@ -547,6 +547,7 @@ int fp_leading_bit(fp_int *a);
int fp_unsigned_bin_size(fp_int *a);
void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c);
void fp_to_unsigned_bin(fp_int *a, unsigned char *b);
+int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b);
/*int fp_signed_bin_size(fp_int *a);*/
/*void fp_read_signed_bin(fp_int *a, const unsigned char *b, int c);*/