1 /*
2  * Copyright (C) 2023 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_sub_session.h"
17 
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "iso_protocol.h"
22 #include "ec_speke_protocol.h"
23 #include "dl_speke_protocol.h"
24 
25 #define MAX_MSG_LEN 1024
26 
27 typedef int32_t (*CreateProtocolFunc)(const void *baseParams, bool isClient, BaseProtocol **);
28 
29 typedef struct {
30     int32_t protocolType;
31     CreateProtocolFunc createProtocolFunc;
32 } ProtocolComponent;
33 
34 typedef struct {
35     AuthSubSession base;
36     BaseProtocol *instance;
37 } AuthSubSessionImpl;
38 
39 static const ProtocolComponent PROTOCOL_COMPONENT_LIB[] = {
40 #ifdef ENABLE_EC_SPEKE
41     { PROTOCOL_TYPE_EC_SPEKE, CreateEcSpekeProtocol },
42 #endif
43 #ifdef ENABLE_P2P_BIND_DL_SPEKE
44     { PROTOCOL_TYPE_DL_SPEKE, CreateDlSpekeProtocol },
45 #endif
46 #ifdef ENABLE_ISO
47     { PROTOCOL_TYPE_ISO, CreateIsoProtocol },
48 #endif
49 };
50 
GetProtocolComponent(int32_t protocolType)51 static const ProtocolComponent *GetProtocolComponent(int32_t protocolType)
52 {
53     for (uint32_t i = 0; i < sizeof(PROTOCOL_COMPONENT_LIB) / sizeof(ProtocolComponent); i++) {
54         if (PROTOCOL_COMPONENT_LIB[i].protocolType == protocolType) {
55             return &PROTOCOL_COMPONENT_LIB[i];
56         }
57     }
58     return NULL;
59 }
60 
StartAuthSubSession(AuthSubSession * self,CJson ** returnSendMsg)61 static int32_t StartAuthSubSession(AuthSubSession *self, CJson **returnSendMsg)
62 {
63     if ((self == NULL) || (returnSendMsg == NULL)) {
64         LOGE("invalid params.");
65         return HC_ERR_INVALID_PARAMS;
66     }
67     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
68     BaseProtocol *protocol = impl->instance;
69     int32_t res = protocol->start(protocol, returnSendMsg);
70     if (res != HC_SUCCESS) {
71         return res;
72     }
73     impl->base.state = AUTH_STATE_RUNNING;
74     return HC_SUCCESS;
75 }
76 
ProcessAuthSubSession(AuthSubSession * self,const CJson * receviedMsg,CJson ** returnSendMsg)77 static int32_t ProcessAuthSubSession(AuthSubSession *self, const CJson *receviedMsg, CJson **returnSendMsg)
78 {
79     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL)) {
80         LOGE("invalid params.");
81         return HC_ERR_INVALID_PARAMS;
82     }
83     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
84     BaseProtocol *protocol = impl->instance;
85     int32_t res = protocol->process(protocol, receviedMsg, returnSendMsg);
86     if (res != HC_SUCCESS) {
87         return res;
88     }
89     impl->base.state = (protocol->curState == protocol->finishState) ? AUTH_STATE_FINISH : AUTH_STATE_RUNNING;
90     return HC_SUCCESS;
91 }
92 
SetPsk(AuthSubSession * self,const Uint8Buff * psk)93 static int32_t SetPsk(AuthSubSession *self, const Uint8Buff *psk)
94 {
95     if ((self == NULL) || (psk == NULL)) {
96         LOGE("invalid params.");
97         return HC_ERR_INVALID_PARAMS;
98     }
99     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
100     return impl->instance->setPsk(impl->instance, psk);
101 }
102 
SetSelfProtectedMsg(AuthSubSession * self,const Uint8Buff * selfMsg)103 static int32_t SetSelfProtectedMsg(AuthSubSession *self, const Uint8Buff *selfMsg)
104 {
105     if ((self == NULL) || (selfMsg == NULL)) {
106         LOGE("invalid params.");
107         return HC_ERR_INVALID_PARAMS;
108     }
109     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
110     return impl->instance->setSelfProtectedMsg(impl->instance, selfMsg);
111 }
112 
SetPeerProtectedMsg(AuthSubSession * self,const Uint8Buff * peerMsg)113 static int32_t SetPeerProtectedMsg(AuthSubSession *self, const Uint8Buff *peerMsg)
114 {
115     if ((self == NULL) || (peerMsg == NULL)) {
116         LOGE("invalid params.");
117         return HC_ERR_INVALID_PARAMS;
118     }
119     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
120     return impl->instance->setPeerProtectedMsg(impl->instance, peerMsg);
121 }
122 
GetSessionKey(AuthSubSession * self,Uint8Buff * returnSessionKey)123 static int32_t GetSessionKey(AuthSubSession *self, Uint8Buff *returnSessionKey)
124 {
125     if ((self == NULL) || (returnSessionKey == NULL)) {
126         LOGE("invalid params.");
127         return HC_ERR_INVALID_PARAMS;
128     }
129     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
130     return impl->instance->getSessionKey(impl->instance, returnSessionKey);
131 }
132 
DestroyAuthSubSession(AuthSubSession * self)133 static void DestroyAuthSubSession(AuthSubSession *self)
134 {
135     if (self == NULL) {
136         LOGD("self is NULL.");
137         return;
138     }
139     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)self;
140     impl->instance->destroy(impl->instance);
141     HcFree(impl);
142 }
143 
CreateAuthSubSession(int32_t protocolType,void * params,bool isClient,AuthSubSession ** returnObj)144 int32_t CreateAuthSubSession(int32_t protocolType, void *params, bool isClient, AuthSubSession **returnObj)
145 {
146     if ((params == NULL) || (returnObj == NULL)) {
147         LOGE("invalid params.");
148         return HC_ERR_INVALID_PARAMS;
149     }
150     const ProtocolComponent *component = GetProtocolComponent(protocolType);
151     if (component == NULL) {
152         LOGE("no protocol component found. type = %d.", protocolType);
153         return HC_ERR_UNSUPPORTED_VERSION;
154     }
155     BaseProtocol *protocol;
156     int32_t res = component->createProtocolFunc(params, isClient, &protocol);
157     if (res != HC_SUCCESS) {
158         LOGE("create protocol fail.");
159         return res;
160     }
161     AuthSubSessionImpl *impl = (AuthSubSessionImpl *)HcMalloc(sizeof(AuthSubSessionImpl), 0);
162     if (impl == NULL) {
163         LOGE("allocate impl memory fail.");
164         protocol->destroy(protocol);
165         return HC_ERR_ALLOC_MEMORY;
166     }
167     impl->base.protocolType = protocolType;
168     impl->base.state = AUTH_STATE_INIT;
169     impl->base.start = StartAuthSubSession;
170     impl->base.process = ProcessAuthSubSession;
171     impl->base.setPsk = SetPsk;
172     impl->base.setSelfProtectedMsg = SetSelfProtectedMsg;
173     impl->base.setPeerProtectedMsg = SetPeerProtectedMsg;
174     impl->base.getSessionKey = GetSessionKey;
175     impl->base.destroy = DestroyAuthSubSession;
176     impl->instance = protocol;
177     *returnObj = (AuthSubSession *)impl;
178     return HC_SUCCESS;
179 }
180 
IsProtocolSupport(int32_t protocolType)181 bool IsProtocolSupport(int32_t protocolType)
182 {
183     return GetProtocolComponent(protocolType) != NULL;
184 }
185