This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Need support for RSA crypto algorithm for Digital Signature

Hi Team,

For our development we are using the nRF52840 soc, We need the some example code or some project which will explains the Usage of RSA algorithm and supported API's for Digital Signature generation and Verification.

Currently we have Crypto backend (CC310, uECC, Oberon, mbed TLS) examples programs which is covering the ECC(ECDSA, ECDH) with supported ECC Curves. We need the some example code which supports the RSA.

It would be more helpful to us if we have any reference projest on RSA.

Regards,

Srinivas.V

Parents
  • Hi,

    The only RSA example in the nRF5 SDK is the RSA CryptoCell integration test (<nRF5 SDK>\examples\crypto\nrf_cc310\rsa\).

  • Hi Einar,

    Thanks for your reply.

    we have taken the code base from the "SDK>\examples\crypto\nrf_cc310\rsa", and ported into my application.

    After porting the code we are seeing some weird behaviour in some of the API's.

    The API's which are calculating the HASH as part of the API itself are not working and for the API's which are taking SHA Digest value as external are working fine.

    Not Working API's, we are getting the error code like 0x00F00441

    ==============================

    1. CRYS_RSA_PSS_Sign(rndState_ptr, rndGenerateVectFunc, UserContext_ptr,UserPrivKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr)

    CRYS_RSA_PSS_Verify(UserContext_ptr,UserPubKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Sig_ptr)

    2. CRYS_RSA_PKCS1v15_Sign(rndState_ptr, rndGenerateVectFunc, UserContext_ptr,UserPrivKey_ptr,hashFunc,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr)

    CRYS_RSA_PKCS1v15_Verify(UserContext_ptr,UserPubKey_ptr,hashFunc,DataIn_ptr,DataInSize,Sig_ptr)

    Working API's:

    =================

    1. CRYS_RSA_PKCS1v15_SHA256_Sign(rndState_ptr, rndGenerateVectFunc, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)

    CRYS_RSA_PKCS1v15_SHA256_Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)

    2. CRYS_RSA_PSS_SHA1_Sign(rndState_ptr, rndGenerateVectFunc, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)

    CRYS_RSA_PSS_SHA1_Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)

    we have taken the reference code from example project only.

    Is there any additional settings required in "sdk_config.h"  file related to SHA calculation or any other settings required to make it work for other API's.

    In example project i seen in one of the API we are sending the wrong argument like,

    CRYS_RSA_PKCS1v15_SHA512_Sign() , we are sending the "rsaSignVerifyDataVectors[test_index].rsaSignVerify_hash_SHA256" as a argument instead of "rsaSignVerify_hash_SHA512"

    Is there any example for RSA Library with Oberon also very helpful to us.

    Is there any timing analysis for this RSA library as compared to ECC Oberon or other libraries is more helpuful to us.

    Regards,

    Srnivas.V

  • Hi Srinivas,

    Srinivas V said:
    Not Working API's, we are getting the error code like 0x00F00441

    Can you specify exactly which function call returned 0x00F00441?

    Srinivas V said:

    we have taken the reference code from example project only.

    Is there any additional settings required in "sdk_config.h"  file related to SHA calculation or any other settings required to make it work for other API's.

    In example project i seen in one of the API we are sending the wrong argument like,

    The CC310 integration tests that demonstrate this require no specific changed in sdk_config.h, so that should not be the problem. If you do the same as the integration tests, it should run in your firmware as well. If you do not make progress it would be good if you can share the failing code.

    Srinivas V said:
    Is there any example for RSA Library with Oberon also very helpful to us.

    There are no examples for RSA using Oberon, but you are right it is supported. You can refer to <SDK 17>\external\nrf_oberon\include\occ_rsa.h and <SDK 17>\external\nrf_oberon\include\occ_rsa_key.h for API documentation, though.

    Srinivas V said:
    Is there any timing analysis for this RSA library as compared to ECC Oberon or other libraries is more helpuful to us.

    I do not have comparison numbers for RSA, unfortunately.

  • Hi Einar,

    Once again thanks for your reply.

    1. Can you specify exactly which function call returned 0x00F00441?

     we are getting this error (CRYS_RSA_INVALID_SIGNATURE_BUFFER_SIZE - 0x00F00441) for the API's which are calculating the SHA as part of the API itself.

     eg: CRYS_RSA_PKCS1v15_Sign()

           CRYS_RSA_PSS_Sign()

    2. Here with i have added failing code. In return value we are getting this error.

    ActualSignatureSize = rsaSignVerifyDataVectors[test_index].rsaSignVerify_KeySize;
    
    			/*Call CRYS_RSA_PSS_Sign for PKCS#1 ver2.1 using SHA512*/
    			ret =  CRYS_RSA_PSS_Sign(rndState_ptr, rndGenerateVectFunc,
    				&ContextPrivate,
    				&UserPrivKey,
    				CRYS_RSA_HASH_SHA512_mode,
    				CRYS_PKCS1_MGF1,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_SaltLength,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_input_data,//DataIn_ptr,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_input_dataSize,//DataInSize,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture,//Output_ptr,
    				&ActualSignatureSize);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PSS_Sign failed with 0x%x \n",ret);
    				goto endRSA;
    			}
    			
    			
    			ActualSignatureSize = rsaSignVerifyDataVectors[test_index].rsaSignVerify_KeySize;
    
    			/*Call CRYS_RSA_PKCS1v15_Sign PKCS#1 ver1.5 to sign on input data*/
    			ret =  CRYS_RSA_PKCS1v15_Sign(rndState_ptr, rndGenerateVectFunc,
    				&ContextPrivate,
    				&UserPrivKey,
    				CRYS_RSA_HASH_SHA256_mode,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_input_data,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_input_dataSize,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture,
    				&ActualSignatureSize);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PKCS1v15_Sign failed with 0x%x \n",ret);
    				goto endRSA;
    			}
    			
    			

    We have taken the reference code from cc310 RSA example only. we haven't modified any code. Just added to my application.

    3. Working APi's, SHA is calculating external to API.

    ActualSignatureSize = rsaSignVerifyDataVectors[test_index].rsaSignVerify_KeySize;
    
    			/*Call CRYS_RSA_PSS_SHA1_Sign PKCS#1 ver2.1 to sign on precalculated hash input using SHA1*/
    			ret =  CRYS_RSA_PSS_SHA1_Sign(rndState_ptr, rndGenerateVectFunc,
    				&ContextPrivate,
    				&UserPrivKey,
    				CRYS_PKCS1_MGF1,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_SaltLength,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_hash_SHA1,//rsaSignVerify_input_data,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture,
    				&ActualSignatureSize);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PSS_SHA1_Sign failed with 0x%x \n",ret);
    				goto endRSA;
    			}
    
    			INTEG_TEST_PRINT("CRYS_RSA_PSS_SHA1_Sign passed \n");
    
    			/*Verify signed hash using SHA1*/
    			ret =  CRYS_RSA_PSS_SHA1_Verify(&ContextPub,
    				&UserPubKey,
    				CRYS_PKCS1_MGF1,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_SaltLength,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_hash_SHA1,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PSS_SHA1_Verify failed with 0x%x \n",ret);
    				goto endRSA;
    			}
    
    ret =  CRYS_RSA_PKCS1v15_SHA256_Sign(rndState_ptr, rndGenerateVectFunc,
    				&ContextPrivate,
    				&UserPrivKey,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_hash_SHA256,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture,
    				&ActualSignatureSize);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PKCS1v15_SHA256_Sign failed with 0x%x \n",ret);
    				goto endRSA;
    			}
    
    			INTEG_TEST_PRINT("CRYS_RSA_PKCS1v15_SHA256_Sign passed \n");
    
    
    			/*Verify the signature*/
    			ret =  CRYS_RSA_PKCS1v15_SHA256_Verify(&ContextPub,
    				&UserPubKey,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_hash_SHA256,
    				rsaSignVerifyDataVectors[test_index].rsaSignVerify_output_signiture);
    
    			if (ret != SA_SILIB_RET_OK){
    				INTEG_TEST_PRINT("CRYS_RSA_PKCS1v15_SHA256_Verify failed with 0x%x \n",ret);
    				goto endRSA;
    			}

    4. But the same code is working fine in as part of the example project. we have added the all required header files and include paths.

    Regards,

    Srinivas.V

  • Hi Srinivas,

    The only reason for getting the CRYS_RSA_INVALID_SIGNATURE_BUFFER_SIZE error is that you have specified a too small buffer size. I do not see the value of your input parameters as that is not part of your code snippets code snippets, but that must be the problem.

    Einar

  • Hi Einar,

    Thanks for your reply. I have cross checked in code for the buffer size. we are allocating the size which is given example project like 256

    Is there  any other things we need to take care.

    #define TST_MAX_PRVT_EXP_SIZE_IN_BYTES                              256
    
    typedef struct rsaSignVerifyDataStuct
    {	
        char				        rsaSignVerify_Name[MAX_TEST_DATA_SIZE];
        uint8_t 		                        rsaSignVerify_PrivetExponent_D[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
        uint8_t					rsaSignVerify_PublicExponent_E[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
        uint8_t					rsaSignVerify_Modulus_N[TST_MAX_MOD_SIZE_IN_BYTES];
        uint8_t					rsaSignVerify_P[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2]; 
        uint8_t					rsaSignVerify_Q[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];  	   
        uint8_t					rsaSignVerify_dP[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
        uint8_t					rsaSignVerify_dQ[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
        uint8_t					rsaSignVerify_Qinv[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];		  	
        uint16_t					rsaSignVerify_KeySize;
        uint16_t					rsaSignVerify_DPSize;
        uint16_t					rsaSignVerify_PubExponentSize; 
        uint16_t					rsaSignVerify_SaltLength;
        uint8_t 					rsaSignVerify_input_data[TST_MAX_SIGN_VERIFY_DATA_IN_BYTES];
        uint16_t 					rsaSignVerify_input_dataSize;
        uint8_t 					rsaSignVerify_output_signiture[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	
        uint8_t                   	                rsaSignVerify_hash_SHA1[CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES];
        uint8_t                   	                rsaSignVerify_hash_SHA256[CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES];
        uint8_t                   	                rsaSignVerify_hash_SHA512[CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES];
        
    } rsaSignVerifyDataStuct;
    
    uint8_trsaSignVerify_output_signiture[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	

    Regards,

    Srinivas.V

  • Hi Srinivas,

    Srinivas V said:

    Thanks for your reply. I have cross checked in code for the buffer size. we are allocating the size which is given example project like 256

    Is there  any other things we need to take care.

    I have checked the implementation in the runtime library, and a too small buffer is the only explanation for this. But please note that the library has no idea about the buffer size other than what you tell it. So I assume you pass the wrong length. I cannot say for sure without seeing more of your code, but my guess is that referring to the code in this post, you have the wrong value of ActualSignatureSize. This is a in/out variable, where you populate it with the buffer size before the call to CRYS_RSA_PSS_Sign(), and as an output it has the actual signature size.

    Einar

Reply
  • Hi Srinivas,

    Srinivas V said:

    Thanks for your reply. I have cross checked in code for the buffer size. we are allocating the size which is given example project like 256

    Is there  any other things we need to take care.

    I have checked the implementation in the runtime library, and a too small buffer is the only explanation for this. But please note that the library has no idea about the buffer size other than what you tell it. So I assume you pass the wrong length. I cannot say for sure without seeing more of your code, but my guess is that referring to the code in this post, you have the wrong value of ActualSignatureSize. This is a in/out variable, where you populate it with the buffer size before the call to CRYS_RSA_PSS_Sign(), and as an output it has the actual signature size.

    Einar

Children
No Data
Related