Fix NULL+0 undefined behavior in ECB encryption and decryption

psa_cipher_encrypt() and psa_cipher_decrypt() sometimes add a zero offset to
a null pointer when the cipher does not use an IV. This is undefined
behavior, although it works as naively expected on most platforms. This
can cause a crash with modern Clang+ASan (depending on compiler optimizations).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/common.h b/library/common.h
index a630fcc..5359822 100644
--- a/library/common.h
+++ b/library/common.h
@@ -25,6 +25,7 @@
 
 #include "mbedtls/build_info.h"
 
+#include <stddef.h>
 #include <stdint.h>
 
 /** Helper to define a function as static except when building invasive tests.
@@ -68,6 +69,42 @@
  */
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
+/** Return an offset into a buffer.
+ *
+ * This is just the addition of an offset to a pointer, except that this
+ * function also accepts an offset of 0 into a buffer whose pointer is null.
+ *
+ * \param p     Pointer to a buffer of at least n bytes.
+ *              This may be \p NULL if \p n is zero.
+ * \param n     An offset in bytes.
+ * \return      Pointer to offset \p n in the buffer \p p.
+ *              Note that this is only a valid pointer if the size of the
+ *              buffer is at least \p n + 1.
+ */
+static inline unsigned char *mbedtls_buffer_offset(
+    unsigned char *p, size_t n )
+{
+    return( p == NULL ? NULL : p + n );
+}
+
+/** Return an offset into a read-only buffer.
+ *
+ * This is just the addition of an offset to a pointer, except that this
+ * function also accepts an offset of 0 into a buffer whose pointer is null.
+ *
+ * \param p     Pointer to a buffer of at least n bytes.
+ *              This may be \p NULL if \p n is zero.
+ * \param n     An offset in bytes.
+ * \return      Pointer to offset \p n in the buffer \p p.
+ *              Note that this is only a valid pointer if the size of the
+ *              buffer is at least \p n + 1.
+ */
+static inline const unsigned char *mbedtls_buffer_offset_const(
+    const unsigned char *p, size_t n )
+{
+    return( p == NULL ? NULL : p + n );
+}
+
 /** Byte Reading Macros
  *
  * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th