diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5476bc601..cd9f1d6ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,4 +52,5 @@ jobs: # uses: ./.github/workflows/haproxy.yml ocsp: uses: ./.github/workflows/ocsp.yml - + no-malloc: + uses: ./.github/workflows/no-malloc.yml diff --git a/.github/workflows/no-malloc.yml b/.github/workflows/no-malloc.yml new file mode 100644 index 000000000..70360fee6 --- /dev/null +++ b/.github/workflows/no-malloc.yml @@ -0,0 +1,34 @@ +name: No Malloc Tests + +on: + workflow_call: + +jobs: + make_check: + strategy: + matrix: + config: [ + # Add new configs here + '--enable-rsa --enable-keygen --disable-dh CFLAGS="-DWOLFSSL_NO_MALLOC"', + ] + name: make check + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 6 + steps: + - uses: actions/checkout@v4 + name: Checkout wolfSSL + + - name: Test wolfSSL + run: | + ./autogen.sh + ./configure ${{ matrix.config }} + make + ./wolfcrypt/test/testwolfcrypt + + - name: Print errors + if: ${{ failure() }} + run: | + if [ -f test-suite.log ] ; then + cat test-suite.log + fi diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9377297e9..3d80e8708 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -25937,11 +25937,16 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) { #ifndef WOLFSSL_ASN_TEMPLATE int ret = 0, i; + int mpSz; word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen = 0; word32 sizes[RSA_INTS]; byte seq[MAX_SEQ_SZ]; byte ver[MAX_VERSION_SZ]; + mp_int* keyInt; +#ifndef WOLFSSL_NO_MALLOC + word32 rawLen; byte* tmps[RSA_INTS]; +#endif if (key == NULL) return BAD_FUNC_ARG; @@ -25949,18 +25954,18 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) if (key->type != RSA_PRIVATE) return BAD_FUNC_ARG; +#ifndef WOLFSSL_NO_MALLOC for (i = 0; i < RSA_INTS; i++) tmps[i] = NULL; +#endif /* write all big ints from key to DER tmps */ for (i = 0; i < RSA_INTS; i++) { - mp_int* keyInt = GetRsaInt(key, i); - int mpSz; - word32 rawLen; - + keyInt = GetRsaInt(key, i); ret = mp_unsigned_bin_size(keyInt); if (ret < 0) - return ret; + break; +#ifndef WOLFSSL_NO_MALLOC rawLen = (word32)ret + 1; ret = 0; if (output != NULL) { @@ -25971,8 +25976,11 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) break; } } - mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]); +#else + ret = 0; + mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, NULL); +#endif if (mpSz < 0) { ret = mpSz; break; @@ -26004,15 +26012,33 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) j += verSz; for (i = 0; i < RSA_INTS; i++) { +/* copy from tmps if we have malloc, otherwise re-export with buffer */ +#ifndef WOLFSSL_NO_MALLOC XMEMCPY(output + j, tmps[i], sizes[i]); j += sizes[i]; +#else + keyInt = GetRsaInt(key, i); + ret = mp_unsigned_bin_size(keyInt); + if (ret < 0) + break; + ret = 0; + /* This won't overrun output due to the outLen check above */ + mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, output + j); + if (mpSz < 0) { + ret = mpSz; + break; + } + j += mpSz; +#endif } } +#ifndef WOLFSSL_NO_MALLOC for (i = 0; i < RSA_INTS; i++) { if (tmps[i]) XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA); } +#endif if (ret == 0) ret = (int)outLen; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 4299fd2f8..cca20c0d3 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4721,7 +4721,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif /* WOLFSSL_SMALL_STACK */ int i, failCount, isPrime = 0; word32 primeSz; +#ifndef WOLFSSL_NO_MALLOC byte* buf = NULL; +#else + /* RSA_MAX_SIZE is the size of n in bits. */ + byte buf[RSA_MAX_SIZE/16]; +#endif #endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */ int err; @@ -4827,12 +4832,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) primeSz = (word32)size / 16; /* size is the size of n in bits. primeSz is in bytes. */ +#ifndef WOLFSSL_NO_MALLOC /* allocate buffer to work with */ if (err == MP_OKAY) { buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA); if (buf == NULL) err = MEMORY_E; } +#endif SAVE_VECTOR_REGISTERS(err = _svr_ret;); @@ -4935,10 +4942,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if (err == MP_OKAY && !isPrime) err = PRIME_GEN_E; +#ifndef WOLFSSL_NO_MALLOC if (buf) { ForceZero(buf, primeSz); XFREE(buf, key->heap, DYNAMIC_TYPE_RSA); } +#else + ForceZero(buf, primeSz); +#endif if (err == MP_OKAY && mp_cmp(p, q) < 0) { err = mp_copy(p, tmp1); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 964fb6269..80e4e49fe 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -2125,7 +2125,11 @@ static wc_test_ret_t _SaveDerAndPem(const byte* der, int derSz, #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) XFILE pemFile; #endif + #ifndef WOLFSSL_NO_MALLOC byte* pem; + #else + byte pem[1024]; + #endif int pemSz; /* calculate PEM size */ @@ -2133,10 +2137,15 @@ static wc_test_ret_t _SaveDerAndPem(const byte* der, int derSz, if (pemSz < 0) { return WC_TEST_RET_ENC(calling_line, 2, WC_TEST_RET_TAG_I); } + #ifndef WOLFSSL_NO_MALLOC pem = (byte*)XMALLOC(pemSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { return WC_TEST_RET_ENC(calling_line, 3, WC_TEST_RET_TAG_I); } + #else + if (pemSz > (int)sizeof(pem)) + return BAD_FUNC_ARG; + #endif /* Convert to PEM */ pemSz = wc_DerToPem(der, derSz, pem, pemSz, pemType); if (pemSz < 0) { @@ -19001,7 +19010,11 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) RsaKey genKey[1]; #endif wc_test_ret_t ret; +#ifndef WOLFSSL_NO_MALLOC byte* der = NULL; +#else + byte der[1024]; +#endif #ifndef WOLFSSL_CRYPTOCELL word32 idx = 0; #endif @@ -19046,11 +19059,12 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif +#ifndef WOLFSSL_NO_MALLOC der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); } - +#endif derSz = wc_RsaKeyToDer(genKey, der, FOURK_BUF); if (derSz < 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(derSz), exit_rsa); @@ -19086,10 +19100,12 @@ exit_rsa: wc_FreeRsaKey(genKey); #endif +#ifndef WOLFSSL_NO_MALLOC if (der != NULL) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); der = NULL; } +#endif return ret; }