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_AES) && defined(HITLS_CRYPTO_CCM)
18
19 #include "bsl_err_internal.h"
20 #include "crypt_errno.h"
21 #include "asm_aes_ccm.h"
22 #include "ccm_core.h"
23 #include "crypt_modes_ccm.h"
24 #include "modes_local.h"
25
AesCcmBlocks(MODES_CipherCCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,bool enc)26 static int32_t AesCcmBlocks(MODES_CipherCCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
27 {
28 if (ctx->ciphCtx == NULL) {
29 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
30 return CRYPT_NULL_INPUT;
31 }
32 XorCryptData data;
33 data.in = in;
34 data.out = out;
35 data.ctr = ctx->last;
36 data.tag = ctx->tag;
37
38 uint8_t countLen = (ctx->nonce[0] & 0x07) + 1;
39 uint32_t dataLen = len;
40 void (*xor)(XorCryptData *data, uint32_t len) = enc ? XorInEncrypt : XorInDecrypt;
41 void (*crypt_asm)(void *key, uint8_t *nonce, const uint8_t *in, uint8_t *out, uint32_t len) =
42 enc ? AesCcmEncryptAsm : AesCcmDecryptAsm;
43 crypt_asm(ctx->ciphCtx, ctx->nonce, data.in, data.out, dataLen);
44 uint32_t tmpOffset = dataLen & 0xfffffff0;
45 dataLen &= 0x0fU;
46 data.in += tmpOffset;
47 data.out += tmpOffset;
48 if (dataLen > 0) { // data processing with less than 16 bytes
49 (void)ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->nonce, ctx->last, CCM_BLOCKSIZE);
50 xor(&data, dataLen);
51 MODE_IncCounter(ctx->nonce + CCM_BLOCKSIZE - countLen, countLen); // counter +1
52 }
53 return CRYPT_SUCCESS;
54 }
55
MODES_AES_CCM_Encrypt(MODES_CipherCCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)56 int32_t MODES_AES_CCM_Encrypt(MODES_CipherCCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
57 {
58 return CcmCrypt(ctx, in, out, len, true, AesCcmBlocks);
59 }
60
MODES_AES_CCM_Decrypt(MODES_CipherCCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)61 int32_t MODES_AES_CCM_Decrypt(MODES_CipherCCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
62 {
63 return CcmCrypt(ctx, in, out, len, false, AesCcmBlocks);
64 }
65
66
AES_CCM_Update(MODES_CCM_Ctx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)67 int32_t AES_CCM_Update(MODES_CCM_Ctx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
68 {
69 return MODES_CipherStreamProcess(modeCtx->enc ? MODES_AES_CCM_Encrypt : MODES_AES_CCM_Decrypt, &modeCtx->ccmCtx,
70 in, inLen, out, outLen);
71 }
72
73 #endif