OpenCores
URL https://opencores.org/ocsvn/gcm-aes/gcm-aes/trunk

Subversion Repositories gcm-aes

[/] [gcm-aes/] [trunk/] [rtl/] [gcm_aes_v0.v] - Rev 2

Compare with Previous | Blame | View Log

/////////////////////////////////////////////////////////////////////
////                                                             ////
////  				GCM-AES Top Module                           ////
////                                                             ////
////                                                             ////
////  Author: Tariq Bashir Ahmad and Guy Hutchison               ////
////          tariq.bashir@gmail.com                             ////
////          ghutchis@gmail.com                                 ////
////                                                             ////
////  Downloaded from: http://www.opencores.org/				  ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Copyright (C) 2010 	 Tariq Bashir Ahmad and 			 ////	
////                         Guy Hutchison						 ////
////                         http://www.ecs.umass.edu/~tbashir   ////
////                                                			 ////
////                                                             ////
//// This source file may be used and distributed without        ////
//// restriction provided that this copyright statement is not   ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
////                                                             ////
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 1ps
 
`define SIZE 128
 
module gcm_aes_v0(
	          input clk,
	          input rst,
 
	          /* DATA Input Interface (dii) */
	          input [`SIZE-1:0] dii_data,
	          input dii_data_vld,
	          input dii_data_type,
	          output reg dii_data_not_ready,
	          input dii_last_word,
                  input [3:0] dii_data_size,
 
	          /* Control Input Interface */
	          input cii_ctl_vld,  			//acts as start signal
	          input cii_IV_vld,
                  input [`SIZE-1:0] cii_K,
 
 
	          /* Data Output Interface */
	          output reg [`SIZE-1:0] Out_data,
	          output reg Out_vld,
                  output reg [3:0] Out_data_size,
                  output reg Out_last_word,
 
	          /* Tag output Interface */
	          output reg  Tag_vld
 
	          );
 
 
 
 
 
  //actual registers
  reg [`SIZE-1:0]             H, nxt_H, EkY0, nxt_EkY0, Yi, Yi_init;
  reg [`SIZE-1:0]             gfm_result;
  reg [63:0]                  enc_byte_cnt, aad_byte_cnt;
 
  reg                         nxt_Out_vld, nxt_Tag_vld;
 
  reg [`SIZE-1:0]             dii_data_star, nxt_Out_data_star;
 
  //wires
  reg [`SIZE-1:0]             nxt_Out_data, nxt_Tag_data;
 
  //aes signals
  reg [`SIZE-1:0]             aes_text_in;
  reg                         aes_kld;
  wire                        aes_done;
  wire [`SIZE-1:0]            aes_text_out;
 
  //control signals
  reg                         mux_aes_text_in_sel, mux_yi_sel;
 
  //gfm signals
  reg  [`SIZE-1:0]             v_in, z_in,b_in, gfm_input1;
  wire [`SIZE-1:0]             z_out, v_out;
  reg [3:0]                    gfm_cnt;
 
  //write enables
  reg                          we_y, we_lenA, we_lenC, start_gfm_cnt;
 
 
  //FSM signals
  reg [9:0]                   state, nxt_state;
 
  parameter          IDLE          = 10'd1,
                     ENCRYPT_0     = 10'd2,
                     INIT_COUNTER  = 10'd4,
                     ENCRYPT_Y0    = 10'd8,
                     DATA_ACCEPT   = 10'd16,
                     GFM_MULT      = 10'd32,
                     INC_COUNTER   = 10'd64,
                     M_ENCRYPT     = 10'd128,
                     PRE_TAG_CALC  = 10'd256,
                     TAG_CALC      = 10'd512;
 
 
 
 
 
 
 
  always @*
    begin
      dii_data_star = 0;
      case(dii_data_size)
        0:  // 1 valid byte
          begin
            dii_data_star = ({dii_data[7:0],120'b0});
          end
        1: //2 valid bytes
          begin
            dii_data_star = {dii_data[15:0],112'b0};
          end
        2: //3 valid bytes
          begin
            dii_data_star = {dii_data[23:0],104'b0};
          end
        3: //4 valid bytes
          begin
            dii_data_star = {dii_data[31:0],96'b0};
          end
        4: //5 valid bytes
          begin
            dii_data_star = {dii_data[39:0],88'b0};
          end
        5: //6 valid bytes
          begin
            dii_data_star = {dii_data[47:0],80'b0};
          end
        6: //7 valid bytes
          begin
            dii_data_star = {dii_data[55:0],72'b0};
          end
        7: //8 valid bytes
          begin
            dii_data_star = {dii_data[63:0],64'b0};
          end
        8:
          begin
            dii_data_star = {dii_data[71:0],56'b0};
          end
        9:
          begin
            dii_data_star = {dii_data[79:0],48'b0};
          end
        10:
          begin
            dii_data_star = {dii_data[87:0],40'b0};
          end
        11:
          begin
            dii_data_star = {dii_data[95:0],32'b0};
          end
        12:
          begin
            dii_data_star = {dii_data[103:0],24'b0};
          end
        13:	//14 valid bytes
          begin
	    dii_data_star = ({dii_data[111:0],16'b0});
          end
        14: //15 valid bytes
          begin
            dii_data_star = {dii_data[119:0],8'b0};
          end
      endcase
 
    end
 
  always @*
    begin
      nxt_Out_data_star = 0;
      case(dii_data_size)
        0:  //1 valid byte
          begin
            nxt_Out_data_star = {nxt_Out_data[127:120],120'b0};
          end
        1:// 2 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:112],112'b0};
          end
        2:// 3 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:104],104'b0};
          end
        3:// 4 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:96],96'b0};
          end
        4:// 5 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:88],88'b0};
          end
        5:// 6 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:80],80'b0};
          end
        6:// 7 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:72],72'b0};
          end
        7:// 8 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:64],64'b0};
          end
        8:// 9 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:56],56'b0};
          end
        9:// 10 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:48],48'b0};
          end
        10:// 11 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:40],40'b0};
          end
        11:  // 12 valid byte
          begin
            nxt_Out_data_star = {nxt_Out_data[127:32],32'b0};
          end
        12:// 13 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:24],24'b0};
          end
        13:// 14 valid bytes
          begin
            nxt_Out_data_star = {nxt_Out_data[127:16],16'b0};
          end
        14:  // 15 valid byte
          begin
            nxt_Out_data_star = {nxt_Out_data[127:8],8'b0};
          end
 
      endcase // case (dii_data_size)
    end
 
 
  always @(posedge clk or posedge rst)
    if(rst)
      begin
        state  <= #1 IDLE;
        H       <= #1 0;
        EkY0    <= #1 0;
      end
    else
      begin
        H     <= #1 nxt_H;
        EkY0  <= #1 nxt_EkY0;
        state <= #1 nxt_state;
      end
 
 
  //out data
   always @(posedge clk)
    begin
      if(nxt_Out_vld & ~nxt_Tag_vld)
        begin
          Out_data 		<= #1 nxt_Out_data;
          Out_data_size <= #1 dii_data_size;
          Out_last_word <= #1 dii_last_word;
        end
      else if(nxt_Tag_vld)
	Out_data <= #1 nxt_Tag_data;
 
      Tag_vld <= #1 nxt_Tag_vld;
      Out_vld <= #1 nxt_Out_vld;
   end
 
 /* always @(posedge clk)
    begin
      if(nxt_Out_vld)
        begin
          Out_data <= #1 nxt_Out_data;
          Out_data_size <= #1 dii_data_size;
          Out_last_word    <= #1 dii_last_word;
        end
      Out_vld <= #1 nxt_Out_vld;
 
    end
 
 
  always @(posedge clk)
    begin
      if(nxt_Tag_vld)
        Out_data <= #1 nxt_Tag_data;
 
      Tag_vld <= #1 nxt_Tag_vld;
    end
  */
 
 //aes text_in
  always @*
    begin
      aes_text_in = 0;
      case(mux_aes_text_in_sel)
        0: aes_text_in = 0;
 
        1: aes_text_in = Yi;
 
      endcase
    end
 
 
  //initializing Yi_init
  always @*
    begin
      Yi_init = 0;
      if(cii_IV_vld)
        begin
          Yi_init = dii_data;
        end
    end
 
 
  //FSM
  always @*
    begin
      //list of defaults
      nxt_state = state;
      we_y = 0;
      we_lenA = 0;
      we_lenC = 0;
      dii_data_not_ready = 1;
      aes_kld = 0;
      mux_aes_text_in_sel = 0;
      mux_yi_sel = 0;
      start_gfm_cnt = 0;
      nxt_H = H;
      nxt_EkY0 = EkY0;
      nxt_Out_vld           = 0;			
      nxt_Tag_vld           = 0;
      gfm_input1 = 0;
      nxt_Out_data = 0;
      nxt_Tag_data = 0;
 
      case(state)
        IDLE:
          begin
        //  $display($time,": In IDLE\n");
            if(cii_ctl_vld)
              begin
                aes_kld = 1;
                mux_aes_text_in_sel = 0;
                nxt_state = ENCRYPT_0;
              end
          end
 
        ENCRYPT_0:
          begin
            if(aes_done)
              begin
                nxt_H = aes_text_out;
                if(cii_IV_vld)
                  begin
                    we_y = 1;
                    nxt_state = INIT_COUNTER;
                  end
              end
          end // case: ENCRYPT_0
 
        INIT_COUNTER:
          begin
			   // figure out how to launch a GCM op here,
				// or go to next state which launches GCM op
            mux_aes_text_in_sel = 1;
            aes_kld = 1;
            nxt_state = ENCRYPT_Y0;
          end
 
 
        ENCRYPT_Y0:
          begin
            if(aes_done)
              begin
                nxt_EkY0 = aes_text_out;
                nxt_state = DATA_ACCEPT;
              end
          end
 
        DATA_ACCEPT:
          begin
            dii_data_not_ready = 0;
            if(dii_data_vld & dii_data_type)   //AAD
              begin
                if(dii_data_size == 4'd15)
                  begin
                    we_lenA      = 1;
                    gfm_input1    = dii_data;
                    start_gfm_cnt = 1;
                    nxt_state     = GFM_MULT;
                  end
                else
                  begin
                    we_lenA      = 1;
                    gfm_input1    = dii_data_star; //note star
                    start_gfm_cnt = 1;
                    nxt_state     = GFM_MULT;
                  end
              end
            else if(dii_data_vld & ~dii_data_type) //ENC
              begin
                mux_yi_sel = 1;
                we_y = 1;
                nxt_state = INC_COUNTER;
              end
          end // case: AAD_ACCEPT
 
        INC_COUNTER:
          begin
            we_lenC = 1;
            mux_aes_text_in_sel = 1;
            aes_kld = 1;
            nxt_state = M_ENCRYPT;
          end
 
        GFM_MULT:
          begin
            if(gfm_cnt == 4'd7)
              begin
                start_gfm_cnt = 0;
                if(~dii_last_word)
                  nxt_state = DATA_ACCEPT;
                else
                  nxt_state = PRE_TAG_CALC;
              end
          end
 
        M_ENCRYPT:
          begin
            if(aes_done)
              begin
                if(dii_data_size == 4'd15)
                  begin
                    nxt_Out_data = aes_text_out ^ dii_data;
                    nxt_Out_vld  = 1;
                    gfm_input1 = nxt_Out_data;
                  end
                else
                  begin
                    nxt_Out_data = aes_text_out ^ dii_data_star;
                    nxt_Out_vld  = 1;
                    gfm_input1 = nxt_Out_data_star;
                  end
                start_gfm_cnt = 1;
                nxt_state = GFM_MULT;
              end
          end // case: M_ACCEPT
 
        PRE_TAG_CALC:
          begin
            gfm_input1 = {(aad_byte_cnt << 3),(enc_byte_cnt << 3)};
            start_gfm_cnt = 1;
            nxt_state = TAG_CALC;
          end
 
        TAG_CALC:
          begin
            if(gfm_cnt == 4'd7)
              begin
                start_gfm_cnt = 0;
                nxt_Tag_data = EkY0 ^ z_out;
                nxt_Tag_vld  = 1'b1;
                nxt_state = IDLE;
              end
          end
 
      endcase
 
    end
 
 
 
 
 
  always @(posedge clk)
    if(we_y)
      case(mux_yi_sel)
        0: Yi <= #1 Yi_init;
        1: Yi <= #1 Yi + 1;
      endcase 
 
  always @(posedge clk or posedge rst)
    if(rst)
      enc_byte_cnt <= #1 0;
    else if(we_lenC)
      enc_byte_cnt <= #1 enc_byte_cnt + dii_data_size + 1;
 
  always @(posedge clk or posedge rst)
    if(rst)
      aad_byte_cnt <= #1 0;
    else if(we_lenA)
      aad_byte_cnt <= #1 aad_byte_cnt + dii_data_size + 1;
 
  always @(posedge clk)
    if(start_gfm_cnt)
      gfm_cnt <= #1 4'd0;
    else if(gfm_cnt != 4'd7)
      gfm_cnt <= #1 gfm_cnt + 1;
 
 
  always @(posedge clk)
    if(cii_ctl_vld)
      gfm_result <= #1 0;
    else if(gfm_cnt == 4'd7)
      gfm_result <= #1 z_out;
 
 
 
  always @(posedge clk)
    if(start_gfm_cnt)
      begin
        v_in     <= #1 H; 
        z_in     <= #1 {`SIZE{1'b0}};
        b_in     <= #1 gfm_input1 ^ gfm_result;
      end
 
    else
      begin
        v_in <= #1 v_out;
        z_in <= #1 z_out;
        b_in <= #1 b_in << 16;
      end
 
 
 
 
   /*
    gfm128_16 AUTO_TEMPLATE
    (
    .v_out             (v_out[127:0]),
    .z_out             (z_out[127:0]),
    .v_in              (v_in[127:0]),
    .z_in              (z_in[127:0]),
    .b_in              (b_in[127:112]),
    );
    */
 
 
  gfm128_16      GFM(/*AUTOINST*/
                     // Outputs
                     .v_out             (v_out[127:0]),          // Templated
                     .z_out             (z_out[127:0]),          // Templated
                     // Inputs
                     .v_in              (v_in[127:0]),           // Templated
                     .z_in              (z_in[127:0]),           // Templated
                     .b_in              (b_in[127:112]));         // Templated
 
 
   /*
    aes_cipher_top AUTO_TEMPLATE
    (
    .done                (aes_done),
    .text_out            (aes_text_out[127:0]),
    .clk                 (clk),
    .rst                 (rst),
    .ld                  (aes_kld),
    .key                 (cii_K),
    .text_in             (aes_text_in[127:0]),
    );
    */
 
  aes_cipher_top  AES_ENC (/*AUTOINST*/
                           // Outputs
                           .done                (aes_done),      // Templated
                           .text_out            (aes_text_out[127:0]), // Templated
                           // Inputs
                           .clk                 (clk),           // Templated
                           .rst                 (rst),           // Templated
                           .ld                  (aes_kld),       // Templated
                           .key                 (cii_K),         // Templated
                           .text_in             (aes_text_in[127:0])); // Templated
 
 
 
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.