/* * Check a private RSA key */ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) { int ret; mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 ) return( ret ); if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I ); mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 ); mbedtls_mpi_init( &L1 ); mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); /* * Check for a valid PKCS1v2 private key */ if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || mbedtls_mpi_cmp_int( &L2, 0 ) != 0 || mbedtls_mpi_cmp_int( &I, 1 ) != 0 || mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) { ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; } cleanup: mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I ); mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 ); mbedtls_mpi_free( &L1 ); mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) return( ret ); if( ret != 0 ) return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret ); return( 0 ); }
void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r, const TEE_BigInt *op1, const TEE_BigInt *op2) { mbedtls_mpi mpi_dest_q; mbedtls_mpi mpi_dest_r; mbedtls_mpi mpi_op1; mbedtls_mpi mpi_op2; mbedtls_mpi *pop1 = &mpi_op1; mbedtls_mpi *pop2 = &mpi_op2; get_mpi(&mpi_dest_q, dest_q); get_mpi(&mpi_dest_r, dest_r); if (op1 == dest_q) pop1 = &mpi_dest_q; else if (op1 == dest_r) pop1 = &mpi_dest_r; else get_mpi(&mpi_op1, op1); if (op2 == dest_q) pop2 = &mpi_dest_q; else if (op2 == dest_r) pop2 = &mpi_dest_r; else if (op2 == op1) pop2 = pop1; else get_mpi(&mpi_op2, op2); MPI_CHECK(mbedtls_mpi_div_mpi(&mpi_dest_q, &mpi_dest_r, pop1, pop2)); MPI_CHECK(copy_mpi_to_bigint(&mpi_dest_q, dest_q)); MPI_CHECK(copy_mpi_to_bigint(&mpi_dest_r, dest_r)); mbedtls_mpi_free(&mpi_dest_q); mbedtls_mpi_free(&mpi_dest_r); if (pop1 == &mpi_op1) mbedtls_mpi_free(&mpi_op1); if (pop2 == &mpi_op2) mbedtls_mpi_free(&mpi_op2); }
static int addi(void *a, unsigned long b, void *c) { uint32_t b32 = b; if (b32 != b) return CRYPT_INVALID_ARG; mbedtls_mpi_uint p = b32; mbedtls_mpi bn = { .s = 1, .n = 1, .p = &p }; return add(a, &bn, c); } /* sub */ static int sub(void *a, void *b, void *c) { if (mbedtls_mpi_sub_mpi(c, a, b)) return CRYPT_MEM; return CRYPT_OK; } static int subi(void *a, unsigned long b, void *c) { uint32_t b32 = b; if (b32 != b) return CRYPT_INVALID_ARG; mbedtls_mpi_uint p = b32; mbedtls_mpi bn = { .s = 1, .n = 1, .p = &p }; return sub(a, &bn, c); } /* mul */ static int mul(void *a, void *b, void *c) { if (mbedtls_mpi_mul_mpi(c, a, b)) return CRYPT_MEM; return CRYPT_OK; } static int muli(void *a, unsigned long b, void *c) { if (b > (unsigned long) UINT32_MAX) return CRYPT_INVALID_ARG; if (mbedtls_mpi_mul_int(c, a, b)) return CRYPT_MEM; return CRYPT_OK; } /* sqr */ static int sqr(void *a, void *b) { return mul(a, a, b); } /* div */ static int divide(void *a, void *b, void *c, void *d) { int res = mbedtls_mpi_div_mpi(c, d, a, b); if (res == MBEDTLS_ERR_MPI_ALLOC_FAILED) return CRYPT_MEM; if (res) return CRYPT_ERROR; return CRYPT_OK; }