blob: b138f8bea1a3e925480a0f705c0ef5522a29743a
1 | /* |
2 | * A 32-bit implementation of the TEA algorithm |
3 | * Copyright (c) 2015 Vesselin Bontchev |
4 | * |
5 | * Loosely based on the implementation of David Wheeler and Roger Needham, |
6 | * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code |
7 | * |
8 | * This file is part of FFmpeg. |
9 | * |
10 | * FFmpeg is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU Lesser General Public |
12 | * License as published by the Free Software Foundation; either |
13 | * version 2.1 of the License, or (at your option) any later version. |
14 | * |
15 | * FFmpeg is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | * Lesser General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU Lesser General Public |
21 | * License along with FFmpeg; if not, write to the Free Software |
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | */ |
24 | |
25 | #include "avutil.h" |
26 | #include "common.h" |
27 | #include "intreadwrite.h" |
28 | #include "tea.h" |
29 | |
30 | typedef struct AVTEA { |
31 | uint32_t key[16]; |
32 | int rounds; |
33 | } AVTEA; |
34 | |
35 | struct AVTEA *av_tea_alloc(void) |
36 | { |
37 | return av_mallocz(sizeof(struct AVTEA)); |
38 | } |
39 | |
40 | const int av_tea_size = sizeof(AVTEA); |
41 | |
42 | void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) |
43 | { |
44 | int i; |
45 | |
46 | for (i = 0; i < 4; i++) |
47 | ctx->key[i] = AV_RB32(key + (i << 2)); |
48 | |
49 | ctx->rounds = rounds; |
50 | } |
51 | |
52 | static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, |
53 | int decrypt, uint8_t *iv) |
54 | { |
55 | uint32_t v0, v1; |
56 | int rounds = ctx->rounds; |
57 | uint32_t k0, k1, k2, k3; |
58 | k0 = ctx->key[0]; |
59 | k1 = ctx->key[1]; |
60 | k2 = ctx->key[2]; |
61 | k3 = ctx->key[3]; |
62 | |
63 | v0 = AV_RB32(src); |
64 | v1 = AV_RB32(src + 4); |
65 | |
66 | if (decrypt) { |
67 | int i; |
68 | uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); |
69 | |
70 | for (i = 0; i < rounds / 2; i++) { |
71 | v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); |
72 | v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); |
73 | sum -= delta; |
74 | } |
75 | if (iv) { |
76 | v0 ^= AV_RB32(iv); |
77 | v1 ^= AV_RB32(iv + 4); |
78 | memcpy(iv, src, 8); |
79 | } |
80 | } else { |
81 | int i; |
82 | uint32_t sum = 0, delta = 0x9E3779B9U; |
83 | |
84 | for (i = 0; i < rounds / 2; i++) { |
85 | sum += delta; |
86 | v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); |
87 | v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); |
88 | } |
89 | } |
90 | |
91 | AV_WB32(dst, v0); |
92 | AV_WB32(dst + 4, v1); |
93 | } |
94 | |
95 | void av_tea_crypt(AVTEA *ctx, uint8_t *dst, const uint8_t *src, int count, |
96 | uint8_t *iv, int decrypt) |
97 | { |
98 | int i; |
99 | |
100 | if (decrypt) { |
101 | while (count--) { |
102 | tea_crypt_ecb(ctx, dst, src, decrypt, iv); |
103 | |
104 | src += 8; |
105 | dst += 8; |
106 | } |
107 | } else { |
108 | while (count--) { |
109 | if (iv) { |
110 | for (i = 0; i < 8; i++) |
111 | dst[i] = src[i] ^ iv[i]; |
112 | tea_crypt_ecb(ctx, dst, dst, decrypt, NULL); |
113 | memcpy(iv, dst, 8); |
114 | } else { |
115 | tea_crypt_ecb(ctx, dst, src, decrypt, NULL); |
116 | } |
117 | src += 8; |
118 | dst += 8; |
119 | } |
120 | } |
121 | } |
122 |