1 /***************************************************************************
2 * Copyright (C) 2005-2007 Tarek Saidi <tarek.saidi@arcor.de> *
3 * Copyright (c) 2003,2004 Dominik Reichl <dominik.reichl@t-online.de> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; version 2 of the License. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
24 static bool g_bInitialized = false;
34 bool CTwofish::init(quint8 *pKey, unsigned long uKeyLen, quint8 *initVector)
36 //ASSERT(pKey != NULL);
37 if(pKey == NULL) return false;
38 //ASSERT(uKeyLen != 0);
39 if(uKeyLen == 0) return false;
41 if(g_bInitialized == false)
44 g_bInitialized = true;
47 Twofish_prepare_key((Twofish_Byte *)pKey, uKeyLen, &m_key);
49 if(initVector != NULL) memcpy(m_pInitVector, initVector, 16);
50 else memset(m_pInitVector, 0, 16);
55 int CTwofish::padEncrypt(quint8 *pInput, int nInputOctets, quint8 *pOutBuffer)
57 int i, numBlocks, padLen;
58 quint8 block[16], *iv;
60 //ASSERT((pInput != NULL) && (nInputOctets != NULL) && (pOutBuffer != NULL));
61 if((pInput == NULL) || (nInputOctets <= 0) || (pOutBuffer == NULL)) return 0;
63 numBlocks = nInputOctets / 16;
66 for(i = numBlocks; i > 0; i--)
68 ((quint32*)block)[0] = ((quint32*)pInput)[0] ^ ((quint32*)iv)[0];
69 ((quint32*)block)[1] = ((quint32*)pInput)[1] ^ ((quint32*)iv)[1];
70 ((quint32*)block)[2] = ((quint32*)pInput)[2] ^ ((quint32*)iv)[2];
71 ((quint32*)block)[3] = ((quint32*)pInput)[3] ^ ((quint32*)iv)[3];
73 Twofish_encrypt(&m_key, (Twofish_Byte *)block, (Twofish_Byte *)pOutBuffer);
80 padLen = 16 - (nInputOctets - (16 * numBlocks));
82 for (i = 0; i < 16 - padLen; i++)
84 block[i] = (quint8)(pInput[i] ^ iv[i]);
87 for (i = 16 - padLen; i < 16; i++)
89 block[i] = (quint8)((quint8)padLen ^ iv[i]);
92 Twofish_encrypt(&m_key, (Twofish_Byte *)block, (Twofish_Byte *)pOutBuffer);
94 return 16 * (numBlocks + 1);
97 int CTwofish::padDecrypt(quint8 *pInput, int nInputOctets, quint8 *pOutBuffer)
99 int i, numBlocks, padLen;
103 //ASSERT((pInput != NULL) && (nInputOctets != NULL) && (pOutBuffer != NULL));
104 if((pInput == NULL) || (nInputOctets <= 0) || (pOutBuffer == NULL)) return 0;
106 if((nInputOctets % 16) != 0) { /*ASSERT(FALSE);*/ return -1; }
108 numBlocks = nInputOctets / 16;
110 memcpy(iv, m_pInitVector, 16);
112 for(i = numBlocks - 1; i > 0; i--)
114 Twofish_decrypt(&m_key, (Twofish_Byte *)pInput, (Twofish_Byte *)block);
115 ((quint32*)block)[0] ^= iv[0];
116 ((quint32*)block)[1] ^= iv[1];
117 ((quint32*)block)[2] ^= iv[2];
118 ((quint32*)block)[3] ^= iv[3];
119 memcpy(iv, pInput, 16);
120 memcpy(pOutBuffer, block, 16);
125 Twofish_decrypt(&m_key, (Twofish_Byte *)pInput, (Twofish_Byte *)block);
126 ((quint32*)block)[0] ^= iv[0];
127 ((quint32*)block)[1] ^= iv[1];
128 ((quint32*)block)[2] ^= iv[2];
129 ((quint32*)block)[3] ^= iv[3];
131 if(padLen <= 0 || padLen > 16) return -1;
132 for(i = 16 - padLen; i < 16; i++)
134 if(block[i] != padLen) return -1;
136 memcpy(pOutBuffer, block, 16 - padLen);
138 return 16*numBlocks - padLen;