密码库LibTomCrypt学习记录——(2.14)分组密码算法的工作模式——CCM代码示例

本文介绍了一种使用CCM模式进行AES加密的测试方法,通过NIST提供的测试向量验证了实现的正确性。测试包括三个例子,详细展示了密钥长度、消息长度、随机数长度、附加数据长度、MAC长度及相应的十六进制字符串。

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


#include "tomcrypt.h"
#include "TestMode.h"

 
// test , use nist test vector

typedef struct NistCCMTestVector_st{
    char *    name;//test vetor name
    int        keylen;
    int        msglen;
    int        noncelen;
    int        adatalen;
    int        maclen;
    BYTE *    key[1];    // 密钥 
    BYTE *    pt[4];    //    明文,暂时最多支持四段明文
    BYTE *    ct[4];    //    密文,暂时最多支持四段明文
    BYTE *    nonce[1];
    BYTE *    adata[1];
    BYTE *    mac[1];
} NistCCMTestVector; 

int Test_CCM_AES(void)

    //    数据来源 
    //    NIST SP 800-38B (Recommendation for Block Cipher Modes of Operation:The CMAC Mode for Authentication).pdf
    NistCCMTestVector vect[] = {
        {//vect[0]   
            /*name*/    "C.1 Example 1",
            /*keylen*/    16, 
            /*msglen*/    4,
            /*noncelen*/7,
            /*adatalen*/8,
            /*maclen*/    4,
            /*Key*/        "404142434445464748494a4b4c4d4e4f", 
            {// pt 
                "20212223" 
            },
            {//ct
                "7162015b4dac255d", 
            },
            /*nonce*/    "10111213141516",
            /*Adata*/    "0001020304050607",
            /*mac*/        "4dac255d"
        },
        //////////////////////////////////////////////////////////////////////////
        {//vect[1]  
            /*name*/    "C.2 Example 2",
            /*keylen*/    16, 
            /*msglen*/    16,
            /*noncelen*/8,
            /*adatalen*/16,
            /*maclen*/    6,
            /*Key*/        "404142434445464748494a4b4c4d4e4f", 
            {// pt 
                "202122232425262728292a2b2c2d2e2f",
            },
            {//ct
                "d2a1f0e051ea5f62081a7792073d593d",  
            },
            /*nonce*/    "1011121314151617",
            /*Adata*/    "000102030405060708090a0b0c0d0e0f",
            /*mac*/        "1fc64fbfaccd" 
        },
        //////////////////////////////////////////////////////////////////////////
        {//vect[2] 
            /*name*/    "C.3 Example 3",
            /*keylen*/    16, 
            /*msglen*/    24,
            /*noncelen*/12,
            /*adatalen*/20,
            /*maclen*/    8,
            /*Key*/        "404142434445464748494a4b4c4d4e4f", 
            {// pt 
                 "202122232425262728292a2b2c2d2e2f"
                 "3031323334353637"
            },
            {//ct
                "e3b201a9f5b71a7a9b1ceaeccd97e70b", 
                "6176aad9a4428aa5"
            },
            /*nonce*/    "101112131415161718191a1b", 
            /*Adata*/    "000102030405060708090a0b0c0d0e0f10111213",
            /*mac*/        "484392fbc1b09951" 
        } 
    };

    int idx, err, i;  
    int keylen, msglen, noncelen, adatalen;
    unsigned long calc_maclen; 
    BYTE key[32], pt[64], ct[64], nonce[64], adata[64], mac[64], calc_ct[64], calc_mac[64];

    /* AES can be under rijndael or aes... try to find it */ 
    if ( register_cipher (&aes_desc) != CRYPT_OK )
    {
        return CRYPT_INVALID_CIPHER;
    }

    if ((idx = find_cipher("aes")) == -1) 
    { 
        return CRYPT_NOP;
    }
    
    printf("\nTest CCM AES Begin!\n" );

    for ( i = 0; i < (int)(sizeof(vect)/sizeof(vect[0])); i++ )
    {
        keylen    = vect[i].keylen;
        msglen    = vect[i].msglen;
        noncelen= vect[i].noncelen;
        adatalen= vect[i].adatalen;
        calc_maclen    = vect[i].maclen;

        Str2Num(vect[i].key, 1, key); 
        Str2Num(vect[i].pt, 4, pt);
        Str2Num(vect[i].ct, 4, ct);
        Str2Num(vect[i].nonce, 1, nonce);
        Str2Num(vect[i].adata, 1, adata);
        Str2Num(vect[i].mac, 1, mac); 

        Str2Num2(vect[i].key,    1, key,        32); 
        Str2Num2(vect[i].pt,    4, pt,        64);
        Str2Num2(vect[i].ct,    4, ct,        64);
        Str2Num2(vect[i].nonce, 1, nonce,    64);
        Str2Num2(vect[i].adata, 1, adata,    64);
        Str2Num2(vect[i].mac,    1, mac,        64);  

        if ((err = ccm_memory(idx, key, 16, NULL, 
            nonce, noncelen, adata, adatalen,
            pt, msglen, calc_ct, 
            calc_mac, &calc_maclen, GCM_ENCRYPT)) != CRYPT_OK ) {
            return err;
        } 
 
        printf("Test Vetor : %s ct pass ? %s \t mac pass ? %s \n", vect[i].name, 
            (XMEMCMP(calc_ct, ct, msglen) == 0) ? "Yes":"No",
            (XMEMCMP(calc_mac, mac, calc_maclen) == 0) ? "Yes":"No");
    }

    printf("\nTest CCM AES Finish!\n" );
    return CRYPT_OK; 
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值