📄 dlock.c
字号:
/* DLOCK.CPP -- Diamond Encryption Demonstration program.This program is used to test and validate the implementation of theDiamond and Diamond Lite encryption algorithms in software. It canalso encrypt or decrypt files using ten round Diamond in cyphertextfeedback mode and a key from a command line parameter, environmentvariable, or keyboard.There are lots of ways to improve upon this program: (1) add keymanagement, (2) use more clever chaining methods, (3) add headerinformation to the encrypted file to allow the decryption program toautomatically determine the proper algorithm(s) needed to decrypt anddecompress, (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 lackof 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 acceptableand 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/ormodify it under the terms of the GNU Library General PublicLicense 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the FreeSoftware Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.You should be aware that the rights granted to you under the abovementioned license may be restricted or revoked by law. Inparticular, you should check the currently valid USA InternationalTraffic in Arms Regulations (ITAR) to see what export restrictionsmay apply. It is your responsibility to determine what legalrequirements pertain to any export or use of this program, and tocomply 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 fromdisk 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_Copystatic uint literounds; /* Number of rounds to use with Diamond Lite. */#endifstatic 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_Copyvoid 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); }#endifint 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 + -