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