Commit 19223deb by Farnoud Farahmand

first commit

parents
================================================================================
Copyright © 2018-2019 by Cryptographic Engineering Research Group (CERG),
ECE Department, George Mason University
Fairfax, VA, U.S.A.
Author: Farnoud Farahmand
================================================================================
To create a new Vivado project for Software/Hardware co-design platform follow
the following steps:
1. Go to the script directory and run "run_vivado.sh" bash script.
This script runs Vivado in batch mode, creates a project and generates the
Bitstream.
Note: if you would like to see the whole process in the gui mode, you should
uncomment the "start_gui" command in the first line of generate_bitstream.tcl
and remove "-mode batch" in "run_vivado.sh" bash script.
2. When the bitstream generated successfully The Xilinx SDK application should
will opened automatically. In SDK application follow the following steps:
1- go to File -> New -> Application Project
2- in "Project name" enter your desired name and select "Next >"
3- select Empty Application in "Available Templates:" and select "Finish"
4- right click on your project name in "Project Explorer" tab and select
"Generate Linker Script"
5- Increase "Heap Size:" and "Stack Size:" to 10 MB
6- copy all C codes available in c_baremetal directory into the "src"
directory of your project
7- build your project and then right click on your project name and select
Run As -> 1 Launch on Hardware (System Debugger)
Note: To see the output of print functions on Windows machine you can use
SDK Terminal. But, on Linux machines you should use a 3rd party application
like GtkTerm to see serial port output.
If you would like to generate a bitstream for accelerator core other than
NTRUEncrypt RTL polymult, you can open the Vivado project created in
vivado_project/platform_project and replace the polymult IP core with another
accelerator and generate a new bitstream.
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#ifndef CTR
#define CTR 1
#endif
//#define AES128 1
//#define AES192 1
#define AES256 1
#define AES_BLOCKLEN 16 //Block length in bytes AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif
struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif //_AES_H_
#ifndef _DMATRANSFER_H_
#define _DMATRANSFER_H_
#include "xaxidma.h"
//#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
//#include "xtime_l.h"
#include <inttypes.h>
//#include "Output_FIFO.h"
//#include "Add_Constant.h"
#include "Output_FIFO_2clk.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xdebug.h"
#include "xscugic.h"
#include "xtmrctr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#define TMR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
#define INTC_TMR_INTERRUPT_ID XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR
#define MEM_BASE_ADDR XPAR_PS7_RAM_0_S_AXI_BASEADDR
#define ADD_CONST_ID XPAR_ADD_CONSTANT_0_DEVICE_ID
//#define ADD_CONST_BASE_ADDR XPAR_ADD_CONSTANT_0_S00_AXI_BASEADDR
//#define ADD_CONST_OFFSET ADD_CONSTANT_S00_AXI_SLV_REG0_OFFSET
#define OUTPUT_FIFO_ID XPAR_OUTPUT_FIFO_0_DEVICE_ID
#define OUTPUT_FIFO_BASE_ADDR XPAR_OUTPUT_FIFO_2CLK_0_S00_AXI_BASEADDR
#define OUTPUT_FIFO_transfer_length_OFFSET OUTPUT_FIFO_2CLK_S00_AXI_SLV_REG0_OFFSET
#define OUTPUT_FIFO_start_delay_OFFSET OUTPUT_FIFO_2CLK_S00_AXI_SLV_REG1_OFFSET
#define OUTPUT_FIFO_time_out_OFFSET OUTPUT_FIFO_2CLK_S00_AXI_SLV_REG2_OFFSET
#define CLK_WIZ_BASE_ADDR XPAR_CLK_WIZ_0_BASEADDR
#define RX_INTR_ID XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR
#define TX_INTR_ID XPAR_FABRIC_AXI_DMA_0_MM2S_INTROUT_INTR
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
/* Timeout loop counter for reset */
#define RESET_TIMEOUT_COUNTER 10000
#define RUN_DMA 0
#define HW_MULT 0
#define DEBUG_HW 0
#define INIT_TIME 0
#define POLY_MUL_EXE 1
/************************** Variable Definitions *****************************/
typedef u64 dma_t;
static XAxiDma AxiDma; /* Instance of the XAxiDma */
static INTC Intc; /* Instance of the Interrupt Controller */
XScuGic ScuGic;
XTmrCtr TMRInst;
//XGpio Gpio;
XAxiDma_Config *Config;
int Status;
#define CHANNEL 1
#define ALL_OUTPUT 0x0
/*
* Flags interrupt handlers use to notify the application context the events.
*/
volatile int TxDone;
volatile int RxDone;
volatile int Error;
u32 execution_time;
//u32 clk_wiz_status=0;
//u32 clk_wiz_VCO_conf = 0x00000A01;
//u32 clk_wiz_CLK0_conf = 0x00000002;
u32 error_count;
//extern XTime time_array[3][2];
int firstrun;
u32 ARRAY_LENGTH_TX;
u32 ARRAY_LENGTH_RX;
static int DMA_Transfer(dma_t *TxBuffer, u32 ARRAY_LENGTH_TX_in, dma_t *RxBuffer, u32 ARRAY_LENGTH_RX_in);
#ifndef DEBUG
extern void xil_printf(const char *format, ...);
#endif
static void TxIntrHandler(void *Callback);
static void RxIntrHandler(void *Callback);
static int SetupIntrSystem(INTC * IntcInstancePtr,
XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId);
static void DisableIntrSystem(INTC * IntcInstancePtr,
u16 TxIntrId, u16 RxIntrId);
static void DMA_Transfer_init();
#endif /* _DMATRANSFER_H_ */
/*
* NTRUEncrypt.h
*
* Created on: Aug 16, 2017
* Author: zhenfei
*/
#ifndef NTRUENCRYPT_H_
#define NTRUENCRYPT_H_
#include "param.h"
#include "poly.h"
/*
* =======================================
*
* key generation functions
*
* =======================================
*/
/*
* memory requirement: 6 ring elements
*/
void
keygen(
uint16_t *f, /* output secret key f */
uint16_t *g, /* optional output secret key g */
uint16_t *h, /* output public key h */
uint16_t *buf,
const PARAM_SET *param);
/*
* memory requirement: 6 ring elements
*/
void
keygen_KAT(
uint16_t *F, /* output secret key f */
uint16_t *g, /* optional output secret key g */
uint16_t *h, /* output public key h */
uint16_t *buf,
const PARAM_SET *param,
const unsigned char
*randomness);
/*
* memory requirement: 4 ring elements
*/
int check_keys(
const uint16_t *f,
const uint16_t *g,
const uint16_t *h,
uint16_t *buf,
const PARAM_SET *param);
/*
* =======================================
*
* key encapsulation functions
*
* =======================================
*/
/*
* memory requirement: 5 ring elements
*/
int encrypt_kem(
const uint16_t *m, /* input binary message */
const uint16_t *h, /* input public key */
uint16_t *c, /* output ciphertext */
uint16_t *buf,
const PARAM_SET *param);
int encrypt_kem_KAT(
const uint16_t *m, /* input binary message */
const uint16_t *h, /* input public key */
uint16_t *c, /* output ciphertext */
uint16_t *buf,
const PARAM_SET *param,
unsigned char *seed);
void decrypt_kem(
uint16_t *m, /* output binary message */
uint16_t *f, /* input secret key */
uint16_t *cntt, /* input ciphertext */
uint16_t *buf,
PARAM_SET *param);
/*
* =======================================
*
* CCA-2 encryption functions
*
* =======================================
*/
/*
* CCA-2 secure encryption algorithm using NAEP
* memory requirement: 6 ring elements
*/
void
encrypt_cca(
uint16_t *c, /* output ciphertext */
const char *msg, /* input message: a string of chars */
const size_t msg_len,/* input the length of the message */
const uint16_t *h, /* input public key */
uint16_t *buf,
const PARAM_SET *param);
/*
* CCA-2 secure encryption algorithm using NAEP
* memory requirement: 6 ring elements
*/
void
encrypt_cca_KAT(
uint16_t *c, /* output ciphertext */
const char *msg, /* input message: a string of chars */
const size_t msg_len,/* input the length of the message */
const uint16_t *h, /* input public key */
uint16_t *buf,
const PARAM_SET *param,
unsigned char *seed);
/*
* CCA-2 secure encryption algorithm using NAEP
* return the length of the message
* memory requirement: 7 ring elements
*/
int decrypt_cca(
char *msg, /* output message: a string of chars */
const uint16_t *f, /* input public key */
const uint16_t *h, /* input public key */
const uint16_t *c, /* input ciphertext */
uint16_t *buf,
const PARAM_SET *param);
/*
* =======================================
*
* misc functions
*
* =======================================
*/
/*
* check if a message length is valid for ntruencrypt-cca
* then convert the message into a binary polynomial and
* pad the message with a random binary string p
*/
int
pad_msg(
uint16_t *m, /* output message */
const char *msg, /* input message string */
const size_t msg_len,/* input length of the message */
const PARAM_SET *param);
/*
* check if a message length is valid for ntruencrypt-cca
* then convert the message into a binary polynomial and
* pad the message with a random binary string p
*/
int
pad_msg_KAT(
uint16_t *m, /* output message */
const char *msg, /* input message string */
const size_t msg_len,/* input length of the message */
const PARAM_SET *param,
unsigned char *seed);
/*
* converting a binary polynomial into a char string
* return the length of the message string
*/
int
recover_msg(
char *msg, /* output message string */
const uint16_t *m, /* input binary message */
const PARAM_SET *param);
#endif /* NTRUENCRYPT_H_ */
//
// PQCgenKAT_encrypt.c
//
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
// Copyright � 2017 Bassham, Lawrence E (Fed). All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "rng.h"
#include "api.h"
#include <time.h>
#include <stdio.h>
//#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
//#include "xtime_l.h"
#include <inttypes.h>
#include "DMA_Transfer_def.c"
#include "DMA_Transfer_def.h"
int main()
{
Xil_Out32(0xFD6E4000,0x1);
dmb();
unsigned char seed[48];
unsigned char msg[3300];
unsigned char entropy_input[48];
unsigned char *m, *c, *m1;
unsigned long long mlen, clen, mlen1;
unsigned char pk[CRYPTO_PUBLICKEYBYTES], sk[CRYPTO_SECRETKEYBYTES];
int ret_val;
int tx_rx_c;
int transfer_c;
transfer_c = 5;
dma_t* TxBuffer;
TxBuffer = malloc(sizeof(dma_t)*ARRAY_LENGTH_TX);
dma_t* RxBuffer;
RxBuffer = malloc(sizeof(dma_t)*ARRAY_LENGTH_RX);
int i, j;
u32 constant = 0x00000008;
u32 start_delay = 0x00000002;
dma_t input_const_tx = 0xDEADBEEDAA000000;
u32 time_out = 0x80000000;
xil_printf("\r\n--- Entering main() --- \r\n");
/************************** Initialize Global Variables ********************************/
error_count = 0;
firstrun = 1;
TxDone = 0;
RxDone = 0;
Error = 0;
/************************** Initialize AXI_Lite Hardware Modules ***********************/
//ADD_CONSTANT_mWriteReg(ADD_CONST_BASE_ADDR, ADD_CONST_OFFSET, constant);
OUTPUT_FIFO_2CLK_mWriteReg(OUTPUT_FIFO_BASE_ADDR, OUTPUT_FIFO_transfer_length_OFFSET, ARRAY_LENGTH_RX);
OUTPUT_FIFO_2CLK_mWriteReg(OUTPUT_FIFO_BASE_ADDR, OUTPUT_FIFO_start_delay_OFFSET, start_delay);
OUTPUT_FIFO_2CLK_mWriteReg(OUTPUT_FIFO_BASE_ADDR, OUTPUT_FIFO_time_out_OFFSET, time_out);
/************************** Hardware Modules Configuration *****************************/
Config = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!Config) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
/* Initialize Timer */
Status = XTmrCtr_Initialize(&TMRInst, TMR_DEVICE_ID);
if(Status != XST_SUCCESS) return XST_FAILURE;
//DMA_Transfer_init();
xil_printf("Interation, Message length, Key Generation, Encryption, Multiplication (t = r*h), Decryption, Multiplication (e = c*f), Multiplication (t_rec = r*h) \r\n");
for (int i=0; i<48; i++)
//{
entropy_input[i] = i;
//xil_printf("i= %d \r\n", i);}
randombytes_init(entropy_input, NULL, 256);
for (int i=0; i<1; i++) { //3
for (int j=0; j<1; j++) { //25
xil_printf("%d, ", 25*i+j);
randombytes(seed, 48);
mlen = 71; //16+i*8 33
xil_printf("%d, ", (uint32_t)mlen);
randombytes(msg, mlen);
randombytes_init(seed, NULL, 256);
m = (unsigned char *)calloc(mlen, sizeof(unsigned char));
m1 = (unsigned char *)calloc(mlen+CRYPTO_BYTES, sizeof(unsigned char));
c = (unsigned char *)calloc(mlen+CRYPTO_CIPHERTEXTBYTES, sizeof(unsigned char));
memcpy(m, msg, mlen);
// free (TxBuffer);
// free (RxBuffer);
//Start Timer
XTmrCtr_Reset(&TMRInst, 0);
XTmrCtr_Start(&TMRInst, 0);
// Generate the public/private keypair
if ( (ret_val = crypto_encrypt_keypair(pk, sk)) != 0) {
xil_printf("crypto_encrypt_keypair returned <%d>\r\n", ret_val);
cleanup_platform();
return -1;
}
//xil_printf("%d%d, ", upper, lower);
/* Stop Timer */
XTmrCtr_Stop(&TMRInst, 0);
execution_time = XTmrCtr_GetValue(&TMRInst, 0); // Read Timer value
xil_printf("\r\n /-/-/-/-/-/-/-/-/-/-/ KEYPAIR Execution Time = %d /-/-/-/-/-/-/-/-/-/-/\r\n", execution_time);
//Start Timer
XTmrCtr_Reset(&TMRInst, 0);
XTmrCtr_Start(&TMRInst, 0);
// Encryption
if ( (ret_val = crypto_encrypt(c, &clen, m, mlen, pk)) != 0) {
xil_printf("crypto_encrypt returned <%d>\r\n", ret_val);
cleanup_platform();
return -1;
}
/* Stop Timer */
XTmrCtr_Stop(&TMRInst, 0);
execution_time = XTmrCtr_GetValue(&TMRInst, 0); // Read Timer value
xil_printf("\r\n /-/-/-/-/-/-/-/-/-/-/ Encrypt Execution Time = %d /-/-/-/-/-/-/-/-/-/-/\r\n", execution_time);
// Encryption duration
//xil_printf("%d%d, ", upper, lower);
// r*h duration
//xil_printf("%d%d, ", upper, lower);
//Start Timer
XTmrCtr_Reset(&TMRInst, 0);
XTmrCtr_Start(&TMRInst, 0);
// Decryption
if ( (ret_val = crypto_encrypt_open(m1, &mlen1, c, clen, sk)) != 0) {
xil_printf("crypto_encrypt_open returned <%d>\r\n", ret_val);
cleanup_platform();
return -1;
}
/* Stop Timer */
XTmrCtr_Stop(&TMRInst, 0);
execution_time = XTmrCtr_GetValue(&TMRInst, 0); // Read Timer value
xil_printf("\r\n /-/-/-/-/-/-/-/-/-/-/ Decrypt Execution Time = %d /-/-/-/-/-/-/-/-/-/-/\r\n", execution_time);
xil_printf("\r\n\r\n ############################################################################################# \r\n", execution_time);
// Decryption duration
//xil_printf("%d%d, ", upper, lower);
// c*f duration
//upper = (time_array[1][1] - time_array[1][0]) >> 32;
//lower = time_array[1][1] - time_array[1][0];
//xil_printf("%d%d, ", upper, lower);
// r*h
//xil_printf("%d%d \r\n", upper, lower);
if ( mlen != mlen1 ) {
xil_printf("crypto_encrypt_open returned bad 'mlen': Got <%llu>, expected <%llu>\r\n", mlen1, mlen);
cleanup_platform();
return -1;
}
if ( memcmp(m, m1, mlen) ) {
xil_printf("crypto_encrypt_open returned bad 'm' value\r\n");
cleanup_platform();
return -1;
}
free(m);
free(m1);
free(c);
}
}
// xil_printf("finished test: keygen %f cycles; enc %f cycles; dec %f cycles\n",
// (double)total_keygen/CLOCKS_PER_SEC/75,
// (double)total_enc/CLOCKS_PER_SEC/75,
// (double)total_dec/CLOCKS_PER_SEC/75);
//--> Should be moved to the end of main
/* Disable TX and RX Ring interrupts and return success */
DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);
//return XST_SUCCESS;
xil_printf("DONE..... \r\n");
//cleanup_platform();
return 0;
}
Empty application. Add your own sources.
/******************************************************************************
* NTRU Cryptography Reference Source Code submitting to NIST call for
* proposals for post quantum cryptography
*
* This code is written by Zhenfei Zhang @ OnboardSecurity, with additional
* codes from public domain.
*
******************************************************************************/
/*
* api.h
*
* Created on: Aug 29, 2017
* Author: zhenfei
*/
#ifndef API_H_
#define API_H_
//#define TEST_PARAM_SET N