Esempio n. 1
0
File: pk.c Progetto: dezelin/maily
static int
wrap_gcry_pk_fixup (gnutls_pk_algorithm_t algo,
                    gnutls_direction_t direction,
                    gnutls_pk_params_st * params)
{
  int ret, result;

  /* only for RSA we invert the coefficient --pgp type */

  if (algo != GNUTLS_PK_RSA)
    return 0;

  if (params->params[5] == NULL)
    params->params[5] =
      _gnutls_mpi_new (_gnutls_mpi_get_nbits (params->params[0]));

  if (params->params[5] == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  ret = 1;
  if (direction == GNUTLS_IMPORT)
    {
      /* calculate exp1 [6] and exp2 [7] */
      _gnutls_mpi_release (&params->params[6]);
      _gnutls_mpi_release (&params->params[7]);
      result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS);
      if (result < 0)
        {
          gnutls_assert ();
          return result;
        }

      ret =
        gcry_mpi_invm (params->params[5], params->params[3],
                       params->params[4]);

      params->params_nr = RSA_PRIVATE_PARAMS;
    }
  else if (direction == GNUTLS_EXPORT)
    ret =
      gcry_mpi_invm (params->params[5], params->params[4], params->params[3]);
  if (ret == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  return 0;
}
Esempio n. 2
0
void point_double(struct affine_point *p, const struct domain_params *dp)
{
  if (gcry_mpi_cmp_ui(p->y, 0)) {
    gcry_mpi_t t1, t2;
    t1 = gcry_mpi_snew(0);
    t2 = gcry_mpi_snew(0);
    gcry_mpi_mulm(t2, p->x, p->x, dp->m);
    gcry_mpi_addm(t1, t2, t2, dp->m);
    gcry_mpi_addm(t1, t1, t2, dp->m);
    gcry_mpi_addm(t1, t1, dp->a, dp->m);
    gcry_mpi_addm(t2, p->y, p->y, dp->m);
    gcry_mpi_invm(t2, t2, dp->m);
    gcry_mpi_mulm(t1, t1, t2, dp->m);
    gcry_mpi_mulm(t2, t1, t1, dp->m);
    gcry_mpi_subm(t2, t2, p->x, dp->m);
    gcry_mpi_subm(t2, t2, p->x, dp->m);
    gcry_mpi_subm(p->x, p->x, t2, dp->m);
    gcry_mpi_mulm(t1, t1, p->x, dp->m);
    gcry_mpi_subm(p->y, t1, p->y, dp->m);
    gcry_mpi_set(p->x, t2);
    gcry_mpi_release(t1);
    gcry_mpi_release(t2);
  }
  else
    gcry_mpi_set_ui(p->x, 0);
}
Esempio n. 3
0
int ECDSA_verify(const char *msg, const struct affine_point *Q,
		 const gcry_mpi_t sig, const struct curve_params *cp)
{
  gcry_mpi_t e, r, s;
  struct affine_point X1, X2;
  int res = 0;
  r = gcry_mpi_new(0);
  s = gcry_mpi_new(0);
  gcry_mpi_div(s, r, sig, cp->dp.order, 0);
  if (gcry_mpi_cmp_ui(s, 0) <= 0 || gcry_mpi_cmp(s, cp->dp.order) >= 0 ||
      gcry_mpi_cmp_ui(r, 0) <= 0 || gcry_mpi_cmp(r, cp->dp.order) >= 0) 
    goto end;
  gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL);
  gcry_mpi_mod(e, e, cp->dp.order);
  gcry_mpi_invm(s, s, cp->dp.order);
  gcry_mpi_mulm(e, e, s, cp->dp.order);
  X1 = pointmul(&cp->dp.base, e, &cp->dp);
  gcry_mpi_mulm(e, r, s, cp->dp.order);
  X2 = pointmul(Q, e, &cp->dp);
  point_add(&X1, &X2, &cp->dp);
  gcry_mpi_release(e);
  if (! point_is_zero(&X1)) {
    gcry_mpi_mod(s, X1.x, cp->dp.order);
    res = ! gcry_mpi_cmp(s, r);
  }
  point_release(&X1);
  point_release(&X2);
 end:
  gcry_mpi_release(r);
  gcry_mpi_release(s);
  return res;
}
Esempio n. 4
0
void point_add(struct affine_point *p1, const struct affine_point *p2,
	       const struct domain_params *dp)
{
  if (! point_is_zero(p2)) {
    if (! point_is_zero(p1)) {
      if (! gcry_mpi_cmp(p1->x, p2->x)) {
	if (! gcry_mpi_cmp(p1->y, p2->y))
	  point_double(p1, dp);
	else
	  point_load_zero(p1);
      }
      else {
	gcry_mpi_t t;
	t = gcry_mpi_snew(0);
	gcry_mpi_subm(t, p1->y, p2->y, dp->m);
	gcry_mpi_subm(p1->y, p1->x, p2->x, dp->m);
	gcry_mpi_invm(p1->y, p1->y, dp->m);
	gcry_mpi_mulm(p1->y, t, p1->y, dp->m);
	gcry_mpi_mulm(t, p1->y, p1->y, dp->m);
	gcry_mpi_addm(p1->x, p1->x, p2->x, dp->m);
	gcry_mpi_subm(p1->x, t, p1->x, dp->m);
	gcry_mpi_subm(t, p2->x, p1->x, dp->m);
	gcry_mpi_mulm(p1->y, p1->y, t, dp->m);
	gcry_mpi_subm(p1->y, p1->y, p2->y, dp->m);
	gcry_mpi_release(t);
      }
    }
    else
      point_set(p1, p2);
  }
}
Esempio n. 5
0
/**
 * Unblind a blind-signed signature.  The signature should have been generated
 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
 * #GNUNET_CRYPTO_rsa_blind().
 *
 * @param sig the signature made on the blinded signature purpose
 * @param bkey the blinding key used to blind the signature purpose
 * @param pkey the public key of the signer
 * @return unblinded signature on success, NULL on error
 */
struct GNUNET_CRYPTO_rsa_Signature *
GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
                           struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
                           struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
{
  gcry_mpi_t n;
  gcry_mpi_t s;
  gcry_mpi_t r_inv;
  gcry_mpi_t ubsig;
  int ret;
  struct GNUNET_CRYPTO_rsa_Signature *sret;

  ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
  if (0 != ret)
    ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
  if (0 != ret)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  if (0 != ret)
    ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  if (0 != ret)
  {
    gcry_mpi_release (n);
    GNUNET_break_op (0);
    return NULL;
  }
  r_inv = gcry_mpi_new (0);
  if (1 !=
      gcry_mpi_invm (r_inv,
                     bkey->r,
                     n))
  {
    GNUNET_break_op (0);
    gcry_mpi_release (n);
    gcry_mpi_release (r_inv);
    gcry_mpi_release (s);
    return NULL;
  }
  ubsig = gcry_mpi_new (0);
  gcry_mpi_mulm (ubsig, s, r_inv, n);
  gcry_mpi_release (n);
  gcry_mpi_release (r_inv);
  gcry_mpi_release (s);

  sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
  GNUNET_assert (0 ==
                 gcry_sexp_build (&sret->sexp,
                                  NULL,
                                  "(sig-val (rsa (s %M)))",
                                  ubsig));
  gcry_mpi_release (ubsig);
  return sret;
}
Esempio n. 6
0
unsigned char* inv(unsigned char* x, unsigned char* y){
	size_t scanned;
	unsigned char *result;
	gcry_mpi_t a = gcry_mpi_new(0);
	gcry_mpi_t b = gcry_mpi_new(0);
	gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned);
	gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned);
	gcry_mpi_invm(a, a, b);
	gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a);
	return result;
}
Esempio n. 7
0
int p2p_convert_private_key(RSA *key, gcry_sexp_t *r_key) {
    size_t err;
    char *buf;
    
    gcry_mpi_t n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi;
    
    buf = BN_bn2hex(key->n);
    gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->e);
    gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->d);
    gcry_mpi_scan(&d_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->p);
    gcry_mpi_scan(&p_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->q);
    gcry_mpi_scan(&q_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    buf = BN_bn2hex(key->iqmp);
    gcry_mpi_scan(&u_mpi, GCRYMPI_FMT_HEX, buf, 0, &err);
    OPENSSL_free(buf);
    
    if(gcry_mpi_cmp(p_mpi, q_mpi) > 0) {
        gcry_mpi_swap(p_mpi, q_mpi);
        gcry_mpi_invm(u_mpi, p_mpi, q_mpi);
    }
    
    gcry_sexp_build(r_key, &err, "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))", n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi);
    
    gcry_mpi_release(n_mpi);
    gcry_mpi_release(e_mpi);
    gcry_mpi_release(d_mpi);
    gcry_mpi_release(p_mpi);
    gcry_mpi_release(q_mpi);
    gcry_mpi_release(u_mpi);
    
    gcry_error_t sane = gcry_pk_testkey(*r_key);
    if(sane) {
        return -1;
    }
    
    return 0;
}
Esempio n. 8
0
/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */
static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) {
        gcry_mpi_t a, u;

        a = gcry_mpi_new(0);
        u = gcry_mpi_new(0);
        *x = gcry_mpi_new(0);
        gcry_mpi_subm(a, xq, xp, q);
        gcry_mpi_invm(u, p, q);
        gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p  (mod q) */
        gcry_mpi_mul(*x, p, a);
        gcry_mpi_add(*x, *x, xp); /* x = p * ((xq - xp) / p mod q) + xp */
        gcry_mpi_release(a);
        gcry_mpi_release(u);
}
Esempio n. 9
0
struct affine_point jacobian_to_affine(const struct jacobian_point *p,
				       const struct domain_params *dp)
{
  struct affine_point r = point_new();
  if (gcry_mpi_cmp_ui(p->z, 0)) {
    gcry_mpi_t h;
    h = gcry_mpi_snew(0);
    gcry_mpi_invm(h, p->z, dp->m);
    gcry_mpi_mulm(r.y, h, h, dp->m);
    gcry_mpi_mulm(r.x, p->x, r.y, dp->m);
    gcry_mpi_mulm(r.y, r.y, h, dp->m);
    gcry_mpi_mulm(r.y, r.y, p->y, dp->m);
    gcry_mpi_release(h);
  }
  return r;
}
Esempio n. 10
0
/* Algorithms 4.29 and 4.30 in the "Guide to Elliptic Curve Cryptography"     */
gcry_mpi_t ECDSA_sign(const char *msg, const gcry_mpi_t d,
		      const struct curve_params *cp)
{
  struct affine_point p1;
  gcry_mpi_t e, k, r, s;

#if ECDSA_DETERMINISTIC
  struct aes256cprng *cprng;
  cprng = ecdsa_cprng_init(msg, d, cp);
#endif
  r = gcry_mpi_snew(0);
  s = gcry_mpi_snew(0);
 Step1:
#if ECDSA_DETERMINISTIC
  k = ecdsa_cprng_get_exponent(cprng, cp);
#else
  k = get_random_exponent(cp);
#endif
  p1 = pointmul(&cp->dp.base, k, &cp->dp);
  gcry_mpi_mod(r, p1.x, cp->dp.order);
  point_release(&p1);
  if (! gcry_mpi_cmp_ui(r, 0)) {
    gcry_mpi_release(k);
    goto Step1;
  }
  gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL);
  gcry_mpi_set_flag(e, GCRYMPI_FLAG_SECURE);
  gcry_mpi_mod(e, e, cp->dp.order);
  gcry_mpi_mulm(s, d, r, cp->dp.order);
  gcry_mpi_addm(s, s, e, cp->dp.order);
  gcry_mpi_invm(e, k, cp->dp.order);
  gcry_mpi_mulm(s, s, e, cp->dp.order);
  gcry_mpi_release(e);
  gcry_mpi_release(k);
  if (! gcry_mpi_cmp_ui(s, 0))
    goto Step1;
  gcry_mpi_mul(s, s, cp->dp.order);
  gcry_mpi_add(s, s, r);
  gcry_mpi_release(r);
#if ECDSA_DETERMINISTIC
  ecdsa_cprng_done(cprng);
#endif
  return s;
}
void attack(int i, unsigned char *digest, int hash_len){
	
    void* dsa_buf; 
	
    gcry_sexp_t new_dsa_key_pair;
    gcry_sexp_t ciphertext , plaintext, ptx2, ctx2;
	
    gcry_sexp_t r_param, r_tilda_param;
    gcry_sexp_t s_param, s_tilda_param;
    gcry_sexp_t g_param;
    gcry_sexp_t p_param;
    gcry_sexp_t q_param;
    gcry_sexp_t m_param;
    gcry_sexp_t y_param;

    gcry_sexp_t x_param;
    gcry_sexp_t misc_param;
	
    gcry_error_t err;
	
    gcry_mpi_t msg_digest, m;
	
    gcry_mpi_t r , r_tilda;
    gcry_mpi_t s , s_tilda;
    gcry_mpi_t g;
    gcry_mpi_t p;
    gcry_mpi_t q;
    gcry_mpi_t y;
    gcry_mpi_t x;
	
    retrieve_key_pair(files[i]);

    //*************** CORRECT SIGNATURE ********************//

	//20 is the mdlen of sha1 as specified in https://lists.gnupg.org/pipermail/gnupg-devel/2013-September/027916.html
    //a well formatted number for the immaediate has an even number of digits
    err = gcry_sexp_build(&plaintext, NULL, "(data (flags rfc6979) (hash %s %b))" , "sha1", hash_len , digest);
	
    err = gcry_pk_sign(&ciphertext, plaintext, dsa_key_pair);

    //now let's convert the s-expression representing r into an MPI in order
    //to use it in the equation of the attack 

    //--------- CIPHERTEXT --------------

    //intercepted during some sniffing...
    
    r_param = gcry_sexp_find_token(ciphertext, "r", 0);
    r = gcry_sexp_nth_mpi ( r_param , 1, GCRYMPI_FMT_USG);
         
    s_param = gcry_sexp_find_token(ciphertext, "s", 0);
    s = gcry_sexp_nth_mpi ( s_param , 1, GCRYMPI_FMT_USG);

    //--------- PUB KEY --------------
    
    g_param = gcry_sexp_find_token(dsa_key_pair, "g", 0);
    g = gcry_sexp_nth_mpi ( g_param , 1, GCRYMPI_FMT_USG);
    
    p_param = gcry_sexp_find_token(dsa_key_pair, "p", 0);
    p = gcry_sexp_nth_mpi ( p_param , 1, GCRYMPI_FMT_USG);
    
    q_param = gcry_sexp_find_token(dsa_key_pair, "q", 0);
    q = gcry_sexp_nth_mpi ( q_param , 1, GCRYMPI_FMT_USG);

    y_param = gcry_sexp_find_token(dsa_key_pair, "y", 0);
    y = gcry_sexp_nth_mpi ( y_param , 1, GCRYMPI_FMT_USG);

    x_param = gcry_sexp_find_token(dsa_key_pair, "x", 0);
    x = gcry_sexp_nth_mpi ( x_param , 1, GCRYMPI_FMT_USG);

    misc_param = gcry_sexp_find_token(dsa_key_pair, "misc-key-info", 0);

    //*************** FAULTY SIGNATURE ********************//

    err = gcry_sexp_build(&ptx2, NULL, "(data (flags rfc6979) (hash %s %b) (attack2_byte))" , "sha1", hash_len , digest);

    err = gcry_pk_sign(&ctx2, ptx2, dsa_key_pair);

    s_tilda_param = gcry_sexp_find_token(ctx2, "s", 0);
    s_tilda = gcry_sexp_nth_mpi ( s_tilda_param , 1, GCRYMPI_FMT_USG);


    r_tilda_param = gcry_sexp_find_token(ctx2, "r", 0);
    r_tilda = gcry_sexp_nth_mpi ( r_tilda_param , 1, GCRYMPI_FMT_USG);

    m_param = gcry_sexp_find_token(ptx2, "hash", 0);
    m = gcry_sexp_nth_mpi ( m_param , 2, GCRYMPI_FMT_USG);


    //NOW LET'S START THE ATTACK 

    unsigned long e = 0;

    unsigned int qbits = mpi_get_nbits(q);
    unsigned int pbits = mpi_get_nbits(p);

    int hash_len_bits = hash_len*8;

    gcry_mpi_t one = gcry_mpi_set_ui(NULL, 1);

    gcry_mpi_t tmp = gcry_mpi_new(qbits);

    gcry_mpi_t result = gcry_mpi_new(mpi_get_nbits(s));

    gcry_mpi_invm(r,r,q); // r^-1
    

    unsigned int j;

    for(e = 0; e < qbits ; e++){

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	       gcry_mpi_mulm(twoi,jmpi,empi,q);
      
        	//retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s_tilda, s, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === k

            //retrieve x
            gcry_mpi_mulm(result, s, result,q); // s*k mod q
            gcry_mpi_subm(result, result, m, q); // s*k - m mod q
            gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q

            err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                         "(key-data"
                         " (public-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                         " (private-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                        p,q,g,y,p,q,g,y,result);

            err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

            err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
        
            if (err) {
                //puts("gcrypt: verify failed");
    	    continue;
            }
            else{
                printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
        	    printf("[DBG] BYTE : %d * 2^%d  FAULT: k-j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }

        }

    }
    
    for(e = 0; e < qbits; e++){

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	    gcry_mpi_mulm(twoi,jmpi,empi,q);
      
            //retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s, s_tilda, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === k

            //retrieve x
            gcry_mpi_mulm(result, s, result,q); // s*k mod q
            gcry_mpi_subm(result, result, m, q); // s*k - m mod q
            gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q


            err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                         "(key-data"
                         " (public-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                         " (private-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                        p,q,g,y,p,q,g,y,result);

            err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

            err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
        
            if (err) {
                continue;
            }
            else{
                printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
        	    printf("[DBG] BYTE : %d * 2^%d  FAULT: k+j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }
        }
    }    
}
Esempio n. 12
0
/**
 * Generate a key pair with a key of size NBITS.
 * @param sk where to store the key
 * @param nbits the number of bits to use
 * @param hc the HC to use for PRNG (modified!)
 */
static void
generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
                     struct GNUNET_HashCode * hc)
{
  gcry_mpi_t t1, t2;
  gcry_mpi_t phi;               /* helper: (p-1)(q-1) */
  gcry_mpi_t g;
  gcry_mpi_t f;

  /* make sure that nbits is even so that we generate p, q of equal size */
  if ((nbits & 1))
    nbits++;

  sk->e = gcry_mpi_set_ui (NULL, 257);
  sk->n = gcry_mpi_new (0);
  sk->p = gcry_mpi_new (0);
  sk->q = gcry_mpi_new (0);
  sk->d = gcry_mpi_new (0);
  sk->u = gcry_mpi_new (0);

  t1 = gcry_mpi_new (0);
  t2 = gcry_mpi_new (0);
  phi = gcry_mpi_new (0);
  g = gcry_mpi_new (0);
  f = gcry_mpi_new (0);

  do
  {
    do
    {
      gcry_mpi_release (sk->p);
      gcry_mpi_release (sk->q);
      gen_prime (&sk->p, nbits / 2, hc);
      gen_prime (&sk->q, nbits / 2, hc);

      if (gcry_mpi_cmp (sk->p, sk->q) > 0)      /* p shall be smaller than q (for calc of u) */
        gcry_mpi_swap (sk->p, sk->q);
      /* calculate the modulus */
      gcry_mpi_mul (sk->n, sk->p, sk->q);
    }
    while (gcry_mpi_get_nbits (sk->n) != nbits);

    /* calculate Euler totient: phi = (p-1)(q-1) */
    gcry_mpi_sub_ui (t1, sk->p, 1);
    gcry_mpi_sub_ui (t2, sk->q, 1);
    gcry_mpi_mul (phi, t1, t2);
    gcry_mpi_gcd (g, t1, t2);
    gcry_mpi_div (f, NULL, phi, g, 0);
    while (0 == gcry_mpi_gcd (t1, sk->e, phi))
    {                           /* (while gcd is not 1) */
      gcry_mpi_add_ui (sk->e, sk->e, 2);
    }

    /* calculate the secret key d = e^1 mod phi */
  }
  while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
         (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));

  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);
  gcry_mpi_release (f);
  gcry_mpi_release (g);
}
Esempio n. 13
0
/* Check that the RSA secret key SKEY is valid.  Swap parameters to
   the libgcrypt standard.  */
static gpg_error_t
rsa_key_check (struct rsa_secret_key_s *skey)
{
  int err = 0;
  gcry_mpi_t t = gcry_mpi_snew (0);
  gcry_mpi_t t1 = gcry_mpi_snew (0);
  gcry_mpi_t t2 = gcry_mpi_snew (0);
  gcry_mpi_t phi = gcry_mpi_snew (0);

  /* Check that n == p * q.  */
  gcry_mpi_mul (t, skey->p, skey->q);
  if (gcry_mpi_cmp( t, skey->n) )
    {
      log_error ("RSA oops: n != p * q\n");
      err++;
    }

  /* Check that p is less than q.  */
  if (gcry_mpi_cmp (skey->p, skey->q) > 0)
    {
      gcry_mpi_t tmp;

      log_info ("swapping secret primes\n");
      tmp = gcry_mpi_copy (skey->p);
      gcry_mpi_set (skey->p, skey->q);
      gcry_mpi_set (skey->q, tmp);
      gcry_mpi_release (tmp);
      /* Recompute u.  */
      gcry_mpi_invm (skey->u, skey->p, skey->q);
    }

  /* Check that e divides neither p-1 nor q-1.  */
  gcry_mpi_sub_ui (t, skey->p, 1 );
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0) )
    {
      log_error ("RSA oops: e divides p-1\n");
      err++;
    }
  gcry_mpi_sub_ui (t, skey->q, 1);
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0))
    {
      log_info ("RSA oops: e divides q-1\n" );
      err++;
    }

  /* Check that d is correct.  */
  gcry_mpi_sub_ui (t1, skey->p, 1);
  gcry_mpi_sub_ui (t2, skey->q, 1);
  gcry_mpi_mul (phi, t1, t2);
  gcry_mpi_invm (t, skey->e, phi);
  if (gcry_mpi_cmp (t, skey->d))
    {
      /* No: try universal exponent. */
      gcry_mpi_gcd (t, t1, t2);
      gcry_mpi_div (t, NULL, phi, t, 0);
      gcry_mpi_invm (t, skey->e, t);
      if (gcry_mpi_cmp (t, skey->d))
        {
          log_error ("RSA oops: bad secret exponent\n");
          err++;
        }
    }

  /* Check for correctness of u.  */
  gcry_mpi_invm (t, skey->p, skey->q);
  if (gcry_mpi_cmp (t, skey->u))
    {
      log_info ("RSA oops: bad u parameter\n");
      err++;
    }

  if (err)
    log_info ("RSA secret key check failed\n");

  gcry_mpi_release (t);
  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);

  return err? gpg_error (GPG_ERR_BAD_SECKEY):0;
}
Esempio n. 14
0
/* Compute and print missing RSA parameters.  */
static void
compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e)
{
  gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u;
  gcry_mpi_t phi, tmp_g, tmp_f;

  rsa_n = gcry_mpi_new (0);
  rsa_d = gcry_mpi_new (0);
  rsa_pm1 = gcry_mpi_new (0);
  rsa_qm1 = gcry_mpi_new (0);
  rsa_u = gcry_mpi_new (0);

  phi = gcry_mpi_new (0);
  tmp_f = gcry_mpi_new (0);
  tmp_g = gcry_mpi_new (0);

  /* Check that p < q; if not swap p and q.  */
  if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0)
    {
      fprintf (stderr, PGM ": swapping p and q\n");
      gcry_mpi_swap (rsa_p, rsa_q);
    }

  gcry_mpi_mul (rsa_n, rsa_p, rsa_q);


  /* Compute the Euler totient:  phi = (p-1)(q-1)  */
  gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1);
  gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1);
  gcry_mpi_mul (phi, rsa_pm1, rsa_qm1);

  if (!gcry_mpi_gcd (tmp_g, rsa_e, phi))
    die ("parameter 'e' does match 'p' and 'q'\n");

  /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
  gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1);
  gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1);

  /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
  gcry_mpi_invm (rsa_d, rsa_e, tmp_f);

  /* Compute the CRT helpers: d mod (p-1), d mod (q-1)   */
  gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1);
  gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1);

  /* Compute the CRT value:   OpenPGP:    u = p^{-1} mod q
                             Standard: iqmp = q^{-1} mod p */
  if (openpgp_mode)
    gcry_mpi_invm (rsa_u, rsa_p, rsa_q);
  else
    gcry_mpi_invm (rsa_u, rsa_q, rsa_p);

  gcry_mpi_release (phi);
  gcry_mpi_release (tmp_f);
  gcry_mpi_release (tmp_g);

  /* Print everything.  */
  print_mpi_line ("n", rsa_n);
  print_mpi_line ("e", rsa_e);
  if (openpgp_mode)
    print_mpi_line ("d", rsa_d);
  print_mpi_line ("p", rsa_p);
  print_mpi_line ("q", rsa_q);
  if (openpgp_mode)
    print_mpi_line ("u", rsa_u);
  else
    {
      print_mpi_line ("dmp1", rsa_pm1);
      print_mpi_line ("dmq1", rsa_qm1);
      print_mpi_line ("iqmp", rsa_u);
    }

  gcry_mpi_release (rsa_n);
  gcry_mpi_release (rsa_d);
  gcry_mpi_release (rsa_pm1);
  gcry_mpi_release (rsa_qm1);
  gcry_mpi_release (rsa_u);
}
Esempio n. 15
0
/*
 * Parse the DER-encoded data at ps_data_der
 * saving the key in an S-expression
 */
int RSAKey::readDER( unsigned char const* ps_data_der, size_t length )
{
    struct tag_info tag_inf;
    gcry_mpi_t key_params[8];
    gcry_error_t err;
    int i;

    /* parse the ASN1 structure */
    if( parseTag( &ps_data_der, &length, &tag_inf )
            || tag_inf.tag != TAG_SEQUENCE || tag_inf.class_ || !tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( parseTag( &ps_data_der, &length, &tag_inf )
       || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
        goto bad_asn1;
    if( tag_inf.length != 1 || *ps_data_der )
        goto bad_asn1;  /* The value of the first integer is no 0. */
    ps_data_der += tag_inf.length;
    length -= tag_inf.length;

    for( i = 0; i < 8; i++ )
    {
        if( parseTag( &ps_data_der, &length, &tag_inf )
                || tag_inf.tag != TAG_INTEGER || tag_inf.class_ || tag_inf.cons || tag_inf.ndef )
            goto bad_asn1;
        err = gcry_mpi_scan( key_params + i, GCRYMPI_FMT_USG, ps_data_der, tag_inf.length, NULL );
        if( err )
        {
            msg_Err( this->p_demux, "error scanning RSA parameter %d: %s", i, gpg_strerror( err ) );
            goto error;
        }
        ps_data_der += tag_inf.length;
        length -= tag_inf.length;
    }

    /* Convert from OpenSSL parameter ordering to the OpenPGP order.
     * First check that p < q; if not swap p and q and recompute u.
     */
    if( gcry_mpi_cmp( key_params[3], key_params[4] ) > 0 )
    {
        gcry_mpi_swap( key_params[3], key_params[4] );
        gcry_mpi_invm( key_params[7], key_params[3], key_params[4] );
    }

    /* Build the S-expression.  */
    err = gcry_sexp_build( & this->priv_key, NULL,
                         "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
                         key_params[0], key_params[1], key_params[2],
                         key_params[3], key_params[4], key_params[7] );
    if( err )
    {
        msg_Err( this->p_demux, "error building S-expression: %s", gpg_strerror( err ) );
        goto error;
    }

    /* clear data */
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_SUCCESS;

bad_asn1:
    msg_Err( this->p_demux, "could not parse ASN1 structure; key might be corrupted" );

error:
    for( i = 0; i < 8; i++ )
        gcry_mpi_release( key_params[i] );
    return VLC_EGENERIC;
}
Esempio n. 16
0
void attack(int i, unsigned char *digest, int hash_len){
    
        gcry_error_t err;

        gcry_sexp_t ciphertext , plaintext, ptx2, new_dsa_key_pair;
        
        gcry_sexp_t r_param, r_tilda_param, k_tilda_param, msg_digest_param;
        gcry_sexp_t s_param, s_tilda_param;
        gcry_sexp_t g_param;
        gcry_sexp_t p_param;
        gcry_sexp_t q_param;
        gcry_sexp_t x_param, y_param;
        
        
        
        gcry_mpi_t r , r_tilda, k_tilda, x, y;
        gcry_mpi_t s , s_tilda;
        gcry_mpi_t g;
        gcry_mpi_t p;
        gcry_mpi_t q;
        gcry_mpi_t msg_digest;
   

        retrieve_key_pair(files[i]);

        //*************** CORRECT SIGNATURE ********************//

        //20 is the mdlen of sha1 as specified in https://lists.gnupg.org/pipermail/gnupg-devel/2013-September/027916.html
        //a well formatted number for the immaediate has an even number of digits
        err = gcry_sexp_build(&plaintext, NULL, "(data (flags rfc6979) (hash %s %b))" , "sha1", hash_len , digest);

        err = gcry_pk_sign(&ciphertext, plaintext, dsa_key_pair);


        //now let's convert the s-expression representing r into an MPI in order
        //to use it in the equation of the attack 

        //--------- CIPHERTEXT --------------

        r_param = gcry_sexp_find_token(ciphertext, "r", 0);
        r = gcry_sexp_nth_mpi ( r_param , 1, GCRYMPI_FMT_USG);
             
        s_param = gcry_sexp_find_token(ciphertext, "s", 0);
        s = gcry_sexp_nth_mpi ( s_param , 1, GCRYMPI_FMT_USG);


        //--------- PUB KEY --------------

        g_param = gcry_sexp_find_token(dsa_key_pair, "g", 0);
        g = gcry_sexp_nth_mpi ( g_param , 1, GCRYMPI_FMT_USG);

        p_param = gcry_sexp_find_token(dsa_key_pair, "p", 0);
        p = gcry_sexp_nth_mpi ( p_param , 1, GCRYMPI_FMT_USG);

        q_param = gcry_sexp_find_token(dsa_key_pair, "q", 0);
        q = gcry_sexp_nth_mpi ( q_param , 1, GCRYMPI_FMT_USG);

        x_param = gcry_sexp_find_token(dsa_key_pair, "x", 0);
        x = gcry_sexp_nth_mpi ( x_param , 1, GCRYMPI_FMT_USG);

        y_param = gcry_sexp_find_token(dsa_key_pair, "y", 0);
        y = gcry_sexp_nth_mpi ( y_param , 1, GCRYMPI_FMT_USG);

    	unsigned int qbits = mpi_get_nbits(q);
    	unsigned int pbits = mpi_get_nbits(p);
    

        msg_digest_param = gcry_sexp_find_token(plaintext, "hash", 0);
        msg_digest = gcry_sexp_nth_mpi ( msg_digest_param , 2, GCRYMPI_FMT_USG);



        //*************** FAULTY SIGNATURE ********************//

        err = gcry_sexp_build(&ptx2, NULL, "(data (flags rfc6979) (hash %s %b) (attack))" , "sha1", hash_len , digest);

        err = gcry_pk_sign(&ciphertext, ptx2, dsa_key_pair);

        s_tilda_param = gcry_sexp_find_token(ciphertext, "s", 0);
        s_tilda = gcry_sexp_nth_mpi ( s_tilda_param , 1, GCRYMPI_FMT_USG);

        r_tilda_param = gcry_sexp_find_token(ciphertext, "r", 0);
        r_tilda = gcry_sexp_nth_mpi ( r_tilda_param , 1, GCRYMPI_FMT_USG);

        k_tilda_param = gcry_sexp_find_token(ciphertext, "k", 0);
        k_tilda = gcry_sexp_nth_mpi ( k_tilda_param , 1, GCRYMPI_FMT_USG);


        //POC 

        // 1 - choose a message
        // 2 - do the correct sign and obtain s and r
        // 3 - do the faulty sign and obtain s_tilda and r_tilda

        gcry_mpi_t tmp = gcry_mpi_new(mpi_get_nbits(p));

        gcry_mpi_t result = gcry_mpi_new(mpi_get_nbits(p));

        gcry_mpi_subm(tmp, s_tilda, s,q);   //s-tilda -s mod q

        gcry_mpi_mulm(msg_digest, msg_digest, tmp, q);  //m* (s-tilda -s mod q) mod q

        gcry_mpi_mulm(tmp, r_tilda, s, q);  //r_tilda - s mod q

        gcry_mpi_mulm(result, s_tilda, r, q);    //s_tilda - r mod q

        gcry_mpi_subm(result, tmp, result, q);  //(r_tilda - s mod q) - (s_tilda - r mod q) mod q

        gcry_mpi_invm(result,result,q); //((r_tilda - s mod q) - (s_tilda - r mod q) mod q)^-1 mod q

        gcry_mpi_mulm(result, msg_digest, result, q);   //( (m* (s-tilda -s mod q) mod q) * ((r_tilda - s mod q) - (s_tilda - r mod q) mod q)^-1 mod q ) mod q == x (private key)

        err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                     "(key-data"
                     " (public-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                     " (private-key"
                     "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                    p,q,g,y,p,q,g,y,result);
    	     
    	err = gcry_pk_sign(&ciphertext, plaintext, new_dsa_key_pair);

        err = gcry_pk_verify(ciphertext, plaintext, dsa_key_pair);
    
        if (err) {
            printf("\nSomething went wrong...\n");
            exit(0);
        }
        if(!printed){
             DEBUG_MPI_PRINT(result,"\nX = ");
             printed = 1;
        }
}
Esempio n. 17
0
GkmDataResult
gkm_data_der_read_private_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
{
	GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
	gcry_mpi_t n, e, d, p, q, u;
	gcry_mpi_t tmp;
	gulong version;
	GNode *asn = NULL;
	int res;

	n = e = d = p = q = u = NULL;

	asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;

	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
		goto done;

	/* We only support simple version */
	if (version != 0) {
		ret = GKM_DATA_UNRECOGNIZED;
		g_message ("unsupported version of RSA key: %lu", version);
		goto done;
	}

	if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "modulus", NULL), &n) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "publicExponent", NULL), &e) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "privateExponent", NULL), &d) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime1", NULL), &p) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime2", NULL), &q) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "coefficient", NULL), &u))
		goto done;

	/* Fix up the incoming key so gcrypt likes it */
	if (gcry_mpi_cmp (p, q) > 0) {
		/* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
		tmp = p;
		p = q;
		q = tmp;
	} else {
		/* U needs to be recomputed.  */
		gcry_mpi_invm (u, p, q);
	}

	res = gcry_sexp_build (s_key, NULL, SEXP_PRIVATE_RSA, n, e, d, p, q, u);
	if (res)
		goto done;

	g_assert (*s_key);
	ret = GKM_DATA_SUCCESS;

done:
	egg_asn1x_destroy (asn);
	gcry_mpi_release (n);
	gcry_mpi_release (e);
	gcry_mpi_release (d);
	gcry_mpi_release (p);
	gcry_mpi_release (q);
	gcry_mpi_release (u);

	if (ret == GKM_DATA_FAILURE)
		g_message ("invalid RSA key");

	return ret;
}