aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/utils.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index 4a0eff45f..73edb2280 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -58,20 +58,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; (int)&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 (((int)&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];
}
}