Add en(de)crypt routine

Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
diff --git a/library/aes.c b/library/aes.c
index 6306fec..64392fc 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -963,6 +963,12 @@
     }
 #endif
 
+#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+    if (mbedtls_aesce_has_support()) {
+        return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
+    }
+#endif
+
 #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
     if (aes_padlock_ace > 0) {
         if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
diff --git a/library/aesce.c b/library/aesce.c
index ba9adc9..e6b675a 100644
--- a/library/aesce.c
+++ b/library/aesce.c
@@ -65,6 +65,66 @@
 #endif
 }
 
+static uint8x16_t aesce_encrypt_block(uint8x16_t block,
+                                      unsigned char *keys,
+                                      int rounds)
+{
+    for (int i = 0; i < rounds - 1; i++) {
+        block = vaeseq_u8(block, vld1q_u8(keys + i * 16));
+        /* AES mix columns */
+        block = vaesmcq_u8(block);
+    }
+
+    /* AES single round encryption */
+    block = vaeseq_u8(block, vld1q_u8(keys + (rounds -1) * 16));
+
+    /* Final Add (bitwise Xor) */
+    block = veorq_u8(block, vld1q_u8(keys + rounds  * 16));
+
+    return block;
+}
+
+static uint8x16_t aesce_decrypt_block(uint8x16_t block,
+                                      unsigned char *keys,
+                                      int rounds)
+{
+
+    for (int i = 0; i < rounds - 1; i++) {
+        block = vaesdq_u8(block, vld1q_u8(keys + i * 16));
+        /* AES inverse mix columns */
+        block = vaesimcq_u8(block);
+    }
+
+    /* AES single round encryption */
+    block = vaesdq_u8(block, vld1q_u8(keys + (rounds - 1) * 16));
+
+    /* Final Add (bitwise Xor) */
+    block = veorq_u8(block, vld1q_u8(keys + rounds * 16));
+
+    return block;
+}
+
+/*
+ * AES-ECB block en(de)cryption
+ */
+int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
+                            int mode,
+                            const unsigned char input[16],
+                            unsigned char output[16])
+{
+    uint8x16_t block = vld1q_u8(&input[0]);
+    unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset);
+
+    if (mode == MBEDTLS_AES_ENCRYPT) {
+        block = aesce_encrypt_block(block, keys, ctx->nr);
+    } else {
+        block = aesce_decrypt_block(block, keys, ctx->nr);
+    }
+    vst1q_u8(&output[0], block);
+
+    return 0;
+}
+
 
 /*
  * Compute decryption round keys from encryption round keys
diff --git a/library/aesce.h b/library/aesce.h
index d0e02a4..741519c 100644
--- a/library/aesce.h
+++ b/library/aesce.h
@@ -49,6 +49,21 @@
  */
 int mbedtls_aesce_has_support(void);
 
+/**
+ * \brief          Internal AES-ECB block encryption and decryption
+ *
+ * \param ctx      AES context
+ * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
+ * \param input    16-byte input block
+ * \param output   16-byte output block
+ *
+ * \return         0 on success (cannot fail)
+ */
+int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
+                            int mode,
+                            const unsigned char input[16],
+                            unsigned char output[16]);
+
 
 /**
  * \brief           Internal round key inversion. This function computes