Return to Main Page
GeSHi © 2004, Nigel McNie.
  1. `include "Constants.v"
  2.  
  3. /**************************************************************************
  4. * Rijndael - This module encapsulates the entire encryption system, and
  5. * contains the controller implementation. The interface to the
  6. * outside world accepts inputs for the data and key, and outputs
  7. * the final encrypted/decrypted data.
  8. *
  9. * clock - This clock signal is used for controlling the state of
  10. * the controller and progressing the system through the
  11. * encryption or decryption process
  12. * reset - This signals the controller to clear out the stored value
  13. * for data_in and the key, and read in new values to start
  14. * a new encryption/decryption
  15. * encrypt - This tells the system whether to perform an encryption or
  16. * a decryption on the data with the given key
  17. * key - This is the key to use for the cryptographic process
  18. * data_in - This is the data to be encrypted or decrypted
  19. * data_out - This is the result of encryption or decryption
  20. * data_ready - This signals that the cryptographic operations have
  21. * completed and the data_out is valid
  22. ***************************************************************************/
  23. module Rijndael(clock, reset, encrypt, key, data_in, data_out, data_ready);
  24. input wire clock;
  25. input wire reset;
  26. input wire encrypt;
  27. output reg data_ready;
  28. input wire[`KeyBits - 1:0] key;
  29. input wire[`DataBits - 1:0] data_in;
  30. output reg[`DataBits - 1:0] data_out;
  31. reg[`KeyBits - 1:0] mappedKey;
  32. wire[`KeyBits - 1:0] key_map;
  33. reg[`DataBits - 1:0] curKey;
  34. wire[`DataBits - 1:0] selKey;
  35. wire[(`Nb * (`Nr + 1) * 32) - 1 :0] keyExp_out;
  36. reg[(`Nb * (`Nr + 1) * 32) - 1 :0] expandedKey;
  37. reg[`DataBits - 1:0] curState;
  38. wire[`DataBits - 1:0] data_map_in, data_map_out, subState, shiftState, mixState, addKeyState;
  39. reg[3:0] round;
  40. reg[6:0] step;
  41. reg key_reset;
  42.  
  43. //These are the instantiations of the modules needed
  44. //mapDataIn - Maps the input data from the Rijndael
  45. //specified format to the systems internal format
  46. DataMap mapDataIn(clock, data_in, data_map_in);
  47.  
  48. //mapDataOut - Maps the output data from the internal
  49. //format to the Rijndael specified format
  50. DataMap mapDataOut(clock, curState, data_map_out);
  51.  
  52. //mapKey - Maps the key from big endian to little endian format
  53. KeyMap mapKey(clock, key, key_map);
  54.  
  55. //sub - Perform the byte substitution (s-box) operations
  56. ByteSub sub(clock, encrypt, curState, subState);
  57.  
  58. //shift - Performs the shift row operations
  59. ShiftRow shift(clock, encrypt, curState, shiftState);
  60.  
  61. //mix - Performs the mix columns operations
  62. MixColumn mix(clock, encrypt, curState, mixState);
  63.  
  64. //addKey - Performs the key addition (XOR) operation
  65. AddRoundKey addKey(clock, curState, addKeyState, curKey);
  66.  
  67. //keyExp - Performs the key expansion
  68. KeyExpander keyExp(clock, key_reset, mappedKey, keyExp_out);
  69.  
  70. //keySel - Performs the key selection for each round
  71. KeySelector keySel(clock, encrypt, expandedKey, selKey, round);
  72.  
  73. //This always block contains the controller state machine that is used
  74. //to progress the system from a reset through the various stages of
  75. //encryption or decryption
  76. always @(posedge clock or negedge reset)
  77. begin
  78. //When there is a reset signal the state of the controller is reset
  79. if (!reset)
  80. begin
  81. //Round F is a special round that indicates the system is just coming
  82. //out of a reset (since there can't really be a 15th round in Rijndael)
  83. round = 4'hF;
  84. //The step is the current step the system is on within the current round
  85. step = 7'h00;
  86. //key_reset is a signal that is used to tell the key expander that the
  87. //key value has changed and the expanded key must be recomputed
  88. key_reset = 0;
  89. //data_ready is set to zero until the computation for encryption/decryption
  90. //have been completed
  91. data_ready = 0;
  92. //data_out is set to zero until a valid value can be placed at the output
  93. data_out = 0;
  94. end
  95. //If the system is not being reset, then a state machine runs controlling
  96. //the encryption/decryption process
  97. else
  98. begin
  99. //When round = `Nr (the total number of rounds) the process is complete
  100. //This is because the rounds were numbered 0 to (`Nr - 1)
  101. //At this point, the data needs to be moved to the output
  102. if (round == `Nr)
  103. begin
  104. //The system must wait for one cycle until the output data map
  105. //has finished performing the map operation before setting the
  106. //output
  107. if (step == 7'h00)
  108. begin
  109. step = 7'h01;
  110. end
  111. //At this point the data is ready to be placed on the output, and data_ready is set
  112. else if (step == 7'h01)
  113. begin
  114. data_out = data_map_out;
  115. data_ready = 1;
  116. step = 7'h02;
  117. end
  118. end
  119. //Round F is a special round used after a reset to calculate the expanded key
  120. //and perform the initial XOR operation with the data and the key that exists
  121. //outside the normal rounds of encryption/decryption
  122. else if (round == 4'hF)
  123. begin
  124. step = step + 7'h01;
  125. //If step = 1 then the system has just been reset
  126. if (step == 1)
  127. begin
  128. //The value of the new mapped key is saved
  129. mappedKey = key_map;
  130. //The key expander is reset
  131. key_reset = 0;
  132. //The value of the new mapped data is saved
  133. curState = data_map_in;
  134. end
  135. //The second clock cycle after a reset is used to clear the
  136. //reset on the key expander to start the key expansion process
  137. else if (step == 2)
  138. begin
  139. key_reset = 1;
  140. end
  141. //After several clock cycles, the key expansion is done and
  142. //the resulting expanded key is saved
  143. else if (step == (`Nb * (`Nr + 1)) - `Nk + 4)
  144. begin
  145. expandedKey = keyExp_out;
  146. end
  147. //After enough cycles have passed for the expanded key to
  148. //have propagated through to the key selector, and for the
  149. //key selector to have made a selection based on the current
  150. //round (1 cycle each, 2 cycles total), the selected key
  151. //is saved into the current key value
  152. else if (step == (`Nb * (`Nr + 1)) - `Nk + 6)
  153. begin
  154. curKey = selKey;
  155. end
  156. //After the current key value is set and enough time has
  157. //passed for the AddRoundKey module to have updated its
  158. //output with the result of the key operation (2 cycles)
  159. //the XORed data is saved into the current state, and
  160. //the controller sets itself to begin the first round
  161. //of encryption/decryption on the first step
  162. //This XOR is a step that exists outside of the normal
  163. //rounds of operation for Rijndael
  164. else if (step == (`Nb * (`Nr + 1)) - `Nk + 8)
  165. begin
  166. round = 4'h0;
  167. step = 7'h00;
  168. curState = addKeyState;
  169. end
  170. end
  171. //If we are not at the final round or the initialization round,
  172. //then the state is somewhere in one of the encryption/decryption
  173. //rounds, which are handled here
  174. else
  175. begin
  176. //The order of operations for encryption and decryption are
  177. //different in addition to the keys being different
  178. //The first case handles encryption
  179. if (encrypt == 1)
  180. begin
  181. case (step)
  182. //The first step in an encryption round is the Byte Substitution (s-box)
  183. 7'h02 : curState = subState;
  184. //The second step in a round is the Row Shift
  185. 7'h04 : curState = shiftState;
  186. //The third step in a round is the Mix Column Transformation
  187. //This step is not included in the last round of encryption or decryption
  188. 7'h06 : {curState, curKey} = (round != `Nr - 1) ? {mixState, selKey} : {curState, selKey};
  189. //The last step in an encyrption round is the Add Round Key operation
  190. 7'h08 : curState = addKeyState;
  191. default : curState = curState;
  192. endcase
  193. end
  194. //The second case handles the decryption operations
  195. else
  196. begin
  197. case (step)
  198. //The first step in a decryption round is the Row Shift
  199. 7'h02 : curState = shiftState;
  200. //The second step is the Byte Substitution (s-box)
  201. 7'h04 : {curState, curKey} = {subState, selKey};
  202. //The third step is the Add Round Key operation
  203. 7'h06 : curState = addKeyState;
  204. //The last step in decryption is the Mix Columns Transformation
  205. 7'h08 : curState = (round != `Nr - 1) ? mixState : curState;
  206. default : curState = curState;
  207. endcase
  208. end
  209. //At each clock cycle, the step within the current round is incremented
  210. step = step + 7'h01;
  211. //Once all of the steps for a round have been completed, the conroller
  212. //moves on to the next round and resets the current step back to zero
  213. if (step == 7'h09)
  214. begin
  215. round = round + 4'h1;
  216. step = 7'h00;
  217. end
  218. end
  219. end
  220. end
  221.  
  222. endmodule
Parsed in 0.025 seconds, using GeSHi 1.0.7.20