xref: /third_party/mbedtls/library/common.c (revision a8e1175b)
1#include "common.h"
2
3void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
4{
5    size_t i = 0;
6#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
7#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
8    /* This codepath probably only makes sense on architectures with 64-bit registers */
9    for (; (i + 8) <= n; i += 8) {
10        uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
11        mbedtls_put_unaligned_uint64(r + i, x);
12    }
13#if defined(__IAR_SYSTEMS_ICC__)
14    /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
15     * where n is a constant multiple of 8.
16     * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
17     * constant, and is a very small perf regression if n is not a compile-time constant. */
18    if (n % 8 == 0) {
19        return;
20    }
21#endif
22#else
23    for (; (i + 4) <= n; i += 4) {
24        uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
25        mbedtls_put_unaligned_uint32(r + i, x);
26    }
27#if defined(__IAR_SYSTEMS_ICC__)
28    if (n % 4 == 0) {
29        return;
30    }
31#endif
32#endif
33#endif
34    for (; i < n; i++) {
35        r[i] = a[i] ^ b[i];
36    }
37}
38
39void mbedtls_xor_no_simd(unsigned char *r,
40                         const unsigned char *a,
41                         const unsigned char *b,
42                         size_t n)
43{
44    size_t i = 0;
45#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
46#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
47    /* This codepath probably only makes sense on architectures with 64-bit registers */
48    for (; (i + 8) <= n; i += 8) {
49        uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
50        mbedtls_put_unaligned_uint64(r + i, x);
51    }
52#if defined(__IAR_SYSTEMS_ICC__)
53    /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
54     * where n is a constant multiple of 8.
55     * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
56     * constant, and is a very small perf regression if n is not a compile-time constant. */
57    if (n % 8 == 0) {
58        return;
59    }
60#endif
61#else
62    for (; (i + 4) <= n; i += 4) {
63        uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
64        mbedtls_put_unaligned_uint32(r + i, x);
65    }
66#if defined(__IAR_SYSTEMS_ICC__)
67    if (n % 4 == 0) {
68        return;
69    }
70#endif
71#endif
72#endif
73    for (; i < n; i++) {
74        r[i] = a[i] ^ b[i];
75    }
76}