• 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 #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