FFmpeg
Loading...
Searching...
No Matches
twofish.c
Go to the documentation of this file.
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
33typedef 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
43static 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
62static 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
81static 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
100static 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
120{
121 return av_mallocz(sizeof(struct AVTWOFISH));
122}
123
124const int av_twofish_size = sizeof(AVTWOFISH);
125
126static 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
141static 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
153static 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
177static 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
191static 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
196static 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
210static 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
238static 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
273av_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
316void 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}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define A(x)
Definition vpx_arith.h:28
#define L(x)
Definition vpx_arith.h:36
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
error code definitions
#define X
Definition f_ebur128.c:157
const char * key
#define AVERROR(e)
Definition error.h:45
void av_twofish_crypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition twofish.c:316
const int av_twofish_size
Definition twofish.c:124
struct AVTWOFISH * av_twofish_alloc(void)
Allocate an AVTWOFISH context To free the struct: av_free(ptr)
Definition twofish.c:119
av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits)
Initialize an AVTWOFISH context.
Definition twofish.c:273
int a
#define B
Definition huffyuv.h:42
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_WL32(p, v)
#define AV_RL32(p)
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
Memory handling functions.
#define P
uint32_t S[4]
Definition twofish.c:35
uint32_t MDS1[256]
Definition twofish.c:37
uint32_t MDS2[256]
Definition twofish.c:38
uint32_t MDS4[256]
Definition twofish.c:40
uint32_t K[40]
Definition twofish.c:34
int ksize
Definition twofish.c:36
uint32_t MDS3[256]
Definition twofish.c:39
#define av_mallocz(s)
#define src
Definition vp8dsp.c:248
int key_bits
Definition rc4.c:30
#define LR(x, n)
Definition twofish.c:30
#define RR(x, n)
Definition twofish.c:31
static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
Definition twofish.c:153
static uint8_t gfmul(uint8_t a, uint8_t b)
Definition twofish.c:126
static const uint8_t MD2[256]
Definition twofish.c:62
static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src)
Definition twofish.c:210
static const uint8_t q1[256]
Definition twofish.c:100
static const uint8_t q0[256]
Definition twofish.c:81
static void precomputeMDS(AVTWOFISH *cs)
Definition twofish.c:196
static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
Definition twofish.c:238
static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
Definition twofish.c:191
static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
Definition twofish.c:177
static uint32_t tf_RS(uint32_t k0, uint32_t k1)
Definition twofish.c:141
static const uint8_t MD1[256]
Definition twofish.c:43
Public header for libavutil TWOFISH algorithm.