⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflcryp.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  ----------------------------------------------------------------<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 + -