📄 sflcryp.c
字号:
/* ----------------------------------------------------------------<Prolog>- Name: sflcryp.c Title: Encryption and decryption functions Package: Standard Function Library (SFL) Written: 96/01/23 iMatix SFL project team <sfl@imatix.com> Revised: 97/12/10 Copyright: Copyright (c) 1991-97 iMatix Synopsis: The encryption/decryption functions were based on the cryptosystem library by Andrew Brown <asb@cs.nott.ac.uk>, cleaned-up for portability. Thanks for a great package. IDEA is registered as the international patent WO 91/18459 "Device for Converting a Digital Block and the Use thereof". For commercial use of IDEA, you should contact: ASCOM TECH AG Freiburgstrasse 370 CH-3018 Bern, Switzerland Alberto Squassabia <alsq@alsqhpw.cnd.hp.com> corrected the MDC code to fix word-alignment problems. License: This is free software; you can redistribute it and/or modify it under the terms of the SFL License Agreement as provided in the file LICENSE.TXT. This software is distributed in the hope that it will be useful, but without any warranty. ------------------------------------------------------------------</Prolog>-*//* $Id: sflcryp.c,v 1.6 1998/12/28 09:34:49 sas Exp $ */#define DEFINE_CRYPT_TABLES#include "prelude.h" /* Universal header file */#include "sflcryp.h" /* Prototypes for functions *//*- Local function prototypes -----------------------------------------------*/static void xor_crypt (byte *buffer, const byte *key);static Bool crypt_data (byte *buffer, word buffer_size, int algorithm, const byte *key, Bool encrypt);/*- IDEA definitions --------------------------------------------------------*/static qbyte Mul (qbyte a, qbyte b);static dbyte MulInv (dbyte x);static void idea (dbyte *dataIn, dbyte *dataOut, dbyte *key);static void invert_idea_key (dbyte *key, dbyte *invKey);static void expand_user_key (dbyte *userKey, dbyte *key);#define mulMod 0x10001L /* 2**16 + 1 */#define addMod 0x10000L /* 2**16 */#define ones 0xFFFF /* 2**16 - 1 */#define nofKeyPerRound 6 /* Number of used keys per round */#define nofRound 8 /* Number of rounds */#define dataSize 8 /* 8 bytes = 64 bits */#define dataLen 4#define keySize 104 /* 104 bytes = 832 bits */#define keyLen 52#define userKeySize 16 /* 16 bytes = 128 bits */#define userKeyLen 8#define data_t(v) dbyte v[dataLen]#define key_t(v) dbyte v[keyLen]#define userkey_t(v) dbyte v[userKeyLen]/*- MDC definitions ---------------------------------------------------------*/static void mdc (qbyte *out1, qbyte *out2, qbyte *in1, qbyte *in2, qbyte *key1, qbyte *key2);static void Transform (qbyte *buffer, qbyte *in);static void mdc_encrypt (qbyte *in, qbyte *out, qbyte *key);static void mdc_decrypt (qbyte *in, qbyte *out, qbyte *key);/* F, G, H and I are the basic MD5 functions */#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))#define H(x, y, z) ((x) ^ (y) ^ (z))#define I(x, y, z) ((y) ^ ((x) | (~z)))/* Rotate x left n bits */#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))/* FF, GG, HH, and II are transformations for rounds 1, 2, 3, and 4 *//* Rotation is separate from addition to prevent recomputation */#define FF(a, b, c, d, x, s, ac) { \ (a) += F((b), (c), (d)) + (x) + (qbyte)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \}#define GG(a, b, c, d, x, s, ac) { \ (a) += G((b), (c), (d)) + (x) + (qbyte)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \}#define HH(a, b, c, d, x, s, ac) { \ (a) += H((b), (c), (d)) + (x) + (qbyte)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \}#define II(a, b, c, d, x, s, ac) { \ (a) += I((b), (c), (d)) + (x) + (qbyte)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \}/* Initial values for the MD5 Transform hash function */static const qbyte ihash[4] = { 0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L };/*- DES definitions ---------------------------------------------------------*/typedef byte des_cblock [8];typedef struct des_ks_struct{ union { des_cblock _; /* Make sure things are correct */ qbyte pad[2]; /* on systems with 8 byte longs */ } ks;# define _ ks._} des_key_schedule [16];static int des_encrypt (qbyte *input, qbyte *output, des_key_schedule *ks, int encrypt);static int des_set_key (des_cblock *key, des_key_schedule *schedule);static int des_ecb_encrypt (des_cblock *input, des_cblock *output, des_key_schedule *ks, int encrypt);static int des_key_sched (des_cblock *key, des_key_schedule *schedule);/* ---------------------------------------------------------------------[<]- Function: crypt_encode Synopsis: Encrypt a buffer with the specified algorithm and specified key. Returns TRUE if the buffer is encrypted sucessfully. The buffer is encrypted in-place. The algorithm can be one of: <Table> CRYPT_IDEA Use IDEA encryption. CRYPT_MDC Use MDC encryption. CRYPT_DES Use DES encryption. CRYPT_XOR Use XOR encryption. </Table> The minimum buffer size, and key size depends on the algorithm: <Table> CRYPT_IDEA Buffer is at least 8 bytes long, key is 16 bytes. CRYPT_MDC Buffer is at least 8 bytes long, key is 8 bytes. CRYPT_DES Buffer is at least 32 bytes long, key is 16 bytes. CRYPT_XOR Buffer is at least 16 bytes long, key is 16 bytes. </Table> Use crypt_decode() with the same algorithm and key to decrypt the buffer. The buffer size must be a multiple of the minimum size shown above. If you specify a buffer size of zero the function does nothing but returns TRUE. For portability, the buffer size is limited to 64k. ---------------------------------------------------------------------[>]-*/Boolcrypt_encode ( byte *buffer, /* Data to encrypt, in-place */ word buffer_size, /* Amount of data to encrypt */ int algorithm, /* What type of encryption */ const byte *key) /* Encryption key */{ return (crypt_data (buffer, buffer_size, algorithm, key, TRUE));}/* ---------------------------------------------------------------------[<]- Function: crypt_decode Synopsis: Decrypt a buffer that was produced by crypt_encode(). You must (obviously, I reckon) use the same algorithm and key as was used to encrypt the data. Returns TRUE if the buffer is decrypted okay. The buffer is encrypted in-place. The algorithm can be one of: <Table> CRYPT_IDEA Use IDEA encryption. CRYPT_MDC Use MDC encryption. CRYPT_DES Use DES encryption. CRYPT_XOR Use XOR encryption. </Table> The minimum buffer size, and key size depends on the algorithm: <Table> CRYPT_IDEA Buffer is at least 8 bytes long, key is 16 bytes. CRYPT_MDC Buffer is at least 8 bytes long, key is 8 bytes. CRYPT_DES Buffer is at least 32 bytes long, key is 16 bytes. CRYPT_XOR Buffer is at least 16 bytes long, key is 16 bytes. </Table> The buffer size must be a multiple of the minimum size shown above. If you specify a buffer size of zero the function does nothing but returns TRUE. ---------------------------------------------------------------------[>]-*/Boolcrypt_decode ( byte *buffer, /* Data to decrypt, in-place */ word buffer_size, /* Amount of data to decrypt */ int algorithm, /* What type of decryption */ const byte *key) /* Decryption key */{ return (crypt_data (buffer, buffer_size, algorithm, key, FALSE));}/* ------------------------------------------------------------------------- Function: crypt_data - internal Synopsis: -------------------------------------------------------------------------*/static Boolcrypt_data ( byte *buffer, /* Data to process, in-place */ word buffer_size, /* Amount of data to process */ int algorithm, /* What type of encryption */ const byte *key, /* Encryption key */ Bool encrypt) /* TRUE=encrypt, FALSE=decrypt */{ word index, nbr_blocks; byte block [CRYPT_MAX_BLOCK_SIZE]; des_key_schedule ks; qbyte aligned_block [CRYPT_MAX_BLOCK_SIZE / 4]; static qbyte aligned_intkey [keySize / 4]; static byte *intkey = (byte *) aligned_intkey; ASSERT (buffer); ASSERT (key); ASSERT (algorithm >= 0 && algorithm < CRYPT_TOP); if (buffer_size == 0) /* Empty buffer is a special case */ return (TRUE); nbr_blocks = buffer_size / crypt_block_size [algorithm]; if ((nbr_blocks * crypt_block_size [algorithm]) != buffer_size) return (FALSE); /* We want whole number of blocks */ if (algorithm == CRYPT_IDEA) { expand_user_key ((dbyte *) key, (dbyte *) intkey); /* Invert the key for decryption */ if (!encrypt) invert_idea_key ((dbyte *) intkey, (dbyte *) intkey); for (index = 0; index < buffer_size; index += 8) { idea ((dbyte *) (buffer + index), (dbyte *) block, (dbyte *) intkey); memcpy ((buffer + index), block, 8); } } else if (algorithm == CRYPT_MDC) { ASSERT (buffer_size % 4 == 0); buffer_size /= 4; for (index = 0; index < buffer_size; index += 8) { if (encrypt) mdc_encrypt ((qbyte *) buffer + index, aligned_block, aligned_intkey); else mdc_decrypt ((qbyte *) buffer + index, aligned_block, aligned_intkey);// memcpy ((qbyte *) buffer + index, block, 32); } } else if (algorithm == CRYPT_DES) { des_key_sched ((des_cblock *) key, (des_key_schedule *) ks); for (index = 0; index < buffer_size; index += 8) des_ecb_encrypt ((des_cblock *) (buffer + index), (des_cblock *) (buffer + index), (des_key_schedule *) ks, encrypt); } else if (algorithm == CRYPT_XOR) { for (index = 0; index < buffer_size; index += 16) xor_crypt (buffer + index, key); } return (TRUE); /* So far so good */}/* ------------------------------------------------------------------------- Function: expand_user_key - internal Synopsis: expand user key of 128 bits to full key of 832 bits -------------------------------------------------------------------------*/static voidexpand_user_key (dbyte *userKey, dbyte *key){ register int index; for (index = 0; index < userKeyLen; index++) key [index] = userKey [index]; /* Shifts */ for (index = userKeyLen; index < keyLen; index++) { if ((index + 2) % 8 == 0) /* For key [14], key [22], .. */ key [index] = ((key [index - 7] & 127) << 9) ^ (key [index - 14] >> 7); else if ((index + 1) % 8 == 0) /* For key [15], key [23], .. */ key [index] = ((key [index - 15] & 127) << 9) ^ (key [index - 14] >> 7); else key [index] = ((key [index - 7] & 127) << 9) ^ (key [index - 6] >> 7); }}/* ------------------------------------------------------------------------- Function: idea - internal Synopsis: encryption and decryption algorithm IDEA -------------------------------------------------------------------------*/static voididea (dbyte *dataIn, dbyte *dataOut, dbyte *key){ qbyte round, x0, x1, x2, x3, t0, t1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -