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_CBC_MAC) || defined(HITLS_CRYPTO_CMAC)
18 #include <stdlib.h>
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "crypt_utils.h"
22 #include "crypt_errno.h"
23 #include "bsl_err_internal.h"
24 #include "crypt_local_types.h"
25 #include "cipher_mac_common.h"
26
CipherMacInitCtx(Cipher_MAC_Common_Ctx * ctx,const EAL_SymMethod * method)27 int32_t CipherMacInitCtx(Cipher_MAC_Common_Ctx *ctx, const EAL_SymMethod *method)
28 {
29 if (ctx == NULL || method == NULL) {
30 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
31 return CRYPT_NULL_INPUT;
32 }
33
34 void *key = (void *)BSL_SAL_Calloc(1u, method->ctxSize);
35 if (key == NULL) {
36 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
37 return CRYPT_MEM_ALLOC_FAIL;
38 }
39
40 // set key and set method
41 ctx->key = key;
42 ctx->method = method;
43 return CRYPT_SUCCESS;
44 }
45
CipherMacDeinitCtx(Cipher_MAC_Common_Ctx * ctx)46 void CipherMacDeinitCtx(Cipher_MAC_Common_Ctx *ctx)
47 {
48 if (ctx == NULL || ctx->method == NULL) {
49 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
50 return;
51 }
52 const EAL_SymMethod *method = ctx->method;
53 BSL_SAL_CleanseData((void *)(ctx->key), method->ctxSize);
54 BSL_SAL_FREE(ctx->key);
55 }
56
CipherMacInit(Cipher_MAC_Common_Ctx * ctx,const uint8_t * key,uint32_t len)57 int32_t CipherMacInit(Cipher_MAC_Common_Ctx *ctx, const uint8_t *key, uint32_t len)
58 {
59 if (ctx == NULL || ctx->method == NULL || (key == NULL && len != 0)) {
60 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
61 return CRYPT_NULL_INPUT;
62 }
63 int32_t ret = ctx->method->setEncryptKey(ctx->key, key, len);
64 if (ret != CRYPT_SUCCESS) {
65 BSL_ERR_PUSH_ERROR(ret);
66 return ret;
67 }
68 (void)memset_s(ctx->data, CIPHER_MAC_MAXBLOCKSIZE, 0, CIPHER_MAC_MAXBLOCKSIZE);
69 ctx->len = 0;
70 return CRYPT_SUCCESS;
71 }
72
CipherMacUpdate(Cipher_MAC_Common_Ctx * ctx,const uint8_t * in,uint32_t len)73 int32_t CipherMacUpdate(Cipher_MAC_Common_Ctx *ctx, const uint8_t *in, uint32_t len)
74 {
75 if (ctx == NULL || ctx->method == NULL || (in == NULL && len != 0)) {
76 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
77 return CRYPT_NULL_INPUT;
78 }
79 const EAL_SymMethod *method = ctx->method;
80 int32_t ret;
81 uint32_t blockSize = method->blockSize;
82 const uint8_t *inTmp = in;
83 uint32_t lenTmp = len;
84 if (ctx->len > 0) {
85 if (ctx->len > (UINT32_MAX - lenTmp)) {
86 BSL_ERR_PUSH_ERROR(CRYPT_CMAC_INPUT_OVERFLOW);
87 return CRYPT_CMAC_INPUT_OVERFLOW;
88 }
89 uint32_t end = (ctx->len + lenTmp) > (blockSize) ? (blockSize) : (ctx->len + lenTmp);
90 for (uint32_t i = ctx->len; i < end; i++) {
91 ctx->left[i] = (*inTmp);
92 inTmp++;
93 }
94 lenTmp -= (end - ctx->len);
95 if (lenTmp == 0) {
96 ctx->len = end;
97 return CRYPT_SUCCESS;
98 }
99 DATA_XOR(ctx->left, ctx->data, ctx->left, blockSize);
100 ret = method->encryptBlock(ctx->key, ctx->left, ctx->data, blockSize);
101 if (ret != CRYPT_SUCCESS) {
102 BSL_ERR_PUSH_ERROR(ret);
103 return ret;
104 }
105 }
106 while (lenTmp > blockSize) {
107 DATA_XOR(inTmp, ctx->data, ctx->left, blockSize);
108 ret = method->encryptBlock(ctx->key, ctx->left, ctx->data, blockSize);
109 if (ret != CRYPT_SUCCESS) {
110 BSL_ERR_PUSH_ERROR(ret);
111 return ret;
112 }
113 lenTmp -= blockSize;
114 inTmp += blockSize;
115 }
116 for (uint32_t i = 0; i < lenTmp; i++) {
117 ctx->left[i] = inTmp[i];
118 }
119 ctx->len = lenTmp;
120 return CRYPT_SUCCESS;
121 }
122
CipherMacReinit(Cipher_MAC_Common_Ctx * ctx)123 void CipherMacReinit(Cipher_MAC_Common_Ctx *ctx)
124 {
125 if (ctx == NULL) {
126 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
127 return;
128 }
129
130 (void)memset_s(ctx->data, CIPHER_MAC_MAXBLOCKSIZE, 0, CIPHER_MAC_MAXBLOCKSIZE);
131 ctx->len = 0;
132 }
133
CipherMacDeinit(Cipher_MAC_Common_Ctx * ctx)134 void CipherMacDeinit(Cipher_MAC_Common_Ctx *ctx)
135 {
136 if (ctx == NULL || ctx->method == NULL) {
137 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
138 return;
139 }
140
141 const uint32_t ctxSize = ctx->method->ctxSize;
142 BSL_SAL_CleanseData(ctx->key, ctxSize);
143 (void)memset_s(ctx->data, CIPHER_MAC_MAXBLOCKSIZE, 0, CIPHER_MAC_MAXBLOCKSIZE);
144 (void)memset_s(ctx->left, CIPHER_MAC_MAXBLOCKSIZE, 0, CIPHER_MAC_MAXBLOCKSIZE);
145 ctx->len = 0;
146 }
147
CipherMacGetMacLen(const Cipher_MAC_Common_Ctx * ctx,void * val,uint32_t len)148 int32_t CipherMacGetMacLen(const Cipher_MAC_Common_Ctx *ctx, void *val, uint32_t len)
149 {
150 if (ctx == NULL || ctx->method == NULL || val == NULL || len != sizeof(uint32_t)) {
151 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
152 return CRYPT_NULL_INPUT;
153 }
154 *(uint32_t *)val = ctx->method->blockSize;
155 return CRYPT_SUCCESS;
156 }
157 #endif // #if defined(HITLS_CRYPTO_CBC_MAC) || defined(HITLS_CRYPTO_CMAC)
158