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}