rijndael.h 5.8 KB

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