-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathrijndael.h
193 lines (170 loc) · 6.4 KB
/
rijndael.h
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
///////////////////////////////////////////////////////////////////////////////
// Name: rijndael.h
// Purpose:
// Author: Ulrich Telle
// Modified by:
// Created: 2006-12-06
// Copyright: (c) Ulrich Telle (Copyright for original code see below)
// Licence: wxWindows licence
//
// The original code is unchanged
///////////////////////////////////////////////////////////////////////////////
/// \file rijndael.h Interface of the Rijndael cipher
*/
#ifndef _RIJNDAEL_H_
#define _RIJNDAEL_H_
/*
// File : rijndael.h
// Creation date : Sun Nov 5 2000 03:21:05 CEST
// Author : Szymon Stefanek (stefanek@tin.it)
//
// Another implementation of the Rijndael cipher.
// This is intended to be an easily usable library file.
// This code is public domain.
// 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::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes));
// len = rin.padDecrypt(output,len,output2);
// if(len >= 0)useYourDecryptedText();
// else decryptError(len);
//
*/
#define _MAX_KEY_COLUMNS (256/32)
#define _MAX_ROUNDS 14
#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;
/* Error codes */
#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
#define RIJNDAEL_Direction_Encrypt 0
#define RIJNDAEL_Direction_Decrypt 1
#define RIJNDAEL_Direction_Mode_ECB 0
#define RIJNDAEL_Direction_Mode_CBC 1
#define RIJNDAEL_Direction_Mode_CFB1 2
#define RIJNDAEL_Direction_KeyLength_Key16Bytes 0
#define RIJNDAEL_Direction_KeyLength_Key24Bytes 1
#define RIJNDAEL_Direction_KeyLength_Key32Bytes 2
#define RIJNDAEL_State_Valid 0
#define RIJNDAEL_State_Invalid 1
/*
/// Class implementing the Rijndael cipher. (For internal use only)
*/
typedef struct _Rijndael
{
int m_state;
int m_mode;
int m_direction;
UINT8 m_initVector[MAX_IV_SIZE];
UINT32 m_uRounds;
UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4];
} Rijndael;
void RijndaelCreate(Rijndael* rijndael);
/*
//////////////////////////////////////////////////////////////////////////////////////////
// API
//////////////////////////////////////////////////////////////////////////////////////////
// init(): Initializes the crypt session
// Returns RIJNDAEL_SUCCESS or an error code
// mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1
// You have to use the same mode for encrypting and decrypting
// dir : Rijndael::Encrypt or Rijndael::Decrypt
// A cipher instance works only in one direction
// (Well , it could be easily modified to work in both
// directions with a single init() call, but it looks
// useless to me...anyway , it is a matter of generating
// two expanded keys)
// key : array of unsigned octets , it can be 16 , 24 or 32 bytes long
// this CAN be binary data (it is not expected to be null terminated)
// keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes
// initVector: initialization vector, you will usually use 0 here
*/
int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector);
/*
// Encrypts the input array (can be binary data)
// The input array length must be a multiple of 16 bytes, the remaining part
// is DISCARDED.
// so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer
// Input len is in BITS!
// 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 RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer);
/*
// Encrypts the input array (can be binary data)
// The input array can be any length , it is automatically padded on a 16 byte boundary.
// 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 RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer);
/*
// Decrypts the input vector
// 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 RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer);
/*
// Decrypts the input vector
// 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 RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer);
void RijndaelInvalidate(Rijndael* rijndael);
void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]);
void RijndaelKeyEncToDec(Rijndael* rijndael);
void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]);
void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]);
#endif /* _RIJNDAEL_H_ */