1 /*
2 * An implementation of the TwoFish algorithm
3 * Copyright (c) 2015 Supraja Meedinti
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <string.h>
23
24 #include "twofish.h"
25 #include "error.h"
26 #include "intreadwrite.h"
27 #include "mem.h"
28 #include "attributes.h"
29
30 #define LR(x, n) ((x) << (n) | (x) >> (32 - (n)))
31 #define RR(x, n) ((x) >> (n) | (x) << (32 - (n)))
32
33 typedef struct AVTWOFISH {
34 uint32_t K[40];
35 uint32_t S[4];
36 int ksize;
37 uint32_t MDS1[256];
38 uint32_t MDS2[256];
39 uint32_t MDS3[256];
40 uint32_t MDS4[256];
41 } AVTWOFISH;
42
43 static const uint8_t MD1[256] = {
44 0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51, 0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2,
45 0x14, 0x4f, 0xa2, 0xf9, 0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40, 0xad, 0xf6,
46 0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0, 0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca,
47 0x3c, 0x67, 0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb, 0x33, 0x68, 0x85, 0xde,
48 0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e, 0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2,
49 0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15, 0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6,
50 0x78, 0x23, 0xce, 0x95, 0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c, 0xc1, 0x9a,
51 0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84, 0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e,
52 0xa0, 0xfb, 0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47, 0xaf, 0xf4, 0x19, 0x42,
53 0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea, 0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56,
54 0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9, 0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a,
55 0x9c, 0xc7, 0x2a, 0x71, 0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8, 0x25, 0x7e,
56 0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18, 0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12,
57 0xe4, 0xbf, 0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03, 0xeb, 0xb0, 0x5d, 0x06,
58 0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86, 0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a,
59 0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d, 0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e
60 };
61
62 static const uint8_t MD2[256] = {
63 0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1, 0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51,
64 0x1c, 0xf3, 0xab, 0x44, 0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa, 0xa2, 0x4d,
65 0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67, 0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69,
66 0x24, 0xcb, 0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72, 0x2d, 0xc2, 0x9a, 0x75,
67 0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98, 0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21,
68 0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d, 0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d,
69 0x48, 0xa7, 0xff, 0x10, 0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae, 0xf6, 0x19,
70 0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b, 0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05,
71 0xe0, 0x0f, 0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6, 0xe9, 0x06, 0x5e, 0xb1,
72 0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14, 0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad,
73 0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39, 0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89,
74 0xc4, 0x2b, 0x73, 0x9c, 0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22, 0x7a, 0x95,
75 0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf, 0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1,
76 0x8c, 0x63, 0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda, 0x85, 0x6a, 0x32, 0xdd,
77 0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40, 0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9,
78 0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55, 0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5
79 };
80
81 static const uint8_t q0[256] = {
82 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38,
83 0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48,
84 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82,
85 0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61,
86 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
87 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7,
88 0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71,
89 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7,
90 0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90,
91 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
92 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64,
93 0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a,
94 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d,
95 0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
96 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
97 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0
98 };
99
100 static const uint8_t q1[256] = {
101 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b,
102 0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f,
103 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5,
104 0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51,
105 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
106 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8,
107 0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2,
108 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17,
109 0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e,
110 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
111 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48,
112 0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64,
113 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69,
114 0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc,
115 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
116 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91
117 };
118
av_twofish_alloc(void)119 struct AVTWOFISH *av_twofish_alloc(void)
120 {
121 return av_mallocz(sizeof(struct AVTWOFISH));
122 }
123
124 const int av_twofish_size = sizeof(AVTWOFISH);
125
gfmul(uint8_t a,uint8_t b)126 static uint8_t gfmul(uint8_t a, uint8_t b)
127 {
128 uint8_t r = 0, t;
129 while (a && b) {
130 if (a & 1)
131 r = r ^ b;
132 t = b & 0x80;
133 b = b << 1;
134 if (t)
135 b = b ^ 0x4d;
136 a = a >> 1;
137 }
138 return r;
139 }
140
tf_RS(uint32_t k0,uint32_t k1)141 static uint32_t tf_RS(uint32_t k0, uint32_t k1)
142 {
143 uint8_t s[4], m[8];
144 AV_WL32(m, k0);
145 AV_WL32(m + 4, k1);
146 s[0] = gfmul(0x01, m[0]) ^ gfmul(0xa4, m[1]) ^ gfmul(0x55, m[2]) ^ gfmul(0x87, m[3]) ^ gfmul(0x5a, m[4]) ^ gfmul(0x58, m[5]) ^ gfmul(0xdb, m[6]) ^ gfmul(0x9e, m[7]);
147 s[1] = gfmul(0xa4, m[0]) ^ gfmul(0x56, m[1]) ^ gfmul(0x82, m[2]) ^ gfmul(0xf3, m[3]) ^ gfmul(0x1e, m[4]) ^ gfmul(0xc6, m[5]) ^ gfmul(0x68, m[6]) ^ gfmul(0xe5, m[7]);
148 s[2] = gfmul(0x02, m[0]) ^ gfmul(0xa1, m[1]) ^ gfmul(0xfc, m[2]) ^ gfmul(0xc1, m[3]) ^ gfmul(0x47, m[4]) ^ gfmul(0xae, m[5]) ^ gfmul(0x3d, m[6]) ^ gfmul(0x19, m[7]);
149 s[3] = gfmul(0xa4, m[0]) ^ gfmul(0x55, m[1]) ^ gfmul(0x87, m[2]) ^ gfmul(0x5a, m[3]) ^ gfmul(0x58, m[4]) ^ gfmul(0xdb, m[5]) ^ gfmul(0x9e, m[6]) ^ gfmul(0x03, m[7]);
150 return AV_RL32(s);
151 }
152
tf_h0(uint8_t y[4],uint32_t L[4],int k)153 static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
154 {
155 uint8_t l[4];
156 if (k == 4) {
157 AV_WL32(l, L[3]);
158 y[0] = q1[y[0]] ^ l[0];
159 y[1] = q0[y[1]] ^ l[1];
160 y[2] = q0[y[2]] ^ l[2];
161 y[3] = q1[y[3]] ^ l[3];
162 }
163 if (k >= 3) {
164 AV_WL32(l, L[2]);
165 y[0] = q1[y[0]] ^ l[0];
166 y[1] = q1[y[1]] ^ l[1];
167 y[2] = q0[y[2]] ^ l[2];
168 y[3] = q0[y[3]] ^ l[3];
169 }
170 AV_WL32(l, L[1]);
171 y[0] = q1[q0[q0[y[0]] ^ l[0]] ^ (L[0] & 0xff)];
172 y[1] = q0[q0[q1[y[1]] ^ l[1]] ^ ((L[0] >> 8) & 0xff)];
173 y[2] = q1[q1[q0[y[2]] ^ l[2]] ^ ((L[0] >> 16) & 0xff)];
174 y[3] = q0[q1[q1[y[3]] ^ l[3]] ^ (L[0] >> 24)];
175 }
176
tf_h(uint32_t X,uint32_t L[4],int k)177 static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
178 {
179 uint8_t y[4], l[4];
180 AV_WL32(y, X);
181 tf_h0(y, L, k);
182
183 l[0] = y[0] ^ MD2[y[1]] ^ MD1[y[2]] ^ MD1[y[3]];
184 l[1] = MD1[y[0]] ^ MD2[y[1]] ^ MD2[y[2]] ^ y[3];
185 l[2] = MD2[y[0]] ^ MD1[y[1]] ^ y[2] ^ MD2[y[3]];
186 l[3] = MD2[y[0]] ^ y[1] ^ MD2[y[2]] ^ MD1[y[3]];
187
188 return AV_RL32(l);
189 }
190
MDS_mul(AVTWOFISH * cs,uint32_t X)191 static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
192 {
193 return cs->MDS1[(X) & 0xff] ^ cs->MDS2[((X) >> 8) & 0xff] ^ cs->MDS3[((X) >> 16) & 0xff] ^ cs->MDS4[(X) >> 24];
194 }
195
precomputeMDS(AVTWOFISH * cs)196 static void precomputeMDS(AVTWOFISH *cs)
197 {
198 uint8_t y[4];
199 int i;
200 for (i = 0; i < 256; i++) {
201 y[0] = y[1] = y[2] = y[3] = i;
202 tf_h0(y, cs->S, cs->ksize);
203 cs->MDS1[i] = ((uint32_t)y[0]) ^ ((uint32_t)MD1[y[0]] << 8) ^ ((uint32_t)MD2[y[0]] << 16) ^ ((uint32_t)MD2[y[0]] << 24);
204 cs->MDS2[i] = ((uint32_t)MD2[y[1]]) ^ ((uint32_t)MD2[y[1]] << 8) ^ ((uint32_t)MD1[y[1]] << 16) ^ ((uint32_t)y[1] << 24);
205 cs->MDS3[i] = ((uint32_t)MD1[y[2]]) ^ ((uint32_t)MD2[y[2]] << 8) ^ ((uint32_t)y[2] << 16) ^ ((uint32_t)MD2[y[2]] << 24);
206 cs->MDS4[i] = ((uint32_t)MD1[y[3]]) ^ ((uint32_t)y[3] << 8) ^ ((uint32_t)MD2[y[3]] << 16) ^ ((uint32_t)MD1[y[3]] << 24);
207 }
208 }
209
twofish_encrypt(AVTWOFISH * cs,uint8_t * dst,const uint8_t * src)210 static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src)
211 {
212 uint32_t P[4], t0, t1;
213 int i;
214 P[0] = AV_RL32(src) ^ cs->K[0];
215 P[1] = AV_RL32(src + 4) ^ cs->K[1];
216 P[2] = AV_RL32(src + 8) ^ cs->K[2];
217 P[3] = AV_RL32(src + 12) ^ cs->K[3];
218 for (i = 0; i < 16; i += 2) {
219 t0 = MDS_mul(cs, P[0]);
220 t1 = MDS_mul(cs, LR(P[1], 8));
221 P[2] = RR(P[2] ^ (t0 + t1 + cs->K[2 * i + 8]), 1);
222 P[3] = LR(P[3], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 9]);
223 t0 = MDS_mul(cs, P[2]);
224 t1 = MDS_mul(cs, LR(P[3], 8));
225 P[0] = RR(P[0] ^ (t0 + t1 + cs->K[2 * i + 10]), 1);
226 P[1] = LR(P[1], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 11]);
227 }
228 P[2] ^= cs->K[4];
229 P[3] ^= cs->K[5];
230 P[0] ^= cs->K[6];
231 P[1] ^= cs->K[7];
232 AV_WL32(dst, P[2]);
233 AV_WL32(dst + 4, P[3]);
234 AV_WL32(dst + 8, P[0]);
235 AV_WL32(dst + 12, P[1]);
236 }
237
twofish_decrypt(AVTWOFISH * cs,uint8_t * dst,const uint8_t * src,uint8_t * iv)238 static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
239 {
240 uint32_t P[4], t0, t1;
241 int i;
242 P[2] = AV_RL32(src) ^ cs->K[4];
243 P[3] = AV_RL32(src + 4) ^ cs->K[5];
244 P[0] = AV_RL32(src + 8) ^ cs->K[6];
245 P[1] = AV_RL32(src + 12) ^ cs->K[7];
246 for (i = 15; i >= 0; i -= 2) {
247 t0 = MDS_mul(cs, P[2]);
248 t1 = MDS_mul(cs, LR(P[3], 8));
249 P[0] = LR(P[0], 1) ^ (t0 + t1 + cs->K[2 * i + 8]);
250 P[1] = RR(P[1] ^ (t0 + 2 * t1 + cs->K[2 * i + 9]), 1);
251 t0 = MDS_mul(cs, P[0]);
252 t1 = MDS_mul(cs, LR(P[1], 8));
253 P[2] = LR(P[2], 1) ^ (t0 + t1 + cs->K[2 * i + 6]);
254 P[3] = RR(P[3] ^ (t0 + 2 * t1 + cs->K[2 * i + 7]), 1);
255 }
256 P[0] ^= cs->K[0];
257 P[1] ^= cs->K[1];
258 P[2] ^= cs->K[2];
259 P[3] ^= cs->K[3];
260 if (iv) {
261 P[0] ^= AV_RL32(iv);
262 P[1] ^= AV_RL32(iv + 4);
263 P[2] ^= AV_RL32(iv + 8);
264 P[3] ^= AV_RL32(iv + 12);
265 memcpy(iv, src, 16);
266 }
267 AV_WL32(dst, P[0]);
268 AV_WL32(dst + 4, P[1]);
269 AV_WL32(dst + 8, P[2]);
270 AV_WL32(dst + 12, P[3]);
271 }
272
av_twofish_init(AVTWOFISH * cs,const uint8_t * key,int key_bits)273 av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits)
274 {
275 int i;
276 uint8_t keypad[32];
277 uint32_t Key[8], Me[4], Mo[4], A, B;
278 const uint32_t rho = 0x01010101;
279 if (key_bits < 0)
280 return AVERROR(EINVAL);
281 if (key_bits <= 128) {
282 cs->ksize = 2;
283 } else if (key_bits <= 192) {
284 cs->ksize = 3;
285 } else {
286 cs->ksize = 4;
287 }
288 memset(keypad, 0, sizeof(keypad));
289 if (key_bits <= 256) {
290 memcpy(keypad, key, key_bits >> 3);
291 } else {
292 memcpy(keypad, key, 32);
293 }
294 for (i = 0; i < 2 * cs->ksize ; i++)
295 Key[i] = AV_RL32(keypad + 4 * i);
296 for (i = 0; i < cs->ksize; i++) {
297 Me[i] = Key[2 * i];
298 Mo[i] = Key[2 * i + 1];
299 cs->S[cs->ksize - i - 1] = tf_RS(Me[i], Mo[i]);
300 }
301 precomputeMDS(cs);
302 for (i = 0; i < 20; i++) {
303 A = tf_h((2 * i) * rho, Me, cs->ksize);
304 B = tf_h((2 * i + 1) * rho, Mo, cs->ksize);
305 B = LR(B, 8);
306 cs->K[2 * i] = A + B;
307 cs->K[2 * i + 1] = LR((A + (2 * B)), 9);
308 }
309 if (cs->ksize << 6 != key_bits) {
310 return 1;
311 } else {
312 return 0;
313 }
314 }
315
av_twofish_crypt(AVTWOFISH * cs,uint8_t * dst,const uint8_t * src,int count,uint8_t * iv,int decrypt)316 void av_twofish_crypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
317 {
318 int i;
319 while (count--) {
320 if (decrypt) {
321 twofish_decrypt(cs, dst, src, iv);
322 } else {
323 if (iv) {
324 for (i = 0; i < 16; i++)
325 dst[i] = src[i] ^ iv[i];
326 twofish_encrypt(cs, dst, dst);
327 memcpy(iv, dst, 16);
328 } else {
329 twofish_encrypt(cs, dst, src);
330 }
331 }
332 src = src + 16;
333 dst = dst + 16;
334 }
335 }
336