常见的MAC算法PBOC_3DES_MAC,C语言实现(高效率,支持单片机)

本文详细介绍了DES(Data Encryption Standard)加密算法的实现过程,包括关键函数如transpose、rotate_l、ff等,并给出了3DES的加密和解密函数。此外,还提供了3DES MAC(消息认证码)的计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <string.h>
typedef unsigned char uint8_t; //无符号8位数

const uint8_t initial_tr[64] =
    {
        57, 49, 41, 33, 25, 17, 9, 1,
        59, 51, 43, 35, 27, 19, 11, 3,
        61, 53, 45, 37, 29, 21, 13, 5,
        63, 55, 47, 39, 31, 23, 15, 7,
        56, 48, 40, 32, 24, 16, 8, 0,
        58, 50, 42, 34, 26, 18, 10, 2,
        60, 52, 44, 36, 28, 20, 12, 4,
        62, 54, 46, 38, 30, 22, 14, 6};
const uint8_t final_tr[64] =
    {
        39, 7, 47, 15, 55, 23, 63, 31,
        38, 6, 46, 14, 54, 22, 62, 30,
        37, 5, 45, 13, 53, 21, 61, 29,
        36, 4, 44, 12, 52, 20, 60, 28,
        35, 3, 43, 11, 51, 19, 59, 27,
        34, 2, 42, 10, 50, 18, 58, 26,
        33, 1, 41, 9, 49, 17, 57, 25,
        32, 0, 40, 8, 48, 16, 56, 24};
const uint8_t swap[64] =
    {
        33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48,
        49, 50, 51, 52, 53, 54, 55, 56,
        57, 58, 59, 60, 61, 62, 63, 64,
        1, 2, 3, 4, 5, 6, 7, 8,
        9, 10, 11, 12, 13, 14, 15, 16,
        17, 18, 19, 20, 21, 22, 23, 24,
        25, 26, 27, 28, 29, 30, 31, 32};
const uint8_t key_tr1[56] =
    {
        56, 48, 40, 32, 24, 16, 8,
        0, 57, 49, 41, 33, 25, 17,
        9, 1, 58, 50, 42, 34, 26,
        18, 10, 2, 59, 51, 43, 35,
        62, 54, 46, 38, 30, 22, 14,
        6, 61, 53, 45, 37, 29, 21,
        13, 5, 60, 52, 44, 36, 28,
        20, 12, 4, 27, 19, 11, 3};
const uint8_t key_tr2[64] =
    {
        0, 0, 13, 4, 16, 10, 23, 0,
        0, 0, 2, 9, 27, 14, 5, 20,
        0, 0, 22, 7, 18, 11, 3, 25,
        0, 0, 15, 1, 6, 26, 19, 12,
        0, 0, 40, 54, 51, 30, 36, 46,
        0, 0, 29, 47, 39, 50, 44, 32,
        0, 0, 43, 52, 48, 38, 55, 33,
        0, 0, 45, 31, 41, 49, 35, 28};
const uint8_t etr[64] =
    {
        0, 0, 31, 4, 0, 1, 2, 3,
        0, 0, 3, 8, 4, 5, 6, 7,
        0, 0, 7, 12, 8, 9, 10, 11,
        0, 0, 11, 16, 12, 13, 14, 15,
        0, 0, 15, 20, 16, 17, 18, 19,
        0, 0, 19, 24, 20, 21, 22, 23,
        0, 0, 23, 28, 24, 25, 26, 27,
        0, 0, 27, 0, 28, 29, 30, 31};
const uint8_t ptr[32] =
    {
        31, 14, 39, 44, 60, 23, 55, 36,
        4, 30, 46, 53, 12, 37, 62, 21,
        5, 15, 47, 29, 63, 54, 6, 20,
        38, 28, 61, 13, 45, 22, 7, 52};
const uint8_t s[8][64] =
    {
        {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
         0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
         4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
         15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
        {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
         3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
         0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
         13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
        {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
         13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
         13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
         1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
        {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
         13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
         10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
         3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
        {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
         14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
         4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
         11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
        {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
         10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
         9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
         4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
        {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
         13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
         1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
         6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
        {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
         1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
         7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
         2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
const char rots[16] =  { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
const char bit_msk[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
uint8_t DES_Encrypt_key[8];
uint8_t DES_Decrypt_key[8];
uint8_t sub_keys[16][8]; //sub_keys[16][8]
uint8_t main_key[8];

/************************************************************************/
/*                                                                      */
/*      Module title:           transpose                               */
/*      Module type:            des subrutine                           */
/*                                                                      */
/*                                                                      */
/*      Functional Description: Permute n bits in a string, according   */
/*                              to a table describing the new order.    */
/*                              0 < n <= 64                             */
/*                                                                      */
/*      input parameter 1:      pointer to first byte in input string   */
/*                      2:      pointer to first byte in output string  */
/*                      3:      pointer to table describing new order   */
/*                      4:      number of bits to be permuted           */
/************************************************************************/
void transpose(uint8_t *idata, uint8_t *odata, const uint8_t *tbl, uint8_t n)
{
    const uint8_t *tab_adr;
    int i, bi_idx;
    tab_adr = (uint8_t *)&bit_msk[0];
    i = 0;

    do
    {
        odata[i++] = 0;
    } while (i < 8);
    i = 0;
    do
    {
        bi_idx = *tbl++;
        if (idata[bi_idx >> 3] & tab_adr[bi_idx & 7])
        {
            odata[i >> 3] |= tab_adr[i & 7];
        }
    } while (++i < n);
}

/************************************************************************/
/*                                                                      */
/*      Module title:           rotate_l                                */
/*      Module type:            des subrutine                           */
/*                                                                      */
/*      Functional Description: rotate 2 concatenated strings of 28     */
/*                              bits one position to the left.          */
/*                                                                      */
/*      input parameter 1:      pointer to first byte in key string     */
/*                                                                      */
/************************************************************************/
void rotate_l(uint8_t *key)
{
    uint8_t str_x[8];
    uint8_t i;
    for (i = 0; i < 8; ++i)
        str_x[i] = key[i];
    for (i = 0; i < 7; ++i)
    {
        key[i] = (key[i] << 1);
        if ((i < 6) && ((str_x[i + 1] & 128) == 128))
            key[i] |= 1;
    }
    if (str_x[0] & 0x80)
        key[3] |= 0x10;
    else
        key[3] &= ~0x10;
    if (str_x[3] & 0x08)
        key[6] |= 0x01;
    else
        key[6] &= ~0x01;
}
/************************************************************************/
/*                                                                      */
/*      Module title:           ff                                       */
/*      Module type:            des subrutine                           */
/*                                                                      */
/*      Functional Description: The chipher function                    */
/*                                                                      */
/*      input parameter 1:      pointer to first byte in key string     */
/*                      2:      pointer to a 32 bit input string        */
/*                      3:      pointer to a 32 bit output string       */
/************************************************************************/
void ff(uint8_t *skey, uint8_t *a_str, uint8_t *x_str)
{
    uint8_t e_str[8], y_str[8], z_str[8];
    uint8_t k;
    transpose(a_str, e_str, etr, 64);
    for (k = 0; k < 8; ++k)
    {
        y_str[k] = (e_str[k] ^ skey[k]) & 63;
        z_str[k] = s[k][y_str[k]];
    }
    transpose(z_str, x_str, ptr, 32);
}

/************************************************************************/
/*                                                                      */
/*      Module title:           compute_subkeys                         */
/*      Module type:            des subrutine                           */
/*                                                                      */
/*                                                                      */
/*      Functional Description: Computes the 16 sub keys for use in the */
/*                              DES algorithm                           */
/*                                                                      */
/*      input parameter 1:      pointer to first byte in key string     */
/*      output           :      fills the array sub_keys[16][8] with    */
/*                              sub keys and stores the input key in    */
/*                              main_key[8]                             */
/************************************************************************/
void compute_subkeys(uint8_t *key) //计算子匙
{
    uint8_t i, j, ikey[8], okey[8];
    for (i = 0; i < 8; ++i)
    {
        main_key[i] = key[i];
    }

    transpose(key, ikey, key_tr1, 56);

    for (i = 0; i < 16; ++i)
    {
        for (j = 0; j < rots[i]; ++j)
        {
            rotate_l(ikey);
        }
        transpose(ikey, okey, key_tr2, 64);
        for (j = 0; j < 8; ++j)
        {
            sub_keys[i][j] = okey[j];
        }
    }
}
/************************************************************************/
/*                                                                      */
/*      Module title:           des                                     */
/*      Module type:            des mainrutine                          */
/*                                                                      */
/*      Functional Description: Encjipher and decipher 64 bits string   */
/*                              according to a 64 bits key string       */
/*                              The string format is shown below        */
/*                                                                      */
/*      input parameter 1:      pointer to 64 bits input string         */
/*                      2:      pointer to 64 bits key string           */
/*                      3:      boolean if false indicating enciphering */
/*                              if true dechiphering                    */
/*                      4:      pointer to a 64 bits output string      */
/************************************************************************/
/*                                                                      */
/*                      msb                     lsb                     */
/*                      bit                     bit                     */
/*                      +-- -- -- -- -- -- -- --+                       */
/*              addr    !1st                 8th!                       */
/*                      +-- -- -- -- -- -- -- --+                       */
/*              addr+1  !9th                16th!                       */
/*                      +-- -- -- -- -- -- -- --+                       */
/*                      :                       :                       */
/*                      :                       :                       */
/*                      +-- -- -- -- -- -- -- --+                       */
/*              addr+7  !57th               64th!                       */
/*                      +-- -- -- -- -- -- -- --+                       */
/*                                                                      */
/************************************************************************/
void des(uint8_t *plain_strng, uint8_t *key, uint8_t d, uint8_t *ciph_strng)
{
    uint8_t a_str[8], b_str[8], x_str[8];
    uint8_t i, j, *pkey, temp;
    for (i = 0; i < 8; ++i)
    {
        if (key[i] != main_key[i])
        {
            compute_subkeys(key);
            i = 7;
        }
    }

    transpose(plain_strng, a_str, initial_tr, 64);
    for (i = 1; i < 17; ++i)
    {
        for (j = 0; j < 8; ++j)
        {
            b_str[j] = a_str[j];
        }

        if (!d) /*enchipher*/
            pkey = &sub_keys[i - 1][0];
        else /*dechipher*/
            pkey = &sub_keys[16 - i][0];

        for (j = 0; j < 4; ++j)
        {
            a_str[j] = b_str[j + 4];
        }

        ff(pkey, a_str, x_str);

        for (j = 0; j < 4; ++j)
        {
            a_str[j + 4] = b_str[j] ^ x_str[j];
        }
    }

    temp = a_str[0];
    a_str[0] = a_str[4];
    a_str[4] = temp;
    temp = a_str[1];
    a_str[1] = a_str[5];
    a_str[5] = temp;
    temp = a_str[2];
    a_str[2] = a_str[6];
    a_str[6] = temp;
    temp = a_str[3];
    a_str[3] = a_str[7];
    a_str[7] = temp;
    transpose(a_str, ciph_strng, final_tr, 64);
}

void xor_8(uint8_t *io, uint8_t *iv, uint8_t *out)
{
    uint8_t i = 0;
    for (i = 0; i < 8; i++)
    {
        out[i] = io[i] ^ iv[i];
    }
}
/************************************************************************/
/*                                                                      */
/*      Module title:           des3_8                                  */
/*      Module type:            3des                                    */
/*                                                                      */
/*                                                                      */
/*      Functional Description: The chipher function                    */
/*                                                                      */
/*      input parameter 1:      加密(解密)的数据8字节                     */
/*                      3:      16字节密钥                               */
/*                      4:      模式(0:加密 1:解密)                      */
/*                      5:      加密(解密)后的数8字节                     */
/************************************************************************/
void des3_8(uint8_t *input, uint8_t *key, uint8_t mode, uint8_t *output)
{
    uint8_t among[8], among1[8], key1[8], key2[8];

    memcpy(key1, key, 8);
    memcpy(key2, &key[8], 8);

    if (mode == 0) //加密模式
    {
        des(input, (uint8_t *)key1, 0, (uint8_t *)among);     //密钥1 DES加密
        des((uint8_t *)&among, (uint8_t *)key2, 1, (uint8_t *)among1); //密钥2 解密
        des((uint8_t *)&among1, (uint8_t *)key1, 0, (uint8_t *)output);   //密钥1 DES加密
    }
    else if (mode == 1) //解密模式
    {
        des(input, (uint8_t *)key1, 1, (uint8_t *)among);     //密钥1 DES解密
        des((uint8_t *)&among, (uint8_t *)key2, 0, (uint8_t *)among1); //密钥2 DES加密
        des((uint8_t *)&among1, (uint8_t *)key1, 1, (uint8_t *)output);   //密钥1 DES解密
    }
}

/************************************************************************/
/*                                                                      */
/*      Module title:           DES3                                    */
/*      Module type:            3des                                    */
/*                                                                      */
/*                                                                      */
/*      Functional Description: The chipher function                    */
/*                                                                      */
/*      input parameter 1:      加密(解密)的数据                         */
/*                      2:      加密(解密)的数据长度                      */
/*                      3:      16字节密钥                               */
/*                      4:      模式(0:加密 1:解密)                      */
/*                      5:      加密(解密)后的数?                        */
/************************************************************************/
void des3(uint8_t *input, uint8_t inputlen, uint8_t *key, uint8_t mode, uint8_t *ouput)
{
    uint8_t number, i;
    uint8_t out[8], among[8], among1[8], in[8], key1[8], key2[8];

    number = inputlen / 8;
    if (inputlen % 8 != 0)
        number++;

    memcpy(key1, key, 8);
    memcpy(key2, &key[8], 8);

    for (i = 0; i < number; i++)
    {
        //每8字节做一次3DES
        memcpy(in, &input[i * 8], 8);
       // des3_8(in, key, mode, out);
        if (mode == 0) //加密模式
        {
            des((uint8_t *)&in, (uint8_t *)key1, 0, (uint8_t *)among);     //密钥1 DES加密
            des((uint8_t *)&among, (uint8_t *)key2, 1, (uint8_t *)among1); //密钥2 解密
            des((uint8_t *)&among1, (uint8_t *)key1, 0, (uint8_t *)out);   //密钥1 DES加密
        }
        else if (mode == 1) //解密模式
        {
            des((uint8_t *)&in, (uint8_t *)key1, 1, (uint8_t *)among);     //密钥1 DES解密
            des((uint8_t *)&among, (uint8_t *)key2, 0, (uint8_t *)among1); //密钥2 DES加密
            des((uint8_t *)&among1, (uint8_t *)key1, 1, (uint8_t *)out);   //密钥1 DES解密
        }
        memcpy(&ouput[i * 8], out, 8);
    }
}

/************************************************************************/
/*                                                                      */
/*      Module title:           PBOC3DesMAC                             */
/*      Module type:            mac                                     */
/*                                                                      */
/*      Last changed by:        kxlele                                  */
/*      Date:                   2021-04-01                              */
/*                                                                      */
/*      Functional Description: The chipher function                    */
/*                                                                      */
/*      input parameter 1:      原始数据                                 */
/*                      2:      原始数据长度                             */
/*                      3:      16字节密钥                               */
/*                      4:      8字节初始向量                            */
/*                      5:      8字节MAC计算结果                         */
/************************************************************************/
void pboc3desmac(uint8_t *input, uint8_t length, uint8_t *key, uint8_t *iv, uint8_t *out)
{
    uint8_t i;
    uint8_t among[8], among1[8], in[8], key1[8];

    uint8_t blockCount = length / 8 + 1;  // 计算需要分几块
	uint8_t last_length = length % 8; // 最后一个块的原始数据长度

    memcpy(key1, key, 8);

    memcpy(in, &input[0], length < 8 ? length : 8);
    if(length < 8)
    {
        in[length] = 0x80;
    }
    xor_8(in, iv, among);
    
    for (i = 1; i < blockCount; i++)
    {
        if (i == blockCount - 1)// 最后一组特殊填充处理
        {
            memset(in, 0, 8);
            if (last_length > 0)
            {
                memcpy(in, &input[i * 8], last_length);
            }
            in[last_length] = 0x80;// 填充
        }
        else
        {
            memcpy(in, &input[i * 8], 8);
        }
        des(among, key1, 0, among1);
        xor_8(among1, in, among);
    }
    des3_8(among, key, 0, out);            // 3des加密不带填充
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值