Browse Source

readability code clean-up (#530)

pull/536/head
Logan oos Even 4 years ago
committed by GitHub
parent
commit
9fbe941511
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 46
      include/tf.h
  2. 145
      src/tf.c

46
include/tf.h

@ -22,37 +22,39 @@
// published on github/drewcsillag/twofish // published on github/drewcsillag/twofish
/* /**
The MIT License (MIT) * The MIT License (MIT)
*
Copyright (c) 2015 Andrew T. Csillag * Copyright (c) 2015 Andrew T. Csillag
*
Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef TF_H #ifndef TF_H
#define TF_H #define TF_H
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "portable_endian.h" #include "portable_endian.h"

145
src/tf.c

@ -22,28 +22,28 @@
// published on github/drewcsillag/twofish // published on github/drewcsillag/twofish
/* /**
The MIT License (MIT) * The MIT License (MIT)
*
Copyright (c) 2015 Andrew T. Csillag * Copyright (c) 2015 Andrew T. Csillag
*
Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. * THE SOFTWARE.
*/ */
@ -123,6 +123,7 @@ const uint8_t multEF[] = { 0x00, 0xEF, 0xB7, 0x58, 0x07, 0xE8, 0xB0, 0x5F, 0x0E,
0xA8, 0x47, 0x1F, 0xF0, 0xAF, 0x40, 0x18, 0xF7, 0xA6, 0x49, 0x11, 0xFE, 0xA1, 0x4E, 0x16, 0xF9, 0xA8, 0x47, 0x1F, 0xF0, 0xAF, 0x40, 0x18, 0xF7, 0xA6, 0x49, 0x11, 0xFE, 0xA1, 0x4E, 0x16, 0xF9,
0xB4, 0x5B, 0x03, 0xEC, 0xB3, 0x5C, 0x04, 0xEB, 0xBA, 0x55, 0x0D, 0xE2, 0xBD, 0x52, 0x0A, 0xE5 }; 0xB4, 0x5B, 0x03, 0xEC, 0xB3, 0x5C, 0x04, 0xEB, 0xBA, 0x55, 0x0D, 0xE2, 0xBD, 0x52, 0x0A, 0xE5 };
#define RS_MOD 0x14D #define RS_MOD 0x14D
#define RHO 0x01010101L #define RHO 0x01010101L
@ -140,13 +141,14 @@ const uint8_t multEF[] = { 0x00, 0xEF, 0xB7, 0x58, 0x07, 0xE8, 0xB0, 0x5F, 0x0E,
#define U8S_TO_U32(r0, r1, r2, r3) ((r0 << 24) ^ (r1 << 16) ^ (r2 << 8) ^ r3) #define U8S_TO_U32(r0, r1, r2, r3) ((r0 << 24) ^ (r1 << 16) ^ (r2 << 8) ^ r3)
/* multiply two polynomials represented as u32's, actually called with bytes */ // multiply two polynomials represented as u32's, actually called with bytes
uint32_t polyMult(uint32_t a, uint32_t b) { uint32_t polyMult(uint32_t a, uint32_t b) {
uint32_t t=0; uint32_t t=0;
while(a) { while(a) {
if(a&1) t^=b; if(a & 1)
t^=b;
b <<= 1; b <<= 1;
a >>= 1; a >>= 1;
} }
@ -155,7 +157,7 @@ uint32_t polyMult(uint32_t a, uint32_t b) {
} }
/* take the polynomial t and return the t % modulus in GF(256) */ // take the polynomial t and return the t % modulus in GF(256)
uint32_t gfMod(uint32_t t, uint32_t modulus) { uint32_t gfMod(uint32_t t, uint32_t modulus) {
int i; int i;
@ -164,7 +166,8 @@ uint32_t gfMod(uint32_t t, uint32_t modulus) {
modulus <<= 7; modulus <<= 7;
for(i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
tt = t ^ modulus; tt = t ^ modulus;
if(tt < t) t = tt; if(tt < t)
t = tt;
modulus >>= 1; modulus >>= 1;
} }
@ -172,11 +175,11 @@ uint32_t gfMod(uint32_t t, uint32_t modulus) {
} }
/*multiply a and b and return the modulus */ // multiply a and b and return the modulus
#define gfMult(a, b, modulus) gfMod(polyMult(a, b), modulus) #define gfMult(a, b, modulus) gfMod(polyMult(a, b), modulus)
/* return a u32 containing the result of multiplying the RS Code matrix by the sd matrix */ // return a u32 containing the result of multiplying the RS Code matrix by the sd matrix
uint32_t RSMatrixMultiply(uint8_t sd[8]) { uint32_t RSMatrixMultiply(uint8_t sd[8]) {
int j, k; int j, k;
@ -195,7 +198,7 @@ uint32_t RSMatrixMultiply(uint8_t sd[8]) {
} }
/* the Zero-keyed h function (used by the key setup routine) */ // the Zero-keyed h function (used by the key setup routine)
uint32_t h(uint32_t X, uint32_t L[4], int k) { uint32_t h(uint32_t X, uint32_t L[4], int k) {
uint8_t y0, y1, y2, y3; uint8_t y0, y1, y2, y3;
@ -224,7 +227,7 @@ uint32_t h(uint32_t X, uint32_t L[4], int k) {
y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ]; y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
} }
/* inline the MDS matrix multiply */ // inline the MDS matrix multiply
z0 = multEF[y0] ^ y1 ^ multEF[y2] ^ mult5B[y3]; z0 = multEF[y0] ^ y1 ^ multEF[y2] ^ mult5B[y3];
z1 = multEF[y0] ^ mult5B[y1] ^ y2 ^ multEF[y3]; z1 = multEF[y0] ^ mult5B[y1] ^ y2 ^ multEF[y3];
z2 = mult5B[y0] ^ multEF[y1] ^ multEF[y2] ^ y3; z2 = mult5B[y0] ^ multEF[y1] ^ multEF[y2] ^ y3;
@ -234,15 +237,15 @@ uint32_t h(uint32_t X, uint32_t L[4], int k) {
} }
/* given the Sbox keys, create the fully keyed QF */ // given the Sbox keys, create the fully keyed QF
void fullKey(uint32_t L[4], int k, uint32_t QF[4][256]) { void fullKey(uint32_t L[4], int k, uint32_t QF[4][256]) {
uint8_t y0, y1, y2, y3; uint8_t y0, y1, y2, y3;
int i; int i;
/* for all input values to the Q permutations */ // for all input values to the Q permutations
for(i = 0; i < 256; i++) { for(i = 0; i < 256; i++) {
/* run the Q permutations */ // run the Q permutations
y0 = i; y1 = i; y2 = i; y3 = i; y0 = i; y1 = i; y2 = i; y3 = i;
switch(k) { switch(k) {
case 4: case 4:
@ -262,7 +265,7 @@ void fullKey(uint32_t L[4], int k, uint32_t QF[4][256]) {
y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ]; y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
} }
/* now do the partial MDS matrix multiplies */ // now do the partial MDS matrix multiplies
QF[0][i] = ((multEF[y0] << 24) QF[0][i] = ((multEF[y0] << 24)
| (multEF[y0] << 16) | (multEF[y0] << 16)
| (mult5B[y0] << 8) | (mult5B[y0] << 8)
@ -282,14 +285,17 @@ void fullKey(uint32_t L[4], int k, uint32_t QF[4][256]) {
} }
} }
// ------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
/* fully keyed h (aka g) function */ // fully keyed h (aka g) function
#define fkh(X) (ctx->QF[0][b0(X)]^ctx->QF[1][b1(X)]^ctx->QF[2][b2(X)]^ctx->QF[3][b3(X)]) #define fkh(X) (ctx->QF[0][b0(X)]^ctx->QF[1][b1(X)]^ctx->QF[2][b2(X)]^ctx->QF[3][b3(X)])
// -------------------------------------------------------------------------------------
/* one encryption round */ // ----------------------------------------------------------------------------------------------------------------
// one encryption round
#define ENC_ROUND(R0, R1, R2, R3, round) \ #define ENC_ROUND(R0, R1, R2, R3, round) \
T0 = fkh(R0); \ T0 = fkh(R0); \
T1 = fkh(ROL(R1, 8)); \ T1 = fkh(ROL(R1, 8)); \
@ -302,7 +308,7 @@ void twofish_internal_encrypt(uint8_t PT[16], tf_context_t *ctx) {
uint32_t R0, R1, R2, R3; uint32_t R0, R1, R2, R3;
uint32_t T0, T1; uint32_t T0, T1;
/* load/byteswap/whiten input */ // load/byteswap/whiten input
R3 = ctx->K[3] ^ le32toh(((uint32_t*)PT)[3]); R3 = ctx->K[3] ^ le32toh(((uint32_t*)PT)[3]);
R2 = ctx->K[2] ^ le32toh(((uint32_t*)PT)[2]); R2 = ctx->K[2] ^ le32toh(((uint32_t*)PT)[2]);
R1 = ctx->K[1] ^ le32toh(((uint32_t*)PT)[1]); R1 = ctx->K[1] ^ le32toh(((uint32_t*)PT)[1]);
@ -325,16 +331,18 @@ void twofish_internal_encrypt(uint8_t PT[16], tf_context_t *ctx) {
ENC_ROUND(R0, R1, R2, R3, 14); ENC_ROUND(R0, R1, R2, R3, 14);
ENC_ROUND(R2, R3, R0, R1, 15); ENC_ROUND(R2, R3, R0, R1, 15);
/* load/byteswap/whiten output */ // whiten/byteswap/store output
((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[7]); ((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[7]);
((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[6]); ((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[6]);
((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[5]); ((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[5]);
((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[4]); ((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[4]);
} }
// -------------------------------------------------------------------------------------
/* one decryption round */ // ----------------------------------------------------------------------------------------------------------------
// one decryption round
#define DEC_ROUND(R0, R1, R2, R3, round) \ #define DEC_ROUND(R0, R1, R2, R3, round) \
T0 = fkh(R0); \ T0 = fkh(R0); \
T1 = fkh(ROL(R1, 8)); \ T1 = fkh(ROL(R1, 8)); \
@ -347,7 +355,7 @@ void twofish_internal_decrypt(uint8_t PT[16], const uint8_t CT[16], tf_context_t
uint32_t T0, T1; uint32_t T0, T1;
uint32_t R0, R1, R2, R3; uint32_t R0, R1, R2, R3;
/* load/byteswap/whiten input */ // load/byteswap/whiten input
R3 = ctx->K[7] ^ le32toh(((uint32_t*)CT)[3]); R3 = ctx->K[7] ^ le32toh(((uint32_t*)CT)[3]);
R2 = ctx->K[6] ^ le32toh(((uint32_t*)CT)[2]); R2 = ctx->K[6] ^ le32toh(((uint32_t*)CT)[2]);
R1 = ctx->K[5] ^ le32toh(((uint32_t*)CT)[1]); R1 = ctx->K[5] ^ le32toh(((uint32_t*)CT)[1]);
@ -370,16 +378,18 @@ void twofish_internal_decrypt(uint8_t PT[16], const uint8_t CT[16], tf_context_t
DEC_ROUND(R0, R1, R2, R3, 1); DEC_ROUND(R0, R1, R2, R3, 1);
DEC_ROUND(R2, R3, R0, R1, 0); DEC_ROUND(R2, R3, R0, R1, 0);
/* load/byteswap/whiten output */ // whiten/byteswap/store output
((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[3]); ((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[3]);
((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[2]); ((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[2]);
((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[1]); ((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[1]);
((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[0]); ((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[0]);
} }
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
/* the key schedule routine */
// the key schedule routine
void keySched(const uint8_t M[], int N, uint32_t **S, uint32_t K[40], int *k) { void keySched(const uint8_t M[], int N, uint32_t **S, uint32_t K[40], int *k) {
uint32_t Mo[4], Me[4]; uint32_t Mo[4], Me[4];
@ -402,6 +412,7 @@ void keySched(const uint8_t M[], int N, uint32_t **S, uint32_t K[40], int *k) {
vector[j+4] = _b(Mo[i], j); vector[j+4] = _b(Mo[i], j);
(*S)[(*k)-i-1] = RSMatrixMultiply(vector); (*S)[(*k)-i-1] = RSMatrixMultiply(vector);
} }
for(i = 0; i < 20; i++) { for(i = 0; i < 20; i++) {
A = h(2*i*RHO, Me, *k); A = h(2*i*RHO, Me, *k);
B = ROL(h(2*i*RHO + RHO, Mo, *k), 8); B = ROL(h(2*i*RHO + RHO, Mo, *k), 8);
@ -410,28 +421,33 @@ void keySched(const uint8_t M[], int N, uint32_t **S, uint32_t K[40], int *k) {
} }
} }
// -------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------
#define fix_xor(target, source) *(uint32_t*)&(target)[0] = *(uint32_t*)&(target)[0] ^ *(uint32_t*)&(source)[0]; *(uint32_t*)&(target)[4] = *(uint32_t*)&(target)[4] ^ *(uint32_t*)&(source)[4]; \ #define fix_xor(target, source) *(uint32_t*)&(target)[0] = *(uint32_t*)&(target)[0] ^ *(uint32_t*)&(source)[0]; *(uint32_t*)&(target)[4] = *(uint32_t*)&(target)[4] ^ *(uint32_t*)&(source)[4]; \
*(uint32_t*)&(target)[8] = *(uint32_t*)&(target)[8] ^ *(uint32_t*)&(source)[8]; *(uint32_t*)&(target)[12] = *(uint32_t*)&(target)[12] ^ *(uint32_t*)&(source)[12]; *(uint32_t*)&(target)[8] = *(uint32_t*)&(target)[8] ^ *(uint32_t*)&(source)[8]; *(uint32_t*)&(target)[12] = *(uint32_t*)&(target)[12] ^ *(uint32_t*)&(source)[12];
// ------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
/** public API **/ // public API
int tf_ecb_decrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) { int tf_ecb_decrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) {
twofish_internal_decrypt(out, in, ctx); twofish_internal_decrypt(out, in, ctx);
return TF_BLOCK_SIZE; return TF_BLOCK_SIZE;
} }
// not used // not used
int tf_ecb_encrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) { int tf_ecb_encrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) {
memcpy(out, in, TF_BLOCK_SIZE); memcpy(out, in, TF_BLOCK_SIZE);
twofish_internal_encrypt(out, ctx); twofish_internal_encrypt(out, ctx);
return TF_BLOCK_SIZE; return TF_BLOCK_SIZE;
} }
@ -451,6 +467,7 @@ int tf_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
twofish_internal_encrypt(tmp, ctx); twofish_internal_encrypt(tmp, ctx);
memcpy(&out[i * TF_BLOCK_SIZE], tmp, TF_BLOCK_SIZE); memcpy(&out[i * TF_BLOCK_SIZE], tmp, TF_BLOCK_SIZE);
} }
return n * TF_BLOCK_SIZE; return n * TF_BLOCK_SIZE;
} }
@ -458,22 +475,22 @@ int tf_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, tf_context_t *ctx) { const unsigned char *iv, tf_context_t *ctx) {
int n; // number of blocks int n; /* number of blocks */
int ret = (int)in_len & 15; // remainder int ret = (int)in_len & 15; /* remainder */
uint8_t ivec[TF_BLOCK_SIZE]; // the ivec/old handling might be optimized if we uint8_t ivec[TF_BLOCK_SIZE]; /* the ivec/old handling might be optimized if we */
uint8_t old[TF_BLOCK_SIZE]; // can be sure that in != out uint8_t old[TF_BLOCK_SIZE]; /* can be sure that in != out */
memcpy(ivec, iv, TF_BLOCK_SIZE); memcpy(ivec, iv, TF_BLOCK_SIZE);
// 3 parallel rails of twofish decryption
for(n = in_len / TF_BLOCK_SIZE; n > 2; n -=3) { for(n = in_len / TF_BLOCK_SIZE; n > 2; n -=3) {
memcpy(old, in + 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE); memcpy(old, in + 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE);
uint32_t T0, T1; uint32_t T0, T1;
uint32_t Q0, Q1, Q2, Q3, R0, R1, R2, R3, S0, S1, S2, S3; uint32_t Q0, Q1, Q2, Q3, R0, R1, R2, R3, S0, S1, S2, S3;
/* load/byteswap/whiten input/iv */ // load/byteswap/whiten input/iv
Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]); Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]);
Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]); Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]);
Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]); Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]);
@ -506,8 +523,7 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
DEC_ROUND(Q0, Q1, Q2, Q3, 1); DEC_ROUND(R0, R1, R2, R3, 1); DEC_ROUND(S0, S1, S2, S3, 1); DEC_ROUND(Q0, Q1, Q2, Q3, 1); DEC_ROUND(R0, R1, R2, R3, 1); DEC_ROUND(S0, S1, S2, S3, 1);
DEC_ROUND(Q2, Q3, Q0, Q1, 0); DEC_ROUND(R2, R3, R0, R1, 0); DEC_ROUND(S2, S3, S0, S1, 0); DEC_ROUND(Q2, Q3, Q0, Q1, 0); DEC_ROUND(R2, R3, R0, R1, 0); DEC_ROUND(S2, S3, S0, S1, 0);
/* load/byteswap/whiten output/iv */ // whiten/byteswap/store output/iv
((uint32_t*)out)[11] = htole32(S1 ^ ctx->K[3] ^ ((uint32_t*)in)[7]); ((uint32_t*)out)[11] = htole32(S1 ^ ctx->K[3] ^ ((uint32_t*)in)[7]);
((uint32_t*)out)[10] = htole32(S0 ^ ctx->K[2] ^ ((uint32_t*)in)[6]); ((uint32_t*)out)[10] = htole32(S0 ^ ctx->K[2] ^ ((uint32_t*)in)[6]);
((uint32_t*)out)[9] = htole32(S3 ^ ctx->K[1] ^ ((uint32_t*)in)[5]); ((uint32_t*)out)[9] = htole32(S3 ^ ctx->K[1] ^ ((uint32_t*)in)[5]);
@ -528,13 +544,14 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
memcpy(ivec, old, TF_BLOCK_SIZE); memcpy(ivec, old, TF_BLOCK_SIZE);
} }
// handle the two or less remaining block on a single rail
for(; n != 0; n--) { for(; n != 0; n--) {
uint32_t T0, T1; uint32_t T0, T1;
uint32_t Q0, Q1, Q2, Q3; uint32_t Q0, Q1, Q2, Q3;
memcpy(old, in, TF_BLOCK_SIZE); memcpy(old, in, TF_BLOCK_SIZE);
/* load/byteswap/whiten input */ // load/byteswap/whiten input
Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]); Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]);
Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]); Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]);
Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]); Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]);
@ -557,7 +574,7 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
DEC_ROUND(Q0, Q1, Q2, Q3, 1); DEC_ROUND(Q0, Q1, Q2, Q3, 1);
DEC_ROUND(Q2, Q3, Q0, Q1, 0); DEC_ROUND(Q2, Q3, Q0, Q1, 0);
/* load/byteswap/whiten output/iv */ // load/byteswap/whiten output/iv
((uint32_t*)out)[3] = htole32(Q1 ^ ctx->K[3] ^ ((uint32_t*)ivec)[3]); ((uint32_t*)out)[3] = htole32(Q1 ^ ctx->K[3] ^ ((uint32_t*)ivec)[3]);
((uint32_t*)out)[2] = htole32(Q0 ^ ctx->K[2] ^ ((uint32_t*)ivec)[2]); ((uint32_t*)out)[2] = htole32(Q0 ^ ctx->K[2] ^ ((uint32_t*)ivec)[2]);
((uint32_t*)out)[1] = htole32(Q3 ^ ctx->K[1] ^ ((uint32_t*)ivec)[1]); ((uint32_t*)out)[1] = htole32(Q3 ^ ctx->K[1] ^ ((uint32_t*)ivec)[1]);
@ -571,11 +588,10 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
return n * TF_BLOCK_SIZE; return n * TF_BLOCK_SIZE;
} }
/**
* By definition twofish can only accept key up to 256 bit // by definition twofish can only accept key up to 256 bit
* we wont do any checking here and will assume user already // we wont do any checking here and will assume user already
* know about it. Twofish is undefined for key larger than 256 bit // know about it. twofish is undefined for key larger than 256 bit
*/
int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx) { int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx) {
int k; int k;
@ -585,10 +601,11 @@ int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx) {
if(!(*ctx)) { if(!(*ctx)) {
return -1; return -1;
} }
(*ctx)->N = key_size; (*ctx)->N = key_size;
keySched(key, key_size, &S, (*ctx)->K, &k); keySched(key, key_size, &S, (*ctx)->K, &k);
fullKey(S, k, (*ctx)->QF); fullKey(S, k, (*ctx)->QF);
free(S); // allocated in keySched(...) free(S); /* allocated in keySched(...) */
return 0; return 0;
} }

Loading…
Cancel
Save