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