/** \details GOST_ENCRYPTED_GAMMA_WITH_FEEDBACK Функция шифрования в режиме гаммирования с обратной связью. \param[in] *Data указатель на даныне для шифрования/дешифрования \param[in] Size размер данных \param[in] *Sync указатель на синхропосылку, заносится текущее значение синхропосылки \param[in] Mode Если _GOST_MODE_ENCRYPT будет выполнено шифрование данных, если _GOST_MODE_DECRYPT - расшифрование \param[in] *GOST_Table указатель на таблицу замен ГОСТ в 64-байтном формате \param[in] *GOST_Key указательн на 256 битный ключ \attetion Если используется режим совместимости с входами эталонного шифратора, то сихнропосылка Sync для первого вызова должна быть подготовлена функцицией GOST_PREPARE_SYNCPACK_GAMMA_FEEDBACK */ void GOST_ENCRYPTED_GAMMA_WITH_FEEDBACK(BYTE *Data, DWORD Size, BYTE *Sync, bool Mode, BYTE *GOST_Table, BYTE *GOST_Key){ GOST_PART_DATA *SyncP = (GOST_PART_DATA *)Sync; BYTE i, tmp; while (Size != 0){ GOST_ENCRYPTED_32_CICLE(SyncP, GOST_Table, (DWORD *)GOST_Key); #if _GOST_COMPATIBILITY_STANDART == 1 (*SyncP).half[_GOST_PART_DATA_N2_HALF] = _SWAPW32((*SyncP).half[_GOST_PART_DATA_N2_HALF]); (*SyncP).half[_GOST_PART_DATA_N1_HALF] = _SWAPW32((*SyncP).half[_GOST_PART_DATA_N1_HALF]); #endif for (i = 0; i < _MINIMUM(_GOST_PART_SIZE, Size); i++){ if (Mode == _GOST_MODE_ENCRYPT){ *Data ^= (*SyncP).parts[i]; (*SyncP).parts[i] = *Data; } else{ tmp = *Data; *Data ^= (*SyncP).parts[i]; (*SyncP).parts[i] = tmp; } Data++; } #if _GOST_COMPATIBILITY_STANDART == 1 (*SyncP).half[_GOST_PART_DATA_N2_HALF] = _SWAPW32((*SyncP).half[_GOST_PART_DATA_N2_HALF]); (*SyncP).half[_GOST_PART_DATA_N1_HALF] = _SWAPW32((*SyncP).half[_GOST_PART_DATA_N1_HALF]); #endif Size -= i; } }
/** \details GOST_SIMPLE_REPLACEMENT Функция шифрования/расшифрования в режиме простой замены Параметры: \param[in] *Data Указатель на данные для шифрования и параметр для занесения данных результата \param[in] Size Размер данных \param[in] Mode Если _GOST_MODE_ENCRYPT шифрование, то _GOST_MODE_DECRYPT - расшифрование \param[in] *GOST_Table Указатель на таблицу замен ГОСТ в 64 байтном формате \param[in] *GOST_Key Указатель на 256 битный массив ключа */ void GOST_SIMPLE_REPLACEMENT(BYTE *Data, DWORD Size, bool Mode, BYTE *GOST_Table, BYTE *GOST_Key){ BYTE Current_Part_Size; //Размер текущей части GOST_PART_DATA Prepare_Data; //Подготовленные данные DWORD *Gost_Key_Pt = (DWORD*)GOST_Key; //Ключ while (Size != 0){ //Пока не кончатся данные продолжаем работу Current_Part_Size = _MINIMUM(_GOST_PART_SIZE, Size); //Определим минимум из размера порции данных для криптообработки и размера данных memset(&Prepare_Data, _GOST_DEFAULT_BYTE, sizeof(Prepare_Data)); //Заполним буфер (&Prepare_Data) символом (_DEFAULT_BYTE), количетсвом символов (sizeof(Prepare_Data)) #if _GOST_COMPATIBILITY_STANDART == 1 Prepare_Data.half[_GOST_PART_DATA_N2_HALF] = _SWAPW32(Prepare_Data.half[_GOST_PART_DATA_N2_HALF]); Prepare_Data.half[_GOST_PART_DATA_N1_HALF] = _SWAPW32(Prepare_Data.half[_GOST_PART_DATA_N1_HALF]); #endif memcpy(&Prepare_Data, Data, Current_Part_Size); //Скопируем Current_Part_Size байтов первого блока памяти, на который ссылается Data, //во второй блок памяти, на который ссылается &Prepare_Data if (Mode == _GOST_MODE_ENCRYPT){ GOST_ENCRYPTED_32_CICLE(&Prepare_Data, GOST_Table, Gost_Key_Pt);//Запускаем шифрование } else{ GOST_DECRYPTED_32_CICLE(&Prepare_Data, GOST_Table, Gost_Key_Pt);//Запускаем дешифрование } #if _GOST_COMPATIBILITY_STANDART == 1 Prepare_Data.half[_GOST_PART_DATA_N2_HALF] = _SWAPW32(Prepare_Data.half[_GOST_PART_DATA_N2_HALF]); Prepare_Data.half[_GOST_PART_DATA_N1_HALF] = _SWAPW32(Prepare_Data.half[_GOST_PART_DATA_N1_HALF]); #endif memcpy(Data, &Prepare_Data, Current_Part_Size); //Скопируем Current_Part_Size байтов первого блока памяти, на который ссылается Prepare_Data, //Во второй блок памяти, на который ссылается Data Data += Current_Part_Size; //Увеличим данные (перейдем к следующей порции) на текущую порцию Size -= Current_Part_Size; //Уменьшим размер на обработанную порцию } }
/** @details GOST_Crypt_GF_Data Функция шифрования в режиме гаммирования с обратной связью. @param *Data - указатель на данные для шифрования/расшифрования. @param Size - Размер данных @param *Synchro - Указатель на синхопросылку, также сюда заносится текущее значение синхропосылки. @param Mode - Если _GOST_Mode_Encrypt будет выполнено шифрование данных, если _GOST_Mode_Decrypt расшифрование @param *GOST_Table - Указатель на таблицу замены ГОСТ(ДК) в 128 байтном формате (вместо старшого полубайта 0). @param *GOST_Key - Указатель на 256 битный массив ключа(СК). @attention Если используется режим совместимости с входами еталонного шифратора, то синхропосылка Synchro для первого вызова должна быть подготовлена функцией GOST_Crypt_GF_Prepare_S. */ void GOST_Crypt_GF_Data(uint8_t *Data, uint32_t Size, uint8_t *Synchro, bool Mode, uint8_t *GOST_Table, uint8_t *GOST_Key ) { GOST_Data_Part *S=(GOST_Data_Part *)Synchro; uint8_t i,Tmp; while(Size!=0) { GOST_Crypt_32_E_Cicle(S,GOST_Table,(uint32_t *)GOST_Key);//C32(S) #if _GOST_ROT==1 (*S).half[_GOST_Data_Part_N2_Half]=_SWAPW32((*S).half[_GOST_Data_Part_N2_Half]); (*S).half[_GOST_Data_Part_N1_Half]=_SWAPW32((*S).half[_GOST_Data_Part_N1_Half]); #endif for (i=0;i<_Min(_GOST_Part_Size,Size);i++)//Data XOR S; S=Data; { if (Mode==_GOST_Mode_Encrypt) { *Data^=(*S).parts[i]; (*S).parts[i]=*Data; } else { Tmp=*Data; *Data^=(*S).parts[i]; (*S).parts[i]=Tmp; } Data++; } #if _GOST_ROT==1 (*S).half[_GOST_Data_Part_N2_Half]=_SWAPW32((*S).half[_GOST_Data_Part_N2_Half]); (*S).half[_GOST_Data_Part_N1_Half]=_SWAPW32((*S).half[_GOST_Data_Part_N1_Half]); #endif Size-=i; } }
/** @details GOST_Crypt_G_Data Шифрование\Расшифрования блока данных в режиме гаммирования. @param *Data - Указатель на данные для шифрования\расшифрования, также сюда заносится результат работы. @param Size - Размер данных @param *Synchro - Указатель на синхопросылку, также сюда заносится текущее значение синхропосылки. @param *GOST_Table - Указатель на таблицу замены ГОСТ(ДК) в 128 байтном формате(вместо старшого полубайта 0). @param *GOST_Key - Указатель на 256 битный массив ключа(СК). @attention Синхропосылка Synchro для первого вызова должна быть подготовлена функцией/макросом GOST_Crypt_G_PS. */ void GOST_Crypt_G_Data(uint8_t *Data, uint32_t Size, uint8_t *Synchro, uint8_t *GOST_Table, uint8_t *GOST_Key ) { GOST_Data_Part *S=(GOST_Data_Part *)Synchro; GOST_Data_Part Tmp; uint8_t i; while(Size!=0) { (*S).half[_GOST_Data_Part_N1_Half]+=_GOST_C0; _GOST_ADC32((*S).half[_GOST_Data_Part_N2_Half],_GOST_C1,(*S).half[_GOST_Data_Part_N2_Half]);//_GOST_Data_Part_HiHalf Tmp=*S; GOST_Crypt_32_E_Cicle(&Tmp,GOST_Table,(uint32_t *)GOST_Key); #if _GOST_ROT==1 Tmp.half[_GOST_Data_Part_N2_Half]=_SWAPW32(Tmp.half[_GOST_Data_Part_N2_Half]); Tmp.half[_GOST_Data_Part_N1_Half]=_SWAPW32(Tmp.half[_GOST_Data_Part_N1_Half]); #endif for (i=0;i<_Min(_GOST_Part_Size,Size);i++) { *Data^=Tmp.parts[i]; Data++; } Size-=i; } }
/** @details GOST_Encrypt_SR Функция шифрования/расшифрования в режиме простой замены. @param *Data - Указатель на данные для шифрования, также сюда заносится результат. @param Size - Размер данных @param Mode - Если _GOST_Mode_Encrypt шифрования, _GOST_Mode_Decrypt - расшифрование @param *GOST_Table - Указатель на таблицу замены ГОСТ(ДК) в 128 байтном формате (вместо старшого полубайта 0) @param *GOST_Key - Указатель на 256 битный массив ключа(СК). */ void GOST_Encrypt_SR(uint8_t *Data, uint32_t Size, bool Mode, uint8_t *GOST_Table, uint8_t *GOST_Key ) { uint8_t Cur_Part_Size; GOST_Data_Part Data_prep; uint32_t *GOST_Key_pt=(uint32_t *) GOST_Key; while (Size!=0) { Cur_Part_Size=_Min(_GOST_Part_Size,Size); memset(&Data_prep,_GOST_Def_Byte,sizeof(Data_prep)); memcpy(&Data_prep,Data,Cur_Part_Size); #if _GOST_ROT==1 Data_prep.half[_GOST_Data_Part_N2_Half]=_SWAPW32(Data_prep.half[_GOST_Data_Part_N2_Half]); Data_prep.half[_GOST_Data_Part_N1_Half]=_SWAPW32(Data_prep.half[_GOST_Data_Part_N1_Half]); #endif if (Mode==_GOST_Mode_Encrypt) { GOST_Crypt_32_E_Cicle(&Data_prep,GOST_Table,GOST_Key_pt); } else { GOST_Crypt_32_D_Cicle(&Data_prep,GOST_Table,GOST_Key_pt); } #if _GOST_ROT==1 Data_prep.half[_GOST_Data_Part_N2_Half]=_SWAPW32(Data_prep.half[_GOST_Data_Part_N2_Half]); Data_prep.half[_GOST_Data_Part_N1_Half]=_SWAPW32(Data_prep.half[_GOST_Data_Part_N1_Half]); #endif memcpy(Data,&Data_prep, Cur_Part_Size); Data+=Cur_Part_Size; Size-=Cur_Part_Size; } }
void GOST_ENCRYPTED_GAMMA(BYTE *Data, DWORD Size, BYTE *SyncPack, BYTE *GOST_Table, DWORD *GOST_Key){ GOST_PART_DATA *SYNCP = (GOST_PART_DATA *)SyncPack; //Приведем к 64битному формату синхропосылку GOST_PART_DATA tmp; //Временная переменная для синхропосылки BYTE i; //Переменная цикла while (Size != 0){ //Цикл по данным (*SYNCP).half[_GOST_PART_DATA_N1_HALF] += _GOST_C0; //Прибавление константы С0 _GOST_ADC32((*SYNCP).half[_GOST_PART_DATA_N2_HALF], _GOST_C1, (*SYNCP).half[_GOST_PART_DATA_N2_HALF]); //Суммирование tmp = *SYNCP; // GOST_ENCRYPTED_32_CICLE(&tmp, GOST_Table, (DWORD*)GOST_Key); //Гаммирование. #if _GOST_COMPATIBILITY_STANDART == 1 tmp.half[_GOST_PART_DATA_N2_HALF] = _SWAPW32(tmp.half[_GOST_PART_DATA_N2_HALF]); tmp.half[_GOST_PART_DATA_N1_HALF] = _SWAPW32(tmp.half[_GOST_PART_DATA_N1_HALF]); #endif for (i = 0; i < _MINIMUM(_GOST_PART_SIZE, Size); i++){ //Цикл прохода по данным *Data ^= tmp.parts[i]; //Побитовый XOR с частями в 8ми битном представлении Data++; //Уведичиваем данные } //Конец FOR Size -= i; //Уменьшаем размер на порцию } //Конец While }
/** \details GOST_IMITTAPASTE Расчет имитовставки \param[in] *Open_data указатель на данные для которых требуется расчитать имитовставку. \param[in] *Im указатель на массив размером _GOST_IMIT_SIZE (64bit) куда будет занесен результат расчета имитовставки \param[in] Size Размер данных \param[in] *GOST_Table Указатель на таблицу замен ГОСТ в 64 байтном формате \param[in] *GOST_Key Указатель на 256 битный массив ключа \warning Для первого раунда массив Im должен быть заполнен _GOST_DEFAULT_BYTE */ void GOST_IMITTAPASTE(BYTE *Open_data, BYTE *Im, DWORD Size, BYTE *GOST_Table, BYTE *GOST_Key){ BYTE Current_Part_Size; GOST_PART_DATA *Im_Prepare = (GOST_PART_DATA *)Im; GOST_PART_DATA Open_data_Prepare; while (Size != 0){ Current_Part_Size = _MINIMUM(_GOST_PART_SIZE, Size); Open_data_Prepare.half[_GOST_PART_DATA_N1_HALF] = 0; Open_data_Prepare.half[_GOST_PART_DATA_N2_HALF] = 0; memcpy(&Open_data_Prepare, Open_data, Current_Part_Size); (*Im_Prepare).half[_GOST_PART_DATA_N1_HALF] ^= Open_data_Prepare.half[_GOST_PART_DATA_N1_HALF]; (*Im_Prepare).half[_GOST_PART_DATA_N2_HALF] ^= Open_data_Prepare.half[_GOST_PART_DATA_N2_HALF]; Size -= Current_Part_Size; Open_data += Current_Part_Size; GOST_IMITTAPASTE_ENCRYPTED_CICLE(Im_Prepare, GOST_Table, (DWORD *)GOST_Key); } #if _GOST_COMPATIBILITY_STANDART == 1 (*Im_Prepare).half[_GOST_PART_DATA_N1_HALF] = _SWAPW32((*Im_Prepare).half[_GOST_PART_DATA_N1_HALF]); (*Im_Prepare).half[_GOST_PART_DATA_N2_HALF] = _SWAPW32((*Im_Prepare).half[_GOST_PART_DATA_N2_HALF]); #endif }
//for first round Imitta must set to _GOST_Def_Byte void GOST_Imitta(uint8_t *Open_Data, uint8_t *Imitta, uint32_t Size, uint8_t *GOST_Table, uint8_t *GOST_Key ) { uint8_t Cur_Part_Size; GOST_Data_Part *Imitta_Prep=(GOST_Data_Part *) Imitta; GOST_Data_Part Open_Data_Prep; while(Size!=0) { Cur_Part_Size=_Min(_GOST_Part_Size,Size); Open_Data_Prep.half[_GOST_Data_Part_N2_Half]=0; Open_Data_Prep.half[_GOST_Data_Part_N1_Half]=0; memcpy(&Open_Data_Prep,Open_Data,Cur_Part_Size); (*Imitta_Prep).half[_GOST_Data_Part_N1_Half]^=Open_Data_Prep.half[_GOST_Data_Part_N1_Half]; (*Imitta_Prep).half[_GOST_Data_Part_N2_Half]^=Open_Data_Prep.half[_GOST_Data_Part_N2_Half]; Size-=Cur_Part_Size; Open_Data+=Cur_Part_Size; GOST_Imitta_16_E_Cicle(Imitta_Prep,GOST_Table,(uint32_t *)GOST_Key); } #if _GOST_ROT==1 (*Imitta_Prep).half[_GOST_Data_Part_N1_Half]=_SWAPW32((*Imitta_Prep).half[_GOST_Data_Part_N1_Half]); (*Imitta_Prep).half[_GOST_Data_Part_N2_Half]=_SWAPW32((*Imitta_Prep).half[_GOST_Data_Part_N2_Half]); #endif }