Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PKCS Pad: public API to do PKCS padding #8502

Merged
merged 1 commit into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading