Newer
Older
AESLearning / utility.c
/*
 * 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