Browse Source

introduce `LTC_NULL_TERMINATED` function attribute

In order to be able to check at compile time whether a vararg function
is correctly NULL-terminated.

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 years ago
parent
commit
0ad23e1b4c

+ 9 - 0
src/headers/tomcrypt_cfg.h

@@ -295,6 +295,15 @@ typedef unsigned long ltc_mp_digit;
    #define LTC_ALIGN(n)
    #define LTC_ALIGN(n)
 #endif
 #endif
 
 
+/* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code
+ * before including `tomcrypt.h` to disable this functionality.
+ */
+#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(LTC_NO_NULL_TERMINATION_CHECK)
+#   define LTC_NULL_TERMINATED __attribute__((sentinel))
+#else
+#   define LTC_NULL_TERMINATED
+#endif
+
 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
 #  define LTC_DEPRECATED(s) __attribute__((deprecated("replaced by " #s)))
 #  define LTC_DEPRECATED(s) __attribute__((deprecated("replaced by " #s)))
 #  define PRIVATE_LTC_DEPRECATED_PRAGMA(s) _Pragma(#s)
 #  define PRIVATE_LTC_DEPRECATED_PRAGMA(s) _Pragma(#s)

+ 2 - 1
src/headers/tomcrypt_hash.h

@@ -494,7 +494,8 @@ int hash_memory(int hash,
                 const unsigned char *in,  unsigned long inlen,
                 const unsigned char *in,  unsigned long inlen,
                       unsigned char *out, unsigned long *outlen);
                       unsigned char *out, unsigned long *outlen);
 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
 int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
-                      const unsigned char *in, unsigned long inlen, ...);
+                      const unsigned char *in, unsigned long inlen, ...)
+                      LTC_NULL_TERMINATED;
 
 
 #ifndef LTC_NO_FILE
 #ifndef LTC_NO_FILE
 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);

+ 22 - 8
src/headers/tomcrypt_mac.h

@@ -19,7 +19,8 @@ int hmac_memory(int hash,
 int hmac_memory_multi(int hash,
 int hmac_memory_multi(int hash,
                 const unsigned char *key,  unsigned long keylen,
                 const unsigned char *key,  unsigned long keylen,
                       unsigned char *out,  unsigned long *outlen,
                       unsigned char *out,  unsigned long *outlen,
-                const unsigned char *in,   unsigned long inlen, ...);
+                const unsigned char *in,   unsigned long inlen, ...)
+                LTC_NULL_TERMINATED;
 int hmac_file(int hash, const char *fname, const unsigned char *key,
 int hmac_file(int hash, const char *fname, const unsigned char *key,
               unsigned long keylen,
               unsigned long keylen,
               unsigned char *out, unsigned long *outlen);
               unsigned char *out, unsigned long *outlen);
@@ -47,7 +48,8 @@ int omac_memory(int cipher,
 int omac_memory_multi(int cipher,
 int omac_memory_multi(int cipher,
                 const unsigned char *key, unsigned long keylen,
                 const unsigned char *key, unsigned long keylen,
                       unsigned char *out, unsigned long *outlen,
                       unsigned char *out, unsigned long *outlen,
-                const unsigned char *in,  unsigned long inlen, ...);
+                const unsigned char *in,  unsigned long inlen, ...)
+                LTC_NULL_TERMINATED;
 int omac_file(int cipher,
 int omac_file(int cipher,
               const unsigned char *key, unsigned long keylen,
               const unsigned char *key, unsigned long keylen,
               const          char *filename,
               const          char *filename,
@@ -83,7 +85,8 @@ int pmac_memory(int cipher,
 int pmac_memory_multi(int cipher,
 int pmac_memory_multi(int cipher,
                 const unsigned char *key, unsigned long keylen,
                 const unsigned char *key, unsigned long keylen,
                       unsigned char *out, unsigned long *outlen,
                       unsigned char *out, unsigned long *outlen,
-                const unsigned char *in, unsigned long inlen, ...);
+                const unsigned char *in, unsigned long inlen, ...)
+                LTC_NULL_TERMINATED;
 
 
 int pmac_file(int cipher,
 int pmac_file(int cipher,
              const unsigned char *key, unsigned long keylen,
              const unsigned char *key, unsigned long keylen,
@@ -112,7 +115,10 @@ int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long ke
 int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen);
 int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen);
 int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen);
 int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen);
 int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
 int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in,  unsigned long inlen, ...);
+int poly1305_memory_multi(const unsigned char *key, unsigned long keylen,
+                                unsigned char *mac, unsigned long *maclen,
+                          const unsigned char *in,  unsigned long inlen, ...)
+                          LTC_NULL_TERMINATED;
 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int poly1305_test(void);
 int poly1305_test(void);
 #endif /* LTC_POLY1305 */
 #endif /* LTC_POLY1305 */
@@ -123,7 +129,10 @@ int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned c
 int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen);
 int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen);
 int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen);
 int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen);
 int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
 int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in,  unsigned long inlen, ...);
+int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen,
+                                  unsigned char *mac, unsigned long *maclen,
+                            const unsigned char *in,  unsigned long inlen, ...)
+                            LTC_NULL_TERMINATED;
 int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int blake2smac_test(void);
 int blake2smac_test(void);
 #endif /* LTC_BLAKE2SMAC */
 #endif /* LTC_BLAKE2SMAC */
@@ -134,7 +143,10 @@ int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned c
 int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen);
 int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen);
 int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen);
 int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen);
 int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
 int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in,  unsigned long inlen, ...);
+int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen,
+                                  unsigned char *mac, unsigned long *maclen,
+                            const unsigned char *in,  unsigned long inlen, ...)
+                            LTC_NULL_TERMINATED;
 int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
 int blake2bmac_test(void);
 int blake2bmac_test(void);
 #endif /* LTC_BLAKE2BMAC */
 #endif /* LTC_BLAKE2BMAC */
@@ -186,7 +198,8 @@ int xcbc_memory(int cipher,
 int xcbc_memory_multi(int cipher,
 int xcbc_memory_multi(int cipher,
                 const unsigned char *key, unsigned long keylen,
                 const unsigned char *key, unsigned long keylen,
                       unsigned char *out, unsigned long *outlen,
                       unsigned char *out, unsigned long *outlen,
-                const unsigned char *in,  unsigned long inlen, ...);
+                const unsigned char *in,  unsigned long inlen, ...)
+                LTC_NULL_TERMINATED;
 int xcbc_file(int cipher,
 int xcbc_file(int cipher,
               const unsigned char *key, unsigned long keylen,
               const unsigned char *key, unsigned long keylen,
               const          char *filename,
               const          char *filename,
@@ -220,7 +233,8 @@ int f9_memory(int cipher,
 int f9_memory_multi(int cipher,
 int f9_memory_multi(int cipher,
                 const unsigned char *key, unsigned long keylen,
                 const unsigned char *key, unsigned long keylen,
                       unsigned char *out, unsigned long *outlen,
                       unsigned char *out, unsigned long *outlen,
-                const unsigned char *in,  unsigned long inlen, ...);
+                const unsigned char *in,  unsigned long inlen, ...)
+                LTC_NULL_TERMINATED;
 int f9_file(int cipher,
 int f9_file(int cipher,
               const unsigned char *key, unsigned long keylen,
               const unsigned char *key, unsigned long keylen,
               const          char *fname,
               const          char *fname,

+ 3 - 3
src/headers/tomcrypt_math.h

@@ -502,9 +502,9 @@ typedef struct {
 
 
 extern ltc_math_descriptor ltc_mp;
 extern ltc_math_descriptor ltc_mp;
 
 
-int ltc_init_multi(void **a, ...);
-void ltc_deinit_multi(void *a, ...);
-void ltc_cleanup_multi(void **a, ...);
+int ltc_init_multi(void **a, ...) LTC_NULL_TERMINATED;
+void ltc_deinit_multi(void *a, ...) LTC_NULL_TERMINATED;
+void ltc_cleanup_multi(void **a, ...) LTC_NULL_TERMINATED;
 
 
 #ifdef LTM_DESC
 #ifdef LTM_DESC
 extern const ltc_math_descriptor ltm_desc;
 extern const ltc_math_descriptor ltm_desc;

+ 3 - 3
src/headers/tomcrypt_misc.h

@@ -93,7 +93,7 @@ const char *error_to_string(int err);
 extern const char *crypt_build_settings;
 extern const char *crypt_build_settings;
 
 
 /* ---- HMM ---- */
 /* ---- HMM ---- */
-int crypt_fsa(void *mp, ...);
+int crypt_fsa(void *mp, ...) LTC_NULL_TERMINATED;
 
 
 /* ---- Dynamic language support ---- */
 /* ---- Dynamic language support ---- */
 int crypt_get_constant(const char* namein, int *valueout);
 int crypt_get_constant(const char* namein, int *valueout);
@@ -172,8 +172,8 @@ typedef enum ssh_data_type_ {
 } ssh_data_type;
 } ssh_data_type;
 
 
 /* VA list handy helpers with tuples of <type, data> */
 /* VA list handy helpers with tuples of <type, data> */
-int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
-int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...);
+int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) LTC_NULL_TERMINATED;
+int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...) LTC_NULL_TERMINATED;
 #endif /* LTC_SSH */
 #endif /* LTC_SSH */
 
 
 int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);
 int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);

+ 2 - 2
src/headers/tomcrypt_pk.h

@@ -654,8 +654,8 @@ int der_encode_setof(const ltc_asn1_list *list, unsigned long inlen,
                      unsigned char *out,        unsigned long *outlen);
                      unsigned char *out,        unsigned long *outlen);
 
 
 /* VA list handy helpers with triplets of <type, size, data> */
 /* VA list handy helpers with triplets of <type, size, data> */
-int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
-int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
+int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) LTC_NULL_TERMINATED;
+int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) LTC_NULL_TERMINATED;
 
 
 /* FLEXI DECODER handle unknown list decoder */
 /* FLEXI DECODER handle unknown list decoder */
 int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
 int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);

+ 2 - 1
src/headers/tomcrypt_private.h

@@ -384,7 +384,8 @@ extern const unsigned long  der_asn1_tag_to_type_map_sz;
 extern const int der_asn1_type_to_identifier_map[];
 extern const int der_asn1_type_to_identifier_map[];
 extern const unsigned long der_asn1_type_to_identifier_map_sz;
 extern const unsigned long der_asn1_type_to_identifier_map_sz;
 
 
-int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...);
+int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
+                                 LTC_NULL_TERMINATED;
 
 
 int der_teletex_char_encode(int c);
 int der_teletex_char_encode(int c);
 int der_teletex_value_decode(int v);
 int der_teletex_value_decode(int v);