/* * Create own private value X and export G^X */ int dhm_make_public( dhm_context *ctx, int x_size, unsigned char *output, size_t olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret, n; if( ctx == NULL || olen < 1 || olen > ctx->len ) return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); /* * generate X and calculate GX = G^X mod P */ n = x_size / sizeof( t_uint ) + 1; mpi_fill_random( &ctx->X, n, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) mpi_shift_r( &ctx->X, 1 ); MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, &ctx->P , &ctx->RP ) ); if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) return( ret ); MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) ); cleanup: if( ret != 0 ) return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); return( 0 ); }
/* * Generate or update blinding values, see section 10 of: * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer * Berlin Heidelberg, 1996. p. 104-113. */ static int rsa_prepare_blinding( rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; if( ctx->Vf.p != NULL ) { /* We already have blinding values, just update them by squaring */ MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); return( 0 ); } /* Unblinding value: Vf = random number */ MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); /* Mathematically speaking, the algorithm should check Vf * against 0, P and Q (Vf should be relatively prime to N, and 0 < Vf < N), * so that Vf^-1 exists. */ /* Blinding value: Vi = Vf^(-e) mod N */ MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); cleanup: return( ret ); }
/* * Setup and write the ServerKeyExchange parameters */ int dhm_make_params( dhm_context *ctx, int x_size, unsigned char *output, size_t *olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret, n; size_t n1, n2, n3; unsigned char *p; /* * Generate X as large as possible ( < P ) */ n = x_size / sizeof( t_uint ) + 1; mpi_fill_random( &ctx->X, n, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) mpi_shift_r( &ctx->X, 1 ); /* * Calculate GX = G^X mod P */ MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, &ctx->P , &ctx->RP ) ); if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) return( ret ); /* * export P, G, GX */ #define DHM_MPI_EXPORT(X,n) \ MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \ *p++ = (unsigned char)( n >> 8 ); \ *p++ = (unsigned char)( n ); p += n; n1 = mpi_size( &ctx->P ); n2 = mpi_size( &ctx->G ); n3 = mpi_size( &ctx->GX ); p = output; DHM_MPI_EXPORT( &ctx->P , n1 ); DHM_MPI_EXPORT( &ctx->G , n2 ); DHM_MPI_EXPORT( &ctx->GX, n3 ); *olen = p - output; ctx->len = n1; cleanup: if( ret != 0 ) return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED + ret ); return( 0 ); }
/* * Generate or update blinding values, see section 10 of: * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer * Berlin Heidelberg, 1996. p. 104-113. */ static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret, count = 0; #if defined(POLARSSL_THREADING_C) polarssl_mutex_lock( &ctx->mutex ); #endif if( ctx->Vf.p != NULL ) { /* We already have blinding values, just update them by squaring */ MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); goto done; } /* Unblinding value: Vf = random number, invertible mod N */ do { if( count++ > 10 ) return( POLARSSL_ERR_RSA_RNG_FAILED ); MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); /* Blinding value: Vi = Vf^(-e) mod N */ MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); done: if( Vi != &ctx->Vi ) { MPI_CHK( mpi_copy( Vi, &ctx->Vi ) ); MPI_CHK( mpi_copy( Vf, &ctx->Vf ) ); } cleanup: #if defined(POLARSSL_THREADING_C) polarssl_mutex_unlock( &ctx->mutex ); #endif return( ret ); }