📄 dlock.cpp
字号:
/* DLOCK.CPP -- Diamond Encryption Demonstration program.
This program is used to test and validate the implementation of the
Diamond and Diamond Lite encryption algorithms in software. It can
also encrypt or decrypt files using ten round Diamond in cyphertext
feedback mode and a key from a command line parameter, environment
variable, or keyboard.
There are lots of ways to improve upon this program: (1) add key
management, (2) use more clever chaining methods, (3) add header
information to the encrypted file to allow the decryption program to
automatically determine the proper algorithm(s) needed to decrypt and
decompress, (4) add data compression and/or noise addition, (5)
improve the user interface, (6) allow selection of other algorithms,
and (7) probably more that I haven't mentioned. In spite of the lack
of the above possible improvements, I think this program is useful to
(1) demonstrate and test Diamond and/or Diamond Lite implementations,
and (2) encrypt some data where manual key management is acceptable
and the file length must be preserved.
DLOCK.CPP is Copyright (C) 1994 Michael Paul Johnson.
All rights reserved. No warranty.
This program is free software; you can redistribute it as a and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation version 2,
treating the functions within this program as a library.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You should be aware that the rights granted to you under the above
mentioned license may be restricted or revoked by law. In
particular, you should check the currently valid USA International
Traffic in Arms Regulations (ITAR) to see what export restrictions
may apply. It is your responsibility to determine what legal
requirements pertain to any export or use of this program, and to
comply with all valid laws and treaties that pertain to it.
The author can be reached at m.p.johnson@ieee.org, or at PO BOX 1151,
LONGMONT CO 80502-1151, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#ifdef UNIX
#include <memory.h>
#include <termio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#define O_BINARY 0
#else
#include <conio.h>
#include <io.h>
#include <mem.h>
#endif
#include "def.h"
#include "diamond.h"
#include "crc.h"
#define PATHSIZE 82
#define PASS_SIZE 256
#define CHUNK 16384
/* CHUNK must be a multiple of 16. CHUNK is the number of bytes read from
disk or written to disk at a time when encrypting or decrypting a file. */
static byte encryption_key[32] =
{0xE8, 0x34, 0xFD, 0xB9, 0x33, 0xC5, 0x02, 0x92,
0x3D, 0x92, 0xBC, 0x9E, 0x14, 0x36, 0x8E, 0x70,
0xD4, 0x1C, 0x66, 0xCB, 0xDF, 0x36, 0x15, 0x50,
0x33, 0xA6, 0x6E, 0x07, 0xE6, 0xCC, 0x6D, 0x8D};
static uint keysize; /* Number of bytes of key to use. */
static uint rounds; /* Number of rounds to use with Diamond. */
#ifdef MPJs_Copy
static uint literounds; /* Number of rounds to use with Diamond Lite. */
#endif
static int blocksize; /* Block size=8 for Diamond Lite or 16 for Diamond. */
static byte seed[16] = {0x5A, 0x8D, 0x87, 0x2D, 0x31, 0xEE, 0xDD, 0xE6,
0x3F, 0xC4, 0x6F, 0x6C, 0x36, 0x45, 0x6D, 0x8E};
static byte ciphertext[16];
static byte plaintext[16];
static boolean generate, end_of_file, validate_file, startpass, encryptit,
decryptit, verbose;
static char testfilename[] = "DIAMOND.DAT";
static char infilename[PATHSIZE] = "";
static char outfilename[PATHSIZE] = "";
static byte passphrase[PASS_SIZE];
FILE *f;
#ifdef MPJs_Copy
void generate_test_data(void)
{
int i;
f = fopen(testfilename, "wt");
if (!f)
{
printf("Can't open %s for writing.\n", testfilename);
exit(2);
}
fprintf(f, "# Diamond/Diamond lite validation data file.\n"
"# Format:\n"
"# Everything between # and end of line is a comment.\n"
"# Numbers are all in hexadecimal (using upper case letters).\n"
"# Data sets are in groups of 6 numbers, separated by white space:\n"
"# Block size (10 or 8), rounds, key size, key, plain text, cipher text.\n\n");
rounds = 15;
literounds = 30;
for (keysize = 32; keysize >= 8; keysize--)
{
/* Generate Diamond Lite test data. */
blocksize = 8;
set_diamond_key(encryption_key, keysize, literounds, true, blocksize);
fprintf(f, "%02X %02X %02X ", blocksize, literounds, keysize);
printf("Block size: %02X Rounds: %02X Key size: %02X\n",
blocksize, literounds, keysize);
for (i=0; i < keysize; i++)
fprintf(f, "%02X", encryption_key[i]);
fprintf(f, "\n ");
for (i=0; i < blocksize; i++)
fprintf(f, "%02X", seed[i]);
fprintf(f, " ");
lite_encrypt_block(seed, ciphertext);
lite_decrypt_block(ciphertext, plaintext);
for (i = 0; i < blocksize; i++)
{
fprintf(f, "%02X", ciphertext[i]);
if (plaintext[i] != seed[i])
{
printf("Reversal failure!\n");
fputs("\nReversal failure!", f);
fclose(f);
exit(4);
}
}
fputs("\n", f);
/* Generate Diamond test data. */
blocksize = 16;
set_diamond_key(encryption_key, keysize, rounds, true, blocksize);
fprintf(f, "%02X %02X %02X ", blocksize, rounds, keysize);
printf("Block size: %02X Rounds: %02X Key size: %02X\n",
blocksize, rounds, keysize);
for (i=0; i < keysize; i++)
fprintf(f, "%02X", encryption_key[i]);
fprintf(f, "\n ");
for (i=0; i < blocksize; i++)
fprintf(f, "%02X", seed[i]);
fprintf(f, " ");
diamond_encrypt_block(seed, ciphertext);
diamond_decrypt_block(ciphertext, plaintext);
for (i = 0; i < blocksize; i++)
{
fprintf(f, "%02X", ciphertext[i]);
if (plaintext[i] != seed[i])
{
printf("Reversal failure!\n");
fputs("\nReversal failure!", f);
fclose(f);
exit(4);
}
}
fputs("\n\n", f);
/* Set up for next set of data. */
diamond_encrypt_block(ciphertext, seed);
diamond_encrypt_block(encryption_key, encryption_key);
diamond_encrypt_block(encryption_key+16, encryption_key+16);
rounds -= 3;
if (rounds < 5) rounds += 11;
literounds -= 3;
if (literounds < 4) literounds += 13;
}
fclose(f);
}
#endif
int read_hex_char(void)
{
static int saved_char = 0;
static int white_space = 1;
int ch;
if (saved_char)
{
ch = saved_char;
saved_char = 0;
}
else if (white_space)
{
do /* Skip leading white space and uninteresting characters. */
{
ch = fgetc(f);
if (ch == '#')
{ /* Skip comment line. */
do
{
ch = fgetc(f);
}
while ((ch != EOF) && (ch != '\n') && (ch != '\r'));
}
}
while ((ch != EOF) && ((ch < '0') || (ch > 'F') || ((ch > '9') && (ch < 'A'))));
white_space = 0;
}
else
{
ch = fgetc(f);
if (ch == '#')
{ /* Skip comment line. */
do
{
ch = fgetc(f);
}
while ((ch != EOF) && (ch != '\n') && (ch != '\r'));
}
if ((ch < '0') || (ch > 'F') || ((ch > '9') && (ch < 'A')))
{
ch = 0;
white_space = 1;
}
}
if (ch == EOF)
{
end_of_file = true;
ch = 0;
}
return ch;
}
uint from_hex(int hex_character)
{
hex_character -= '0';
if (hex_character > 9)
hex_character -= 7;
return (uint)hex_character;
}
uint read_uint(void)
{
int ch, i;
uint u;
u = 0;
i = 0;
do
{
ch = read_hex_char();
if (ch)
{
u = (u << 4) + from_hex(ch);
}
if (++i > 5)
{
puts("Unexpected character reading unsigned integer.");
exit(6);
}
}
while (ch && (!end_of_file));
return u;
}
void read_hex_block(byte *dest, uint numbytes)
{
uint u;
int ch;
for (u = 0; u < numbytes; u++)
{
dest[u] = from_hex(read_hex_char());
dest[u] = (dest[u] << 4) + from_hex(read_hex_char());
}
ch = read_hex_char();
if ((ch != 0) && (ch != EOF))
{
puts("Unexpected input.");
exit(7);
}
}
void validate_test_data(void)
{
int i;
end_of_file = false;
f = fopen(testfilename, "rt");
if (!f)
{
printf("Unable to open %s\n", testfilename);
exit(5);
}
while (!end_of_file)
{
blocksize = read_uint();
if (end_of_file) return;
rounds = read_uint();
keysize = read_uint();
read_hex_block(encryption_key, keysize);
read_hex_block(plaintext, blocksize);
read_hex_block(ciphertext, blocksize);
if (blocksize == 8)
{
printf("Testing Diamond Lite");
}
else if (blocksize == 16)
{
printf("Testing Diamond");
}
else
{
puts("Unexected data.");
exit(9);
}
printf(" with %u rounds, %u byte key.\n", rounds, keysize);
set_diamond_key(encryption_key, keysize, rounds, true, blocksize);
if (blocksize == 16)
{
diamond_encrypt_block(plaintext, seed);
for (i=0; i<blocksize; i++)
{
if (seed[i] != ciphertext[i])
{
puts("Encryption error.");
exit(8);
}
}
diamond_decrypt_block(ciphertext, seed);
for (i=0; i<blocksize; i++)
{
if (seed[i] != plaintext[i])
{
puts("Decryption error.");
exit(8);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -