📄 sflcryp.c
字号:
/* ----------------------------------------------------------------<Prolog>-
Name: sflcryp.c
Title: Encryption and decryption functions
Package: Standard Function Library (SFL)
Written: 1996/01/23 iMatix SFL project team <sfl@imatix.com>
Revised: 1997/12/10
Copyright: Copyright (c) 1996-2000 iMatix Corporation
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>-*/
#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.
---------------------------------------------------------------------[>]-*/
Bool
crypt_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.
---------------------------------------------------------------------[>]-*/
Bool
crypt_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 Bool
crypt_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 void
expand_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 void
idea (dbyte *dataIn, dbyte *dataOut, dbyte *key)
{
qbyte
round,
x0, x1, x2, x3,
t0, t1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -