Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Документация по криптоалгоритмам / GOST-28147-89 / GOST_UTI / MAKEPSWS
.C/*----------------------------------------------------------
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