1/* BEGIN_HEADER */
2#include "common.h"
3
4void fill_arrays(unsigned char *a, unsigned char *b, unsigned char *r1, unsigned char *r2, size_t n)
5{
6    for (size_t i = 0; i < n; i++) {
7        a[i]  = (unsigned char) i * 3;
8        b[i]  = (unsigned char) i * 3 + 1;
9        r1[i] = (unsigned char) i * 3 + 2;
10        r2[i] = r1[i];
11    }
12}
13/* END_HEADER */
14
15/* BEGIN_CASE */
16void mbedtls_xor(int len)
17{
18    size_t n = (size_t) len;
19    unsigned char *a = NULL, *b = NULL, *r1 = NULL, *r2 = NULL;
20    TEST_CALLOC(a, n + 1);
21    TEST_CALLOC(b, n + 1);
22    TEST_CALLOC(r1, n + 1);
23    TEST_CALLOC(r2, n + 1);
24
25    /* Test non-overlapping */
26    fill_arrays(a, b, r1, r2, n);
27    for (size_t i = 0; i < n; i++) {
28        r1[i] = a[i] ^ b[i];
29    }
30    mbedtls_xor(r2, a, b, n);
31    TEST_MEMORY_COMPARE(r1, n, r2, n);
32
33    /* Test r == a */
34    fill_arrays(a, b, r1, r2, n);
35    for (size_t i = 0; i < n; i++) {
36        r1[i] = r1[i] ^ b[i];
37    }
38    mbedtls_xor(r2, r2, b, n);
39    TEST_MEMORY_COMPARE(r1, n, r2, n);
40
41    /* Test r == b */
42    fill_arrays(a, b, r1, r2, n);
43    for (size_t i = 0; i < n; i++) {
44        r1[i] = a[i] ^ r1[i];
45    }
46    mbedtls_xor(r2, a, r2, n);
47    TEST_MEMORY_COMPARE(r1, n, r2, n);
48
49    /* Test a == b */
50    fill_arrays(a, b, r1, r2, n);
51    for (size_t i = 0; i < n; i++) {
52        r1[i] = a[i] ^ a[i];
53    }
54    mbedtls_xor(r2, a, a, n);
55    TEST_MEMORY_COMPARE(r1, n, r2, n);
56
57    /* Test a == b == r */
58    fill_arrays(a, b, r1, r2, n);
59    for (size_t i = 0; i < n; i++) {
60        r1[i] = r1[i] ^ r1[i];
61    }
62    mbedtls_xor(r2, r2, r2, n);
63    TEST_MEMORY_COMPARE(r1, n, r2, n);
64
65    /* Test non-word-aligned buffers, for all combinations of alignedness */
66    for (int i = 0; i < 7; i++) {
67        int r_off = i & 1, a_off = (i & 2) >> 1, b_off = (i & 4) >> 2;
68        fill_arrays(a, b, r1, r2, n + 1);
69
70        for (size_t j = 0; j < n; j++) {
71            r1[j + r_off] = a[j + a_off] ^ b[j + b_off];
72        }
73        mbedtls_xor(r2 + r_off, a + a_off, b + b_off, n);
74        TEST_MEMORY_COMPARE(r1 + r_off, n, r2 + r_off, n);
75    }
76exit:
77    mbedtls_free(a);
78    mbedtls_free(b);
79    mbedtls_free(r1);
80    mbedtls_free(r2);
81}
82/* END_CASE */
83