CMAC(C/C++)
===========

CMAC是基于对称密钥分组加密算法的消息认证码（Cipher-based Message Authentication Code），目前支持3DES加密算法的消息认证方法。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e4/v3/YX_kLcUtRwO2bZsl94kxEg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132425Z&HW-CC-Expire=86400&HW-CC-Sign=2C5A9A588EB59052B04E69F2B09DE51DF153FAD9DF63DFE10854816EEA062C6E)

仅支持在智能穿戴设备（Wearable）使用。

#### 开发步骤

**生成密钥**

1.  获取生成密钥算法参数配置。
    
2.  调用[OH\_Huks\_GenerateKeyItem](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_generatekeyitem)生成密钥，支持的规格是128比特长度的密钥。
    

除此之外，开发者也可以参考[密钥导入](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-import-overview#支持的算法)的规格介绍，导入已有的密钥。

**执行CMAC**

1.  调用[OH\_Huks\_InitParamSet](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-param-h#oh_huks_initparamset)获取算法参数配置。
    
2.  调用[OH\_Huks\_InitSession](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_initsession)和[OH\_Huks\_FinishSession](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_finishsession)计算MAC值。
    

#include "huks/native\_huks\_api.h"
#include "huks/native\_huks\_param.h"
#include "huks/native\_huks\_type.h"
#include "napi/native\_api.h"
#include <string.h>

static const uint32\_t CMAC\_COMMON\_SIZE = 8;
static const uint32\_t IV\_SIZE = 8;
static uint8\_t IV\[IV\_SIZE\] = { 0 };

OH\_Huks\_Result InitParamSet(struct OH\_Huks\_ParamSet \*\*paramSet, const struct OH\_Huks\_Param \*params, uint32\_t paramCount)
{
    OH\_Huks\_Result ret = OH\_Huks\_InitParamSet(paramSet);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        return ret;
    }
    ret = OH\_Huks\_AddParams(\*paramSet, params, paramCount);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        OH\_Huks\_FreeParamSet(paramSet);
        return ret;
    }
    ret = OH\_Huks\_BuildParamSet(paramSet);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        OH\_Huks\_FreeParamSet(paramSet);
        return ret;
    }
    return ret;
}

static struct OH\_Huks\_Param g\_genParams\[\] = {
    {
        .tag = OH\_HUKS\_TAG\_ALGORITHM,
        .uint32Param = OH\_HUKS\_ALG\_3DES
    }, {
        .tag = OH\_HUKS\_TAG\_KEY\_SIZE,
        .uint32Param = OH\_HUKS\_3DES\_KEY\_SIZE\_128
    }, {
        .tag = OH\_HUKS\_TAG\_PURPOSE,
        .uint32Param = OH\_HUKS\_KEY\_PURPOSE\_MAC
    }
};

static struct OH\_Huks\_Param g\_cmacParams\[\] = {
    {
        .tag = OH\_HUKS\_TAG\_ALGORITHM,
        .uint32Param = OH\_HUKS\_ALG\_CMAC
    }, {
        .tag = OH\_HUKS\_TAG\_KEY\_SIZE,
        .uint32Param = OH\_HUKS\_3DES\_KEY\_SIZE\_128
    }, {
        .tag = OH\_HUKS\_TAG\_PURPOSE,
        .uint32Param = OH\_HUKS\_KEY\_PURPOSE\_MAC
    }, {
        .tag = OH\_HUKS\_TAG\_BLOCK\_MODE,
        .uint32Param = OH\_HUKS\_MODE\_CBC
    }, {
        .tag = OH\_HUKS\_TAG\_PADDING,
        .uint32Param = OH\_HUKS\_PADDING\_ISO\_IEC\_9797\_1
    }, {
        .tag = OH\_HUKS\_TAG\_IV,
        .blob = {
            .size = IV\_SIZE,
            .data = (uint8\_t \*)IV
        }
    }
};

OH\_Huks\_Result HksCmacTest(const struct OH\_Huks\_Blob \*keyAlias, const struct OH\_Huks\_ParamSet \*cmacParamSet,
    const struct OH\_Huks\_Blob \*inData, struct OH\_Huks\_Blob \*outData)
{
    uint8\_t handleE\[sizeof(uint64\_t)\] = {0};
    struct OH\_Huks\_Blob handle = {sizeof(uint64\_t), handleE};
    OH\_Huks\_Result ret = OH\_Huks\_InitSession(keyAlias, cmacParamSet, &handle, nullptr);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        return ret;
    }
    ret = OH\_Huks\_FinishSession(&handle, cmacParamSet, inData, outData);
    return ret;
}

static napi\_value CmacKey(napi\_env env, napi\_callback\_info info)
{
    char tmpKeyAlias\[\] = "test\_cmac";
    struct OH\_Huks\_Blob keyAlias = { (uint32\_t)strlen(tmpKeyAlias), (uint8\_t \*)tmpKeyAlias };
    struct OH\_Huks\_ParamSet \*genParamSet = nullptr;
    struct OH\_Huks\_ParamSet \*cmacParamSet = nullptr;
    OH\_Huks\_Result ohResult;
    do {
      /\*       \* 1.1 获取生成密钥算法参数配置       \*/
        ohResult = InitParamSet(&genParamSet, g\_genParams, sizeof(g\_genParams) / sizeof(OH\_Huks\_Param));
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
       /\*               \* 1.2 调用OH\_Huks\_GenerateKeyItem        \*/
        ohResult = OH\_Huks\_GenerateKeyItem(&keyAlias, genParamSet, nullptr);
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
       /\*        \* 2.1. 获取CMAC算法参数配置        \*/
        char tmpInData\[\] = "CMAC\_INDATA";
        struct OH\_Huks\_Blob inData = { (uint32\_t)strlen(tmpInData), (uint8\_t \*)tmpInData };
        uint8\_t mac\[CMAC\_COMMON\_SIZE\] = { 0 };
        struct OH\_Huks\_Blob macData= {CMAC\_COMMON\_SIZE, mac};
        ohResult = InitParamSet(&cmacParamSet, g\_cmacParams, sizeof(g\_cmacParams) / sizeof(OH\_Huks\_Param));
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
       /\*        \* 2.2 调用initSession和finishSession计算MAC        \*/
        ohResult = HksCmacTest(&keyAlias, cmacParamSet, &inData, &macData);
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
    } while (0);
    OH\_Huks\_FreeParamSet(&genParamSet);
    OH\_Huks\_FreeParamSet(&cmacParamSet);
    
    napi\_value ret;
    napi\_create\_int32(env, ohResult.errorCode, &ret);
    return ret;
}