Browse Source

Merge pull request #7053 from douzzer/20231208-asn-big-short-ints

20231208-asn-big-short-ints
Sean Parkinson 4 months ago
parent
commit
1aed438a21
4 changed files with 66 additions and 74 deletions
  1. 18 31
      wolfcrypt/src/asn.c
  2. 30 20
      wolfcrypt/src/evp.c
  3. 4 13
      wolfcrypt/test/test.c
  4. 14 10
      wolfssl/wolfcrypt/asn.h

+ 18 - 31
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 < MAX_LENGTH_SZ && idx < maxIdx; i++) {
-        input[idx++] = ar[i]; len++;
-    }
+    for (i = (int)len - 1; i >= 0; --i)
+        output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE));
 
-    /* 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 */

+ 30 - 20
wolfcrypt/src/evp.c

@@ -146,14 +146,16 @@ static const struct s_ent {
     #endif
     #endif /* WOLFSSL_AES_OFB */
 
-    #ifdef WOLFSSL_AES_XTS
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
         static const char EVP_AES_128_XTS[] = "AES-128-XTS";
     #endif
     #ifdef WOLFSSL_AES_256
         static const char EVP_AES_256_XTS[] = "AES-256-XTS";
     #endif
-    #endif /* WOLFSSL_AES_XTS */
+    #endif /* WOLFSSL_AES_XTS &&
+              (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 
     #ifdef WOLFSSL_AES_CFB
     #ifdef WOLFSSL_AES_128
@@ -330,7 +332,7 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
       case AES_192_OFB_TYPE: return 24;
       case AES_256_OFB_TYPE: return 32;
   #endif
-  #if defined(WOLFSSL_AES_XTS)
+  #if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
       /* Two keys for XTS. */
       case AES_128_XTS_TYPE: return 16 * 2;
       case AES_256_XTS_TYPE: return 32 * 2;
@@ -632,7 +634,7 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
                 ret = wc_AesCfbDecrypt(&ctx->cipher.aes, out, in, inl);
             break;
     #endif
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     case AES_128_XTS_TYPE:
     case AES_256_XTS_TYPE:
         if (ctx->enc)
@@ -1703,7 +1705,7 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)
     case AES_192_OFB_TYPE:
     case AES_256_OFB_TYPE:
 #endif
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     case AES_128_XTS_TYPE:
     case AES_256_XTS_TYPE:
 #endif
@@ -1831,7 +1833,7 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)
         return AES_256_ECB_TYPE;
     #endif
 #endif /*HAVE_AES_CBC */
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
     else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_AES_128_XTS))
         return AES_128_XTS_TYPE;
@@ -1997,7 +1999,8 @@ int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)
         case AES_256_OFB_TYPE:
             return 1;
     #endif
-    #if defined(WOLFSSL_AES_XTS)
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
         case AES_128_XTS_TYPE:
         case AES_256_XTS_TYPE:
             return 1;
@@ -2106,7 +2109,8 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
         case AES_256_OFB_TYPE:
             return WOLFSSL_EVP_CIPH_OFB_MODE;
     #endif
-    #if defined(WOLFSSL_AES_XTS)
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
         case AES_128_XTS_TYPE:
         case AES_256_XTS_TYPE:
             return WOLFSSL_EVP_CIPH_XTS_MODE;
@@ -4852,7 +4856,8 @@ static const struct cipher{
     #endif
     #endif
 
-    #ifdef WOLFSSL_AES_XTS
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
     {AES_128_XTS_TYPE, EVP_AES_128_XTS, NID_aes_128_xts},
     #endif
@@ -5565,7 +5570,8 @@ void wolfSSL_EVP_init(void)
     #endif /* WOLFSSL_AES_256 */
     #endif /* WOLFSSL_AES_OFB */
 
-    #ifdef WOLFSSL_AES_XTS
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
     const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void)
     {
@@ -5581,7 +5587,8 @@ void wolfSSL_EVP_init(void)
         return EVP_AES_256_XTS;
     }
     #endif /* WOLFSSL_AES_256 */
-    #endif /* WOLFSSL_AES_XTS */
+    #endif /* WOLFSSL_AES_XTS &&
+              (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 
     #ifdef HAVE_AESGCM
     #ifdef WOLFSSL_AES_128
@@ -6135,7 +6142,8 @@ void wolfSSL_EVP_init(void)
                     wc_AesFree(&ctx->cipher.aes);
                     ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED;
                     break;
-    #ifdef WOLFSSL_AES_XTS
+    #if defined(WOLFSSL_AES_XTS) && \
+        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
                 case AES_128_XTS_TYPE:
                 case AES_256_XTS_TYPE:
                     wc_AesXtsFree(&ctx->cipher.xts);
@@ -7465,7 +7473,8 @@ void wolfSSL_EVP_init(void)
         }
         #endif /* WOLFSSL_AES_256 */
     #endif /* WOLFSSL_AES_OFB */
-    #ifdef WOLFSSL_AES_XTS
+        #if defined(WOLFSSL_AES_XTS) && \
+            (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
         #ifdef WOLFSSL_AES_128
         if (ctx->cipherType == AES_128_XTS_TYPE ||
             (type && EVP_CIPHER_TYPE_MATCHES(type, EVP_AES_128_XTS))) {
@@ -7548,7 +7557,8 @@ void wolfSSL_EVP_init(void)
             }
         }
         #endif /* WOLFSSL_AES_256 */
-    #endif /* WOLFSSL_AES_XTS */
+    #endif /* WOLFSSL_AES_XTS &&
+              (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 #endif /* NO_AES */
     #if defined(HAVE_ARIA)
         if (ctx->cipherType == ARIA_128_GCM_TYPE ||
@@ -8210,7 +8220,7 @@ void wolfSSL_EVP_init(void)
                     ret = (int)len;
                 break;
 #endif /* WOLFSSL_AES_OFB */
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
             case AES_128_XTS_TYPE:
             case AES_256_XTS_TYPE:
                 WOLFSSL_MSG("AES XTS");
@@ -8223,7 +8233,7 @@ void wolfSSL_EVP_init(void)
                 if (ret == 0)
                     ret = (int)len;
                 break;
-#endif /* WOLFSSL_AES_XTS */
+#endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 
 #if defined(HAVE_AESGCM) && ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) \
     || FIPS_VERSION_GE(2,0))
@@ -9309,12 +9319,12 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
             WOLFSSL_MSG("AES OFB");
             return AES_BLOCK_SIZE;
 #endif /* WOLFSSL_AES_OFB */
-#ifdef WOLFSSL_AES_XTS
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
         case AES_128_XTS_TYPE:
         case AES_256_XTS_TYPE:
             WOLFSSL_MSG("AES XTS");
             return AES_BLOCK_SIZE;
-#endif /* WOLFSSL_AES_XTS */
+#endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 #ifdef HAVE_ARIA
         case ARIA_128_GCM_TYPE :
         case ARIA_192_GCM_TYPE :
@@ -9438,7 +9448,7 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
         return AES_BLOCK_SIZE;
     #endif
 #endif
-#ifdef WOLFSSL_AES_XTS
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
     if (XSTRCMP(name, EVP_AES_128_XTS) == 0)
         return AES_BLOCK_SIZE;
@@ -9448,7 +9458,7 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
     if (XSTRCMP(name, EVP_AES_256_XTS) == 0)
         return AES_BLOCK_SIZE;
     #endif /* WOLFSSL_AES_256 */
-#endif /* WOLFSSL_AES_XTS */
+#endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */
 
 #endif
 #ifdef HAVE_ARIA

+ 4 - 13
wolfcrypt/test/test.c

@@ -9358,7 +9358,8 @@ static wc_test_ret_t aes_key_size_test(void)
     return ret;
 }
 
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
+
 /* test vectors from http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html */
 #ifdef WOLFSSL_AES_128
 static wc_test_ret_t aes_xts_128_test(void)
@@ -9435,8 +9436,6 @@ static wc_test_ret_t aes_xts_128_test(void)
         0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a
     };
 
-#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)
-
     WOLFSSL_SMALL_STACK_STATIC unsigned char k3[] = {
         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
@@ -9462,8 +9461,6 @@ static wc_test_ret_t aes_xts_128_test(void)
         0xB5, 0x5A, 0xDD, 0xCB, 0x80, 0xE0, 0xFC, 0xCD
     };
 
-#endif /* !HAVE_FIPS || FIPS_VERSION_GE(5,3) */
-
 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
     if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL)
         ERROR_OUT(WC_TEST_RET_ENC_ERRNO, out);
@@ -9641,8 +9638,6 @@ static wc_test_ret_t aes_xts_128_test(void)
     if (XMEMCMP(p2, buf, sizeof(p2)))
         ERROR_OUT(WC_TEST_RET_ENC_NC, out);
 
-#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)
-
     /* Test ciphertext stealing in-place. */
     XMEMCPY(buf, p3, sizeof(p3));
     ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION);
@@ -9670,10 +9665,7 @@ static wc_test_ret_t aes_xts_128_test(void)
     if (XMEMCMP(p3, buf, sizeof(p3)))
         ERROR_OUT(WC_TEST_RET_ENC_NC, out);
 
-#endif /* !HAVE_FIPS || FIPS_VERSION_GE(5,3) */
-
 #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \
-    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) &&     \
     !defined(WOLFSSL_AFALG)
     {
     #define LARGE_XTS_SZ        1024
@@ -9726,7 +9718,6 @@ static wc_test_ret_t aes_xts_128_test(void)
     #endif
     }
 #endif /* !BENCH_EMBEDDED && !HAVE_CAVIUM &&
-        * (!HAVE_FIPS || FIPS_VERSION_GE(5,3)) &&
         * !WOLFSSL_AFALG
         */
 
@@ -10332,7 +10323,7 @@ static wc_test_ret_t aes_xts_args_test(void)
     return ret;
 }
 #endif /* WOLFSSL_AES_128 */
-#endif /* WOLFSSL_AES_XTS */
+#endif /* WOLFSSL_AES_XTS && (!HAVE_FIPS || FIPS_VERSION_GE(5,3)) */
 
 #if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
 static wc_test_ret_t aes_cbc_test(void)
@@ -11706,7 +11697,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_test(void)
         goto out;
 #endif
 
-#if defined(WOLFSSL_AES_XTS)
+#if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
     #ifdef WOLFSSL_AES_128
     ret = aes_xts_128_test();
     if (ret != 0)

+ 14 - 10
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. */