1
\$\begingroup\$

I'm trying to perform a decryption operation using RSA. I'm using the PolarSSl library. I have a char array key[] that contains RSA private key like the following,

N = D0C2ACDCF780B1E4846054BDA700F18D567247FE8BC5BA4FBCAB814E619DA63A20F65A58EE89FC0824DC9367C5725BDDC596065F1C8868E99C896F3A0CF7D7F0A785E668F2568F19BAFB8FF3BA5CDF487544EFE71010BEDB4EE16EDC3AF0A71391AD3194B42D3FD40B4E0DE12A22D8188AF03FF4E36D37BA1DA1F3C57188E60DA38C25329E48805FC7FF524761A6F010E737B927D8F67383274F8E600167A52A042E1DCA3335150C090803F9D96F6E63BEBFB153516E863F5B4CB02104077834FC5EC31A47451783931D643CE736DD1BAB40C5523858BB067FB9E490DCB5FDBBB03B9D68A8998C1347E237C477AA14B0997A84708CED05A9E24C7072B838F753
E = 010001
D = 21AFE07431CE47269083F8F8B7ABCBCEDA6DCB975457BE6662942C64091586FEE755C9A3832EAA0868665DB507A41A15F1EDF12E44ECF03D0E61111D457D730FA700D0FB0B6C13607C0F5F1DDDEB61AE9019E53A9C998F2AD5924430EEA3E9DA1B0E5F2B575DDBE86C4096B5C87661F7A7E7F7F21D0701509BBA881B4AE463F6F18C7F04AB742319E2D7319EECA136EEB0CF7B2BFA87E3A0E69FBC0E5FDC7EE6271EB2CA09DDBF7C8B57D951762708D76890E62858C1D5FC5B7E40D50913CE7797BD80F6A398FB92703FBDD33FBCB129B86E54F13EC14DA68BE139634DD1E9C01F01751C427B029AF629EED23C99726F0A0C3CEA1229E4099B588CE676975D25
P = FD1120F3E183DF72779B9B4A29FF9157C89FF8204988B6FB1211642B4D59B6A1BB306E81C040F0F822B41765FC4435A46B5090700E72B9720481EACF3624885D7A263CAC0CA559954E9382FCC7D57221CD9394C64585653664976174CAE2E7DC6A7B03DE09599B5D9501927ACC4EED5F5CBC5870E31A051AF9842945A0168E35
Q = D32E15E032B256C7DE0BDB585379EB897343ABFB8C7A86A3D798C13AE3E3F048A50DA9D7C31EB65A588CF6B9911F7B41D6F154F99B4F64839E110C30BA4B79286A4A3A3F7F0169A1D3A21F0D084CFA423E04C90C5966AC391A47F10E823C71B9716856B05BC12160DF0BA96300F8ADDC0D59E54E9CBDC7AC0EA6747DBA46C067
DP = 2004DECA7CAA16C780E2AB4F42E91716A847B53940948FB24CA2EEAD9BE7D1F7BC9B701FF29744E5E05E30E7B2775EE222C1DAC492CF692F47EAB82EE786CFCA23FE5A86DA42C186E69E3B608858354C999A26A4BF7F1543408EF6C1B439E9643604C2848162590A0A245CC834B977C72D10979010EBE5E177D884F04E450C51
DQ = 9A035E48E8305041EB9AD21994A7B233C8306E59429689632C7567573FA4993521CAD93756422BD3B008FE574F939A1CE659931387455B94F1CE950964946E841F208B628B89C83411588734C5FCFDF719ABFBC459DF1B7379CB45EEC2E4BA3BF88D93CB82DF532C86FEC646420B1B21054BAE84AAA36DDFF9BF43EDFDD063B9
QP = E7A5BC150E6A20E52920C6F24FC872B1893ED9268AA506D86EC3AA6E3B377E5F6AE0D686751CE40F684435C6F64F31888861389CE430FB271EE81D0067ED8A1BD8096FB3E4AF5839383F26F99916EED4D80CFA9B5901350A9C0AAD4E348EBCC559F92434C71DA864C13371626D9F29998748BB3C47BED31471B73ABF2E27B983

I tokenize the char array and read each token into rsa_context using the following code block,

// tokenize key and read into rsa context
const char s[3] = "= ";
char *token;
int k=0, size;

// get the first token
token = strtok(key, s);

// walk through other tokens
while( token != NULL ) {
    size = strlen(token);

    switch (k) {
        case 1:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->N, 16, token);
            break;

        case 3:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->E, 16, token);
            break;

        case 5:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->D, 16, token);
            break;

        case 7:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->P, 16, token);
            break;

        case 9:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->Q, 16, token);
            break;

        case 11:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->DP, 16, token);
            break;

        case 13:
            token[size-1]='\0';
            mpi_read_string(&rsaContext->DQ, 16, token);
            break;

        case 15:          
            token[size-1]='\0';                
            mpi_read_string(&rsaContext->QP, 16, token);                
            break;
    }
    k=k+1;
    token = strtok(NULL, "= \n");
}

Above code block works. How can I achieve the same goal of tokenizing the char array and reading each token into rsa_context more efficiently in terms of speed and minimum steps?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't know how this lib works but in general terms, replacing the switch with a look-up table should help with readability/maintenance and performance both. Since there's just 15 items, we don't need to use much memory for such a table and can afford to leave empty items in it.

Define some struct so that it contains all that's different between the various cases, along the lines of this pseudo code:

typedef struct
{
  something* rsaContext;
} context_t;

Then allocate a look-up table and initialize using designated initializers:

const context_t context [16] = 
{
  [1] = { &rsaContext->N },
  [3] = { &rsaContext->E },
  ... // and so on
};

This table needs to be placed at local scope, since rsaContext isn't a constant expression but another variable.

The way initialization works in C, it means that all context items in the table that we didn't initialize explicitly, will get set to all zeroes, or NULL in case of pointers. So all "rsaContext" members that weren't initialized will be null pointers.

Now you can replace the whole switch with a table look-up:

something* dst = context[k].rsaContext;
if(dst != NULL)
{
  token[size-1]='\0';
  mpi_read_string(dst, 16, token);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.