Skip to content

Commit

Permalink
Merge pull request #8502 from SparkiDev/pkcs_pad
Browse files Browse the repository at this point in the history
PKCS Pad: public API to do PKCS padding
  • Loading branch information
dgarske authored Feb 26, 2025
2 parents 307b71c + f204ac8 commit 92ed003
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 = wc_PkcsPad(NULL, inputSz, (word32)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 = wc_PkcsPad(NULL, inputSz, (word32)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 = wc_PkcsPad(out + inOutIdx, inputSz, (word32)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 = wc_PkcsPad(NULL, inputSz, (word32)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);
(void)wc_PkcsPad(pkcs8, inputSz, (word32)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.
*/
word32 wc_PkcsPad(byte* buf, word32 sz, word32 blockSz)
{
/* Calculate number of padding bytes. */
word32 padSz = blockSz - (sz & (blockSz - 1));

/* Pad with padSz byte. */
if (buf != NULL) {
word32 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,10 @@ 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 (int)(blockSz - (inputSz % blockSz));
}


Expand All @@ -8722,28 +8718,16 @@ int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
word32 blockSz)
{
int ret;
word32 i, padSz;

if (in == NULL || inSz == 0 ||
out == NULL || outSz == 0)
out == NULL || outSz == 0 || blockSz == 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 < 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 (int)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 word32 wc_PkcsPad(byte* buf, word32 sz, word32 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 92ed003

Please sign in to comment.