twofish.c
Go to the documentation of this file.
1 /**
2  * @file twofish.c
3  * @brief Twofish encryption algorithm
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "cipher/twofish.h"
37 
38 //Check crypto library configuration
39 #if (TWOFISH_SUPPORT == ENABLED)
40 
41 //MDS matrix
42 static const uint8_t mds[4][4] =
43 {
44  {0x01, 0xEF, 0x5B, 0x5B},
45  {0x5B, 0xEF, 0xEF, 0x01},
46  {0xEF, 0x5B, 0x01, 0xEF},
47  {0xEF, 0x01, 0xEF, 0x5B}
48 };
49 
50 //RS matrix
51 static const uint8_t rs[4][8] =
52 {
53  {0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E},
54  {0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5},
55  {0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19},
56  {0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03}
57 };
58 
59 //Permutation table q0
60 static const uint8_t q0[256] =
61 {
62  0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
63  0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
64  0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
65  0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
66  0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
67  0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
68  0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
69  0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
70  0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
71  0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
72  0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
73  0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
74  0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
75  0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
76  0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
77  0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
78 };
79 
80 //Permutation table q1
81 static const uint8_t q1[256] =
82 {
83  0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
84  0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
85  0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
86  0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
87  0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
88  0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
89  0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
90  0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
91  0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
92  0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
93  0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
94  0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
95  0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
96  0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
97  0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
98  0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
99 };
100 
101 //Common interface for encryption algorithms
103 {
104  "Twofish",
105  sizeof(TwofishContext),
109  NULL,
110  NULL,
114 };
115 
116 
117 /**
118  * @brief Multiplication in GF(2^8)
119  * @param[in] a First operand
120  * @param[in] b Second operand
121  * @param[in] p Primitive polynomial of degree 8 over GF(2)
122  * @return Resulting value
123  **/
124 
125 static uint32_t GF_MUL(uint8_t a, uint8_t b, uint8_t p)
126 {
127  uint_t i;
128  uint8_t r;
129 
130  //Initialize result
131  r = 0;
132 
133  //The operand is processed bit by bit
134  for(i = 0; i < 8; i++)
135  {
136  //Check the value of the current bit
137  if((b & 0x01) != 0)
138  {
139  //An addition in GF(2^8) is identical to a bitwise XOR operation
140  r ^= a;
141  }
142 
143  //The multiplication of a polynomial by x in GF(2^8) corresponds
144  //to a shift of indices
145  if((a & 0x80) != 0)
146  {
147  a = (a << 1) ^ p;
148  }
149  else
150  {
151  a = a << 1;
152  }
153 
154  //Process next bit
155  b = b >> 1;
156  }
157 
158  //Return the resulting value
159  return r;
160 }
161 
162 
163 /**
164  * @brief Helper subroutine for implementing function h
165  * @param[in] x Input value X
166  * @param[in] l List L of 32-bit words of length k
167  * @param[in] k Length of the list L
168  * @param[in] i Index in range 0 to 3
169  * @return Output value Z
170  **/
171 
172 static uint32_t H_SUB(uint8_t x, const uint32_t *l, uint_t k, uint_t i)
173 {
174  uint32_t z;
175 
176  //This stage is optional
177  if(k == 4)
178  {
179  //The byte is passed through a fixed S-box
180  x = (i == 1 || i == 2) ? q0[x] : q1[x];
181  //Then resulting value is XORed with a byte derived from the list
182  x ^= (l[3] >> (8 * i)) & 0xFF;
183  }
184 
185  //This stage is optional
186  if(k >= 3)
187  {
188  //The byte is passed through a fixed S-box
189  x = (i == 2 || i == 3) ? q0[x] : q1[x];
190  //Then resulting value is XORed with a byte derived from the list
191  x ^= (l[2] >> (8 * i)) & 0xFF;
192  }
193 
194  //The following 2 stages are always required
195  x = (i == 0 || i == 2) ? q0[x] : q1[x];
196  x ^= (l[1] >> (8 * i)) & 0xFF;
197  x = (i == 0 || i == 1) ? q0[x] : q1[x];
198  x ^= (l[0] >> (8 * i)) & 0xFF;
199 
200  //Finally, the byte is once again passed through a fixed S-box
201  x = (i == 1 || i == 3) ? q0[x] : q1[x];
202 
203  //The resulting value is multiplied by the MDS matrix
204  z = GF_MUL(mds[0][i], x, 0x69);
205  z |= GF_MUL(mds[1][i], x, 0x69) << 8;
206  z |= GF_MUL(mds[2][i], x, 0x69) << 16;
207  z |= GF_MUL(mds[3][i], x, 0x69) << 24;
208 
209  //Return the resulting value
210  return z;
211 }
212 
213 
214 /**
215  * @brief Function h
216  * @param[in] x Input value X
217  * @param[in] l List L of 32-bit words of length k
218  * @param[in] k Length of the list L
219  * @return Output value Z
220  **/
221 
222 static uint32_t H(uint8_t x, const uint32_t *l, uint_t k)
223 {
224  uint_t i;
225  uint32_t z;
226 
227  //Initialize result
228  z = 0;
229 
230  //Process each byte of the 32-bit word
231  for(i = 0; i < 4; i++)
232  {
233  z ^= H_SUB(x, l, k, i);
234  }
235 
236  //Return the resulting value
237  return z;
238 }
239 
240 
241 /**
242  * @brief Key expansion
243  * @param[in] context Pointer to the Twofish context to initialize
244  * @param[in] key Pointer to the key
245  * @param[in] keyLen Length of the key
246  * @return Error code
247  **/
248 
249 error_t twofishInit(TwofishContext *context, const uint8_t *key, size_t keyLen)
250 {
251  uint_t i;
252  uint_t j;
253  uint_t k;
254  uint_t n;
255  uint32_t a;
256  uint32_t b;
257  uint32_t me[4];
258  uint32_t mo[4];
259  uint32_t s[4];
260 
261  //Check parameters
262  if(context == NULL || key == NULL)
264 
265  //Check the length of the key
266  if(keyLen != 16 && keyLen != 24 && keyLen != 32)
268 
269  //Let k = N / 64 where N is the length of the key, in bits
270  k = keyLen / 8;
271 
272  //The bytes are first converted into 2*k words of 32 bits each and then
273  //into two word vectors Me and Mo of length k
274  for(i = 0; i < k; i++)
275  {
276  me[i] = LOAD32LE(key + 8 * i);
277  mo[i] = LOAD32LE(key + 8 * i + 4);
278  }
279 
280  //A third word vector S of length k is derived from the key
281  for(i = 0; i < k; i++)
282  {
283  //Note that S lists the words in reverse order
284  s[k - i - 1] = 0;
285 
286  //Each result of 4 bytes is interpreted as a 32-bit word
287  for(j = 0; j < 4; j++)
288  {
289  //Take the key bytes in groups of 8, interpreting them as a vector
290  //over GF(2^8), and multiplying them by the RS matrix
291  for(a = 0, n = 0; n < 8; n++)
292  {
293  a ^= GF_MUL(rs[j][n], key[8 * i + n], 0x4D);
294  }
295 
296  //Update current word
297  s[k - i - 1] |= a << (8 * j);
298  }
299  }
300 
301  //Generate the key-dependent S-boxes
302  for(i = 0; i < 256; i++)
303  {
304  context->s1[i] = H_SUB(i, s, k, 0);
305  context->s2[i] = H_SUB(i, s, k, 1);
306  context->s3[i] = H_SUB(i, s, k, 2);
307  context->s4[i] = H_SUB(i, s, k, 3);
308  }
309 
310  //Generate the expanded key words K
311  for(i = 0; i < 20; i++)
312  {
313  //The words of the expanded key are defined using the h function
314  a = H(2 * i, me, k);
315  b = H(2 * i + 1, mo, k);
316  b = ROL32(b, 8);
317  a += b;
318  context->k[2 * i] = a;
319  a += b;
320  context->k[2 * i + 1] = ROL32(a, 9);
321  }
322 
323  //No error to report
324  return NO_ERROR;
325 }
326 
327 
328 /**
329  * @brief Encrypt a 16-byte block using Twofish algorithm
330  * @param[in] context Pointer to the Twofish context
331  * @param[in] input Plaintext block to encrypt
332  * @param[out] output Ciphertext block resulting from encryption
333  **/
334 
335 void twofishEncryptBlock(TwofishContext *context, const uint8_t *input,
336  uint8_t *output)
337 {
338  uint_t i;
339  uint32_t r0;
340  uint32_t r1;
341  uint32_t r2;
342  uint32_t r3;
343  uint32_t t0;
344  uint32_t t1;
345 
346  //The 16 bytes of plaintext are split into 4 words
347  r0 = LOAD32LE(input + 0);
348  r1 = LOAD32LE(input + 4);
349  r2 = LOAD32LE(input + 8);
350  r3 = LOAD32LE(input + 12);
351 
352  //In the input whitening step, the data words are XORed with 4 words of
353  //the expanded key
354  r0 ^= context->k[0];
355  r1 ^= context->k[1];
356  r2 ^= context->k[2];
357  r3 ^= context->k[3];
358 
359  //16 rounds of computation are needed
360  for(i = 0; i < 32; i += 4)
361  {
362  //Apply odd round function
363  t0 = context->s1[r0 & 0xFF];
364  t0 ^= context->s2[(r0 >> 8) & 0xFF];
365  t0 ^= context->s3[(r0 >> 16) & 0xFF];
366  t0 ^= context->s4[(r0 >> 24) & 0xFF];
367 
368  t1 = context->s2[r1 & 0xFF];
369  t1 ^= context->s3[(r1 >> 8) & 0xFF];
370  t1 ^= context->s4[(r1 >> 16) & 0xFF];
371  t1 ^= context->s1[(r1 >> 24) & 0xFF];
372 
373  r2 ^= t0 + t1 + context->k[8 + i];
374  r2 = ROR32(r2, 1);
375  r3 = ROL32(r3, 1);
376  r3 ^= (t0 + t1 + t1 + context->k[9 + i]);
377 
378  //Apply even round function
379  t0 = context->s1[r2 & 0xFF];
380  t0 ^= context->s2[(r2 >> 8) & 0xFF];
381  t0 ^= context->s3[(r2 >> 16) & 0xFF];
382  t0 ^= context->s4[(r2 >> 24) & 0xFF];
383 
384  t1 = context->s2[r3 & 0xFF];
385  t1 ^= context->s3[(r3 >> 8) & 0xFF];
386  t1 ^= context->s4[(r3 >> 16) & 0xFF];
387  t1 ^= context->s1[(r3 >> 24) & 0xFF];
388 
389  r0 ^= t0 + t1 + context->k[10 + i];
390  r0 = ROR32(r0, 1);
391  r1 = ROL32(r1, 1);
392  r1 ^= (t0 + t1 + t1 + context->k[11 + i]);
393  }
394 
395  //The output whitening step undoes the swap of the last round, and XORs
396  //the data words with 4 words of the expanded key
397  r2 ^= context->k[4];
398  r3 ^= context->k[5];
399  r0 ^= context->k[6];
400  r1 ^= context->k[7];
401 
402  //The 4 words of ciphertext are then written as 16 bytes
403  STORE32LE(r2, output + 0);
404  STORE32LE(r3, output + 4);
405  STORE32LE(r0, output + 8);
406  STORE32LE(r1, output + 12);
407 }
408 
409 
410 /**
411  * @brief Decrypt a 16-byte block using Twofish algorithm
412  * @param[in] context Pointer to the Twofish context
413  * @param[in] input Ciphertext block to decrypt
414  * @param[out] output Plaintext block resulting from decryption
415  **/
416 
417 void twofishDecryptBlock(TwofishContext *context, const uint8_t *input,
418  uint8_t *output)
419 {
420  uint_t i;
421  uint32_t r0;
422  uint32_t r1;
423  uint32_t r2;
424  uint32_t r3;
425  uint32_t t0;
426  uint32_t t1;
427 
428  //The 16 bytes of ciphertext are split into 4 words
429  r2 = LOAD32LE(input + 0);
430  r3 = LOAD32LE(input + 4);
431  r0 = LOAD32LE(input + 8);
432  r1 = LOAD32LE(input + 12);
433 
434  //The input whitening step undoes the swap of the last round, and XORs
435  //the data words with 4 words of the expanded key
436  r2 ^= context->k[4];
437  r3 ^= context->k[5];
438  r0 ^= context->k[6];
439  r1 ^= context->k[7];
440 
441  //16 rounds of computation are needed
442  for(i = 0; i < 32; i += 4)
443  {
444  //Apply even round function
445  t0 = context->s1[r2 & 0xFF];
446  t0 ^= context->s2[(r2 >> 8) & 0xFF];
447  t0 ^= context->s3[(r2 >> 16) & 0xFF];
448  t0 ^= context->s4[(r2 >> 24) & 0xFF];
449 
450  t1 = context->s2[r3 & 0xFF];
451  t1 ^= context->s3[(r3 >> 8) & 0xFF];
452  t1 ^= context->s4[(r3 >> 16) & 0xFF];
453  t1 ^= context->s1[(r3 >> 24) & 0xFF];
454 
455  r0 = ROL32(r0, 1);
456  r0 ^= t0 + t1 + context->k[38 - i];
457  r1 ^= (t0 + t1 + t1 + context->k[39 - i]);
458  r1 = ROR32(r1, 1);
459 
460  //Apply odd round function
461  t0 = context->s1[r0 & 0xFF];
462  t0 ^= context->s2[(r0 >> 8) & 0xFF];
463  t0 ^= context->s3[(r0 >> 16) & 0xFF];
464  t0 ^= context->s4[(r0 >> 24) & 0xFF];
465 
466  t1 = context->s2[r1 & 0xFF];
467  t1 ^= context->s3[(r1 >> 8) & 0xFF];
468  t1 ^= context->s4[(r1 >> 16) & 0xFF];
469  t1 ^= context->s1[(r1 >> 24) & 0xFF];
470 
471  r2 = ROL32(r2, 1);
472  r2 ^= t0 + t1 + context->k[36 - i];
473  r3 ^= (t0 + t1 + t1 + context->k[37 - i]);
474  r3 = ROR32(r3, 1);
475  }
476 
477  //In the output whitening step, the data words are XORed with 4 words of
478  //the expanded key
479  r0 ^= context->k[0];
480  r1 ^= context->k[1];
481  r2 ^= context->k[2];
482  r3 ^= context->k[3];
483 
484  //The 4 words of plaintext are then written as 16 bytes
485  STORE32LE(r0, output + 0);
486  STORE32LE(r1, output + 4);
487  STORE32LE(r2, output + 8);
488  STORE32LE(r3, output + 12);
489 }
490 
491 
492 /**
493  * @brief Release Twofish context
494  * @param[in] context Pointer to the Twofish context
495  **/
496 
498 {
499  //Clear Twofish context
500  osMemset(context, 0, sizeof(TwofishContext));
501 }
502 
503 #endif
unsigned int uint_t
Definition: compiler_port.h:50
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
General definitions for cryptographic algorithms.
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:983
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:980
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:968
#define ROR32(a, n)
Definition: crypto.h:782
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:977
#define ROL32(a, n)
Definition: crypto.h:776
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:932
uint8_t n
uint32_t t1
uint8_t z
Definition: dns_common.h:191
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t x
Definition: lldp_ext_med.h:211
#define H(x, y, z)
Definition: md4.c:49
uint8_t b
Definition: nbns_common.h:104
uint8_t r
Definition: ndp.h:346
uint8_t s
Definition: ndp.h:345
uint8_t l
Definition: ndp.h:412
uint8_t p
Definition: ndp.h:300
uint8_t a
Definition: ndp.h:411
#define osMemset(p, value, length)
Definition: os_port.h:135
Common interface for encryption algorithms.
Definition: crypto.h:1036
Twofish algorithm context.
Definition: twofish.h:53
uint32_t s4[256]
Definition: twofish.h:58
uint32_t s3[256]
Definition: twofish.h:57
uint32_t s1[256]
Definition: twofish.h:55
uint32_t k[40]
Definition: twofish.h:54
uint32_t s2[256]
Definition: twofish.h:56
error_t twofishInit(TwofishContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: twofish.c:249
const CipherAlgo twofishCipherAlgo
Definition: twofish.c:102
void twofishDecryptBlock(TwofishContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using Twofish algorithm.
Definition: twofish.c:417
void twofishEncryptBlock(TwofishContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using Twofish algorithm.
Definition: twofish.c:335
void twofishDeinit(TwofishContext *context)
Release Twofish context.
Definition: twofish.c:497
Twofish encryption algorithm.
#define TWOFISH_BLOCK_SIZE
Definition: twofish.h:38