-
Notifications
You must be signed in to change notification settings - Fork 0
/
etausencr.c
223 lines (209 loc) · 7.89 KB
/
etausencr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/************************************************************************/
/* etausencr.c Version 1.0.0 */
/* Encrypt an input stream with the etaus algorithm */
/* Copyright (C) 2016 aquila62 at github.com */
/* This program is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License as */
/* published by the Free Software Foundation; either version 2 of */
/* the License, or (at your option) any later version. */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to: */
/* Free Software Foundation, Inc. */
/* 59 Temple Place - Suite 330 */
/* Boston, MA 02111-1307, USA. */
/************************************************************************/
/**********************************************************/
/* This program initializes the etaus random number */
/* generator state by overriding its state with RANDU. */
/* RANDU is initialized by the CRC of the input password */
/* parameter. */
/* RANDU is a weak random number generator, but it is */
/* satisfactory enough for the encryption program to */
/* pass the dieharder random number test suite. */
/* Once initialized with RANDU, etaus is warmed up */
/* to minimize the weakness behind its initialization */
/* routine. */
/**********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "etaus.h"
/* length of input/output buffer */
#define BUFSZ (1024*1024)
/* RANDU algorithm */
#define RANDU (seed = seed * 65539)
/* print the command syntax */
void putstx(char *pgm)
{
fprintf(stderr,"Usage: %s password\n", pgm);
fprintf(stderr,"Where password is an ASCII string\n");
fprintf(stderr,"Example: %s abcd\n", pgm);
fprintf(stderr,"Example: %s \"abcd efgh\"\n", pgm);
fprintf(stderr,"Example: %s 'abcd efgh'\n", pgm);
exit(1);
} /* putstx */
/**************************************/
/* read one block of input from stdin */
/* return the length of the block */
/* a partial block may be returned */
/* maximum blocksize is BUFSZ */
/* input may be binary data */
/**************************************/
int getblk(unsigned char *blk)
{
int len;
len = read(0,blk,BUFSZ);
if (!len) return(EOF);
if (len < 0)
{
fprintf(stderr,"getblk: read error\n");
exit(1);
} /* read error */
return(len);
} /* getblk */
/***************************************/
/* write one block of output to stdout */
/* maximum blocksize is determined by */
/* the calling routine. */
/* output is binary data */
/***************************************/
void putblk(unsigned char *blk, int len)
{
int rslt;
rslt = write(1,blk,len);
if (rslt != len)
{
fprintf(stderr,"putblk: write error\n");
exit(1);
} /* write error */
} /* putblk */
/* Generate the CRC32C table */
void bldtbl(unsigned int *table)
{
int j;
unsigned int byte;
unsigned int crc;
unsigned int mask;
for (byte = 0; byte <= 255; byte++)
{
crc = byte;
for (j = 7; j >= 0; j--)
{ // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
} /* for each bit in byte */
table[byte] = crc;
} /* for each of 256 bytes in table */
} /* bldtbl */
/* Calculate the 32-bit CRC of a message */
unsigned int crc32c(unsigned char *message, unsigned int *table)
{
int i;
unsigned int byte, crc;
i = 0;
crc = 0xFFFFFFFF;
while ((byte = message[i]) != 0) {
crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
i = i + 1;
}
return ~crc;
} /* crc32c */
int main(int argc, char **argv)
{
int i; /* loop counter */
int pswlen; /* length of password parameter */
unsigned int seed; /* RANDU seed */
unsigned int tbl[256]; /* CRC table */
unsigned int *statep; /* pointer into et->state */
unsigned int *stateq; /* pointer for end of et->state */
unsigned char psw[128]; /* password text */
unsigned char *buf; /* input/output buffer */
etfmt *et; /* etaus RNG structure */
if (argc != 2) putstx(*argv); /* must have password parameter */
/*******************************/
/* validate length of password */
/*******************************/
pswlen = strlen(*(argv+1)); /* validate length of password */
if (pswlen > 64)
{
fprintf(stderr,"main: password overflow\n");
fprintf(stderr,"password is 1-64 bytes long\n");
putstx(*argv);
} /* password overflow */
strcpy((char *) psw,*(argv+1)); /* save password */
/*****************************************************/
/* Alloocate memory for the input/output buffer */
/*****************************************************/
buf = (unsigned char *) malloc(BUFSZ);
if (buf == NULL)
{
fprintf(stderr,"main: out of memory "
"allocating buf\n");
exit(1);
} /* out of memory */
/*****************************************************/
/* initialize random number generator etaus */
/* initialize the CRC table */
/* calculate the CRC of the password parameter */
/* initialize the RANDU seed to this CRC */
/*****************************************************/
et = (etfmt *) etausinit(); /* initialize etaus RNG */
bldtbl(tbl); /* initialize CRC table */
seed = crc32c(psw,tbl);
/*****************************************************/
/* warm up the RANDU random number generator */
/*****************************************************/
i = 256;
while (i--) RANDU;
/*****************************************************/
/* override the state of the random number generator */
/* with the password parameter converted into */
/* 32-bit unsigned integers. */
/*****************************************************/
et->s1 = RANDU;
et->s2 = RANDU;
et->s3 = RANDU;
et->out = RANDU;
et->prev = RANDU;
et->pprev = RANDU;
statep = (unsigned int *) et->state;
stateq = (unsigned int *) et->state + 1024;
while (statep < stateq)
{
*statep++ = RANDU;
} /* for each state in et->state array */
/*****************************************************/
/* warm up the etaus random number generator */
/*****************************************************/
i = 2048;
while (i--) etaus(et);
/*****************************************************/
/* encrypt the stdin data stream */
/* write encrypted data to stdout */
/* loop terminated by end of input stream */
/*****************************************************/
while (1)
{
int blklen;
unsigned char *p,*q;
blklen = getblk(buf);
if (blklen == EOF) break;
p = (unsigned char *) buf;
q = (unsigned char *) buf + blklen;
while (p < q)
{
*p = *p ^ etauspwr(et,8);
p++;
} /* for each byte in the buffer */
putblk(buf,blklen);
} /* for each block encrypted */
free(buf);
free(et->state);
free(et);
return(0);
} /* main */