Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методы Защиты Асушников / лабы Васильева / 5 / Ot2[гаммирование с зацепкой].pdf
Скачиваний:
43
Добавлен:
15.06.2014
Размер:
781.47 Кб
Скачать

__global__ void encrypt(uI32 *cio, int size)

{

for(size;size>0;size--,cio += 32<<9){

uI32 *rk = cencryption_round_key;

 

//считываем блок и добавляем раундовый ключ

((<<4) - tPitch)

uI32 b0, b1, b2 = threadIdx.y<<2, b3 = blockIdx.x<<9;

uI32 a0

= cio[b3+((0+b2)<<4)+threadIdx.x]^rk[0];

uI32 a1

= cio[b3+((1+b2)<<4)+threadIdx.x]^rk[1];

uI32 a2

= cio[b3+((2+b2)<<4)+threadIdx.x]^rk[2];

uI32 a3

= cio[b3+((3+b2)<<4)+threadIdx.x]^rk[3];

//раунды криптолиза (сycle 2x) for(int i=AES128_ROUNDS;;rk += 8)

{

b0 = fb(a0, 0) ^ fb(a1, 1) ^ fb(a2, 2) ^ fb(a3, 3) ^ rk[4]; b1 = fb(a1, 0) ^ fb(a2, 1) ^ fb(a3, 2) ^ fb(a0, 3) ^ rk[5]; b2 = fb(a2, 0) ^ fb(a3, 1) ^ fb(a0, 2) ^ fb(a1, 3) ^ rk[6]; b3 = fb(a3, 0) ^ fb(a0, 1) ^ fb(a1, 2) ^ fb(a2, 3) ^ rk[7];

if(!(i-=2)) break;

a0 = fb(b0, 0) ^ fb(b1, 1) ^ fb(b2, 2) ^ fb(b3, 3) ^ rk[8]; a1 = fb(b1, 0) ^ fb(b2, 1) ^ fb(b3, 2) ^ fb(b0, 3) ^ rk[9]; a2 = fb(b2, 0) ^ fb(b3, 1) ^ fb(b0, 2) ^ fb(b1, 3) ^ rk[10]; a3 = fb(b3, 0) ^ fb(b0, 1) ^ fb(b1, 2) ^ fb(b2, 3) ^ rk[11];

}

a2=threadIdx.y<<2; a3 = blockIdx.x<<9;

//последний раунд (без перемешивания столбцов) ret(cio[a3+((0+a2)<<4)+threadIdx.x],rk[ 8],cs_box,b3,b2,b1,b0); ret(cio[a3+((1+a2)<<4)+threadIdx.x],rk[ 9],cs_box,b0,b3,b2,b1); ret(cio[a3+((2+a2)<<4)+threadIdx.x],rk[10],cs_box,b1,b0,b3,b2); ret(cio[a3+((3+a2)<<4)+threadIdx.x],rk[11],cs_box,b2,b1,b0,b3);

}

}

Рисунок 14 – Шифрование на GPU

При помощи встроенных констант (blockIdx /threadIdx) определяем текущее положение функции в GPU. Подсчитаем количество использованных переменных, и получим 12 регистров и остается 4 из 16 на промежуточные вычисления. Хотя ―size‖, ―cio‖ и ―i‖ могут быть выкинуты в локальную память при неудачной компиляции. Кстати в данном случае переменные ―a0-a3, b0-b3‖ являются столбцами (рисунок 1).

Особенно внимание стоит обратить на структуру: загрузили блок, обработали и выгрузили.

1.3 Генерация случайной последовательности бит

Для генерации ключа и начального рандомного блока (синхропосылки) обычно используют все от простого генератора псевдослучайных последовательностей (завязанного на текущее время) до долгого собирания всевозможной информации из системы (состояния регистров процессора, значения из памяти по рандомным адресам, действия пользователя…), но у первого проблемным местом является его предсказуемость, а у второго – длительность выполнения.

Все вышеперечисленное является программным способом генерации, аппаратные генераторы обычно реализуются на двух (их два, а не два такта) тактовых генераторах с высокой погрешностью. В CUDAESdelsa применяется подобный способ. В качестве генераторов здесь выступает счетчик времени выполнения от CUDA и стандартный счетчик тактов.

Код на рисунке 15 реализует генератор.

12

#include <winternl.h>

#include <time.h>

typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

/*g*/clock_t genCloc=clock();

//даz zer gen

/*g*/float genCuF;

 

/*g*/BYTE key[16],gamma[16];

 

/*g*/cudaEvent_t genCuEv0,genCuEv1;

 

/*g*/cudaEventCreate(&genCuEv0); /*g*/cudaEventCreate(&genCuEv1); /*g*/cudaEventRecord(genCuEv0,0);

/*g*/_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION genProcInfo;

/*g*/PROCNTQSI NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle("ntdll"), "NtQuerySystemInformation");

/*g*/NtQuerySystemInformation(SystemProcessorPerformanceInformation, &genProcInfo, sizeof(_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),0);

/*g*/((uI32*)key)[0]=_rotl(*(uI32*)&(genProcInfo.UserTime), *(uI32*)&(genProcInfo.Reserved1[0]))^rand(); /*g*/((uI32*)key)[1]=_rotl(*(uI32*)&(genProcInfo.IdleTime), *(uI32*)&(genProcInfo.KernelTime))^rand();

/*g*/((uI32*)key)[2]=_rotl(*(uI32*)&(genProcInfo.Reserved1[1]),*(uI32*)&(genProcInfo. Reserved2))^rand();

/*g*/cudaEventRecord(genCuEv1,0);

/*g*/cudaEventSynchronize(genCuEv1);

/*g*/cudaEventElapsedTime(&genCuF,genCuEv0,genCuEv1);

/*g*/genCloc=clock()-genCloc-(uI32)genCuF;

/*g*/((uI32*)key)[3]=((uI32)genCuF)^((uI32*)&(genProcInfo.IdleTime))[1]^ ((uI32*)&(genProcInfo.UserTime))[1]^((uI32*)&(genProcInfo.Reserved1[1]))[1];

/*g*/*(uI32*)(&key[ 2])=_rotl(*(uI32*)(&key[ 2]),genCloc);

/*g*/*(uI32*)(&key[ 6])=_rotl(*(uI32*)(&key[ 6]),genCloc); /*g*/*(uI32*)(&key[10])=_rotl(*(uI32*)(&key[10]),genCloc);

Рисунок 15 – Генератор случайных чисел

1.4 Плавающее гаммирование с зацепкой

Собственно плавающая версия отличается тем, что блок исходного текста перед использованием разбивается на 4 части и каждая часть циклически сдвигается на величину, зависящую от текущего положения блока в данных. Это не только уменьшает косвенное присутствие прямых последовательностей исходных данных в зашифрованных, но и дает зависимость от размера данных. Код на рисунке 16 использует данное гаммирование.

//кримируем

bufCu[0]^=((uI32*)gamma)[0];

bufCu[1]^=((uI32*)gamma)[1];

bufCu[2]^=((uI32*)gamma)[2];

bufCu[3]^=((uI32*)gamma)[3];

ibufCu=bufCu+4-1; ibuf=buf -1;

for(DWORD i=cmhSize/(4*sizeof(uI32))-1;i;--i){ *(++ibufCu)^=_rotl(*(++ibuf),i); *(++ibufCu)^=_rotl(*(++ibuf),i); *(++ibufCu)^=_rotl(*(++ibuf),i); *(++ibufCu)^=_rotl(*(++ibuf),i);

}

Рисунок 16 – Плавающее гаммирование с зацепкой

13

Соседние файлы в папке 5