diff --git a/CMakeLists.txt b/CMakeLists.txt index f9decc6..fe3e0c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,15 +8,31 @@ ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -I. -DUCI_PREFIX="${CMAKE_INST OPTION(UCI_DEBUG "debugging support" OFF) OPTION(UCI_DEBUG_TYPECAST "typecast debugging support" OFF) OPTION(BUILD_LUA "build Lua binding" ON) +#OPTION(TP_FEATURE_GDPR "GDPR support" ON) +OPTION(DEBUG "debug support" OFF) CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/uci_config.h.in ${CMAKE_SOURCE_DIR}/uci_config.h ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) -SET(LIB_SOURCES libuci.c file.c util.c delta.c parse.c blob.c) +#IF(TP_FEATURE_GDPR) +# message("add TP_FEATURE_GDPR") +# add_definitions("-DTP_FEATURE_GDPR") +#ELSE() +# message("GDPR not support") +#ENDIF(TP_FEATURE_GDPR) + +IF(DEBUG) + message("add DEBUG") + add_definitions("-DDEBUG") +ELSE() + message(" DEBUG not support") +ENDIF(DEBUG) + +SET(LIB_SOURCES libuci.c file.c util.c delta.c parse.c blob.c gdpr_aes_interface.c base64.c) ADD_LIBRARY(uci SHARED ${LIB_SOURCES}) -TARGET_LINK_LIBRARIES(uci ubox) +TARGET_LINK_LIBRARIES(uci ubox crypto) SET_TARGET_PROPERTIES(uci PROPERTIES OUTPUT_NAME uci) ADD_EXECUTABLE(cli cli.c) diff --git a/base64.c b/base64.c new file mode 100644 index 0000000..16cda8e --- /dev/null +++ b/base64.c @@ -0,0 +1,168 @@ +/* + * This file is part of libESMTP, a library for submission of RFC 2822 + * formatted electronic mail messages using the SMTP protocol described + * in RFC 2821. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/*#ifdef HAVE_CONFIG_H +#include +#endif*/ + +#include + +/* Routines to encode and decode base64 text. + */ +#include +#include +#include "base64.h" + +/* RFC 2045 section 6.8 */ + +static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + +static const char index_64[128] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + }; + +/* Decode srclen bytes of base64 data contained in src and put the result + in dst. Since the destination buffer may contain arbitrary binary + data and it is not necessarily a string, there is no \0 byte at the + end of the decoded data. */ +int +b64_decode (void *dst, int dstlen, const char *src, int srclen) +{ + const unsigned char *p, *q; + unsigned char *t; + int c1, c2; + + assert (dst != NULL && dstlen > 0); + + if (src == NULL) + return 0; + + if (srclen < 0) + srclen = strlen (src); + + /* Remove leading and trailing white space */ + for (p = (const unsigned char *) src; + srclen > 0 && isspace (*p); + p++, srclen--) + ; + for (q = p + srclen - 1; q >= p && isspace (*q); q--, srclen--) + ; + + /* Length MUST be a multiple of 4 */ + if (srclen % 4 != 0) + return -1; + + /* Destination buffer length must be sufficient */ + if (srclen / 4 * 3 + 1 > dstlen) + return -1; + + t = dst; + while (srclen > 0) + { + srclen -= 4; + if (*p >= 128 || (c1 = index_64[*p++]) == -1) + return -1; + if (*p >= 128 || (c2 = index_64[*p++]) == -1) + return -1; + *t++ = (c1 << 2) | ((c2 & 0x30) >> 4); + + if (p[0] == '=' && p[1] == '=') + break; + if (*p >= 128 || (c1 = index_64[*p++]) == -1) + return -1; + *t++ = ((c2 & 0x0f) << 4) | ((c1 & 0x3c) >> 2); + + if (p[0] == '=') + break; + if (*p >= 128 || (c2 = index_64[*p++]) == -1) + return -1; + *t++ = ((c1 & 0x03) << 6) | c2; + } + + return t - (unsigned char *) dst; +} + +/* Return a pointer to a base 64 encoded string. The input data is + arbitrary binary data, the output is a \0 terminated string. + src and dst may not share the same buffer. */ +int +b64_encode (unsigned char *dst, int dstlen, const void *src, int srclen) +{ + char *to = (char *)dst; + const unsigned char *from; + unsigned char c1, c2; + int dst_needed; + + assert (dst != NULL && dstlen > 0 && srclen >= 0); + + if (src == NULL) + return 0; + + dst_needed = (srclen + 2) / 3; + dst_needed *= 4; + if (dstlen < dst_needed + 1) + return -1; + + from = src; + while (srclen > 0) + { + c1 = *from++; srclen--; + *to++ = base64[c1 >> 2]; + c1 = (c1 & 0x03) << 4; + if (srclen <= 0) + { + *to++ = base64[c1]; + *to++ = '='; + *to++ = '='; + break; + } + c2 = *from++; srclen--; + c1 |= (c2 >> 4) & 0x0f; + *to++ = base64[c1]; + c1 = (c2 & 0x0f) << 2; + if (srclen <= 0) + { + *to++ = base64[c1]; + *to++ = '='; + break; + } + c2 = *from++; srclen--; + c1 |= (c2 >> 6) & 0x03; + *to++ = base64[c1]; + *to++ = base64[c2 & 0x3f]; + } + *to = '\0'; + return to - (char *)dst; +} + + diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..f9223bb --- /dev/null +++ b/base64.h @@ -0,0 +1,29 @@ +#ifndef _base64_h +#define _base64_h +/* + * This file is part of libESMTP, a library for submission of RFC 2822 + * formatted electronic mail messages using the SMTP protocol described + * in RFC 2821. + * + * Copyright (C) 2001,2002 Brian Stafford + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +int b64_decode (void *dst, int dstlen, const char *src, int srclen); +int b64_encode (unsigned char *dst, int dstlen, const void *src, int srclen); + +#endif + diff --git a/file.c b/file.c index 36bfdda..c623d8d 100644 --- a/file.c +++ b/file.c @@ -31,6 +31,7 @@ #include "uci.h" #include "uci_internal.h" +#include "gdpr_aes_interface.h" #define LINEBUF 32 #define LINEBUF_MAX 4096 @@ -445,7 +446,21 @@ static void uci_parse_option(struct uci_context *ctx, char **str, bool list) if (e) ptr.o = uci_to_option(e); ptr.option = name; - ptr.value = value; + +#ifdef TP_FEATURE_GDPR + char decrypt_data_buf[LINEBUF_MAX]; + int decrypt_data_buf_len = LINEBUF_MAX; + int ret = 0; + ret = uci_decrypt(decrypt_data_buf, decrypt_data_buf_len,value, strlen(value)); + if( ret != 0) + { + UCI_THROW(ctx, UCI_ERR_DECRYPT); + } + ptr.value = decrypt_data_buf; +#else + ptr.value = value; +#endif + ctx->internal = !pctx->merge; if (list) @@ -577,7 +592,20 @@ static void uci_export_package(struct uci_package *p, FILE *stream, bool header) switch(opt->type) { case UCI_TYPE_STRING: fprintf(stream, "\toption %s", uci_escape(ctx, opt->e.name)); + +#ifdef TP_FEATURE_GDPR + char encry_data_buf[LINEBUF_MAX]; + int ret = 0; + ret = uci_encrypt( opt->v.string, strlen( opt->v.string), encry_data_buf, LINEBUF_MAX); + if( ret != 0 ) + { + UCI_THROW(ctx, UCI_ERR_DECRYPT); + } + fprintf(stream, " '%s'\n", uci_escape(ctx, encry_data_buf)); +#else fprintf(stream, " '%s'\n", uci_escape(ctx, opt->v.string)); +#endif + break; case UCI_TYPE_LIST: uci_foreach_element(&opt->v.list, i) { diff --git a/gdpr_aes_interface.c b/gdpr_aes_interface.c new file mode 100755 index 0000000..a470c38 --- /dev/null +++ b/gdpr_aes_interface.c @@ -0,0 +1,972 @@ +/* Copyright(c) 2009-2018 Shenzhen TP-LINK Technologies Co.Ltd. + * + * file gdpr_aes_interface.c + * brief AES handle + * details lcrypto + * + * author Li Qiang + * version 1.0.0 + * date 26Apr18 + * + * warning + * + * history \arg 1.0.0, 25May18, Li Qiang, Create the file. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gdpr_aes_interface.h" +#include "base64.h" +#include "gdpr_log.h" + +/**************************************************************************************************/ +/* DEFINES */ +/**************************************************************************************************/ +#define HTTP_ERROR -1 +#define HTTP_OK 0 + +#define MAX_BUF_SIZE 600 +#define MARK_LEN 1 + +/**************************************************************************************************/ +/* TYPES */ +/**************************************************************************************************/ + +/**************************************************************************************************/ +/* VARIABLES */ +/**************************************************************************************************/ +static unsigned char *l_pKey = NULL; +static unsigned char *l_pV = NULL; + +unsigned char *l_key = (unsigned char *)"1527156067762978"; +unsigned char *l_v = (unsigned char *)"1527156067762421"; + +unsigned char gmark[MARK_LEN+1] = {0x03,0x0}; + +/**************************************************************************************************/ +/* FUNCTIONS */ +/**************************************************************************************************/ +/* +**Function: unsigned char *real_padding_buf(unsigned char *buf,int size, int *final_size) +**Des: padding buf +**param[in] buf - enough buffer padding the buffer +**param[in] size +**param[in] final_size +** +**ret the after buff padding +*/ +void real_padding_buf(unsigned char *buf, int size, int *final_size) +{ + //unsigned char * ret = NULL; + int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE); + int i; + + if(buf == NULL || final_size == NULL) + { + GDPR_DEBUG("buf or final_size NULL !!!\n"); + return ; + } + *final_size = size + pidding_size; + + if (pidding_size!=0) { + for (i =size;i < (size+pidding_size); i++ ) { + buf[i] = pidding_size; + } + } +} + +unsigned char *padding_buf(unsigned char *buf,int size, int *final_size) +{ + unsigned char *ret = NULL; + int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE); + int i; + + *final_size = size + pidding_size; + ret = (unsigned char *)malloc(size+pidding_size); + memcpy( ret, buf, size); + + if (pidding_size!=0) { + for (i =size;i < (size+pidding_size); i++ ) { + ret[i] = pidding_size; + } + } + + return ret; +} + +int remove_padding(unsigned char *buff, int dataLen, int blockSize) +{ + int paddingLen = 0; + + if (NULL == buff || 0 == dataLen || 0 == blockSize) + { + GDPR_DEBUG("remove padding fail: input params\n"); + return -1; + } + + paddingLen = buff[dataLen - 1]; + + if (paddingLen > blockSize || paddingLen > dataLen) + { + GDPR_DEBUG("remove padding fail. paddingLen: %d, dataLen: %d, blockSize: %d\n", + paddingLen, dataLen, blockSize); + return -1; + } + + return paddingLen; +} + +void printf_buff(unsigned char *buff,int size) +{ + int i = 0; + + for (i=0;i ITEM_LEN) + { + + lenpart = ITEM_LEN; + ret = aes_cbc_encrypt_intface(pIndex, pOut, &lenpart, ptmpKey , tmpIv, 1); + if(ret != HTTP_OK) + { + GDPR_DEBUG("aes_cbc_encrypt_intface_bypart aes_cbc_encrypt_intface Error "); + return HTTP_ERROR; + } + + memcpy(pIndex, pOut, lenpart); + pIndex += ITEM_LEN; + memset(encrypt_buf, 0, ITEM_LEN + AES_BLOCK_SIZE + 1); + enlen -= ITEM_LEN; + } + + memset(encrypt_buf, 0, ITEM_LEN + AES_BLOCK_SIZE + 1); + if(enlen) + { + padding_size -= enlen; + + //aes_cbc_encrypt_16NL_intface(pIndex, pOut, enlen, ptmpKey, tmpIv, 1); + ret = aes_tmp_encrypt_buf_nopadding_new(pIndex, pOut, &enlen, ptmpKey, tmpIv); + if(ret != HTTP_OK) + { + GDPR_DEBUG("aes_cbc_encrypt_intface_bypart aes_tmp_encrypt_buf_nopadding_new Error \n"); + return HTTP_ERROR; + } + + memcpy(pIndex, pOut, enlen); + + padding_size += enlen; + + } + + *len = padding_size; + + return HTTP_OK; +} + + +int aes_cbc_decrypt_intface_bypart(unsigned char *raw_buf, int* len, unsigned char *ptmpKey, unsigned char * ptmpIv) +{ + unsigned char tmpIv[AES_KEY_LEN+1] = {0}; + unsigned char encrypt_buf[ITEM_LEN + AES_BLOCK_SIZE + 1] = {0}; + unsigned int padding_size = * len; + int enlen = 0; + unsigned char * pOut = NULL; + unsigned char * pIndex = NULL; + int lenpart = 0; + //unsigned char * ptmp=NULL; + int ret = HTTP_OK; + + memcpy(tmpIv, ptmpIv, AES_KEY_LEN); + enlen = padding_size; + pIndex = raw_buf; + + memset(encrypt_buf, 0, ITEM_LEN + AES_BLOCK_SIZE + 1); + + pOut = encrypt_buf; + + while( enlen > ITEM_LEN) + { + + lenpart = ITEM_LEN; + ret = aes_cbc_encrypt_intface(pIndex, pOut, &lenpart, ptmpKey , tmpIv, 0); + if(ret != HTTP_OK) + { + GDPR_DEBUG("aes_cbc_decrypt_intface_bypart aes_cbc_encrypt_intface Error \n"); + return HTTP_ERROR; + } + memcpy(pIndex, pOut, lenpart); + pIndex += ITEM_LEN; + memset(encrypt_buf, 0, ITEM_LEN + AES_BLOCK_SIZE + 1); + enlen -= ITEM_LEN; + } + memset(encrypt_buf, 0, ITEM_LEN + AES_BLOCK_SIZE + 1); + // no padding + if(enlen) + { + padding_size -= enlen; + + //aes_cbc_encrypt_16NL_intface(pIndex, pOut, enlen, ptmpKey, tmpIv, 0); + ret = aes_tmp_decrypt_buf_nopadding_new(pIndex, pOut, &enlen, ptmpKey, tmpIv); + if(ret != HTTP_OK) + { + GDPR_DEBUG("aes_cbc_decrypt_intface_bypart aes_tmp_decrypt_buf_nopadding_new Error \n"); + return HTTP_ERROR; + } + + memcpy(pIndex, pOut, enlen); + padding_size += enlen; + } + + *len = padding_size; + GDPR_DEBUG("aes_cbc_decrypt_intface_bypart Success !!! \n"); + + + return HTTP_OK; +} + +/*************************************************************************************/ +int aes_genKey() +{ + + l_pKey = (unsigned char *)malloc(AES_KEY_LEN); + l_pV = (unsigned char *)malloc(AES_KEY_LEN); + + if(l_pKey == NULL || l_pV == NULL) + { + GDPR_DEBUG("l_pKey or l_pV is NULL \n"); + return HTTP_ERROR; + } + + memset(l_pKey, 0, AES_KEY_LEN); + memset(l_pV, 0, AES_KEY_LEN); + + AES_STRNCPY(l_pKey, l_key, AES_KEY_LEN); + AES_STRNCPY(l_pV, l_v, AES_KEY_LEN); + + return HTTP_OK; +} + + +int aes_getKey(unsigned char *key, unsigned char *iv) +{ + + if(l_pKey != NULL && l_pV != NULL ) + { + AES_STRNCPY(key, l_pKey, AES_KEY_LEN); + AES_STRNCPY(iv, l_pV, AES_KEY_LEN); + } + else + { + GDPR_DEBUG("aes_getKey failed "); + return HTTP_ERROR; + } + + return HTTP_OK; +} + +int aes_set_KeyandIv(unsigned char * Keystr, unsigned char *Ivstr) +{ + if( Keystr == NULL || Ivstr == NULL) + { + GDPR_DEBUG("Error aes_set_KeyandIv !!!\n"); + return HTTP_ERROR; + } + + if(aes_free_KeyandIv() != HTTP_OK) + { + GDPR_DEBUG("Error aes_set_KeyandIv !!!\n"); + return HTTP_ERROR; + } + + l_pKey = (unsigned char *)malloc(AES_KEY_LEN); + l_pV = (unsigned char *)malloc(AES_KEY_LEN); + + if(l_pKey == NULL || l_pV == NULL ) + { + GDPR_DEBUG("Error aes_set_KeyandIv !!!\n"); + return HTTP_ERROR; + } + memset( l_pKey, 0, AES_KEY_LEN); + memset( l_pV, 0, AES_KEY_LEN); + + AES_STRNCPY(l_pKey, Keystr, AES_KEY_LEN); + AES_STRNCPY(l_pV, Ivstr, AES_KEY_LEN); + + return HTTP_OK; +} + + +int aes_free_KeyandIv() +{ + + if(l_pKey!= NULL) + { + memset(l_pKey, 0, AES_KEY_LEN); + free(l_pKey); + l_pKey = NULL; + } + + if(l_pV != NULL ) + { + memset(l_pV, 0, AES_KEY_LEN); + free(l_pV); + l_pV = NULL; + } + + return HTTP_OK; +} + +/* +**Function: int aes_enBufToFile(char * pfile, char *pIn, unsigned int inLen, unsigned char *Key, unsigned char *Iv,unsigned char*pExtend, unsigned int exLen) +**Des: Encrypt the Buff to File +**param[in] pfile +**param[in] pIn +**param[in] Key +**param[in] Iv +**param[in] pExtend +**param[in] exLen +** +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_enBufToFile(char * pfile, char *pIn, unsigned int inLen, unsigned char *Key, unsigned char *Iv,unsigned char*pExtend, unsigned int exLen) +{ + //int ret = 0; + FILE * fp ; + + + unsigned char pOutBuff[HTTP_DATA_EN_LEN] = {0}; // 128 * 3 + 8 + 1 + unsigned char pAesEncrypt[HTTP_DATA_EN_LEN] = {0}; // 128 * 3 + 8 + 1 + unsigned char Base64AesEncrypt[HTTP_DATA_BASE64_LEN + 1]={0}; // 128 * 3 * 4 / 3 + 1 + + char * pSend; + unsigned char * pExSend; + + unsigned char tmpIv[AES_KEY_LEN + 1] = {0}; + + int sendLen = 0; + int outBuflen = 0; + int outExBuflen = 0; + int aesLen = 0; + int totalLen = 0; + + //unsigned char * ptmp; + + sendLen = inLen; + pSend = pIn; + pExSend = pExtend; + outExBuflen = exLen; + + fp = fopen(pfile, "w"); + if (NULL == fp) + { + GDPR_DEBUG("open %s fail\n", pfile); + return HTTP_ERROR; + } + + memcpy(tmpIv, Iv, AES_KEY_LEN); + while ( sendLen > HTTP_DATA_AES_LEN ) + { + memset(pOutBuff, 0, AES_BLOCK_SIZE+1); + memcpy(pOutBuff, pSend, HTTP_DATA_AES_LEN) ; + + outBuflen = HTTP_DATA_AES_LEN; + aesLen = outBuflen; + + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + + pSend += HTTP_DATA_AES_LEN; + sendLen -= HTTP_DATA_AES_LEN; + + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + } + + /*********************************Send the addr + pExtend ******************************************/ + if(sendLen > 0) + { + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + memcpy(pOutBuff, pSend, sendLen); + outBuflen = sendLen; + if(exLen > 0) + { + outExBuflen = (exLen + sendLen > HTTP_DATA_AES_LEN) ? (HTTP_DATA_AES_LEN - sendLen) : exLen; + strncat((char *)pOutBuff, (char *)pExSend, outExBuflen); + + pExSend += outExBuflen; + exLen -= outExBuflen; + outBuflen+= outExBuflen; + } + aesLen = outBuflen; + + if(aesLen < HTTP_DATA_AES_LEN || ( aesLen == HTTP_DATA_AES_LEN && exLen==0 ) ) + { + aes_tmp_encrypt_buf_nopadding_new(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + } + else + { + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + } + + + + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN + 1); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + } + + while( exLen > HTTP_DATA_AES_LEN ) + { + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + memcpy(pOutBuff, pExSend, HTTP_DATA_AES_LEN); + + outBuflen = HTTP_DATA_AES_LEN; + aesLen = outBuflen; + + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, outBuflen); + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + + pExSend += HTTP_DATA_AES_LEN; + exLen -= HTTP_DATA_AES_LEN; + + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + } + + if(exLen > 0) + { + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + memcpy(pOutBuff, pExSend, exLen); + outBuflen = exLen; + aesLen = outBuflen; + + aes_tmp_encrypt_buf_nopadding_new(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv); + + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + + pExSend += aesLen; + exLen -= aesLen; + } + + /*********************************Send the pExtend******************************************/ + + fclose(fp); + return totalLen; +} + + +/* +**Function: int aes_enBufToFile_ByArgList(char * pfile, AES_ARGS_ENTRY_HEAD * pAesArgsList, unsigned char *Key, unsigned char *Iv) +**Des: Encrypt the Buff to File +**param[in] pfile +**param[in] pAesArgsList +**param[in] Key +**param[in] Iv +** +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_enBufToFile_ByArgList(char * pfile, AES_ARGS_ENTRY_HEAD * pAesArgsList, unsigned char *Key, unsigned char *Iv) +{ + //int ret = 0; + FILE * fp ; + unsigned char pOutBuff[HTTP_DATA_EN_LEN] = {0}; // 128 * 3 + 8 + 1 + unsigned char pAesEncrypt[HTTP_DATA_EN_LEN] = {0}; // 128 * 3 + 8 + 1 + unsigned char Base64AesEncrypt[HTTP_DATA_BASE64_LEN + 1]={0}; // 128 * 3 * 4 / 3 + 1 + + unsigned char * pSend; + unsigned char * pExSend; + + unsigned char tmpIv[AES_KEY_LEN + 1] = {0}; + + unsigned int sendLen = 0; + unsigned int outBuflen = 0; + + unsigned int outExBuflen = 0; + + int aesLen = 0; + unsigned int exLen = 0; + + unsigned int totalLen = 0; + AES_ARGS_ENTRY * pAesArgsEntry = pAesArgsList->next; + AES_ARGS_ENTRY * pTmpAesArgsEntry; + + //unsigned char * ptmp; + + + fp = fopen(pfile, "w"); + if (NULL == fp) + { + GDPR_DEBUG("open %s fail\n", pfile); + return HTTP_ERROR; + } + + memcpy(tmpIv, Iv, AES_KEY_LEN); + + + while(pAesArgsEntry != NULL) + { + pSend = pAesArgsEntry->addr; + sendLen = pAesArgsEntry->len; + + /********************************* HTTP_DATA_AES_LEN ******************************************/ + while ( sendLen > HTTP_DATA_AES_LEN ) + { + memset(pOutBuff, 0, AES_BLOCK_SIZE+1); + memcpy(pOutBuff, pSend, HTTP_DATA_AES_LEN); + + outBuflen = HTTP_DATA_AES_LEN; + aesLen = outBuflen; + + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, outBuflen); + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + + pSend += HTTP_DATA_AES_LEN; + sendLen -= HTTP_DATA_AES_LEN; + + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + } + if(sendLen > 0) + { + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + memcpy(pOutBuff, pSend, sendLen); + outBuflen = sendLen; + aesLen = outBuflen; + pSend += aesLen; + sendLen -= aesLen; + if(pAesArgsEntry->next==NULL) + { + + /*********************************Send the addr + pExtend ******************************************/ + aes_tmp_encrypt_buf_nopadding_new(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + break; //the pAesArgsEntry flush + } + else + { + pTmpAesArgsEntry = pAesArgsEntry->next; + while( pTmpAesArgsEntry !=NULL ) + { + pExSend = pTmpAesArgsEntry->addr; + exLen = pTmpAesArgsEntry->len; + sendLen = strlen((char *)pOutBuff); + outExBuflen = (exLen + sendLen > HTTP_DATA_AES_LEN) ? (HTTP_DATA_AES_LEN - sendLen) : exLen; + + if(strlen((char *)pOutBuff) != 0) + { + strncat((char *)pOutBuff, (char *)pExSend, outExBuflen); + } + else + { + memcpy(pOutBuff, pExSend, outExBuflen); + } + + outBuflen += outExBuflen; + aesLen = outBuflen; + + pTmpAesArgsEntry->addr += outExBuflen; + pTmpAesArgsEntry->len -= outExBuflen; + + if(outBuflen < HTTP_DATA_AES_LEN && pTmpAesArgsEntry->next != NULL) // pTmpAesArgsEntry->len == 0 + { + sendLen = outBuflen; + pTmpAesArgsEntry = pTmpAesArgsEntry->next; + } + else if(pTmpAesArgsEntry->next == NULL) + { + if(pTmpAesArgsEntry->len == 0) + { + aes_tmp_encrypt_buf_nopadding_new(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + pTmpAesArgsEntry = pTmpAesArgsEntry->next; + } + else + { + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + } + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + sendLen = 0; + outBuflen=0; + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN + 1); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + continue; + } + else + { + aes_cbc_encrypt_intface(pOutBuff, pAesEncrypt, &aesLen, Key, tmpIv, 1); + outBuflen = b64_encode(Base64AesEncrypt, HTTP_DATA_BASE64_LEN, pAesEncrypt, aesLen); + fwrite(Base64AesEncrypt, outBuflen, 1 , fp); + totalLen += outBuflen; + memset(Base64AesEncrypt, 0, HTTP_DATA_BASE64_LEN + 1); + memset(pAesEncrypt, 0, HTTP_DATA_AES_LEN); + memset(pOutBuff, 0, HTTP_DATA_AES_LEN); + break; + } + } + pAesArgsEntry = pTmpAesArgsEntry; + } + + } + else // won't be exec + { + pAesArgsEntry = pAesArgsEntry->next; + } + } + /*********************************Send the pExtend******************************************/ + + fclose(fp); + return totalLen; +} + + +/* +**Function: int aes_argList_add(AES_ARGS_ENTRY_HEAD* pAesArgsList, unsigned char * raw_buf, unsigned int len) +**Des: Add the addr and len AES_ARGS_ENTRY_HEAD* pAesArgsList +**param[in] pAesArgsList +**param[in] raw_buf +**param[in] len +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_argList_add(AES_ARGS_ENTRY_HEAD* pAesArgsList, unsigned char * raw_buf, unsigned int len) +{ + AES_ARGS_ENTRY* pAesArgsEntry = pAesArgsList->next; + AES_ARGS_ENTRY* Item; + + Item = (AES_ARGS_ENTRY *)malloc(sizeof(AES_ARGS_ENTRY)); + + if(Item == NULL) + { + GDPR_DEBUG("malloc is null "); + return HTTP_ERROR; + } + + Item->addr = raw_buf; + Item->len = len; + Item->next = NULL; + Item->prev = NULL; + + if(pAesArgsEntry != NULL) + { + while(pAesArgsEntry->next !=NULL ) + { + pAesArgsEntry = pAesArgsEntry->next; + } + pAesArgsEntry->next = Item; + Item->prev = pAesArgsEntry; + } + else + { + pAesArgsList->next=Item; + Item->prev = NULL; + } + + return HTTP_OK; +} + +/* +**Function: int aes_argList_add(AES_ARGS_ENTRY_HEAD* pAesArgsList, unsigned char * raw_buf, unsigned int len) +**Des: Encrypt the Buff to File +**param[in] pAesArgsList +**param[in] raw_buf +**param[in] len +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_argList_flush(AES_ARGS_ENTRY_HEAD* pAesArgsList) +{ + AES_ARGS_ENTRY* pAesArgsEntry = pAesArgsList->next; + AES_ARGS_ENTRY* pAesArgsEntry2 = pAesArgsEntry; + + if(pAesArgsEntry == NULL) + { + GDPR_DEBUG("aes_argList_add Error pAesArgsList is null!"); + return HTTP_ERROR; + } + + while(pAesArgsEntry->next !=NULL ) + { + pAesArgsEntry = pAesArgsEntry->next; + } + pAesArgsEntry2 = pAesArgsEntry; + while(pAesArgsEntry2->prev != NULL) + { + pAesArgsEntry2 = pAesArgsEntry->prev; + free(pAesArgsEntry); + pAesArgsEntry=pAesArgsEntry2; + } + + return HTTP_OK; +} + + + + + +int uci_encrypt(char * raw_data_buf, unsigned int raw_data_buf_len, char * encry_data_buf, unsigned int encry_data_buf_len) +{ + int ret = 0; + int len = raw_data_buf_len + AES_BLOCK_SIZE + 1; + char *ptr = NULL; + + GDPR_DEBUG("raw data=%s, len=%d\n",raw_data_buf, raw_data_buf_len); + + char * aes_data_buf = (char *) malloc(len); + if(aes_data_buf == NULL) + { + GDPR_DEBUG("uci_encrypt malloc space error \n"); + return -1; + } + + memset(aes_data_buf,0,len); + + ptr = aes_data_buf; + + memcpy( ptr, raw_data_buf, raw_data_buf_len); + + aes_data_buf[raw_data_buf_len] = '\0'; + + len = raw_data_buf_len; + + ret = aes_cbc_encrypt_intface_bypart((unsigned char*)aes_data_buf, &len, l_key, l_v); + if (ret < 0) + { + GDPR_DEBUG("aes_encrypt error\n"); + goto ERROR; + } + GDPR_DEBUG("aes data=%s, len=%d\n",aes_data_buf, len); + + memcpy(encry_data_buf,gmark,strlen((const char *)gmark)); + + ret = b64_encode((unsigned char *)encry_data_buf+strlen((const char *)gmark), encry_data_buf_len, aes_data_buf, len); + if(ret < 0) + { + GDPR_DEBUG("b64 encode error \n"); + goto ERROR; + } + GDPR_DEBUG("base64 data=%s, len=%d\n",encry_data_buf, encry_data_buf_len); + + free(aes_data_buf); + return 0; + +ERROR: + free(aes_data_buf); + return -1; +} + +int uci_decrypt(char * decrypt_data_buf, unsigned int decrypt_data_buf_len,char* encrypt_data_buf, unsigned int encrypt_data_buf_len) +{ + int ret = 0; + + GDPR_DEBUG(" GDPR_DEBUG encrypt_data_buf = %s, encrypt_data_buf_len = %d",encrypt_data_buf,encrypt_data_buf_len); + + if( strncmp(encrypt_data_buf,(const char *)gmark, strlen((const char *)gmark)) != 0) + { + memset(decrypt_data_buf,0,decrypt_data_buf_len); + decrypt_data_buf_len = encrypt_data_buf_len; + memcpy(decrypt_data_buf, encrypt_data_buf,encrypt_data_buf_len); + GDPR_DEBUG("not find mark=%s, decrypt_data_buf = %s , len=%d\n", gmark, decrypt_data_buf, encrypt_data_buf_len); + return 0; + } + //base64 decrypt + decrypt_data_buf_len = b64_decode(decrypt_data_buf, (int)decrypt_data_buf_len, encrypt_data_buf+strlen((const char *)gmark), encrypt_data_buf_len-strlen((const char *)gmark)); + + if( decrypt_data_buf_len == -1) + { + GDPR_DEBUG("b64 decode fail\n"); + return -1; + } + GDPR_DEBUG("after base64 decode data= %s, len = %d",decrypt_data_buf,decrypt_data_buf_len); + + //aes decrypt + ret = aes_cbc_decrypt_intface_bypart((unsigned char *)decrypt_data_buf, (int *)&decrypt_data_buf_len, l_key, l_v); + decrypt_data_buf[decrypt_data_buf_len]='\0'; + if( ret != 0 ) + { + GDPR_DEBUG("aes decrypt fail\n"); + return -1; + } + GDPR_DEBUG("after aes decrypt data=%s,len = %d \n",decrypt_data_buf,decrypt_data_buf_len); + + return 0; +} + diff --git a/gdpr_aes_interface.h b/gdpr_aes_interface.h new file mode 100755 index 0000000..390aae9 --- /dev/null +++ b/gdpr_aes_interface.h @@ -0,0 +1,201 @@ +/* Copyright(c) 2009-2018 Shenzhen TP-LINK Technologies Co.Ltd. + * + * file gdpr_aes_interface.h + * brief AES handle + * details lcrypto + * + * author Li Qiang + * version 1.0.1 + * date 26Apr18 + * + * warning + * + * history \arg 1.0.0, 25May18, Li Qiang, Create the file. + * history \arg 1.0.1 10JUL18, Liao Xingwei, merge functions from http_aes.h + */ +#ifndef __GDPR_AES_INTERFACE_H__ +#define __GDPR_AES_INTERFACE_H__ + +#include "openssl/aes.h" +/**************************************************************************************************/ +/* DEFINES */ +/**************************************************************************************************/ +#define AES_KEY_LEN 32 + +#define AES_STRNCPY(dest, src, len) memcpy(dest, src, len); + +#define ITEM_LEN 128 + +#define HTTP_DATA_AES_LEN 128*3 // 512 = 128 * 4 need padding ==> 128*4 + 16 = 16*(32 + 1) Base64 : ( 16 * 33 ) * 4 /3 = 16 * 44 = 704 + +#define HTTP_DATA_BASE64_LEN 1024 // 128 * 3 ==> Base64 : ( 128 * 3 ) * 4 /3 = 512 + +#define HTTP_DATA_EN_LEN HTTP_DATA_AES_LEN+16 + 1 //128 * 3 + 16 +1 + +/**************************************************************************************************/ +/* TYPES */ +/**************************************************************************************************/ +typedef struct _AES_ARGS_ENTRY{ + struct _AES_ARGS_ENTRY * next; + struct _AES_ARGS_ENTRY * prev; + unsigned char * addr; + unsigned int len; +} AES_ARGS_ENTRY; + +typedef struct _AES_ARGS_ENTRY_HEAD{ + struct _AES_ARGS_ENTRY * next; + struct _AES_ARGS_ENTRY * prev; +} AES_ARGS_ENTRY_HEAD; + +/**************************************************************************************************/ +/* VARIABLES */ +/**************************************************************************************************/ + +/**************************************************************************************************/ +/* FUNCTIONS */ +/**************************************************************************************************/ +/* +**Function: int remove_padding(unsigned char *buff, int dataLen, int blockSize) +**Des: padding buf +**param[in] buf - enough buffer +**param[in] dataLen +**param[in] blockSize block size 16 +** +**ret buff padding size need remove +*/ +int remove_padding(unsigned char *buff, int dataLen, int blockSize); + +void printf_buff(unsigned char *buff,int size) ; + +/* +**Function: unsigned char *real_padding_buf(unsigned char *buf,int size, int *final_size) +**Des: padding buf +**param[in] buf - enough buffer padding the buffer +**param[in] size +**param[in] final_size +** +**ret the after buff padding +*/ +void real_padding_buf(unsigned char *buf, int size, int *final_size); + +/* +**Des: flag : 1 Encrypt 0 or other : Decrypt +** input : raw_buf +** output: encrypt_buf +**ret£ºvoid +*/ +int aes_cbc_encrypt_intface(unsigned char *raw_buf, unsigned char *encrypt_buf, int* len , unsigned char *ptmpKey, unsigned char * ptmpIv, int flag); + +/* +**Des: Encrypt and Decrypt with temp Key and Iv +*/ +int aes_tmp_encrypt_buf_nopadding_new(unsigned char *raw_buf, unsigned char *encrypt_buf, int* len , unsigned char *ptmpKey, unsigned char * ptmpIv); +int aes_tmp_decrypt_buf_nopadding_new(unsigned char *raw_buf, unsigned char *encrypt_buf, int* len , unsigned char *ptmpKey, unsigned char * ptmpIv); + +/* +**Des: flag : Encrypt +** input : raw_buf +** output: raw_buf +**ret£ºvoid +*/ +int aes_cbc_encrypt_intface_bypart(unsigned char *raw_buf, int* len, unsigned char *ptmpKey, unsigned char * ptmpIv); + +/* +**Des: flag : Decrypt +** input : raw_buf +** output: raw_buf +**ret£ºvoid +*/ +int aes_cbc_decrypt_intface_bypart(unsigned char *raw_buf, int* len, unsigned char *ptmpKey, unsigned char * ptmpIv); + +/* +**Des: SetKey and Iv +*/ +int aes_set_KeyandIv(unsigned char * Keystr, unsigned char *Ivstr); + +/* +**Des: Free the System Key And Iv +*/ +int aes_free_KeyandIv(); + +/* +**Des: Get the System Key And Iv +**return TTP_OK / HTTP_ERROR +*/ +int aes_getKey(unsigned char *key, unsigned char *iv); + +/* +**Function: int aes_enBufToFile(char * pfile, char *pIn, unsigned int inLen, unsigned char *Key, unsigned char *Iv,unsigned char*pExtend, unsigned int exLen) +**Des: Encrypt the Buff to File +**param[in] pfile +**param[in] pIn +**param[in] Key +**param[in] Iv +**param[in] pExtend +**param[in] exLen +** +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_enBufToFile(char * pfile, char *pIn, unsigned int inLen, unsigned char *Key, unsigned char *Iv,unsigned char*pExtend, unsigned int exLen); + +/* +**Function: int aes_enBufToFile_ByArgList(char * pfile, AES_ARGS_ENTRY_HEAD * pAesArgsList, unsigned char *Key, unsigned char *Iv) +**Des: Encrypt the Buff to File +**param[in] pfile +**param[in] pAesArgsList +**param[in] Key +**param[in] Iv +** +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_enBufToFile_ByArgList(char * pfile, AES_ARGS_ENTRY_HEAD * pAesArgsList, unsigned char *Key, unsigned char *Iv); + +/* +**Function: int aes_argList_add(AES_ARGS_ENTRY_HEAD* pAesArgsList, unsigned char * raw_buf, unsigned int len) +**Des: Add the addr and len AES_ARGS_ENTRY_HEAD* pAesArgsList +**param[in] pAesArgsList +**param[in] raw_buf +**param[in] len +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_argList_add(AES_ARGS_ENTRY_HEAD* pAesArgsList, unsigned char * raw_buf, unsigned int len); + +/* +**Function: int aes_argList_flush(AES_ARGS_ENTRY_HEAD* pAesArgsList) +**Des: flush the AES_ARGS_ENTRY_HEAD* pAesArgsList +**param[in] pAesArgsList +** +**return HTTP_OK / HTTP_ERROR +*/ +int aes_argList_flush(AES_ARGS_ENTRY_HEAD* pAesArgsList); + +/* +**Function: int uci_encrypt(char * raw_data_buf, unsigned int raw_data_buf_len, char * encrypt_data_buf, unsigned int encrypt_data_buf_len) +**Des: encrypt uci data +**param[in] raw_data_buf +**param[in] raw_data_buf_len +**param[in/out] encrypt_data_buf +**param[in] encrypt_data_buf_len +** +**return 0 / -1 +*/ +int uci_encrypt(char * raw_data_buf, unsigned int raw_data_buf_len, char * encrypt_data_buf, unsigned int encrypt_data_buf_len); + +/* +**Function: int uci_decrypt(char * decrypt_data_buf, unsigned int decrypt_data_buf_len,char* encrypt_data_buf, unsigned int encrypt_data_buf_len) +**Des: decrpty uci data +**param[in] decrypt_data_buf +**param[in] decrypt_data_buf_len +**param[in/out] encrypt_data_buf +**param[in] encrypt_data_buf_len +** +**return 0 / -1 +*/ + +int uci_decrypt(char * decrypt_data_buf, unsigned int decrypt_data_buf_len,char* encrypt_data_buf, unsigned int encrypt_data_buf_len); + +#endif /*__GDPR_AES_INTERFACE_H__*/ + diff --git a/gdpr_log.h b/gdpr_log.h new file mode 100644 index 0000000..426826a --- /dev/null +++ b/gdpr_log.h @@ -0,0 +1,37 @@ +#ifndef __GDPR_LOG_H_ +#define __GDPR_LOG_H_ +/******************************************************************************/ +/* INCLUDE_FILES */ +/******************************************************************************/ +#include + +/**************************************************************************************************/ +/* DEFINES */ +/**************************************************************************************************/ +#define UCI_LOG_TAG "UCI_GDPR" + +#ifdef DEBUG +#define GDPR_DEBUG(_fmt, ...) \ + {\ + printf("[ %s ] %d: ", __FUNCTION__, __LINE__); \ + printf(_fmt, ##__VA_ARGS__); \ + /*LOG_PRI(ANDROID_LOG_INFO, UCI_LOG_TAG, _fmt, ## __VA_ARGS__); */\ + } +#else +#define GDPR_DEBUG(_fmt,...) {} +#endif + +/**************************************************************************************************/ +/* TYPES */ +/**************************************************************************************************/ + +/**************************************************************************************************/ +/* VARIABLES */ +/**************************************************************************************************/ + +/**************************************************************************************************/ +/* FUNCTIONS */ +/**************************************************************************************************/ + + +#endif /* __GDPR_LOG_H_ */ diff --git a/libuci.c b/libuci.c index b17cda1..1f382e7 100644 --- a/libuci.c +++ b/libuci.c @@ -35,6 +35,10 @@ static const char *uci_errstr[] = { [UCI_ERR_PARSE] = "Parse error", [UCI_ERR_DUPLICATE] = "Duplicate entry", [UCI_ERR_UNKNOWN] = "Unknown error", +#ifdef TP_FEATURE_GDPR + [UCI_ERR_ENCRYPT] = "encrypt data error", + [UCI_ERR_DECRYPT] = "decrypt data error", +#endif }; #include "uci_internal.h" diff --git a/list.c b/list.c index faf4494..1509205 100644 --- a/list.c +++ b/list.c @@ -693,9 +693,11 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr) ptr->s = uci_alloc_section(ptr->p, ptr->value, ptr->section); ptr->last = &ptr->s->e; } else if (ptr->o && ptr->option) { /* update option */ +#ifndef TP_FEATURE_GDPR if ((ptr->o->type == UCI_TYPE_STRING) && !strcmp(ptr->o->v.string, ptr->value)) return 0; +#endif uci_free_option(ptr->o); ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value); ptr->last = &ptr->o->e; diff --git a/uci.h b/uci.h index 36c8890..d7de962 100644 --- a/uci.h +++ b/uci.h @@ -50,6 +50,10 @@ enum UCI_ERR_PARSE, UCI_ERR_DUPLICATE, UCI_ERR_UNKNOWN, +#ifdef TP_FEATURE_GDPR + UCI_ERR_ENCRYPT, + UCI_ERR_DECRYPT, +#endif UCI_ERR_LAST };