Skip to content

Commit 9c17d5d

Browse files
committed
support ASN ShortInts up to 4 bytes (2^32-1):
* parameterize MAX_LENGTH_SZ using overrideable WOLFSSL_ASN_MAX_LENGTH_SZ, default value 5 (raised from 4). * refactor other Misc_ASN constants to refer to MAX_LENGTH_SZ as appropriate. * tweak BytePrecision() appropriately. * refactor SetShortInt() to use BytePrecision() and include a length assert against MAX_SHORT_SZ to assure no buffer overruns with reduced WOLFSSL_ASN_MAX_LENGTH_SZ.
1 parent 03a8271 commit 9c17d5d

2 files changed

Lines changed: 32 additions & 41 deletions

File tree

wolfcrypt/src/asn.c

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,14 @@ static const char* TagString(byte tag)
315315

316316

317317
/* Calculates the minimum number of bytes required to encode the value.
318-
*
319-
* Only support up to 2^24-1.
320318
*
321319
* @param [in] value Value to be encoded.
322320
* @return Number of bytes to encode value.
323321
*/
324322
static word32 BytePrecision(word32 value)
325323
{
326324
word32 i;
327-
for (i = (word32)sizeof(value) - 1; i; --i)
325+
for (i = (word32)sizeof(value); i; --i)
328326
if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
329327
break;
330328

@@ -3139,46 +3137,35 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
31393137
defined(HAVE_PKCS12)
31403138
/* Set small integer, 32 bits or less. DER encoding with no leading 0s
31413139
* returns total amount written including ASN tag and length byte on success */
3142-
int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)
3140+
int SetShortInt(byte* output, word32* inOutIdx, word32 number, word32 maxIdx)
31433141
{
31443142
word32 idx = *inOutIdx;
3145-
int len = 0;
3143+
word32 len;
31463144
int i;
3147-
byte ar[MAX_LENGTH_SZ];
31483145

3149-
/* check for room for type and length bytes */
3150-
if ((idx + 2) > maxIdx)
3146+
if (number == 0)
3147+
len = 1;
3148+
else
3149+
len = BytePrecision(number);
3150+
3151+
/* check for room for type and length bytes. */
3152+
if ((idx + 2 + len) > maxIdx)
31513153
return BUFFER_E;
31523154

3153-
input[idx++] = ASN_INTEGER;
3154-
idx++; /* place holder for length byte */
3155-
if (MAX_LENGTH_SZ + idx > maxIdx)
3155+
/* check that MAX_SHORT_SZ allows this size of ShortInt. */
3156+
if (2 + len > MAX_SHORT_SZ)
31563157
return ASN_PARSE_E;
31573158

3158-
/* find first non zero byte */
3159-
XMEMSET(ar, 0, MAX_LENGTH_SZ);
3160-
c32toa(number, ar);
3161-
for (i = 0; i < MAX_LENGTH_SZ; i++) {
3162-
if (ar[i] != 0) {
3163-
break;
3164-
}
3165-
}
3159+
output[idx++] = ASN_INTEGER;
3160+
output[idx++] = (byte)len;
31663161

3167-
/* handle case of 0 */
3168-
if (i == MAX_LENGTH_SZ) {
3169-
input[idx++] = 0; len++;
3170-
}
3171-
3172-
for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
3173-
input[idx++] = ar[i]; len++;
3174-
}
3162+
for (i = (int)len - 1; i >= 0; --i)
3163+
output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE));
31753164

3176-
/* jump back to beginning of input buffer using unaltered inOutIdx value
3177-
* and set number of bytes for integer, then update the index value */
3178-
input[*inOutIdx + 1] = (byte)len;
3165+
len = idx - *inOutIdx;
31793166
*inOutIdx = idx;
31803167

3181-
return len + 2; /* size of integer bytes plus ASN TAG and length byte */
3168+
return (int)len;
31823169
}
31833170
#endif /* !WOLFSSL_ASN_TEMPLATE || HAVE_PKCS8 || HAVE_PKCS12 */
31843171
#endif /* !NO_PWDBASED */

wolfssl/wolfcrypt/asn.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,10 @@ enum ECC_TYPES
901901
/* Maximum OID dotted form size. */
902902
#define ASN1_OID_DOTTED_MAX_SZ 16
903903

904+
#ifndef WOLFSSL_ASN_MAX_LENGTH_SZ
905+
#define WOLFSSL_ASN_MAX_LENGTH_SZ 5 /* 1 byte length + 4 bytes of number */
906+
#endif
907+
904908
enum Misc_ASN {
905909
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
906910
MAX_IV_SIZE = 64, /* MAX PKCS Iv length */
@@ -943,18 +947,18 @@ enum Misc_ASN {
943947
#endif
944948
MAX_SIG_SZ = 256,
945949
MAX_ALGO_SZ = 20,
946-
MAX_SHORT_SZ = 6, /* asn int + byte len + 4 byte length */
947-
MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */
948-
MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */
949-
MAX_SET_SZ = 5, /* enum(set | con) + length(4) */
950-
MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */
951-
MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */
952-
MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */
950+
MAX_LENGTH_SZ = WOLFSSL_ASN_MAX_LENGTH_SZ, /* Max length size for DER encoding */
951+
MAX_SHORT_SZ = (1 + MAX_LENGTH_SZ), /* asn int + byte len + 4 byte length */
952+
MAX_SEQ_SZ = (1 + MAX_LENGTH_SZ), /* enum(seq | con) + length(5) */
953+
MAX_SET_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */
954+
MAX_OCTET_STR_SZ = (1 + MAX_LENGTH_SZ), /* enum(set | con) + length(5) */
955+
MAX_EXP_SZ = (1 + MAX_LENGTH_SZ), /* enum(contextspec|con|exp) + length(5) */
956+
MAX_PRSTR_SZ = (1 + MAX_LENGTH_SZ), /* enum(prstr) + length(5) */
953957
MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/
954-
MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */
958+
MAX_ENCODED_DIG_ASN_SZ = (5 + MAX_LENGTH_SZ), /* enum(bit or octet) + length(5) */
955959
MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */
956-
MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */
957-
MAX_DSA_INT_SZ = 389, /* DSA raw sz 3072 for bits + tag + len(4) */
960+
MAX_RSA_INT_SZ = (512 + 1 + MAX_LENGTH_SZ), /* RSA raw sz 4096 for bits + tag + len(5) */
961+
MAX_DSA_INT_SZ = (384 + 1 + MAX_LENGTH_SZ), /* DSA raw sz 3072 for bits + tag + len(5) */
958962
MAX_DSA_PUBKEY_SZ = (DSA_PUB_INTS * MAX_DSA_INT_SZ) + (2 * MAX_SEQ_SZ) +
959963
2 + MAX_LENGTH_SZ, /* Maximum size of a DSA public
960964
key taken from wc_SetDsaPublicKey. */

0 commit comments

Comments
 (0)