Files
cryptsetup/lib/crypto_backend/memutils.c
Ondrej Kozina 3a8feb8be7 Improve check for a function attribute support.
The compiler may advertise function attribute support
with __has_attribute operator even though it does
not implement the feature on some architecture.

This fixes the issue with  GCC 11 on ppc64le with
__attribute__((zero_call_used_regs("used"))).

Fixes: #959.
2025-09-11 14:18:39 +02:00

62 lines
1.5 KiB
C

// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Safe memory utilities
*
* Copyright (C) 2024-2025 Milan Broz
*/
#include "crypto_backend_internal.h"
#define ATTR_NOINLINE __attribute__ ((noinline))
#define ATTR_ZERO_REGS
#if HAVE_ATTRIBUTE_ZEROCALLUSEDREGS
# undef ATTR_ZERO_REGS
# define ATTR_ZERO_REGS __attribute__ ((zero_call_used_regs("used")))
#endif
/* Workaround for https://github.com/google/sanitizers/issues/1507 */
#if defined __has_feature
# if __has_feature (memory_sanitizer)
# undef HAVE_EXPLICIT_BZERO
# endif
#endif
/* Memzero helper (memset on stack can be optimized out) */
ATTR_NOINLINE ATTR_ZERO_REGS
void crypt_backend_memzero(void *s, size_t n)
{
#if HAVE_EXPLICIT_BZERO
explicit_bzero(s, n);
#else
volatile uint8_t *p = (volatile uint8_t *)s;
while(n--) *p++ = 0;
#endif
}
/* Memcpy helper to avoid spilling sensitive data through additional registers */
ATTR_NOINLINE ATTR_ZERO_REGS
void *crypt_backend_memcpy(void *dst, const void *src, size_t n)
{
volatile uint8_t *d = (volatile uint8_t *)dst;
const volatile uint8_t *s = (const volatile uint8_t *)src;
while(n--) *d++ = *s++;
return dst;
}
/* Internal implementation for constant time memory comparison */
ATTR_NOINLINE ATTR_ZERO_REGS
int crypt_internal_memeq(const void *m1, const void *m2, size_t n)
{
const unsigned char *_m1 = (const unsigned char *) m1;
const unsigned char *_m2 = (const unsigned char *) m2;
unsigned char result = 0;
size_t i;
for (i = 0; i < n; i++)
result |= _m1[i] ^ _m2[i];
return result;
}