forked from wolfSSL/wolfssl
Merge pull request #8502 from SparkiDev/pkcs_pad
PKCS Pad: public API to do PKCS padding
This commit is contained in:
@@ -9210,26 +9210,6 @@ int ToTraditionalEnc(byte* input, word32 sz, const char* password,
|
|||||||
|
|
||||||
#ifdef HAVE_PKCS12
|
#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
|
#ifdef WOLFSSL_ASN_TEMPLATE
|
||||||
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
|
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
|
||||||
* PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
|
* PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
|
||||||
@@ -9339,7 +9319,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
|
|
||||||
/* calculate size */
|
/* calculate size */
|
||||||
/* size of constructed string at end */
|
/* 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 = ASN_TAG_SZ;
|
||||||
totalSz += SetLength(sz, seq);
|
totalSz += SetLength(sz, seq);
|
||||||
totalSz += sz;
|
totalSz += sz;
|
||||||
@@ -9435,7 +9415,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
|
out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
|
||||||
|
|
||||||
/* get pad size and verify buffer room */
|
/* 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) {
|
if (sz + inOutIdx > *outSz) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@@ -9446,7 +9426,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
|
|
||||||
/* copy input to output buffer and pad end */
|
/* copy input to output buffer and pad end */
|
||||||
XMEMCPY(out + inOutIdx, input, inputSz);
|
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
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (cbcIv == NULL) {
|
if (cbcIv == NULL) {
|
||||||
@@ -9520,7 +9500,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
salt, saltSz);
|
salt, saltSz);
|
||||||
SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER],
|
SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER],
|
||||||
(word16)itt);
|
(word16)itt);
|
||||||
pkcs8Sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
|
pkcs8Sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
|
||||||
SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
|
SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
|
||||||
|
|
||||||
/* Calculate size of encoding. */
|
/* Calculate size of encoding. */
|
||||||
@@ -9558,7 +9538,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
byte* pkcs8 =
|
byte* pkcs8 =
|
||||||
(byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
|
(byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
|
||||||
XMEMCPY(pkcs8, input, inputSz);
|
XMEMCPY(pkcs8, input, inputSz);
|
||||||
Pkcs8Pad(pkcs8, (int)inputSz, blockSz);
|
(void)wc_PkcsPad(pkcs8, inputSz, (word32)blockSz);
|
||||||
|
|
||||||
/* Encrypt PKCS#8 key inline. */
|
/* Encrypt PKCS#8 key inline. */
|
||||||
ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
|
ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
|
||||||
@@ -9578,6 +9558,36 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
|
|||||||
#endif /* HAVE_PKCS12 */
|
#endif /* HAVE_PKCS12 */
|
||||||
#endif /* NO_PWDBASED */
|
#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
|
#ifndef NO_RSA
|
||||||
#ifdef WOLFSSL_ASN_TEMPLATE
|
#ifdef WOLFSSL_ASN_TEMPLATE
|
||||||
/* ASN.1 template for an RSA public key.
|
/* ASN.1 template for an RSA public key.
|
||||||
|
@@ -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 */
|
/* return size of padded data, padded to blockSz chunks, or negative on error */
|
||||||
int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
|
int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
|
||||||
{
|
{
|
||||||
word32 padSz;
|
|
||||||
|
|
||||||
if (blockSz == 0)
|
if (blockSz == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
padSz = blockSz - (inputSz % blockSz);
|
return (int)(blockSz - (inputSz % blockSz));
|
||||||
|
|
||||||
return (int)padSz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -8722,28 +8718,16 @@ int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
|
|||||||
int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
|
int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
|
||||||
word32 blockSz)
|
word32 blockSz)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
word32 i, padSz;
|
|
||||||
|
|
||||||
if (in == NULL || inSz == 0 ||
|
if (in == NULL || inSz == 0 ||
|
||||||
out == NULL || outSz == 0)
|
out == NULL || outSz == 0 || blockSz == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
ret = wc_PKCS7_GetPadSize(inSz, blockSz);
|
if (outSz < wc_PkcsPad(NULL, inSz, blockSz))
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
padSz = (word32)ret;
|
|
||||||
|
|
||||||
if (outSz < (inSz + padSz))
|
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
XMEMCPY(out, in, inSz);
|
XMEMCPY(out, in, inSz);
|
||||||
|
|
||||||
for (i = 0; i < padSz; i++) {
|
return (int)wc_PkcsPad(out, inSz, blockSz);
|
||||||
out[inSz + i] = (byte)padSz;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)(inSz + padSz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3065,6 +3065,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void)
|
|||||||
struct tm timearg;
|
struct tm timearg;
|
||||||
time_t now;
|
time_t now;
|
||||||
#endif
|
#endif
|
||||||
|
int i;
|
||||||
|
unsigned char buf[16];
|
||||||
|
|
||||||
WOLFSSL_ENTER("asn_test");
|
WOLFSSL_ENTER("asn_test");
|
||||||
|
|
||||||
ret = wc_GetDateInfo(dateBuf, (int)sizeof(dateBuf), &datePart, &format,
|
ret = wc_GetDateInfo(dateBuf, (int)sizeof(dateBuf), &datePart, &format,
|
||||||
@@ -3093,6 +3096,31 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void)
|
|||||||
return WC_TEST_RET_ENC_EC(ret);
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
#endif /* !NO_ASN_TIME */
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* !NO_ASN */
|
#endif /* !NO_ASN */
|
||||||
|
@@ -729,6 +729,8 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
|
|||||||
word32 outputSz, byte *cipherIno, int type);
|
word32 outputSz, byte *cipherIno, int type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
WOLFSSL_API word32 wc_PkcsPad(byte* buf, word32 sz, word32 blockSz);
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
|
WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
|
||||||
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);
|
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);
|
||||||
|
Reference in New Issue
Block a user