Added a memwipe() function to safely overwrite sensitive memory
authorMartin Willi <martin@revosec.ch>
Mon, 9 May 2011 11:16:27 +0000 (13:16 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 9 May 2011 12:36:14 +0000 (14:36 +0200)
src/libstrongswan/utils.c
src/libstrongswan/utils.h

index ba12cd7..6ffb62a 100644 (file)
@@ -102,6 +102,14 @@ void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
 /**
  * Described in header.
  */
 /**
  * Described in header.
  */
+void memwipe_noinline(void *ptr, size_t n)
+{
+       memwipe_inline(ptr, n);
+}
+
+/**
+ * Described in header.
+ */
 void *memstr(const void *haystack, const char *needle, size_t n)
 {
        unsigned const char *pos = haystack;
 void *memstr(const void *haystack, const char *needle, size_t n)
 {
        unsigned const char *pos = haystack;
index ed61895..a334954 100644 (file)
@@ -337,6 +337,51 @@ void *clalloc(void *pointer, size_t size);
 void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
 
 /**
 void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
 
 /**
+ * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
+ */
+void memwipe_noinline(void *ptr, size_t n);
+
+/**
+ * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
+ */
+static inline void memwipe_inline(void *ptr, size_t n)
+{
+       volatile char *c = (volatile char*)ptr;
+       int m, i;
+
+       /* byte wise until long aligned */
+       for (i = 0; (uintptr_t)&c % sizeof(long) && i < n; i++)
+       {
+               c[i] = 0;
+       }
+       /* word wize */
+       for (m = n - sizeof(long); i <= m; i += sizeof(long))
+       {
+               *(volatile long*)&c[i] = 0;
+       }
+       /* byte wise of the rest */
+       for (; i < n; i++)
+       {
+               c[i] = 0;
+       }
+}
+
+/**
+ * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
+ */
+static inline void memwipe(void *ptr, size_t n)
+{
+       if (__builtin_constant_p(n))
+       {
+               memwipe_inline(ptr, n);
+       }
+       else
+       {
+               memwipe_noinline(ptr, n);
+       }
+}
+
+/**
  * A variant of strstr with the characteristics of memchr, where haystack is not
  * a null-terminated string but simply a memory area of length n.
  */
  * A variant of strstr with the characteristics of memchr, where haystack is not
  * a null-terminated string but simply a memory area of length n.
  */