LINUX.ORG.RU

История изменений

Исправление ncrmnt, (текущая версия) :

Это что-то новое. Последняя реализация, которую я имплементил выглядела как-то так:

#include <arch/antares.h>
#include <avr/eeprom.h>
#include <string.h>
#include <util/crc16.h>
#include <skeleton.h>
#include "aes.h"


/* 8hz timer is recommended */
uint16_t g_timestamp_low;
uint8_t g_timestamp_high;

static uint8_t otps_generated;

#define YUBIKEY_MODHEX_MAP "cbdefghijklnrtuv"
const char trans[] = YUBIKEY_MODHEX_MAP;

void yubikey_modhex_encode (char *dst, const char *src, size_t srcSize)
{
  while (srcSize--)
    {
      *dst++ = trans[(*src >> 4) & 0xf];
      *dst++ = trans[*src++ & 0xf];
    }

  *dst = '\0';
}


inline uint16_t yubi_crc16_update(uint16_t crc, uint8_t a)
{
    int i;

    crc ^= a;
    for (i = 0; i < 8; ++i)
    {
        if (crc & 1)
            crc = (crc >> 1) ^ 0x8408;
        else
            crc = (crc >> 1);
    }

    return crc;
}


void skeleton_send_yubi_token(struct key_yubikey *conf)
{
	int len, i;
	char buf[64];
	struct yubikey_secret_token tok;
	char *ptr;
	uint16_t crc = 0x5af0;
	aes128_ctx_t ctx;


	len = min_t(int, 2 * YUBIKEY_ID_LEN, strlen(conf->pub_string));
	memcpy(buf, conf->pub_string, len);
	memcpy(tok.secret, conf->secret, YUBIKEY_ID_LEN);

	cli();
	tok.timestamp_high = g_timestamp_high;
	tok.timestamp_low  = g_timestamp_low;
	sei();

	tok.insert_count = g_eeprom_conf.insertcount;
	tok.otps = otps_generated++;

	tok.random = rand(); //Fair dice roll

	ptr = (char *) &tok;
	for (i=0; i < sizeof(struct yubikey_secret_token) - sizeof(uint16_t); i++) {
		crc = yubi_crc16_update(crc, ptr[i]);
	}

	tok.crc = crc;

	aes128_init(conf->aes_key, &ctx);
	aes128_enc(&tok, &ctx);

	yubikey_modhex_encode(&buf[len], &tok, sizeof(tok));
	skeleton_type_message(buf);
}

void update_rgb();
ISR(TIMER1_OVF_vect)
{
	if (++g_timestamp_low == 0) {
		g_timestamp_high++;
	}
	//update_rgb();

}

ANTARES_INIT_LOW(timer_init)
{
	TCCR1A = 0;
	TCCR1B = 0;
	ICR1 = 1470; /* ~8Hz at 12Mhz clock */
	TCCR1A = (1<<WGM11);
	TCCR1B = (1 << WGM13) | (1<<WGM12) | 0x5; // /1024
#ifdef TIMSK
	TIMSK = 1<<TOIE1;
#else
	TIMSK1 = 1<<TOIE1;
#endif

}

По сути берем секретную строку, количество втыканий, значение таймера, шифруем AES одним блоком, потом транслируем в modhex и печатаем имитируя клавиатуру.

Кому надо, вот моя старая реализация этих токенов: https://git.ncrmnt.org/firmwares/SkeletonKey/

Исправление ncrmnt, :

Это что-то новое. Последняя реализация, которую я имплементил выглядела как-то так:

#include <arch/antares.h>
#include <avr/eeprom.h>
#include <string.h>
#include <util/crc16.h>
#include <skeleton.h>
#include "aes.h"


/* 8hz timer is recommended */
uint16_t g_timestamp_low;
uint8_t g_timestamp_high;

static uint8_t otps_generated;

#define YUBIKEY_MODHEX_MAP "cbdefghijklnrtuv"
const char trans[] = YUBIKEY_MODHEX_MAP;

void yubikey_modhex_encode (char *dst, const char *src, size_t srcSize)
{
  while (srcSize--)
    {
      *dst++ = trans[(*src >> 4) & 0xf];
      *dst++ = trans[*src++ & 0xf];
    }

  *dst = '\0';
}


inline uint16_t yubi_crc16_update(uint16_t crc, uint8_t a)
{
    int i;

    crc ^= a;
    for (i = 0; i < 8; ++i)
    {
        if (crc & 1)
            crc = (crc >> 1) ^ 0x8408;
        else
            crc = (crc >> 1);
    }

    return crc;
}


void skeleton_send_yubi_token(struct key_yubikey *conf)
{
	int len, i;
	char buf[64];
	struct yubikey_secret_token tok;
	char *ptr;
	uint16_t crc = 0x5af0;
	aes128_ctx_t ctx;


	len = min_t(int, 2 * YUBIKEY_ID_LEN, strlen(conf->pub_string));
	memcpy(buf, conf->pub_string, len);
	memcpy(tok.secret, conf->secret, YUBIKEY_ID_LEN);

	cli();
	tok.timestamp_high = g_timestamp_high;
	tok.timestamp_low  = g_timestamp_low;
	sei();

	tok.insert_count = g_eeprom_conf.insertcount;
	tok.otps = otps_generated++;

	tok.random = rand(); //Fair dice roll

	ptr = (char *) &tok;
	for (i=0; i < sizeof(struct yubikey_secret_token) - sizeof(uint16_t); i++) {
		crc = yubi_crc16_update(crc, ptr[i]);
	}

	tok.crc = crc;

	aes128_init(conf->aes_key, &ctx);
	aes128_enc(&tok, &ctx);

	yubikey_modhex_encode(&buf[len], &tok, sizeof(tok));
	skeleton_type_message(buf);
}

void update_rgb();
ISR(TIMER1_OVF_vect)
{
	if (++g_timestamp_low == 0) {
		g_timestamp_high++;
	}
	//update_rgb();

}

ANTARES_INIT_LOW(timer_init)
{
	TCCR1A = 0;
	TCCR1B = 0;
	ICR1 = 1470; /* ~8Hz at 12Mhz clock */
	TCCR1A = (1<<WGM11);
	TCCR1B = (1 << WGM13) | (1<<WGM12) | 0x5; // /1024
#ifdef TIMSK
	TIMSK = 1<<TOIE1;
#else
	TIMSK1 = 1<<TOIE1;
#endif

}

По сути берем секретную строку, количество втыканий, значение таймера, шифруем AES одним блоком, потом транслируем в modhex и печатаем имитируя клавиатуру.

Кому надо, вот моя старая реализация этих токенов: https://git.ncrmnt.org/firmwares/SkeletonKey/

Исходная версия ncrmnt, :

Это что-то новое. Последняя реализация, которую я имплементил выглядела как-то так:

#include <arch/antares.h>
#include <avr/eeprom.h>
#include <string.h>
#include <util/crc16.h>
#include <skeleton.h>
#include "aes.h"


/* 8hz timer is recommended */
uint16_t g_timestamp_low;
uint8_t g_timestamp_high;

static uint8_t otps_generated;

#define YUBIKEY_MODHEX_MAP "cbdefghijklnrtuv"
const char trans[] = YUBIKEY_MODHEX_MAP;

void yubikey_modhex_encode (char *dst, const char *src, size_t srcSize)
{
  while (srcSize--)
    {
      *dst++ = trans[(*src >> 4) & 0xf];
      *dst++ = trans[*src++ & 0xf];
    }

  *dst = '\0';
}


inline uint16_t yubi_crc16_update(uint16_t crc, uint8_t a)
{
    int i;

    crc ^= a;
    for (i = 0; i < 8; ++i)
    {
        if (crc & 1)
            crc = (crc >> 1) ^ 0x8408;
        else
            crc = (crc >> 1);
    }

    return crc;
}


void skeleton_send_yubi_token(struct key_yubikey *conf)
{
	int len, i;
	char buf[64];
	struct yubikey_secret_token tok;
	char *ptr;
	uint16_t crc = 0x5af0;
	aes128_ctx_t ctx;


	len = min_t(int, 2 * YUBIKEY_ID_LEN, strlen(conf->pub_string));
	memcpy(buf, conf->pub_string, len);
	memcpy(tok.secret, conf->secret, YUBIKEY_ID_LEN);

	cli();
	tok.timestamp_high = g_timestamp_high;
	tok.timestamp_low  = g_timestamp_low;
	sei();

	tok.insert_count = g_eeprom_conf.insertcount;
	tok.otps = otps_generated++;

	tok.random = rand(); //Fair dice roll

	ptr = (char *) &tok;
	for (i=0; i < sizeof(struct yubikey_secret_token) - sizeof(uint16_t); i++) {
		crc = yubi_crc16_update(crc, ptr[i]);
	}

	tok.crc = crc;

	aes128_init(conf->aes_key, &ctx);
	aes128_enc(&tok, &ctx);

	yubikey_modhex_encode(&buf[len], &tok, sizeof(tok));
	skeleton_type_message(buf);
}

void update_rgb();
ISR(TIMER1_OVF_vect)
{
	if (++g_timestamp_low == 0) {
		g_timestamp_high++;
	}
	//update_rgb();

}

ANTARES_INIT_LOW(timer_init)
{
	TCCR1A = 0;
	TCCR1B = 0;
	ICR1 = 1470; /* ~8Hz at 12Mhz clock */
	TCCR1A = (1<<WGM11);
	TCCR1B = (1 << WGM13) | (1<<WGM12) | 0x5; // /1024
#ifdef TIMSK
	TIMSK = 1<<TOIE1;
#else
	TIMSK1 = 1<<TOIE1;
#endif

}