mbed library sources. Supersedes mbed-src. Edited target satm32f446 for user USART3 pins

Dependents:   IGLOO_board

Fork of mbed-dev by mbed official

Revision:
182:a56a73fd2a6f
Parent:
180:96ed750bd169
--- a/targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.c	Fri Feb 16 16:09:33 2018 +0000
+++ b/targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.c	Tue Mar 20 16:56:18 2018 +0000
@@ -30,6 +30,8 @@
 static uint16_t crypto_des_avail = 1;
 /* Track if SHA H/W is available */
 static uint16_t crypto_sha_avail = 1;
+/* Track if ECC H/W is available */
+static uint16_t crypto_ecc_avail = 1;
 
 /* Crypto (AES, DES, SHA, etc.) init counter. Crypto's keeps active as it is non-zero. */
 static uint16_t crypto_init_counter = 0U;
@@ -37,12 +39,18 @@
 static bool crypto_submodule_acquire(uint16_t *submodule_avail);
 static void crypto_submodule_release(uint16_t *submodule_avail);
 
+/* Crypto done flags */
+#define CRYPTO_DONE_OK              BIT0    /* Done with OK */
+#define CRYPTO_DONE_ERR             BIT1    /* Done with error */
+
 /* Track if PRNG H/W operation is done */
 static volatile uint16_t crypto_prng_done;
 /* Track if AES H/W operation is done */
 static volatile uint16_t crypto_aes_done;
 /* Track if DES H/W operation is done */
 static volatile uint16_t crypto_des_done;
+/* Track if ECC H/W operation is done */
+static volatile uint16_t crypto_ecc_done;
 
 static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
 static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
@@ -96,7 +104,16 @@
 /* Implementation that should never be optimized out by the compiler */
 void crypto_zeroize(void *v, size_t n)
 {
-    volatile unsigned char *p = (unsigned char*) v;
+    volatile unsigned char *p = (volatile unsigned char*) v;
+    while (n--) {
+        *p++ = 0;
+    }
+}
+
+/* Implementation that should never be optimized out by the compiler */
+void crypto_zeroize32(uint32_t *v, size_t n)
+{
+    volatile uint32_t *p = (volatile uint32_t*) v;
     while (n--) {
         *p++ = 0;
     }
@@ -132,6 +149,16 @@
     crypto_submodule_release(&crypto_sha_avail);
 }
 
+bool crypto_ecc_acquire(void)
+{
+    return crypto_submodule_acquire(&crypto_ecc_avail);
+}
+
+void crypto_ecc_release(void)
+{
+    crypto_submodule_release(&crypto_ecc_avail);
+}
+
 void crypto_prng_prestart(void)
 {
     crypto_submodule_prestart(&crypto_prng_done);
@@ -162,6 +189,16 @@
     return crypto_submodule_wait(&crypto_des_done);
 }
 
+void crypto_ecc_prestart(void)
+{
+    crypto_submodule_prestart(&crypto_ecc_done);
+}
+
+bool crypto_ecc_wait(void)
+{
+    return crypto_submodule_wait(&crypto_ecc_done);
+}
+
 bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
 {
     uint32_t buff_ = (uint32_t) buff;
@@ -236,20 +273,47 @@
     /* Ensure while loop above and subsequent code are not reordered */
     __DSB();
 
-    return true;
+    if ((*submodule_done & CRYPTO_DONE_OK)) {
+        /* Done with OK */
+        return true;
+    } else if ((*submodule_done & CRYPTO_DONE_ERR)) {
+        /* Done with error */
+        return false;
+    }
+
+    return false;
 }
 
 /* Crypto interrupt handler */
 void CRYPTO_IRQHandler()
 {
-    if (PRNG_GET_INT_FLAG()) {
-        crypto_prng_done = 1;
+    uint32_t intsts;
+    
+    if ((intsts = PRNG_GET_INT_FLAG()) != 0) {
+        /* Done with OK */
+        crypto_prng_done |= CRYPTO_DONE_OK;
+        /* Clear interrupt flag */
         PRNG_CLR_INT_FLAG();
-    }  else if (AES_GET_INT_FLAG()) {
-        crypto_aes_done = 1;
+    }  else if ((intsts = AES_GET_INT_FLAG()) != 0) {
+        /* Done with OK */
+        crypto_aes_done |= CRYPTO_DONE_OK;
+        /* Clear interrupt flag */
         AES_CLR_INT_FLAG();
-    } else if (TDES_GET_INT_FLAG()) {
-        crypto_des_done = 1;
+    } else if ((intsts = TDES_GET_INT_FLAG()) != 0) {
+        /* Done with OK */
+        crypto_des_done |= CRYPTO_DONE_OK;
+        /* Clear interrupt flag */
         TDES_CLR_INT_FLAG();
+    } else if ((intsts = ECC_GET_INT_FLAG()) != 0) {
+        /* Check interrupt flags */
+        if (intsts & CRPT_INTSTS_ECCIF_Msk) {
+            /* Done with OK */
+            crypto_ecc_done |= CRYPTO_DONE_OK;
+        } else if (intsts & CRPT_INTSTS_ECCEIF_Msk) {
+            /* Done with error */
+            crypto_ecc_done |= CRYPTO_DONE_ERR;
+        }
+        /* Clear interrupt flag */
+        ECC_CLR_INT_FLAG();
     }
 }