Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
28
Добавлен:
16.04.2013
Размер:
12.72 Кб
Скачать
/*----------------------------------------------------------
  MakePsws.c -- Џа®Ја ¬¬  ўла Ў®вЄЁ ¬ ббЁў  Ї а®«м­®©
		Ё­д®а¬ жЁЁ.
  ----------------------------------------------------------
  ђ §а Ў®в « Ђ.ћ.‚Ё­®Єга®ў, Ј.Њ®бЄў ,  ЇаҐ«м-¬ © 1995 Ј.
  (c) 1995, ‘ў®Ў®¤­®Ґ  ЁбЇ®«м§®ў ­ЁҐ  Ё Є®ЇЁа®ў ­ЁҐ.
  ----------------------------------------------------------
  ЃҐбЇ« в­®Ґ ЇаЁ«®¦Ґ­ЁҐ Є бв вмҐ ў "Њ®­Ёв®аҐ".
  ----------------------------------------------------------
*/
#include <io.h>		// open, filelength
#include <fcntl.h>	// O_RDONLY
#include <ctype.h>	// toupper,isdigit
#include <stdlib.h>	// strtoul
#include <stdio.h>	// printf
#include <dir.h>	// MAXPATH
#include <memory.h>	// setmem
#include <string.h>	// strlen
#include "gost.h"	// „ ­­лҐ Ё Їа®в®вЁЇл ѓЋ‘’ 

#define  BUFFER_SIZE    1024
#define  MAX_ALPHABET     16
#define  MAX_GROUP        16

// ѓ«®Ў «м­лҐ бв вЁзҐбЄЁҐ ¤ ­­лҐ

typedef enum
{
  O_K_=0,	    	// ўбҐ O.K.
  errInvalidFlag,   	// ­ҐўҐа­л© д« Ј ўл§®ў  Їа®Ја ¬¬л
  errBadSynchro,    	// ­ҐўҐа­® § ¤ ­  бЁ­еа®Ї®бл«Є 
  errInsufficientParm,	// ­Ґ¤®бв в®з­® Ї а ¬Ґва®ў ўл§®ў 
  errTooManyParm,	// б«ЁиЄ®¬ ¬­®Ј® Ї а ¬Ґва®ў ўл§®ў 
  errBadKey,	    	// Ї«®е®© д ©« Є«оз 
  errBadXCHT,	    	// Ї«®е®© д ©« б в Ў«ЁжҐ© § ¬Ґ­
  errBadKeyLength,  	// ­ҐўҐа­® § ¤ ­® зЁб«® Ї а®«Ґ©
  errZeroKeyLength, 	// § ¤ ­  ­г«Ґў®Ґ зЁб«® Ї а®«Ґ©
  errKeyFailure,     	// ®иЁЎЄ  ­  д ©«Ґ б Є«о箬
  errBadPWNumber,	// ­ҐўҐа­® § ¤ ­® зЁб«® Ї а ¬Ґва®ў

  errItemCountExceed,   // ЇаҐўл襭® зЁб«® ЈагЇЇ бЁ¬ў®«®ў
  errPWCFileError,      // ®иЁЎЄ  ­  д ©«Ґ Є®­дЁЈга жЁЁ
  errBadPWCFileFormat,  // ­ҐўҐа­л© д®а¬ в д ©«  Є®­дЁЈга жЁЁ
  errBadPWCNumberItem,  // ­Ґ-жЁда  Ё ­Ґ-а §¤Ґ«ЁвҐ«м
  errOddPWCItemNumber,  // ­ҐзҐв­®Ґ зЁб«® зЁбҐ« ў бва®ЄҐ
  errAlphabetCountExceed, // ЇаҐўл襭® зЁб«®  «д ўЁв®ў
  errInvalidAlphabetRef,// ббл«Є  ­  ®вбгвбвўгойЁ©  «д ўЁв
  errPWsFileError       // ®иЁЎЄ  ­  д ©«Ґ Ї а®«Ґ©
} errList;

struct
{
  char	*alpha;         // гЄ § вҐ«м ­   «д ўЁв
  unsigned int power;   // ¬®й­®бвм  «д ўЁв 
} Alphabet [MAX_ALPHABET];  // ®ЇЁб вҐ«Ё  «д ўЁв®ў

union
{
  unsigned char seq [MAX_GROUP*2];
  struct
  {
    unsigned char AlphaNo;  // #  «д ўЁв 
    unsigned char SymbolNo; // зЁб«® бЁ¬ў®«®ў
  } stru [MAX_GROUP];
} item;			// бвагЄвга  ®ЇЁб ­Ёп

unsigned char chtab[1024];

Item	Key[32];	// а §ўҐа­гвл© Є«оз

Item    Synchro[2]=	// бЁ­еа®Ї®бл«Є 
{
  0UL,0UL
};

errList code=O_K_;	// Є®¤ ўл室 

char	 buffer[BUFFER_SIZE];
unsigned PWNeed=0;	// вॡго饥бп Є®«ЁзҐбвў® Ї а®«Ґ©
short	 PrintPWNo=0;	// ЇаЁ§­ Є, вॡговбп «Ё ­®¬Ґа
unsigned ItemCount;	// бзҐвзЁЄ зЁб«®ўле н«Ґ¬Ґ­в®ў
unsigned ParmCount=-1;	// бзҐвзЁЄ Ї а ¬Ґва®ў


// Џа®в®вЁЇл дг­ЄжЁ©

errList ProcessKey	(char *parameter);
errList ProcessItem	(char *parameter);
errList	SignalError     (errList errType, char *errPlace);
errList loadCht		(char *chtFile);
errList loadKey		(char *keyFile);
errList	execute		(void);

unsigned char getRandomByte (void);

typedef errList Processor   (char *string);

Processor BuildPwsParmTable,// Ї®бв஥­ЁҐ в Ў«Ёжл
	  GetPWNumber,  // ®ЇаҐ¤Ґ«Ґ­ЁҐ зЁб«  Ї а®«Ґ©
	  makePWs;      // Ї®бв஥­ЁҐ Ї а®«Ґ©

Processor *processor[]=
{
	BuildPwsParmTable,  // Ї®бв஥­ЁҐ в Ў«Ёжл
	GetPWNumber,	// ®ЇаҐ¤Ґ«Ґ­ЁҐ зЁб«  Ї а®«Ґ©
	makePWs 	// Ї®бв஥­ЁҐ Ї а®«Ґ©
};

// ѓ« ў­ п Їа®Ја ¬¬  ¬®¤г«п

errList	main (int argc, char *argv[])
{
  unsigned short i;

  printf("Џа®Ја ¬¬  ўла Ў®вЄЁ Ї а®«Ґ© б Ї®¬®ймо "
	 "ЄаЁЇв®Ја дЁзҐбЄ®Ј®  «Ј®аЁв¬  ѓЋ‘’ 28147-89"
	 "‘®бв ўЁ« Ђ.ћ.‚Ё­®Єга®ў,  ¬ © 1995 Ј®¤ ,"
	 "  бў®Ў®¤­®Ґ ЁбЇ®«м§®ў ­ЁҐ Ё Є®ЇЁа®ў ­ЁҐ\n");

  if (argc==1)
    return printf(
"Љ®¬ ­¤  § ЇгбЄ :  \"makepsws [Є«озЁ] Є®­дЁЈга жЁп "
	"Є®«ЁзҐбвў® १г«мв в\", Ј¤Ґ:\n"
"  Є«озЁ - нв® ®¤Ё­ Ё«Ё ­ҐбЄ®«мЄ® б«Ґ¤гойЁе"
	" н«Ґ¬Ґ­в®ў:\n"
"    /K<д ©«> - § ¤ Ґв д ©« б Є«о箬, §¤Ґбм Ё ¤ «ҐҐ"
	" <д ©«> - нв® ¤®ЇгбвЁ¬®Ґ\n"
"             ў MS-DOS Ё¬п д ©« .\n"
"             „«Ё­  д ©«  б Є«о箬 ¤®«¦­  Ўлвм "
	"32 Ё«Ё 256 Ў ©в®ў\n"
"             Џ® 㬮«з ­Ёо ЁбЇ®«м§гҐвбп ваЁўЁ «м­л©"
	" ­г«Ґў®© Є«оз.\n"
"    /C<д ©«> - § ¤ Ґв д ©« б в Ў«ЁжҐ© § ¬Ґ­"
	" ¤«Ё­®© - 256 Ё«Ё 1024 Ў ©в \n"
"             Џ® 㬮«з ­Ёо ЁбЇ®«м§гҐвбп ваЁўЁ «м­ п"
	" в Ў«Ёж  § ¬Ґ­.\n"
"    /SXXXX - § ¤ Ґв бЁ­еа®Ї®бл«Єг, §¤Ґбм XXXX - "
	"8(Ё«Ё ¬Ґ­миҐ)-а §ап¤­®Ґ\n"
"             16-аЁз­®Ґ 楫®Ґ ЎҐ§ §­ Є  Ё ¬ аЄҐа®ў"
	" ®б­®ў ­Ёп\n"
"             Џ® 㬮«з ­Ёо ЁбЇ®«м§гҐвбп ­г«Ґў п"
	" бЁ­еа®Ї®бл«Є .\n"
"    /L - ЇаҐ¤ЇЁблў Ґв ўлў®¤Ёвм ­®¬Ґа  Ї а®«Ґ© ў "
	"бЇЁбЄҐ ўла Ў влў Ґ¬ле Ї а®«Ґ©\n"
"  Є®­дЁЈга жЁп - д ©« ®ЇЁб ­Ёп Є®­дЁЈга жЁЁ Ї а®«Ґ©\n"
"  Є®«ЁзҐбвў®   - Є®«ЁзҐбвў® ўла Ў влў Ґ¬ле Ї а®«Ґ©\n"
"  १г«мв в    - д ©« ¤«п § ЇЁбЁ бЈҐ­ҐаЁа®ў ­­ле Ї а®«Ґ©\n"
  ),-1;
  else
  {
// ќв®в жЁЄ« бва®Ёв ваЁўЁ «м­го в Ў«Ёжг § ¬Ґ­
// “¤ «ЁвҐ ҐЈ®, Ґб«Ё Ўг¤ҐвҐ Ё­ЁжЁ «Ё§Ёа®ў вм  chtab
    for (i=0; i<1024; i++) chtab[i]=i;

// жЁЄ« Їа®б¬®ва  Є®¬ ­¤­®© бва®ЄЁ
    while (*++argv)
      if (
	(code=(**argv=='/' ? ProcessKey : ProcessItem)
		   (*argv))   != O_K_)
	break;
    return ( code == O_K_ && ParmCount < 2 ) ?
      SignalError(errInsufficientParm, NULL):
      code;
  }
}

// ®Ўа Ў®вЄ  Є«о祩 [/x...] Є®¬ ­¤­®© бва®ЄЁ

errList	ProcessKey (char *parameter)
{
  char *c;

  ++parameter;
  switch (toupper(*(parameter++)))// ўлЎ®а Ї® ЎгЄўҐ
  {
  case 'K':
    if(loadKey(parameter) != O_K_)
      return errBadKey;
    break;
  case 'C':
    if (loadCht(parameter) != O_K_)
      return errBadXCHT;
    break;
  case 'S':
    if (strlen(parameter)==0 ||
       (Synchro[0]=strtoul(parameter,&c,16),*c))
      return SignalError(errBadSynchro,parameter);
    break;
  case 'L':
    PrintPWNo = 1;
    break;
  default:
    return  SignalError(errInvalidFlag,parameter-2);
  }
  return O_K_;
}

// ®Ўа Ў®вЄ  ­ҐЄ«о祢ле Ї а ¬Ґва®ў Є®¬ ­¤­®© бва®ЄЁ

errList	ProcessItem (char *parameter)
{
  return
    ++ParmCount >= 3 ?
    SignalError (errTooManyParm, parameter) :
    processor[ParmCount](parameter);
}

// ‡ Јаг§Є  в Ў«Ёжл § ¬Ґ­

errList loadCht(char *ChtFile)
{
  int	handle;
  unsigned long  FileSize;
  unsigned char  buffer[128];

  if ((handle=open(ChtFile,O_RDONLY))==-1 ||
       ((FileSize=filelength(handle)) != 128 &&
			      FileSize != 1024) ||
    read(handle,
      FileSize==128 ? buffer : chtab,FileSize)==-1)
    return errBadKey;

  if (FileSize == 128) ExpCht(buffer,chtab);
  close(handle);
  return O_K_;
}

// ‡ Јаг§Є  Є«оз 

errList loadKey(char *KeyFile)
{
  int	handle,FileSize;
  unsigned char  buffer[32];

  if ((handle=open(KeyFile,O_RDONLY))==-1 ||
       ((FileSize=filelength(handle)) != 32 &&
			      FileSize != 128) ||
	  read(handle, FileSize==32 ?
            (void*) buffer : (void*) Key, FileSize)==-1)
    return errBadKey;

  if (FileSize==32) ExpKey31(buffer,Key);
  close(handle);
  return O_K_;
}

// ‚л¤ з  б®®ЎйҐ­Ёп ®Ў ®иЁЎЄҐ

errList	SignalError(errList errType, char *errPlace)
{
  char *errText[]=
  {
  "ЌҐўҐа­л© д« Ј ўл§®ў  Їа®Ја ¬¬л - %s\n",
  "ЌҐўҐа­® § ¤ ­  бЁ­еа®Ї®бл«Є  - %s\n",
  "ЋвбгвбвўгҐв ®¤Ё­ Ё§ ­Ґ®Ўе®¤Ё¬ле Ї а ¬Ґва®ў\n",
  "‹Ёи­Ё© ­ҐЄ«о祢®© Ї а ¬Ґва ўл§®ў  - \"%s\"\n",
  "ЌҐўҐа­® § ¤ ­ д ©« б Ёб室­л¬ Є«о箬 - %s\n",
  "ЌҐўҐа­® § ¤ ­ д ©« б в Ў«ЁжҐ© § ¬Ґ­ - %s\n",
  "ЌҐЇ®­пв­л© н«Ґ¬Ґ­в ў¬Ґбв® ¤«Ё­л Є«оз  - %s\n",
  "‡ ¤ ­  ­г«Ґў п ¤«Ё­  Є«оз , зв® ­Ґ¤®ЇгбвЁ¬®\n",
  "ЋиЁЎЄ  ЇаЁ ®вЄалвЁЁ/§ ЇЁбЁ д ©«  б Є«о箬 - %s\n",
  "—Ёб«® Ї а®«Ґ© ¤®«¦­® Ўлвм ­Ґ­г«Ґўл¬ ¤ҐбпвЁз­л¬ 楫л¬"
	" ЎҐ§ §­ Є  - \"%s\"\n",

  "ЏаҐўл襭® ЇаҐ¤Ґ«м­®Ґ зЁб«® ЈагЇЇ бЁ¬ў®«®ў ў д ©«Ґ"
	" Є®­дЁЈга жЁЁ %s\n",
  "ЋиЁЎЄ  ЇаЁ а Ў®вҐ б д ©«®¬ Є®­дЁЈга жЁЁ - %s\n",
  "ЌҐўҐа­л© д®а¬ в д ©«  Є®­дЁЈга жЁЁ - %s\n",
  "ЌҐўҐа­л© бЁ¬ў®« ў бва®ЄҐ Ї а ¬Ґва®ў ў д ©«Ґ %s\n",
  "ЌҐзҐв­®Ґ зЁб«® зЁб«®ўле н«Ґ¬Ґ­в®ў ў бва®ЄҐ ®ЇЁб ­Ёп\n",
  "ЏаҐўл襭® ЇаҐ¤Ґ«м­®Ґ зЁб«® ЈагЇЇ  «д ўЁв®ў ў д ©«Ґ"
	" Є®­дЁЈга жЁЁ %s\n",
  "‘бл«Є  ­  ®вбгвбвўгойЁ©  «д ўЁв ў д ©«Ґ %s\n",
  "ЋиЁЎЄ  ЇаЁ а Ў®вҐ б д ©«®¬ Ї а®«Ґ© - %s\n"
  };
  printf(errText[errType-1],errPlace);
  return errType;
}
//--------------------------------------------------------

// Џ®бв஥­ЁҐ в Ў«Ёжл Є®­дЁЈга жЁЁ Ї а®«Ґ©
// Ї« ­Ёа㥬 п ¤®а Ў®вЄ :  ЇаЁ § ¤ ­ЁЁ Ё¬Ґ­Ё д ©«  ЎҐ§
// а биЁаҐ­Ёп ¤®«¦­® ¤®Ў ў«пвмбп а биЁаҐ­ЁҐ .pwc

errList BuildPwsParmTable (char *PWCFileName)
{
  FILE  *PWCFile;	// д ©« б ®ЇЁб ­ЁҐ¬ Є®­дЁЈга жЁЁ
  int	c,n;		// ўбЇ®¬®Ј вҐ«м­лҐ ЇҐаҐ¬Ґ­­лҐ
  int   AlphabetNumber; // бзҐвзЁЄ  «д ўЁв®ў
  char  *b;		// гЄ § вҐ«м ­  Ў ©в ў ЎгдҐаҐ


  if ( (PWCFile= fopen(PWCFileName,"rt")) == NULL)
    return SignalError (errPWCFileError, PWCFileName);

			// Їа®ЇгбЄ Ґ¬ бва®ЄЁ Є®¬¬Ґ­в аЁҐў
  while ( c=getc(PWCFile),
	  c == ' ' || c == ';' || c == '\t' || c == '\n' )
    while ( c != '\n' && c != EOF )
      c=getc(PWCFile);

			// ўў®¤ зЁб«®ўле Ї а ¬Ґва®ў Ї а®«Ґ©
  for ( ItemCount = 0; n = c-'0', isdigit(c) ; ItemCount++ )
  {
    if ( ItemCount > MAX_GROUP * 2 )
      return SignalError ( errItemCountExceed, PWCFileName );
    while ( c=getc(PWCFile), isdigit(c) )
      n *= 10, n += c-'0';
    item.seq [ItemCount] = n;
    while ( c==' ' || c== '\t' )
      c = getc(PWCFile);
  }

			// ўбваҐвЁ«бп бЁ¬ў®« - вҐа¬Ё­ в®а
  switch ( c )
  {
    case ';':
      while ( c != '\n' && c != EOF )
	c=getc(PWCFile);
      if ( c==EOF )
	goto caseEOF;

    case '\n':
      break;

    case EOF: caseEOF:
      return SignalError (errBadPWCFileFormat, PWCFileName);

    default:
      return SignalError (errBadPWCNumberItem, PWCFileName);
  }

			// Їа®ўҐаЄ  Є®а४⭮бвЁ Ї а ¬Ґва®ў
  if ( ItemCount == 1)  // ¤«п Ґ¤Ё­б⢥­­®© ЈагЇЇл ЁбЄ«о祭ЁҐ
  {
    ItemCount++ ;
    item.stru->SymbolNo = item.stru->AlphaNo;
    item.stru->AlphaNo  = 1;

  }
  if ( ItemCount & 1)   // ¤®«¦­® Ўлвм зҐв­®Ґ зЁб«® н«-в®ў
    return SignalError (errOddPWCItemNumber, PWCFileName);
  ItemCount >>= 1;      // зЁб«® ЈагЇЇ ў¤ў®Ґ ¬Ґ­миҐ

			// бзЁвлў Ґ¬  «д ўЁвл
  for ( AlphabetNumber=0, b=buffer; c=getc(PWCFile), c != EOF ;)
  {
    if ( c != ' ' && c != ';' && c != '\t' && c != '\n' )
    {
      if ( AlphabetNumber >= MAX_ALPHABET )
	return SignalError ( errAlphabetCountExceed, PWCFileName );
      Alphabet[AlphabetNumber].power = 0;
      Alphabet[AlphabetNumber].alpha = b;
      do
      {
	*(b++) = c;
	c=getc(PWCFile);
	Alphabet[AlphabetNumber].power++;
      }
      while ( c!=' ' && c!=';' && c!='\t' && c!='\n' && c!=EOF );
      AlphabetNumber++;
      *(b++) = '\000';
    }
    while ( c != '\n' && c != EOF )
      c=getc(PWCFile);
  }
			// Їа®ўҐа塞 Є®а४⭮бвм ®ЇЁб ­Ёп  «д ўЁв®ў
  for ( n=0; n < ItemCount; n++)
    if ( item.stru[n].AlphaNo > AlphabetNumber )
      return SignalError ( errInvalidAlphabetRef, PWCFileName );

  if (fclose(PWCFile))
    return SignalError (errPWCFileError, PWCFileName);
  else
    return O_K_;
}

// ”г­ЄжЁп ўў®¤  зЁб«  Ї а®«Ґ©

errList GetPWNumber (char *StringNumber)
{
  if ( ! isdigit ( *StringNumber ) )
    return SignalError (errBadPWNumber, StringNumber);
  for (PWNeed=0; isdigit(*StringNumber); StringNumber++)
    PWNeed *= 10, PWNeed += *StringNumber - '0';
  return *StringNumber ?
    SignalError (errBadPWNumber, StringNumber) :
    O_K_;
}

// ”г­ЄжЁп Ї®«г祭Ёп Ё ўлў®¤  бЇЁбЄ  Ї а®«Ґ©

errList makePWs (char *TargetFileName)
{
  unsigned int PWCount,GroupNo,ByteLimit,power,i;
  unsigned char b;      // ЈҐ­ҐаЁагҐ¬л© Ў ©в
  FILE	*PWsFile;	// д ©« Ї а®«Ґ©

  if ( (PWsFile= fopen(TargetFileName,"wt")) == NULL)
    return SignalError (errPWCFileError, TargetFileName);

  for ( PWCount=1; PWCount <= PWNeed; PWCount++)
  {
    if (PrintPWNo)	// ЇҐз вм ­®¬Ґа  Ї а®«п, Ґб«Ё ­ ¤®
      fprintf (PWsFile, "%4u ", PWCount);
    for ( GroupNo = 0; GroupNo < ItemCount; GroupNo++)
    {
      power = Alphabet[item.stru[GroupNo].AlphaNo-1].power;
      ByteLimit = (256 / power) * power;
      for ( i=0; i<item.stru[GroupNo].SymbolNo; i++ )
      {
	do
	  b = getRandomByte ();
	while ( b > ByteLimit );
	putc (Alphabet[item.stru[GroupNo].AlphaNo-1].alpha[b%power],
	      PWsFile);
      }
    }
    putc ('\n', PWsFile);
  }
  if (fclose(PWsFile))
    return SignalError (errPWCFileError, TargetFileName);
  else
    return O_K_;
}

// Џ®«г祭ЁҐ ®¤­®Ј® Ў ©в  б ¤ взЁЄ  б«гз ©­ле Ў ©в®ў

unsigned char getRandomByte (void)
{
# define RANDOM_BLOCK_SIZE 8

  unsigned char static buffer[RANDOM_BLOCK_SIZE];
  static unsigned char *p = buffer + RANDOM_BLOCK_SIZE;

  if ( p == buffer + RANDOM_BLOCK_SIZE )
    gamme ( Key, chtab, Synchro, p=buffer, 1);
  return *(p++);
}
Соседние файлы в папке GOST_UTI