Не глянешь на код? Может найдешь ошибки. А то я запутался совсем...
//---------------------------------------------------------------------------
#include <stdio.h>
#include <conio.h>
//---------------------------------------------------------------------------
// взято из хелпа, определяем размер файла
long filesize(FILE *stream)
{
 long curpos, length;
 curpos = ftell(stream);
 fseek(stream, 0L, SEEK_END);
 length = ftell(stream);
 fseek(stream, curpos, SEEK_SET);
 return length;
}
// функция, реализующая работу ГОСТ 28147-89 в режиме простой замены
void rpz(int rezh, char* opener, char* saver)
{
 FILE *f_begin, *f_end; // потоки для исходного и конечного файлов
 // таблица замен
 unsigned char Tab_Z[8][16] =
 {
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
  0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,
 };
// ключик
 unsigned long key[8] =
 {
  0x0123,
  0x4567,
  0x89AB,
  0xCDEF,
  0x0123,
  0x4567,
  0x89AB,
  0xCDEF,
 };
 char N[4]; // 32-разрядный накопитель,
 unsigned long n1=0, n2=0, SUM232=0; // накопители N1, N2, и сумматор
 // открываем файлы
 f_begin = fopen (opener,"rb");
 f_end = fopen (saver,"wb");
 // определим количество блоков
 float blokoff;
 blokoff=8*filesize(f_begin);
 blokoff = blokoff/64;
 int block = blokoff;
 if (blokoff-block>0) block++;
 int sh;
 if (filesize(f_begin)>=4) sh = 4; else sh = filesize(f_begin);
 int sh1 = 0;
 int flag=0;
 // начнем считывание и преобразование блоков
 // присутствуют проверки на полноту блоков, чтобы считать только нужное количество бит
 for (int i=0; i<block; i++)
 {
  // записываем в накопитель N1
  for (int q1=0; q1<4; q1++) *((unsigned char *)&N+q1) = 0x00;
  if ((sh1+sh)<filesize(f_begin))
  {
   fread (N,sh,1,f_begin);
   sh1+=sh;
  }
  else
  {
   sh=filesize(f_begin)-sh1;
   fread (N,sh,1,f_begin);
   flag=1;
  }
  n1 = *((unsigned long *)&N);
  // записываем в накопитель N2
  for (int q2=0; q2<4; q2++) *((unsigned char *)&N+q2) = 0x00;
 // memset(N,0,sizeof(N));
  if ((sh1+sh)<filesize(f_begin))
  {
   fread (N,sh,1,f_begin);
   sh1+=sh;
  }
  else
  {
   if (flag==0)
   {
    sh=filesize(f_begin)-sh1;
    fread (N,sh,1,f_begin);
   } 
  }
  n2 = *((unsigned long *)&N);
  // 32 цикла простой замены
  // ключ считываем в требуемом ГОСТом порядке
  int c = 0;
  for (int k=0; k<32; k++)
  {
   if (rezh==1) { if (k==24) c = 7; }
    else { if (k==8) c = 7; }
   // суммируем в сумматоре СМ1
   SUM232 = key[c] + n1;
   // заменяем по таблице замен
   unsigned char first_byte=0,second_byte=0,zam_symbol=0;
   int n = 7;
   for (int a=3; a>=0; a--)
   {
    zam_symbol = *((unsigned char *)&SUM232+a);
    first_byte = (zam_symbol & 0xF0) >> 4;
    second_byte = (zam_symbol & 0x0F);
    first_byte = Tab_Z[n][first_byte];
    n--;
    second_byte = Tab_Z[n][second_byte];
    n--;
    zam_symbol = (first_byte << 4) | second_byte;
    *((unsigned char *)&SUM232+a) = zam_symbol;
   } 
   
   SUM232 = (SUM232<<11)|(SUM232>>21); // циклический сдвиг на 11
   SUM232 = n2^SUM232; // складываем в сумматоре СМ2
   if (k<31)
   {
    n2 = n1;
    n1 = SUM232;
   }
   if (rezh==1)
   {
    if (k<24)
    {
     c++;
     if (c>7) c = 0;
    }
    else
    {
     c--;
     if (c<0) c = 7;
    }
   }
   else
   {
    if (k<8)
    {
     c++;
     if (c>7) c = 0;
    }
   else
   {
    c--;
    if (c<0) c = 7;
   }
  }
 }
 n2 = SUM232;
 // вывод результата в файл
  char sym_rez;
  for (int q3=0; q3<=3; q3++)
  {
   sym_rez = *((unsigned char *)&n1+q3);
   fprintf(f_end, "%c", sym_rez);
  }
  for (int q4=0; q4<=3; q4++)
  {
   sym_rez = *((unsigned char *)&n2+q4);
   fprintf(f_end, "%c", sym_rez);
  }
 }
 fclose (f_begin);
 fclose (f_end);
}
//---------------------------------------------------------------------------
int main()
{
 // выбираем шифрование или расшифрование
 int rezhim = 0;
 do
 {
  printf("Vuberite rejum rabotu:\nShufrovanie - 1\nRasshufrovanie - 2\n");
   scanf("%d", &rezhim);
 } while ((rezhim!=1)&&(rezhim!=2)); // повторяем до тех пор, пока не будет введено 1 или 
 // выбираем исходный и конечный файлы (слэш '\' в пути писать как '\\') 
 char open_str[50], save_str[50];
 printf("\nVvedite adres faila\n");
 scanf("%s", &open_str);
 printf("\nVvedite imja zashufrovanogo faila\n");
 scanf("%s", &save_str);
 rpz(rezhim, open_str, save_str); // запускаем РПЗ
 return 0;
}
//------------------------------------------------------------------------