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 }