Skip to content

Commit

Permalink
PKCS Pad: public API to do PKCS padding
Browse files Browse the repository at this point in the history
PKCS padding adds length of padding as repeated padding byte.
Use the new function in all places.
  • Loading branch information
SparkiDev committed Feb 25, 2025
1 parent a856415 commit 9aada6f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 45 deletions.
60 changes: 35 additions & 25 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -9210,26 +9210,6 @@ int ToTraditionalEnc(byte* input, word32 sz, const char* password,

#ifdef HAVE_PKCS12

#define PKCS8_MIN_BLOCK_SIZE 8
static int Pkcs8Pad(byte* buf, int sz, int blockSz)
{
int padSz;

/* calculate pad size */
padSz = blockSz - (sz & (blockSz - 1));

/* pad with padSz value */
if (buf) {
int i;
for (i = 0; i < padSz; i++) {
buf[sz+i] = (byte)(padSz & 0xFF);
}
}

/* return adjusted length */
return sz + padSz;
}

#ifdef WOLFSSL_ASN_TEMPLATE
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
* PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
Expand Down Expand Up @@ -9339,7 +9319,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,

/* calculate size */
/* size of constructed string at end */
sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
sz = (word32)wc_PkcsPad(NULL, (int)inputSz, blockSz);
totalSz = ASN_TAG_SZ;
totalSz += SetLength(sz, seq);
totalSz += sz;
Expand Down Expand Up @@ -9435,7 +9415,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;

/* get pad size and verify buffer room */
sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
sz = (word32)wc_PkcsPad(NULL, (int)inputSz, blockSz);
if (sz + inOutIdx > *outSz) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
Expand All @@ -9446,7 +9426,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,

/* copy input to output buffer and pad end */
XMEMCPY(out + inOutIdx, input, inputSz);
sz = (word32)Pkcs8Pad(out + inOutIdx, (int)inputSz, blockSz);
sz = (word32)wc_PkcsPad(out + inOutIdx, (int)inputSz, blockSz);
#ifdef WOLFSSL_SMALL_STACK
cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (cbcIv == NULL) {
Expand Down Expand Up @@ -9520,7 +9500,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
salt, saltSz);
SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER],
(word16)itt);
pkcs8Sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
pkcs8Sz = (word32)wc_PkcsPad(NULL, (int)inputSz, blockSz);
SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);

/* Calculate size of encoding. */
Expand Down Expand Up @@ -9558,7 +9538,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
byte* pkcs8 =
(byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
XMEMCPY(pkcs8, input, inputSz);
Pkcs8Pad(pkcs8, (int)inputSz, blockSz);
wc_PkcsPad(pkcs8, (int)inputSz, blockSz);

/* Encrypt PKCS#8 key inline. */
ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
Expand All @@ -9578,6 +9558,36 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
#endif /* HAVE_PKCS12 */
#endif /* NO_PWDBASED */

/* Block padding used for PKCS#5, PKCS#7, PKCS#8 and PKCS#12.
*
* The length of padding is the value of each padding byte.
*
* When buf is NULL, the padded size is returned.
*
* @param [in, out] buf Buffer of data to be padded. May be NULL.
* @param [in] sz Size of data in bytes.
* @param [in] blockSz Size of block, in bytes, which buffer size must be
* a multiple of. Assumed to be less than 256 and
* a power of 2.
* @return Size of padded buffer in bytes.
*/
int wc_PkcsPad(byte* buf, int sz, int blockSz)
{
/* Calculate number of padding bytes. */
int padSz = blockSz - (sz & (blockSz - 1));

/* Pad with padSz byte. */
if (buf != NULL) {
int i;
for (i = 0; i < padSz; i++) {
buf[sz+i] = (byte)(padSz & 0xFF);
}
}

/* Return padded buffer size in bytes. */
return sz + padSz;
}

#ifndef NO_RSA
#ifdef WOLFSSL_ASN_TEMPLATE
/* ASN.1 template for an RSA public key.
Expand Down
24 changes: 4 additions & 20 deletions wolfcrypt/src/pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -8706,14 +8706,7 @@ int wc_PKCS7_SetContentType(wc_PKCS7* pkcs7, byte* contentType, word32 sz)
/* return size of padded data, padded to blockSz chunks, or negative on error */
int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
{
word32 padSz;

if (blockSz == 0)
return BAD_FUNC_ARG;

padSz = blockSz - (inputSz % blockSz);

return (int)padSz;
return wc_PkcsPad(NULL, inputSz, blockSz);
}


Expand All @@ -8723,27 +8716,18 @@ int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
word32 blockSz)
{
int ret;
word32 i, padSz;
word32 i;

if (in == NULL || inSz == 0 ||
out == NULL || outSz == 0)
return BAD_FUNC_ARG;

ret = wc_PKCS7_GetPadSize(inSz, blockSz);
if (ret < 0)
return ret;
padSz = (word32)ret;

if (outSz < (inSz + padSz))
if (outSz < (word32)wc_PkcsPad(NULL, inSz, blockSz))
return BAD_FUNC_ARG;

XMEMCPY(out, in, inSz);

for (i = 0; i < padSz; i++) {
out[inSz + i] = (byte)padSz;
}

return (int)(inSz + padSz);
return wc_PkcsPad(out, inSz, blockSz);
}


Expand Down
28 changes: 28 additions & 0 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3065,6 +3065,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void)
struct tm timearg;
time_t now;
#endif
int i;
unsigned char buf[16];

WOLFSSL_ENTER("asn_test");

ret = wc_GetDateInfo(dateBuf, (int)sizeof(dateBuf), &datePart, &format,
Expand Down Expand Up @@ -3093,6 +3096,31 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void)
return WC_TEST_RET_ENC_EC(ret);
#endif /* !NO_ASN_TIME */

/* Test that only calculating the length works. */
for (i = 16; i < 32; i++) {
ret = wc_PkcsPad(NULL, i, 16);
if (ret != i + (16 - (i % 16)))
return WC_TEST_RET_ENC_I(i);
}

/* Test that adding padding works. */
XMEMSET(buf, 0xa5, sizeof(buf));
for (i = 15; i >= 0; i--) {
int j;
ret = wc_PkcsPad(buf, i, 16);
if (ret != 16)
return WC_TEST_RET_ENC_I(i);
/* Check padded buffer. */
for (j = 0; j < 16; j++) {
/* Check buffer bytes haven't been modified. */
if ((j < i) && (buf[j] != 0xa5))
return WC_TEST_RET_ENC_I(i);
/* Check padding bytes are correct. */
if (j >= i && (buf[j] != (16 - i)))
return WC_TEST_RET_ENC_I(i);
}
}

return 0;
}
#endif /* !NO_ASN */
Expand Down
2 changes: 2 additions & 0 deletions wolfssl/wolfcrypt/asn_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
word32 outputSz, byte *cipherIno, int type);
#endif

WOLFSSL_API int wc_PkcsPad(byte* buf, int sz, int blockSz);

#ifndef NO_RSA
WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);
Expand Down

0 comments on commit 9aada6f

Please sign in to comment.