diff options
author | NIIBE Yutaka <[email protected]> | 2018-09-06 00:30:40 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2018-09-06 01:16:46 +0000 |
commit | c03cc0015612a1f626fe79faeeea7a5e28a68935 (patch) | |
tree | 18c94d9138eb43a5956f2ff70d9538920caa1b06 | |
parent | Remove fips_mode support originally available in libgcrypt. (diff) | |
download | libgpg-error-c03cc0015612a1f626fe79faeeea7a5e28a68935.tar.gz libgpg-error-c03cc0015612a1f626fe79faeeea7a5e28a68935.zip |
Copy definitions from libgcrypt/src/g10lib.h.
* src/secmem.c (PROPERLY_ALIGNED_TYPE): Move to ...
* src/semem.h (PROPERLY_ALIGNED_TYPE): ... here.
* src/semem.h (LIKELY, UNLIKELY): Copy definitions
from libgcrypt/src/g10lib.h.
(wipememory2, wipememory)
(fast_wipememory2_unaligned_head, fast_wipememory2): Likewise.
(FASTWIPE_T, FASTWIPE_MULT): Use uint64_t and ULL of C99.
-rw-r--r-- | src/secmem.c | 11 | ||||
-rw-r--r-- | src/secmem.h | 74 |
2 files changed, 74 insertions, 11 deletions
diff --git a/src/secmem.c b/src/secmem.c index dd1d3cc..7645093 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -44,17 +44,6 @@ #include "gpgrt-int.h" #include "secmem.h" -typedef union -{ - int a; - short b; - char c[1]; - long d; - uint64_t e; - float f; - double g; -} PROPERLY_ALIGNED_TYPE; - #if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS) #define MAP_ANONYMOUS MAP_ANON #endif diff --git a/src/secmem.h b/src/secmem.h index 8f0a938..cdab761 100644 --- a/src/secmem.h +++ b/src/secmem.h @@ -41,4 +41,78 @@ int _gpgrt_private_is_secure (const void *p); #define GPGRT_SECMEM_FLAG_NO_MLOCK (1 << 3) #define GPGRT_SECMEM_FLAG_NO_PRIV_DROP (1 << 4) +#if __GNUC__ >= 3 +#define LIKELY( expr ) __builtin_expect( !!(expr), 1 ) +#define UNLIKELY( expr ) __builtin_expect( !!(expr), 0 ) +#else +#define LIKELY( expr ) (!!(expr)) +#define UNLIKELY( expr ) (!!(expr)) +#endif + +typedef union +{ + int a; + short b; + char c[1]; + long d; + uint64_t e; + float f; + double g; +} PROPERLY_ALIGNED_TYPE; + +/* To avoid that a compiler optimizes certain memset calls away, these + macros may be used instead. */ +#define wipememory2(_ptr,_set,_len) do { \ + volatile char *_vptr=(volatile char *)(_ptr); \ + size_t _vlen=(_len); \ + unsigned char _vset=(_set); \ + fast_wipememory2(_vptr,_vset,_vlen); \ + while(_vlen) { *_vptr=(_vset); _vptr++; _vlen--; } \ + } while(0) +#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) + +#define FASTWIPE_T uint64_t +#define FASTWIPE_MULT (0x0101010101010101ULL) + +/* Following architectures can handle unaligned accesses fast. */ +#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ + defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ + defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) && \ + (defined(__i386__) || defined(__x86_64__) || \ + defined(__powerpc__) || defined(__powerpc64__) || \ + (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ + defined(__aarch64__)) +#define fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/ +typedef struct fast_wipememory_s +{ + FASTWIPE_T a; +} __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t; +#else +#define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \ + while(UNLIKELY((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1)) && _vlen) \ + { *_vptr=(_vset); _vptr++; _vlen--; } \ + } while(0) +typedef struct fast_wipememory_s +{ + FASTWIPE_T a; +} fast_wipememory_t; +#endif + +/* fast_wipememory2 may leave tail bytes unhandled, in which case tail bytes + are handled by wipememory2. */ +#define fast_wipememory2(_vptr,_vset,_vlen) do { \ + FASTWIPE_T _vset_long = _vset; \ + fast_wipememory2_unaligned_head(_vptr,_vset,_vlen); \ + if (_vlen < sizeof(FASTWIPE_T)) \ + break; \ + _vset_long *= FASTWIPE_MULT; \ + do { \ + volatile fast_wipememory_t *_vptr_long = \ + (volatile void *)_vptr; \ + _vptr_long->a = _vset_long; \ + _vlen -= sizeof(FASTWIPE_T); \ + _vptr += sizeof(FASTWIPE_T); \ + } while (_vlen >= sizeof(FASTWIPE_T)); \ + } while (0) + #endif /* G10_SECMEM_H */ |