1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15 #include <stdint.h>
16 #include "securec.h"
17 #include "bsl_errno.h"
18 #include "bsl_err_internal.h"
19 #include "bsl_sal.h"
20 #include "bsl_bytes.h"
21 #include "auth_errno.h"
22 #include "auth_params.h"
23 #include "auth_privpass_token.h"
24 #include "privpass_token.h"
25
26 #define PRIVPASS_TOKEN_MAX_ENCODE_PUBKEY_LEN 1024
27
SetAndValidateTokenType(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)28 static int32_t SetAndValidateTokenType(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
29 {
30 const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE);
31 if (temp == NULL) {
32 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_TYPE);
33 return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_TYPE;
34 }
35
36 uint32_t tokenTypeLen = (uint32_t)sizeof(tokenChallenge->tokenType);
37 uint16_t tokenType = 0;
38 int32_t ret = BSL_PARAM_GetValue(temp, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE, BSL_PARAM_TYPE_UINT16,
39 &tokenType, &tokenTypeLen);
40 if (ret != BSL_SUCCESS) {
41 BSL_ERR_PUSH_ERROR(ret);
42 return ret;
43 }
44 if (tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
45 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
46 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
47 }
48 tokenChallenge->tokenType = tokenType;
49 return HITLS_AUTH_SUCCESS;
50 }
51
SetIssuerName(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)52 static int32_t SetIssuerName(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
53 {
54 const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ISSUERNAME);
55 if (temp == NULL) {
56 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_ISSUERNAME);
57 return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_ISSUERNAME;
58 }
59
60 if (temp->valueLen == 0 || temp->valueLen > PRIVPASS_MAX_ISSUER_NAME_LEN) {
61 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ISSUER_NAME);
62 return HITLS_AUTH_PRIVPASS_INVALID_ISSUER_NAME;
63 }
64
65 tokenChallenge->issuerName.data = BSL_SAL_Dump(temp->value, temp->valueLen);
66 if (tokenChallenge->issuerName.data == NULL) {
67 BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
68 return BSL_DUMP_FAIL;
69 }
70 tokenChallenge->issuerName.dataLen = temp->valueLen;
71 return HITLS_AUTH_SUCCESS;
72 }
73
SetOptionalFields(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)74 static int32_t SetOptionalFields(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
75 {
76 // Set redemption
77 const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_REDEMPTION);
78 if (temp == NULL) {
79 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REDEMPTION);
80 return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REDEMPTION;
81 }
82 if (temp->valueLen != 0) {
83 if (temp->valueLen != PRIVPASS_REDEMPTION_LEN) {
84 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_REDEMPTION);
85 return HITLS_AUTH_PRIVPASS_INVALID_REDEMPTION;
86 }
87 tokenChallenge->redemption.data = BSL_SAL_Dump(temp->value, temp->valueLen);
88 if (tokenChallenge->redemption.data == NULL) {
89 BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
90 return BSL_DUMP_FAIL;
91 }
92 tokenChallenge->redemption.dataLen = temp->valueLen;
93 }
94
95 // Set originInfo (optional)
96 temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ORIGININFO);
97 if (temp != NULL && temp->valueLen > 0) {
98 if (temp->valueLen > PRIVPASS_MAX_ORIGIN_INFO_LEN) {
99 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ORIGIN_INFO);
100 return HITLS_AUTH_PRIVPASS_INVALID_ORIGIN_INFO;
101 }
102 tokenChallenge->originInfo.data = BSL_SAL_Dump(temp->value, temp->valueLen);
103 if (tokenChallenge->originInfo.data == NULL) {
104 BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
105 return BSL_DUMP_FAIL;
106 }
107 tokenChallenge->originInfo.dataLen = temp->valueLen;
108 }
109 return HITLS_AUTH_SUCCESS;
110 }
111
HITLS_AUTH_PrivPassGenTokenChallenge(HITLS_AUTH_PrivPassCtx * ctx,const BSL_Param * param,HITLS_AUTH_PrivPassToken ** challenge)112 int32_t HITLS_AUTH_PrivPassGenTokenChallenge(HITLS_AUTH_PrivPassCtx *ctx, const BSL_Param *param,
113 HITLS_AUTH_PrivPassToken **challenge)
114 {
115 (void)ctx;
116 if (param == NULL || challenge == NULL || *challenge != NULL) {
117 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
118 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
119 }
120
121 HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE);
122 if (output == NULL) {
123 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
124 return BSL_MALLOC_FAIL;
125 }
126 uint64_t challengeLen;
127 PrivPass_TokenChallenge *tokenChallenge = output->st.tokenChallenge;
128 int32_t ret = SetAndValidateTokenType(param, tokenChallenge);
129 if (ret != HITLS_AUTH_SUCCESS) {
130 HITLS_AUTH_PrivPassFreeToken(output);
131 return ret;
132 }
133
134 ret = SetIssuerName(param, tokenChallenge);
135 if (ret != HITLS_AUTH_SUCCESS) {
136 HITLS_AUTH_PrivPassFreeToken(output);
137 return ret;
138 }
139
140 ret = SetOptionalFields(param, tokenChallenge);
141 if (ret != HITLS_AUTH_SUCCESS) {
142 HITLS_AUTH_PrivPassFreeToken(output);
143 return ret;
144 }
145 challengeLen = sizeof(tokenChallenge->tokenType) + tokenChallenge->issuerName.dataLen +
146 tokenChallenge->redemption.dataLen + tokenChallenge->originInfo.dataLen;
147 if (challengeLen > UINT32_MAX) {
148 HITLS_AUTH_PrivPassFreeToken(output);
149 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_PARAM);
150 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_PARAM;
151 }
152 *challenge = output;
153 return HITLS_AUTH_SUCCESS;
154 }
155
ParamCheckOfGenTokenReq(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,HITLS_AUTH_PrivPassToken ** tokenRequest)156 static int32_t ParamCheckOfGenTokenReq(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
157 HITLS_AUTH_PrivPassToken **tokenRequest)
158 {
159 if (ctx == NULL || ctx->method.blind == NULL || ctx->method.digest == NULL || ctx->method.random == NULL ||
160 tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
161 tokenRequest == NULL || *tokenRequest != NULL) {
162 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
163 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
164 }
165 if (tokenChallenge->st.tokenChallenge->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
166 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
167 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
168 }
169 if (ctx->pubKeyCtx == NULL) {
170 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
171 return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
172 }
173 return HITLS_AUTH_SUCCESS;
174 }
175
ObtainAuthenticatorLen(uint16_t tokenType)176 static uint32_t ObtainAuthenticatorLen(uint16_t tokenType)
177 {
178 if (tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
179 return (uint32_t)PRIVPASS_TOKEN_NK;
180 }
181 return 0;
182 }
183
GenerateChallengeDigest(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,uint8_t * challengeDigest)184 static int32_t GenerateChallengeDigest(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
185 uint8_t *challengeDigest)
186 {
187 uint8_t *challenge = NULL;
188 uint32_t challengeLen = 0;
189 uint32_t challengeDigestLen = PRIVPASS_TOKEN_SHA256_SIZE;
190 int32_t ret = HITLS_AUTH_PrivPassSerialization(ctx, tokenChallenge, NULL, &challengeLen);
191 if (ret != HITLS_AUTH_SUCCESS) {
192 BSL_ERR_PUSH_ERROR(ret);
193 return ret;
194 }
195 challenge = BSL_SAL_Malloc(challengeLen);
196 if (challenge == NULL) {
197 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
198 return BSL_MALLOC_FAIL;
199 }
200 ret = HITLS_AUTH_PrivPassSerialization(ctx, tokenChallenge, challenge, &challengeLen);
201 if (ret != HITLS_AUTH_SUCCESS) {
202 BSL_SAL_Free(challenge);
203 BSL_ERR_PUSH_ERROR(ret);
204 return ret;
205 }
206 ret = ctx->method.digest(NULL, NULL, HITLS_AUTH_PRIVPASS_CRYPTO_SHA256, challenge, challengeLen, challengeDigest,
207 &challengeDigestLen);
208 BSL_SAL_Free(challenge);
209 if (ret != HITLS_AUTH_SUCCESS) {
210 BSL_ERR_PUSH_ERROR(ret);
211 }
212 return ret;
213 }
214
HITLS_AUTH_PrivPassGenTokenReq(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,HITLS_AUTH_PrivPassToken ** tokenRequest)215 int32_t HITLS_AUTH_PrivPassGenTokenReq(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
216 HITLS_AUTH_PrivPassToken **tokenRequest)
217 {
218 int32_t ret = ParamCheckOfGenTokenReq(ctx, tokenChallenge, tokenRequest);
219 if (ret != HITLS_AUTH_SUCCESS) {
220 return ret;
221 }
222 HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_REQUEST);
223 if (output == NULL) {
224 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
225 return BSL_MALLOC_FAIL;
226 }
227 uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
228 const PrivPass_TokenChallenge *challenge = tokenChallenge->st.tokenChallenge;
229 PrivPass_TokenRequest *request = output->st.tokenRequest;
230 uint32_t authenticatorLen = ObtainAuthenticatorLen(challenge->tokenType); // challenge->tokenType has been checked.
231 // Construct token_input = concat(token_type, nonce, challenge_digest, token_key_id)
232 uint8_t tokenInput[HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN];
233 size_t offset = 0;
234 // Copy token type from challenge
235 request->tokenType = challenge->tokenType;
236 request->truncatedTokenKeyId = ctx->tokenKeyId[PRIVPASS_TOKEN_SHA256_SIZE - 1];
237 // cal tokenChallengeDigest
238 ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
239 if (ret != HITLS_AUTH_SUCCESS) {
240 BSL_ERR_PUSH_ERROR(ret);
241 goto ERR;
242 }
243 // Generate nonce
244 ret = ctx->method.random(ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
245 if (ret != HITLS_AUTH_SUCCESS) {
246 BSL_ERR_PUSH_ERROR(ret);
247 goto ERR;
248 }
249
250 // Add token type (2 bytes)
251 BSL_Uint16ToByte(challenge->tokenType, tokenInput);
252 offset += 2; // offset 2 bytes.
253 // Add nonce
254 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_NONCE_LEN, ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
255 offset += PRIVPASS_TOKEN_NONCE_LEN;
256 // Add challenge digest
257 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
258 offset += PRIVPASS_TOKEN_SHA256_SIZE;
259 // Add token key id
260 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
261
262 // Calculate blinded message
263 request->blindedMsg.data = BSL_SAL_Malloc(authenticatorLen);
264 if (request->blindedMsg.data == NULL) {
265 ret = BSL_MALLOC_FAIL;
266 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
267 goto ERR;
268 }
269 request->blindedMsg.dataLen = authenticatorLen;
270 ret = ctx->method.blind(ctx->pubKeyCtx, HITLS_AUTH_PRIVPASS_CRYPTO_SHA384, tokenInput,
271 HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN, request->blindedMsg.data, &request->blindedMsg.dataLen);
272 if (ret != HITLS_AUTH_SUCCESS) {
273 BSL_ERR_PUSH_ERROR(ret);
274 goto ERR;
275 }
276
277 *tokenRequest = output;
278 return HITLS_AUTH_SUCCESS;
279 ERR:
280 HITLS_AUTH_PrivPassFreeToken(output);
281 return ret;
282 }
283
ParamCheckOfGenTokenResp(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenRequest,HITLS_AUTH_PrivPassToken ** tokenResponse)284 static int32_t ParamCheckOfGenTokenResp(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenRequest,
285 HITLS_AUTH_PrivPassToken **tokenResponse)
286 {
287 if (ctx == NULL || ctx->method.signData == NULL ||
288 tokenRequest == NULL || tokenRequest->type != HITLS_AUTH_PRIVPASS_TOKEN_REQUEST ||
289 tokenResponse == NULL || *tokenResponse != NULL) {
290 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
291 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
292 }
293 if (tokenRequest->st.tokenRequest->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
294 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
295 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
296 }
297
298 if (ctx->prvKeyCtx == NULL) {
299 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PRVKEY_INFO);
300 return HITLS_AUTH_PRIVPASS_NO_PRVKEY_INFO;
301 }
302 if (ctx->pubKeyCtx == NULL) {
303 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
304 return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
305 }
306 return HITLS_AUTH_SUCCESS;
307 }
308
HITLS_AUTH_PrivPassGenTokenResponse(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenRequest,HITLS_AUTH_PrivPassToken ** tokenResponse)309 int32_t HITLS_AUTH_PrivPassGenTokenResponse(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenRequest,
310 HITLS_AUTH_PrivPassToken **tokenResponse)
311 {
312 int32_t ret = ParamCheckOfGenTokenResp(ctx, tokenRequest, tokenResponse);
313 if (ret != HITLS_AUTH_SUCCESS) {
314 return ret;
315 }
316
317 const PrivPass_TokenRequest *request = tokenRequest->st.tokenRequest;
318 uint32_t authenticatorLen = ObtainAuthenticatorLen(request->tokenType); // request->tokenType has been checked.
319 if (request->truncatedTokenKeyId != ctx->tokenKeyId[PRIVPASS_TOKEN_SHA256_SIZE - 1]) {
320 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID);
321 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID;
322 }
323 if (request->blindedMsg.dataLen != authenticatorLen) {
324 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_BLINDED_MSG);
325 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_BLINDED_MSG;
326 }
327 HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE);
328 if (output == NULL) {
329 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
330 return BSL_MALLOC_FAIL;
331 }
332 PrivPass_TokenResponse *response = output->st.tokenResponse;
333 response->type = HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB;
334 // Calculate blind signature
335 response->st.pubResp.blindSig = BSL_SAL_Malloc(authenticatorLen);
336 if (response->st.pubResp.blindSig == NULL) {
337 ret = BSL_MALLOC_FAIL;
338 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
339 goto ERR;
340 }
341 response->st.pubResp.blindSigLen = authenticatorLen;
342
343 ret = ctx->method.signData(ctx->prvKeyCtx, request->blindedMsg.data, request->blindedMsg.dataLen,
344 response->st.pubResp.blindSig, &response->st.pubResp.blindSigLen);
345 if (ret != HITLS_AUTH_SUCCESS) {
346 BSL_ERR_PUSH_ERROR(ret);
347 goto ERR;
348 }
349 *tokenResponse = output;
350 return HITLS_AUTH_SUCCESS;
351
352 ERR:
353 HITLS_AUTH_PrivPassFreeToken(output);
354 return ret;
355 }
356
ParamCheckOfGenToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * tokenResponse,HITLS_AUTH_PrivPassToken ** token)357 static int32_t ParamCheckOfGenToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
358 const HITLS_AUTH_PrivPassToken *tokenResponse, HITLS_AUTH_PrivPassToken **token)
359 {
360 if (ctx == NULL || ctx->method.unBlind == NULL ||
361 tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
362 tokenResponse == NULL || tokenResponse->type != HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE ||
363 token == NULL || *token != NULL) {
364 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
365 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
366 }
367 if (ctx->pubKeyCtx == NULL) {
368 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
369 return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
370 }
371 if (tokenChallenge->st.tokenChallenge->tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE &&
372 tokenResponse->st.tokenResponse->type == HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB) {
373 return HITLS_AUTH_SUCCESS;
374 }
375 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
376 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
377 }
378
HITLS_AUTH_PrivPassGenToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * tokenResponse,HITLS_AUTH_PrivPassToken ** token)379 int32_t HITLS_AUTH_PrivPassGenToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
380 const HITLS_AUTH_PrivPassToken *tokenResponse, HITLS_AUTH_PrivPassToken **token)
381 {
382 int32_t ret = ParamCheckOfGenToken(ctx, tokenChallenge, tokenResponse, token);
383 if (ret != HITLS_AUTH_SUCCESS) {
384 return ret;
385 }
386
387 HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE);
388 if (output == NULL) {
389 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
390 return BSL_MALLOC_FAIL;
391 }
392 uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
393 PrivPass_TokenInstance *finalToken = output->st.token;
394 const PrivPass_TokenChallenge *challenge = tokenChallenge->st.tokenChallenge;
395 const PrivPass_TokenResponse *response = tokenResponse->st.tokenResponse;
396 uint32_t outputLen = ObtainAuthenticatorLen(challenge->tokenType);
397 // Copy token type from challenge
398 finalToken->tokenType = challenge->tokenType;
399 // cal tokenChallengeDigest
400 ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
401 if (ret != HITLS_AUTH_SUCCESS) {
402 BSL_ERR_PUSH_ERROR(ret);
403 goto ERR;
404 }
405 // Copy nonce from ctx
406 (void)memcpy_s(finalToken->nonce, PRIVPASS_TOKEN_NONCE_LEN, ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
407
408 // Copy challenge digest from ctx
409 (void)memcpy_s(finalToken->challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE,
410 challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
411
412 // Copy token key ID from ctx
413 (void)memcpy_s(finalToken->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
414
415 // Copy authenticator from tokenResponse
416 finalToken->authenticator.data = BSL_SAL_Malloc(outputLen);
417 if (finalToken->authenticator.data == NULL) {
418 ret = BSL_MALLOC_FAIL;
419 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
420 goto ERR;
421 }
422 ret = ctx->method.unBlind(ctx->pubKeyCtx, response->st.pubResp.blindSig, response->st.pubResp.blindSigLen,
423 finalToken->authenticator.data, &outputLen);
424 if (ret != HITLS_AUTH_SUCCESS) {
425 BSL_ERR_PUSH_ERROR(ret);
426 goto ERR;
427 }
428 finalToken->authenticator.dataLen = outputLen;
429 *token = output;
430 return HITLS_AUTH_SUCCESS;
431
432 ERR:
433 HITLS_AUTH_PrivPassFreeToken(output);
434 return ret;
435 }
436
ParamCheckOfVerifyToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * token)437 static int32_t ParamCheckOfVerifyToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
438 const HITLS_AUTH_PrivPassToken *token)
439 {
440 if (ctx == NULL || ctx->method.verify == NULL ||
441 tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
442 token == NULL || token->type != HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE) {
443 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
444 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
445 }
446 if (tokenChallenge->st.tokenChallenge->tokenType != token->st.token->tokenType) {
447 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
448 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
449 }
450 if (tokenChallenge->st.tokenChallenge->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
451 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
452 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
453 }
454 if (ctx->pubKeyCtx == NULL) {
455 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
456 return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
457 }
458 PrivPass_TokenInstance *finalToken = token->st.token;
459 if (memcmp(finalToken->tokenKeyId, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE) != 0) {
460 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID);
461 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID;
462 }
463 uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
464 int32_t ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
465 if (ret != HITLS_AUTH_SUCCESS) {
466 BSL_ERR_PUSH_ERROR(ret);
467 return ret;
468 }
469 if (memcmp(finalToken->challengeDigest, challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE) != 0) {
470 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_DIGEST);
471 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_DIGEST;
472 }
473 return HITLS_AUTH_SUCCESS;
474 }
475
HITLS_AUTH_PrivPassVerifyToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * token)476 int32_t HITLS_AUTH_PrivPassVerifyToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
477 const HITLS_AUTH_PrivPassToken *token)
478 {
479 int32_t ret = ParamCheckOfVerifyToken(ctx, tokenChallenge, token);
480 if (ret != HITLS_AUTH_SUCCESS) {
481 return ret;
482 }
483 PrivPass_TokenInstance *finalToken = token->st.token;
484 uint32_t authenticatorLen = ObtainAuthenticatorLen(finalToken->tokenType);
485 if (finalToken->authenticator.data == NULL || authenticatorLen != finalToken->authenticator.dataLen) {
486 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE);
487 return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE;
488 }
489 // Construct token_input = concat(token_type, nonce, challenge_digest, token_key_id)
490 uint8_t tokenInput[HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN];
491 size_t offset = 0;
492
493 // Add token type (2 bytes)
494 BSL_Uint16ToByte(finalToken->tokenType, tokenInput);
495 offset += 2; // offset 2 bytes.
496
497 // Add nonce
498 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_NONCE_LEN, finalToken->nonce, PRIVPASS_TOKEN_NONCE_LEN);
499 offset += PRIVPASS_TOKEN_NONCE_LEN;
500
501 // Add challenge digest
502 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE,
503 finalToken->challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
504 offset += PRIVPASS_TOKEN_SHA256_SIZE;
505
506 // Add token key id
507 (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, finalToken->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
508
509 // Verify the token using ctx's verify method
510 ret = ctx->method.verify(ctx->pubKeyCtx, HITLS_AUTH_PRIVPASS_CRYPTO_SHA384, tokenInput,
511 HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN, finalToken->authenticator.data, PRIVPASS_TOKEN_NK);
512 if (ret != HITLS_AUTH_SUCCESS) {
513 BSL_ERR_PUSH_ERROR(ret);
514 }
515 return ret;
516 }
517
HITLS_AUTH_PrivPassSetPubkey(HITLS_AUTH_PrivPassCtx * ctx,uint8_t * pki,uint32_t pkiLen)518 int32_t HITLS_AUTH_PrivPassSetPubkey(HITLS_AUTH_PrivPassCtx *ctx, uint8_t *pki, uint32_t pkiLen)
519 {
520 if (ctx == NULL || ctx->method.decodePubKey == NULL || ctx->method.freePkeyCtx == NULL ||
521 ctx->method.digest == NULL || pki == NULL || pkiLen == 0) {
522 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
523 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
524 }
525 uint32_t tokenKeyIdLen = PRIVPASS_TOKEN_SHA256_SIZE;
526 void *pubKeyCtx = NULL;
527 int32_t ret = ctx->method.decodePubKey(NULL, NULL, pki, pkiLen, &pubKeyCtx);
528 if (ret != HITLS_AUTH_SUCCESS) {
529 BSL_ERR_PUSH_ERROR(ret);
530 return ret;
531 }
532 if (ctx->prvKeyCtx != NULL) {
533 if (ctx->method.checkKeyPair == NULL) {
534 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK);
535 ret = HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK;
536 goto ERR;
537 }
538
539 ret = ctx->method.checkKeyPair(pubKeyCtx, ctx->prvKeyCtx);
540 if (ret != HITLS_AUTH_SUCCESS) {
541 ret = HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED;
542 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED);
543 goto ERR;
544 }
545 }
546 ret = ctx->method.digest(NULL, NULL, HITLS_AUTH_PRIVPASS_CRYPTO_SHA256, pki, pkiLen, ctx->tokenKeyId,
547 &tokenKeyIdLen);
548 if (ret != HITLS_AUTH_SUCCESS) {
549 BSL_ERR_PUSH_ERROR(ret);
550 goto ERR;
551 }
552 if (ctx->pubKeyCtx != NULL) {
553 ctx->method.freePkeyCtx(ctx->pubKeyCtx);
554 }
555 ctx->pubKeyCtx = pubKeyCtx;
556 return HITLS_AUTH_SUCCESS;
557
558 ERR:
559 ctx->method.freePkeyCtx(pubKeyCtx);
560 return ret;
561 }
562
HITLS_AUTH_PrivPassSetPrvkey(HITLS_AUTH_PrivPassCtx * ctx,void * param,uint8_t * ski,uint32_t skiLen)563 int32_t HITLS_AUTH_PrivPassSetPrvkey(HITLS_AUTH_PrivPassCtx *ctx, void *param, uint8_t *ski, uint32_t skiLen)
564 {
565 if (ctx == NULL || ctx->method.decodePrvKey == NULL || ctx->method.freePkeyCtx == NULL ||
566 ski == NULL || skiLen == 0) {
567 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
568 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
569 }
570 void *prvKeyCtx = NULL;
571 int32_t ret = ctx->method.decodePrvKey(NULL, NULL, param, ski, skiLen, &prvKeyCtx);
572 if (ret != HITLS_AUTH_SUCCESS) {
573 BSL_ERR_PUSH_ERROR(ret);
574 return ret;
575 }
576 if (ctx->pubKeyCtx != NULL) {
577 if (ctx->method.checkKeyPair == NULL) {
578 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK);
579 ret = HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK;
580 goto ERR;
581 }
582 ret = ctx->method.checkKeyPair(ctx->pubKeyCtx, prvKeyCtx);
583 if (ret != HITLS_AUTH_SUCCESS) {
584 ret = HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED;
585 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED);
586 goto ERR;
587 }
588 }
589 if (ctx->prvKeyCtx != NULL) {
590 ctx->method.freePkeyCtx(ctx->prvKeyCtx);
591 }
592 ctx->prvKeyCtx = prvKeyCtx;
593 return HITLS_AUTH_SUCCESS;
594
595 ERR:
596 ctx->method.freePkeyCtx(prvKeyCtx);
597 return ret;
598 }
599