1/* 2 * A 32-bit implementation of the XTEA algorithm 3 * Copyright (c) 2012 Samuel Pitoiset 4 * 5 * loosely based on the implementation of David Wheeler and Roger Needham 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24/** 25 * @file 26 * @brief XTEA 32-bit implementation 27 * @author Samuel Pitoiset 28 * @ingroup lavu_xtea 29 */ 30 31#include <string.h> 32#include "config.h" 33#include "intreadwrite.h" 34#include "mem.h" 35#include "xtea.h" 36 37AVXTEA *av_xtea_alloc(void) 38{ 39 return av_mallocz(sizeof(struct AVXTEA)); 40} 41 42void av_xtea_init(AVXTEA *ctx, const uint8_t key[16]) 43{ 44 int i; 45 46 for (i = 0; i < 4; i++) 47 ctx->key[i] = AV_RB32(key + (i << 2)); 48} 49 50void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16]) 51{ 52 int i; 53 54 for (i = 0; i < 4; i++) 55 ctx->key[i] = AV_RL32(key + (i << 2)); 56} 57 58static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, 59 int decrypt, uint8_t *iv) 60{ 61 uint32_t v0, v1; 62#if !CONFIG_SMALL 63 uint32_t k0 = ctx->key[0]; 64 uint32_t k1 = ctx->key[1]; 65 uint32_t k2 = ctx->key[2]; 66 uint32_t k3 = ctx->key[3]; 67#endif 68 69 v0 = AV_RB32(src); 70 v1 = AV_RB32(src + 4); 71 72 if (decrypt) { 73#if CONFIG_SMALL 74 int i; 75 uint32_t delta = 0x9E3779B9U, sum = delta * 32; 76 77 for (i = 0; i < 32; i++) { 78 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); 79 sum -= delta; 80 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 81 } 82#else 83#define DSTEP(SUM, K0, K1) \ 84 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + K0); \ 85 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9U + K1) 86 87 DSTEP(0xC6EF3720U, k2, k3); 88 DSTEP(0x28B7BD67U, k3, k2); 89 DSTEP(0x8A8043AEU, k0, k1); 90 DSTEP(0xEC48C9F5U, k1, k0); 91 DSTEP(0x4E11503CU, k2, k3); 92 DSTEP(0xAFD9D683U, k2, k2); 93 DSTEP(0x11A25CCAU, k3, k1); 94 DSTEP(0x736AE311U, k0, k0); 95 DSTEP(0xD5336958U, k1, k3); 96 DSTEP(0x36FBEF9FU, k1, k2); 97 DSTEP(0x98C475E6U, k2, k1); 98 DSTEP(0xFA8CFC2DU, k3, k0); 99 DSTEP(0x5C558274U, k0, k3); 100 DSTEP(0xBE1E08BBU, k1, k2); 101 DSTEP(0x1FE68F02U, k1, k1); 102 DSTEP(0x81AF1549U, k2, k0); 103 DSTEP(0xE3779B90U, k3, k3); 104 DSTEP(0x454021D7U, k0, k2); 105 DSTEP(0xA708A81EU, k1, k1); 106 DSTEP(0x08D12E65U, k1, k0); 107 DSTEP(0x6A99B4ACU, k2, k3); 108 DSTEP(0xCC623AF3U, k3, k2); 109 DSTEP(0x2E2AC13AU, k0, k1); 110 DSTEP(0x8FF34781U, k0, k0); 111 DSTEP(0xF1BBCDC8U, k1, k3); 112 DSTEP(0x5384540FU, k2, k2); 113 DSTEP(0xB54CDA56U, k3, k1); 114 DSTEP(0x1715609DU, k0, k0); 115 DSTEP(0x78DDE6E4U, k0, k3); 116 DSTEP(0xDAA66D2BU, k1, k2); 117 DSTEP(0x3C6EF372U, k2, k1); 118 DSTEP(0x9E3779B9U, k3, k0); 119#endif 120 if (iv) { 121 v0 ^= AV_RB32(iv); 122 v1 ^= AV_RB32(iv + 4); 123 memcpy(iv, src, 8); 124 } 125 } else { 126#if CONFIG_SMALL 127 int i; 128 uint32_t sum = 0, delta = 0x9E3779B9U; 129 130 for (i = 0; i < 32; i++) { 131 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 132 sum += delta; 133 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); 134 } 135#else 136#define ESTEP(SUM, K0, K1) \ 137 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM + K0);\ 138 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9U + K1) 139 ESTEP(0x00000000U, k0, k3); 140 ESTEP(0x9E3779B9U, k1, k2); 141 ESTEP(0x3C6EF372U, k2, k1); 142 ESTEP(0xDAA66D2BU, k3, k0); 143 ESTEP(0x78DDE6E4U, k0, k0); 144 ESTEP(0x1715609DU, k1, k3); 145 ESTEP(0xB54CDA56U, k2, k2); 146 ESTEP(0x5384540FU, k3, k1); 147 ESTEP(0xF1BBCDC8U, k0, k0); 148 ESTEP(0x8FF34781U, k1, k0); 149 ESTEP(0x2E2AC13AU, k2, k3); 150 ESTEP(0xCC623AF3U, k3, k2); 151 ESTEP(0x6A99B4ACU, k0, k1); 152 ESTEP(0x08D12E65U, k1, k1); 153 ESTEP(0xA708A81EU, k2, k0); 154 ESTEP(0x454021D7U, k3, k3); 155 ESTEP(0xE3779B90U, k0, k2); 156 ESTEP(0x81AF1549U, k1, k1); 157 ESTEP(0x1FE68F02U, k2, k1); 158 ESTEP(0xBE1E08BBU, k3, k0); 159 ESTEP(0x5C558274U, k0, k3); 160 ESTEP(0xFA8CFC2DU, k1, k2); 161 ESTEP(0x98C475E6U, k2, k1); 162 ESTEP(0x36FBEF9FU, k3, k1); 163 ESTEP(0xD5336958U, k0, k0); 164 ESTEP(0x736AE311U, k1, k3); 165 ESTEP(0x11A25CCAU, k2, k2); 166 ESTEP(0xAFD9D683U, k3, k2); 167 ESTEP(0x4E11503CU, k0, k1); 168 ESTEP(0xEC48C9F5U, k1, k0); 169 ESTEP(0x8A8043AEU, k2, k3); 170 ESTEP(0x28B7BD67U, k3, k2); 171#endif 172 } 173 174 AV_WB32(dst, v0); 175 AV_WB32(dst + 4, v1); 176} 177 178static void xtea_le_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, 179 int decrypt, uint8_t *iv) 180{ 181 uint32_t v0, v1; 182 int i; 183 184 v0 = AV_RL32(src); 185 v1 = AV_RL32(src + 4); 186 187 if (decrypt) { 188 uint32_t delta = 0x9E3779B9, sum = delta * 32; 189 190 for (i = 0; i < 32; i++) { 191 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); 192 sum -= delta; 193 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 194 } 195 if (iv) { 196 v0 ^= AV_RL32(iv); 197 v1 ^= AV_RL32(iv + 4); 198 memcpy(iv, src, 8); 199 } 200 } else { 201 uint32_t sum = 0, delta = 0x9E3779B9; 202 203 for (i = 0; i < 32; i++) { 204 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 205 sum += delta; 206 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); 207 } 208 } 209 210 AV_WL32(dst, v0); 211 AV_WL32(dst + 4, v1); 212} 213 214static void xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, 215 uint8_t *iv, int decrypt, 216 void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *)) 217{ 218 int i; 219 220 if (decrypt) { 221 while (count--) { 222 crypt(ctx, dst, src, decrypt, iv); 223 224 src += 8; 225 dst += 8; 226 } 227 } else { 228 while (count--) { 229 if (iv) { 230 for (i = 0; i < 8; i++) 231 dst[i] = src[i] ^ iv[i]; 232 crypt(ctx, dst, dst, decrypt, NULL); 233 memcpy(iv, dst, 8); 234 } else { 235 crypt(ctx, dst, src, decrypt, NULL); 236 } 237 src += 8; 238 dst += 8; 239 } 240 } 241} 242 243void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, 244 uint8_t *iv, int decrypt) 245{ 246 xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb); 247} 248 249void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, 250 uint8_t *iv, int decrypt) 251{ 252 xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb); 253} 254