diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 35b8add19..594b39074 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -315,8 +315,6 @@ static const char* TagString(byte tag) /* Calculates the minimum number of bytes required to encode the value. - * - * Only support up to 2^24-1. * * @param [in] value Value to be encoded. * @return Number of bytes to encode value. @@ -324,7 +322,7 @@ static const char* TagString(byte tag) static word32 BytePrecision(word32 value) { word32 i; - for (i = (word32)sizeof(value) - 1; i; --i) + for (i = (word32)sizeof(value); i; --i) if (value >> ((i - 1) * WOLFSSL_BIT_SIZE)) break; @@ -3139,46 +3137,35 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) defined(HAVE_PKCS12) /* Set small integer, 32 bits or less. DER encoding with no leading 0s * returns total amount written including ASN tag and length byte on success */ -int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx) +int SetShortInt(byte* output, word32* inOutIdx, word32 number, word32 maxIdx) { word32 idx = *inOutIdx; - int len = 0; + word32 len; int i; - byte ar[MAX_LENGTH_SZ]; - /* check for room for type and length bytes */ - if ((idx + 2) > maxIdx) + if (number == 0) + len = 1; + else + len = BytePrecision(number); + + /* check for room for type and length bytes. */ + if ((idx + 2 + len) > maxIdx) return BUFFER_E; - input[idx++] = ASN_INTEGER; - idx++; /* place holder for length byte */ - if (MAX_LENGTH_SZ + idx > maxIdx) + /* check that MAX_SHORT_SZ allows this size of ShortInt. */ + if (2 + len > MAX_SHORT_SZ) return ASN_PARSE_E; - /* find first non zero byte */ - XMEMSET(ar, 0, MAX_LENGTH_SZ); - c32toa(number, ar); - for (i = 0; i < MAX_LENGTH_SZ; i++) { - if (ar[i] != 0) { - break; - } - } + output[idx++] = ASN_INTEGER; + output[idx++] = (byte)len; - /* handle case of 0 */ - if (i == MAX_LENGTH_SZ) { - input[idx++] = 0; len++; - } + for (i = (int)len - 1; i >= 0; --i) + output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE)); - for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) { - input[idx++] = ar[i]; len++; - } - - /* jump back to beginning of input buffer using unaltered inOutIdx value - * and set number of bytes for integer, then update the index value */ - input[*inOutIdx + 1] = (byte)len; + len = idx - *inOutIdx; *inOutIdx = idx; - return len + 2; /* size of integer bytes plus ASN TAG and length byte */ + return (int)len; } #endif /* !WOLFSSL_ASN_TEMPLATE || HAVE_PKCS8 || HAVE_PKCS12 */ #endif /* !NO_PWDBASED */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 6cde834d5..351517e4b 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -901,6 +901,10 @@ enum ECC_TYPES /* Maximum OID dotted form size. */ #define ASN1_OID_DOTTED_MAX_SZ 16 +#ifndef WOLFSSL_ASN_MAX_LENGTH_SZ + #define WOLFSSL_ASN_MAX_LENGTH_SZ 5 /* 1 byte length + 4 bytes of number */ +#endif + enum Misc_ASN { MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */ MAX_IV_SIZE = 64, /* MAX PKCS Iv length */ @@ -943,18 +947,18 @@ enum Misc_ASN { #endif MAX_SIG_SZ = 256, MAX_ALGO_SZ = 20, - MAX_SHORT_SZ = 6, /* asn int + byte len + 4 byte length */ - MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */ - MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */ - MAX_SET_SZ = 5, /* enum(set | con) + length(4) */ - MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */ - MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */ - MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */ + 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_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) */ + MAX_EXP_SZ = (1 + MAX_LENGTH_SZ), /* enum(contextspec|con|exp) + length(5) */ + MAX_PRSTR_SZ = (1 + MAX_LENGTH_SZ), /* enum(prstr) + length(5) */ MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/ - MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */ + MAX_ENCODED_DIG_ASN_SZ = (5 + MAX_LENGTH_SZ), /* enum(bit or octet) + length(5) */ MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */ - MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */ - MAX_DSA_INT_SZ = 389, /* DSA raw sz 3072 for bits + tag + len(4) */ + MAX_RSA_INT_SZ = (512 + 1 + MAX_LENGTH_SZ), /* RSA raw sz 4096 for bits + tag + len(5) */ + MAX_DSA_INT_SZ = (384 + 1 + MAX_LENGTH_SZ), /* DSA raw sz 3072 for bits + tag + len(5) */ MAX_DSA_PUBKEY_SZ = (DSA_PUB_INTS * MAX_DSA_INT_SZ) + (2 * MAX_SEQ_SZ) + 2 + MAX_LENGTH_SZ, /* Maximum size of a DSA public key taken from wc_SetDsaPublicKey. */