SDK Casper ModExp API funtion giving completely false values

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDK Casper ModExp API funtion giving completely false values

649 Views
jesm86
Contributor II

Hello,

I am still working on RSA Modular Exponentiation using the Casper example. In the SDK example, which uses that API function, there are a 2048 bit signature (signature0), a 2048bit public key (i.e. the modulus, labeled pubkey0) and a plaintext given. This plaintext is supposed to be the correct result when you apply modular exponentiation using the given parameters together with the exponent 0x10001 (i.e. plaintext0 = signature0^(0x10001) mod pubkey0.

What I now found out is the fact, this plaintext may be the result using the API modular exponentiation, but as soon as I use the official openssl tool for modular exponentiation or a python script which does that, I get a totally different plaintext..

After further examination I realized that the openssl tool and the python script are consistent and both yield the same results when I use the same inputs. The only thing that gives different results is the Casper API function. If I create my own ciphertext using openssl, modular exponentiation (with the appropriate parameters) of this ciphertext using openssl or the python scripts also yields my own original plaintext again, while the SDK API somehow gives me nonsense values. So the one thing I know for a fact is, that openssl and python script are definitely working. the SDK API ModExp function is not..

 

Is this fact known is there a newer version or a fix for that?

 

Btw: I appended screenshots of the supposedly correct plaintext given in the SDK and the real plaintext which was given my openssl and python

0 Kudos
5 Replies

518 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I have contacted our AE team, if you suspect that the SDK result about RSA is wrong, pls provide the project including the python code and SDK project so that the AE team engineer can duplicate the result and check if the SDK code is correct or not.

BR

XiangJun Rong

0 Kudos

627 Views
jesm86
Contributor II

Hi,

thanks for the quick response.

I hope you can post the array in SDK.png as a text or post your code here even python code so that we can duplicate the issue.

It is difficult to construct the array with a picture format.

Yep, you're of course right. My first intention was just to ask if this is a known issue. Appearently not, so thanks for trying to duplicate it.

The SDK.png is a screenshot of the code exactly as it is in NXP's latest SDK Casper example for the LPC55S16 (the example name is "lpcxpresso55s16_casper"). But I can give you binary files containing the examples signature and modulus (pubkey0). I'll give you both modulus and signature in little and big endian format (I actually exported the data of the memory region containing these variables - so I think the little endian should be the one to use, but i wanted to exclude this as a possible cause of the different value and checked it nonetheless).

I'll also attack the python script which gives the same correct values as the openssl tool. Its a very basic implementation of RSA using the square and multiply algorithm.

 

Thanks in advance for checking it out and helping,

Jerome

0 Kudos

630 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I hope you can post the array in SDK.png as a text or post your code here even python code so that we can duplicate the issue.

It is difficult to construct the array with a picture format.

BR

XiangJun Rong

0 Kudos

598 Views
jesm86
Contributor II

I accidently posted my answer with your requested data not directly as a response to your post, but as a new response in the thread. Hope you still get a notification.

 

I was also looking into the code and noticed something that seemed odd to me:

In the MultprecMultiply(unsigned w_out[], const unsigned u[], const unsigned v[]) function that is used for transforming the signature into Montgomery Form (ModExp()->RSA_SignatureToPlaintextFast()->MultprecMontPrepareX()->MultprecMultiply()), the numbers u and v are multiplied using casper accelleration and the result stored in w_out, i.e. w_out = u * v.

/* Step 1. Fill w[t-1:0] with 0s, the upper half will be written as we go */
PreZeroW(i, w_out);

/* We do 1st pass NOSUM so we do not have to 0 output */
Accel_SetABCD_Addr(CA_MK_OFF(&v[0]), CA_MK_OFF(u));
Accel_crypto_mul(
  Accel_IterOpcodeResaddr(N_wordlen / 2U - 1U, (uint32_t)kCASPER_OpMul6464NoSum, CA_MK_OFF(&w_out[0])));
Accel_done();
/* Step 2. iterate over N words of v using j */
for (j = 2U; j < N_wordlen; j += 2U)
{
  /* Step 2b. Check for 0 on v word - skip if so since we 0ed already */
  /* Step 3. Iterate over N words of u using i - perform Multiply-accumulate */
  if (0U != (GET_WORD(&v[j])) || 0U != (GET_WORD(&v[j + 1U])))
  {
    Accel_SetABCD_Addr(CA_MK_OFF(&v[j]), CA_MK_OFF(u));
    Accel_crypto_mul(
    Accel_IterOpcodeResaddr(N_wordlen / 2U - 1U, (uint32_t)kCASPER_OpMul6464Sum, CA_MK_OFF(&w_out[j])));
    Accel_done();
  }
}

It iterates through all elements of the v[] array using the j iterator variable as stated in step2. According to step3, the same is later with all the elements of the u[] array using the i iterator. Where exactly is this happening? I see the multiply and accumulate of the casper acceleration engine (kCapser_OpMul6464Sum), but I dont see where the iteration through all elements of the 64 u[] array elements is happening?

Might the be the reason for the wrong result?

0 Kudos

537 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I have asked the security expert on security in AE team, I will post the answer shortly after I get reply.

BR

XiangJun Rong

0 Kudos