| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | |||
| 37 | 1 | AVXTEA *av_xtea_alloc(void) | |
| 38 | { | ||
| 39 | 1 | return av_mallocz(sizeof(struct AVXTEA)); | |
| 40 | } | ||
| 41 | |||
| 42 | 6 | void av_xtea_init(AVXTEA *ctx, const uint8_t key[16]) | |
| 43 | { | ||
| 44 | int i; | ||
| 45 | |||
| 46 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
|
30 | for (i = 0; i < 4; i++) |
| 47 | 24 | ctx->key[i] = AV_RB32(key + (i << 2)); | |
| 48 | 6 | } | |
| 49 | |||
| 50 | 6 | void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16]) | |
| 51 | { | ||
| 52 | int i; | ||
| 53 | |||
| 54 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
|
30 | for (i = 0; i < 4; i++) |
| 55 | 24 | ctx->key[i] = AV_RL32(key + (i << 2)); | |
| 56 | 6 | } | |
| 57 | |||
| 58 | 84 | static 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 | 84 | uint32_t k0 = ctx->key[0]; | |
| 64 | 84 | uint32_t k1 = ctx->key[1]; | |
| 65 | 84 | uint32_t k2 = ctx->key[2]; | |
| 66 | 84 | uint32_t k3 = ctx->key[3]; | |
| 67 | #endif | ||
| 68 | |||
| 69 | 84 | v0 = AV_RB32(src); | |
| 70 | 84 | v1 = AV_RB32(src + 4); | |
| 71 | |||
| 72 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 30 times.
|
84 | 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 | 54 | DSTEP(0xC6EF3720U, k2, k3); | |
| 88 | 54 | DSTEP(0x28B7BD67U, k3, k2); | |
| 89 | 54 | DSTEP(0x8A8043AEU, k0, k1); | |
| 90 | 54 | DSTEP(0xEC48C9F5U, k1, k0); | |
| 91 | 54 | DSTEP(0x4E11503CU, k2, k3); | |
| 92 | 54 | DSTEP(0xAFD9D683U, k2, k2); | |
| 93 | 54 | DSTEP(0x11A25CCAU, k3, k1); | |
| 94 | 54 | DSTEP(0x736AE311U, k0, k0); | |
| 95 | 54 | DSTEP(0xD5336958U, k1, k3); | |
| 96 | 54 | DSTEP(0x36FBEF9FU, k1, k2); | |
| 97 | 54 | DSTEP(0x98C475E6U, k2, k1); | |
| 98 | 54 | DSTEP(0xFA8CFC2DU, k3, k0); | |
| 99 | 54 | DSTEP(0x5C558274U, k0, k3); | |
| 100 | 54 | DSTEP(0xBE1E08BBU, k1, k2); | |
| 101 | 54 | DSTEP(0x1FE68F02U, k1, k1); | |
| 102 | 54 | DSTEP(0x81AF1549U, k2, k0); | |
| 103 | 54 | DSTEP(0xE3779B90U, k3, k3); | |
| 104 | 54 | DSTEP(0x454021D7U, k0, k2); | |
| 105 | 54 | DSTEP(0xA708A81EU, k1, k1); | |
| 106 | 54 | DSTEP(0x08D12E65U, k1, k0); | |
| 107 | 54 | DSTEP(0x6A99B4ACU, k2, k3); | |
| 108 | 54 | DSTEP(0xCC623AF3U, k3, k2); | |
| 109 | 54 | DSTEP(0x2E2AC13AU, k0, k1); | |
| 110 | 54 | DSTEP(0x8FF34781U, k0, k0); | |
| 111 | 54 | DSTEP(0xF1BBCDC8U, k1, k3); | |
| 112 | 54 | DSTEP(0x5384540FU, k2, k2); | |
| 113 | 54 | DSTEP(0xB54CDA56U, k3, k1); | |
| 114 | 54 | DSTEP(0x1715609DU, k0, k0); | |
| 115 | 54 | DSTEP(0x78DDE6E4U, k0, k3); | |
| 116 | 54 | DSTEP(0xDAA66D2BU, k1, k2); | |
| 117 | 54 | DSTEP(0x3C6EF372U, k2, k1); | |
| 118 | 54 | DSTEP(0x9E3779B9U, k3, k0); | |
| 119 | #endif | ||
| 120 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
|
54 | if (iv) { |
| 121 | 48 | v0 ^= AV_RB32(iv); | |
| 122 | 48 | v1 ^= AV_RB32(iv + 4); | |
| 123 | 48 | 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 | 30 | ESTEP(0x00000000U, k0, k3); | |
| 140 | 30 | ESTEP(0x9E3779B9U, k1, k2); | |
| 141 | 30 | ESTEP(0x3C6EF372U, k2, k1); | |
| 142 | 30 | ESTEP(0xDAA66D2BU, k3, k0); | |
| 143 | 30 | ESTEP(0x78DDE6E4U, k0, k0); | |
| 144 | 30 | ESTEP(0x1715609DU, k1, k3); | |
| 145 | 30 | ESTEP(0xB54CDA56U, k2, k2); | |
| 146 | 30 | ESTEP(0x5384540FU, k3, k1); | |
| 147 | 30 | ESTEP(0xF1BBCDC8U, k0, k0); | |
| 148 | 30 | ESTEP(0x8FF34781U, k1, k0); | |
| 149 | 30 | ESTEP(0x2E2AC13AU, k2, k3); | |
| 150 | 30 | ESTEP(0xCC623AF3U, k3, k2); | |
| 151 | 30 | ESTEP(0x6A99B4ACU, k0, k1); | |
| 152 | 30 | ESTEP(0x08D12E65U, k1, k1); | |
| 153 | 30 | ESTEP(0xA708A81EU, k2, k0); | |
| 154 | 30 | ESTEP(0x454021D7U, k3, k3); | |
| 155 | 30 | ESTEP(0xE3779B90U, k0, k2); | |
| 156 | 30 | ESTEP(0x81AF1549U, k1, k1); | |
| 157 | 30 | ESTEP(0x1FE68F02U, k2, k1); | |
| 158 | 30 | ESTEP(0xBE1E08BBU, k3, k0); | |
| 159 | 30 | ESTEP(0x5C558274U, k0, k3); | |
| 160 | 30 | ESTEP(0xFA8CFC2DU, k1, k2); | |
| 161 | 30 | ESTEP(0x98C475E6U, k2, k1); | |
| 162 | 30 | ESTEP(0x36FBEF9FU, k3, k1); | |
| 163 | 30 | ESTEP(0xD5336958U, k0, k0); | |
| 164 | 30 | ESTEP(0x736AE311U, k1, k3); | |
| 165 | 30 | ESTEP(0x11A25CCAU, k2, k2); | |
| 166 | 30 | ESTEP(0xAFD9D683U, k3, k2); | |
| 167 | 30 | ESTEP(0x4E11503CU, k0, k1); | |
| 168 | 30 | ESTEP(0xEC48C9F5U, k1, k0); | |
| 169 | 30 | ESTEP(0x8A8043AEU, k2, k3); | |
| 170 | 30 | ESTEP(0x28B7BD67U, k3, k2); | |
| 171 | #endif | ||
| 172 | } | ||
| 173 | |||
| 174 | 84 | AV_WB32(dst, v0); | |
| 175 | 84 | AV_WB32(dst + 4, v1); | |
| 176 | 84 | } | |
| 177 | |||
| 178 | 12 | static 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 | 12 | v0 = AV_RL32(src); | |
| 185 | 12 | v1 = AV_RL32(src + 4); | |
| 186 | |||
| 187 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
|
12 | if (decrypt) { |
| 188 | 6 | uint32_t delta = 0x9E3779B9, sum = delta * 32; | |
| 189 | |||
| 190 |
2/2✓ Branch 0 taken 192 times.
✓ Branch 1 taken 6 times.
|
198 | for (i = 0; i < 32; i++) { |
| 191 | 192 | v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); | |
| 192 | 192 | sum -= delta; | |
| 193 | 192 | v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); | |
| 194 | } | ||
| 195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (iv) { |
| 196 | ✗ | v0 ^= AV_RL32(iv); | |
| 197 | ✗ | v1 ^= AV_RL32(iv + 4); | |
| 198 | ✗ | memcpy(iv, src, 8); | |
| 199 | } | ||
| 200 | } else { | ||
| 201 | 6 | uint32_t sum = 0, delta = 0x9E3779B9; | |
| 202 | |||
| 203 |
2/2✓ Branch 0 taken 192 times.
✓ Branch 1 taken 6 times.
|
198 | for (i = 0; i < 32; i++) { |
| 204 | 192 | v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); | |
| 205 | 192 | sum += delta; | |
| 206 | 192 | v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); | |
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | 12 | AV_WL32(dst, v0); | |
| 211 | 12 | AV_WL32(dst + 4, v1); | |
| 212 | 12 | } | |
| 213 | |||
| 214 | 42 | static 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 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
|
42 | if (decrypt) { |
| 221 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 24 times.
|
84 | while (count--) { |
| 222 | 60 | crypt(ctx, dst, src, decrypt, iv); | |
| 223 | |||
| 224 | 60 | src += 8; | |
| 225 | 60 | dst += 8; | |
| 226 | } | ||
| 227 | } else { | ||
| 228 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 18 times.
|
54 | while (count--) { |
| 229 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
|
36 | if (iv) { |
| 230 |
2/2✓ Branch 0 taken 192 times.
✓ Branch 1 taken 24 times.
|
216 | for (i = 0; i < 8; i++) |
| 231 | 192 | dst[i] = src[i] ^ iv[i]; | |
| 232 | 24 | crypt(ctx, dst, dst, decrypt, NULL); | |
| 233 | 24 | memcpy(iv, dst, 8); | |
| 234 | } else { | ||
| 235 | 12 | crypt(ctx, dst, src, decrypt, NULL); | |
| 236 | } | ||
| 237 | 36 | src += 8; | |
| 238 | 36 | dst += 8; | |
| 239 | } | ||
| 240 | } | ||
| 241 | 42 | } | |
| 242 | |||
| 243 | 30 | void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, | |
| 244 | uint8_t *iv, int decrypt) | ||
| 245 | { | ||
| 246 | 30 | xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb); | |
| 247 | 30 | } | |
| 248 | |||
| 249 | 12 | void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, | |
| 250 | uint8_t *iv, int decrypt) | ||
| 251 | { | ||
| 252 | 12 | xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb); | |
| 253 | 12 | } | |
| 254 |