1 /*
2  * Copyright (c) 2020 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 "auth_info.h"
17 #include "securec.h"
18 #include "log.h"
19 #include "mem_stat.h"
20 #include "huks_adapter.h"
21 
22 #define HC_AUTH_DECRYPT_LEN 300
23 
24 #if !(defined(_CUT_PAKE_) || defined(_CUT_PAKE_SERVER_))
get_pake_session_key(const struct hichain * hichain)25 const struct pake_session_key *get_pake_session_key(const struct hichain *hichain)
26 {
27     if (hichain->pake_server == NULL) {
28         LOGE("Pake server object is NULL");
29         return NULL;
30     }
31     return &hichain->pake_server->session_key;
32 }
33 
get_pake_self_challenge(const struct hichain * hichain)34 const struct challenge *get_pake_self_challenge(const struct hichain *hichain)
35 {
36     if (hichain->pake_server == NULL) {
37         LOGE("Pake server object is NULL");
38         return NULL;
39     }
40     return &hichain->pake_server->self_challenge;
41 }
42 
get_pake_peer_challenge(const struct hichain * hichain)43 const struct challenge *get_pake_peer_challenge(const struct hichain *hichain)
44 {
45     if (hichain->pake_server == NULL) {
46         LOGE("Pake server object is NULL");
47         return NULL;
48     }
49     return &hichain->pake_server->peer_challenge;
50 }
51 
get_pake_self_auth_id(const struct hichain * hichain)52 const struct hc_auth_id *get_pake_self_auth_id(const struct hichain *hichain)
53 {
54     if (hichain->pake_server == NULL) {
55         LOGE("Pake server object is NULL");
56         return NULL;
57     }
58     return &hichain->pake_server->self_id;
59 }
60 
61 #endif /* _CUT_XXX_ */
62 
63 #if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_))
get_sts_session_key(const struct hichain * hichain)64 const struct sts_session_key *get_sts_session_key(const struct hichain *hichain)
65 {
66     if (hichain->sts_server == NULL) {
67         LOGE("Sts server object is NULL");
68         return NULL;
69     }
70     return &hichain->sts_server->session_key;
71 }
72 
73 #endif /* _CUT_XXX_ */
74 
encrypt_payload(const struct var_buffer * key,const struct uint8_buff * plain,const char * aad,struct uint8_buff * payload)75 int32_t encrypt_payload(const struct var_buffer *key, const struct uint8_buff *plain,
76     const char *aad, struct uint8_buff *payload)
77 {
78     struct aes_aad aes_aad;
79     (void)memset_s(&aes_aad, sizeof(aes_aad), 0, sizeof(aes_aad));
80     if (strcpy_s((char *)aes_aad.aad, sizeof(aes_aad.aad), aad) != EOK) {
81         LOGE("What happened was that the probability was zero"); /* caller perceives memory error, no return */
82     }
83     aes_aad.length = strlen(aad);
84     int32_t ret = aes_gcm_encrypt((struct var_buffer *)key, plain, &aes_aad, payload);
85     if (ret != HC_OK) {
86         LOGE("Encrypt payload failed, error code is %d", ret);
87         return HC_ENCRYPT_FAILED;
88     }
89     DBG_OUT("Encrypt payload success");
90     return HC_OK;
91 }
92 
decrypt_payload(const struct var_buffer * key,const struct uint8_buff * payload,const char * aad,struct uint8_buff * plain)93 int32_t decrypt_payload(const struct var_buffer *key, const struct uint8_buff *payload,
94     const char *aad, struct uint8_buff *plain)
95 {
96     plain->val = (uint8_t *)MALLOC(HC_AUTH_DECRYPT_LEN);
97     if (plain->val == NULL) {
98         LOGE("Malloc failed");
99         return HC_MALLOC_FAILED;
100     }
101     plain->size = HC_AUTH_DECRYPT_LEN;
102     plain->length = 0;
103     (void)memset_s(plain->val, plain->size, 0, plain->size);
104     struct aes_aad aes_aad;
105     (void)memset_s(&aes_aad, sizeof(aes_aad), 0, sizeof(aes_aad));
106     if (strcpy_s((char *)aes_aad.aad, sizeof(aes_aad.aad), aad) != EOK) {
107         LOGE("What happened was that the probability was zero"); /* caller perceives memory error, no return */
108     }
109     aes_aad.length = strlen(aad);
110     int32_t ret = aes_gcm_decrypt((struct var_buffer *)key, payload, &aes_aad, plain);
111     if (ret != HC_OK) {
112         LOGE("Decrypt payload failed");
113         FREE(plain->val);
114         plain->val = NULL;
115         plain->size = 0;
116         return HC_DECRYPT_FAILED;
117     }
118     DBG_OUT("Decrypt payload success");
119     return HC_OK;
120 }
121 
malloc_auth_info_msg(uint32_t size)122 struct auth_info_message *malloc_auth_info_msg(uint32_t size)
123 {
124     struct auth_info_message *data = (struct auth_info_message *)MALLOC(sizeof(struct auth_info_message));
125     if (data == NULL) {
126         LOGE("Malloc struct remove_response_data failed");
127         return NULL;
128     }
129     (void)memset_s(data, sizeof(*data), 0, sizeof(*data));
130     data->cipher.val = (uint8_t *)MALLOC(size);
131     if (data->cipher.val == NULL) {
132         LOGE("Malloc remove response val failed");
133         FREE(data);
134         return NULL;
135     }
136     (void)memset_s(data->cipher.val, size, 0, size);
137     data->cipher.size = size;
138     data->cipher.length = 0;
139     return data;
140 }
141 
free_auth_info_msg(struct auth_info_message * data)142 void free_auth_info_msg(struct auth_info_message *data)
143 {
144     FREE(data->cipher.val);
145     data->cipher.val = NULL;
146     FREE(data);
147 }
148 
save_auth_info(const struct hichain * hichain,int32_t pair_type,struct auth_info_cache * cache)149 int32_t save_auth_info(const struct hichain *hichain, int32_t pair_type, struct auth_info_cache *cache)
150 {
151     struct service_id service_id = generate_service_id(&hichain->identity);
152     if (service_id.length == 0) {
153         LOGE("Generate service id failed");
154         return HC_GEN_SERVICE_ID_FAILED;
155     }
156     enum huks_key_alias_type alias_type = (cache->user_type == HC_USER_TYPE_ACCESSORY) ?
157                                            KEY_ALIAS_ACCESSOR_PK : KEY_ALIAS_CONTROLLER_PK;
158     struct hc_key_alias alias = generate_key_alias(&service_id, &cache->auth_id, alias_type);
159     if (alias.length == 0) {
160         LOGE("Generate key alias failed");
161         return HC_GEN_ALIAS_FAILED;
162     }
163     int32_t ret = import_lt_public_key(&alias, &cache->ltpk, cache->user_type, pair_type, &cache->auth_id);
164     if (ret != HC_OK) {
165         LOGE("Import ltpk failed, error code is %d", ret);
166         return HC_SAVE_LTPK_FAILED;
167     }
168     ret = check_lt_public_key_exist(&alias);
169     if (ret != HC_OK) {
170         LOGE("Check ltpk failed, error code is %d", ret);
171         return HC_SAVE_LTPK_FAILED;
172     }
173     DBG_OUT("Save ltpk success");
174     return HC_OK;
175 }
176 
build_auth_client_info(struct hc_auth_id auth_id,int32_t user_type)177 struct auth_info_cache *build_auth_client_info(struct hc_auth_id auth_id, int32_t user_type)
178 {
179     struct auth_info_cache *auth_info = MALLOC(sizeof(struct auth_info_cache));
180     if (auth_info == NULL) {
181         LOGE("Malloc failed");
182         return NULL;
183     }
184     (void)memset_s(auth_info, sizeof(*auth_info), 0, sizeof(*auth_info));
185     auth_info->user_type = user_type;
186     auth_info->auth_id = auth_id;
187 
188     return auth_info;
189 }
190 
destroy_auth_client(struct auth_info_cache * auth_info)191 void destroy_auth_client(struct auth_info_cache *auth_info)
192 {
193     if (auth_info == NULL) {
194         LOGE("Destroy auth info client object failed");
195         return;
196     }
197     FREE(auth_info);
198 }
199