aboutsummaryrefslogblamecommitdiff
path: root/sw/modexp_tester.c
blob: 21bebbdb255b591e877a59dfb0baa9104e08bf80 (plain) (tree)














































                                                                           









                                                                    





                                         



























































                                                                      
 




                                             
                                                   






                                             
                                                        
















                                                                    
 




                                              
                                                   

























                                                                    
 




                                             
                                                   
















                                                                    
               
  
                          
                                                                    
                        
 



                                              
 




                                             
 
                                              
                                              
                                              

 





                                                                    
























                                                                     























                                                                    
                                             


                                          
                                              


                                             
                                             







                                            
                                            




                                                                    






















                                                                    
 



                                              
 




                                             





                                                             
                                      





















                                                                    

               





                                                        
 


                                              
 


                                             
 


                                           

                                      












                                                                    





                                         


                                                                    
                            
 
                                                                                                                 





                                               
 



                                              
 



                                             
 


                                           

                                      





                                                         
                                                                       




                                                                    
         
                                                                    
              

                        





                         

        
        
        




                                                                        
                      
                                                                        
//======================================================================
//
// modexp_tester.c
// ---------------
// Simple test sw for the modexp.
//
//
// Author: Joachim Strombergson, Rob Austein,
// Copyright (c) 2014-2015, NORDUnet A/S All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// - Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
//
// - Neither the name of the NORDUnet nor the names of its contributors may
//   be used to endorse or promote products derived from this software
//   without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER 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.
//
//
//======================================================================

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "cryptech.h"

//------------------------------------------------------------------
// Global defines.
//------------------------------------------------------------------
#define VERBOSE 0
#define CHECK_WRITE 0


//------------------------------------------------------------------
// Robs macros. Scary scary.
//------------------------------------------------------------------
#define check(_expr_)			\
  do {					\
    if ((_expr_) != 0) {		\
      printf("%s failed\n", #_expr_);	\
      exit(1);				\
    }					\
  } while (0)


//------------------------------------------------------------------
// tc_w32()
//
// Write 32-bit word to given address.
//------------------------------------------------------------------
static void tc_w32(const off_t addr, const uint32_t data)
{
  uint8_t w[4];
  w[0] = data >> 24 & 0xff;
  w[1] = data >> 16 & 0xff;
  w[2] = data >> 8  & 0xff;
  w[3] = data       & 0xff;
  check(tc_write(addr, w, 4));
}


//------------------------------------------------------------------
// tc_r32
//
// Read 32-bit word from given address.
//------------------------------------------------------------------
static uint32_t tc_r32(const off_t addr)
{
  uint8_t w[4];
  check(tc_read(addr, w, 4));
  return (uint32_t)((w[0] << 24) + (w[1] << 16) + (w[2] << 8) + w[3]);
}


//------------------------------------------------------------------
// check_modexp_access
//
// Check that we can read from the modexp core by trying to
// read out the name and version.
//------------------------------------------------------------------
static void check_modexp_access(void)
{
  uint8_t name0[4], name1[4], version[4];

  printf("Trying to read the modexp core name\n");

  check(tc_read(MODEXP_ADDR_NAME0,   name0,    sizeof(name0)));
  check(tc_read(MODEXP_ADDR_NAME1,   name1,    sizeof(name1)));
  check(tc_read(MODEXP_ADDR_VERSION, version, sizeof(version)));
  printf("%4.4s%4.4s %4.4s\n\n", name0, name1, version);
}


//------------------------------------------------------------------
// check_modulus_mem()
//
// Check that we can write and read to the modulus memory.
//------------------------------------------------------------------
static void check_modulus_mem(void)
{
  uint8_t i;
  uint32_t j;

  printf("Testing modulus mem access.\n");

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  // Write test data to modulus mempory.
  for (i = 0 ; i < 64; i = i + 1) {
    j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
      ((i * 4 + 1) << 8) + i * 4;
    tc_w32(MODEXP_MODULUS_DATA, j);
  }

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  // Read out test data from modulus mempory.
  for (i = 0 ; i < 64 ; i = i + 4) {
    printf("modulus mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
	   tc_r32(MODEXP_MODULUS_DATA),
	   tc_r32(MODEXP_MODULUS_DATA),
	   tc_r32(MODEXP_MODULUS_DATA),
	   tc_r32(MODEXP_MODULUS_DATA));
  }
}


//------------------------------------------------------------------
// check_exponent_mem()
//
// Check that we can write and read to the exponent memory.
//------------------------------------------------------------------
static void check_exponent_mem(void)
{
  uint8_t i;
  uint32_t j;

  printf("Testing exponent mem access.\n");

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  // Write test data to exponent memory.
  for (i = 0 ; i < 64; i = i + 1) {
    j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
      ((i * 4 + 1) << 8) + i * 4;
    tc_w32(MODEXP_EXPONENT_DATA, j);
  }

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  // Read out test data from exponent memory.
  for (i = 0 ; i < 64 ; i = i + 4) {
    printf("exponent mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
	   tc_r32(MODEXP_EXPONENT_DATA),
	   tc_r32(MODEXP_EXPONENT_DATA),
	   tc_r32(MODEXP_EXPONENT_DATA),
	   tc_r32(MODEXP_EXPONENT_DATA));
  }
}



//------------------------------------------------------------------
// check_message_mem()
//
// Check that we can write and read to the message memory.
//------------------------------------------------------------------
static void check_message_mem(void)
{
  uint8_t i;
  uint32_t j;

  printf("Testing message mem access.\n");

  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  // Write test data to message memory.
  for (i = 0 ; i < 64; i = i + 1) {
    j = ((i * 4 + 3) << 24) + ((i * 4 + 2) << 16) +
      ((i * 4 + 1) << 8) + i * 4;
    tc_w32(MODEXP_MESSAGE_DATA, j);
  }

  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  // Read out test data from messsage memory.
  for (i = 0 ; i < 64 ; i = i + 4) {
    printf("message mem: 0x%08x 0x%08x 0x%08x 0x%08x\n",
	   tc_r32(MODEXP_MESSAGE_DATA),
	   tc_r32(MODEXP_MESSAGE_DATA),
	   tc_r32(MODEXP_MESSAGE_DATA),
	   tc_r32(MODEXP_MESSAGE_DATA));
  }
}


//------------------------------------------------------------------
// clear_mems()
//
// Zero fill the memories.
//------------------------------------------------------------------
static void clear_mems()
{
  uint32_t i;
  tc_w32(MODEXP_MESSAGE_PTR_RST,  0x00000000);
  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_PTR_RST,  0x00000000);

  for (i = 0 ; i < 256 ; i++) {
    tc_w32(MODEXP_MESSAGE_DATA,  0x00000000);
    tc_w32(MODEXP_EXPONENT_DATA, 0x00000000);
    tc_w32(MODEXP_MODULUS_DATA,  0x00000000);
  }

  tc_w32(MODEXP_MESSAGE_PTR_RST,  0x00000000);
  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_PTR_RST,  0x00000000);
}


//------------------------------------------------------------------
// dump_mems()
//
// Dump the first words from the memories.
//------------------------------------------------------------------
static void dump_mems()
{
  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  printf("First words in messagee mem:\n");
  printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
	 tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA),
	 tc_r32(MODEXP_MESSAGE_DATA), tc_r32(MODEXP_MESSAGE_DATA));

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  printf("First words in exponent mem:\n");
  printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
	 tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA),
	 tc_r32(MODEXP_EXPONENT_DATA), tc_r32(MODEXP_EXPONENT_DATA));

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  printf("First words in modulus mem:\n");
  printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
	 tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA),
	 tc_r32(MODEXP_MODULUS_DATA), tc_r32(MODEXP_MODULUS_DATA));

  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
  printf("First words in result mem:\n");
  printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
	 tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA),
	 tc_r32(MODEXP_RESULT_DATA), tc_r32(MODEXP_RESULT_DATA));

  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
}


//------------------------------------------------------------------
// tc1()
//
// c = m ** e % N with the following (decimal) test values:
//  m = 3
//  e = 7
//  n = 11 (0x0b)
//  c = 3 ** 7 % 11 = 9
//------------------------------------------------------------------
static void tc1()
{
  uint32_t result;

  printf("Running TC1: 0x03 ** 0x07 mod 0x0b = 0x09\n");

  // Write operands and set associated lengths.
  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MESSAGE_DATA, 0x00000003);
  tc_w32(MODEXP_LENGTH, 0x00000001);

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_EXPONENT_DATA, 0x00000007);
  tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001);

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_DATA, 0x0000000b);
  tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001);

  // Start processing and wait for ready.
  tc_w32(MODEXP_ADDR_CTRL, 0x00000001);
  check(tc_wait_ready(MODEXP_ADDR_STATUS));

  // Check result with expected value.
  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
  result = tc_r32(MODEXP_RESULT_DATA);
  if (result == 0x00000009)
    printf("TC1: OK\n");
  else
    printf("TC1: Error. Expected 0x00000009, got 0x%08x\n", result);
}


//------------------------------------------------------------------
// tc2()
//
// c = m ** e % N with the following test values:
//  m = 251 (0xfb)
//  e = 251 (0xfb)
//  n = 257 (0x101)
//  c = 251 ** 251 % 257 = 183 (0xb7)
//------------------------------------------------------------------
static void tc2()
{
  uint32_t result;

  printf("Running TC2: 0xfb ** 0xfb mod 0x101 = 0xb7\n");

  // Write operands and set associated lengths.
  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MESSAGE_DATA, 0x000000fb);
  tc_w32(MODEXP_MESSAGE_DATA, 0x00000000);
  tc_w32(MODEXP_LENGTH, 0x00000001);

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_EXPONENT_DATA, 0x000000fb);
  tc_w32(MODEXP_EXPONENT_DATA, 0x00000000);
  tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001);

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_DATA, 0x00000101);
  tc_w32(MODEXP_MODULUS_DATA, 0x00000000);
  tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001);

  // Start processing and wait for ready.
  printf("TC2: Starting processing. Waiting for ready...\n");
  tc_w32(MODEXP_ADDR_CTRL, 0x00000001);
  check(tc_wait_ready(MODEXP_ADDR_STATUS));
  printf("TC2: Ready seen.\n");

  // Check result with expected value.
  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
  result = tc_r32(MODEXP_RESULT_DATA);
  if (result == 0x000000b7)
    printf("TC2: OK\n");
  else
    printf("TC2: Error. Expected 0x000000b7, got 0x%08x\n", result);
}


//------------------------------------------------------------------
// tc3()
//
// c = m ** e % N with the following test values:
//  m = 0x81
//  e = 0x41
//  n = 0x87
//  c = 0x81 ** 0x41 % 0x87 = 0x36
//------------------------------------------------------------------
static void tc3()
{
  uint32_t result;

  clear_mems();

  printf("Running TC3: 0x81 ** 0x41 mod 0x87 = 0x36\n");

  // Write operands and set associated lengths.
  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MESSAGE_DATA, 0x00000081);
  tc_w32(MODEXP_LENGTH, 0x00000001);

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_EXPONENT_DATA, 0x00000041);
  tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000001);

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_DATA, 0x00000087);
  tc_w32(MODEXP_MODULUS_LENGTH, 0x00000001);

  // Start processing and wait for ready.
  tc_w32(MODEXP_ADDR_CTRL, 0x00000001);
  check(tc_wait_ready(MODEXP_ADDR_STATUS));

  // Check result with expected value.
  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
  result = tc_r32(MODEXP_RESULT_DATA);
  if (result == 0x00000036)
    printf("TC3: OK\n");
  else
    printf("TC3: Error. Expected 0x00000036, got 0x%08x\n", result);
}


//------------------------------------------------------------------
// tc4()
//
// c = m ** e % N with the following test values:
//  m = 0x00000001946473e1
//  e = 0xh000000010e85e74f
//  n = 0x0000000170754797
//  c = 0x000000007761ed4f
//
// These operands spans two 32-bit words.
//------------------------------------------------------------------
static void tc4()
{
  uint32_t result0, result1;

  printf("Running TC4: 0x00000001946473e1 ** 0xh000000010e85e74f mod 0x0000000170754797 = 0x000000007761ed4f\n");

  // Write operands and set associated lengths.
  tc_w32(MODEXP_MESSAGE_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MESSAGE_DATA, 0x00000001);
  tc_w32(MODEXP_MESSAGE_DATA, 0x946473e1);
  tc_w32(MODEXP_LENGTH, 0x00000002);

  tc_w32(MODEXP_EXPONENT_PTR_RST, 0x00000000);
  tc_w32(MODEXP_EXPONENT_DATA, 0x00000001);
  tc_w32(MODEXP_EXPONENT_DATA, 0x0e85e74f);
  tc_w32(MODEXP_EXPONENT_LENGTH, 0x00000002);

  tc_w32(MODEXP_MODULUS_PTR_RST, 0x00000000);
  tc_w32(MODEXP_MODULUS_DATA, 0x00000001);
  tc_w32(MODEXP_MODULUS_DATA, 0x70754797);
  tc_w32(MODEXP_MODULUS_LENGTH, 0x00000002);

  // Start processing and wait for ready.
  tc_w32(MODEXP_ADDR_CTRL, 0x00000001);
  check(tc_wait_ready(MODEXP_ADDR_STATUS));

  // Check result with expected value.
  tc_w32(MODEXP_RESULT_PTR_RST, 0x00000000);
  result0 = tc_r32(MODEXP_RESULT_DATA);
  result1 = tc_r32(MODEXP_RESULT_DATA);
  if ((result0 == 0x00000000) && (result1 == 0x7761ed4f))
    printf("TC4: OK\n");
  else
    printf("TC4: Error. Expected 0x000000007761ed4f, got 0x%08x%08x\n",
	   result0, result1);
}


//------------------------------------------------------------------
// main()
//------------------------------------------------------------------
int main(void)
{
  check_modexp_access();
  tc_set_debug(1);

//  check_modulus_mem();
//  check_exponent_mem();
//  check_message_mem();

  tc1();
  tc2();
  tc3();
  tc4();

  return 0;
}

//======================================================================
// EOF modexp_tester.c
//======================================================================