1 /*
2  * Copyright (C) 2021 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 "pake_protocol_dl_common.h"
17 #include "device_auth_defines.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "pake_defs.h"
21 #include "protocol_common.h"
22 
23 static const char * const g_largePrimeNumberHex384 =
24     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"\
25     "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"\
26     "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"\
27     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"\
28     "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"\
29     "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"\
30     "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"\
31     "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33"\
32     "A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"\
33     "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864"\
34     "D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2"\
35     "08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
36 
37 static const char * const g_largePrimeNumberHex256 =
38     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"\
39     "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"\
40     "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"\
41     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"\
42     "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"\
43     "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"\
44     "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"\
45     "3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
46 
GetPakeDlAlg(void)47 uint32_t GetPakeDlAlg(void)
48 {
49     return PAKE_ALG_DL;
50 }
51 
GenerateEsk(PakeBaseParams * params)52 static int32_t GenerateEsk(PakeBaseParams *params)
53 {
54     int res = params->loader->generateRandom(&(params->eskSelf));
55     if (res != HC_SUCCESS) {
56         LOGE("GenerateRandom for eskSelf failed, res: %x.", res);
57     }
58     return res;
59 }
60 
FillDlKeysLenAccordingToEpkPeer(PakeBaseParams * params)61 static int FillDlKeysLenAccordingToEpkPeer(PakeBaseParams *params)
62 {
63     if ((params->epkPeer.length == PAKE_DL_PRIME_LEN) &&
64         (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_384) != 0)) {
65         params->eskSelf.length = PAKE_DL_ESK_LEN;
66         params->innerKeyLen = PAKE_DL_PRIME_LEN;
67         return HC_SUCCESS;
68     }
69     if ((params->epkPeer.length == PAKE_DL_PRIME_SMALL_LEN) &&
70         (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_256) != 0)) {
71         params->eskSelf.length = PAKE_DL_ESK_SMALL_LEN;
72         params->innerKeyLen = PAKE_DL_PRIME_SMALL_LEN;
73         return HC_SUCCESS;
74     }
75     LOGE("PAKE DL mod: %x, Invalid epkPeer length: %u.", params->supportedDlPrimeMod, params->epkPeer.length);
76     return HC_ERR_INVALID_LEN;
77 }
78 
FillDlKeysLenAccordingToMod(PakeBaseParams * params)79 static int FillDlKeysLenAccordingToMod(PakeBaseParams *params)
80 {
81     if (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_384) != 0) {
82         params->eskSelf.length = PAKE_DL_ESK_LEN;
83         params->innerKeyLen = PAKE_DL_PRIME_LEN;
84         return HC_SUCCESS;
85     }
86     if (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_256) != 0) {
87         params->eskSelf.length = PAKE_DL_ESK_SMALL_LEN;
88         params->innerKeyLen = PAKE_DL_PRIME_SMALL_LEN;
89         return HC_SUCCESS;
90     }
91     LOGE("Unsupported PAKE DL mod: %x.", params->supportedDlPrimeMod);
92     return HC_ERR_NOT_SUPPORT;
93 }
94 
InitDlPakeParams(PakeBaseParams * params)95 static int32_t InitDlPakeParams(PakeBaseParams *params)
96 {
97     int32_t res;
98     if (params->isClient) {
99         res = FillDlKeysLenAccordingToEpkPeer(params);
100     } else {
101         res = FillDlKeysLenAccordingToMod(params);
102     }
103     if (res != HC_SUCCESS) {
104         LOGE("FillDlKeysLen failed, res: %x.", res);
105         return res;
106     }
107     res = InitSingleParam(&(params->eskSelf), params->eskSelf.length);
108     if (res !=  HC_SUCCESS) {
109         LOGE("InitSingleParam for eskSelf failed, res: %x.", res);
110         return res;
111     }
112     res = InitSingleParam(&(params->epkSelf), params->innerKeyLen);
113     if (res !=  HC_SUCCESS) {
114         LOGE("InitSingleParam for epkSelf failed, res: %x.", res);
115         return res;
116     }
117     res = InitSingleParam(&(params->base), params->innerKeyLen);
118     if (res !=  HC_SUCCESS) {
119         LOGE("InitSingleParam for base failed, res: %x.", res);
120         return res;
121     }
122     return res;
123 }
124 
GenerateDlPakeParams(PakeBaseParams * params,const Uint8Buff * secret)125 int32_t GenerateDlPakeParams(PakeBaseParams *params, const Uint8Buff *secret)
126 {
127     int32_t res = InitDlPakeParams(params);
128     if (res != HC_SUCCESS) {
129         LOGE("InitDlPakeParams failed, res: %x.", res);
130         goto CLEAN_UP;
131     }
132     res = GenerateEsk(params);
133     if (res != HC_SUCCESS) {
134         LOGE("GenerateEsk failed, res: %x.", res);
135         goto CLEAN_UP;
136     }
137     uint8_t expVal[PAKE_DL_EXP_LEN] = { 2 };
138     Uint8Buff exp = { expVal, PAKE_DL_EXP_LEN };
139     params->largePrimeNumHex = (params->innerKeyLen == PAKE_DL_PRIME_SMALL_LEN) ?
140         g_largePrimeNumberHex256 : g_largePrimeNumberHex384;
141     res = params->loader->bigNumExpMod(secret, &exp, params->largePrimeNumHex, &params->base);
142     if (res != HC_SUCCESS) {
143         LOGE("BigNumExpMod for base failed, res: %x.", res);
144         goto CLEAN_UP;
145     }
146 
147     res = params->loader->bigNumExpMod(&params->base, &(params->eskSelf), params->largePrimeNumHex, &(params->epkSelf));
148     if (res != HC_SUCCESS) {
149         LOGE("BigNumExpMod for epkSelf failed, res: %x.", res);
150         goto CLEAN_UP;
151     }
152     return res;
153 CLEAN_UP:
154     CleanPakeSensitiveKeys(params);
155     return res;
156 }
157 
IsEpkPeerLenInvalid(PakeBaseParams * params)158 static bool IsEpkPeerLenInvalid(PakeBaseParams *params)
159 {
160     if ((params->epkPeer.length == PAKE_DL_PRIME_LEN) &&
161         (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_384) != 0)) {
162         return false;
163     }
164     if ((params->epkPeer.length == PAKE_DL_PRIME_SMALL_LEN) &&
165         (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_256) != 0)) {
166         return false;
167     }
168     LOGE("Invalid epkPeer length: %u.", params->epkPeer.length);
169     return true;
170 }
171 
AgreeDlSharedSecret(PakeBaseParams * params,Uint8Buff * sharedSecret)172 int32_t AgreeDlSharedSecret(PakeBaseParams *params, Uint8Buff *sharedSecret)
173 {
174     int res;
175     if (IsEpkPeerLenInvalid(params)) {
176         res = HC_ERR_INVALID_LEN;
177         goto CLEAN_UP;
178     }
179     if (!params->loader->checkDlPublicKey(&(params->epkPeer), params->largePrimeNumHex)) {
180         LOGE("CheckDlPublicKey failed.");
181         res = HC_ERR_INVALID_PUBLIC_KEY;
182         goto CLEAN_UP;
183     }
184     res = params->loader->bigNumExpMod(&(params->epkPeer), &(params->eskSelf), params->largePrimeNumHex, sharedSecret);
185     if (res != HC_SUCCESS) {
186         LOGE("BigNumExpMod for sharedSecret failed, res: %x.", res);
187         goto CLEAN_UP;
188     }
189     return res;
190 CLEAN_UP:
191     CleanPakeSensitiveKeys(params);
192     return res;
193 }