Due to SM2 and other encrypted grouping methods, each time the request is 16byte, it needs to be filled. The filling method is as follows:
pkcs5/pkcs7/ISO10126 padding/ANSIX923 padding/Zeros padding
explain:
pkcs5 is a subset of pkcs7, specially used to fill 8 bytes or multiples of 8, pkcs7 can fill bytes into multiple bytes
Definition of pkcs7:
For example, the byte length is 10:
Example 1. If the current data is 8, then 2 bytes need to be filled, and the filled bytes are 0x02, 0x02,
Example 2. If the current data is 3, then 7 bytes need to be filled, and the filled bytes are 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07
Example 3. If the current data is 10, then fill another 10 bytes, and the filling bytes are
0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A
When parsing, it is to judge whether there are consecutive same values in the follow-up, and the value and length are equal.
pkcs5 definition: only limits the length, if it is 8 or 16, it is the same as pkcs7.
Definition of ISO10126:
The last bit identifies the number of padding n, and the previous padding is n-1 random values
For example, if the byte length is 10:
Example 1: The current length is 7, then 3 bytes need to be filled, the last byte is 0x03, the first two are random numbers, the filling is as follows: 0x01, 0xff, 0x03
ANSIX923 padding:
Pad the last byte to be the length and the rest to be 0
For example, if the byte length is 10:
Example 1: The current data is 4, and 6 bytes need to be filled, then the last byte is 0x06, and the remaining 5 bytes are 0, and the filling is as follows:
0x00,0x00,0x00,0x00,0x00,0x06
Definition of zeros padding:
Not enough to fill with 0
For example, if the byte length is 10:
Example 1: The current length is 6, then 4 bytes need to be filled, and the filled byte is 0x00:
0x00,0x00,0x00,0x00
The specific implementation is as follows:
define a padding structure
//add hmy 2023-07-17 14:18:33 // fill type #define NONE_PADDING 0 // no padding #define PKCS5_PADDING 1 //pkcs5 padding #define PKCS7_PADDING 2 //pkcs7 padding #define ISO10126_PADDING 3 //ISO10126 padding #define ANSIX923_PADDING 4 //ANSIX923 padding #define ZERO_PADDING 5 //Zeros padding #define SEC_TRUE 1000 // success #define SEC_FALSE 0 // fail // fill structure typedef struct str_padding_info{ U32 PaddingType;//filling type U32 dataLen;//data length U32 PaddingBit;//Padding alignment byte default 16 U8 dataBuf[255];//buffer message, 255 U32 bufLen;//The buffer message length, the length is 0~255 }PADDING_INFO, * P_PADDING_INFO;
First initialize the structure:
panding_type filling type
panding_bit padding digits, the default is 16
padding_info padding structure
int pandingInit(u32 panding_type, u32 panding_bit, P_PADDING_INFO padding_info)
details as follows:
//add hmy 2023-07-17 14:18:33 // fill structure initialization //panding_type filling type //panding_bit padding digits, the default is 16 //padding_info padding structure int pandingInit(u32 panding_type, u32 panding_bit, P_PADDING_INFO padding_info){ if (padding_info != NULL){ if (panding_type != NONE_PADDING & amp; & amp; panding_type != PKCS5_PADDING & amp; & amp; panding_type != PKCS7_PADDING & amp; & amp; & amp; panding_type != ZERO_PADDING ){ PRINTF("error:pading_type error\\ "); return -1; } memset(padding_info->dataBuf, 0 ,sizeof(padding_info->dataBuf)); padding_info->bufLen = 0; padding_info->dataLen = 0; padding_info->PaddingBit = panding_bit; padding_info->PaddingType = panding_type; } return 0; }
Padding implementation:
//add hmy 2023-07-17 14:19:28 //zero padding removal SEC_BOOL chip_padding_zero_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ int padding_len = 0; for (int i = *padingLen - 1; i >= *padingLen - padding_info->PaddingBit; i--){ if (paddingbuf[i] == 0){ padding_len++; } else { break; } } *padingLen = *padingLen - pading_len; memset(paddingbuf + *padingLen, 0, padding_len); return SEC_TRUE; } //zero fill SEC_BOOL chip_padding_zero_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit); for (int i =0 ; i < padding_len; i ++ ){ paddingbuf[i] = 0;//generate a random number; } *padingLen = pading_len; } //ansix923 padding removal SEC_BOOL chip_padding_ansix923_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = paddingbuf[*padingLen - 1]; U8 pos = 0; if (padding_info->PaddingBit < padding_len){ return SEC_FALSE; } for (int i = *padingLen- 2; i >= *padingLen - pading_len ; i--){ if (paddingbuf[i] == 0){ pos + + ; } else { break; } } PRINTF("ansix923 decode pos:%d, padding_len:%d\\ ",pos, padingLen); if (pos != padding_len - 1){ return SEC_FALSE; } *padingLen = *padingLen - pading_len; memset(paddingbuf + *padingLen, 0, padding_len); return SEC_TRUE; } //ansix923 padding SEC_BOOL chip_padding_ansix923_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit); for (int i =0 ; i < padding_len - 1; i ++ ){ paddingbuf[i] = 0;//generate a random number; } paddingbuf[pading_len - 1] = padding_len; *padingLen = pading_len; return SEC_TRUE; } //iso10126 padding removal SEC_BOOL chip_padding_iso10126_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = paddingbuf[*padingLen - 1]; U8 pos = 0; if (padding_info->PaddingBit < padding_len){ return SEC_FALSE; } *padingLen = *padingLen - pading_len; memset(paddingbuf + *padingLen, 0, padding_len); return SEC_TRUE; } //iso10126 padding SEC_BOOL chip_padding_iso10126_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *paddingLen){ U8 padding_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit); srand(time(nullptr));//Set random number seed for (int i =0 ; i < padding_len - 1; i ++ ){ paddingbuf[i] = (U8)rand();//generate a random number; } paddingbuf[pading_len - 1] = padding_len; *padingLen = pading_len; return SEC_TRUE; } //PKCS#5 padding removal SEC_BOOL chip_padding_pkcs5_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = paddingbuf[*padingLen - 1]; U8 pos = 0; if (8 < padding_len){ return SEC_FALSE; } for (int i = *padingLen - 1; i >= *padingLen - pading_len; i--){ if (paddingbuf[i] == padding_len){ pos + + ; } else { break; } } if (pos != padding_len){ return SEC_FALSE; } *padingLen = *padingLen - pading_len; memset(paddingbuf + *padingLen, 0, padding_len); return SEC_TRUE; } //pkcs#5 padding SEC_BOOL chip_padding_pkcs5_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = (U8)8 - (padding_info->dataLen % 8); for (int i =0 ; i < padding_len; i ++ ){ paddingbuf[i] = padding_len; } *padingLen = pading_len; return SEC_TRUE; } //PKCS#7 padding removal SEC_BOOL chip_padding_pkcs7_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = paddingbuf[*padingLen - 1]; U8 pos = 0; if (padding_info->PaddingBit < padding_len){ PRINTF("padding_pkcs7_decode bit:%d padding_len:%d\\ ",padding_info->PaddingBit, padding_len); return SEC_FALSE; } for (int i = *padingLen - 1; i >= *padingLen - pading_len; i--){ if (paddingbuf[i] == padding_len){ pos + + ; } else { break; } } //PRINTF("pkcs7 pos:%d padding_len:%d\\ ",pos, pading_len); if (pos != padding_len){ PRINTF("error: pkcs7 pos:%d padding_len:%d\\ ",pos, pading_len); return SEC_FALSE; } *padingLen = *padingLen - pading_len; memset(paddingbuf + *padingLen, 0, padding_len); return SEC_TRUE; } //PKCS#7 padding SEC_BOOL chip_padding_pkcs7_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *padingLen){ U8 padding_len = (U8)padding_info->PaddingBit - (padding_info->dataLen % (U8)padding_info->PaddingBit); for (int i =0 ; i < padding_len; i ++ ){ paddingbuf[i] = padding_len; } *padingLen = pading_len; return SEC_TRUE; } /** * Filling treatment * [in] padding_info padding structure * [out] paddingbuf output padding data * [out] padingLen output padding length */ SEC_BOOL chip_padding_encode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *paddingLen){ switch(padding_info->PaddingType){ case NONE_PADDING: return SEC_FALSE; break; case PKCS5_PADDING: return chip_padding_pkcs5_encode(padding_info, paddingbuf, paddingLen); break; case PKCS7_PADDING: PRINTF("pkcs7 padding\\ "); return chip_padding_pkcs7_encode(padding_info, paddingbuf, paddingLen); break; case ISO10126_PADDING: return chip_padding_iso10126_encode(padding_info, paddingbuf, paddingLen); break; case ANSIX923_PADDING: return chip_padding_ansix923_encode(padding_info, paddingbuf, paddingLen); break; case ZERO_PADDING: return chip_padding_zero_encode(padding_info, paddingbuf, paddingLen); break; } return SEC_FALSE; } /** * Filling removal treatment * [in] padding_info padding structure * [out] paddingbuf output padding data * [out] padingLen output padding length */ SEC_BOOL chip_padding_decode(P_PADDING_INFO padding_info, U8 *paddingbuf, U32 *paddingLen){ switch(padding_info->PaddingType){ case NONE_PADDING: return SEC_FALSE; break; case PKCS5_PADDING: return chip_padding_pkcs5_decode(padding_info, paddingbuf, paddingLen); break; case PKCS7_PADDING: return chip_padding_pkcs7_decode(padding_info, paddingbuf, paddingLen); break; case ISO10126_PADDING: return chip_padding_iso10126_decode(padding_info, paddingbuf, paddingLen); break; case ANSIX923_PADDING: return chip_padding_ansix923_decode(padding_info, paddingbuf, paddingLen); break; case ZERO_PADDING: return chip_padding_zero_decode(padding_info, paddingbuf, paddingLen); break; default: PRINTF("pading encode type error\\ "); return SEC_FALSE; } return SEC_FALSE; }
Call method, here is an example of how to call once
//fill once int main(){ char data[8] = {'1','2','3','4','5','6','7',\ '8'}; int dataLen = 8; char padding_msg = NULL; int padding_len = 0; \t PADDING_INFO padding_info = {0}; if (pandingInit(PKCS7_PADDING, 16, &padding_info) < 0){ printf("pandingInit error\\ "); return -1; } \t padding_info->dataLen = dataLen; padding_len = padding_info->dataLen + padding_info->PaddingBit; padding_msg = (char *)malloc(msg_len * sizeof(char)); if (padding_msg == NULL){ printf("error: malloc error\\ "); return -1; } //fill if (SEC_TRUE != chip_padding_encode( &padding_info, padding_msg + padding_info->dataLen, &msg_len)){ printf("error: padding error\\ "); free(pmsg_in); return -1; } memcpy(padding_msg, data, dataLen); msg_len = msg_len + dataLen; \t printf("fill data:\\ "); for (int i = 0; i < msg_len; i ++ ){ printf("X",padding_msg[i]); } printf("\\ "); if (pandingInit(PKCS7_PADDING, 16, &padding_info) < 0){ printf("pandingInit error\\ "); free(pmsg_in); return -1; } \t padding_info->dataLen = msg_len; padding_info->bufLen = 0; if (SEC_TRUE != chip_padding_decode( & amp; padding_info, padding_msg, & amp; msg_len)){ printf("decode error\\ "); free(pmsg_in); return -1; } printf("src data:\\ "); for (int i = 0; i < msg_len; i ++ ){ printf("X",padding_msg[i]); } printf("\\ "); \t free(pmsg_in); return 0; }
If the amount of data is large, and the method of filling multiple times, then you need to use the buffer inside. Every time you have to judge whether it is a multiple of filling bytes. If it is not enough, you need to intercept the part and store it in dataBuf. The next packet When splicing at the front, add it at the end of the pack.
Originally, multi-packet codec filling can also be encapsulated, but if it is enough, there is no encapsulation, and it is put together with the logic business. Here is a simple call to explain
In fact, it borrows the buffer of the structure. Whether the data that comes in each time is a multiple of the alignment byte, if it is a multiple, then there is no need to process it. If not, then you need to put the extra data into the padding, and when it comes in next time , splicing the data to the front before querying
// fill multiple times int main(){ char data[24] = {0}; int dataLen = 24; int offset = 0; char padding_msg[16] = {0}; int padding_len = 0; \t \t for (int i = 0;i < 24; i ++ ){ data[i] = (char)('0' + (i % 9)); } PADDING_INFO padding_info = {0}; if (pandingInit(PKCS7_PADDING, 16, &padding_info) < 0){ printf("pandingInit error\\ "); return -1; } \t //Example: fill 2 bytes for the first time dataLen = 2; if (dataLen < padding_info->PaddingBit){ padding_info->bufLen = dataLen; memcpy(padding_info->dataBuf,data + offset,dataLen); padding_info->bufLen = dataLen; } offset += dataLen; \t //For example: fill in 3 bytes for the second time dataLen = 3; if (dataLen + padding_info->bufLen < padding_info->PaddingBit){ padding_info->bufLen = dataLen; memcpy(padding_info->dataBuf + padding_info->bufLen,data + offset,dataLen); padding_info->bufLen += dataLen; } offset += dataLen; \t \t //For example: fill 14 bytes for the third time, this time the total is 17 bytes, which is greater than the alignment byte, I will not make a general judgment here, and when the time comes to realize it by myself dataLen = 14; if (dataLen + padding_info->bufLen >= padding_info->PaddingBit & amp; & amp; padding_info->bufLen > 0){ \t //First take out the cache part of the filling structure memcpy(padding_msg, padding_info->dataBuf, padding_info->bufLen); padding_len = padding_info->bufLen; padding_info->bufLen = 0; \t //Add the data part to make up 16 bytes of aligned bytes memcpy(padding_msg + padding_len, data + offset, padding_info->PaddingBit - padding_len); //Continue to put the remaining bytes that need to be added into the field memcpy(padding_info->dataBuf,data + offset + (padding_info->PaddingBit - padding_len),dataLen - (padding_info->PaddingBit- padding_len)); padding_info->bufLen =dataLen - (padding_info->PaddingBit- padding_len); \t padding_len + = padding_info->PaddingBit - padding_len; \t\t //This time is full of alignment bytes, padding_msg can be used to handle encoding or something } offset += dataLen; \t \t //For example, the last packet: fill the remaining 6 bytes dataLen = 6; if (dataLen + padding_info->bufLen < padding_info->PaddingBit){ padding_info->bufLen = dataLen; memcpy(padding_info->dataBuf + padding_info->bufLen,data + offset,dataLen); padding_info->bufLen += dataLen; } offset += dataLen; \t // last pack dataLen = 6; if (padding_info->bufLen > 0){ //First take out the cache part of the filling structure memcpy(padding_msg, padding_info->dataBuf, padding_info->bufLen); padding_len = padding_info->bufLen; padding_info->bufLen = 0; \t\t memcpy(padding_msg + padding_len, data + oofset, dataLen); padding_len += dataLen; } \t padding_info->dataLen = padding_len; padding_len = 16; //fill if (SEC_TRUE != chip_padding_encode( &padding_info, padding_msg + padding_info->dataLen, &padding_len)){ printf("error: padding error\\ "); free(pmsg_in); return -1; } padding_len += padding_info->dataLen; printf("fill data:\\ "); for (int i = 0; i < padding_len; i ++ ){ printf("X",padding_msg[i]); } printf("\\ "); if (pandingInit(PKCS7_PADDING, 16, &padding_info) < 0){ printf("pandingInit error\\ "); free(pmsg_in); return -1; } \t return 0; }