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: %" LOG_PUB "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: %" LOG_PUB "x, Invalid epkPeer length: %" LOG_PUB "u.",
76 params->supportedDlPrimeMod, params->epkPeer.length);
77 return HC_ERR_INVALID_LEN;
78 }
79
FillDlKeysLenAccordingToMod(PakeBaseParams * params)80 static int FillDlKeysLenAccordingToMod(PakeBaseParams *params)
81 {
82 if (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_384) != 0) {
83 params->eskSelf.length = PAKE_DL_ESK_LEN;
84 params->innerKeyLen = PAKE_DL_PRIME_LEN;
85 return HC_SUCCESS;
86 }
87 if (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_256) != 0) {
88 params->eskSelf.length = PAKE_DL_ESK_SMALL_LEN;
89 params->innerKeyLen = PAKE_DL_PRIME_SMALL_LEN;
90 return HC_SUCCESS;
91 }
92 LOGE("Unsupported PAKE DL mod: %" LOG_PUB "x.", params->supportedDlPrimeMod);
93 return HC_ERR_NOT_SUPPORT;
94 }
95
InitDlPakeParams(PakeBaseParams * params)96 static int32_t InitDlPakeParams(PakeBaseParams *params)
97 {
98 int32_t res;
99 if (params->isClient) {
100 res = FillDlKeysLenAccordingToEpkPeer(params);
101 } else {
102 res = FillDlKeysLenAccordingToMod(params);
103 }
104 if (res != HC_SUCCESS) {
105 LOGE("FillDlKeysLen failed, res: %" LOG_PUB "x.", res);
106 return res;
107 }
108 res = InitSingleParam(&(params->eskSelf), params->eskSelf.length);
109 if (res != HC_SUCCESS) {
110 LOGE("InitSingleParam for eskSelf failed, res: %" LOG_PUB "x.", res);
111 return res;
112 }
113 res = InitSingleParam(&(params->epkSelf), params->innerKeyLen);
114 if (res != HC_SUCCESS) {
115 LOGE("InitSingleParam for epkSelf failed, res: %" LOG_PUB "x.", res);
116 return res;
117 }
118 res = InitSingleParam(&(params->base), params->innerKeyLen);
119 if (res != HC_SUCCESS) {
120 LOGE("InitSingleParam for base failed, res: %" LOG_PUB "x.", res);
121 return res;
122 }
123 return res;
124 }
125
GenerateDlPakeParams(PakeBaseParams * params,const Uint8Buff * secret)126 int32_t GenerateDlPakeParams(PakeBaseParams *params, const Uint8Buff *secret)
127 {
128 int32_t res = InitDlPakeParams(params);
129 if (res != HC_SUCCESS) {
130 LOGE("InitDlPakeParams failed, res: %" LOG_PUB "x.", res);
131 goto CLEAN_UP;
132 }
133 res = GenerateEsk(params);
134 if (res != HC_SUCCESS) {
135 LOGE("GenerateEsk failed, res: %" LOG_PUB "x.", res);
136 goto CLEAN_UP;
137 }
138 uint8_t expVal[PAKE_DL_EXP_LEN] = { 2 };
139 Uint8Buff exp = { expVal, PAKE_DL_EXP_LEN };
140 params->largePrimeNumHex = (params->innerKeyLen == PAKE_DL_PRIME_SMALL_LEN) ?
141 g_largePrimeNumberHex256 : g_largePrimeNumberHex384;
142 res = params->loader->bigNumExpMod(secret, &exp, params->largePrimeNumHex, ¶ms->base);
143 if (res != HC_SUCCESS) {
144 LOGE("BigNumExpMod for base failed, res: %" LOG_PUB "x.", res);
145 goto CLEAN_UP;
146 }
147
148 res = params->loader->bigNumExpMod(¶ms->base, &(params->eskSelf), params->largePrimeNumHex, &(params->epkSelf));
149 if (res != HC_SUCCESS) {
150 LOGE("BigNumExpMod for epkSelf failed, res: %" LOG_PUB "x.", res);
151 goto CLEAN_UP;
152 }
153 return res;
154 CLEAN_UP:
155 CleanPakeSensitiveKeys(params);
156 return res;
157 }
158
IsEpkPeerLenInvalid(PakeBaseParams * params)159 static bool IsEpkPeerLenInvalid(PakeBaseParams *params)
160 {
161 if ((params->epkPeer.length == PAKE_DL_PRIME_LEN) &&
162 (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_384) != 0)) {
163 return false;
164 }
165 if ((params->epkPeer.length == PAKE_DL_PRIME_SMALL_LEN) &&
166 (((uint32_t)params->supportedDlPrimeMod & DL_PRIME_MOD_256) != 0)) {
167 return false;
168 }
169 LOGE("Invalid epkPeer length: %" LOG_PUB "u.", params->epkPeer.length);
170 return true;
171 }
172
AgreeDlSharedSecret(PakeBaseParams * params,Uint8Buff * sharedSecret)173 int32_t AgreeDlSharedSecret(PakeBaseParams *params, Uint8Buff *sharedSecret)
174 {
175 int res;
176 if (IsEpkPeerLenInvalid(params)) {
177 res = HC_ERR_INVALID_LEN;
178 goto CLEAN_UP;
179 }
180 if (!params->loader->checkDlPublicKey(&(params->epkPeer), params->largePrimeNumHex)) {
181 LOGE("CheckDlPublicKey failed.");
182 res = HC_ERR_INVALID_PUBLIC_KEY;
183 goto CLEAN_UP;
184 }
185 res = params->loader->bigNumExpMod(&(params->epkPeer), &(params->eskSelf), params->largePrimeNumHex, sharedSecret);
186 if (res != HC_SUCCESS) {
187 LOGE("BigNumExpMod for sharedSecret failed, res: %" LOG_PUB "x.", res);
188 goto CLEAN_UP;
189 }
190 return res;
191 CLEAN_UP:
192 CleanPakeSensitiveKeys(params);
193 return res;
194 }