1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hmac_key.h"
17 
18 #include <stddef.h>
19 #include <string.h>
20 
21 #include "adaptor_algorithm.h"
22 #include "adaptor_log.h"
23 #include "buffer.h"
24 #include "defines.h"
25 #include "sign_param.h"
26 #include "udid_manager.h"
27 
GenerateHmacKey(const Buffer * peerUdid)28 static Buffer *GenerateHmacKey(const Buffer *peerUdid)
29 {
30     if (!CheckBufferWithSize(peerUdid, UDID_LEN)) {
31         LOG_ERROR("param is invalid");
32         return NULL;
33     }
34 
35     uint8_t udid[UDID_LEN] = {};
36     Uint8Array localUdidArray = { .data = udid, .len = UDID_LEN };
37     if (!GetLocalUdid(&localUdidArray)) {
38         LOG_ERROR("GetLocalUdid fail");
39         return NULL;
40     }
41     Buffer localUdidBuf = GetTmpBuffer(localUdidArray.data, localUdidArray.len, localUdidArray.len);
42 
43     Buffer *salt = NULL;
44     if (memcmp(localUdidBuf.buf, peerUdid->buf, UDID_LEN) < 0) {
45         salt = MergeBuffers(&localUdidBuf, peerUdid);
46     } else {
47         salt = MergeBuffers(peerUdid, &localUdidBuf);
48     }
49     if (!IsBufferValid(salt)) {
50         LOG_ERROR("generate salt failed");
51         return NULL;
52     }
53     Buffer *key = NULL;
54     ResultCode result = (ResultCode)GetDistributeKey(peerUdid, salt, &key);
55     DestoryBuffer(salt);
56     if (result != RESULT_SUCCESS) {
57         LOG_ERROR("GetDistributeKey failed");
58         return NULL;
59     }
60     if (!IsBufferValid(key)) {
61         DestoryBuffer(key);
62         LOG_ERROR("GenerateHmacKey fail");
63         return NULL;
64     }
65     return key;
66 }
67 
HmacSign(const Buffer * data,SignParam signParam)68 Buffer *HmacSign(const Buffer *data, SignParam signParam)
69 {
70     if (signParam.keyType != KEY_TYPE_CROSS_DEVICE || !IsBufferValid(data)) {
71         LOG_ERROR("invalid param");
72         return NULL;
73     }
74 
75     Buffer peerUdidBuf = GetTmpBuffer(signParam.peerUdid.data, signParam.peerUdid.len, signParam.peerUdid.len);
76     Buffer *key = GenerateHmacKey(&peerUdidBuf);
77     if (!IsBufferValid(key)) {
78         LOG_ERROR("GenerateHmacKey failed");
79         return NULL;
80     }
81 
82     Buffer *signature = NULL;
83     int32_t ret = HmacSha256(key, data, &signature);
84     DestoryBuffer(key);
85     if (ret != RESULT_SUCCESS) {
86         LOG_ERROR("HmacSha256 failed");
87         return NULL;
88     }
89 
90     if (!CheckBufferWithSize(signature, SHA256_DIGEST_SIZE)) {
91         LOG_ERROR("CheckBufferWithSize failed");
92         DestoryBuffer(signature);
93         return NULL;
94     }
95 
96     LOG_INFO("HmacSign success");
97     return signature;
98 }
99 
HmacVerify(const Buffer * data,const Buffer * sign,SignParam signParam)100 ResultCode HmacVerify(const Buffer *data, const Buffer *sign, SignParam signParam)
101 {
102     if (signParam.keyType != KEY_TYPE_CROSS_DEVICE || !IsBufferValid(data) || !IsBufferValid(sign)) {
103         LOG_ERROR("invalid param");
104         return RESULT_BAD_PARAM;
105     }
106 
107     Buffer peerUdidBuf = GetTmpBuffer(signParam.peerUdid.data, signParam.peerUdid.len, signParam.peerUdid.len);
108     Buffer *key = GenerateHmacKey(&peerUdidBuf);
109     if (!IsBufferValid(key)) {
110         LOG_ERROR("GenerateHmacKey failed");
111         return RESULT_GENERAL_ERROR;
112     }
113 
114     Buffer *rightSign = NULL;
115     ResultCode ret = HmacSha256(key, data, &rightSign);
116     DestoryBuffer(key);
117     if (ret != RESULT_SUCCESS) {
118         LOG_ERROR("HmacSha256 failed");
119         return RESULT_GENERAL_ERROR;
120     }
121     if (!CompareBuffer(rightSign, sign)) {
122         LOG_ERROR("sign compare failed");
123         DestoryBuffer(rightSign);
124         return RESULT_BAD_SIGN;
125     }
126     LOG_INFO("HmacVerify success");
127     DestoryBuffer(rightSign);
128     return RESULT_SUCCESS;
129 }