FFmpeg
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 
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 
120 {
121  return av_mallocz(sizeof(struct AVTWOFISH));
122 }
123 
124 const int av_twofish_size = sizeof(AVTWOFISH);
125 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 }
A
#define A(x)
Definition: vpx_arith.h:28
q1
static const uint8_t q1[256]
Definition: twofish.c:100
AVTWOFISH::S
uint32_t S[4]
Definition: twofish.c:35
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVTWOFISH
Definition: twofish.c:33
av_twofish_size
const int av_twofish_size
Definition: twofish.c:124
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
b
#define b
Definition: input.c:41
RR
#define RR(x, n)
Definition: twofish.c:31
twofish_encrypt
static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src)
Definition: twofish.c:210
AVTWOFISH::K
uint32_t K[40]
Definition: twofish.c:34
MDS_mul
static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
Definition: twofish.c:191
av_twofish_init
av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits)
Initialize an AVTWOFISH context.
Definition: twofish.c:273
AVTWOFISH::MDS2
uint32_t MDS2[256]
Definition: twofish.c:38
precomputeMDS
static void precomputeMDS(AVTWOFISH *cs)
Definition: twofish.c:196
AVTWOFISH::MDS4
uint32_t MDS4[256]
Definition: twofish.c:40
AVTWOFISH::MDS1
uint32_t MDS1[256]
Definition: twofish.c:37
av_twofish_alloc
struct AVTWOFISH * av_twofish_alloc(void)
Allocate an AVTWOFISH context To free the struct: av_free(ptr)
Definition: twofish.c:119
twofish_decrypt
static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
Definition: twofish.c:238
av_cold
#define av_cold
Definition: attributes.h:90
tf_RS
static uint32_t tf_RS(uint32_t k0, uint32_t k1)
Definition: twofish.c:141
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
B
#define B
Definition: huffyuv.h:42
key
const char * key
Definition: hwcontext_opencl.c:189
q0
static const uint8_t q0[256]
Definition: twofish.c:81
AVTWOFISH::MDS3
uint32_t MDS3[256]
Definition: twofish.c:39
MD1
static const uint8_t MD1[256]
Definition: twofish.c:43
error.h
av_twofish_crypt
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
P
#define P
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
twofish.h
Public header for libavutil TWOFISH algorithm.
X
@ X
Definition: vf_addroi.c:27
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
attributes.h
AVTWOFISH::ksize
int ksize
Definition: twofish.c:36
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
gfmul
static uint8_t gfmul(uint8_t a, uint8_t b)
Definition: twofish.c:126
MD2
static const uint8_t MD2[256]
Definition: twofish.c:62
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
LR
#define LR(x, n)
Definition: twofish.c:30
L
#define L(x)
Definition: vpx_arith.h:36
mem.h
tf_h0
static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
Definition: twofish.c:153
tf_h
static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
Definition: twofish.c:177
src
#define src
Definition: vp8dsp.c:248