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