FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 #include "twofish.h"
22 #include "common.h"
23 #include "intreadwrite.h"
24 #include "attributes.h"
25 
26 #define LR(x, n) ((x) << (n) | (x) >> (32 - (n)))
27 #define RR(x, n) ((x) >> (n) | (x) << (32 - (n)))
28 
29 typedef struct AVTWOFISH {
30  uint32_t K[40];
31  uint32_t S[4];
32  int ksize;
33  uint32_t MDS1[256];
34  uint32_t MDS2[256];
35  uint32_t MDS3[256];
36  uint32_t MDS4[256];
37 } AVTWOFISH;
38 
39 static const uint8_t MD1[256] = {
40  0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51, 0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2,
41  0x14, 0x4f, 0xa2, 0xf9, 0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40, 0xad, 0xf6,
42  0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0, 0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca,
43  0x3c, 0x67, 0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb, 0x33, 0x68, 0x85, 0xde,
44  0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e, 0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2,
45  0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15, 0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6,
46  0x78, 0x23, 0xce, 0x95, 0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c, 0xc1, 0x9a,
47  0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84, 0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e,
48  0xa0, 0xfb, 0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47, 0xaf, 0xf4, 0x19, 0x42,
49  0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea, 0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56,
50  0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9, 0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a,
51  0x9c, 0xc7, 0x2a, 0x71, 0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8, 0x25, 0x7e,
52  0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18, 0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12,
53  0xe4, 0xbf, 0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03, 0xeb, 0xb0, 0x5d, 0x06,
54  0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86, 0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a,
55  0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d, 0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e
56 };
57 
58 static const uint8_t MD2[256] = {
59  0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1, 0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51,
60  0x1c, 0xf3, 0xab, 0x44, 0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa, 0xa2, 0x4d,
61  0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67, 0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69,
62  0x24, 0xcb, 0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72, 0x2d, 0xc2, 0x9a, 0x75,
63  0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98, 0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21,
64  0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d, 0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d,
65  0x48, 0xa7, 0xff, 0x10, 0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae, 0xf6, 0x19,
66  0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b, 0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05,
67  0xe0, 0x0f, 0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6, 0xe9, 0x06, 0x5e, 0xb1,
68  0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14, 0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad,
69  0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39, 0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89,
70  0xc4, 0x2b, 0x73, 0x9c, 0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22, 0x7a, 0x95,
71  0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf, 0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1,
72  0x8c, 0x63, 0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda, 0x85, 0x6a, 0x32, 0xdd,
73  0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40, 0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9,
74  0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55, 0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5
75 };
76 
77 static const uint8_t q0[256] = {
78  0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38,
79  0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48,
80  0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82,
81  0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61,
82  0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
83  0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7,
84  0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71,
85  0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7,
86  0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90,
87  0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
88  0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64,
89  0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a,
90  0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d,
91  0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
92  0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
93  0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0
94 };
95 
96 static const uint8_t q1[256] = {
97  0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b,
98  0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f,
99  0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5,
100  0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51,
101  0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
102  0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8,
103  0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2,
104  0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17,
105  0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e,
106  0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
107  0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48,
108  0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64,
109  0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69,
110  0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc,
111  0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
112  0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91
113 };
114 
116 {
117  return av_mallocz(sizeof(struct AVTWOFISH));
118 }
119 
120 const int av_twofish_size = sizeof(AVTWOFISH);
121 
123 {
124  uint8_t r = 0, t;
125  while (a && b) {
126  if (a & 1)
127  r = r ^ b;
128  t = b & 0x80;
129  b = b << 1;
130  if (t)
131  b = b ^ 0x4d;
132  a = a >> 1;
133  }
134  return r;
135 }
136 
137 static uint32_t tf_RS(uint32_t k0, uint32_t k1)
138 {
139  uint8_t s[4], m[8];
140  AV_WL32(m, k0);
141  AV_WL32(m + 4, k1);
142  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]);
143  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]);
144  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]);
145  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]);
146  return AV_RL32(s);
147 }
148 
149 static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
150 {
151  uint8_t l[4];
152  if (k == 4) {
153  AV_WL32(l, L[3]);
154  y[0] = q1[y[0]] ^ l[0];
155  y[1] = q0[y[1]] ^ l[1];
156  y[2] = q0[y[2]] ^ l[2];
157  y[3] = q1[y[3]] ^ l[3];
158  }
159  if (k >= 3) {
160  AV_WL32(l, L[2]);
161  y[0] = q1[y[0]] ^ l[0];
162  y[1] = q1[y[1]] ^ l[1];
163  y[2] = q0[y[2]] ^ l[2];
164  y[3] = q0[y[3]] ^ l[3];
165  }
166  AV_WL32(l, L[1]);
167  y[0] = q1[q0[q0[y[0]] ^ l[0]] ^ (L[0] & 0xff)];
168  y[1] = q0[q0[q1[y[1]] ^ l[1]] ^ ((L[0] >> 8) & 0xff)];
169  y[2] = q1[q1[q0[y[2]] ^ l[2]] ^ ((L[0] >> 16) & 0xff)];
170  y[3] = q0[q1[q1[y[3]] ^ l[3]] ^ (L[0] >> 24)];
171 }
172 
173 static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
174 {
175  uint8_t y[4], l[4];
176  AV_WL32(y, X);
177  tf_h0(y, L, k);
178 
179  l[0] = y[0] ^ MD2[y[1]] ^ MD1[y[2]] ^ MD1[y[3]];
180  l[1] = MD1[y[0]] ^ MD2[y[1]] ^ MD2[y[2]] ^ y[3];
181  l[2] = MD2[y[0]] ^ MD1[y[1]] ^ y[2] ^ MD2[y[3]];
182  l[3] = MD2[y[0]] ^ y[1] ^ MD2[y[2]] ^ MD1[y[3]];
183 
184  return AV_RL32(l);
185 }
186 
187 static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
188 {
189  return cs->MDS1[(X) & 0xff] ^ cs->MDS2[((X) >> 8) & 0xff] ^ cs->MDS3[((X) >> 16) & 0xff] ^ cs->MDS4[(X) >> 24];
190 }
191 
192 static void precomputeMDS(AVTWOFISH *cs)
193 {
194  uint8_t y[4];
195  int i;
196  for (i = 0; i < 256; i++) {
197  y[0] = y[1] = y[2] = y[3] = i;
198  tf_h0(y, cs->S, cs->ksize);
199  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);
200  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);
201  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);
202  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);
203  }
204 }
205 
206 static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src)
207 {
208  uint32_t P[4], t0, t1;
209  int i;
210  P[0] = AV_RL32(src) ^ cs->K[0];
211  P[1] = AV_RL32(src + 4) ^ cs->K[1];
212  P[2] = AV_RL32(src + 8) ^ cs->K[2];
213  P[3] = AV_RL32(src + 12) ^ cs->K[3];
214  for (i = 0; i < 16; i += 2) {
215  t0 = MDS_mul(cs, P[0]);
216  t1 = MDS_mul(cs, LR(P[1], 8));
217  P[2] = RR(P[2] ^ (t0 + t1 + cs->K[2 * i + 8]), 1);
218  P[3] = LR(P[3], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 9]);
219  t0 = MDS_mul(cs, P[2]);
220  t1 = MDS_mul(cs, LR(P[3], 8));
221  P[0] = RR(P[0] ^ (t0 + t1 + cs->K[2 * i + 10]), 1);
222  P[1] = LR(P[1], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 11]);
223  }
224  P[2] ^= cs->K[4];
225  P[3] ^= cs->K[5];
226  P[0] ^= cs->K[6];
227  P[1] ^= cs->K[7];
228  AV_WL32(dst, P[2]);
229  AV_WL32(dst + 4, P[3]);
230  AV_WL32(dst + 8, P[0]);
231  AV_WL32(dst + 12, P[1]);
232 }
233 
234 static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
235 {
236  uint32_t P[4], t0, t1;
237  int i;
238  P[2] = AV_RL32(src) ^ cs->K[4];
239  P[3] = AV_RL32(src + 4) ^ cs->K[5];
240  P[0] = AV_RL32(src + 8) ^ cs->K[6];
241  P[1] = AV_RL32(src + 12) ^ cs->K[7];
242  for (i = 15; i >= 0; i -= 2) {
243  t0 = MDS_mul(cs, P[2]);
244  t1 = MDS_mul(cs, LR(P[3], 8));
245  P[0] = LR(P[0], 1) ^ (t0 + t1 + cs->K[2 * i + 8]);
246  P[1] = RR(P[1] ^ (t0 + 2 * t1 + cs->K[2 * i + 9]), 1);
247  t0 = MDS_mul(cs, P[0]);
248  t1 = MDS_mul(cs, LR(P[1], 8));
249  P[2] = LR(P[2], 1) ^ (t0 + t1 + cs->K[2 * i + 6]);
250  P[3] = RR(P[3] ^ (t0 + 2 * t1 + cs->K[2 * i + 7]), 1);
251  }
252  P[0] ^= cs->K[0];
253  P[1] ^= cs->K[1];
254  P[2] ^= cs->K[2];
255  P[3] ^= cs->K[3];
256  if (iv) {
257  P[0] ^= AV_RL32(iv);
258  P[1] ^= AV_RL32(iv + 4);
259  P[2] ^= AV_RL32(iv + 8);
260  P[3] ^= AV_RL32(iv + 12);
261  memcpy(iv, src, 16);
262  }
263  AV_WL32(dst, P[2]);
264  AV_WL32(dst + 4, P[3]);
265  AV_WL32(dst + 8, P[0]);
266  AV_WL32(dst + 12, P[1]);
267 }
268 
269 av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits)
270 {
271  int i;
272  uint8_t keypad[32];
273  uint32_t Key[8], Me[4], Mo[4], A, B;
274  const uint32_t rho = 0x01010101;
275  if (key_bits < 0)
276  return -1;
277  if (key_bits <= 128) {
278  cs->ksize = 2;
279  } else if (key_bits <= 192) {
280  cs->ksize = 3;
281  } else {
282  cs->ksize = 4;
283  }
284  memset(keypad, 0, sizeof(keypad));
285  if (key_bits <= 256) {
286  memcpy(keypad, key, key_bits >> 3);
287  } else {
288  memcpy(keypad, key, 32);
289  }
290  for (i = 0; i < 2 * cs->ksize ; i++)
291  Key[i] = AV_RL32(keypad + 4 * i);
292  for (i = 0; i < cs->ksize; i++) {
293  Me[i] = Key[2 * i];
294  Mo[i] = Key[2 * i + 1];
295  cs->S[cs->ksize - i - 1] = tf_RS(Me[i], Mo[i]);
296  }
297  precomputeMDS(cs);
298  for (i = 0; i < 20; i++) {
299  A = tf_h((2 * i) * rho, Me, cs->ksize);
300  B = tf_h((2 * i + 1) * rho, Mo, cs->ksize);
301  B = LR(B, 8);
302  cs->K[2 * i] = A + B;
303  cs->K[2 * i + 1] = LR((A + (2 * B)), 9);
304  }
305  if (cs->ksize << 6 != key_bits) {
306  return 1;
307  } else {
308  return 0;
309  }
310 }
311 
312 void av_twofish_crypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
313 {
314  int i;
315  while (count--) {
316  if (decrypt) {
317  twofish_decrypt(cs, dst, src, iv);
318  } else {
319  if (iv) {
320  for (i = 0; i < 16; i++)
321  dst[i] = src[i] ^ iv[i];
322  twofish_encrypt(cs, dst, dst);
323  memcpy(iv, dst, 16);
324  } else {
325  twofish_encrypt(cs, dst, src);
326  }
327  }
328  src = src + 16;
329  dst = dst + 16;
330  }
331 }
332 
333 #ifdef TEST
334 #include<stdio.h>
335 #include<stdlib.h>
336 #include"log.h"
337 
338 int main(int argc, char *argv[])
339 {
340  uint8_t Key[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
341  };
342  const uint8_t rct[6][16] = {
343  {0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a},
344  {0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf, 0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48},
345  {0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8, 0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20},
346  {0x5d, 0x9d, 0x4e, 0xef, 0xfa, 0x91, 0x51, 0x57, 0x55, 0x24, 0xf1, 0x15, 0x81, 0x5a, 0x12, 0xe0},
347  {0xe7, 0x54, 0x49, 0x21, 0x2b, 0xee, 0xf9, 0xf4, 0xa3, 0x90, 0xbd, 0x86, 0x0a, 0x64, 0x09, 0x41},
348  {0x37, 0xfe, 0x26, 0xff, 0x1c, 0xf6, 0x61, 0x75, 0xf5, 0xdd, 0xf4, 0xc3, 0x3b, 0x97, 0xa2, 0x05}
349  };
350  uint8_t temp[32], iv[16], rpt[32] = {0};
351  const int kbits[3] = {128, 192, 256};
352  int i, j, err = 0;
353  AVTWOFISH *cs;
354  cs = av_twofish_alloc();
355  if (!cs)
356  return 1;
357  for (j = 1; j < 3; j++) {
358  av_twofish_init(cs, Key, kbits[j]);
359  av_twofish_crypt(cs, temp, rpt, 1, NULL, 0);
360  for (i = 0; i < 16; i++) {
361  if (rct[j][i] != temp[i]) {
362  av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]);
363  err = 1;
364  }
365  }
366  av_twofish_crypt(cs, temp, rct[j], 1, NULL, 1);
367  for (i = 0; i < 16; i++) {
368  if (rpt[i] != temp[i]) {
369  av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
370  err = 1;
371  }
372  }
373  }
374  for (j = 0; j < 3; j++) {
375  memset(Key, 0, sizeof(Key));
376  memset(rpt, 0, sizeof(rpt));
377  for (i = 1; i < 50; i++) {
378  av_twofish_init(cs, Key, kbits[j]);
379  av_twofish_crypt(cs, temp, rpt, 1, NULL, 0);
380  memcpy(Key+16,Key,(kbits[j]-128) >> 3);
381  memcpy(Key,rpt,16);
382  memcpy(rpt,temp,16);
383  }
384  for (i = 0; i < 16; i++) {
385  if (rct[3 + j][i] != temp[i]) {
386  av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[3 + j][i], temp[i]);
387  err = 1;
388  }
389  }
390  }
391  memset(rpt, 0, sizeof(rpt));
392  memcpy(iv, "HALLO123HALLO123", 16);
393  av_twofish_crypt(cs, temp, rpt, 2, iv, 0);
394  memcpy(iv, "HALLO123HALLO123", 16);
395  av_twofish_crypt(cs, temp, temp, 2, iv, 1);
396  for (i = 0; i < 32; i++) {
397  if (rpt[i] != temp[i]) {
398  av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
399  err = 1;
400  }
401  }
402  av_free(cs);
403  return err;
404 }
405 #endif
#define NULL
Definition: coverity.c:32
static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src)
Definition: twofish.c:206
const char * s
Definition: avisynth_c.h:631
#define P
else temp
Definition: vf_mcdeint.c:257
const char * b
Definition: vf_curves.c:109
int ksize
Definition: twofish.c:32
static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
Definition: twofish.c:173
static uint32_t tf_RS(uint32_t k0, uint32_t k1)
Definition: twofish.c:137
static const uint8_t q1[256]
Definition: twofish.c:96
Macro definitions for various function/variable attributes.
#define RR(x, n)
Definition: twofish.c:27
uint8_t
#define av_cold
Definition: attributes.h:74
static void precomputeMDS(AVTWOFISH *cs)
Definition: twofish.c:192
#define t0
Definition: regdef.h:28
static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
Definition: twofish.c:187
#define A(x)
Definition: vp56_arith.h:28
#define av_log(a,...)
unsigned m
Definition: audioconvert.c:187
Public header for libavutil TWOFISH algorithm.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
const char * r
Definition: vf_curves.c:107
#define t1
Definition: regdef.h:29
GLsizei count
Definition: opengl_enc.c:109
static const uint8_t q0[256]
Definition: twofish.c:77
static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
Definition: twofish.c:234
const int av_twofish_size
Definition: twofish.c:120
float y
struct AVTWOFISH * av_twofish_alloc(void)
Allocate an AVTWOFISH context To free the struct: av_free(ptr)
Definition: twofish.c:115
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:312
uint32_t S[4]
Definition: twofish.c:31
static const uint8_t MD1[256]
Definition: twofish.c:39
#define L(x)
Definition: vp56_arith.h:36
AVS_Value src
Definition: avisynth_c.h:482
uint32_t K[40]
Definition: twofish.c:30
static uint8_t gfmul(uint8_t a, uint8_t b)
Definition: twofish.c:122
uint32_t MDS2[256]
Definition: twofish.c:34
static const uint8_t MD2[256]
Definition: twofish.c:58
common internal and external API header
uint32_t MDS4[256]
Definition: twofish.c:36
uint32_t MDS1[256]
Definition: twofish.c:33
Definition: vf_geq.c:46
#define av_free(p)
#define LR(x, n)
Definition: twofish.c:26
av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits)
Initialize an AVTWOFISH context.
Definition: twofish.c:269
int main(int argc, char **argv)
Definition: main.c:22
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
uint32_t MDS3[256]
Definition: twofish.c:35
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
Definition: twofish.c:149
#define AV_WL32(p, v)
Definition: intreadwrite.h:426