Introduce MBEDTLS_OPTIMIZE_TINYCRYPT_ASM

Make the ASM optimizations in tinycrypt optional.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 9fa3918..6281537 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -116,6 +116,8 @@
     MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED
 
 #define MBEDTLS_USE_TINYCRYPT
+#define MBEDTLS_HAVE_ASM
+#define MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
 
 /* X.509 CRT parsing */
 #define MBEDTLS_X509_USE_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 5e2a661..f08aea5 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -130,6 +130,12 @@
 #error "MBEDTLS_USE_TINYCRYPT defined, but not all prerequesites"
 #endif
 
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM) &&           \
+    ( !defined(MBEDTLS_HAVE_ASM) || \
+      !defined(MBEDTLS_USE_TINYCRYPT) )
+#error "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_NIST_KW_C) && \
     ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
 #error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 06cdde9..3587bba 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -2703,6 +2703,21 @@
 //#define MBEDTLS_USE_TINYCRYPT
 
 /**
+ * \def MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+ *
+ * Optimize TinyCrypt operations using assembly.
+ * Add T32/A32 assembly for core tinycrypt/microecc routines, for ARMC5 and GCC;
+ * Use fast integer types to avoid frequent narrowing instructions;
+ * Use __builtin_clz and avoid boolean ops.
+ *
+ * Requires: MBEDTLS_USE_TINYCRYPT
+ *           MBEDTLS_HAVE_ASM
+ *
+ * Module:  tinycrypt/ecc.c
+ */
+//#define MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+
+/**
  * \def MBEDTLS_ENTROPY_C
  *
  * Enable the platform-specific entropy code.
diff --git a/library/version_features.c b/library/version_features.c
index 2ef9d12..1a226c8 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -678,6 +678,9 @@
 #if defined(MBEDTLS_USE_TINYCRYPT)
     "MBEDTLS_USE_TINYCRYPT",
 #endif /* MBEDTLS_USE_TINYCRYPT */
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM)
+    "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM",
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
 #if defined(MBEDTLS_ENTROPY_C)
     "MBEDTLS_ENTROPY_C",
 #endif /* MBEDTLS_ENTROPY_C */
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index ac0ef2e..ba4b596 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1850,6 +1850,14 @@
     }
 #endif /* MBEDTLS_USE_TINYCRYPT */
 
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM)
+    if( strcmp( "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_OPTIMIZE_TINYCRYPT_ASM );
+        return( 0 );
+    }
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
+
 #if defined(MBEDTLS_ENTROPY_C)
     if( strcmp( "MBEDTLS_ENTROPY_C", config ) == 0 )
     {
diff --git a/scripts/config.pl b/scripts/config.pl
index 1c3422e..0a65ef4 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -59,6 +59,7 @@
 #   MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
 #   MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
 #   MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+#   MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
 #   and any symbol beginning _ALT
 #
 # The baremetal configuration excludes options that require a library or
@@ -144,6 +145,7 @@
 MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
 MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
 MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
 _ALT\s*$
 );
 
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index 6c944d3..79ecc8c 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -70,15 +70,15 @@
 #include <string.h>
 #include "mbedtls/platform_util.h"
 
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
 #ifdef __CC_ARM
 #pragma diag_suppress 667 // strict diagnostic: "asm" function is nonstandard
 #endif
 
-#if defined MBEDTLS_HAVE_ASM
 #ifndef asm
 #define asm __asm
 #endif
-#endif
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
 
 /* Parameters for curve NIST P-256 aka secp256r1 */
 const uECC_word_t curve_p[NUM_ECC_WORDS] = {
@@ -214,7 +214,7 @@
 	return 2 * NUM_ECC_BYTES;
 }
 
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 __asm void uECC_vli_clear(uECC_word_t *vli)
 {
 #if NUM_ECC_WORDS != 8
@@ -237,7 +237,7 @@
     BX      lr
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
 void uECC_vli_clear(uECC_word_t *vli)
 {
 #if NUM_ECC_WORDS != 8
@@ -281,7 +281,7 @@
 }
 #endif
 
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 __asm uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
 {
 #if NUM_ECC_WORDS != 8
@@ -323,7 +323,7 @@
     BX      lr
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
 uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
 {
     uECC_word_t ret;
@@ -501,7 +501,7 @@
 
 /* Computes result = left - right, returning borrow, in constant time.
  * Can modify in place. */
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 __asm uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
                 const uECC_word_t *right)
 {
@@ -556,7 +556,7 @@
     POP     {r4-r8,pc}
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
 uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
              const uECC_word_t *right)
 {
@@ -638,7 +638,7 @@
 
 /* Computes result = left + right, returning carry, in constant time.
  * Can modify in place. */
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 static __asm uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
                 const uECC_word_t *right)
 {
@@ -693,7 +693,7 @@
     POP     {r4-r8,pc}
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
 static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
                 const uECC_word_t *right)
 {
@@ -779,7 +779,7 @@
 }
 
 /* Computes vli = vli >> 1. */
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 static __asm void uECC_vli_rshift1(uECC_word_t *vli)
 {
 #if defined __thumb__ &&  __TARGET_ARCH_THUMB < 4
@@ -818,7 +818,7 @@
     BX      lr
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__ && defined __thumb2__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__ && defined __thumb2__
 static void uECC_vli_rshift1(uECC_word_t *vli)
 {
     register uECC_word_t *r0 asm ("r0") = vli;
@@ -867,7 +867,7 @@
  * [in] r: 3 words of operand to add
  * [out] r: 3 words of result
  */
-#if defined MBEDTLS_HAVE_ASM && defined __CC_ARM
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
 static __asm void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t r[3])
 {
 #if defined __thumb__ &&  __TARGET_ARCH_THUMB < 4
@@ -917,7 +917,7 @@
     BX      lr
 #endif
 }
-#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
 static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t r[3])
 {
     register uECC_word_t r0 asm ("r0") = a;