buffer: convert to stdatomic
[ffmpeg.git] / libavutil / xtea.c
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 Libav.
8  *
9  * Libav 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  * Libav 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 Libav; 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 "avutil.h"
32 #include "common.h"
33 #include "intreadwrite.h"
34 #include "mem.h"
35 #include "xtea.h"
36
37 #if !FF_API_CRYPTO_CONTEXT
38 struct AVXTEA {
39     uint32_t key[16];
40 };
41 #endif
42
43 AVXTEA *av_xtea_alloc(void)
44 {
45     return av_mallocz(sizeof(struct AVXTEA));
46 }
47
48 void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
49 {
50     int i;
51
52     for (i = 0; i < 4; i++)
53         ctx->key[i] = AV_RB32(key + (i << 2));
54 }
55
56 void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16])
57 {
58     int i;
59
60     for (i = 0; i < 4; i++)
61         ctx->key[i] = AV_RL32(key + (i << 2));
62 }
63
64 static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
65                            int decrypt, uint8_t *iv)
66 {
67     uint32_t v0, v1;
68     int i;
69
70     v0 = AV_RB32(src);
71     v1 = AV_RB32(src + 4);
72
73     if (decrypt) {
74         uint32_t delta = 0x9E3779B9, sum = delta * 32;
75
76         for (i = 0; i < 32; i++) {
77             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
78             sum -= delta;
79             v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
80         }
81         if (iv) {
82             v0 ^= AV_RB32(iv);
83             v1 ^= AV_RB32(iv + 4);
84             memcpy(iv, src, 8);
85         }
86     } else {
87         uint32_t sum = 0, delta = 0x9E3779B9;
88
89         for (i = 0; i < 32; i++) {
90             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
91             sum += delta;
92             v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
93         }
94     }
95
96     AV_WB32(dst, v0);
97     AV_WB32(dst + 4, v1);
98 }
99
100 static void xtea_le_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
101                               int decrypt, uint8_t *iv)
102 {
103     uint32_t v0, v1;
104     int i;
105
106     v0 = AV_RL32(src);
107     v1 = AV_RL32(src + 4);
108
109     if (decrypt) {
110         uint32_t delta = 0x9E3779B9, sum = delta * 32;
111
112         for (i = 0; i < 32; i++) {
113             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
114             sum -= delta;
115             v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
116         }
117         if (iv) {
118             v0 ^= AV_RL32(iv);
119             v1 ^= AV_RL32(iv + 4);
120             memcpy(iv, src, 8);
121         }
122     } else {
123         uint32_t sum = 0, delta = 0x9E3779B9;
124
125         for (i = 0; i < 32; i++) {
126             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
127             sum += delta;
128             v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
129         }
130     }
131
132     AV_WL32(dst, v0);
133     AV_WL32(dst + 4, v1);
134 }
135
136 static void xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
137                        uint8_t *iv, int decrypt,
138                        void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *))
139 {
140     int i;
141
142     if (decrypt) {
143         while (count--) {
144             crypt(ctx, dst, src, decrypt, iv);
145
146             src   += 8;
147             dst   += 8;
148         }
149     } else {
150         while (count--) {
151             if (iv) {
152                 for (i = 0; i < 8; i++)
153                     dst[i] = src[i] ^ iv[i];
154                 crypt(ctx, dst, dst, decrypt, NULL);
155                 memcpy(iv, dst, 8);
156             } else {
157                 crypt(ctx, dst, src, decrypt, NULL);
158             }
159             src   += 8;
160             dst   += 8;
161         }
162     }
163 }
164
165 void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
166                    uint8_t *iv, int decrypt)
167 {
168     xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb);
169 }
170
171 void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
172                       uint8_t *iv, int decrypt)
173 {
174     xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb);
175 }