当前位置:网站首页>AES encryption learning of openharmony security module
AES encryption learning of openharmony security module
2022-07-18 07:22:00 【Pseudo procedural ape who loves fishing】
OpenHarmony Preliminary analysis
security_huks/frameworks/crypto_lite/cipher/src/cipher_aes
In the last study , We get it OpenHarmony The characteristics of the three modules , Today we will learn the third module —— Security module . We know , Hongmeng general keystore system is mainly to provide the function of keystore to applications , Including key management and cryptographic operations to generate keys .
OpenHarmony The operating system is an open system , Developers can use OpenHarmony Develop flexible services and Applications , Bring convenience and value to developers and users . To that end ,OpenHarmony It provides an execution environment that can effectively protect applications and user data .

The security mechanism consists of HUKS Provide function 
frameworks File is framework code , Under its directory crypto_lite It provides the function of encryption and decryption .
Today we mainly study AES File encryption ,AES-GCM encryption algorithm :AES Is a symmetric encryption algorithm ,GCM Is the symmetric encryption using Counter Pattern , with GMAC Message authentication code .AES-GCM Algorithms are algorithms with authentication and encryption , At the same time, it can be used for the given text , Generate encrypted data and authentication code . Now let's start a brief analysis of the code

Here are two definitions :
Plaintext : Data that is not encrypted
secret key : A password used to encrypt plaintext , In symmetric encryption algorithm , The encryption and decryption keys are the same . The sender and the sender negotiate for the key , But it can't be transmitted directly over the network , Otherwise, the key will be leaked , The key is usually encrypted by an asymmetric encryption algorithm , And then transmit it to the other party through the network , Or negotiate the key face to face . The key must not be disclosed , Otherwise, the ciphertext will be restored by the attacker , Stealing confidential data .
The data is plaintext by PaddingPkcs5 Given characters to fill ,UnpaddingPkcs5 Used to remove the filled characters after filling in plaintext .
MallocDecodeData The code can be divided into two modules , One is the memory filling module , It is mainly about the symbol filling of the document plaintext ; The other is the plaintext decoding module , Decode the filled file
SetIv Is the initialization vector function , because OpenHarmony The encryption mode adopted by the module is cipher block link mode , Block by block encryption modules can be connected , and SetIv As the first 0 Interference term of block Ming character block , Prevent parsing attacks ,
The code modules are as follows :
static int32_t PaddingPkcs5(char *data, size_t inSize)
{
if (inSize % AES_BLOCK_SIZE == 0) {
return strlen((const char *)(uintptr_t)data); // Judge whether the data information is neat
}
int32_t paddingLen = AES_BLOCK_SIZE - inSize % AES_BLOCK_SIZE; //paddingLen It includes the filled data value and length
int32_t needLen = paddingLen + inSize;
for (int32_t i = 0; i < paddingLen; i++) {
// Use the method of filling data circularly
data[inSize + i] = paddingLen;
}
return needLen;
}
static int32_t UnpaddingPkcs5(char *data, size_t dataLen) // Used to remove the padding characters in the decrypted plaintext containing padding characters
{
// Get the length of the fill data
int32_t padLen = data[dataLen - 1];
// When the data is unreasonable , Exit function
if (padLen <= 0 || padLen >= AES_BLOCK_SIZE) {
return ERROR_CODE_GENERAL;
}
// Delete the filling data circularly
for (int32_t i = 0; i < padLen; i++) {
if (data[dataLen - 1 - i] != padLen) {
return ERROR_CODE_GENERAL;
}
data[dataLen - 1 - i] = '\0';
}
return (dataLen - padLen);
}
static char *MallocDecodeData(const char *text, size_t *olen) // Memory filling module
{
size_t decodeLen = 0; // initialization
int32_t ret = mbedtls_base64_decode(NULL, 0, &decodeLen, (const unsigned char *)(text), strlen(text));// encryption text
if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
// Judge BUFFER Value , If the cache space is too small , Not applicable to decoding
return NULL;
}
// Apply for memory space
if ((decodeLen + 1) <= 0) {
return NULL; // Check decodeLen Size , If it's negative , The program cannot continue to run , False report
}
char *decData = (char *)malloc(decodeLen + 1);
if (decData == NULL) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "malloc failed, length:%{public}d.", (int32_t)(decodeLen + 1));
return NULL; // When the data exceeds the memory size , The program cannot continue , False report
}
// Reset operation , Fill the applied address space 0
memset_s(decData, decodeLen + 1, 0, decodeLen + 1); // Yes decData Fill in
// be based on mbedtls Of base64 decode , The first parameter is the requested address space , Store the decoded data into the address space
if (mbedtls_base64_decode((unsigned char *)decData, decodeLen + 1, olen,
(const unsigned char *)text, strlen(text)) != 0) {
// Decoding data failed , Clear memory space , Release resources
free(decData); // Free memory
HILOG_ERROR(HILOG_MODULE_HIVIEW, "decode data failed, text:%s.", text);
return NULL; // If the operation fails, an error is reported
}
return decData;
}
static char *MallocEncodeData(const unsigned char *text, size_t *olen) // Plaintext decoding module
{
size_t dataLen = 0; // initialization
int32_t ret = mbedtls_base64_encode(NULL, 0, &dataLen, text, *olen); // Decrypt text
if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
// Judge BUFFER Value , If the cache space is too small , Not applicable to coding
return NULL;
}
if ((dataLen + 1) <= 0) {
return NULL; // Check decodeLen Size , If it's negative , The program cannot continue to run , False report
}
// Apply for memory space
char *encData = (char *)malloc(dataLen + 1);
if (encData == NULL) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "malloc data failed, expect len:%{public}zu.", dataLen);
return NULL; // When there is no data plaintext in memory , The program cannot continue , False report
}
// Reset operation , Fill the applied address space 0
memset_s(encData, dataLen, 0, dataLen); // Plaintext decoding
// be based on mbedtls Of base64 code , The first parameter is the requested address space
if (mbedtls_base64_encode((unsigned char *)(encData), dataLen, olen, text, *olen) != 0) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "encode data failed."); // Program error , Decoding failed
free(encData); // Free memory
return NULL;
}
return encData;
}
static int32_t SetIv(const char *ivBuf, int32_t ivBufLen, AesCryptContext *ctx) // Initialize vector function
{
if ((ivBuf == NULL) || (ctx == NULL)) {
return ERROR_CODE_GENERAL; //ivBuf and ctx Can't be empty
}
if ((ivBufLen < (ctx->iv.ivOffset + ctx->iv.ivLen)) || (ctx->iv.ivOffset < 0) || (ctx->iv.ivLen <= 0)) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "ivLen or ivOffset err."); // Judge whether the length of the encrypted block meets the encryption conditions
return ERROR_CODE_GENERAL;
}
// Apply for memory space
ctx->iv.ivBuf = malloc(ctx->iv.ivLen);
if (ctx->iv.ivBuf == NULL) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "malloc failed.");
return ERROR_CODE_GENERAL;
}
// Reset operation , Fill the applied address space 0
(void)memset_s(ctx->iv.ivBuf, ctx->iv.ivLen, 0, ctx->iv.ivLen);
// Then copy the data in the buffer to the requested memory
int32_t ret = memcpy_s(ctx->iv.ivBuf, ctx->iv.ivLen, ivBuf + ctx->iv.ivOffset, ctx->iv.ivLen);
if (ret) {
// Judge whether the copy is successful , If unsuccessful, release resources
HILOG_ERROR(HILOG_MODULE_HIVIEW, "memcpy failed, ret:%{public}d.", ret);
free(ctx->iv.ivBuf);
ctx->iv.ivBuf = NULL;
return ERROR_CODE_GENERAL;
}
return ERROR_SUCCESS;
}
static int32_t InitAesCryptContext(const char *key, const AesIvMode *iv, AesCryptContext *ctx)
{
int32_t ret;
// Judge the legitimacy of the incoming parameters
if (iv == NULL || ctx == NULL || key == NULL) {
return ERROR_CODE_GENERAL;
}
if ((iv->transformation != NULL) && (strcmp(iv->transformation, "AES/CBC/PKCS5Padding"))) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "transformation err.");
return ERROR_CODE_GENERAL;
}
// use AES、CBC Encryption mode
ctx->mode = CIPHER_AES_CBC;
ctx->iv.ivOffset = iv->ivOffset; // initialization ctx In the offset
if ((iv->ivLen >= 0) && (iv->ivLen != AES_BLOCK_SIZE)) {
// If the vector length is greater than the block size , Exit function
HILOG_ERROR(HILOG_MODULE_HIVIEW, "ivLen:%{public}d error, need be %{public}d Bytes.",
iv->ivLen, AES_BLOCK_SIZE);
return ERROR_CODE_GENERAL;
}
ctx->iv.ivLen = AES_BLOCK_SIZE; // Assign the block size to the vector length
if (iv->ivBuf != NULL) {
size_t ivBufLen = strlen((const char *)(uintptr_t)iv->ivBuf); // Get the decoded data
char* ivBuf = MallocDecodeData(iv->ivBuf, &ivBufLen);
if (ivBuf == NULL) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "base64 decode failed.");
return ERROR_CODE_GENERAL;
}
// Store the decoded data into the context
ret = SetIv((const char *)ivBuf, strlen((const char *)(uintptr_t)ivBuf), ctx);
if (ret == ERROR_CODE_GENERAL) {
free(ivBuf);
HILOG_ERROR(HILOG_MODULE_HIVIEW, "SetIv failed.");
return ERROR_CODE_GENERAL;
}
free(ivBuf);
} else {
// Store the key in the context
ret = SetIv(ctx->data.key, strlen((const char *)(uintptr_t)ctx->data.key), ctx);
if (ret == ERROR_CODE_GENERAL) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "SetIv failed.");
return ERROR_CODE_GENERAL;
}
}
return ERROR_SUCCESS;
}
static int32_t InitAesData(const char *action, const char *key, const char *text, CryptData *data)
{
if (action == NULL || text == 0 || data == NULL || key == NULL) {
// Judge the legitimacy of the passed in related parameters
return ERROR_CODE_GENERAL;
}
if (!strcmp(action, "encrypt")) {
data->action = MBEDTLS_AES_ENCRYPT; // Set the current encryption
if (strlen(text) % AES_BLOCK_SIZE) {
// Set the length of the data
data->textLen = (strlen(text) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE + AES_BLOCK_SIZE;
} else {
data->textLen = strlen(text);
}
if ((data->textLen + 1) <= 0) {
return ERROR_CODE_GENERAL;
}
data->text = malloc(data->textLen + 1); // Request memory space for text content
if (data->text == NULL) {
return ERROR_CODE_GENERAL;
}
// Clear the memory space
(void)memset_s(data->text, data->textLen + 1, 0, data->textLen + 1);
if (memcpy_s(data->text, data->textLen + 1, text, strlen(text))) {
// Copy the text content to the address space just applied
goto ERROR;
}
data->textLen = PaddingPkcs5(data->text, strlen(text));
} else if (!strcmp(action, "decrypt")) {
data->action = MBEDTLS_AES_DECRYPT; // Set current as decryption
data->text = MallocDecodeData(text, (size_t *)&data->textLen); // Request memory space for text content
if (data->text == NULL) {
return ERROR_CODE_GENERAL;
}
data->textLen -= data->textLen % AES_BLOCK_SIZE;
} else {
return ERROR_CODE_GENERAL;
}
data->key = MallocDecodeData(key, (size_t *)&data->keyLen); // Request memory space for the key
if (data->key == NULL) {
goto ERROR;
}
if (data->keyLen != KEY_LEN) {
// Verify the validity of the key
HILOG_ERROR(HILOG_MODULE_HIVIEW, "key length:%{public}d error, need be %{public}d Bytes.",
data->keyLen, KEY_LEN);
memset_s(data->key, data->keyLen, 0, data->keyLen); // If illegal , Memory space is cleared , Release resources
free(data->key);
data->key = NULL;
goto ERROR;
}
return ERROR_SUCCESS;
ERROR:
free(data->text);
data->text = NULL;
return ERROR_CODE_GENERAL;
}
void DeinitAesCryptData(AesCryptContext *ctx)
{
if (ctx == NULL) {
// Judge the validity of parameters
return;
}
if (ctx->iv.ivBuf != NULL) {
// Empty the initial vector buffer
free(ctx->iv.ivBuf);
ctx->iv.ivBuf = NULL;
}
if (ctx->data.key != NULL) {
// Set the key address space to zero and release , Key emptying in context
memset_s(ctx->data.key, ctx->data.keyLen, 0, ctx->data.keyLen);
free(ctx->data.key);
ctx->data.key = NULL;
}
if (ctx->data.text != NULL) {
// Free text content address space , The text in the context is empty
free(ctx->data.text);
ctx->data.text = NULL;
}
}
static int32_t DoAesCbcEncrypt(mbedtls_aes_context *aesCtx, AesCryptContext *ctx)
{
int32_t ret;
if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
// Set the corresponding key
ret = mbedtls_aes_setkey_enc(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
} else {
ret = mbedtls_aes_setkey_dec(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
}
if (ret != 0) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "aes setkey error.");
return ERROR_CODE_GENERAL;
}
// Encrypt or decrypt data
ret = mbedtls_aes_crypt_cbc(aesCtx, ctx->data.action, ctx->data.textLen,
(unsigned char *)ctx->iv.ivBuf, (const unsigned char *)ctx->data.text, (unsigned char *)ctx->data.text);
if (ret != 0) {
// Judge whether the encryption or decryption is successful
HILOG_ERROR(HILOG_MODULE_HIVIEW, "aes crypt cbc error, ret:%{public}d.", ret);
return ERROR_CODE_GENERAL;
}
if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
// Judge if it is currently encrypted
// Apply for address space for encrypted data
char *out = MallocEncodeData((const unsigned char *)ctx->data.text, (size_t *)&ctx->data.textLen);
free(ctx->data.text); // Free plaintext memory space
ctx->data.text = out; // The text data in the context is set as ciphertext
if (out == NULL) {
return ERROR_CODE_GENERAL;
}
} else {
ctx->data.textLen = UnpaddingPkcs5(ctx->data.text, ctx->data.textLen); // If the current state is decryption , Then remove the filling bit
if (ctx->data.textLen < 0) {
return ERROR_CODE_GENERAL;
}
}
return ERROR_SUCCESS;
}
int32_t InitAesCryptData(const char *action, const char *text, const char *key, const AesIvMode *iv,
AesCryptContext *aesCryptCxt)
{
if (action == NULL || text == NULL || key == NULL || iv == NULL || aesCryptCxt == NULL) {
// Judge the legitimacy of the incoming parameters
return ERROR_CODE_GENERAL;
}
int32_t ret = InitAesData(action, key, text, &(aesCryptCxt->data)); // initialization AES Data needed , And initialization fails , Release Aes related data
if (ret != 0) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "fill aes crypt data failed.");
DeinitAesCryptData(aesCryptCxt);
return ERROR_CODE_GENERAL;
}
ret = InitAesCryptContext(key, iv, aesCryptCxt); // initialization Aes The context of encryption and decryption
if (ret != 0) {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "fill aes crypt context failed.");
return ERROR_CODE_GENERAL;
}
return ERROR_SUCCESS;
}
int32_t AesCrypt(AesCryptContext* aesCryptCxt)
{
if (aesCryptCxt == NULL) {
return ERROR_CODE_GENERAL;
}
if (aesCryptCxt->mode == CIPHER_AES_CBC) {
// Judge whether it is CBC Pattern
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
int32_t ret = DoAesCbcEncrypt(&aes, aesCryptCxt); // Encryption and decryption
if (ret != ERROR_SUCCESS) {
// Judge whether the encryption and decryption is successful , Release resources when unsuccessful
HILOG_ERROR(HILOG_MODULE_HIVIEW, "Aes cbc encrypt failed.");
mbedtls_aes_free(&aes);
return ERROR_CODE_GENERAL;
}
mbedtls_aes_free(&aes);
return ERROR_SUCCESS;
} else {
HILOG_ERROR(HILOG_MODULE_HIVIEW, "crypt mode not support.");
return ERROR_CODE_GENERAL;
}
}
边栏推荐
- OpenHarmony模块二下文件samgr_server解析(1)
- MySQL MySQL Foundation
- 布尔代数值
- 【森城市】GIS数据漫谈(四)— 坐标系统
- How to migrate the complex SQL statements used by applications developed for Oracle to polardb for POS
- 前六章补充案例和知识点(一)
- 根据verilog代码画电路图
- In mysql, the decimal (10,2) format is written to Kafka through stream and becomes stri
- Typora changes text color and line breaks
- 【使用Win10自带远程连接工具】远程访问并控制【另一台Win10电脑】
猜你喜欢

美团一面面经及详细答案

根据verilog代码画电路图

Business development stagnates, decision-making is not supported by information, and data analysis is the solution

前六章补充案例和知识点(一)

OpenHarmony安全模块之AES加密学习

(开源项目)abattoir unity游戏

【示波器的基本使用】以及【示波器按键面板上各个按键含义的介绍】

带图像识别的YYS连点器 V2.0

A-F Codeforces Round #806 (Div.4) A-F题解及代码

The most important diagram of machine learning, how to select the model sklearn structure diagram
随机推荐
Fosai biology interprets the changes in the atmospheric environment in the first half of 2022, and VOCs control is still the key to breaking the situation
非法获利超百万,行业新风口正被破解侵蚀
C language: [bit field operation] (colon is used in the structure)
MySQL trigger
时间复杂度和空间复杂度详解
OpenHarmony模块二初分析
C语言学习第一周——C语言的历史
如何通过psql导入TPC-H数据?
The regular expression retains [content within the matching range], and then replaces [content outside the matching range]
OpenHarmony安全模块之AES加密学习
How to import TPC-H data through PSQL?
使用JDBC操作数据库时出现了SSL和time zone错误的解决办法
MODBUS-RS485布线的8条准则
The function of ifndef /define/endif in the header file
Illegal profits exceed one million, and new outlets in the industry are being cracked and eroded
OpenHarmony模块二下文件samgr_server解析(3)
If you don't want to step on those holes in SaaS, you must first understand the "SaaS architecture"
MySQL pymysql module
makefile变量赋值
mysql中 decimal(10,2)格式的通过stream 方式写到 kafka 变成 stri