From: Nikos Mavrogiannopoulos Date: Tue, 11 Nov 2014 10:25:44 +0000 (+0100) Subject: Added gnutls_memcmp() and exported it. X-Git-Tag: gnutls_3_4_0~646 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8e6f8a967647ae79ee77c27754951602ffbe272;p=thirdparty%2Fgnutls.git Added gnutls_memcmp() and exported it. --- diff --git a/lib/Makefile.am b/lib/Makefile.am index febc59bbaa..528c23f984 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -82,7 +82,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \ random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c \ gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \ crypto-backend.c verify-tofu.c pin.c tpm.c fips.c \ - safe-memset.c inet_pton.c atfork.c atfork.h + safe-memfuncs.c inet_pton.c atfork.c atfork.h if ENABLE_SELF_CHECKS COBJECTS += crypto-selftests.c crypto-selftests-pk.c diff --git a/lib/crypto-api.c b/lib/crypto-api.c index c7add3e6b9..d0e30b7e49 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -714,7 +714,7 @@ gnutls_aead_cipher_decrypt(gnutls_aead_cipher_hd_t handle, ptr = ctext; ptr += ctext_len; - if (memcmp(ptr, tag, h->tag_size) != 0) + if (gnutls_memcmp(ptr, tag, h->tag_size) != 0) return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); h->nonce_set = 0; diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c index 84b7d69dbf..159c501d13 100644 --- a/lib/ext/session_ticket.c +++ b/lib/ext/session_ticket.c @@ -119,7 +119,7 @@ decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv, } _gnutls_cipher_tag(&cipher_hd, final, TAG_SIZE); - if (memcmp(ticket->tag, final, TAG_SIZE) != 0) { + if (gnutls_memcmp(ticket->tag, final, TAG_SIZE) != 0) { gnutls_assert(); ret = GNUTLS_E_DECRYPTION_FAILED; goto cleanup; diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 32d4576136..ec68238c0c 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -538,7 +538,7 @@ ciphertext_to_compressed(gnutls_session_t session, if (unlikely(ret < 0)) return gnutls_assert_val(ret); - if (unlikely(memcmp(tag, &ciphertext->data[ciphertext->size-tag_size], tag_size) != 0)) { + if (unlikely(gnutls_memcmp(tag, &ciphertext->data[ciphertext->size-tag_size], tag_size) != 0)) { /* HMAC was not the same. */ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); } @@ -798,7 +798,7 @@ ciphertext_to_compressed(gnutls_session_t session, * a memcmp comparison is negligible over the crypto operations. */ if (unlikely - (memcmp(tag, tag_ptr, tag_size) != 0 || pad_failed != 0)) { + (gnutls_memcmp(tag, tag_ptr, tag_size) != 0 || pad_failed != 0)) { /* HMAC was not the same. */ dummy_wait(params, compressed, pad_failed, pad, length + preamble_size); diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 908f056d08..d017c79345 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1517,6 +1517,9 @@ extern _SYM_EXPORT char *(*gnutls_strdup) (const char *); /* a variant of memset that doesn't get optimized out */ void gnutls_memset(void *data, int c, size_t size); +/* constant time memcmp */ +int gnutls_memcmp(const void *s1, const void *s2, size_t n); + typedef void (*gnutls_log_func) (int, const char *); typedef void (*gnutls_audit_log_func) (gnutls_session_t, const char *); void gnutls_global_set_log_function(gnutls_log_func log_func); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 0dd9de0246..26ed6ac7fa 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1059,6 +1059,7 @@ GNUTLS_3_1_0 { gnutls_aead_cipher_deinit; gnutls_dh_params_import_raw2; gnutls_memset; + gnutls_memcmp; gnutls_pkcs12_bag_set_privkey; } GNUTLS_3_0_0; diff --git a/lib/safe-memset.c b/lib/safe-memfuncs.c similarity index 72% rename from lib/safe-memset.c rename to lib/safe-memfuncs.c index c959357822..e18eff403c 100644 --- a/lib/safe-memset.c +++ b/lib/safe-memfuncs.c @@ -24,7 +24,7 @@ # include #endif -/*- +/** * gnutls_memset: * @data: the memory to set * @c: the constant byte to fill the memory with @@ -35,8 +35,8 @@ * * Returns: void. * - * Since: 3.3.3 - -*/ + * Since: 3.4.0 + **/ void gnutls_memset(void *data, int c, size_t size) { volatile unsigned volatile_zero = 0; @@ -53,6 +53,34 @@ void gnutls_memset(void *data, int c, size_t size) } } +/** + * gnutls_memcmp: + * @s1: the first address to compare + * @s2: the second address to compare + * @n: the size of memory to compare + * + * This function will operate similarly to memcmp(), but instead + * of comparing it will return 0 on memory match and non-zero + * on difference. + * + * Returns: void. + * + * Since: 3.4.0 + **/ +int gnutls_memcmp(const void *s1, const void *s2, size_t n) +{ + unsigned i; + unsigned status = 0; + const uint8_t *_s1 = s1; + const uint8_t *_s2 = s2; + + for (i=0;i