FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/twofish.c
Date: 2024-04-19 17:50:32
Exec Total Coverage
Lines: 150 153 98.0%
Functions: 11 11 100.0%
Branches: 41 44 93.2%

Line Branch Exec Source
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
119 1 struct AVTWOFISH *av_twofish_alloc(void)
120 {
121 1 return av_mallocz(sizeof(struct AVTWOFISH));
122 }
123
124 const int av_twofish_size = sizeof(AVTWOFISH);
125
126 14336 static uint8_t gfmul(uint8_t a, uint8_t b)
127 {
128 14336 uint8_t r = 0, t;
129
4/4
✓ Branch 0 taken 94258 times.
✓ Branch 1 taken 13596 times.
✓ Branch 2 taken 93518 times.
✓ Branch 3 taken 740 times.
107854 while (a && b) {
130
2/2
✓ Branch 0 taken 51877 times.
✓ Branch 1 taken 41641 times.
93518 if (a & 1)
131 51877 r = r ^ b;
132 93518 t = b & 0x80;
133 93518 b = b << 1;
134
2/2
✓ Branch 0 taken 47268 times.
✓ Branch 1 taken 46250 times.
93518 if (t)
135 47268 b = b ^ 0x4d;
136 93518 a = a >> 1;
137 }
138 14336 return r;
139 }
140
141 448 static uint32_t tf_RS(uint32_t k0, uint32_t k1)
142 {
143 uint8_t s[4], m[8];
144 448 AV_WL32(m, k0);
145 448 AV_WL32(m + 4, k1);
146 448 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 448 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 448 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 448 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 448 return AV_RL32(s);
151 }
152
153 44104 static void tf_h0(uint8_t y[4], uint32_t L[4], int k)
154 {
155 uint8_t l[4];
156
2/2
✓ Branch 0 taken 14800 times.
✓ Branch 1 taken 29304 times.
44104 if (k == 4) {
157 14800 AV_WL32(l, L[3]);
158 14800 y[0] = q1[y[0]] ^ l[0];
159 14800 y[1] = q0[y[1]] ^ l[1];
160 14800 y[2] = q0[y[2]] ^ l[2];
161 14800 y[3] = q1[y[3]] ^ l[3];
162 }
163
2/2
✓ Branch 0 taken 29600 times.
✓ Branch 1 taken 14504 times.
44104 if (k >= 3) {
164 29600 AV_WL32(l, L[2]);
165 29600 y[0] = q1[y[0]] ^ l[0];
166 29600 y[1] = q1[y[1]] ^ l[1];
167 29600 y[2] = q0[y[2]] ^ l[2];
168 29600 y[3] = q0[y[3]] ^ l[3];
169 }
170 44104 AV_WL32(l, L[1]);
171 44104 y[0] = q1[q0[q0[y[0]] ^ l[0]] ^ (L[0] & 0xff)];
172 44104 y[1] = q0[q0[q1[y[1]] ^ l[1]] ^ ((L[0] >> 8) & 0xff)];
173 44104 y[2] = q1[q1[q0[y[2]] ^ l[2]] ^ ((L[0] >> 16) & 0xff)];
174 44104 y[3] = q0[q1[q1[y[3]] ^ l[3]] ^ (L[0] >> 24)];
175 44104 }
176
177 5960 static uint32_t tf_h(uint32_t X, uint32_t L[4], int k)
178 {
179 uint8_t y[4], l[4];
180 5960 AV_WL32(y, X);
181 5960 tf_h0(y, L, k);
182
183 5960 l[0] = y[0] ^ MD2[y[1]] ^ MD1[y[2]] ^ MD1[y[3]];
184 5960 l[1] = MD1[y[0]] ^ MD2[y[1]] ^ MD2[y[2]] ^ y[3];
185 5960 l[2] = MD2[y[0]] ^ MD1[y[1]] ^ y[2] ^ MD2[y[3]];
186 5960 l[3] = MD2[y[0]] ^ y[1] ^ MD2[y[2]] ^ MD1[y[3]];
187
188 5960 return AV_RL32(l);
189 }
190
191 9664 static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X)
192 {
193 9664 return cs->MDS1[(X) & 0xff] ^ cs->MDS2[((X) >> 8) & 0xff] ^ cs->MDS3[((X) >> 16) & 0xff] ^ cs->MDS4[(X) >> 24];
194 }
195
196 149 static void precomputeMDS(AVTWOFISH *cs)
197 {
198 uint8_t y[4];
199 int i;
200
2/2
✓ Branch 0 taken 38144 times.
✓ Branch 1 taken 149 times.
38293 for (i = 0; i < 256; i++) {
201 38144 y[0] = y[1] = y[2] = y[3] = i;
202 38144 tf_h0(y, cs->S, cs->ksize);
203 38144 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 38144 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 38144 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 38144 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 149 }
209
210 151 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 151 P[0] = AV_RL32(src) ^ cs->K[0];
215 151 P[1] = AV_RL32(src + 4) ^ cs->K[1];
216 151 P[2] = AV_RL32(src + 8) ^ cs->K[2];
217 151 P[3] = AV_RL32(src + 12) ^ cs->K[3];
218
2/2
✓ Branch 0 taken 1208 times.
✓ Branch 1 taken 151 times.
1359 for (i = 0; i < 16; i += 2) {
219 1208 t0 = MDS_mul(cs, P[0]);
220 1208 t1 = MDS_mul(cs, LR(P[1], 8));
221 1208 P[2] = RR(P[2] ^ (t0 + t1 + cs->K[2 * i + 8]), 1);
222 1208 P[3] = LR(P[3], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 9]);
223 1208 t0 = MDS_mul(cs, P[2]);
224 1208 t1 = MDS_mul(cs, LR(P[3], 8));
225 1208 P[0] = RR(P[0] ^ (t0 + t1 + cs->K[2 * i + 10]), 1);
226 1208 P[1] = LR(P[1], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 11]);
227 }
228 151 P[2] ^= cs->K[4];
229 151 P[3] ^= cs->K[5];
230 151 P[0] ^= cs->K[6];
231 151 P[1] ^= cs->K[7];
232 151 AV_WL32(dst, P[2]);
233 151 AV_WL32(dst + 4, P[3]);
234 151 AV_WL32(dst + 8, P[0]);
235 151 AV_WL32(dst + 12, P[1]);
236 151 }
237
238 151 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 151 P[2] = AV_RL32(src) ^ cs->K[4];
243 151 P[3] = AV_RL32(src + 4) ^ cs->K[5];
244 151 P[0] = AV_RL32(src + 8) ^ cs->K[6];
245 151 P[1] = AV_RL32(src + 12) ^ cs->K[7];
246
2/2
✓ Branch 0 taken 1208 times.
✓ Branch 1 taken 151 times.
1359 for (i = 15; i >= 0; i -= 2) {
247 1208 t0 = MDS_mul(cs, P[2]);
248 1208 t1 = MDS_mul(cs, LR(P[3], 8));
249 1208 P[0] = LR(P[0], 1) ^ (t0 + t1 + cs->K[2 * i + 8]);
250 1208 P[1] = RR(P[1] ^ (t0 + 2 * t1 + cs->K[2 * i + 9]), 1);
251 1208 t0 = MDS_mul(cs, P[0]);
252 1208 t1 = MDS_mul(cs, LR(P[1], 8));
253 1208 P[2] = LR(P[2], 1) ^ (t0 + t1 + cs->K[2 * i + 6]);
254 1208 P[3] = RR(P[3] ^ (t0 + 2 * t1 + cs->K[2 * i + 7]), 1);
255 }
256 151 P[0] ^= cs->K[0];
257 151 P[1] ^= cs->K[1];
258 151 P[2] ^= cs->K[2];
259 151 P[3] ^= cs->K[3];
260
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 149 times.
151 if (iv) {
261 2 P[0] ^= AV_RL32(iv);
262 2 P[1] ^= AV_RL32(iv + 4);
263 2 P[2] ^= AV_RL32(iv + 8);
264 2 P[3] ^= AV_RL32(iv + 12);
265 2 memcpy(iv, src, 16);
266 }
267 151 AV_WL32(dst, P[0]);
268 151 AV_WL32(dst + 4, P[1]);
269 151 AV_WL32(dst + 8, P[2]);
270 151 AV_WL32(dst + 12, P[3]);
271 151 }
272
273 149 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 149 const uint32_t rho = 0x01010101;
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
149 if (key_bits < 0)
280 return AVERROR(EINVAL);
281
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 100 times.
149 if (key_bits <= 128) {
282 49 cs->ksize = 2;
283
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 50 times.
100 } else if (key_bits <= 192) {
284 50 cs->ksize = 3;
285 } else {
286 50 cs->ksize = 4;
287 }
288 149 memset(keypad, 0, sizeof(keypad));
289
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 if (key_bits <= 256) {
290 149 memcpy(keypad, key, key_bits >> 3);
291 } else {
292 memcpy(keypad, key, 32);
293 }
294
2/2
✓ Branch 0 taken 896 times.
✓ Branch 1 taken 149 times.
1045 for (i = 0; i < 2 * cs->ksize ; i++)
295 896 Key[i] = AV_RL32(keypad + 4 * i);
296
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 149 times.
597 for (i = 0; i < cs->ksize; i++) {
297 448 Me[i] = Key[2 * i];
298 448 Mo[i] = Key[2 * i + 1];
299 448 cs->S[cs->ksize - i - 1] = tf_RS(Me[i], Mo[i]);
300 }
301 149 precomputeMDS(cs);
302
2/2
✓ Branch 0 taken 2980 times.
✓ Branch 1 taken 149 times.
3129 for (i = 0; i < 20; i++) {
303 2980 A = tf_h((2 * i) * rho, Me, cs->ksize);
304 2980 B = tf_h((2 * i + 1) * rho, Mo, cs->ksize);
305 2980 B = LR(B, 8);
306 2980 cs->K[2 * i] = A + B;
307 2980 cs->K[2 * i + 1] = LR((A + (2 * B)), 9);
308 }
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
149 if (cs->ksize << 6 != key_bits) {
310 return 1;
311 } else {
312 149 return 0;
313 }
314 }
315
316 300 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
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 300 times.
602 while (count--) {
320
2/2
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 151 times.
302 if (decrypt) {
321 151 twofish_decrypt(cs, dst, src, iv);
322 } else {
323
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 149 times.
151 if (iv) {
324
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 for (i = 0; i < 16; i++)
325 32 dst[i] = src[i] ^ iv[i];
326 2 twofish_encrypt(cs, dst, dst);
327 2 memcpy(iv, dst, 16);
328 } else {
329 149 twofish_encrypt(cs, dst, src);
330 }
331 }
332 302 src = src + 16;
333 302 dst = dst + 16;
334 }
335 300 }
336