10a7ce71fSopenharmony_ci/*
20a7ce71fSopenharmony_ci * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
30a7ce71fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40a7ce71fSopenharmony_ci * you may not use this file except in compliance with the License.
50a7ce71fSopenharmony_ci * You may obtain a copy of the License at
60a7ce71fSopenharmony_ci *
70a7ce71fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80a7ce71fSopenharmony_ci *
90a7ce71fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100a7ce71fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110a7ce71fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a7ce71fSopenharmony_ci * See the License for the specific language governing permissions and
130a7ce71fSopenharmony_ci * limitations under the License.
140a7ce71fSopenharmony_ci */
150a7ce71fSopenharmony_ci
160a7ce71fSopenharmony_ci/**
170a7ce71fSopenharmony_ci * This file make use the hmac to make mqtt pwd.
180a7ce71fSopenharmony_ci * The method is use the date string to hash the device passwd
190a7ce71fSopenharmony_ci * Take care that this implement depends on the hmac of the mbedtls
200a7ce71fSopenharmony_ci*/
210a7ce71fSopenharmony_ci#include <stdint.h>
220a7ce71fSopenharmony_ci#include <stddef.h>
230a7ce71fSopenharmony_ci#include <string.h>
240a7ce71fSopenharmony_ci#include <stdio.h>
250a7ce71fSopenharmony_ci#include "md.h"
260a7ce71fSopenharmony_ci#include "md_internal.h"
270a7ce71fSopenharmony_ci
280a7ce71fSopenharmony_ci#define CN_HMAC256_LEN_MAX (65)
290a7ce71fSopenharmony_ci#define CN_HMAC256_LEN   32
300a7ce71fSopenharmony_ci#define RIGHT_MOVE_BIT_4 (4)
310a7ce71fSopenharmony_ci#define NUMBER_9 (9)
320a7ce71fSopenharmony_ci#define DECIMAL_BASE (10)
330a7ce71fSopenharmony_ci#define STRING_LEN_TIMES (2)
340a7ce71fSopenharmony_ci#define LEN_TIMES (2)
350a7ce71fSopenharmony_ci#define OFFSET (1)
360a7ce71fSopenharmony_ci// make a byte to 2 ascii hex
370a7ce71fSopenharmony_cistatic int byte2hexstr(unsigned char *bufin, int len, char *bufout)
380a7ce71fSopenharmony_ci{
390a7ce71fSopenharmony_ci    int i = 0;
400a7ce71fSopenharmony_ci    unsigned char  tmp_l = 0x0;
410a7ce71fSopenharmony_ci    unsigned char  tmp_h = 0;
420a7ce71fSopenharmony_ci    if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
430a7ce71fSopenharmony_ci        return -1;
440a7ce71fSopenharmony_ci    }
450a7ce71fSopenharmony_ci    for (i = 0; i < len; i++) {
460a7ce71fSopenharmony_ci        tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
470a7ce71fSopenharmony_ci        tmp_l = bufin[i] & 0x0F;
480a7ce71fSopenharmony_ci        bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
490a7ce71fSopenharmony_ci            (tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
500a7ce71fSopenharmony_ci        bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
510a7ce71fSopenharmony_ci            (tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
520a7ce71fSopenharmony_ci    }
530a7ce71fSopenharmony_ci    bufout[STRING_LEN_TIMES * len] = '\0';
540a7ce71fSopenharmony_ci
550a7ce71fSopenharmony_ci    return 0;
560a7ce71fSopenharmony_ci}
570a7ce71fSopenharmony_ci
580a7ce71fSopenharmony_ciint HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
590a7ce71fSopenharmony_ci    int keyLen, unsigned char *buf)
600a7ce71fSopenharmony_ci{
610a7ce71fSopenharmony_ci    int ret = -1;
620a7ce71fSopenharmony_ci    mbedtls_md_context_t mbedtls_md_ctx;
630a7ce71fSopenharmony_ci    const mbedtls_md_info_t *md_info;
640a7ce71fSopenharmony_ci    unsigned char hash[CN_HMAC256_LEN];
650a7ce71fSopenharmony_ci
660a7ce71fSopenharmony_ci    if ((key == NULL)||(content == NULL)||(buf == NULL)||
670a7ce71fSopenharmony_ci        (keyLen == 0)||(contentLen == 0)||
680a7ce71fSopenharmony_ci        (CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
690a7ce71fSopenharmony_ci        return ret;
700a7ce71fSopenharmony_ci    }
710a7ce71fSopenharmony_ci
720a7ce71fSopenharmony_ci    md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
730a7ce71fSopenharmony_ci    if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
740a7ce71fSopenharmony_ci        return ret;
750a7ce71fSopenharmony_ci    }
760a7ce71fSopenharmony_ci
770a7ce71fSopenharmony_ci    mbedtls_md_init(&mbedtls_md_ctx);
780a7ce71fSopenharmony_ci    ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
790a7ce71fSopenharmony_ci    if (ret != 0) {
800a7ce71fSopenharmony_ci        mbedtls_md_free(&mbedtls_md_ctx);
810a7ce71fSopenharmony_ci        return ret;
820a7ce71fSopenharmony_ci    }
830a7ce71fSopenharmony_ci
840a7ce71fSopenharmony_ci    (void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
850a7ce71fSopenharmony_ci    (void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
860a7ce71fSopenharmony_ci    (void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
870a7ce71fSopenharmony_ci
880a7ce71fSopenharmony_ci    // <transfer the hash code to the string mode
890a7ce71fSopenharmony_ci    ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
900a7ce71fSopenharmony_ci    if (ret != 0) {
910a7ce71fSopenharmony_ci        return ret;
920a7ce71fSopenharmony_ci    }
930a7ce71fSopenharmony_ci
940a7ce71fSopenharmony_ci    return ret;
950a7ce71fSopenharmony_ci}