Kinetis Bootloader Host  2.0.0
Host Tools for Kinetis devices
src/blfwk/rijndael.h
1 #ifndef _RIJNDAEL_H_
2 #define _RIJNDAEL_H_
3 
4 //
5 // File : rijndael.h
6 // Creation date : Sun Nov 5 2000 03:21:05 CEST
7 // Author : Szymon Stefanek (stefanek@tin.it)
8 //
9 // Another implementation of the Rijndael cipher.
10 // This is intended to be an easily usable library file.
11 // This code is public domain.
12 // Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
13 //
14 
15 //
16 // Original Copyright notice:
17 //
18 // rijndael-alg-fst.c v2.4 April '2000
19 // rijndael-alg-fst.h
20 // rijndael-api-fst.c
21 // rijndael-api-fst.h
22 //
23 // Optimised ANSI C code
24 //
25 // authors: v1.0: Antoon Bosselaers
26 // v2.0: Vincent Rijmen, K.U.Leuven
27 // v2.3: Paulo Barreto
28 // v2.4: Vincent Rijmen, K.U.Leuven
29 //
30 // This code is placed in the public domain.
31 //
32 
33 //
34 // This implementation works on 128 , 192 , 256 bit keys
35 // and on 128 bit blocks
36 //
37 
38 //
39 // Example of usage:
40 //
41 // // Input data
42 // unsigned char key[32]; // The key
43 // initializeYour256BitKey(); // Obviously initialized with sth
44 // const unsigned char * plainText = getYourPlainText(); // Your plain text
45 // int plainTextLen = strlen(plainText); // Plain text length
46 //
47 // // Encrypting
48 // Rijndael rin;
49 // unsigned char output[plainTextLen + 16];
50 //
51 // rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
52 // // It is a good idea to check the error code
53 // int len = rin.padEncrypt(plainText,len,output);
54 // if(len >= 0)useYourEncryptedText();
55 // else encryptError(len);
56 //
57 // // Decrypting: we can reuse the same object
58 // unsigned char output2[len];
59 // rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes));
60 // len = rin.padDecrypt(output,len,output2);
61 // if(len >= 0)useYourDecryptedText();
62 // else decryptError(len);
63 //
64 
65 #include <stdint.h>
66 
67 #define _MAX_KEY_COLUMNS (256 / 32)
68 #define _MAX_ROUNDS 14
69 #define MAX_IV_SIZE 16
70 
71 // We assume that unsigned int is 32 bits long....
72 // typedef unsigned char uint8_t;
73 // typedef unsigned int uint32_t;
74 // typedef unsigned short uint16_t;
75 
76 // Error codes
77 #define RIJNDAEL_SUCCESS 0
78 #define RIJNDAEL_UNSUPPORTED_MODE -1
79 #define RIJNDAEL_UNSUPPORTED_DIRECTION -2
80 #define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3
81 #define RIJNDAEL_BAD_KEY -4
82 #define RIJNDAEL_NOT_INITIALIZED -5
83 #define RIJNDAEL_BAD_DIRECTION -6
84 #define RIJNDAEL_CORRUPTED_DATA -7
85 
86 class Rijndael
87 {
88 public:
89  enum Direction
90  {
91  Encrypt,
92  Decrypt
93  };
94  enum Mode
95  {
96  ECB,
97  CBC,
98  CFB1
99  };
100  enum KeyLength
101  {
102  Key16Bytes,
103  Key24Bytes,
104  Key32Bytes
105  };
106  //
107  // Creates a Rijndael cipher object
108  // You have to call init() before you can encrypt or decrypt stuff
109  //
110  Rijndael();
111  ~Rijndael();
112 
113 protected:
114  // Internal stuff
115  enum State
116  {
117  Valid,
118  Invalid
119  };
120 
121  State m_state;
122  Mode m_mode;
123  Direction m_direction;
124  uint8_t m_initVector[MAX_IV_SIZE];
125  uint32_t m_uRounds;
126  uint8_t m_expandedKey[_MAX_ROUNDS + 1][4][4];
127 
128 public:
130  // API
132 
133  // init(): Initializes the crypt session
134  // Returns RIJNDAEL_SUCCESS or an error code
135  // mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1
136  // You have to use the same mode for encrypting and decrypting
137  // dir : Rijndael::Encrypt or Rijndael::Decrypt
138  // A cipher instance works only in one direction
139  // (Well , it could be easily modified to work in both
140  // directions with a single init() call, but it looks
141  // useless to me...anyway , it is a matter of generating
142  // two expanded keys)
143  // key : array of unsigned octets , it can be 16 , 24 or 32 bytes long
144  // this CAN be binary data (it is not expected to be null terminated)
145  // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes
146  // initVector: initialization vector, you will usually use 0 here
147  int init(Mode mode, Direction dir, const uint8_t *key, KeyLength keyLen, uint8_t *initVector = 0);
148  // Encrypts the input array (can be binary data)
149  // The input array length must be a multiple of 16 bytes, the remaining part
150  // is DISCARDED.
151  // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer
152  // Input len is in BITS!
153  // outBuffer must be at least inputLen / 8 bytes long.
154  // Returns the encrypted buffer length in BITS or an error code < 0 in case of error
155  int blockEncrypt(const uint8_t *input, int inputLen, uint8_t *outBuffer);
156  // Encrypts the input array (can be binary data)
157  // The input array can be any length , it is automatically padded on a 16 byte boundary.
158  // Input len is in BYTES!
159  // outBuffer must be at least (inputLen + 16) bytes long
160  // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
161  int padEncrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer);
162  // Decrypts the input vector
163  // Input len is in BITS!
164  // outBuffer must be at least inputLen / 8 bytes long
165  // Returns the decrypted buffer length in BITS and an error code < 0 in case of error
166  int blockDecrypt(const uint8_t *input, int inputLen, uint8_t *outBuffer);
167  // Decrypts the input vector
168  // Input len is in BYTES!
169  // outBuffer must be at least inputLen bytes long
170  // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
171  int padDecrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer);
172 
173 protected:
174  void keySched(uint8_t key[_MAX_KEY_COLUMNS][4]);
175  void keyEncToDec();
176  void encrypt(const uint8_t a[16], uint8_t b[16]);
177  void decrypt(const uint8_t a[16], uint8_t b[16]);
178 };
179 
180 #endif // _RIJNDAEL_H_
Definition: apps/elftosb/common/rijndael.h:86