/* * Check a private RSA key */ int rsa_check_privkey( const rsa_context *ctx ) { int ret; mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) return( ret ); if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &I ); mpi_init( &G ); mpi_init( &G2 ); mpi_init( &L1 ); mpi_init( &L2 ); mpi_init( &DP ); mpi_init( &DQ ); mpi_init( &QP ); MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) ); MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) ); MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) ); MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); /* * Check for a valid PKCS1v2 private key */ if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || mpi_cmp_int( &L2, 0 ) != 0 || mpi_cmp_int( &I, 1 ) != 0 || mpi_cmp_int( &G, 1 ) != 0 ) { ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED; } cleanup: mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &I ); mpi_free( &G ); mpi_free( &G2 ); mpi_free( &L1 ); mpi_free( &L2 ); mpi_free( &DP ); mpi_free( &DQ ); mpi_free( &QP ); if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED ) return( ret ); if( ret != 0 ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED + ret ); return( 0 ); }
static int Bdivmod(lua_State *L) { mpi *a=Bget(L,1); mpi *b=Bget(L,2); mpi *q=Bnew(L); mpi *r=Bnew(L); mpi_div_mpi(q,r,a,b); return 2; }
/* * Check a private RSA key */ int rsa_check_privkey( const rsa_context *ctx ) { int ret; mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2; if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) return( ret ); if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL ); MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) ); MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) ); MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) ); /* * Check for a valid PKCS1v2 private key */ if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 && mpi_cmp_int( &L2, 0 ) == 0 && mpi_cmp_int( &I, 1 ) == 0 && mpi_cmp_int( &G, 1 ) == 0 ) { mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL ); return( 0 ); } cleanup: mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL ); return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret ); }
int main(void) { int ret; mpi A, E, N, X, Y, U, V; mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL ); MPI_CHK( mpi_read_string( &A, 16, "EFE021C2645FD1DC586E69184AF4A31E" \ "D5F53E93B5F123FA41680867BA110131" \ "944FE7952E2517337780CB0DB80E61AA" \ "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); MPI_CHK( mpi_read_string( &E, 16, "B2E7EFD37075B9F03FF989C7C5051C20" \ "34D2A323810251127E7BF8625A4F49A5" \ "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ "5B5C25763222FEFCCFC38B832366C29E" ) ); MPI_CHK( mpi_read_string( &N, 16, "0066A198186C18C10B2F5ED9B522752A" \ "9830B69916E535C8F047518A889A43A5" \ "94B6BED27A168D31D4A52F88925AA8F5" ) ); MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "602AB7ECA597A3D6B56FF9829A5E8B85" \ "9E857EA95A03512E2BAE7391688D264A" \ "A5663B0341DB9CCFD2C4C5F421FEC814" \ "8001B72E848A38CAE1C65F78E56ABDEF" \ "E12D3C039B8A02D6BE593F0BBBDA56F1" \ "ECF677152EF804370C1A305CAF3B5BF1" \ "30879B56C61DE584A0F53A2447A51E" ) ); if( verbose != 0 ) printf( " MPI test #1 (mul_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "256567336059E52CAE22925474705F39A94" ) ); MPI_CHK( mpi_read_string( &V, 16, "6613F26162223DF488E9CD48CC132C7A" \ "0AC93C701B001B092E4E5B9F73BCD27B" \ "9EE50D0657C77F374E903CDFA4C642" ) ); if( verbose != 0 ) printf( " MPI test #2 (div_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 || mpi_cmp_mpi( &Y, &V ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); MPI_CHK( mpi_read_string( &U, 16, "36E139AEA55215609D2816998ED020BB" \ "BD96C37890F65171D948E9BC7CBAA4D9" \ "325D24D6A3C12710F10A09FA08AB87" ) ); if( verbose != 0 ) printf( " MPI test #3 (exp_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ "C3DBA76456363A10869622EAC2DD84EC" \ "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); if( verbose != 0 ) printf( " MPI test #4 (inv_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); cleanup: if( ret != 0 && verbose != 0 ) printf( "Unexpected error, return code = %08X\n", ret ); mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL ); if( verbose != 0 ) printf( "\n" ); return( ret ); }
void cmd_sign(char *conf, char *key) { rsa_sig_t sign; rsa_key_t pubkey; rsa_key_t seckey; rsa_context *ctx; sigstruct_t *sigstruct; // Load sigstruct from file sigstruct = load_sigstruct(conf); // Ignore fields don't need to sign memset(sigstruct->modulus, 0, 384); sigstruct->exponent = 0; memset(sigstruct->signature, 0, 384); memset(sigstruct->q1, 0, 384); memset(sigstruct->q2, 0, 384); // Load rsa keys from file ctx = load_rsa_keys(key, pubkey, seckey, KEY_LENGTH_BITS); #if 0 { char *pubkey_str = fmt_bytes(pubkey, KEY_LENGTH); char *seckey_str = fmt_bytes(seckey, KEY_LENGTH); printf("PUBKEY: %.40s..\n", pubkey_str); printf("SECKEY: %.40s..\n", seckey_str); free(pubkey_str); free(seckey_str); } #endif // Generate rsa sign on sigstruct with private key rsa_sign(ctx, sign, (unsigned char *)sigstruct, sizeof(sigstruct_t)); // Compute q1, q2 unsigned char *q1, *q2; q1 = malloc(384); q2 = malloc(384); memset(q1, 0, 384); memset(q2, 0, 384); mpi Q1, Q2, S, M, T1, T2, R; mpi_init(&Q1); mpi_init(&Q2); mpi_init(&S); mpi_init(&M); mpi_init(&T1); mpi_init(&T2); mpi_init(&R); // q1 = signature ^ 2 / modulus mpi_read_binary(&S, sign, 384); mpi_read_binary(&M, pubkey, 384); mpi_mul_mpi(&T1, &S, &S); mpi_div_mpi(&Q1, &R, &T1, &M); // q2 = (signature ^ 3 - q1 * signature * modulus) / modulus mpi_init(&R); mpi_mul_mpi(&T1, &T1, &S); mpi_mul_mpi(&T2, &Q1, &S); mpi_mul_mpi(&T2, &T2, &M); mpi_sub_mpi(&Q2, &T1, &T2); mpi_div_mpi(&Q2, &R, &Q2, &M); mpi_write_binary(&Q1, q1, 384); mpi_write_binary(&Q2, q2, 384); mpi_free(&Q1); mpi_free(&Q2); mpi_free(&S); mpi_free(&M); mpi_free(&T1); mpi_free(&T2); mpi_free(&R); sigstruct = load_sigstruct(conf); sigstruct->exponent = 3; memcpy(sigstruct->modulus, pubkey, 384); memcpy(sigstruct->signature, sign, 384); memcpy(sigstruct->q1, q1, 384); memcpy(sigstruct->q2, q2, 384); char *msg = dump_sigstruct(sigstruct); printf("# SIGSTRUCT START\n"); printf("%s\n", msg); printf("# SIGSTRUCT END\n"); /*unsigned char exp[4] = { 0x00, 0x00, 0x00, 0x03 }; char *mod_str = fmt_bytes(pubkey, 384); char *exp_str = fmt_bytes(exp, 4); char *sign_str = fmt_bytes(sign, 384); char *q1_str = fmt_bytes(q1, 384); char *q2_str = fmt_bytes(q2, 384); printf("# sign information\n"); printf("MODULUS : %s\n", mod_str); printf("EXPONENT : %s\n", exp_str); printf("SIGNATURE : %s\n", sign_str); printf("Q1 : %s\n", q1_str); printf("Q2 : %s\n", q2_str); free(mod_str); free(exp_str); free(sign_str); unsigned char signer[32]; sha256(pubkey, KEY_LENGTH, signer, 0); char *signer_str = fmt_bytes(pubkey, 32); printf("# hash of public key\n"); printf("MRSIGNER : %s\n", signer_str);*/ }