aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-09-06 00:30:40 +0000
committerNIIBE Yutaka <[email protected]>2018-09-06 01:16:46 +0000
commitc03cc0015612a1f626fe79faeeea7a5e28a68935 (patch)
tree18c94d9138eb43a5956f2ff70d9538920caa1b06
parentRemove fips_mode support originally available in libgcrypt. (diff)
downloadlibgpg-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.c11
-rw-r--r--src/secmem.h74
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 */