/*
* SensorBoard Secure Library
* Subject: Utility Functions Implementation File
* Copyright (C) 2015, T.Kurosawa
*/
#include <string.h>
#include <stdlib.h> // for rand
#include "aes128.h"
#include "utility.h"
#include "md5.h"
#include "driver.h"
// for temporary
static ODAT ret;
static u256 ret256;
KEY_TABLE key_table[15];
const UID uid = { // valid 120-bits
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
} ;
static uint16 error_reg;
/* "FPGA全暗号モジュールのSWリセット・割込み許可指定、及び入力データの全0設定"
in secure-C-lib do nothing */
void sb_b_sw_rst() //{{{1
{
// SOFTRST[15:0] = 13'h0000 -> SOFTRST[15:0] = 13'h0007
// INTENABLE[15:0] = 14'h0003
// RTC start & read once
memset(&ret, 0, sizeof(ODAT));
memset(key_table, 0, sizeof(key_table));
memcpy(&key_table[0].key, uid, sizeof(uid));
// for C-base lib only
error_reg = 0;
return;
}
//}}}
/* "引数SEED(32bit)を乱数シードとしてFPGA/PRNGを起動。CONTROL/PRNG_Kを0
に設定。ブロッキングでは割込み許可、ノンブロッキングでは割込み不許可" */
uint sb_b_start_prng(uint seed) //{{{1
{
// SOFTRST[2] = 1'b0 -> 1'b1 (PRNG RST)
// PRNG_SEED = seed
srand(seed);
// INTENABLE[2] /PRNG = 1'b1
// check CONTROL/PRNG_L == 0 -> write 1
return 10;
}
//}}}
/* "FPGA/PRNGを停止。*/
void sb_nb_stop_prng() //{{{1
{
// SOFTRST[2] = 1'b1;
// INTENABLE_PRNG_INTE = 1'b0;
}//}}}
/* "引数SEED(32bit)を乱数シードとしてFPGA/PRNGの再開
ブロッキングでは割込み許可、ノンブロッキングでは割込み不許可" */
ODAT sb_b_resume_prng(uint32 seed) //{{{1
{
// PRNG_SEED = seed
srand(seed);
// INTENABLE[2] /PRNG = 1'b1
// check CONTROL/PRNG_L == 0 -> write 1
return ret;
}
//}}}
/* FPGA/MD5をリセット後に実行 */
ODAT sb_b_md5(IDAT ival) //{{{1
{
// SOFTRST[1] = 1'b0 -> SOFTRST[1] = 1'b1
drv_reset(DRV_RST_MD5);
return ret;
}
//}}}
#define AES_OUT (void*)0xff000000
/* FPGA/AESをリセット後に実行 */
static u128 buf;
ODAT sb_b_aes_enc(KEY key, IDAT dat) //{{{1
{
// SOFTRST[0] = 1'b1 -> 1'b0
// memcpy(AES_KEY, key, sizeof(KEY));
// while (CONTROL[AES]) ; -> CONTROL[AES] |= 0x01;
//memcpy(AES_DATA, dat, sizeof(IDAT));
drv_reset(DRV_RST_AES);
drv_AES_crypt((uint*)&buf, (uint8*)&key);
memcpy(ret.uc, AES_OUT, sizeof(ODAT));
return ret;
}
//}}}
/* SW実装したAESデコーダを実行 */
ODAT sb_b_aes_dec(KEY key, IDAT dat) //{{{1
{
drv_AES_decrypt((uint*)&dat, (uint8*)&key);
memcpy(ret.uc, dat.ul, 32);
return ret;
}
//}}}
/* FPGA/MD5の出力レジスタMD5_OUTからデータ読出し */
ODAT sb_b_read_md5() //{{{1
{
// memcpy(ret, MD5_OUT, sizeof(ODAT));
return ret;
}
//}}}
/* FPGA/AESの出力レジスタAES_OUTからデータ読出し */
ODAT sb_b_read_aes_enc() //{{{1
{
//memcpy(ret, AES_DATA, sizeof(ODAT));
return ret;
}
//}}}
/* FPGA/PRNGの出力値を一度だけ取得し、下位120bitを返す。常に同じ結果を返す */
u128 sb_b_gen_uid() //{{{1
{
uint32 seed;
// FPGA/PRNG reset
// RTC -> MD5 -> seed
srand(seed);
return ret;
}
//}}}
/* 関数をコールする事で、sb_gen_uidが新たなUIDを1値度だけ生成可能となる */
void sb_b_modify_uid() //{{{1
{
uint8 s[] = "hoge";
md5_context ctx;
unsigned char md5sum[16];
md5_starts( &ctx );
md5_update( &ctx, s,
strlen((char*)s) );
md5_finish( &ctx, md5sum );
}
//}}}
/* FPGA/PRNGの出力値を取得し、それを返す */
IV sb_b_gen_iv() //{{{1
{
return ret;
}
//}}}
// FPGA/PRNGの出力値を一度だけ取得し、それを返す。常に同じ結果を返す
uint sb_b_gen_secret_key() //{{{1
{
return 0;
}
//}}}
// "関数をコールする事で、sb_gen_secret_keyが新たなSECRET_KEYを1値度だけ生成
// 可能となる"
void sb_b_modify_secrete_key(KEY key) //{{{1
{
}
//}}}
// FPGA/PRNGの出力値を取得し、それを返す。
KEY sb_b_gen_key() //{{{1
{
return ret;
}
//}}}
// "KEY_IDとビット列を引数として、指定したビット列に従い、KEY IDに対応するKEY
// FLAGをクリア"
void sb_b_clear_key_flg(KEY_ID kid, uint8 flg) //{{{1
{
// key_table[kid].key_flg = flg;
}
//}}}
// KEY_IDを引数として、KEY_IDに対応するKEY FRAGの値を返す
uint sb_b_read_key_flg(KEY_ID kid) //{{{1
{
return key_table[kid].key_flag;
}
//}}}
// エラーレジスタの値を返す
uint32 sb_b_read_error_reg() //{{{1
{
return error_reg;
}
//}}}
// KEY_IDを引数として、鍵更新回数を表すCOUNTER値を取得し返す
uint sb_b_read_counter(KEY_ID kid) //{{{1
{
return key_table[kid].counter;
}
//}}}
// ユーザ指定の乱数シードをFPGA/PRNGの乱数シードとして設定
ODAT sb_b_set_rand_seed(uint32 seed) //{{{1
{
return ret;
}
//}}}
// 内容
// "h(128bit)とm(256bit)を引数として、mを上位・下位128bitのm1、m0として、
// AES(h,m1) xor AES(0,m0) xor m0 xor m1 を算出し、これを返す
// ※ここで、AES関数は、AES(鍵、平文)の形式"
void sb_b_kdf(KEY key , IDAT dat) //{{{1
{
}
//}}}
// "データ長(64bit)、鍵K(128bit)、データ(128×nbit)を引数として、下記RFCの
// AES-CMAC生成アルゴリズム(概ねAESをCBCモードで実行)を用いてCMAC
// (128bit)を算出し、それを返す
// http://tools.ietf.org/html/rfc4493"
void sb_b_cmac(uint32 len, KEY128 key, IDAT dat) //{{{1
{
}
//}}}
// UID,KEY_ID、AuthKEY_IDを引数として、計算式に従いM1(128bit)を返す
u128 sb_b_create_M1(u128 UID, KEY_ID kid, AUTHKEY_ID auth_kid) //{{{1
{
memcpy(&(key_table[kid].M1.uc), UID.uc, 15);
key_table[kid].M1.uc[15] = ((kid&0xf)<<4)|(auth_kid&0xf);
return key_table[kid].M1;
}
//}}}
// COUNTER、KEY FRAG、KEY(128bit)を引数として、計算式に従いM2(256bit)を返す
u256 sb_b_create_M2(uint32 counter, uint flg, KEY key, KEY_ID kid) //{{{1
{
key_table[kid].M2.ul[0] = ((counter&0xffffff) << 4) | ((flg >> 1) &1) ;
key_table[kid].M2.ul[1] = ((flg&1) << 30) ;
key_table[kid].M2.ul[2] = 0 ;
key_table[kid].M2.ul[3] = 0 ;
memcpy(key_table[kid].M2.ul+4, &key, 16);
return key_table[kid].M2;
}
//}}}
// M1とM2を引数として、計算式に従いM3(128bit)を返す
u128 sb_b_create_M3(u128 m1, u256 m2) //{{{1
{
u128 a= {0};
return a;
}
//}}}
// UID、KEY_ID、AuthKEY_ID、COUNTERを引数として、計算式に従いM4(256bit)を返す
u128 sb_b_create_M4(u128 uid, KEY_ID kid, AUTHKEY_ID akid, uint32 counter) //{{{1
{
return ret;
}
//}}}
// M4を引数として、計算式に従いM5(128bit)を返す
u128 sb_b_create_M5(u128 key, u128 m4) //{{{1
{
return ret;
}
//}}}
// "COUNTER、KEY FRAG、KEY(128bit)を暗号化前のM2形式としたデータ13個から成る
// データを引数として、各データを順次KEY_IDが1~13の鍵格納領域に書込む"
void sb_b_import_plain_key(uint counter, uint flg, KEY key) //{{{1
{
}
//}}}
// "KEY_IDが1~13の鍵格納領域から、COUNTER、KEY FRAG、KEY(128bit)を暗号化
// 前のM2の形式のデータ13個から成るデータを取得し、これを返す"
u256 sb_b_export_plain_key() //{{{1
{
return ret256;
}
//}}}
// "KEY_IDと、COUNTER、KEY FRAG、KEY(128bit)を暗号化前のM2形式としたデータ
// 1個から成るデータを引数として、KEY_IDに対応する鍵格納領域に書込む"
void sb_b_import_each_plain_key(KEY_ID kid, uint32 counter, uint flg, KEY key) //{{{1
{
}
//}}}
// "KEY_IDを引数として、KEY_IDに対応する鍵格納領域から、COUNTER、KEY FRAG、
// KEY(128bit)を暗号化前のM2の形式のデータ13個から成るデータを取得し、これを
// 返す"
u256 sb_b_export_each_plain_key(KEY_ID kid) //{{{1
{
return ret256;
}
//}}}
// "RAM_KEYの鍵格納領域から、COUNTER、KEY FRAG、KEY(128bit)を暗号化前の
// M2の形式のデータを取得し、これを返す"
u256 sb_b_export_plain_ram_key() //{{{1
{
return ret256;
}
//}}}
// vi:expandtab:foldmethod=marker sw=4 ts=4