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 #ifdef HITLS_CRYPTO_CBC_MAC
18 #include <stdint.h>
19 #include "bsl_sal.h"
20 #include "crypt_types.h"
21 #include "crypt_utils.h"
22 #include "bsl_err_internal.h"
23 #include "cipher_mac_common.h"
24 #include "crypt_errno.h"
25 #include "crypt_cbc_mac.h"
26 #include "eal_mac_local.h"
27
CRYPT_CBC_MAC_NewCtx(CRYPT_MAC_AlgId id)28 CRYPT_CBC_MAC_Ctx *CRYPT_CBC_MAC_NewCtx(CRYPT_MAC_AlgId id)
29 {
30 int32_t ret;
31 EAL_MacMethLookup method = {0};
32 ret = EAL_MacFindMethod(id, &method);
33 if (ret != CRYPT_SUCCESS) {
34 return NULL;
35 }
36 CRYPT_CBC_MAC_Ctx *ctx = BSL_SAL_Calloc(1, sizeof(CRYPT_CBC_MAC_Ctx));
37 if (ctx == NULL) {
38 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
39 return NULL;
40 }
41 ret = CipherMacInitCtx(&ctx->common, method.ciph);
42 if (ret != CRYPT_SUCCESS) {
43 BSL_SAL_Free(ctx);
44 return NULL;
45 }
46 ctx->paddingType = CRYPT_PADDING_MAX_COUNT;
47 return ctx;
48 }
49
CRYPT_CBC_MAC_Init(CRYPT_CBC_MAC_Ctx * ctx,const uint8_t * key,uint32_t len,void * param)50 int32_t CRYPT_CBC_MAC_Init(CRYPT_CBC_MAC_Ctx *ctx, const uint8_t *key, uint32_t len, void *param)
51 {
52 (void)param;
53 if (ctx == NULL) {
54 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
55 return CRYPT_NULL_INPUT;
56 }
57 return CipherMacInit(&ctx->common, key, len);
58 }
59
CRYPT_CBC_MAC_Update(CRYPT_CBC_MAC_Ctx * ctx,const uint8_t * in,uint32_t len)60 int32_t CRYPT_CBC_MAC_Update(CRYPT_CBC_MAC_Ctx *ctx, const uint8_t *in, uint32_t len)
61 {
62 if (ctx == NULL) {
63 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
64 return CRYPT_NULL_INPUT;
65 }
66 if (ctx->paddingType == CRYPT_PADDING_MAX_COUNT) {
67 BSL_ERR_PUSH_ERROR(CRYPT_CBC_MAC_PADDING_NOT_SET);
68 return CRYPT_CBC_MAC_PADDING_NOT_SET;
69 }
70 return CipherMacUpdate(&ctx->common, in, len);
71 }
72
CbcMacPadding(CRYPT_CBC_MAC_Ctx * ctx)73 static int32_t CbcMacPadding(CRYPT_CBC_MAC_Ctx *ctx)
74 {
75 const EAL_SymMethod *method = ctx->common.method;
76 uint32_t length = ctx->common.len;
77 uint32_t padLen = method->blockSize - length;
78 switch (ctx->paddingType) {
79 case CRYPT_PADDING_ZEROS:
80 for (uint32_t i = 0; i < padLen; i++) {
81 ctx->common.left[length++] = 0;
82 }
83 ctx->common.len = length;
84 return CRYPT_SUCCESS;
85 default:
86 BSL_ERR_PUSH_ERROR(CRYPT_CBC_MAC_PADDING_NOT_SUPPORT);
87 return CRYPT_CBC_MAC_PADDING_NOT_SUPPORT;
88 }
89 }
90
CRYPT_CBC_MAC_Final(CRYPT_CBC_MAC_Ctx * ctx,uint8_t * out,uint32_t * len)91 int32_t CRYPT_CBC_MAC_Final(CRYPT_CBC_MAC_Ctx *ctx, uint8_t *out, uint32_t *len)
92 {
93 if (ctx == NULL || ctx->common.method == NULL || len == NULL || out == NULL) {
94 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
95 return CRYPT_NULL_INPUT;
96 }
97 const EAL_SymMethod *method = ctx->common.method;
98 uint32_t blockSize = method->blockSize;
99 if (*len < blockSize) {
100 BSL_ERR_PUSH_ERROR(CRYPT_CBC_MAC_OUT_BUFF_LEN_NOT_ENOUGH);
101 return CRYPT_CBC_MAC_OUT_BUFF_LEN_NOT_ENOUGH;
102 }
103
104 int32_t ret = CbcMacPadding(ctx);
105 if (ret != CRYPT_SUCCESS) {
106 return ret;
107 }
108 DATA_XOR(ctx->common.left, ctx->common.data, ctx->common.left, blockSize);
109 ret = method->encryptBlock(ctx->common.key, ctx->common.left, out, blockSize);
110 if (ret != CRYPT_SUCCESS) {
111 BSL_ERR_PUSH_ERROR(ret);
112 return ret;
113 }
114 *len = blockSize;
115 return CRYPT_SUCCESS;
116 }
117
CRYPT_CBC_MAC_Reinit(CRYPT_CBC_MAC_Ctx * ctx)118 void CRYPT_CBC_MAC_Reinit(CRYPT_CBC_MAC_Ctx *ctx)
119 {
120 if (ctx == NULL) {
121 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
122 return;
123 }
124 CipherMacReinit(&ctx->common);
125 }
126
CRYPT_CBC_MAC_Deinit(CRYPT_CBC_MAC_Ctx * ctx)127 void CRYPT_CBC_MAC_Deinit(CRYPT_CBC_MAC_Ctx *ctx)
128 {
129 if (ctx == NULL) {
130 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
131 return;
132 }
133 CipherMacDeinit(&ctx->common);
134 }
135
CRYPT_CBC_MAC_Ctrl(CRYPT_CBC_MAC_Ctx * ctx,uint32_t opt,void * val,uint32_t len)136 int32_t CRYPT_CBC_MAC_Ctrl(CRYPT_CBC_MAC_Ctx *ctx, uint32_t opt, void *val, uint32_t len)
137 {
138 if (ctx == NULL || val == NULL) {
139 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
140 return CRYPT_NULL_INPUT;
141 }
142 switch (opt) {
143 case CRYPT_CTRL_SET_CBC_MAC_PADDING:
144 if (len != sizeof(CRYPT_PaddingType)) {
145 BSL_ERR_PUSH_ERROR(CRYPT_CBC_MAC_ERR_CTRL_LEN);
146 return CRYPT_CBC_MAC_ERR_CTRL_LEN;
147 }
148 ctx->paddingType = *(CRYPT_PaddingType*)val;
149 return CRYPT_SUCCESS;
150 case CRYPT_CTRL_GET_MACLEN:
151 return CipherMacGetMacLen(&ctx->common, val, len);
152 default:
153 BSL_ERR_PUSH_ERROR(CRYPT_CBC_MAC_ERR_UNSUPPORTED_CTRL_OPTION);
154 return CRYPT_CBC_MAC_ERR_UNSUPPORTED_CTRL_OPTION;
155 }
156 }
157
CRYPT_CBC_MAC_FreeCtx(CRYPT_CBC_MAC_Ctx * ctx)158 void CRYPT_CBC_MAC_FreeCtx(CRYPT_CBC_MAC_Ctx *ctx)
159 {
160 if (ctx == NULL) {
161 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
162 return;
163 }
164 CipherMacDeinitCtx(&ctx->common);
165 BSL_SAL_Free(ctx);
166 }
167 #endif
168