• 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_ec_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 #define PAKE_PRIVATE_KEY_AND_MASK_HIGH 0xF8
24 #define PAKE_PRIVATE_KEY_AND_MASK_LOW  0x7F
25 #define PAKE_PRIVATE_KEY_OR_MASK_LOW   0x40
26 
GetPakeEcAlg(void)27 uint32_t GetPakeEcAlg(void)
28 {
29     return PAKE_ALG_EC;
30 }
31 
GenerateEsk(PakeBaseParams * params)32 static int32_t GenerateEsk(PakeBaseParams *params)
33 {
34     int32_t res;
35     if (params->curveType == CURVE_256) {
36         return params->loader->generateRandom(&(params->eskSelf));
37     } else if (params->curveType == CURVE_25519) {
38         res = params->loader->generateRandom(&(params->eskSelf));
39         if (res != HC_SUCCESS) {
40             LOGE("CURVE_25519: GenerateRandom for eskSelf failed, res: %x.", res);
41             return res;
42         }
43         params->eskSelf.val[PAKE_EC_KEY_LEN - 1] &= PAKE_PRIVATE_KEY_AND_MASK_HIGH;
44         params->eskSelf.val[0] &= PAKE_PRIVATE_KEY_AND_MASK_LOW;
45         params->eskSelf.val[0] |= PAKE_PRIVATE_KEY_OR_MASK_LOW;
46         return HC_SUCCESS;
47     } else {
48         LOGE("Unsupported curve: %d.", params->curveType);
49         return HC_ERR_UNSUPPORTED_CURVE;
50     }
51 }
52 
InitEcPakeParams(PakeBaseParams * params)53 static int32_t InitEcPakeParams(PakeBaseParams *params)
54 {
55     params->eskSelf.length = PAKE_EC_KEY_LEN;
56     params->innerKeyLen = PAKE_EC_KEY_LEN;
57     /* P256 requires buffer for both X and Y coordinates. */
58     uint32_t keyBufferLen = (params->curveType == CURVE_256) ? (params->innerKeyLen * 2) : (params->innerKeyLen);
59     int32_t res = InitSingleParam(&(params->eskSelf), params->eskSelf.length);
60     if (res !=  HC_SUCCESS) {
61         LOGE("InitSingleParam for eskSelf failed, res: %x.", res);
62         return res;
63     }
64     res = InitSingleParam(&(params->epkSelf), keyBufferLen);
65     if (res !=  HC_SUCCESS) {
66         LOGE("InitSingleParam for epkSelf failed, res: %x.", res);
67         return res;
68     }
69     res = InitSingleParam(&(params->base), keyBufferLen);
70     if (res !=  HC_SUCCESS) {
71         LOGE("InitSingleParam for base failed, res: %x.", res);
72         return res;
73     }
74     return res;
75 }
76 
GenerateEcPakeParams(PakeBaseParams * params,Uint8Buff * secret)77 int32_t GenerateEcPakeParams(PakeBaseParams *params, Uint8Buff *secret)
78 {
79     int32_t res = InitEcPakeParams(params);
80     if (res != HC_SUCCESS) {
81         LOGE("InitEcPakeParams failed, res: %x.", res);
82         goto CLEAN_UP;
83     }
84 
85     res = GenerateEsk(params);
86     if (res != HC_SUCCESS) {
87         LOGE("GenerateEsk failed, res: %x.", res);
88         goto CLEAN_UP;
89     }
90 
91     Algorithm alg = (params->curveType == CURVE_256) ? P256 : X25519;
92     res = params->loader->hashToPoint(secret, alg, &params->base);
93     if (res != HC_SUCCESS) {
94         LOGE("HashToPoint from secret to base failed, res: %x.", res);
95         goto CLEAN_UP;
96     }
97     KeyBuff eskSelfBuff = { params->eskSelf.val, params->eskSelf.length, false };
98     KeyBuff baseBuff = { params->base.val, params->base.length, false };
99     res = params->loader->agreeSharedSecret(&eskSelfBuff, &baseBuff, alg, &params->epkSelf);
100     if (res != HC_SUCCESS) {
101         LOGE("AgreeSharedSecret failed, res: %x.", res);
102         goto CLEAN_UP;
103     }
104     return res;
105 CLEAN_UP:
106     CleanPakeSensitiveKeys(params);
107     return res;
108 }
109 
AgreeEcSharedSecret(PakeBaseParams * params,Uint8Buff * sharedSecret)110 int32_t AgreeEcSharedSecret(PakeBaseParams *params, Uint8Buff *sharedSecret)
111 {
112     int32_t res;
113     /* P256 requires buffer for both X and Y coordinates. */
114     uint32_t validKeyBufferLen = (params->curveType == CURVE_256) ? (PAKE_EC_KEY_LEN * 2) : (PAKE_EC_KEY_LEN);
115     if (params->epkPeer.length != validKeyBufferLen) {
116         LOGE("Invalid epkPeer length: %u.", params->epkPeer.length);
117         res = HC_ERR_INVALID_LEN;
118         goto CLEAN_UP;
119     }
120 
121     Algorithm alg = (params->curveType == CURVE_256) ? P256 : X25519;
122     if (!params->loader->checkEcPublicKey(&(params->epkPeer), alg)) {
123         LOGE("Check public key failed.");
124         res = HC_ERR_INVALID_PUBLIC_KEY;
125         goto CLEAN_UP;
126     }
127     KeyBuff eskSelfBuff = { params->eskSelf.val, params->eskSelf.length, false };
128     KeyBuff epkPeerBuff = { params->epkPeer.val, params->epkPeer.length, false };
129     res = params->loader->agreeSharedSecret(&eskSelfBuff, &epkPeerBuff, alg, sharedSecret);
130     if (res != HC_SUCCESS) {
131         LOGE("AgreeSharedSecret failed, res: %x.", res);
132         goto CLEAN_UP;
133     }
134     return res;
135 CLEAN_UP:
136     CleanPakeSensitiveKeys(params);
137     return res;
138 }