From 92b27a4f88cbfc62d23914f05d8044abf878cfce Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 28 Feb 2019 16:23:26 +0100 Subject: [PATCH] shared: add nm_utils_memeqzero_secret() [thaller@redhat.com: the code is effectively key_is_zero() by (LGPL2.1+). I took it into our source tree and adjusted it to our style] (cherry picked from commit 6234e41153150cee4742360af1f5009c03cf2f77) --- shared/nm-utils/nm-secret-utils.c | 27 +++++++++++++++++++++++++++ shared/nm-utils/nm-secret-utils.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/shared/nm-utils/nm-secret-utils.c b/shared/nm-utils/nm-secret-utils.c index 65f99c65d9..ec5cc6b1b3 100644 --- a/shared/nm-utils/nm-secret-utils.c +++ b/shared/nm-utils/nm-secret-utils.c @@ -17,6 +17,7 @@ * Boston, MA 02110-1301 USA. * * (C) Copyright 2018 Red Hat, Inc. + * (C) Copyright 2015 - 2019 Jason A. Donenfeld . All Rights Reserved. */ #include "nm-default.h" @@ -132,3 +133,29 @@ nm_secret_buf_to_gbytes_take (NMSecretBuf *secret, gssize actual_len) _secret_buf_free, secret); } + +/*****************************************************************************/ + +/** + * nm_utils_memeqzero_secret: + * @data: the data pointer to check (may be %NULL if @length is zero). + * @length: the number of bytes to check. + * + * Checks that all bytes are zero. This always takes the same amount + * of time to prevent timing attacks. + * + * Returns: whether all bytes are zero. + */ +gboolean +nm_utils_memeqzero_secret (gconstpointer data, gsize length) +{ + const guint8 *const key = data; + volatile guint8 acc = 0; + gsize i; + + for (i = 0; i < length; i++) { + acc |= key[i]; + asm volatile("" : "=r"(acc) : "0"(acc)); + } + return 1 & ((acc - 1) >> 8); +} diff --git a/shared/nm-utils/nm-secret-utils.h b/shared/nm-utils/nm-secret-utils.h index 1bd518704e..034ef7bd33 100644 --- a/shared/nm-utils/nm-secret-utils.h +++ b/shared/nm-utils/nm-secret-utils.h @@ -173,4 +173,6 @@ GBytes *nm_secret_buf_to_gbytes_take (NMSecretBuf *secret, gssize actual_len); /*****************************************************************************/ +gboolean nm_utils_memeqzero_secret (gconstpointer data, gsize length); + #endif /* __NM_SECRET_UTILS_H__ */