// // XOR.h // TunnelKit // // Created by Tejas Mehta on 5/24/22. // Copyright (c) 2023 Davide De Rosa. All rights reserved. // // https://github.com/passepartoutvpn // // This file is part of TunnelKit. // // TunnelKit is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // TunnelKit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with TunnelKit. If not, see . // #import #import "XORMethodNative.h" static inline void xor_mask(uint8_t *dst, const uint8_t *src, NSData *xorMask, size_t length) { if (xorMask.length > 0) { for (size_t i = 0; i < length; ++i) { dst[i] = src[i] ^ ((uint8_t *)(xorMask.bytes))[i % xorMask.length]; } return; } memcpy(dst, src, length); } static inline void xor_ptrpos(uint8_t *dst, const uint8_t *src, size_t length) { for (size_t i = 0; i < length; ++i) { dst[i] = src[i] ^ (i + 1); } } static inline void xor_reverse(uint8_t *dst, const uint8_t *src, size_t length) { size_t start = 1; size_t end = length - 1; uint8_t temp = 0; dst[0] = src[0]; while (start < end) { temp = src[start]; dst[start] = src[end]; dst[end] = temp; start++; end--; } if (start == end) { dst[start] = src[start]; } } static inline void xor_memcpy(uint8_t *dst, NSData *src, XORMethodNative method, NSData *mask, BOOL outbound) { const uint8_t *source = (uint8_t *)src.bytes; switch (method) { case XORMethodNativeNone: memcpy(dst, source, src.length); break; case XORMethodNativeMask: xor_mask(dst, source, mask, src.length); break; case XORMethodNativePtrPos: xor_ptrpos(dst, source, src.length); break; case XORMethodNativeReverse: xor_reverse(dst, source, src.length); break; case XORMethodNativeObfuscate: if (outbound) { xor_ptrpos(dst, source, src.length); xor_reverse(dst, dst, src.length); xor_ptrpos(dst, dst, src.length); xor_mask(dst, dst, mask, src.length); } else { xor_mask(dst, source, mask, src.length); xor_ptrpos(dst, dst, src.length); xor_reverse(dst, dst, src.length); xor_ptrpos(dst, dst, src.length); } break; } }