• 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 #if defined(HITLS_CRYPTO_ENTROPY) && defined(HITLS_CRYPTO_ENTROPY_SYS)
18 
19 #include <stdint.h>
20 #include "securec.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "crypt_local_types.h"
24 #include "crypt_errno.h"
25 #include "es_cf.h"
26 
27 /*
28  * see FIPS 140-3 section Full Entropy
29  * To receive full entropy from the output of a conditioning component, the following criteria must be met:
30  *   The conditioning component shall be vetted,
31  *   ℎin shall be greater than or equal to ����out + 64 bits,
32  *   ����out shall be less than or equal to the security strength of the cryptographic function used as the
33  *    conditioning component.
34  */
35 #define CF_FE_EXLEN 64
36 #define CF_BYTE_TO_BIT 8
37 
38 typedef struct {
39     void *ctx; // Hash algorithm handle
40     EAL_MdMethod meth; // Hash algorithm operation function
41 } ES_CfDfCtx;
42 
ES_CfDfDeinit(void * ctx)43 static void ES_CfDfDeinit(void *ctx)
44 {
45     ES_CfDfCtx *cfCtx = (ES_CfDfCtx *)ctx;
46     if (cfCtx == NULL) {
47         return;
48     }
49     if (cfCtx->ctx != NULL) {
50         cfCtx->meth.freeCtx(cfCtx->ctx);
51     }
52     BSL_SAL_Free(cfCtx);
53     return;
54 }
55 
ES_CfDfInit(void * mdMeth)56 static void *ES_CfDfInit(void *mdMeth)
57 {
58     ES_CfDfCtx *ctx = BSL_SAL_Malloc(sizeof(ES_CfDfCtx));
59     EAL_MdMethod *meth = (EAL_MdMethod *)mdMeth;
60     if (ctx == NULL) {
61         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
62         return NULL;
63     }
64     (void)memcpy_s(&ctx->meth, sizeof(EAL_MdMethod), meth, sizeof(EAL_MdMethod));
65     ctx->ctx = meth->newCtx();
66     if (ctx->ctx == NULL) {
67         BSL_SAL_Free(ctx);
68         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
69         return NULL;
70     }
71     int32_t ret = meth->init(ctx->ctx, NULL);
72     if (ret != CRYPT_SUCCESS) {
73         ES_CfDfDeinit(ctx);
74         BSL_ERR_PUSH_ERROR(ret);
75         return NULL;
76     }
77     return ctx;
78 }
79 
DfI32ToByte(uint8_t values[4],uint32_t len)80 static void DfI32ToByte(uint8_t values[4], uint32_t len)
81 {
82     values[0] = (uint8_t)(((len << 3) >> 24) & 0xff); /* leftward by 3, rightwards by 24 */
83     values[1] = (uint8_t)(((len << 3) >> 16) & 0xff); /* leftward by 3, rightwards by 16 */
84     values[2] = (uint8_t)(((len << 3) >> 8) & 0xff); /* leftward by 3, rightwards by 8 */
85     values[3] = (uint8_t)((len << 3) & 0xff); /* leftward by 3 */
86     return;
87 }
88 
ES_CfDfUpdateData(void * ctx,uint8_t * data,uint32_t dataLen)89 static int32_t ES_CfDfUpdateData(void *ctx, uint8_t *data, uint32_t dataLen)
90 {
91     ES_CfDfCtx *cfCtx = (ES_CfDfCtx *)ctx;
92     uint8_t tmp[1] = { 0x01};
93     int32_t ret = cfCtx->meth.update(cfCtx->ctx, tmp, 1);
94     if (ret != CRYPT_SUCCESS) {
95         BSL_ERR_PUSH_ERROR(ret);
96         return ret;
97     }
98     uint8_t values[4] = {0}; // 4 is sizeof(uint32_t)
99     DfI32ToByte(values, cfCtx->meth.mdSize);
100     ret = cfCtx->meth.update(cfCtx->ctx, values, sizeof(values));
101     if (ret != CRYPT_SUCCESS) {
102         BSL_ERR_PUSH_ERROR(ret);
103         return ret;
104     }
105     ret = cfCtx->meth.update(cfCtx->ctx, data, dataLen);
106     if (ret != CRYPT_SUCCESS) {
107         BSL_ERR_PUSH_ERROR(ret);
108     }
109     return ret;
110 }
111 
ES_CfDfGetEntropyData(void * cfCtx,uint32_t * len)112 static uint8_t *ES_CfDfGetEntropyData(void *cfCtx, uint32_t *len)
113 {
114     ES_CfDfCtx *ctx = (ES_CfDfCtx *)cfCtx;
115     uint32_t bufLen = ctx->meth.mdSize;
116     uint8_t *buf = BSL_SAL_Malloc(bufLen);
117     if (buf == NULL) {
118         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
119         return NULL;
120     }
121     int32_t ret = ctx->meth.final(ctx->ctx, buf, &bufLen);
122     if (ret != CRYPT_SUCCESS) {
123         BSL_SAL_Free(buf);
124         BSL_ERR_PUSH_ERROR(ret);
125         return NULL;
126     }
127     ctx->meth.deinit(ctx->ctx);
128     ret = ctx->meth.init(ctx->ctx, NULL);
129     if (ret != CRYPT_SUCCESS) {
130         BSL_SAL_Free(buf);
131         BSL_ERR_PUSH_ERROR(ret);
132         return NULL;
133     }
134     *len = bufLen;
135     return buf;
136 }
137 
ES_CfDfGetCfOutLen(void * cfCtx)138 static uint32_t ES_CfDfGetCfOutLen(void *cfCtx)
139 {
140     ES_CfDfCtx *ctx = (ES_CfDfCtx *)cfCtx;
141     return ctx->meth.mdSize;
142 }
143 
ES_CfDfGetNeedEntropy(void * cfCtx)144 static uint32_t ES_CfDfGetNeedEntropy(void *cfCtx)
145 {
146     ES_CfDfCtx *ctx = (ES_CfDfCtx *)cfCtx;
147     return ctx->meth.mdSize * CF_BYTE_TO_BIT + CF_FE_EXLEN;
148 }
149 
ES_CFGetDfMethod(EAL_MdMethod * mdMeth)150 ES_CfMethod *ES_CFGetDfMethod(EAL_MdMethod *mdMeth)
151 {
152     ES_CfMethod *meth = BSL_SAL_Malloc(sizeof(ES_CfMethod));
153     if (meth == NULL) {
154         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
155         return NULL;
156     }
157     meth->ctx = NULL;
158     meth->meth.mdMeth = *mdMeth;
159     meth->init = ES_CfDfInit;
160     meth->update = ES_CfDfUpdateData;
161     meth->deinit = ES_CfDfDeinit;
162     meth->getCfOutLen = ES_CfDfGetCfOutLen;
163     meth->getEntropyData = ES_CfDfGetEntropyData;
164     meth->getNeedEntropy = ES_CfDfGetNeedEntropy;
165     return meth;
166 }
167 #endif