📄 aes.c
字号:
memcpy (state, newstate, sizeof(newstate));
}
// restore and un-mix each row in a column
void InvMixSubColumns (uchar *state)
{
uchar newstate[4 * Nb];
int i;
// restore column 0
newstate[0] = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]];
newstate[5] = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]];
newstate[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]];
newstate[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]];
// restore column 1
newstate[4] = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]];
newstate[9] = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]];
newstate[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]];
newstate[3] = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]];
// restore column 2
newstate[8] = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]];
newstate[13] = Xtime9[state[8]] ^ XtimeE[state[9]] ^ XtimeB[state[10]] ^ XtimeD[state[11]];
newstate[2] = XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^ XtimeB[state[11]];
newstate[7] = XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^ XtimeE[state[11]];
// restore column 3
newstate[12] = XtimeE[state[12]] ^ XtimeB[state[13]] ^ XtimeD[state[14]] ^ Xtime9[state[15]];
newstate[1] = Xtime9[state[12]] ^ XtimeE[state[13]] ^ XtimeB[state[14]] ^ XtimeD[state[15]];
newstate[6] = XtimeD[state[12]] ^ Xtime9[state[13]] ^ XtimeE[state[14]] ^ XtimeB[state[15]];
newstate[11] = XtimeB[state[12]] ^ XtimeD[state[13]] ^ Xtime9[state[14]] ^ XtimeE[state[15]];
for( i=0; i < 4 * Nb; i++ )
state[i] = InvSbox[newstate[i]];
}
// encrypt/decrypt columns of the key
// n.b. you can replace this with
// byte-wise xor if you wish.
void AddRoundKey (unsigned *state, unsigned *key)
{
int idx;
for( idx = 0; idx < 4; idx++ )
state[idx] ^= key[idx];
}
uchar Rcon[11] = {
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
// produce Nk bytes for each round
void ExpandKey (uchar *key, uchar *expkey)
{
uchar tmp0, tmp1, tmp2, tmp3, tmp4;
unsigned idx;
for( idx = 0; idx < Nk; idx++ ) {
expkey[4*idx+0] = key[4 * idx + 0];
expkey[4*idx+1] = key[4 * idx + 1];
expkey[4*idx+2] = key[4 * idx + 2];
expkey[4*idx+3] = key[4 * idx + 3];
}
for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
tmp0 = expkey[4*idx - 4];
tmp1 = expkey[4*idx - 3];
tmp2 = expkey[4*idx - 2];
tmp3 = expkey[4*idx - 1];
if( !(idx % Nk) ) {
tmp4 = tmp3;
tmp3 = Sbox[tmp0];
tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk];
tmp1 = Sbox[tmp2];
tmp2 = Sbox[tmp4];
}
// convert from longs to bytes
expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0;
expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1;
expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2;
expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3;
}
}
// encrypt one 128 bit block
void Encrypt (uchar *in, uchar *expkey, uchar *out)
{
unsigned round, idx, j;
uchar state[Nb * 4];
for( idx = 0; idx < 4; idx++ ) {
state[4*idx+0] = *in++;
state[4*idx+1] = *in++;
state[4*idx+2] = *in++;
state[4*idx+3] = *in++;
}
// for( idx = 2; idx < Nb; idx++ ) {
// state[4*idx+0] = '\0';
// state[4*idx+1] = '\0';
// state[4*idx+2] = '\0';
// state[4*idx+3] = '\0';
// }
AddRoundKey ((unsigned *)state, (unsigned *)expkey);
for( round = 1; round < Nr + 1; round++ ) {
if( round < Nr )
MixSubColumns (state);
else
ShiftRows (state);
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
}
for( idx = 0; idx < Nb; idx++ ) {
*out++ = state[4*idx+0];
*out++ = state[4*idx+1];
*out++ = state[4*idx+2];
*out++ = state[4*idx+3];
}
}
uint32_t gen_hotp_from_aes(uint8_t secret[], uint8_t salt[]) {
int i;
uint8_t text[8];
uint8_t hash[20];
uint32_t binary, otp;
int offset,base;
// for (i = 7; i >= 0; i--) {
// text[i] = (uint8_t) (moving_factor & 0xff);
// moving_factor >>= 8;
// }
Encrypt(salt, secret, hash);
otp = 0;
base = 1;
for (i=0; i<6; ++i ){
otp += (uint32_t)( ( ( hash[i]&0xff ) %10)*base ) ;
base *= 10;
}
// offset = hash[15] & 0x0f;
// binary = (((uint32_t) hash[offset] & 0x7f) << 24)
// | (((uint32_t) hash[offset + 1] & 0xff) << 16)
// | (((uint32_t) hash[offset + 2] & 0xff) << 8)
// | (((uint32_t) hash[offset + 3] & 0xff));
// otp = binary % 1000000;
return otp;
/* printf("%ld ", otp); */
}
int otp_auth_general_aes(ntoken_context_t *ctx, uint8_t *secret, int secret_len,
uint64_t server_time, uint64_t otp, uint8_t *meta_inout, int *metalen_inout) {
token_meta_t meta;
int window;
uint64_t base_counter, from, to, c;
struct tm *tm_tmp;
uint8_t salt[16];
int success = 0;
time_t time_t_tmp;
if (unmarshall_meta(&meta, meta_inout, metalen_inout))
return NTOKEN_CORRUPTED_DATA;
window = predictWindowSize(server_time, &meta);
base_counter = server_time/GENERAL_SHA1_COUNTER_INTERVAL + meta.last_drift_counter;
from = base_counter - window;
to = base_counter + (uint32_t)(window * 1.5); /* "*1.5" because the clock on our token tends to run faster */
/* Start the authentication from "from" or 1 larger than last verified
* counter step, whichever is larger */
c = from > meta.last_verify_counter ? from : (meta.last_verify_counter+1);
DEBUG(1, "Testing against otp=%lld from step %lld to %lld (window=%d)\n", otp, c, to, window);
while (c <= to) {
time_t_tmp = c*60;
tm_tmp = localtime(&time_t_tmp);
memset( salt,0,16 );
memcpy( salt+10,&ctx->serial,6 );
salt[9] = 0x00;
salt[8] = 0x20;
salt[7] = int2bcd((uint8_t)(tm_tmp->tm_year%100));
salt[6] = int2bcd((uint8_t)(tm_tmp->tm_mon+1));
salt[5] = int2bcd((uint8_t)(tm_tmp->tm_mday));
salt[4] = int2bcd((uint8_t)(tm_tmp->tm_hour));
salt[3] = int2bcd((uint8_t)(tm_tmp->tm_min));
DEBUG(2, "%llx\n", salt);
int test_otp = gen_hotp_from_aes(secret, salt);
DEBUG(2, "Step %lld: %d\n", c, test_otp);
if (otp == test_otp) {
meta.last_verify_time = server_time;
meta.last_verify_counter = c;
meta.last_drift_counter = c - server_time/GENERAL_SHA1_COUNTER_INTERVAL;
success = 1;
break;
}
c++;
}
if (!success) {
DEBUG(1, "None matches. Authentication failure.\n");
return NTOKEN_AUTH_FAILURE;
}
DEBUG(1, "Authentication succeeded at step %lld. New drift=%lld.\n", c, meta.last_drift_counter);
marshall_meta(&meta, meta_inout, metalen_inout);
return NTOKEN_SUCCESS;
}
void Decrypt (uchar *in, uchar *expkey, uchar *out)
{
unsigned idx, round, j;
uchar state[Nb * 4];
for( idx = 0; idx < Nb; idx++ ) {
state[4*idx+0] = *in++;
state[4*idx+1] = *in++;
state[4*idx+2] = *in++;
state[4*idx+3] = *in++;
}
AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb);
round = Nr;
InvShiftRows(state);
while( round-- )
{
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
if( round )
InvMixSubColumns (state);
}
for( idx = 0; idx < Nb; idx++ ) {
*out++ = state[4*idx+0];
*out++ = state[4*idx+1];
*out++ = state[4*idx+2];
*out++ = state[4*idx+3];
}
}
#include <stdio.h>
#include <fcntl.h>
extern int _setmode (int, int);
uchar in[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
uchar key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
uchar out[16];
#ifndef unix
void rd_clock (__int64 *ans)
{
unsigned dwLow, dwHigh;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -