summaryrefslogtreecommitdiffstats
path: root/src/modules/rijndael/rijndael.h
blob: e720df3ea9074730fb263dd04937e51842286c8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef _RIJNDAEL_H_
#define _RIJNDAEL_H_

//
//   File : rijndael.h
//   Creation date : Sun Nov 5 2000 15:42:14 CEST by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 1999-2000 Szymon Stefanek (pragma at kvirc dot net)
//
//   This program is FREE software. You can redistribute it and/or
//   modify it under the terms of the GNU General Public License
//   as published by the Free Software Foundation; either version 2
//   of the License, or (at your opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//

//
// Another implementation of the Rijndael cipher.
// This is intended to be an easily usable library file.
// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
//

//
// Original Copyright notice:
//
//    rijndael-alg-fst.c   v2.4   April '2000
//    rijndael-alg-fst.h
//    rijndael-api-fst.c
//    rijndael-api-fst.h
//
//    Optimised ANSI C code
//
//    authors: v1.0: Antoon Bosselaers
//             v2.0: Vincent Rijmen, K.U.Leuven
//             v2.3: Paulo Barreto
//             v2.4: Vincent Rijmen, K.U.Leuven
//
//    This code is placed in the public domain.
//

//
// This implementation works on 128 , 192 , 256 bit keys
// and on 128 bit blocks
//

//
// Example of usage:
//
//  // Input data
//	unsigned char key[32];                       // The key
//  initializeYour256BitKey();                   // Obviously initialized with sth
//  const unsigned char * plainText = getYourPlainText(); // Your plain text
//  int plainTextLen = strlen(plainText);        // Plain text length
//
//  // Encrypting
//	Rijndael rin;
//  unsigned char output[plainTextLen + 16];
//
//	rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
//  // It is a good idea to check the error code
//	int len = rin.padEncrypt(plainText,len,output);
//  if(len >= 0)useYourEncryptedText();
//  else encryptError(len);
//
//  // Decrypting: we can reuse the same object
//	unsigned char output2[len];
//	rin.init(Rijndael::ECB,Rijndael::Decrypt,keyMaterial,Rijndael::Key32Bytes));
//	len = rin.padDecrypt(output,len,output2);
//  if(len >= 0)useYourDecryptedText();
//  else decryptError(len);
//

#include "kvi_settings.h"

#ifdef COMPILE_CRYPT_SUPPORT

#define _MAX_KEY_COLUMNS (256/32)
#define _MAX_ROUNDS      14
//#define BITSPERBLOCK        128 /* Default number of bits in a cipher block */
#define MAX_IV_SIZE      16

// We assume that unsigned int is 32 bits long.... 
typedef unsigned char  UINT8;
typedef unsigned int   UINT32;
typedef unsigned short UINT16;

#define RIJNDAEL_SUCCESS 0
#define RIJNDAEL_UNSUPPORTED_MODE -1
#define RIJNDAEL_UNSUPPORTED_DIRECTION -2
#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3
#define RIJNDAEL_BAD_KEY -4
#define RIJNDAEL_NOT_INITIALIZED -5
#define RIJNDAEL_BAD_DIRECTION -6
#define RIJNDAEL_CORRUPTED_DATA -7

class Rijndael
{	
public:
	enum Direction { Encrypt , Decrypt };
	enum Mode { ECB , CBC , CFB1 };
	enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes };

	Rijndael();
	~Rijndael();
protected:
	enum State { Valid , Invalid };

	State     m_state;
	Mode      m_mode;
	Direction m_direction;
	UINT8     m_initVector[MAX_IV_SIZE];
	UINT32    m_uRounds;
    UINT8     m_expandedKey[_MAX_ROUNDS+1][4][4];
public:
	// Initializes the crypt session
	// Returns RIJNDAEL_SUCCESS or an error code
	int init(Mode mode,Direction dir,const UINT8 *key,KeyLength keyLen,UINT8 * initVector = 0);
	// Input len is in BITS!
	// Encrypts inputLen / 128 blocks of input and puts it in outBuffer
	// outBuffer must be at least inputLen / 8 bytes long.
	// Returns the encrypted buffer length in BITS or an error code < 0 in case of error
	int blockEncrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer);
	// Input len is in BYTES!
	// outBuffer must be at least inputLen + 16 bytes long
	// Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
	int padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer);
	// Input len is in BITS!
	// outBuffer must be at least inputLen / 8 bytes long
	// Returns the decrypted buffer length in BITS and an error code < 0 in case of error
	int blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer);
	// Input len is in BYTES!
	// outBuffer must be at least inputLen bytes long
	// Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
	int padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer);
protected:
	void keySched(UINT8 key[_MAX_KEY_COLUMNS][4]);
	void keyEncToDec();
	void encrypt(const UINT8 a[16], UINT8 b[16]);
	void decrypt(const UINT8 a[16], UINT8 b[16]);
};

#endif // COMPILE_CRYPT_SUPPORT

#endif // _RIJNDAEL_H_