diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e89f3627b..3a8362b58 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3252,22 +3252,31 @@ int SetShortInt(byte* output, word32* inOutIdx, word32 number, word32 maxIdx) word32 idx = *inOutIdx; word32 len; int i; + word32 extraByte = 0; if (number == 0) len = 1; else len = BytePrecision(number); + if (number >> (WOLFSSL_BIT_SIZE * len - 1)) { + /* Need one byte of zero value not to be negative number */ + extraByte = 1; + } + /* check for room for type and length bytes. */ - if ((idx + 2 + len) > maxIdx) + if ((idx + 2 + extraByte + len) > maxIdx) return BUFFER_E; /* check that MAX_SHORT_SZ allows this size of ShortInt. */ - if (2 + len > MAX_SHORT_SZ) + if (2 + extraByte + len > MAX_SHORT_SZ) return ASN_PARSE_E; output[idx++] = ASN_INTEGER; - output[idx++] = (byte)len; + output[idx++] = (byte)(len + extraByte); + if (extraByte) { + output[idx++] = 0x00; + } for (i = (int)len - 1; i >= 0; --i) output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE)); @@ -9565,6 +9574,8 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz, word32 encIdx = 0; const byte* hmacOidBuf = NULL; word32 hmacOidBufSz = 0; + byte tmpShort[MAX_SHORT_SZ]; + word32 tmpIdx = 0; (void)heap; @@ -9587,9 +9598,14 @@ int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz, if (ret == 0) { padSz = (word32)((blockSz - ((int)keySz & (blockSz - 1))) & (blockSz - 1)); - /* inner = OCT salt INT itt */ - innerLen = 2 + saltSz + 2 + ((itt < 256) ? 1 : ((itt < 65536) ? 2 : 3)); - + ret = SetShortInt(tmpShort, &tmpIdx, (word32)itt, MAX_SHORT_SZ); + if (ret > 0) { + /* inner = OCT salt INT itt */ + innerLen = 2 + saltSz + (word32)ret; + ret = 0; + } + } + if (ret == 0) { if (version != PKCS5v2) { pbeOidBuf = OidFromId((word32)pbeId, oidPBEType, &pbeOidBufSz); /* pbe = OBJ pbse1 SEQ [ inner ] */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index afee382fd..986417439 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -2021,7 +2021,7 @@ enum Max_ASN { MAX_SIG_SZ = 256, MAX_ALGO_SZ = 20, MAX_LENGTH_SZ = WOLFSSL_ASN_MAX_LENGTH_SZ, /* Max length size for DER encoding */ - MAX_SHORT_SZ = (1 + MAX_LENGTH_SZ), /* asn int + byte len + 4 byte length */ + MAX_SHORT_SZ = (1 + 1 + 5), /* asn int + byte len + 5 byte length */ MAX_SEQ_SZ = (1 + MAX_LENGTH_SZ), /* enum(seq | con) + length(5) */ MAX_SET_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */ MAX_OCTET_STR_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */