This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/CC2650STK:AES-CCM 加密

Guru**** 2472470 points
Other Parts Discussed in Thread: CC2650STK, CC2640, CC2650

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/663941/rtos-cc2650stk-aes-ccm-encryption

器件型号:CC2650STK
Thread 中讨论的其他器件: CC2640CC2650

工具/软件:TI-RTOS

如果在论坛中搜索提示、但我没有得到任何有用的提示。

我正在使用 CC2650STK - Sensortag。

我要尝试的是、传感器值(湿度和 IR-温度) 通过 AES-CCM 进行加密。 稍后、RaspberryPi 3会连接到它并收集数据、然后对其解密。

如果阅读《开发人员指南》(CC2640和 CC2650 SimpleLinkTm低功耗 BluetoothRegistered软件栈2.2.1),则说明存在加密驱动程序。 它发布为:C:\TI\tirtos_cc13xx_cc26xx_2_20_01_08\products\tidrivers_cc13xx_cc26xx_2_20_01_10\docs\doxygen\html\index.html。 这将引导我进入 CryptoCC26XX.h 文件参考-部分。

I'v 使用了示例代码(sensortag_hum.c 内部-文件从 第328行开始-->就在 SensorHdc1000_read (&data.v.rawTemp、&data.v.rawHum)函数之后):

#define macLength (4)
#define clearTextLength (16)
#define cipherTextLength (macLength + clearTextLength)
#define NonceLength (12)
#define aadLength (14)


//保持此示例的 AES-CCM 设置
typedef 结构
{
uint8_t key[16]; // 128位 AES 密钥
CryptoCC26XX_KeyLocation 密钥位置; //硬件中的8个关键位置之一
uint8_t clearAndCniText[cnextlength];//保留前面的 cleartext 和 cnitext
//完成加密操作后。
//加密文本=加密文本+消息身份验证代码(MAC)。
uint8_t nonce[非 ceLength ];//仅使用一次的值(加密术语'nonce')
uint8_t header[aadLength ];//未加密但在操作(AAD)中经过身份验证的标头
。} AesCcmExamples;

AesCcmExamples CCMSetup =
{
.key ={0x2B、0x7E、0x15、0x16、0x28、 0xAE、0xD2、0xA6、
0xAB、0xF7、0x15、0x88、0x09、 0xCF、0x4F、0x3C}、
.keyLocation = CRYPTOCC26XX_KEY_0、
.clearAndChiText ={"t"、"h"、"i"、"S"、"i"、"a"、"p"、"l"、"a"、"i"、"n"、"t"、"e"、"e"、"x"、"t"、"t"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、"0"、
.nonce ={"t"、"h"、"i"、"S"、"i"、"S"、"a"、"n"、"o"、"n"、"c"、"e"}、
.header={"t"、"h"、"i"、"S"、"i"、"S"、"h"、"e"、"a"、"a"、"d"、"d"、"e"、"e"、"r"、"1"}
};

CryptoCC26XX_handle 句柄;
内部32_t KeyIndex;
CryptoCC26XX_AESCM_Transaction Trans;
内部32_t 状态;

//初始化 Crypto 驱动程序结构
CryptoCC26XX_init();

//使用非独占访问和默认参数打开加密硬件。
Handle = CryptoCC26XX_open (Board_crypto、false、NULL);

if (handle == NULL){
//System_abort ("CryptoCC26XX did not open");
CryptoOpen = 0;
}否则{
CryptoOpen = 1;
}

//在硬件中分配密钥存储位置
KeyIndex = CryptoCC26XX_allocateKey (handle、CCMSetup.keyLocation、(const UINT32_t *) CCMSetup.key);
if (keyIndex =CRYPTOCC26XX_STATUS_ERROR){
//System_abort ("未分配密钥位置。");
KeyLocation = 0;
} 否则{
KeyLocation = 1;
}

//加密并验证消息
CryptoCC26XX_transac_init ((CryptoCC26XX_Transaction *)&trans、CRYPTOCC26XX_OP_AES_CCM);
TRANS.keyIndex = keyIndex;
trans.authLength = macLength;
trans.nonce =(char *) ccmSetup.nonce;
TRANS.HEADER =(char *) CCMSetup.HEADER;
TRANS.Fieldbength = 3;
TRANS.msgInLength = clearTextLength;
TRANS.headerLength = aadLength;
TRANS.msgIn =(char *)&(CCMSetup.clearAndChinText[0]); //消息已加密到位
TRANS.msgOut =(char *)&(CCMSetup.clearAndCipherText[clearTextLength ]);// MAC 将被写入此位置
状态= CryptoCC26XX_transact (handle、(CryptoCC26XX_Transaction *)&trans);


if (status!= CRYPTOCC26XX_STATUS_SUCCESS){
//System_abort ("加密和签名失败。");
encryption_and_signing = 0;
} 否则{
encryption_and_signing = 1;
}

//解密和验证消息
CryptoCC26XX_transac_init ((CryptoCC26XX_Transaction *)&trans、CRYPTOCC26XX_OP_AES_CCMINV);
TRANS.keyIndex = keyIndex;
trans.authLength = macLength;
trans.nonce =(char *) ccmSetup.nonce;
TRANS.HEADER =(char *) CCMSetup.HEADER;
TRANS.Fieldbength = 3;
TRANS.msgInLength =密码文本长度;
TRANS.headerLength = aadLength;
TRANS.msgIn =(char *)&(CCMSetup.clearAndChinText[0]); //在适当的位置解密消息
TRANS.msgOut =(char *)&(CCMSetup.clearAndCipherText[clearTextLength ]);//指向 MAC、在这里用作输入

//进行 AES-CCM 解密和身份验证
状态= CryptoCC26XX_transact (handle、(CryptoCC26XX_Transaction *)&trans);
if (status!= CRYPTOCC26XX_STATUS_SUCCESS){
//System_abort ("解密和验证失败。");
decrytion_and_ath = 0;
}
否则{
decrytion_and_ath = 1;
}

//释放关键位置
状态= CryptoCC26XX_releaseKey (handle、&keyIndex);
if (status!= CRYPTOCC26XX_STATUS_SUCCESS){
//System_abort ("密钥释放失败。");
keyRealease = 0;
} 否则{
keyRealease = 1;
} 

调试时、 我的虚拟变量(cryptoOpen、keyLocation、encryption_and_signing、decrytion_and_ath、keyRelease)始终具有值1、这意味着一切都应该正常工作。 遗憾的是、我无法访问 trans 变量(更精确的 transrs.msgOut、它应该是密码+ MAC)。

I'v 还尝试了 crypto.c/crypto.h (第一个出现在该线程中: e2e.ti.com/.../2298769):

uint32_t plaintext[16]={'t'、'h'、'i'、's'、'i'、'p'、'l'、'a'、'i'、'n'、't'、'e'、'x'、't'};
uint32_t c'、's'

、'n'、't'
、't32'、't'、't'、't'、't'、't'、't'、't'、

t'、t'、't'、't'、t'、't'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、t'、 nonce、crypto_key_area_0、true、false);
status = CRYPTOAesCbcStatus ();
if (status!= AES_SUCCESS)
{
//Error
encryption_and_signing = 0;
}否则{
//Success
encryption_and_signing = 1;
} 

这会导致应用程序停止(似乎它卡在 CRYPTOAesCbc ()-function <- I'v 这次尝试了另一种模式(CBC)))。

是否有办法加密(使用 AES-CCM)值、例如 uint16_t rawTemp、huminidity typdef 联合体的 rawHum、然后像正常值一样发送它? 就我所知:  

uint8* const pValue; 

最多可获得512个八位位组、这对于加密长度为(2*16bit = 4字节+ 16字节身份验证长度)足够。

感谢您的任何帮助、并提前感谢您。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Eagle5、

    TRANS.msgOut 可能会根据编译器设置进行优化。 加密后的消息将存储在 clearAndChinText 数组中。 在您参考的 CryptoCC26XX 使用指南中的示例使用代码中、在"加密和验证消息"部分中调用 CryptoCC26XX_transact 后 clearAndCipherText 的值是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     您好、RachelP、

    遗憾的是、我甚至在调试会话中看不到变量 clearAndChiText。 此外、向表达式中添加 CCMSetup.clearAndChinText 也没有帮助。
    我在解密开始之前就建立了断点。 因此、我希望 CCMSetup.clearAndChinText 数组将保存该密码文本。


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、RachelP、
    我现在调试时成功地看到了这些变量(刚刚将它们声明为全局变量)。

    我还能够将加密内容传输到 IOS - Sensortag -应用、在该应用中、我可以看到加密的密码

    CCMSetup.clearAndCipherText ={"t"、'h"、'i'、"S"、'i'、'a'、'p'、'l'、'a'、'i'、'n'、't'、'e'、'x'、't'、'0'、'0'、'0'、'0'、'0'、'0'、'0'、'0'、 

    但现在的问题是、它对内容进行了两次加密。 这意味着在"第一次"时、它会解密问题并向我提供以下 chipe+Mac 消息:

    [0]unsigned char156 '\x9c'0x20000935
    [1]unsigned char79 'O'0x20000936
    [2]unsigned char234 '\xe'0x20000937
    [3]unsigned char155 '\x9b'0x20000938
    [4]unsigned char150 '\X96'0x20000939
    [5]unsigned char 93204'\x9318'\200008783b'[0x200009138]
    [unsignedchar 9318]0x200008783c'[unsigned char'\20000938]0x200009138][unsigned char '\20000938'
    
    char82 'R'0x20000933D
    [9]unsigned char44 '、'0x2000093E
    [10]unsigned char198 '\xc6'0x2000093F
    [11]unsigned char162 '\xa2'0x20000940
    [12]unsigned char191
    
    unsigned char '\xBF' 0x2009441 [13] 009204 '\xcc' 0x20000942' 0x20000402'[0x20000942]
    
    unsigned char 'x0014'[12] unsigned char unsigned char 'x94424'[12'm'0x20000945
    [17]unsigned char92 '\'0x20000946
    [18]unsigned char144 '\x90'0x20000947
    [19]unsigned char124 '|'0x20000948

    在 IOS-App 中、我看到以下字符串:

    9c4羽毛9b 96cc8a88 522cc6a2 bfcca228 4d5c907c 

    这是预期的卡尺+Mac (参见下图)。

    但是、它再次尝试加密、但失败、这会显示此消息(这是我可以通过 IOS-APP 看到的、一旦湿度配置设置为0x01、传感器数据将显示/传输):

    74686973 69736170 6c61696e 74657874 a92b8239 

    以下是进行调试时的情况:

    您可以看到加密和签名失败(您可以看到 clearAndChiText 仍然是"旧版本"-->它与我每秒在 IOS-App 中看到的内容不匹配)。

    你有线索吗、什么是错误的?

    提前感谢您

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还尝试解密我在调试时获得的密文-->我使用的是 python2脚本。

    我不知道它是否正确、但在我看来、解密有点错误?

    因为我总是会得到:

    [0]unsigned char116 't'0x20000935
    [1]unsigned char104 'h'0x20000936
    [2]unsigned char105 'I'0x20000937
    [3]unsigned char115 's'0x20000938
    [4]unsigned char105 'I'0x20000939
    [5]unsigned char115 's' 0x2000093A
    [6]0x200009397'0x20000938[4] unsigned char 'C' 0x200009381' 0x200009381' unsigned
    char [51] unsigned char 's'[5
    char108 'l'0x2000093D
    [9]unsigned char97 'a'0x2000093E
    [10]unsigned char105 'i'0x2000093F
    [11]unsigned char110 'n'0x20000940
    [12]unsigned char 116unsigned 't'0x20000941
    [13]unsigned char101 'e'0x20000942
    [14] 0x20000942[14] 0x20000944[16]unsigned char944[15
    
    'm'0x20000945
    [17]unsigned char92 '\'0x20000946
    [18]unsigned char144 '\x90'0x20000947
    [19]unsigned char124 '|'0x20000948

    而不是原始纯文本:

    [0]unsigned char116 't'0x20000935
    [1]unsigned char104 'h'0x20000936
    [2]unsigned char105 'I'0x20000937
    [3]unsigned char115 's'0x20000938
    [4]unsigned char105 'I'0x20000939
    [5]unsigned char115 's' 0x2000093A
    [6]0x200009397'0x20000938[4] unsigned char 'C' 0x200009381' 0x200009381' unsigned
    char [51] unsigned char 's'[5
    char108 'l'0x2000093D
    [9]unsigned char97 'a'0x2000093E
    [10]unsigned char105 'i'0x2000093F
    [11]unsigned char110 'n'0x20000940
    [12]unsigned char 116unsigned 't'0x20000941
    [13]unsigned char101 'e'0x20000942
    [14] 0x20000942[14] 0x20000944[16]unsigned char944[15
    
    "0"0x20000945
    [17]unsigned char48 "0"0x20000946
    [18]unsigned char48 "0"0x20000947
    [19]unsigned char48 "0"0x20000948

    下面是我正在使用的 python 脚本:

    从 Cryptodome 导入 AES
    从 Cryptodome 导入 AES。随机导入 get_random_bytes
    导入 base64
    
    
    HDR = b'thissaheader1'
    明文= b'thissaintext0000'
    键= b'\x2B\x7E\x15\x28\xAe\xA2\xA2\xA6\xA6\xab\xB\x86\x86\xHDRV1'密
    
    
    
    
    
    
    钥=加密一次加密一次加密,加密一次加密一次加密一次加密后,加密后加密后加密后,加密后加密后加密后的密码:%x86\x015e2r\nHDR=x015\x015\x015\x015\x015\x015\x015\x015\x015\xe\x015\xe\xe\xe\xe\x430\xe\xe\xe\xe\x %s、Mac:%s"%(msg、密码文本、ciph.digure())
    
    
    #我们假设将 tuple ``mSG``传输到接收器:
    #nonce、HDR、密码文本、Mac = msg
    
    密码文本= b'\x9c\X4F\x9b\x96\xcc\x8a\x28%x782\x782\x782%\cxintrines\cx90\x78\x78%\cx782\x782\x782\x782\x90\xines\cxines\cx78%\cx90\x78\x78\x78\x782\x782\x78\x78\x20\x78\x20\xines\cmc\x78\x78\x90\x20\x78\x20\x20\x20\x20\x20\x20\xines\c
    
    
    
    
    
    
    
    %s"%(Mac)
    
    key = b'\x2B\x7E\x15\xX6\x28\xA6\xD2\xA6\xA6\xAB\x15\x88\x09\XCF\X4F\x3C'
    cipher = AES.new (key、AES.MODE_CCM、nonce、mac_len=4
    )密钥=
    cipher.decrypt(ciphertext 纯文本更新(HDR):
    尝试密钥:
    cips.verify (Mac)
    打印“消息为真:HDR=%s,pt=%s”%(HDR,纯文本)
    ,ValueError 除外:
    打印"密钥不正确或消息损坏"
    

    由于 AES-Lib、我使用 的是 PyCryptoDome 以下链接: http://pycryptodome.readthedocs.io/en/latest/src/installation.html

    PIP 安装 pycryptotomex 

    我还添加 sensortag_hum.c 文件。

    感谢您的提前帮助。

    e2e.ti.com/.../8765.sensortag_5F00_hum.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    到目前为止、加密和解密始终正确(在传感器端)、这是我的 python 脚本中的一个错误。

    但湿度任务中的"双重加密"问题仍然存在。

    我将加密驱动程序的初始化移动到湿度任务的初始化函数:

    /*********
    *@fn SensorTagHum
    *
    @SensorTag 湿度传感器的简要初始化函
    数*
    @param none
    *
    *@return none
    */
    void SensorTagHum_init (void)
    {
    //添加服务
    湿度_addService ();
    
    //使用配置文件
    湿度_
    
    
    
    
    初始化调用参数(_sensorCallbacks)注册模块;//默认设置= sensor_period_resensor_resensor_resetor_period_reset.sensor_statistor_reset.ality.ality.ality.ality.alsensor_period.sensor_statuor_stat
    / sensor_period_resolution、sizeof (uint8_t);
    
    //初始化驱动程序
    SensorHdc1000_init ();
    
    //初始化加密驱动程序结构
    CryptoCC26XX_init ();
    } 



    其余的 crpyto 代码(来自示例: file:///C:/ti/tirtos_cc13xx_cc26xx_2_20_01_08/products/tidrivers_cc13xx_cc26xx_2_20_01_10/docs/doxygen/html/_crypto_c_c26_x_x_8h.html #crypto_use_cases)保留在 taskFxn()中:

    /*********
    *@fn sensorTaskFxn
    *
    *@
    
    
    
    
    
    @简要介绍湿度读取任务的任务循环**@param a0 -未使用*@param A1 -未使用**返回 none
    */
    static void sensorTaskFxn (UArg a0、UArg A1)
    {
    typedef union{
    结构{
    //uint16_t rawTemp、rawHum;//以字节为单位的传感器(湿度)数据长度为4 (2*16bit = 32位= 4字节)
    uint8_t sensor_data[20];
    } 五;
    uint8_t a[sensor_data_LEN];
    }Data_t;
    uint16_t test_rawTemp = 0;
    uint16_t test_rawHum = 0;
    
    
    //使用 BLE 堆栈注册任务
    iCall_registerApp (&sensorSelfEntity、&sensorSem);
    
    //取消激活任务(仅在启用了 sensorTask1
    
    
    
    时激活)–task (true/true/task (true/true/true/true/track_track_track/task)(当启用时)
    
    如果(sensorConfig = ST_CFG_SENSOR_ENABLE)
    {
    data_t 数据;
    
    // 1. 开始温度测量
    SensorHdc1000_start();
    delay_ms (hum_delay_period);
    
    // 2. 读取数据
    //SensorHdc1000_read (&data.v.rawTemp、&data.v.rawHum);
    SensorHdc1000_read (&test_rawTemp、&test_rawHum);
    
    
    LowerByteTemp =(uint8_t) test_rawTemp;
    UpperByteTemp =(uint8_t)(test_rawTemp >> 8);
    CCMSetup.clearAndCipherText[0]= LowerByteTemp;
    CCMSetup.clearAndCipherText[1]=上行字节温度;
    
    LowerByteHum =(uint8_t) test_rawHum;
    UpperByteHum =(uint8_t)(test_rawHum >> 8);
    CCMSetup.clearAndCipherText[2]=LowerByteHum;
    CCMSetup.clearAndChiText[3]=UpperByteHum;
    
    
    //TODO:在此处加密传感器数据
    
    
    //使用非独占访问和默认参数打开加密硬件。
    Handle = CryptoCC26XX_open (Board_crypto、false、NULL);
    
    if (handle == NULL){
    //System_abort ("CryptoCC26XX did not open");
    CryptoOpen = 0;
    }否则{
    CryptoOpen = 1;
    }
    
    //在硬件中分配密钥存储位置
    KeyIndex = CryptoCC26XX_allocateKey (handle、CCMSetup.keyLocation、(const UINT32_t *) CCMSetup.key);
    if (keyIndex =CRYPTOCC26XX_STATUS_ERROR){
    //System_abort ("未分配密钥位置。");
    KeyLocation = 0;
    } 否则{
    KeyLocation = 1;
    }
    
    //加密并验证消息
    CryptoCC26XX_transac_init ((CryptoCC26XX_Transaction *)&trans、CRYPTOCC26XX_OP_AES_CCM);
    TRANS.keyIndex = keyIndex;
    trans.authLength = macLength;
    trans.nonce =(char *) ccmSetup.nonce;
    TRANS.HEADER =(char *) CCMSetup.HEADER;
    TRANS.Fieldbength = 3;
    TRANS.msgInLength = clearTextLength;
    TRANS.headerLength = aadLength;
    TRANS.msgIn =(char *)&(CCMSetup.clearAndChinText[0]); //消息已加密到位
    TRANS.msgOut =(char *)&(CCMSetup.clearAndCniText[clearTextLength ]);// clearAndCniText_test[clearTextLength ];// MAC 将写入此位置
    状态= CryptoCC26XX_transact (handle、(CryptoCC26XX_Transaction *)&trans);
    
    
    if (status!= CRYPTOCC26XX_STATUS_SUCCESS){
    //System_abort ("加密和签名失败。");
    encryption_and_signing = 0;
    } 否则{
    encryption_and_signing = 1;
    }
    
    
    for (int i = 0;i < 20;i ++)
    {
    data.v.sensor_data[i]= CCMSetup.clearAndChiText[i];
    }
    
    
    //释放关键位置
    状态= CryptoCC26XX_releaseKey (handle、&keyIndex);
    if (status!= CRYPTOCC26XX_STATUS_SUCCESS){
    //System_abort ("密钥释放失败。");
    keyRealease = 0;
    } 否则{
    keyRealease = 1;
    }
    
    // 3. 发送数据
    Humide_SetParameter (sensor_data、sensor_data_LEN、data.a);
    
    
    // 4. 等待下一个周期
    delay_ms (sensorPeriod - hum_delay_period);
    }
    其他
    {
    delay_ms (sensor_default_period);
    }
    }
    



    对于调试(以便我可以读取我在全局范围内声明的变量):

    //在 sensortag_hm.c 文件中包含和其他变量
    。
    。
    。
    //任务配置
    #define sensor_task_priority 1
    #define sensor_task_stack_size 600
    
    #define macLength (4)
    #define clearTextLength (16)
    #define cipherTextLength (macLength + clearTextLength)
    #define NonceLength (12)
    #define aadLength (14)
    
    /*********
    * typedef
    */
    
    
    uint8_t UpperByteTemp;
    uint8_t LowerByteTemp;
    uint8_t UpperByteHum;
    uint8_t LowerByteHum;
    
    //加密参数
    uint8_t cryptettoOpen = 0;
    uint8_t keystructure = 0;
    uint8_t
    
    = uint8_t + uint8_t 加密
    设置= 0;uint8_t trunit_t = uint_t = uint8和 uint_detryt = uint_t
    
    
    uint8_t key[16]; // 128位 AES 密钥
    CryptoCC26XX_KeyLocation 密钥位置; //硬件中的8个关键位置之一
    uint8_t clearAndCniText[cnextlength];//保留前面的 cleartext 和 cnitext
    //完成加密操作后。
    //加密文本=加密文本+消息身份验证代码(MAC)。
    uint8_t nonce[非 ceLength ];//仅使用一次的值(加密术语'nonce')
    uint8_t header[aadLength ];//未加密但在操作(AAD)中经过身份验证的标头
    。} AesCcmExamples;.
    
    。
    。 


    加密方法的初始化是否错误? 或者、我是否只是错误地使用了加密方法?

    提前感谢