Encrypted padding method (pkcs5/pkcs7/ISO10126 padding/ANSIX923 padding/Zeros padding) external padding

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;
}