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, ¶ms->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(¶ms->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 }