summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils.c')
-rw-r--r--src/libstrongswan/utils.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index 4a0eff45f..305841172 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -20,6 +20,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+#include <stdint.h>
#include <limits.h>
#include <dirent.h>
#include <time.h>
@@ -58,20 +59,43 @@ void *clalloc(void * pointer, size_t size)
/**
* Described in header.
*/
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
+void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
{
- int i = 0, m;
+ int m, i;
- m = n - sizeof(long);
- while (i < m)
+ /* byte wise XOR until dst aligned */
+ for (i = 0; (uintptr_t)&dst[i] % sizeof(long); i++)
{
- *(long*)(dest + i) ^= *(long*)(src + i);
- i += sizeof(long);
+ dst[i] ^= src[i];
}
- while (i < n)
+ /* try to use words if src shares an aligment with dst */
+ switch (((uintptr_t)&src[i] % sizeof(long)))
{
- dest[i] ^= src[i];
- i++;
+ case 0:
+ for (m = n - sizeof(long); i <= m; i += sizeof(long))
+ {
+ *(long*)&dst[i] ^= *(long*)&src[i];
+ }
+ break;
+ case sizeof(int):
+ for (m = n - sizeof(int); i <= m; i += sizeof(int))
+ {
+ *(int*)&dst[i] ^= *(int*)&src[i];
+ }
+ break;
+ case sizeof(short):
+ for (m = n - sizeof(short); i <= m; i += sizeof(short))
+ {
+ *(short*)&dst[i] ^= *(short*)&src[i];
+ }
+ break;
+ default:
+ break;
+ }
+ /* byte wise XOR of the rest */
+ for (; i < n; i++)
+ {
+ dst[i] ^= src[i];
}
}