• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params->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(&params->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 }