• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "hitls_build.h"
17 
18 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_HPKE)
19 
20 #include <string.h>
21 #include "securec.h"
22 #include "crypt_eal_pkey.h"
23 #include "crypt_eal_kdf.h"
24 #include "crypt_eal_cipher.h"
25 #include "crypt_eal_rand.h"
26 #include "crypt_algid.h"
27 #include "crypt_errno.h"
28 #include "crypt_bn.h"
29 #include "crypt_params_key.h"
30 #include "bsl_err_internal.h"
31 #include "bsl_sal.h"
32 #include "bsl_bytes.h"
33 
34 #include "crypt_eal_hpke.h"
35 
36 // Data from RFC9180
37 #define HPKE_HKDF_MAX_EXTRACT_KEY_LEN 64
38 #define HPKE_KEM_MAX_SHARED_KEY_LEN  64
39 #define HPKE_KEM_MAX_ENCAPSULATED_KEY_LEN  133
40 #define HPKE_KEM_MAX_PUBLIC_KEY_LEN  133
41 #define HPKE_KEM_MAX_PRIVATE_KEY_LEN  66
42 #define HPKE_KEM_DH_MAX_SHARED_KEY_LEN 66 // p521 key length
43 #define MAX_ECC_PARAM_LEN 66
44 
45 #define HPKE_AEAD_NONCE_LEN  12
46 #define HPKE_AEAD_TAG_LEN  16
47 
48 #define HPKE_KEM_SUITEID_LEN 5
49 #define HPKE_HPKE_SUITEID_LEN 10
50 
51 typedef struct {
52     // PSK mode
53     uint8_t *psk;
54     uint32_t pskLen;
55     uint8_t *pskId;
56     uint32_t pskIdLen;
57     // AUTH mode, Sender's private key held by the sender, Sender's public key held by the recipient
58     CRYPT_EAL_PkeyCtx *authPkey;
59 } AuthInfo;
60 
61 struct CRYPT_EAL_HpkeCtx {
62     uint8_t role;                    // Sender or Recipient
63     uint8_t mode;                    // HPKE mode
64     uint8_t kemIndex;
65     uint8_t kdfIndex;
66     uint8_t aeadIndex;
67     uint8_t *symKey;
68     uint8_t *baseNonce;
69     uint32_t symKeyLen;
70     uint32_t baseNonceLen;
71     uint8_t *exporterSecret;
72     uint8_t *sharedSecret;
73     uint32_t exporterSecretLen;
74     uint32_t sharedSecretLen;
75     uint64_t seq;                   // Message sequence number
76     CRYPT_EAL_KdfCTX *kdfCtx;
77     CRYPT_EAL_CipherCtx *cipherCtx;
78     CRYPT_EAL_LibCtx *libCtx;
79     char *attrName;
80     AuthInfo *authInfo;
81 };
82 
83 typedef struct {
84     uint16_t hpkeKemId;
85     CRYPT_PKEY_AlgId pkeyId;
86     CRYPT_PKEY_ParaId curveId;
87     CRYPT_MAC_AlgId macId;
88     uint16_t privateKeyLen;
89     uint16_t sharedKeyLen;
90     uint16_t encapsulatedKeyLen;
91     uint16_t hkdfExtractKeyLen;
92 } HPKE_KemAlgInfo;
93 
94 typedef struct {
95     uint16_t hpkeKdfId;
96     uint16_t hkdfExtractKeyLen;
97     CRYPT_MAC_AlgId macId;
98 } HPKE_KdfAlgInfo;
99 
100 typedef struct {
101     uint16_t hpkeAeadId;
102     uint16_t keyLen;
103     CRYPT_CIPHER_AlgId cipherId;
104 } HPKE_AeadAlgInfo;
105 
106 #define HPKE_INVALID_ALG_INDEX 0xFF
107 
108 static HPKE_KemAlgInfo g_hpkeKemAlgInfo[] = {
109     {CRYPT_KEM_DHKEM_P256_HKDF_SHA256, CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP256, CRYPT_MAC_HMAC_SHA256, 32, 32, 65, 32},
110     {CRYPT_KEM_DHKEM_P384_HKDF_SHA384, CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP384, CRYPT_MAC_HMAC_SHA384, 48, 48, 97, 48},
111     {CRYPT_KEM_DHKEM_P521_HKDF_SHA512, CRYPT_PKEY_ECDH, CRYPT_ECC_NISTP521, CRYPT_MAC_HMAC_SHA512, 66, 64, 133, 64},
112     {CRYPT_KEM_DHKEM_X25519_HKDF_SHA256, CRYPT_PKEY_X25519, CRYPT_PKEY_PARAID_MAX, CRYPT_MAC_HMAC_SHA256, 32, 32, 32,
113      32},
114 };
115 
116 static HPKE_KdfAlgInfo g_hpkeKdfAlgInfo[] = {
117     {CRYPT_KDF_HKDF_SHA256, 32, CRYPT_MAC_HMAC_SHA256},
118     {CRYPT_KDF_HKDF_SHA384, 48, CRYPT_MAC_HMAC_SHA384},
119     {CRYPT_KDF_HKDF_SHA512, 64, CRYPT_MAC_HMAC_SHA512},
120 };
121 
122 static HPKE_AeadAlgInfo g_hpkeAeadAlgInfo[] = {
123     {CRYPT_AEAD_AES_128_GCM, 16, CRYPT_CIPHER_AES128_GCM},
124     {CRYPT_AEAD_AES_256_GCM, 32, CRYPT_CIPHER_AES256_GCM},
125     {CRYPT_AEAD_CHACHA20_POLY1305, 32, CRYPT_CIPHER_CHACHA20_POLY1305},
126     {CRYPT_AEAD_EXPORT_ONLY, 0, CRYPT_CIPHER_MAX},
127 };
128 
HpkeCheckCipherSuite(const CRYPT_HPKE_CipherSuite * cipherSuite,uint8_t * kemIndex,uint8_t * kdfIndex,uint8_t * aeadIndex)129 static int32_t HpkeCheckCipherSuite(const CRYPT_HPKE_CipherSuite *cipherSuite, uint8_t *kemIndex, uint8_t *kdfIndex,
130     uint8_t *aeadIndex)
131 {
132     uint8_t kemPosition = HPKE_INVALID_ALG_INDEX;
133     uint8_t kdfPosition = HPKE_INVALID_ALG_INDEX;
134     uint8_t aeadPosition = HPKE_INVALID_ALG_INDEX;
135     uint8_t i;
136 
137     for (i = 0; i < sizeof(g_hpkeKemAlgInfo) / sizeof(HPKE_KemAlgInfo); i++) {
138         if (cipherSuite->kemId == g_hpkeKemAlgInfo[i].hpkeKemId) {
139             kemPosition = i;
140             break;
141         }
142     }
143 
144     for (i = 0; i < sizeof(g_hpkeKdfAlgInfo) / sizeof(HPKE_KdfAlgInfo); i++) {
145         if (cipherSuite->kdfId == g_hpkeKdfAlgInfo[i].hpkeKdfId) {
146             kdfPosition = i;
147             break;
148         }
149     }
150 
151     for (i = 0; i < sizeof(g_hpkeAeadAlgInfo) / sizeof(HPKE_AeadAlgInfo); i++) {
152         if (cipherSuite->aeadId == g_hpkeAeadAlgInfo[i].hpkeAeadId) {
153             aeadPosition = i;
154             break;
155         }
156     }
157 
158     if (kemPosition == HPKE_INVALID_ALG_INDEX || kdfPosition == HPKE_INVALID_ALG_INDEX ||
159         aeadPosition == HPKE_INVALID_ALG_INDEX) {
160         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
161         return CRYPT_INVALID_ARG;
162     }
163 
164     if (kemIndex != NULL) {
165         *kemIndex = kemPosition;
166     }
167     if (kdfIndex != NULL) {
168         *kdfIndex = kdfPosition;
169     }
170     if (aeadIndex != NULL) {
171         *aeadIndex = aeadPosition;
172     }
173     return CRYPT_SUCCESS;
174 }
175 
InitCipherSuiteCtx(CRYPT_EAL_HpkeCtx * ctx,uint8_t aeadIndex,CRYPT_EAL_LibCtx * libCtx,const char * attrName)176 static int32_t InitCipherSuiteCtx(CRYPT_EAL_HpkeCtx *ctx, uint8_t aeadIndex, CRYPT_EAL_LibCtx *libCtx,
177     const char *attrName)
178 {
179     CRYPT_EAL_KdfCTX *kdfCtx = NULL;
180     CRYPT_EAL_CipherCtx *cipherCtx = NULL;
181     kdfCtx = CRYPT_EAL_ProviderKdfNewCtx(libCtx, CRYPT_KDF_HKDF, attrName);
182     if (kdfCtx == NULL) {
183         return CRYPT_HPKE_FAILED_FETCH_KDF;
184     }
185 
186     if (g_hpkeAeadAlgInfo[aeadIndex].hpkeAeadId != CRYPT_AEAD_EXPORT_ONLY) {
187         cipherCtx = CRYPT_EAL_ProviderCipherNewCtx(libCtx, g_hpkeAeadAlgInfo[aeadIndex].cipherId, attrName);
188         if (cipherCtx == NULL) {
189             CRYPT_EAL_KdfFreeCtx(kdfCtx);
190             return CRYPT_HPKE_FAILED_FETCH_CIPHER;
191         }
192     }
193 
194     ctx->kdfCtx = kdfCtx;
195     ctx->cipherCtx = cipherCtx;
196     return CRYPT_SUCCESS;
197 }
198 
HpkeInitCipherSuite(CRYPT_EAL_HpkeCtx * ctx,CRYPT_HPKE_CipherSuite * cipherSuite,CRYPT_EAL_LibCtx * libCtx,const char * attrName)199 static int32_t HpkeInitCipherSuite(CRYPT_EAL_HpkeCtx *ctx, CRYPT_HPKE_CipherSuite *cipherSuite,
200     CRYPT_EAL_LibCtx *libCtx, const char *attrName)
201 {
202     uint8_t kemIndex;
203     uint8_t kdfIndex;
204     uint8_t aeadIndex;
205     int32_t ret;
206     ret = HpkeCheckCipherSuite(cipherSuite, &kemIndex, &kdfIndex, &aeadIndex);
207     if (ret != CRYPT_SUCCESS) {
208         return ret;
209     }
210 
211     ret = InitCipherSuiteCtx(ctx, aeadIndex, libCtx, attrName);
212     if (ret != CRYPT_SUCCESS) {
213         BSL_ERR_PUSH_ERROR(ret);
214         return ret;
215     }
216 
217     ctx->kemIndex = kemIndex;
218     ctx->aeadIndex = aeadIndex;
219     ctx->kdfIndex = kdfIndex;
220     return CRYPT_SUCCESS;
221 }
222 
CRYPT_EAL_HpkeNewCtx(CRYPT_EAL_LibCtx * libCtx,const char * attrName,CRYPT_HPKE_Role role,CRYPT_HPKE_Mode mode,CRYPT_HPKE_CipherSuite cipherSuite)223 CRYPT_EAL_HpkeCtx *CRYPT_EAL_HpkeNewCtx(CRYPT_EAL_LibCtx *libCtx, const char *attrName, CRYPT_HPKE_Role role,
224     CRYPT_HPKE_Mode mode, CRYPT_HPKE_CipherSuite cipherSuite)
225 {
226     if (role != CRYPT_HPKE_SENDER && role != CRYPT_HPKE_RECIPIENT) {
227         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
228         return NULL;
229     }
230 
231     if (mode != CRYPT_HPKE_MODE_BASE && mode != CRYPT_HPKE_MODE_PSK && mode != CRYPT_HPKE_MODE_AUTH &&
232         mode != CRYPT_HPKE_MODE_AUTH_PSK) {
233         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
234         return NULL;
235     }
236 
237     CRYPT_EAL_HpkeCtx *ctx = (CRYPT_EAL_HpkeCtx*)BSL_SAL_Calloc(1, sizeof(CRYPT_EAL_HpkeCtx));
238     if (ctx == NULL) {
239         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
240         return NULL;
241     }
242 
243     int32_t ret = HpkeInitCipherSuite(ctx, &cipherSuite, libCtx, attrName);
244     if (ret != CRYPT_SUCCESS) {
245         CRYPT_EAL_HpkeFreeCtx(ctx);
246         return NULL;
247     }
248 
249     if (attrName != NULL && strlen(attrName) > 0) {
250         ctx->attrName = BSL_SAL_Dump(attrName, (uint32_t)strlen(attrName) + 1);
251         if (ctx->attrName == NULL) {
252             CRYPT_EAL_HpkeFreeCtx(ctx);
253             BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
254             return NULL;
255         }
256     }
257 
258     if (mode == CRYPT_HPKE_MODE_PSK || mode == CRYPT_HPKE_MODE_AUTH || mode == CRYPT_HPKE_MODE_AUTH_PSK) {
259         AuthInfo *authInfo = (AuthInfo *)BSL_SAL_Calloc(1, sizeof(AuthInfo));
260         if (authInfo == NULL) {
261             CRYPT_EAL_HpkeFreeCtx(ctx);
262             BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
263             return NULL;
264         }
265         ctx->authInfo = authInfo;
266     }
267 
268     ctx->mode = mode;
269     ctx->role = role;
270     ctx->libCtx = libCtx;
271     return ctx;
272 }
273 
CRYPT_EAL_HpkeGetEncapKeyLen(CRYPT_HPKE_CipherSuite cipherSuite,uint32_t * encapKeyLen)274 int32_t CRYPT_EAL_HpkeGetEncapKeyLen(CRYPT_HPKE_CipherSuite cipherSuite, uint32_t *encapKeyLen)
275 {
276     if (encapKeyLen == NULL) {
277         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
278         return CRYPT_NULL_INPUT;
279     }
280 
281     uint8_t kemIndex;
282     int32_t ret = HpkeCheckCipherSuite(&cipherSuite, &kemIndex, NULL, NULL);
283     if (ret != CRYPT_SUCCESS) {
284         return ret;
285     }
286 
287     *encapKeyLen = g_hpkeKemAlgInfo[kemIndex].encapsulatedKeyLen;
288     return CRYPT_SUCCESS;
289 }
290 
HpkeCreatePkeyCtx(uint8_t kemIdex,CRYPT_EAL_PkeyCtx ** pkeyCtx,CRYPT_EAL_LibCtx * libCtx,const char * attrName)291 static int32_t HpkeCreatePkeyCtx(uint8_t kemIdex, CRYPT_EAL_PkeyCtx **pkeyCtx, CRYPT_EAL_LibCtx *libCtx,
292     const char *attrName)
293 {
294     CRYPT_PKEY_AlgId algId = g_hpkeKemAlgInfo[kemIdex].pkeyId;
295     CRYPT_EAL_PkeyCtx *pkey = NULL;
296 #ifdef HITLS_CRYPTO_PROVIDER
297     pkey = CRYPT_EAL_ProviderPkeyNewCtx(libCtx, algId, CRYPT_EAL_PKEY_EXCH_OPERATE, attrName);
298 #else
299     (void)libCtx;
300     (void)attrName;
301     pkey = CRYPT_EAL_PkeyNewCtx(algId);
302 #endif
303     if (pkey == NULL) {
304         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_FAILED_FETCH_PKEY);
305         return CRYPT_HPKE_FAILED_FETCH_PKEY;
306     }
307 
308     if (algId == CRYPT_PKEY_ECDH) {
309         CRYPT_PKEY_ParaId curveId = g_hpkeKemAlgInfo[kemIdex].curveId;
310         int32_t ret = CRYPT_EAL_PkeySetParaById(pkey, curveId);
311         if (ret != CRYPT_SUCCESS) {
312             CRYPT_EAL_PkeyFreeCtx(pkey);
313             return ret;
314         }
315     }
316 
317     *pkeyCtx = pkey;
318     return CRYPT_SUCCESS;
319 }
320 
HpkeCreatePubKey(uint8_t kemIdex,uint8_t * pubKey,uint32_t pubKeyLen,CRYPT_EAL_PkeyCtx ** pkey,CRYPT_EAL_LibCtx * libCtx,const char * attrName)321 static int32_t HpkeCreatePubKey(uint8_t kemIdex, uint8_t *pubKey, uint32_t pubKeyLen, CRYPT_EAL_PkeyCtx **pkey,
322     CRYPT_EAL_LibCtx *libCtx, const char *attrName)
323 {
324     CRYPT_EAL_PkeyCtx *tmpPkey = NULL;
325     int32_t ret = HpkeCreatePkeyCtx(kemIdex, &tmpPkey, libCtx, attrName);
326     if (ret != CRYPT_SUCCESS) {
327         return ret;
328     }
329 
330     CRYPT_EAL_PkeyPub pub = {0};
331     pub.id = CRYPT_EAL_PkeyGetId(tmpPkey);
332     pub.key.eccPub.data = pubKey; // compatible curve25519Pub
333     pub.key.eccPub.len = pubKeyLen;
334 
335     ret = CRYPT_EAL_PkeySetPub(tmpPkey, &pub);
336     if (ret != CRYPT_SUCCESS) {
337         CRYPT_EAL_PkeyFreeCtx(tmpPkey);
338         return ret;
339     }
340 
341     *pkey = tmpPkey;
342     return CRYPT_SUCCESS;
343 }
344 
HpkeCreatePriKey(uint8_t kemIdex,uint8_t * priKey,uint32_t priKeyLen,CRYPT_EAL_PkeyCtx ** pkey,CRYPT_EAL_LibCtx * libCtx,const char * attrName)345 static int32_t HpkeCreatePriKey(uint8_t kemIdex, uint8_t *priKey, uint32_t priKeyLen, CRYPT_EAL_PkeyCtx **pkey,
346     CRYPT_EAL_LibCtx *libCtx, const char *attrName)
347 {
348     CRYPT_EAL_PkeyCtx *tmpPkey = *pkey;
349     int32_t ret;
350 
351     if (tmpPkey == NULL) {
352         ret = HpkeCreatePkeyCtx(kemIdex, &tmpPkey, libCtx, attrName);
353         if (ret != CRYPT_SUCCESS) {
354             return ret;
355         }
356     }
357 
358     CRYPT_EAL_PkeyPrv prv = {0};
359     prv.id = CRYPT_EAL_PkeyGetId(tmpPkey);
360     prv.key.eccPrv.data = priKey;
361     prv.key.eccPrv.len = priKeyLen;
362 
363     ret = CRYPT_EAL_PkeySetPrv(tmpPkey, &prv);
364     if (ret != CRYPT_SUCCESS) {
365         goto EXIT;
366     }
367 
368     if (g_hpkeKemAlgInfo[kemIdex].hpkeKemId == CRYPT_KEM_DHKEM_X25519_HKDF_SHA256) {
369         ret = CRYPT_EAL_PkeyCtrl(tmpPkey, CRYPT_CTRL_GEN_X25519_PUBLICKEY, NULL, 0);
370     } else {
371         ret = CRYPT_EAL_PkeyCtrl(tmpPkey, CRYPT_CTRL_GEN_ECC_PUBLICKEY, NULL, 0);
372     }
373 
374     if (ret == CRYPT_SUCCESS) {
375         *pkey = tmpPkey;
376         return CRYPT_SUCCESS;
377     }
378 
379 EXIT:
380     if (*pkey == NULL) {
381         CRYPT_EAL_PkeyFreeCtx(tmpPkey);
382     }
383     return ret;
384 }
385 
HpkeGenerateHpkeSuiteId(uint8_t kemIndex,uint8_t kdfIndex,uint8_t aeadIndex,uint8_t * suiteId,uint32_t suiteIdLen)386 static inline void HpkeGenerateHpkeSuiteId(uint8_t kemIndex, uint8_t kdfIndex, uint8_t aeadIndex, uint8_t *suiteId,
387     uint32_t suiteIdLen)
388 {
389     (void)memcpy_s(suiteId, suiteIdLen, "HPKE", strlen("HPKE"));
390     uint32_t offset = strlen("HPKE");
391 
392     BSL_Uint16ToByte(g_hpkeKemAlgInfo[kemIndex].hpkeKemId, suiteId + offset);
393     offset += sizeof(uint16_t);
394 
395     BSL_Uint16ToByte(g_hpkeKdfAlgInfo[kdfIndex].hpkeKdfId, suiteId + offset);
396     offset += sizeof(uint16_t);
397 
398     BSL_Uint16ToByte(g_hpkeAeadAlgInfo[aeadIndex].hpkeAeadId, suiteId + offset);
399 }
400 
HpkeGenerateKemSuiteId(uint8_t kemIdex,uint8_t * suiteId,uint32_t suiteIdLen)401 static inline void HpkeGenerateKemSuiteId(uint8_t kemIdex, uint8_t *suiteId, uint32_t suiteIdLen)
402 {
403     uint16_t kemId = g_hpkeKemAlgInfo[kemIdex].hpkeKemId;
404     (void)memcpy_s(suiteId, suiteIdLen, "KEM", strlen("KEM"));
405     uint32_t offset = strlen("KEM");
406 
407     BSL_Uint16ToByte(kemId, suiteId + offset);
408 }
409 
410 typedef struct {
411     int32_t macId;
412     uint8_t *key;
413     uint32_t keyLen;
414     uint8_t *salt;
415     uint32_t saltLen;
416 } HPKE_HkdfExtractParams;
417 
418 typedef struct {
419     int32_t macId;
420     uint8_t *prk;
421     uint32_t prkLen;
422     uint8_t *info;
423     uint32_t infoLen;
424 } HPKE_HkdfExpandParam;
425 
HpkeHkdfExtract(CRYPT_EAL_KdfCTX * hkdfCtx,HPKE_HkdfExtractParams * extractParams,uint8_t * out,uint32_t outLen)426 static int32_t HpkeHkdfExtract(CRYPT_EAL_KdfCTX *hkdfCtx, HPKE_HkdfExtractParams *extractParams, uint8_t *out,
427     uint32_t outLen)
428 {
429     int32_t ret;
430     CRYPT_HKDF_MODE mode = CRYPT_KDF_HKDF_MODE_EXTRACT;
431 
432     BSL_Param params[6] = {{0}, {0}, {0}, {0}, {0}, BSL_PARAM_END}; // 6 parameters
433     ret = BSL_PARAM_InitValue(&params[0], CRYPT_PARAM_KDF_MAC_ID, BSL_PARAM_TYPE_UINT32, (void *)&extractParams->macId,
434         sizeof(int32_t));
435     if (ret != CRYPT_SUCCESS) {
436         return ret;
437     }
438 
439     ret = BSL_PARAM_InitValue(&params[1], CRYPT_PARAM_KDF_MODE, BSL_PARAM_TYPE_UINT32, (void *)&mode, sizeof(mode));
440     if (ret != CRYPT_SUCCESS) {
441         return ret;
442     }
443 
444     ret = BSL_PARAM_InitValue(&params[2], CRYPT_PARAM_KDF_KEY, BSL_PARAM_TYPE_OCTETS, // param index 2
445         (void *)extractParams->key, extractParams->keyLen);
446     if (ret != CRYPT_SUCCESS) {
447         return ret;
448     }
449 
450     ret = BSL_PARAM_InitValue(&params[3], CRYPT_PARAM_KDF_SALT, BSL_PARAM_TYPE_OCTETS, // param index 3
451         (void *)extractParams->salt, extractParams->saltLen);
452     if (ret != CRYPT_SUCCESS) {
453         return ret;
454     }
455 
456     ret = BSL_PARAM_InitValue(&params[4], CRYPT_PARAM_KDF_EXLEN, BSL_PARAM_TYPE_UINT32_PTR, // param index 4
457         (void *)&outLen, sizeof(outLen));
458     if (ret != CRYPT_SUCCESS) {
459         return ret;
460     }
461 
462     ret = CRYPT_EAL_KdfSetParam(hkdfCtx, params);
463     if (ret != CRYPT_SUCCESS) {
464         return ret;
465     }
466 
467     ret = CRYPT_EAL_KdfDerive(hkdfCtx, out, outLen);
468     CRYPT_EAL_KdfDeInitCtx(hkdfCtx);
469     return ret;
470 }
471 
HpkeHkdfExpand(CRYPT_EAL_KdfCTX * hkdfCtx,HPKE_HkdfExpandParam * expandParams,uint8_t * out,uint32_t outLen)472 static int32_t HpkeHkdfExpand(CRYPT_EAL_KdfCTX *hkdfCtx, HPKE_HkdfExpandParam *expandParams, uint8_t *out,
473     uint32_t outLen)
474 {
475     int32_t ret;
476     CRYPT_HKDF_MODE mode = CRYPT_KDF_HKDF_MODE_EXPAND;
477 
478     BSL_Param params[5] = {{0}, {0}, {0}, {0}, BSL_PARAM_END}; // 5 parameters
479     ret = BSL_PARAM_InitValue(&params[0], CRYPT_PARAM_KDF_MAC_ID, BSL_PARAM_TYPE_UINT32, (void *)&expandParams->macId,
480         sizeof(int32_t));
481     if (ret != CRYPT_SUCCESS) {
482         return ret;
483     }
484 
485     ret = BSL_PARAM_InitValue(&params[1], CRYPT_PARAM_KDF_MODE, BSL_PARAM_TYPE_UINT32, (void *)&mode, sizeof(mode));
486     if (ret != CRYPT_SUCCESS) {
487         return ret;
488     }
489 
490     ret = BSL_PARAM_InitValue(&params[2], CRYPT_PARAM_KDF_PRK, BSL_PARAM_TYPE_OCTETS, // param index 2
491         (void *)expandParams->prk, expandParams->prkLen);
492     if (ret != CRYPT_SUCCESS) {
493         return ret;
494     }
495 
496     ret = BSL_PARAM_InitValue(&params[3], CRYPT_PARAM_KDF_INFO, BSL_PARAM_TYPE_OCTETS, // param index 3
497         (void *)expandParams->info, expandParams->infoLen);
498     if (ret != CRYPT_SUCCESS) {
499         return ret;
500     }
501 
502     ret = CRYPT_EAL_KdfSetParam(hkdfCtx, params);
503     if (ret != CRYPT_SUCCESS) {
504         return ret;
505     }
506 
507     ret = CRYPT_EAL_KdfDerive(hkdfCtx, out, outLen);
508     CRYPT_EAL_KdfDeInitCtx(hkdfCtx);
509     return ret;
510 }
511 
512 typedef struct {
513     int32_t macId;
514     uint8_t *salt;
515     uint32_t saltLen;
516     uint8_t *label;
517     uint32_t labelLen;
518     uint8_t *ikm;
519     uint32_t ikmLen;
520     uint8_t *suiteId;
521     uint32_t suiteIdLen;
522 } HPKE_LabeledExtractParams;
523 
524 typedef struct {
525     int32_t macId;
526     uint8_t *prk;
527     uint32_t prkLen;
528     uint8_t *label;
529     uint32_t labelLen;
530     uint8_t *info;
531     uint32_t infoLen;
532     uint8_t *suiteId;
533     uint32_t suiteIdLen;
534 } HPKE_LabeledExpandParams;
535 
HpkeLabeledExtract(CRYPT_EAL_KdfCTX * hkdfCtx,HPKE_LabeledExtractParams * params,uint8_t * out,uint32_t outLen)536 static int32_t HpkeLabeledExtract(CRYPT_EAL_KdfCTX *hkdfCtx, HPKE_LabeledExtractParams *params, uint8_t *out,
537     uint32_t outLen)
538 {
539     // labeled_ikm = "HPKE-v1" || suite_id || label || ikm
540     const uint8_t *version = (const uint8_t *)"HPKE-v1";
541     uint32_t versionLen = strlen("HPKE-v1");
542     uint32_t partialLen = versionLen + params->suiteIdLen + params->labelLen;
543     if (params->ikmLen > (UINT32_MAX - partialLen)) {
544         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
545         return CRYPT_INVALID_ARG;
546     }
547 
548     uint32_t labeledIkmLen = partialLen + params->ikmLen;
549     uint8_t *labeledIkm = (uint8_t *)BSL_SAL_Malloc(labeledIkmLen);
550     if (labeledIkm == NULL) {
551         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
552         return CRYPT_MEM_ALLOC_FAIL;
553     }
554 
555     uint32_t offset = 0;
556     (void)memcpy_s(labeledIkm + offset, labeledIkmLen - offset, version, versionLen);
557     offset += versionLen;
558     (void)memcpy_s(labeledIkm + offset, labeledIkmLen - offset, params->suiteId, params->suiteIdLen);
559     offset += params->suiteIdLen;
560     (void)memcpy_s(labeledIkm + offset, labeledIkmLen - offset, params->label, params->labelLen);
561     offset += params->labelLen;
562     (void)memcpy_s(labeledIkm + offset, labeledIkmLen - offset, params->ikm, params->ikmLen);
563 
564     HPKE_HkdfExtractParams extractParams = {params->macId, labeledIkm, labeledIkmLen, params->salt, params->saltLen};
565     int32_t ret = HpkeHkdfExtract(hkdfCtx, &extractParams, out, outLen);
566     BSL_SAL_ClearFree(labeledIkm, labeledIkmLen);
567     return ret;
568 }
569 
HpkeLabeledExpand(CRYPT_EAL_KdfCTX * hkdfCtx,HPKE_LabeledExpandParams * params,uint8_t * out,uint32_t outLen)570 static int32_t HpkeLabeledExpand(CRYPT_EAL_KdfCTX *hkdfCtx, HPKE_LabeledExpandParams *params, uint8_t *out,
571     uint32_t outLen)
572 {
573     // labeled_info = I2OSP(L, 2) || "HPKE-v1" || suite_id || label || info
574     const uint8_t *version = (const uint8_t *)"HPKE-v1";
575     uint32_t versionLen = strlen("HPKE-v1");
576     uint32_t partialLen = sizeof(uint16_t) + versionLen + params->suiteIdLen + params->labelLen;
577 
578     if (params->infoLen > (UINT32_MAX - partialLen)) {
579         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
580         return CRYPT_INVALID_ARG;
581     }
582 
583     uint32_t labeledInfoLen = partialLen + params->infoLen;
584     uint8_t *labeledInfo = (uint8_t *)BSL_SAL_Malloc(labeledInfoLen);
585     if (labeledInfo == NULL) {
586         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
587         return CRYPT_MEM_ALLOC_FAIL;
588     }
589 
590     BSL_Uint16ToByte((uint16_t)outLen, labeledInfo);
591     uint32_t offset = sizeof(uint16_t);
592     (void)memcpy_s(labeledInfo + offset, labeledInfoLen - offset, version, versionLen);
593     offset += versionLen;
594     (void)memcpy_s(labeledInfo + offset, labeledInfoLen - offset, params->suiteId, params->suiteIdLen);
595     offset += params->suiteIdLen;
596     (void)memcpy_s(labeledInfo + offset, labeledInfoLen - offset, params->label, params->labelLen);
597     offset += params->labelLen;
598     (void)memcpy_s(labeledInfo + offset, labeledInfoLen - offset, params->info, params->infoLen);
599 
600     HPKE_HkdfExpandParam expandParams = {params->macId, params->prk, params->prkLen, labeledInfo, labeledInfoLen};
601     int32_t ret = HpkeHkdfExpand(hkdfCtx, &expandParams, out, outLen);
602     BSL_SAL_FREE(labeledInfo);
603     return ret;
604 }
605 
GetPubKeyData(CRYPT_EAL_PkeyCtx * pkey,uint8_t * out,uint32_t * outLen)606 static int32_t GetPubKeyData(CRYPT_EAL_PkeyCtx *pkey, uint8_t *out, uint32_t *outLen)
607 {
608     CRYPT_EAL_PkeyPub ephemPub = { 0 };
609     ephemPub.id = CRYPT_EAL_PkeyGetId(pkey);
610     ephemPub.key.eccPub.data = out;
611     ephemPub.key.eccPub.len = *outLen; // compatible curve25519Pub, CRYPT_Data type.
612 
613     int32_t ret = CRYPT_EAL_PkeyGetPub(pkey, &ephemPub);
614     if (ret != CRYPT_SUCCESS) {
615         return ret;
616     }
617 
618     *outLen = ephemPub.key.eccPub.len;
619     return CRYPT_SUCCESS;
620 }
621 
HpkeComputeSharedSecret(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * priKey,CRYPT_EAL_PkeyCtx * pubKey,CRYPT_EAL_PkeyCtx * authKey,uint8_t * kemContext,uint32_t kemContextLen,uint8_t * sharedSecret,uint32_t sharedSecretLen)622 static int32_t HpkeComputeSharedSecret(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *priKey, CRYPT_EAL_PkeyCtx *pubKey,
623     CRYPT_EAL_PkeyCtx *authKey, uint8_t *kemContext, uint32_t kemContextLen, uint8_t *sharedSecret,
624     uint32_t sharedSecretLen)
625 {
626     uint8_t dh[HPKE_KEM_DH_MAX_SHARED_KEY_LEN * 2];
627     uint32_t dhLen = HPKE_KEM_DH_MAX_SHARED_KEY_LEN;
628 
629     int32_t ret = CRYPT_EAL_PkeyComputeShareKey(priKey, pubKey, dh, &dhLen);
630     if (ret != CRYPT_SUCCESS) {
631         memset_s(dh, dhLen, 0, dhLen);
632         return ret;
633     }
634 
635     if (ctx->mode == CRYPT_HPKE_MODE_AUTH || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
636         uint32_t dh0Len = HPKE_KEM_DH_MAX_SHARED_KEY_LEN;
637 
638         if (ctx->role == CRYPT_HPKE_SENDER) {
639             ret = CRYPT_EAL_PkeyComputeShareKey(authKey, pubKey, dh + dhLen, &dh0Len);
640         }
641         if (ctx->role == CRYPT_HPKE_RECIPIENT) {
642             ret = CRYPT_EAL_PkeyComputeShareKey(priKey, authKey, dh + dhLen, &dh0Len);
643         }
644         if (ret != CRYPT_SUCCESS) {
645             memset_s(dh, dhLen + dh0Len, 0, dhLen + dh0Len);
646             return ret;
647         }
648         dhLen = dhLen + dh0Len;
649     }
650 
651     uint8_t suiteId[HPKE_KEM_SUITEID_LEN];
652     HpkeGenerateKemSuiteId(ctx->kemIndex, suiteId, HPKE_KEM_SUITEID_LEN);
653 
654     CRYPT_MAC_AlgId macId = g_hpkeKemAlgInfo[ctx->kemIndex].macId;
655     uint32_t eaePrkLen = g_hpkeKemAlgInfo[ctx->kemIndex].hkdfExtractKeyLen;
656     uint8_t eaePrk[HPKE_HKDF_MAX_EXTRACT_KEY_LEN];
657 
658     HPKE_LabeledExtractParams extractParams = {macId, NULL, 0, (uint8_t *)"eae_prk", strlen("eae_prk"), dh, dhLen,
659         suiteId, HPKE_KEM_SUITEID_LEN};
660     ret = HpkeLabeledExtract(ctx->kdfCtx, &extractParams, eaePrk, eaePrkLen);
661     BSL_SAL_CleanseData(dh, dhLen);
662     if (ret != CRYPT_SUCCESS) {
663         return ret;
664     }
665 
666     HPKE_LabeledExpandParams expandParams = {macId, eaePrk, eaePrkLen, (uint8_t *)"shared_secret",
667         strlen("shared_secret"), kemContext, kemContextLen, suiteId, HPKE_KEM_SUITEID_LEN};
668     ret = HpkeLabeledExpand(ctx->kdfCtx, &expandParams, sharedSecret, sharedSecretLen);
669 
670     BSL_SAL_CleanseData(eaePrk, eaePrkLen);
671     return ret;
672 }
673 
HpkeCreateKemContext(uint8_t * enc,uint32_t encLen,uint8_t * pkR,uint32_t pkRLen,CRYPT_EAL_PkeyCtx * authKey,uint8_t ** out,uint32_t * outLen)674 static int32_t HpkeCreateKemContext(uint8_t *enc, uint32_t encLen, uint8_t *pkR, uint32_t pkRLen,
675     CRYPT_EAL_PkeyCtx *authKey, uint8_t **out, uint32_t *outLen)
676 {
677     uint8_t pkSm[HPKE_KEM_MAX_PUBLIC_KEY_LEN] = { 0 };
678     uint32_t pkSmLen = HPKE_KEM_MAX_PUBLIC_KEY_LEN;
679 
680     if (authKey != NULL) {
681         int32_t ret = GetPubKeyData(authKey, pkSm, &pkSmLen);
682         if (ret != CRYPT_SUCCESS) {
683             return ret;
684         }
685     } else {
686         pkSmLen = 0;
687     }
688 
689     // kemContext = enc || pkRm || pkSm
690     uint32_t kemContextLen = encLen + pkRLen + pkSmLen;
691     uint8_t *kemContext = (uint8_t *)BSL_SAL_Malloc(kemContextLen);
692     if (kemContext == NULL) {
693         return CRYPT_MEM_ALLOC_FAIL;
694     }
695 
696     (void)memcpy_s(kemContext, encLen, enc, encLen);
697     (void)memcpy_s(kemContext + encLen, pkRLen, pkR, pkRLen);
698 
699     if (authKey != NULL) {
700         (void)memcpy_s(kemContext + encLen + pkRLen, pkSmLen, pkSm, pkSmLen);
701     }
702 
703     *out = kemContext;
704     *outLen = kemContextLen;
705     return CRYPT_SUCCESS;
706 }
707 
HpkeEncap(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey,uint8_t * pkR,uint32_t pkRLen,uint8_t * encapsulatedKey,uint32_t * encapsulatedKeyLen,uint8_t * sharedSecret,uint32_t sharedSecretLen)708 static int32_t HpkeEncap(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey, uint8_t *pkR, uint32_t pkRLen,
709     uint8_t *encapsulatedKey, uint32_t *encapsulatedKeyLen, uint8_t *sharedSecret, uint32_t sharedSecretLen)
710 {
711     int32_t ret;
712     CRYPT_EAL_PkeyCtx *pkeyS = pkey;
713     if (pkeyS == NULL) {
714         CRYPT_HPKE_CipherSuite cipherSuite = {g_hpkeKemAlgInfo[ctx->kemIndex].hpkeKemId,
715             g_hpkeKdfAlgInfo[ctx->kdfIndex].hpkeKdfId, g_hpkeAeadAlgInfo[ctx->aeadIndex].hpkeAeadId};
716         ret = CRYPT_EAL_HpkeGenerateKeyPair(ctx->libCtx, ctx->attrName, cipherSuite, NULL, 0, &pkeyS);
717         if (ret != CRYPT_SUCCESS) {
718             return ret;
719         }
720     }
721 
722     CRYPT_EAL_PkeyCtx *pkeyR = NULL;
723     uint8_t enc[HPKE_KEM_MAX_PUBLIC_KEY_LEN] = { 0 };
724     uint32_t encLen = HPKE_KEM_MAX_PUBLIC_KEY_LEN;
725     uint32_t kemContextLen = 0;
726     uint8_t *kemContext = NULL;
727     CRYPT_EAL_PkeyCtx *authKey = NULL;
728 
729     if (ctx->mode == CRYPT_HPKE_MODE_AUTH || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
730         authKey = ctx->authInfo->authPkey;
731     }
732 
733     ret = GetPubKeyData(pkeyS, enc, &encLen);
734     if (ret != CRYPT_SUCCESS) {
735         goto EXIT;
736     }
737 
738     ret = HpkeCreatePubKey(ctx->kemIndex, pkR, pkRLen, &pkeyR, ctx->libCtx, ctx->attrName);
739     if (ret != CRYPT_SUCCESS) {
740         goto EXIT;
741     }
742 
743     ret = HpkeCreateKemContext(enc, encLen, pkR, pkRLen, authKey, &kemContext, &kemContextLen);
744     if (ret != CRYPT_SUCCESS) {
745         goto EXIT;
746     }
747 
748     ret = HpkeComputeSharedSecret(ctx, pkeyS, pkeyR, authKey, kemContext, kemContextLen, sharedSecret, sharedSecretLen);
749     if (ret == CRYPT_SUCCESS) {
750         (void)memcpy_s(encapsulatedKey, *encapsulatedKeyLen, enc, encLen);
751         *encapsulatedKeyLen = encLen;
752     }
753 EXIT:
754     BSL_SAL_FREE(kemContext);
755     CRYPT_EAL_PkeyFreeCtx(pkeyR);
756     if (pkey == NULL) {
757         CRYPT_EAL_PkeyFreeCtx(pkeyS);
758     }
759     return ret;
760 }
761 
HpkeGenKeyScheduleCtx(CRYPT_EAL_HpkeCtx * ctx,uint8_t * info,uint32_t infoLen,uint8_t * pskId,uint32_t pskIdLen,uint8_t * suiteId,uint32_t suiteIdLen,uint8_t ** keyScheduleContext,uint32_t * keyScheduleContextLen)762 static int32_t HpkeGenKeyScheduleCtx(CRYPT_EAL_HpkeCtx *ctx, uint8_t *info, uint32_t infoLen, uint8_t *pskId,
763     uint32_t pskIdLen, uint8_t *suiteId, uint32_t suiteIdLen, uint8_t **keyScheduleContext,
764     uint32_t *keyScheduleContextLen)
765 {
766     uint32_t extractKeyLen = g_hpkeKdfAlgInfo[ctx->kdfIndex].hkdfExtractKeyLen;
767     uint32_t contextLen = sizeof(uint8_t) + extractKeyLen + extractKeyLen;
768     uint8_t *context = (uint8_t *)BSL_SAL_Malloc(contextLen);
769     if (context == NULL) {
770         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
771         return CRYPT_MEM_ALLOC_FAIL;
772     }
773 
774     context[0] = ctx->mode;
775     uint32_t offset = sizeof(uint8_t);
776     CRYPT_MAC_AlgId macId = g_hpkeKdfAlgInfo[ctx->kdfIndex].macId;
777     HPKE_LabeledExtractParams params = {macId, NULL, 0, (uint8_t*)"psk_id_hash", strlen("psk_id_hash"), pskId, pskIdLen,
778         suiteId, suiteIdLen};
779     int32_t ret = HpkeLabeledExtract(ctx->kdfCtx, &params, context + offset, extractKeyLen);
780     if (ret != CRYPT_SUCCESS) {
781         goto EXIT;
782     }
783 
784     offset += extractKeyLen;
785     params.label = (uint8_t*)"info_hash";
786     params.labelLen = strlen("info_hash");
787     params.ikm = info;
788     params.ikmLen = infoLen;
789     ret = HpkeLabeledExtract(ctx->kdfCtx, &params, context + offset, extractKeyLen);
790     if (ret != CRYPT_SUCCESS) {
791         goto EXIT;
792     }
793 
794     *keyScheduleContext = context;
795     *keyScheduleContextLen = contextLen;
796     return CRYPT_SUCCESS;
797 EXIT:
798     BSL_SAL_ClearFree(context, contextLen);
799     return ret;
800 }
801 
HpkeFreeKeyInfo(CRYPT_EAL_HpkeCtx * ctx)802 static void HpkeFreeKeyInfo(CRYPT_EAL_HpkeCtx *ctx)
803 {
804     BSL_SAL_ClearFree(ctx->symKey, ctx->symKeyLen);
805     ctx->symKey = NULL;
806     ctx->symKeyLen = 0;
807 
808     BSL_SAL_ClearFree(ctx->baseNonce, ctx->baseNonceLen);
809     ctx->baseNonce = NULL;
810     ctx->baseNonceLen = 0;
811 
812     BSL_SAL_ClearFree(ctx->exporterSecret, ctx->exporterSecretLen);
813     ctx->exporterSecret = NULL;
814     ctx->exporterSecretLen = 0;
815 }
816 
HpkeMallocKeyInfo(CRYPT_EAL_HpkeCtx * ctx)817 static int32_t HpkeMallocKeyInfo(CRYPT_EAL_HpkeCtx *ctx)
818 {
819     if (g_hpkeAeadAlgInfo[ctx->aeadIndex].hpkeAeadId != CRYPT_AEAD_EXPORT_ONLY) {
820         ctx->symKeyLen = g_hpkeAeadAlgInfo[ctx->aeadIndex].keyLen;
821         ctx->symKey = BSL_SAL_Malloc(ctx->symKeyLen);
822         ctx->baseNonceLen = HPKE_AEAD_NONCE_LEN;
823         ctx->baseNonce = BSL_SAL_Malloc(HPKE_AEAD_NONCE_LEN);
824         if (ctx->symKey == NULL || ctx->baseNonce == NULL) {
825             BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
826             HpkeFreeKeyInfo(ctx);
827             return CRYPT_MEM_ALLOC_FAIL;
828         }
829     }
830 
831     ctx->exporterSecretLen = g_hpkeKdfAlgInfo[ctx->kdfIndex].hkdfExtractKeyLen;
832     ctx->exporterSecret = BSL_SAL_Malloc(ctx->exporterSecretLen);
833     if (ctx->exporterSecret == NULL) {
834         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
835         HpkeFreeKeyInfo(ctx);
836         return CRYPT_MEM_ALLOC_FAIL;
837     }
838     return CRYPT_SUCCESS;
839 }
840 
HpkeDeriveKeyInfo(CRYPT_EAL_HpkeCtx * ctx,HPKE_LabeledExpandParams * expandParams)841 static int32_t HpkeDeriveKeyInfo(CRYPT_EAL_HpkeCtx *ctx, HPKE_LabeledExpandParams *expandParams)
842 {
843     CRYPT_HPKE_AEAD_AlgId aeadId = g_hpkeAeadAlgInfo[ctx->aeadIndex].hpkeAeadId;
844     if (aeadId != CRYPT_AEAD_EXPORT_ONLY) {
845         int32_t ret = HpkeLabeledExpand(ctx->kdfCtx, expandParams, ctx->symKey, ctx->symKeyLen);
846         if (ret != CRYPT_SUCCESS) {
847             return ret;
848         }
849 
850         expandParams->label = (uint8_t*)"base_nonce";
851         expandParams->labelLen = strlen("base_nonce");
852         ret = HpkeLabeledExpand(ctx->kdfCtx, expandParams, ctx->baseNonce, ctx->baseNonceLen);
853         if (ret != CRYPT_SUCCESS) {
854             return ret;
855         }
856     }
857 
858     expandParams->label = (uint8_t*)"exp";
859     expandParams->labelLen = strlen("exp");
860     return HpkeLabeledExpand(ctx->kdfCtx, expandParams, ctx->exporterSecret, ctx->exporterSecretLen);
861 }
862 
HpkeKeySchedule(CRYPT_EAL_HpkeCtx * ctx,uint8_t * sharedSecret,uint32_t sharedSecretLen,uint8_t * info,uint32_t infoLen)863 static int32_t HpkeKeySchedule(CRYPT_EAL_HpkeCtx *ctx, uint8_t *sharedSecret, uint32_t sharedSecretLen, uint8_t *info,
864     uint32_t infoLen)
865 {
866     uint8_t suiteId[HPKE_HPKE_SUITEID_LEN];
867     uint8_t suiteIdLen = HPKE_HPKE_SUITEID_LEN;
868     HpkeGenerateHpkeSuiteId(ctx->kemIndex, ctx->kdfIndex, ctx->aeadIndex, suiteId, HPKE_HPKE_SUITEID_LEN);
869 
870     uint32_t contextLen;
871     uint8_t *context = NULL;
872     uint8_t *pskId = (uint8_t *)"";
873     uint32_t pskIdLen = 0;
874     uint8_t *psk = (uint8_t *)"";
875     uint32_t pskLen = 0;
876 
877     if (ctx->mode == CRYPT_HPKE_MODE_PSK || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
878         pskId = ctx->authInfo->pskId;
879         pskIdLen = ctx->authInfo->pskIdLen;
880         psk = ctx->authInfo->psk;
881         pskLen = ctx->authInfo->pskLen;
882     }
883 
884     int32_t ret = HpkeGenKeyScheduleCtx(ctx, info, infoLen, pskId, pskIdLen, suiteId, suiteIdLen, &context,
885         &contextLen);
886     if (ret != CRYPT_SUCCESS) {
887         return ret;
888     }
889 
890     CRYPT_MAC_AlgId macId = g_hpkeKdfAlgInfo[ctx->kdfIndex].macId;
891     uint8_t secret[HPKE_KEM_MAX_SHARED_KEY_LEN] = {0};
892     uint32_t secretLen = g_hpkeKdfAlgInfo[ctx->kdfIndex].hkdfExtractKeyLen;
893     HPKE_LabeledExtractParams extractparams = {macId, sharedSecret, sharedSecretLen, (uint8_t*)"secret",
894         strlen("secret"), psk, pskLen, suiteId, suiteIdLen};
895     HPKE_LabeledExpandParams expandParams = {macId, secret, secretLen, (uint8_t*)"key", strlen("key"), context,
896         contextLen, suiteId, suiteIdLen};
897 
898     ret = HpkeLabeledExtract(ctx->kdfCtx, &extractparams, secret, secretLen);
899     if (ret != CRYPT_SUCCESS) {
900         goto EXIT;
901     }
902 
903     ret = HpkeMallocKeyInfo(ctx);
904     if (ret != CRYPT_SUCCESS) {
905         goto EXIT;
906     }
907 
908     ret = HpkeDeriveKeyInfo(ctx, &expandParams);
909 
910 EXIT:
911     BSL_SAL_CleanseData(secret, HPKE_KEM_MAX_SHARED_KEY_LEN);
912     BSL_SAL_ClearFree(context, contextLen);
913     if (ret != CRYPT_SUCCESS) {
914         HpkeFreeKeyInfo(ctx);
915     }
916     return ret;
917 }
918 
HpkeCheckAuthInfo(CRYPT_EAL_HpkeCtx * ctx)919 static int32_t HpkeCheckAuthInfo(CRYPT_EAL_HpkeCtx *ctx)
920 {
921     if (ctx->mode == CRYPT_HPKE_MODE_AUTH || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
922         if (ctx->authInfo == NULL || ctx->authInfo->authPkey == NULL) {
923             return CRYPT_HPKE_ERR_CALL;
924         }
925     }
926 
927     if (ctx->mode == CRYPT_HPKE_MODE_PSK || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
928         if (ctx->authInfo == NULL || ctx->authInfo->psk == NULL || ctx->authInfo->pskId == NULL) {
929             return CRYPT_HPKE_ERR_CALL;
930         }
931     }
932 
933     return CRYPT_SUCCESS;
934 }
935 
HpkeFreeAuthInfo(CRYPT_EAL_HpkeCtx * ctx)936 static void HpkeFreeAuthInfo(CRYPT_EAL_HpkeCtx *ctx)
937 {
938     if (ctx->authInfo == NULL) {
939         return;
940     }
941 
942     BSL_SAL_ClearFree(ctx->authInfo->psk, ctx->authInfo->pskLen);
943     ctx->authInfo->psk = NULL;
944     ctx->authInfo->pskLen = 0;
945 
946     BSL_SAL_ClearFree(ctx->authInfo->pskId, ctx->authInfo->pskIdLen);
947     ctx->authInfo->pskId = NULL;
948     ctx->authInfo->pskIdLen = 0;
949 
950     CRYPT_EAL_PkeyFreeCtx(ctx->authInfo->authPkey);
951     ctx->authInfo->authPkey = NULL;
952 
953     BSL_SAL_FREE(ctx->authInfo);
954 }
955 
HpkeCheckSenderParams(CRYPT_EAL_HpkeCtx * ctx,uint8_t * info,uint32_t infoLen,const uint8_t * pkR,uint32_t pkRLen,uint8_t * encapsulatedKey,uint32_t * encapsulatedKeyLen)956 static int32_t HpkeCheckSenderParams(CRYPT_EAL_HpkeCtx *ctx, uint8_t *info, uint32_t infoLen, const uint8_t *pkR,
957     uint32_t pkRLen, uint8_t *encapsulatedKey, uint32_t *encapsulatedKeyLen)
958 {
959     if (ctx == NULL) {
960         return CRYPT_NULL_INPUT;
961     }
962 
963     if (ctx->role != CRYPT_HPKE_SENDER) {
964         return CRYPT_HPKE_ERR_CALL;
965     }
966 
967     if (ctx->sharedSecret != NULL) {
968         return CRYPT_HPKE_ERR_CALL;
969     }
970 
971     if (pkR == NULL || encapsulatedKey == NULL || encapsulatedKeyLen == NULL) {
972         return CRYPT_NULL_INPUT;
973     }
974 
975     if ((info == NULL && infoLen != 0) || (info != NULL && infoLen == 0)) {
976         return CRYPT_INVALID_ARG;
977     }
978 
979     uint32_t encLen = g_hpkeKemAlgInfo[ctx->kemIndex].encapsulatedKeyLen;
980     if (pkRLen != encLen) {
981         return CRYPT_INVALID_ARG;
982     }
983 
984     if (*encapsulatedKeyLen < encLen) {
985         return CRYPT_INVALID_ARG;
986     }
987 
988     return HpkeCheckAuthInfo(ctx);
989 }
990 
CRYPT_EAL_HpkeSetupSender(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey,uint8_t * info,uint32_t infoLen,uint8_t * pkR,uint32_t pkRLen,uint8_t * encapKey,uint32_t * encapKeyLen)991 int32_t CRYPT_EAL_HpkeSetupSender(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey, uint8_t *info, uint32_t infoLen,
992     uint8_t *pkR, uint32_t pkRLen, uint8_t *encapKey, uint32_t *encapKeyLen)
993 {
994     int32_t ret = HpkeCheckSenderParams(ctx, info, infoLen, pkR, pkRLen, encapKey, encapKeyLen);
995     if (ret != CRYPT_SUCCESS) {
996         BSL_ERR_PUSH_ERROR(ret);
997         return ret;
998     }
999 
1000     uint32_t sharedSecretLen = g_hpkeKemAlgInfo[ctx->kemIndex].sharedKeyLen;
1001     uint8_t *sharedSecret = BSL_SAL_Malloc(sharedSecretLen);
1002     if (sharedSecret == NULL) {
1003         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1004         return CRYPT_MEM_ALLOC_FAIL;
1005     }
1006 
1007     ret = HpkeEncap(ctx, pkey, pkR, pkRLen, encapKey, encapKeyLen, sharedSecret, sharedSecretLen);
1008     if (ret != CRYPT_SUCCESS) {
1009         BSL_SAL_ClearFree(sharedSecret, sharedSecretLen);
1010         return ret;
1011     }
1012 
1013     ret = HpkeKeySchedule(ctx, sharedSecret, sharedSecretLen, info, infoLen);
1014     if (ret != CRYPT_SUCCESS) {
1015         BSL_SAL_ClearFree(sharedSecret, sharedSecretLen);
1016         return ret;
1017     }
1018 
1019     ctx->sharedSecret = sharedSecret;
1020     ctx->sharedSecretLen = sharedSecretLen;
1021     HpkeFreeAuthInfo(ctx); // Derived key successfully, no longer requires authinfo
1022     return ret;
1023 }
1024 
HpkeAeadEncrypt(CRYPT_EAL_HpkeCtx * ctx,const uint8_t * nonce,uint32_t nonceLen,uint8_t * aad,uint32_t aadLen,const uint8_t * plainText,uint32_t plainTextLen,uint8_t * cipherText,uint32_t * cipherTextLen)1025 static int32_t HpkeAeadEncrypt(CRYPT_EAL_HpkeCtx *ctx, const uint8_t *nonce, uint32_t nonceLen, uint8_t *aad,
1026     uint32_t aadLen, const uint8_t *plainText, uint32_t plainTextLen, uint8_t *cipherText, uint32_t *cipherTextLen)
1027 {
1028     CRYPT_EAL_CipherCtx *cipherCtx = ctx->cipherCtx;
1029     uint32_t outLen = *cipherTextLen;
1030     int32_t ret = CRYPT_EAL_CipherInit(cipherCtx, ctx->symKey, ctx->symKeyLen, nonce, nonceLen, true);
1031     if (ret != CRYPT_SUCCESS) {
1032         goto EXIT;
1033     }
1034 
1035     if (aad != NULL && aadLen > 0) {
1036         ret = CRYPT_EAL_CipherCtrl(cipherCtx, CRYPT_CTRL_SET_AAD, aad, aadLen);
1037         if (ret != CRYPT_SUCCESS) {
1038             goto EXIT;
1039         }
1040     }
1041 
1042     ret = CRYPT_EAL_CipherUpdate(cipherCtx, plainText, plainTextLen, cipherText, &outLen);
1043     if (ret != CRYPT_SUCCESS) {
1044         goto EXIT;
1045     }
1046 
1047     ret = CRYPT_EAL_CipherCtrl(cipherCtx, CRYPT_CTRL_GET_TAG, cipherText + outLen, HPKE_AEAD_TAG_LEN);
1048     if (ret != CRYPT_SUCCESS) {
1049         goto EXIT;
1050     }
1051 
1052     *cipherTextLen = outLen + HPKE_AEAD_TAG_LEN;
1053 EXIT:
1054     CRYPT_EAL_CipherDeinit(cipherCtx);
1055     return ret;
1056 }
1057 
CRYPT_EAL_HpkeSetSeq(CRYPT_EAL_HpkeCtx * ctx,uint64_t seq)1058 int32_t CRYPT_EAL_HpkeSetSeq(CRYPT_EAL_HpkeCtx *ctx, uint64_t seq)
1059 {
1060     if (ctx == NULL) {
1061         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1062         return CRYPT_NULL_INPUT;
1063     }
1064 
1065     if (seq == UINT64_MAX) {
1066         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1067         return CRYPT_INVALID_ARG;
1068     }
1069 
1070     ctx->seq = seq;
1071     return CRYPT_SUCCESS;
1072 }
1073 
CRYPT_EAL_HpkeGetSeq(CRYPT_EAL_HpkeCtx * ctx,uint64_t * seq)1074 int32_t CRYPT_EAL_HpkeGetSeq(CRYPT_EAL_HpkeCtx *ctx, uint64_t *seq)
1075 {
1076     if (ctx == NULL || seq == NULL) {
1077         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1078         return CRYPT_NULL_INPUT;
1079     }
1080 
1081     *seq = ctx->seq;
1082     return CRYPT_SUCCESS;
1083 }
1084 
HpkeComputeNonce(CRYPT_EAL_HpkeCtx * ctx,uint8_t * nonce,uint32_t nonceLen)1085 static void HpkeComputeNonce(CRYPT_EAL_HpkeCtx *ctx, uint8_t *nonce, uint32_t nonceLen)
1086 {
1087     uint64_t seq = ctx->seq;
1088     for (uint32_t i = 0; i < sizeof(seq); i++) {
1089         nonce[nonceLen - i - 1] = seq & UINT8_MAX;
1090         seq = seq >> 8; // 8 bits
1091     }
1092 
1093     for (uint32_t i = 0; i < nonceLen; i++) {
1094         nonce[i] ^= ctx->baseNonce[i];
1095     }
1096 }
1097 
HpkeCheckSealParams(CRYPT_EAL_HpkeCtx * ctx,const uint8_t * plainText,uint32_t plainTextLen,uint32_t * cipherTextLen)1098 static int32_t HpkeCheckSealParams(CRYPT_EAL_HpkeCtx *ctx, const uint8_t *plainText, uint32_t plainTextLen,
1099     uint32_t *cipherTextLen)
1100 {
1101     if (ctx == NULL) {
1102         return CRYPT_NULL_INPUT;
1103     }
1104 
1105     if (ctx->role != CRYPT_HPKE_SENDER) {
1106         return CRYPT_HPKE_ERR_CALL;
1107     }
1108 
1109     if (g_hpkeAeadAlgInfo[ctx->aeadIndex].hpkeAeadId == CRYPT_AEAD_EXPORT_ONLY) {
1110         return CRYPT_HPKE_ERR_CALL;
1111     }
1112 
1113     if (ctx->symKey == NULL || ctx->baseNonce == NULL) {
1114         return CRYPT_HPKE_ERR_CALL;
1115     }
1116 
1117     if (plainText == NULL || plainTextLen == 0 || cipherTextLen == NULL) {
1118         return CRYPT_NULL_INPUT;
1119     }
1120 
1121     if (plainTextLen > (UINT32_MAX - HPKE_AEAD_TAG_LEN)) {
1122         return CRYPT_INVALID_ARG;
1123     }
1124 
1125     return CRYPT_SUCCESS;
1126 }
1127 
CRYPT_EAL_HpkeSeal(CRYPT_EAL_HpkeCtx * ctx,uint8_t * aad,uint32_t aadLen,const uint8_t * plainText,uint32_t plainTextLen,uint8_t * cipherText,uint32_t * cipherTextLen)1128 int32_t CRYPT_EAL_HpkeSeal(CRYPT_EAL_HpkeCtx *ctx, uint8_t *aad, uint32_t aadLen, const uint8_t *plainText,
1129     uint32_t plainTextLen, uint8_t *cipherText, uint32_t *cipherTextLen)
1130 {
1131     int32_t ret = HpkeCheckSealParams(ctx, plainText, plainTextLen, cipherTextLen);
1132     if (ret != CRYPT_SUCCESS) {
1133         BSL_ERR_PUSH_ERROR(ret);
1134         return ret;
1135     }
1136 
1137     if (ctx->seq + 1 == 0) {
1138         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1139         return CRYPT_HPKE_ERR_CALL;
1140     }
1141 
1142     if (cipherText == NULL) {
1143         *cipherTextLen = plainTextLen + HPKE_AEAD_TAG_LEN;
1144         return CRYPT_SUCCESS;
1145     }
1146 
1147     if (*cipherTextLen < (plainTextLen + HPKE_AEAD_TAG_LEN)) {
1148         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1149         return CRYPT_INVALID_ARG;
1150     }
1151 
1152     uint8_t nonce[HPKE_AEAD_NONCE_LEN] = { 0 };
1153     HpkeComputeNonce(ctx, nonce, HPKE_AEAD_NONCE_LEN);
1154 
1155     ret = HpkeAeadEncrypt(ctx, nonce, HPKE_AEAD_NONCE_LEN, aad, aadLen, plainText, plainTextLen, cipherText,
1156         cipherTextLen);
1157     if (ret == CRYPT_SUCCESS) {
1158         ctx->seq++;
1159     }
1160     return ret;
1161 }
1162 
HpkeDecap(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey,uint8_t * encKey,uint32_t encKeyLen,uint8_t * sharedSecret,uint32_t sharedSecretLen)1163 static int32_t HpkeDecap(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey, uint8_t *encKey, uint32_t encKeyLen,
1164     uint8_t *sharedSecret, uint32_t sharedSecretLen)
1165 {
1166     CRYPT_EAL_PkeyCtx *pkeyS = NULL;
1167     int32_t ret = HpkeCreatePubKey(ctx->kemIndex, encKey, encKeyLen, &pkeyS, ctx->libCtx, ctx->attrName);
1168     if (ret != CRYPT_SUCCESS) {
1169         return ret;
1170     }
1171 
1172     uint8_t *kemContext = NULL;
1173     uint32_t kemContextLen;
1174     uint8_t pubKeyData[HPKE_KEM_MAX_PUBLIC_KEY_LEN];
1175     uint32_t pubKeyDataLen = HPKE_KEM_MAX_PUBLIC_KEY_LEN;
1176     CRYPT_EAL_PkeyCtx *authKey = NULL;
1177 
1178     if (ctx->mode == CRYPT_HPKE_MODE_AUTH || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
1179         authKey = ctx->authInfo->authPkey;
1180     }
1181 
1182     ret = GetPubKeyData(pkey, pubKeyData, &pubKeyDataLen);
1183     if (ret != CRYPT_SUCCESS) {
1184         goto EXIT;
1185     }
1186 
1187     ret = HpkeCreateKemContext(encKey, encKeyLen, pubKeyData, pubKeyDataLen, authKey, &kemContext, &kemContextLen);
1188     if (ret != CRYPT_SUCCESS) {
1189         goto EXIT;
1190     }
1191 
1192     ret = HpkeComputeSharedSecret(ctx, pkey, pkeyS, authKey, kemContext, kemContextLen, sharedSecret, sharedSecretLen);
1193 
1194 EXIT:
1195     CRYPT_EAL_PkeyFreeCtx(pkeyS);
1196     BSL_SAL_FREE(kemContext);
1197     return ret;
1198 }
1199 
HpkeCheckRecipientParams(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey,uint8_t * info,uint32_t infoLen,const uint8_t * encapsulatedKey,uint32_t encapsulatedKeyLen)1200 static int32_t HpkeCheckRecipientParams(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey, uint8_t *info,
1201     uint32_t infoLen, const uint8_t *encapsulatedKey, uint32_t encapsulatedKeyLen)
1202 {
1203     if (ctx == NULL) {
1204         return CRYPT_NULL_INPUT;
1205     }
1206 
1207     if (ctx->role != CRYPT_HPKE_RECIPIENT) {
1208         return CRYPT_HPKE_ERR_CALL;
1209     }
1210 
1211     if (ctx->sharedSecret != NULL) {
1212         return CRYPT_HPKE_ERR_CALL;
1213     }
1214 
1215     if ((info == NULL && infoLen != 0) || (info != NULL && infoLen == 0)) {
1216         return CRYPT_INVALID_ARG;
1217     }
1218 
1219     if (pkey == NULL || encapsulatedKey == NULL) {
1220         return CRYPT_NULL_INPUT;
1221     }
1222 
1223     if (encapsulatedKeyLen != g_hpkeKemAlgInfo[ctx->kemIndex].encapsulatedKeyLen) {
1224         return CRYPT_INVALID_ARG;
1225     }
1226 
1227     return HpkeCheckAuthInfo(ctx);
1228 }
1229 
CRYPT_EAL_HpkeSetupRecipient(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey,uint8_t * info,uint32_t infoLen,uint8_t * encapKey,uint32_t encapKeyLen)1230 int32_t CRYPT_EAL_HpkeSetupRecipient(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey, uint8_t *info, uint32_t infoLen,
1231     uint8_t *encapKey, uint32_t encapKeyLen)
1232 {
1233     int32_t ret = HpkeCheckRecipientParams(ctx, pkey, info, infoLen, encapKey, encapKeyLen);
1234     if (ret != CRYPT_SUCCESS) {
1235         BSL_ERR_PUSH_ERROR(ret);
1236         return ret;
1237     }
1238 
1239     uint32_t sharedSecretLen = g_hpkeKemAlgInfo[ctx->kemIndex].sharedKeyLen;
1240     uint8_t *sharedSecret = BSL_SAL_Malloc(sharedSecretLen);
1241     if (sharedSecret == NULL) {
1242         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1243         return CRYPT_MEM_ALLOC_FAIL;
1244     }
1245 
1246     ret = HpkeDecap(ctx, pkey, encapKey, encapKeyLen, sharedSecret, sharedSecretLen);
1247     if (ret != CRYPT_SUCCESS) {
1248         BSL_SAL_ClearFree(sharedSecret, sharedSecretLen);
1249         return ret;
1250     }
1251 
1252     ret = HpkeKeySchedule(ctx, sharedSecret, sharedSecretLen, info, infoLen);
1253     if (ret != CRYPT_SUCCESS) {
1254         BSL_SAL_ClearFree(sharedSecret, sharedSecretLen);
1255         return ret;
1256     }
1257 
1258     ctx->sharedSecret = sharedSecret;
1259     ctx->sharedSecretLen = sharedSecretLen;
1260     HpkeFreeAuthInfo(ctx); // Derived key successfully, no longer requires authinfo
1261     return ret;
1262 }
1263 
HpkeAeadDecrypt(CRYPT_EAL_HpkeCtx * ctx,const uint8_t * nonce,uint32_t nonceLen,uint8_t * aad,uint32_t aadLen,const uint8_t * cipherText,uint32_t cipherTextLen,uint8_t * plainText,uint32_t * plainTextLen)1264 static int32_t HpkeAeadDecrypt(CRYPT_EAL_HpkeCtx *ctx, const uint8_t *nonce, uint32_t nonceLen, uint8_t *aad,
1265     uint32_t aadLen, const uint8_t *cipherText, uint32_t cipherTextLen, uint8_t *plainText, uint32_t *plainTextLen)
1266 {
1267     CRYPT_EAL_CipherCtx *cipherCtx = ctx->cipherCtx;
1268 
1269     int32_t ret = CRYPT_EAL_CipherInit(cipherCtx, ctx->symKey, ctx->symKeyLen, nonce, nonceLen, false);
1270     if (ret != CRYPT_SUCCESS) {
1271         CRYPT_EAL_CipherDeinit(cipherCtx);
1272         return ret;
1273     }
1274 
1275     if (aad != NULL && aadLen > 0) {
1276         ret = CRYPT_EAL_CipherCtrl(cipherCtx, CRYPT_CTRL_SET_AAD, (void *)aad, aadLen);
1277         if (ret != CRYPT_SUCCESS) {
1278             CRYPT_EAL_CipherDeinit(cipherCtx);
1279             return ret;
1280         }
1281     }
1282 
1283     ret = CRYPT_EAL_CipherUpdate(cipherCtx, cipherText, cipherTextLen - HPKE_AEAD_TAG_LEN, plainText, plainTextLen);
1284     if (ret != CRYPT_SUCCESS) {
1285         CRYPT_EAL_CipherDeinit(cipherCtx);
1286         return ret;
1287     }
1288 
1289     uint8_t tag[HPKE_AEAD_TAG_LEN];
1290     ret = CRYPT_EAL_CipherCtrl(cipherCtx, CRYPT_CTRL_GET_TAG, (void *)tag, HPKE_AEAD_TAG_LEN);
1291     if (ret != CRYPT_SUCCESS) {
1292         goto EXIT;
1293     }
1294 
1295     if (memcmp(tag, cipherText + (cipherTextLen - HPKE_AEAD_TAG_LEN), HPKE_AEAD_TAG_LEN) != 0) {
1296         ret = CRYPT_HPKE_ERR_AEAD_TAG;
1297         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_AEAD_TAG);
1298     }
1299 
1300 EXIT:
1301     if (ret != CRYPT_SUCCESS) {
1302         BSL_SAL_CleanseData(plainText, *plainTextLen);
1303     }
1304 
1305     CRYPT_EAL_CipherDeinit(cipherCtx);
1306     return ret;
1307 }
1308 
HpkeCheckOpenParams(CRYPT_EAL_HpkeCtx * ctx,const uint8_t * cipherText,uint32_t cipherTextLen,uint32_t * plainTextLen)1309 static int32_t HpkeCheckOpenParams(CRYPT_EAL_HpkeCtx *ctx, const uint8_t *cipherText, uint32_t cipherTextLen,
1310     uint32_t *plainTextLen)
1311 {
1312     if (ctx == NULL) {
1313         return CRYPT_NULL_INPUT;
1314     }
1315 
1316     if (ctx->role != CRYPT_HPKE_RECIPIENT) {
1317         return CRYPT_HPKE_ERR_CALL;
1318     }
1319 
1320     if (g_hpkeAeadAlgInfo[ctx->aeadIndex].hpkeAeadId == CRYPT_AEAD_EXPORT_ONLY) {
1321         return CRYPT_HPKE_ERR_CALL;
1322     }
1323 
1324     if (ctx->symKey == NULL || ctx->baseNonce == NULL) {
1325         return CRYPT_HPKE_ERR_CALL;
1326     }
1327 
1328     if (cipherText == NULL || cipherTextLen == 0 || plainTextLen == NULL) {
1329         return CRYPT_NULL_INPUT;
1330     }
1331 
1332     return CRYPT_SUCCESS;
1333 }
1334 
CRYPT_EAL_HpkeOpen(CRYPT_EAL_HpkeCtx * ctx,uint8_t * aad,uint32_t aadLen,const uint8_t * cipherText,uint32_t cipherTextLen,uint8_t * plainText,uint32_t * plainTextLen)1335 int32_t CRYPT_EAL_HpkeOpen(CRYPT_EAL_HpkeCtx *ctx, uint8_t *aad, uint32_t aadLen, const uint8_t *cipherText,
1336     uint32_t cipherTextLen, uint8_t *plainText, uint32_t *plainTextLen)
1337 {
1338     int32_t ret = HpkeCheckOpenParams(ctx, cipherText, cipherTextLen, plainTextLen);
1339     if (ret != CRYPT_SUCCESS) {
1340         BSL_ERR_PUSH_ERROR(ret);
1341         return ret;
1342     }
1343 
1344     if (ctx->seq + 1 == 0) {
1345         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1346         return CRYPT_HPKE_ERR_CALL;
1347     }
1348 
1349     if (cipherTextLen <= HPKE_AEAD_TAG_LEN) {
1350         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1351         return CRYPT_INVALID_ARG;
1352     }
1353 
1354     if (plainText == NULL) {
1355         *plainTextLen = cipherTextLen - HPKE_AEAD_TAG_LEN;
1356         return CRYPT_SUCCESS;
1357     }
1358 
1359     uint8_t nonce[HPKE_AEAD_NONCE_LEN] = { 0 };
1360     HpkeComputeNonce(ctx, nonce, HPKE_AEAD_NONCE_LEN);
1361 
1362     ret = HpkeAeadDecrypt(ctx, nonce, HPKE_AEAD_NONCE_LEN, aad, aadLen, cipherText, cipherTextLen, plainText,
1363         plainTextLen);
1364     if (ret == CRYPT_SUCCESS) {
1365         ctx->seq++;
1366     }
1367     return ret;
1368 }
1369 
CRYPT_EAL_HpkeFreeCtx(CRYPT_EAL_HpkeCtx * ctx)1370 void CRYPT_EAL_HpkeFreeCtx(CRYPT_EAL_HpkeCtx *ctx)
1371 {
1372     if (ctx == NULL) {
1373         return;
1374     }
1375     BSL_SAL_ClearFree(ctx->sharedSecret, ctx->sharedSecretLen);
1376     HpkeFreeKeyInfo(ctx);
1377     CRYPT_EAL_CipherFreeCtx(ctx->cipherCtx);
1378     CRYPT_EAL_KdfFreeCtx(ctx->kdfCtx);
1379     BSL_SAL_FREE(ctx->attrName);
1380     HpkeFreeAuthInfo(ctx);
1381     BSL_SAL_ClearFree(ctx, sizeof(CRYPT_EAL_HpkeCtx));
1382 }
1383 
HpkeGetEccOrder(CRYPT_EAL_PkeyCtx * pkey,BN_BigNum ** order)1384 static int32_t HpkeGetEccOrder(CRYPT_EAL_PkeyCtx *pkey, BN_BigNum **order)
1385 {
1386     uint8_t ecP[MAX_ECC_PARAM_LEN];
1387     uint8_t ecA[MAX_ECC_PARAM_LEN];
1388     uint8_t ecB[MAX_ECC_PARAM_LEN];
1389     uint8_t ecN[MAX_ECC_PARAM_LEN];
1390     uint8_t ecH[MAX_ECC_PARAM_LEN];
1391     uint8_t ecX[MAX_ECC_PARAM_LEN];
1392     uint8_t ecY[MAX_ECC_PARAM_LEN];
1393 
1394     CRYPT_EAL_PkeyPara para = {0};
1395     para.id = CRYPT_EAL_PkeyGetId(pkey);
1396     para.para.eccPara.p = ecP;
1397     para.para.eccPara.a = ecA;
1398     para.para.eccPara.b = ecB;
1399     para.para.eccPara.n = ecN;
1400     para.para.eccPara.h = ecH;
1401     para.para.eccPara.x = ecX;
1402     para.para.eccPara.y = ecY;
1403     para.para.eccPara.pLen = MAX_ECC_PARAM_LEN;
1404     para.para.eccPara.aLen = MAX_ECC_PARAM_LEN;
1405     para.para.eccPara.bLen = MAX_ECC_PARAM_LEN;
1406     para.para.eccPara.nLen = MAX_ECC_PARAM_LEN;
1407     para.para.eccPara.hLen = MAX_ECC_PARAM_LEN;
1408     para.para.eccPara.xLen = MAX_ECC_PARAM_LEN;
1409     para.para.eccPara.yLen = MAX_ECC_PARAM_LEN;
1410     int32_t ret = CRYPT_EAL_PkeyGetPara(pkey, &para);
1411     if (ret != CRYPT_SUCCESS) {
1412         return ret;
1413     }
1414 
1415     BN_BigNum *bn = BN_Create(para.para.eccPara.nLen * 8);
1416     if (bn == NULL) {
1417         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1418         return CRYPT_MEM_ALLOC_FAIL;
1419     }
1420 
1421     ret = BN_Bin2Bn(bn, para.para.eccPara.n, para.para.eccPara.nLen);
1422     if (ret != CRYPT_SUCCESS) {
1423         BN_Destroy(bn);
1424         return ret;
1425     }
1426 
1427     *order = bn;
1428     return CRYPT_SUCCESS;
1429 }
1430 
HpkeExpandEccPriKey(CRYPT_EAL_PkeyCtx * pkey,CRYPT_EAL_KdfCTX * hkdfCtx,uint32_t kemIndex,HPKE_LabeledExpandParams * params,uint8_t * sk,uint32_t skLen)1431 static int32_t HpkeExpandEccPriKey(CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_KdfCTX *hkdfCtx, uint32_t kemIndex,
1432     HPKE_LabeledExpandParams *params, uint8_t *sk, uint32_t skLen)
1433 {
1434     BN_BigNum *order = NULL;
1435     int32_t ret = HpkeGetEccOrder(pkey, &order);
1436     if (ret != CRYPT_SUCCESS) {
1437         return ret;
1438     }
1439 
1440     BN_BigNum *skBn = BN_Create(skLen * 8);
1441     if (skBn == NULL) {
1442         BN_Destroy(order);
1443         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1444         return CRYPT_MEM_ALLOC_FAIL;
1445     }
1446 
1447     uint8_t counter = 0;
1448     uint8_t bitmask = 0xFF; // 0xFF for P256 P384
1449     if (g_hpkeKemAlgInfo[kemIndex].hpkeKemId == CRYPT_KEM_DHKEM_P521_HKDF_SHA512) {
1450         bitmask = 0x01;
1451     }
1452     do {
1453         if (counter == 255) { // RFC9180 7.1.3, up to 255 attempts.
1454             ret = CRYPT_HPKE_ERR_GEN_ASYM_KEY;
1455             BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_GEN_ASYM_KEY);
1456             break;
1457         }
1458         *(params->info) = counter;
1459         ret = HpkeLabeledExpand(hkdfCtx, params, sk, skLen);
1460         if (ret != CRYPT_SUCCESS) {
1461             break;
1462         }
1463 
1464         sk[0] = sk[0] & bitmask;
1465         ret = BN_Bin2Bn(skBn, sk, skLen);
1466         if (ret != CRYPT_SUCCESS) {
1467             break;
1468         }
1469         counter++;
1470     } while (BN_IsZero(skBn) || BN_Cmp(skBn, order) >= 0);
1471     BN_Destroy(skBn);
1472     BN_Destroy(order);
1473 
1474     if (ret != CRYPT_SUCCESS) {
1475         BSL_SAL_CleanseData(sk, skLen);
1476     }
1477     return ret;
1478 }
1479 
DeriveSk(uint8_t kemIndex,CRYPT_EAL_KdfCTX * kdfCtx,CRYPT_EAL_PkeyCtx * pkey,HPKE_LabeledExpandParams * expandParams,uint8_t * sk,uint32_t skLen)1480 static int32_t DeriveSk(uint8_t kemIndex, CRYPT_EAL_KdfCTX *kdfCtx, CRYPT_EAL_PkeyCtx *pkey,
1481     HPKE_LabeledExpandParams *expandParams, uint8_t *sk, uint32_t skLen)
1482 {
1483     if (g_hpkeKemAlgInfo[kemIndex].hpkeKemId == CRYPT_KEM_DHKEM_X25519_HKDF_SHA256) {
1484         return HpkeLabeledExpand(kdfCtx, expandParams, sk, skLen);
1485     } else {
1486         uint8_t counter = 0;
1487         expandParams->label = (uint8_t *)"candidate";
1488         expandParams->labelLen = strlen("candidate");
1489         expandParams->info = (uint8_t *)&counter;
1490         expandParams->infoLen = sizeof(uint8_t);
1491         return HpkeExpandEccPriKey(pkey, kdfCtx, kemIndex, expandParams, sk, skLen);
1492     }
1493 }
1494 
HpkeDeriveKeyPair(uint8_t kemIndex,uint8_t * ikm,uint32_t ikmLen,CRYPT_EAL_PkeyCtx ** pctx,CRYPT_EAL_LibCtx * libCtx,const char * attrName)1495 static int32_t HpkeDeriveKeyPair(uint8_t kemIndex, uint8_t *ikm, uint32_t ikmLen,
1496     CRYPT_EAL_PkeyCtx **pctx, CRYPT_EAL_LibCtx *libCtx, const char *attrName)
1497 {
1498     uint8_t suiteId[HPKE_KEM_SUITEID_LEN];
1499     HpkeGenerateKemSuiteId(kemIndex, suiteId, HPKE_KEM_SUITEID_LEN);
1500 
1501     uint8_t dkpPrk[HPKE_HKDF_MAX_EXTRACT_KEY_LEN];
1502     uint8_t sk[HPKE_KEM_MAX_PRIVATE_KEY_LEN] = { 0 };
1503     uint32_t dkpPrkLen = g_hpkeKemAlgInfo[kemIndex].hkdfExtractKeyLen;
1504     CRYPT_MAC_AlgId macId = g_hpkeKemAlgInfo[kemIndex].macId;
1505     uint32_t skLen = g_hpkeKemAlgInfo[kemIndex].privateKeyLen;
1506 
1507     CRYPT_EAL_KdfCTX *kdfCtx = NULL;
1508     kdfCtx = CRYPT_EAL_ProviderKdfNewCtx(libCtx, CRYPT_KDF_HKDF, attrName);
1509     if (kdfCtx == NULL) {
1510         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_FAILED_FETCH_KDF);
1511         return CRYPT_HPKE_FAILED_FETCH_KDF;
1512     }
1513 
1514     CRYPT_EAL_PkeyCtx *pkey = NULL;
1515     int32_t ret = HpkeCreatePkeyCtx(kemIndex, &pkey, libCtx, attrName);
1516     if (ret != CRYPT_SUCCESS) {
1517         CRYPT_EAL_KdfFreeCtx(kdfCtx);
1518         return ret;
1519     }
1520 
1521     HPKE_LabeledExtractParams extractParams = {macId, (uint8_t *)"", 0, (uint8_t *)"dkp_prk", strlen("dkp_prk"),
1522         ikm, ikmLen, suiteId, HPKE_KEM_SUITEID_LEN};
1523     HPKE_LabeledExpandParams expandParams = {macId, dkpPrk, dkpPrkLen, (uint8_t *)"sk", strlen("sk"), (uint8_t *)"", 0,
1524         suiteId, HPKE_KEM_SUITEID_LEN};
1525     ret = HpkeLabeledExtract(kdfCtx, &extractParams, dkpPrk, dkpPrkLen);
1526     if (ret != CRYPT_SUCCESS) {
1527         goto EXIT;
1528     }
1529 
1530     ret = DeriveSk(kemIndex, kdfCtx, pkey, &expandParams, sk, skLen);
1531     if (ret != CRYPT_SUCCESS) {
1532         goto EXIT;
1533     }
1534 
1535     ret = HpkeCreatePriKey(kemIndex, sk, skLen, &pkey, libCtx, attrName);
1536 
1537 EXIT:
1538     CRYPT_EAL_KdfFreeCtx(kdfCtx);
1539     BSL_SAL_CleanseData(sk, skLen);
1540     BSL_SAL_CleanseData(dkpPrk, HPKE_HKDF_MAX_EXTRACT_KEY_LEN);
1541     if (ret != CRYPT_SUCCESS) {
1542         CRYPT_EAL_PkeyFreeCtx(pkey);
1543         return ret;
1544     }
1545     *pctx = pkey;
1546     return CRYPT_SUCCESS;
1547 }
1548 
CRYPT_EAL_HpkeGenerateKeyPair(CRYPT_EAL_LibCtx * libCtx,const char * attrName,CRYPT_HPKE_CipherSuite cipherSuite,uint8_t * ikm,uint32_t ikmLen,CRYPT_EAL_PkeyCtx ** pctx)1549 int32_t CRYPT_EAL_HpkeGenerateKeyPair(CRYPT_EAL_LibCtx *libCtx, const char *attrName,
1550     CRYPT_HPKE_CipherSuite cipherSuite, uint8_t *ikm, uint32_t ikmLen, CRYPT_EAL_PkeyCtx **pctx)
1551 {
1552     if (pctx == NULL) {
1553         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1554         return CRYPT_NULL_INPUT;
1555     }
1556 
1557     if (*pctx != NULL) {
1558         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1559         return CRYPT_INVALID_ARG;
1560     }
1561 
1562     uint8_t kemIndex;
1563     int32_t ret = HpkeCheckCipherSuite(&cipherSuite, &kemIndex, NULL, NULL);
1564     if (ret != CRYPT_SUCCESS) {
1565         return ret;
1566     }
1567 
1568     uint32_t ikmNewLen = g_hpkeKemAlgInfo[kemIndex].privateKeyLen;
1569     if (ikm != NULL && ikmLen != 0) {
1570         if (ikmLen < ikmNewLen) {
1571             BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1572             return CRYPT_INVALID_ARG;
1573         }
1574         return HpkeDeriveKeyPair(kemIndex, ikm, ikmLen, pctx, libCtx, attrName);
1575     }
1576 
1577     uint8_t ikmNew[HPKE_KEM_MAX_PRIVATE_KEY_LEN];
1578     ret = CRYPT_EAL_RandbytesEx(libCtx, ikmNew, ikmNewLen);
1579     if (ret != CRYPT_SUCCESS) {
1580         return ret;
1581     }
1582 
1583     ret = HpkeDeriveKeyPair(kemIndex, ikmNew, ikmNewLen, pctx, libCtx, attrName);
1584     BSL_SAL_CleanseData(ikmNew, ikmNewLen);
1585     return ret;
1586 }
1587 
CRYPT_EAL_HpkeExportSecret(CRYPT_EAL_HpkeCtx * ctx,uint8_t * info,uint32_t infoLen,uint8_t * key,uint32_t keyLen)1588 int32_t CRYPT_EAL_HpkeExportSecret(CRYPT_EAL_HpkeCtx *ctx, uint8_t *info, uint32_t infoLen, uint8_t *key,
1589     uint32_t keyLen)
1590 {
1591     if (ctx == NULL || key == NULL || keyLen == 0) {
1592         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1593         return CRYPT_NULL_INPUT;
1594     }
1595 
1596     if (ctx->exporterSecret == NULL) {
1597         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1598         return CRYPT_HPKE_ERR_CALL;
1599     }
1600 
1601     if ((info == NULL && infoLen != 0) || (info != NULL && infoLen == 0)) {
1602         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1603         return CRYPT_INVALID_ARG;
1604     }
1605 
1606     if (keyLen > 255 * g_hpkeKdfAlgInfo[ctx->kdfIndex].hkdfExtractKeyLen) { // RFC9180 5.3 max L is 255*Nh
1607         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1608         return CRYPT_INVALID_ARG;
1609     }
1610 
1611     uint8_t suiteId[HPKE_HPKE_SUITEID_LEN];
1612     HpkeGenerateHpkeSuiteId(ctx->kemIndex, ctx->kdfIndex, ctx->aeadIndex, suiteId, HPKE_HPKE_SUITEID_LEN);
1613 
1614     CRYPT_MAC_AlgId macId = g_hpkeKdfAlgInfo[ctx->kdfIndex].macId;
1615     HPKE_LabeledExpandParams params = {macId, ctx->exporterSecret, ctx->exporterSecretLen, (uint8_t *)"sec",
1616         strlen("sec"), info, infoLen, suiteId, HPKE_HPKE_SUITEID_LEN};
1617     return HpkeLabeledExpand(ctx->kdfCtx, &params, key, keyLen);
1618 }
1619 
CRYPT_EAL_HpkeGetSharedSecret(CRYPT_EAL_HpkeCtx * ctx,uint8_t * buff,uint32_t * buffLen)1620 int32_t CRYPT_EAL_HpkeGetSharedSecret(CRYPT_EAL_HpkeCtx *ctx, uint8_t *buff, uint32_t *buffLen)
1621 {
1622     if (ctx == NULL || buffLen == NULL) {
1623         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1624         return CRYPT_NULL_INPUT;
1625     }
1626 
1627     if (ctx->sharedSecret == NULL) {
1628         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1629         return CRYPT_HPKE_ERR_CALL;
1630     }
1631 
1632     if (buff == NULL) {
1633         *buffLen = ctx->sharedSecretLen;
1634         return CRYPT_SUCCESS;
1635     }
1636 
1637     if (*buffLen < ctx->sharedSecretLen) {
1638         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1639         return CRYPT_INVALID_ARG;
1640     }
1641 
1642     (void)memcpy_s(buff, *buffLen, ctx->sharedSecret, ctx->sharedSecretLen);
1643     *buffLen = ctx->sharedSecretLen;
1644     return CRYPT_SUCCESS;
1645 }
1646 
CRYPT_EAL_HpkeSetSharedSecret(CRYPT_EAL_HpkeCtx * ctx,uint8_t * info,uint32_t infoLen,uint8_t * buff,uint32_t buffLen)1647 int32_t CRYPT_EAL_HpkeSetSharedSecret(CRYPT_EAL_HpkeCtx *ctx, uint8_t *info, uint32_t infoLen,
1648     uint8_t *buff, uint32_t buffLen)
1649 {
1650     if (ctx == NULL) {
1651         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1652         return CRYPT_NULL_INPUT;
1653     }
1654 
1655     if (ctx->sharedSecret != NULL) {
1656         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1657         return CRYPT_HPKE_ERR_CALL;
1658     }
1659 
1660     if (buff == NULL) {
1661         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1662         return CRYPT_NULL_INPUT;
1663     }
1664 
1665     if ((info == NULL && infoLen != 0) || (info != NULL && infoLen == 0)) {
1666         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1667         return CRYPT_INVALID_ARG;
1668     }
1669 
1670     if (buffLen != g_hpkeKemAlgInfo[ctx->kemIndex].sharedKeyLen) {
1671         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
1672         return CRYPT_INVALID_ARG;
1673     }
1674 
1675     if (ctx->mode == CRYPT_HPKE_MODE_PSK || ctx->mode == CRYPT_HPKE_MODE_AUTH_PSK) {
1676         if (ctx->authInfo == NULL || ctx->authInfo->psk == NULL || ctx->authInfo->pskId == NULL) {
1677             BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1678             return CRYPT_HPKE_ERR_CALL;
1679         }
1680     }
1681 
1682     int32_t ret = HpkeKeySchedule(ctx, buff, buffLen, info, infoLen);
1683     if (ret != CRYPT_SUCCESS) {
1684         return ret;
1685     }
1686 
1687     ctx->sharedSecret = BSL_SAL_Dump(buff, buffLen);
1688     if (ctx->sharedSecret == NULL) {
1689         HpkeFreeKeyInfo(ctx);
1690         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1691         return CRYPT_MEM_ALLOC_FAIL;
1692     }
1693     ctx->sharedSecretLen = buffLen;
1694     HpkeFreeAuthInfo(ctx); // Derived key successfully, no longer requires authinfo
1695     return CRYPT_SUCCESS;
1696 }
1697 
CRYPT_EAL_HpkeSetPsk(CRYPT_EAL_HpkeCtx * ctx,uint8_t * psk,uint32_t pskLen,uint8_t * pskId,uint32_t pskIdLen)1698 int32_t CRYPT_EAL_HpkeSetPsk(CRYPT_EAL_HpkeCtx *ctx, uint8_t *psk, uint32_t pskLen, uint8_t *pskId, uint32_t pskIdLen)
1699 {
1700     if (ctx == NULL) {
1701         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1702         return CRYPT_NULL_INPUT;
1703     }
1704 
1705     if (ctx->mode != CRYPT_HPKE_MODE_PSK && ctx->mode != CRYPT_HPKE_MODE_AUTH_PSK) {
1706         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1707         return CRYPT_HPKE_ERR_CALL;
1708     }
1709 
1710     if (ctx->authInfo == NULL) {
1711         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1712         return CRYPT_HPKE_ERR_CALL;
1713     }
1714 
1715     if (ctx->authInfo->psk != NULL || ctx->authInfo->pskId != NULL) {
1716         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1717         return CRYPT_HPKE_ERR_CALL;
1718     }
1719 
1720     // psk and pskId must appear together
1721     if (psk == NULL || pskIdLen == 0 || pskId == NULL || pskLen == 0) {
1722         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1723         return CRYPT_NULL_INPUT;
1724     }
1725 
1726     ctx->authInfo->psk = BSL_SAL_Dump(psk, pskLen);
1727     if (ctx->authInfo->psk == NULL) {
1728         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1729         return CRYPT_MEM_ALLOC_FAIL;
1730     }
1731     ctx->authInfo->pskLen = pskLen;
1732 
1733     ctx->authInfo->pskId = BSL_SAL_Dump(pskId, pskIdLen);
1734     if (ctx->authInfo->pskId == NULL) {
1735         BSL_SAL_ClearFree(ctx->authInfo->psk, ctx->authInfo->pskLen);
1736         ctx->authInfo->psk = NULL;
1737         ctx->authInfo->pskLen = 0;
1738         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
1739         return CRYPT_MEM_ALLOC_FAIL;
1740     }
1741     ctx->authInfo->pskIdLen = pskIdLen;
1742     return CRYPT_SUCCESS;
1743 }
1744 
CRYPT_EAL_HpkeSetAuthPriKey(CRYPT_EAL_HpkeCtx * ctx,CRYPT_EAL_PkeyCtx * pkey)1745 int32_t CRYPT_EAL_HpkeSetAuthPriKey(CRYPT_EAL_HpkeCtx *ctx, CRYPT_EAL_PkeyCtx *pkey)
1746 {
1747     if (ctx == NULL || pkey == NULL) {
1748         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1749         return CRYPT_NULL_INPUT;
1750     }
1751 
1752     if (ctx->mode != CRYPT_HPKE_MODE_AUTH && ctx->mode != CRYPT_HPKE_MODE_AUTH_PSK) {
1753         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1754         return CRYPT_HPKE_ERR_CALL;
1755     }
1756 
1757     if (ctx->role != CRYPT_HPKE_SENDER) {
1758         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1759         return CRYPT_HPKE_ERR_CALL;
1760     }
1761 
1762     if (ctx->authInfo == NULL) {
1763         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1764         return CRYPT_HPKE_ERR_CALL;
1765     }
1766 
1767     if (ctx->authInfo->authPkey != NULL) {
1768         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1769         return CRYPT_HPKE_ERR_CALL;
1770     }
1771 
1772     CRYPT_EAL_PkeyCtx *skS = NULL;
1773 #ifdef HITLS_CRYPTO_PROVIDER
1774     skS = CRYPT_EAL_ProviderPkeyNewCtx(ctx->libCtx, g_hpkeKemAlgInfo[ctx->kemIndex].pkeyId,
1775         CRYPT_EAL_PKEY_EXCH_OPERATE, ctx->attrName);
1776 #else
1777     skS = CRYPT_EAL_PkeyNewCtx(g_hpkeKemAlgInfo[ctx->kemIndex].pkeyId);
1778 #endif
1779     if (skS == NULL) {
1780         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_FAILED_FETCH_PKEY);
1781         return CRYPT_HPKE_FAILED_FETCH_PKEY;
1782     }
1783 
1784     int32_t ret = CRYPT_EAL_PkeyCopyCtx(skS, pkey);
1785     if (ret != CRYPT_SUCCESS) {
1786         CRYPT_EAL_PkeyFreeCtx(skS);
1787         return ret;
1788     }
1789 
1790     ctx->authInfo->authPkey = skS;
1791     return CRYPT_SUCCESS;
1792 }
1793 
CRYPT_EAL_HpkeSetAuthPubKey(CRYPT_EAL_HpkeCtx * ctx,uint8_t * pub,uint32_t pubLen)1794 int32_t CRYPT_EAL_HpkeSetAuthPubKey(CRYPT_EAL_HpkeCtx *ctx, uint8_t *pub, uint32_t pubLen)
1795 {
1796     if (ctx == NULL || pub == NULL || pubLen == 0) {
1797         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1798         return CRYPT_NULL_INPUT;
1799     }
1800 
1801     if (ctx->mode != CRYPT_HPKE_MODE_AUTH && ctx->mode != CRYPT_HPKE_MODE_AUTH_PSK) {
1802         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1803         return CRYPT_HPKE_ERR_CALL;
1804     }
1805 
1806     if (ctx->role != CRYPT_HPKE_RECIPIENT) {
1807         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1808         return CRYPT_HPKE_ERR_CALL;
1809     }
1810 
1811     if (ctx->authInfo == NULL) {
1812         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1813         return CRYPT_HPKE_ERR_CALL;
1814     }
1815 
1816     if (ctx->authInfo->authPkey != NULL) {
1817         BSL_ERR_PUSH_ERROR(CRYPT_HPKE_ERR_CALL);
1818         return CRYPT_HPKE_ERR_CALL;
1819     }
1820 
1821     CRYPT_EAL_PkeyCtx *pkS = NULL;
1822     int32_t ret = HpkeCreatePubKey(ctx->kemIndex, pub, pubLen, &pkS, ctx->libCtx, ctx->attrName);
1823     if (ret != CRYPT_SUCCESS) {
1824         return ret;
1825     }
1826 
1827     ctx->authInfo->authPkey = pkS;
1828     return CRYPT_SUCCESS;
1829 }
1830 #endif // HITLS_CRYPTO_HPKE
1831