Skip to content

On 32-bit platform, ocsp.test to www.google.com may fail? #7929

Open
@mpsuzuki

Description

@mpsuzuki

Version

5.7.2

Description

It seems that the binaries built on/for 32-bit platforms have some troubles in OCSP.

ocsp.test differs on 64-bit platform and 32-bit platform

If I build binaries on GNU/Linux x86_64, scripts/ocsp.test finishes 2 tests: 1st for www.globalsign.com, 2nd for www.google.com. But if I build binaries for GNU/Linux i386, and Mac OS X 10.4 (running on PowerPC 32-bit), the 1st test passes, but the 2nd test fails by "ASN sig error".

Here I report the case of the binary built without single precision module (to compare with the result of PowerPC, a real 32-bit processor, but Mac OS X 10.4 assembler might be too buggy to compile single precision module, as reported in Issue #7905), but almost same error is found in the binary built with single precision module. The error occurs in fp_exptmod_nct(), by too big input length.

The beginning of the error happens in fp_exptmod_nct(), wolfcrypt/src/tfm.c:

3300 int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
3301 {
3302 #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3303    int retHW = FP_OKAY;
3304 #endif
3305
3306    /* handle modulus of zero and prevent overflows */
3307    if (fp_iszero(P) || (P->used > (FP_SIZE/2))) {
3308       return FP_VAL;
3309    }

If P->used is greater than (FP_SIZE / 2), fp_exptmod_nct() returns an error (if everything goes well, FP_OKAY would be returned).

GDB debugging script

I inspected the variables by following .gdbinit and traced the values for RsaFunctionSync() and fp_exptmod_nct().

break fp_exptmod_nct
commands
  silent
  printf "  fp_exptmod_nct(): P->used = %d, (FP_SIZE / 2) = %d\n", P->used, (FP_SIZE / 2)
  cont
end

break RsaFunctionSync
commands
  silent
  printf "RsaFunctionSync(): receive data with inLen = %d\n", inLen
  cont
end

GDB output for a passing case

Below is the passing output of the x86_64 platform. P->used is always less than (FP_SIZE / 2) == 68

(gdb) run -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
Starting program: /tmp/wolfssl-current/build-amd64-no-sp/examples/client/client -X -C -h www.google.com -p
 443 -A "certs/external/ca-google-root.pem" -g -o -N
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
... client would read block
... client would read block
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 512
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 32, (FP_SIZE / 2) = 68
... client would read block
Session Ticket CB: ticketSz = 229, ctx = initial session
...

GDB output for a failing case (i686 binary)

Below is the failing output of the cross-built i686 binary (running on x86_64 machine). P->used == 128 is greater than (FP_SIZE / 2) == 68.

(gdb) run -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
Starting program: /tmp/wolfssl-current/build-i686-no-sp/examples/client/client -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
... client would read block
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 512
  fp_exptmod_nct(): P->used = 128, (FP_SIZE / 2) = 68
wolfSSL_connect error -155, ASN sig error, confirm failure
wolfSSL error: wolfSSL_connect failed
[Inferior 1 (process 250925) exited with code 01]

GDB output for a failing case (PowerPC)

Below is the failing output of the PowerPC binary (running on MacOS X 10.4). Unfortunately, the last version of gdb ported to MacOS X/ppc cannot handle the preprocessor macro constants, I inserted an unused fp_size variable to copy FP_SIZE value.

(gdb) run -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
Starting program: /tmp/wolfssl-current/build-no-sp/examples/client/client -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
Reading symbols for shared libraries . done
... client would read block
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 68
RsaFunctionSync(): receive data with inLen = 512
  fp_exptmod_nct(): P->used = 128, (FP_SIZE / 2) = 68
wolfSSL_connect error -155, ASN sig error, confirm failure
wolfSSL error: wolfSSL_connect failed

Program exited with code 01.

NOTE: "gcc -m32" is not good to reproduce this error

Maybe, I should note that using "-m32" on 64-bit platforms is inappropriate in such testing, because this option does not change the proprocessor macros __x86_64__ or __aarch64__, thus, the bitwidth of the registers might be different from real 32-bit processor.

Below is the passing output of "-m32" binary built on the x86_64 platform.

(gdb) run -X -C -h www.google.com -p 443 -A "certs/external/ca-google-root.pem" -g -o -N
Starting program: /tmp/wolfssl-current/build-m32-no-sp/examples/client/client -X -C -h www.google.com -p 4
43 -A "certs/external/ca-google-root.pem" -g -o -N
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
... client would read block
... client would read block
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 512
  fp_exptmod_nct(): P->used = 128, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
RsaFunctionSync(): receive data with inLen = 256
  fp_exptmod_nct(): P->used = 64, (FP_SIZE / 2) = 132
... client would read block
Session Ticket CB: ticketSz = 229, ctx = initial session
...

QUESTION

In summary, FP_SIZE for both platform are same, it looks reasonable, but P->used on 32-bit platform is sometimes too big. On 64-bit platforms, P->used seems to be the one-eighth (1/8) of the inLen of RsaFunctionSync(). But on 32-bit platforms, P->used seems to be quarter (1/4) of the inLen of RsaFunctionSync().

Yet I could not find why they are different, which part of the code I should check?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions