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