Пример #1
0
/**
*  Decrypts a string and removes the padding using either private or public key. 
* (depending on mode).
*  @param ciphertext: binary string to be decrypted.
*  @param key: table containing either the public or the private key, as generated by gen_key.
*  @return  The original message (if everything works ok).
*  @see  rsa_genkey
*/
static int luarsa_pkcs1_decrypt (lua_State *L) {
	int res = 0;
	int mode;
    size_t lmsg, lresult;
    rsa_context rsa;
    char *message = (char*)luaL_checklstring(L, 1, &lmsg); /* ciphertext */
    char result[KEY_SIZE];
    
    rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL ); 
    

    mode = processKey(L, 2, &rsa); /* keytable */
    
    rsa.len = lmsg;

    memset(result, 0, KEY_SIZE);
    printf("\nMode==%s\n", mode==RSA_PUBLIC ? "RSA_PUBLIC" : "RSA_PRIVATE" );
    printf("Size==%d\n", lmsg );
    printf("Crypt.Size==%d\n", rsa.len );
    
    printf("ver: %d\n", rsa.ver);
    printf("len: %d\n", rsa.len);
    printf("padding: %d\n", rsa.padding);
    printf("hash_id: %d\n", rsa.hash_id);
    
    mpi_print("N:%s\n", &rsa.N);
    mpi_print("E:%s\n", &rsa.E);
    
    if(mode!=RSA_PUBLIC) {
        mpi_print("D:%s\n", &rsa.D);
        mpi_print("P:%s\n", &rsa.P);
        mpi_print("Q:%s\n", &rsa.Q);
        mpi_print("DP:%s\n", &rsa.DP);
        mpi_print("DQ:%s\n", &rsa.DQ);
        mpi_print("QP:%s\n", &rsa.QP);

        //mpi_print("RN:%s\n", &rsa.RN);
        //mpi_print("RP:%s\n", &rsa.RP);
        //mpi_print("RQ:%s\n", &rsa.RQ);
    }
    
    // pass rsa context and ciphertext to decryption engine
    res = rsa_pkcs1_decrypt(&rsa, RSA_PRIVATE, &lmsg, message, result);
    printf("Orig.Size==%d\n", lmsg );
    
    if(res) {
    	luaL_error(L, "Error during cipher (%d)", res);
    }
    
    // push encrypted result buffer
    lua_pushlstring(L, result, lmsg); /* ciphertext */

    rsa_free( &rsa );
    
    return 1;
}
Пример #2
0
void
g10_log_mpidump( const char *text, MPI a )
{
    FILE *fp = log_stream();

    g10_log_print_prefix(text);
    mpi_print(fp, a, 1 );
    fputc('\n', fp);
}
Пример #3
0
static void
print_key_data( PKT_public_key *pk, u32 *keyid )
{
    int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
    int i;

    for(i=0; i < n; i++ ) {
	printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
	mpi_print(stdout, pk->pkey[i], 1 );
	putchar(':');
	putchar('\n');
    }
}
Пример #4
0
int
main(int argc, char **argv)
{
    static ARGPARSE_OPTS opts[] = {
    {0} };
    ARGPARSE_ARGS pargs;
    int i, c;
    int state = 0;
    char strbuf[1000];
    int stridx=0;

    pargs.argc = &argc;
    pargs.argv = &argv;
    pargs.flags = 0;

    i18n_init();
    while( arg_parse( &pargs, opts) ) {
	switch( pargs.r_opt ) {
	  default : pargs.err = 2; break;
	}
    }
    if( argc )
	usage(1);


    for(i=0; i < STACKSIZE; i++ )
	stack[i] = NULL;
    stackidx =0;

    while( (c=getc(stdin)) != EOF ) {
	if( !state ) {	/* waiting */
	    if( isdigit(c) ) {
		state = 1;
		ungetc(c, stdin);
		strbuf[0] = '0';
		strbuf[1] = 'x';
		stridx=2;
	    }
	    else if( isspace(c) )
		;
	    else {
		switch(c) {
		  case '+':
		    if( (c=getc(stdin)) == '+' )
			do_inc();
		    else {
			ungetc(c, stdin);
			do_add();
		    }
		    break;
		  case '-':
		    if( (c=getc(stdin)) == '-' )
			do_dec();
		    else if( isdigit(c) || (c >='A' && c <= 'F') ) {
			state = 1;
			ungetc(c, stdin);
			strbuf[0] = '-';
			strbuf[1] = '0';
			strbuf[2] = 'x';
			stridx=3;
		    }
		    else {
			ungetc(c, stdin);
			do_sub();
		    }
		    break;
		  case '*':
		    do_mul();
		    break;
		  case 'm':
		    do_mulm();
		    break;
		  case '/':
		    do_div();
		    break;
		  case '%':
		    do_rem();
		    break;
		  case '^':
		    do_powm();
		    break;
		  case 'I':
		    do_inv();
		    break;
		  case 'G':
		    do_gcd();
		    break;
		  case '>':
		    do_rshift();
		    break;
		  case 'i': /* dummy */
		    if( !stackidx )
			fputs("stack underflow\n", stderr);
		    else {
			mpi_free(stack[stackidx-1]);
			stackidx--;
		    }
		    break;
		  case 'd': /* duplicate the tos */
		    if( !stackidx )
			fputs("stack underflow\n", stderr);
		    else if( stackidx < STACKSIZE ) {
			mpi_free(stack[stackidx]);
			stack[stackidx] = mpi_copy( stack[stackidx-1] );
			stackidx++;
		    }
		    else
			fputs("stack overflow\n", stderr);
		    break;
		  case 'c':
		    for(i=0; i < stackidx; i++ )
			mpi_free(stack[i]), stack[i] = NULL;
		    stackidx = 0;
		    break;
		  case 'p': /* print the tos */
		    if( !stackidx )
			puts("stack is empty");
		    else {
			mpi_print(stdout, stack[stackidx-1], 1 );
			putchar('\n');
		    }
		    break;
		  case 'f': /* print the stack */
		    for( i = stackidx-1 ; i >= 0; i-- ) {
			printf("[%2d]: ", i );
			mpi_print(stdout, stack[i], 1 );
			putchar('\n');
		    }
		    break;
		  default:
		    fputs("invalid operator\n", stderr);
		}
	    }
	}
	else if( state == 1 ) { /* in a number */
	    if( !isxdigit(c) ) { /* store the number */
		state = 0;
		ungetc(c, stdin);
		if( stridx < 1000 )
		    strbuf[stridx] = 0;

		if( stackidx < STACKSIZE ) {
		    if( !stack[stackidx] )
			stack[stackidx] = mpi_alloc(10);
		    if( mpi_fromstr(stack[stackidx], strbuf) )
			fputs("invalid number\n", stderr);
		    else
			stackidx++;
		}
		else
		    fputs("stack overflow\n", stderr);
	    }
	    else { /* store digit */
		if( stridx < 999 )
		    strbuf[stridx++] = c;
		else if( stridx == 999 ) {
		    strbuf[stridx] = 0;
		    fputs("string too large - truncated\n", stderr);
		    stridx++;
		}
	    }
	}

    }
    for(i=0; i < stackidx; i++ )
	mpi_free(stack[i]);
    return 0;
}
Пример #5
0
/**
*  Adds padding and encrypts a string using either private or public key. 
* (depending on mode).
*  @param message: arbitrary binary string to be encrypted.
*  @param keytable: table containing either the public or the private key, as generated by gen_key.
*  @return  The cyphertext (as a binary string).
*  @see  rsa_genkey
*/
static int luarsa_pkcs1_encrypt (lua_State *L) {
	int res = 0;
	int mode;
    size_t lmsg, lresult;
    rsa_context rsa;
    char *message = (char*)luaL_checklstring(L, 1, &lmsg); /* message */
    char result[KEY_SIZE];
char alt_result[KEY_SIZE];
    char* strMode=NULL;
    if(lua_type(L, 3)==LUA_TSTRING) {
        printf("Got parameter\n");
        strMode = (char*)lua_tostring(L, 3);
        printf("[%s]\n", strMode);
        mode = strncmp(strMode, "private", 7) ? RSA_PUBLIC : RSA_PRIVATE;
    }
    
    rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL ); 
    
    processKey(L, 2, &rsa); /* keytable */
    
    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
    
    memset(result, 0, KEY_SIZE);
    
// <test> by Jason
    printf("\nMode==%s\n", mode==RSA_PUBLIC ? "RSA_PUBLIC" : "RSA_PRIVATE" );
    printf("Size==%d\n", lmsg );
    printf("Crypt.Size==%d\n", rsa.len );
    
    printf("ver: %d\n", rsa.ver);
    printf("len: %d\n", rsa.len);
    printf("padding: %d\n", rsa.padding);
    printf("hash_id: %d\n", rsa.hash_id);
    
    mpi_print("N:%s\n", &rsa.N);
    mpi_print("E:%s\n", &rsa.E);
    
    if(mode!=RSA_PUBLIC) {
        //mpi_print("D:%s\n", &rsa.D);
        //mpi_print("P:%s\n", &rsa.P);
        //mpi_print("Q:%s\n", &rsa.Q);
        //mpi_print("DP:%s\n", &rsa.DP);
        //mpi_print("DQ:%s\n", &rsa.DQ);
        //mpi_print("QP:%s\n", &rsa.QP);

        //mpi_print("RN:%s\n", &rsa.RN);
        //mpi_print("RP:%s\n", &rsa.RP);
        //mpi_print("RQ:%s\n", &rsa.RQ);
    }
// </test> by Jason

    // pass rsa context and message to encryption engine
    res = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, lmsg, message, result);
    
    if(res)
    	luaL_error(L, "Error during cipher (%d)", res);
/*    
    lmsg = 128;
    res = rsa_pkcs1_decrypt(&rsa, mode, &lmsg, result, alt_result);
    
    if(res)
    	luaL_error(L, "Error during decipher (%d)", res);
    
    printf("(%d)", lmsg);
*/
    push_private_key(L, &rsa);
    
    // push encrypted result buffer
    lua_pushlstring(L, result, rsa.len); /* ciphertext */

    rsa_free( &rsa );
    
    return 1;
}
Пример #6
0
/****************
 * We do not need to use the strongest RNG because we gain no extra
 * security from it - The prime number is public and we could also
 * offer the factors for those who are willing to check that it is
 * indeed a strong prime.
 *
 * mode 0: Standard
 *	1: Make sure that at least one factor is of size qbits.
 */
MPI
generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
		    MPI g, MPI **ret_factors )
{
    int n;  /* number of factors */
    int m;  /* number of primes in pool */
    unsigned fbits; /* length of prime factors */
    MPI *factors; /* current factors */
    MPI *pool;	/* pool of primes */
    MPI q;	/* first prime factor (variable)*/
    MPI prime;	/* prime test value */
    MPI q_factor; /* used for mode 1 */
    byte *perms = NULL;
    int i, j;
    int count1, count2;
    unsigned nprime;
    unsigned req_qbits = qbits; /* the requested q bits size */
    MPI val_2  = mpi_alloc_set_ui( 2 );

    /* find number of needed prime factors */
    for(n=1; (pbits - qbits - 1) / n  >= qbits; n++ )
	;
    n--;
    if( !n || (mode==1 && n < 2) )
	log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
    if( mode == 1 ) {
	n--;
	fbits = (pbits - 2*req_qbits -1) / n;
	qbits =  pbits - req_qbits - n*fbits;
    }
    else {
	fbits = (pbits - req_qbits -1) / n;
	qbits = pbits - n*fbits;
    }
    if( DBG_CIPHER )
	log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
		    pbits, req_qbits, qbits, fbits, n  );
    prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) /  BITS_PER_MPI_LIMB );
    q = gen_prime( qbits, 0, 0 );
    q_factor = mode==1? gen_prime( req_qbits, 0, 0 ) : NULL;

    /* allocate an array to hold the factors + 2 for later usage */
    factors = m_alloc_clear( (n+2) * sizeof *factors );

    /* make a pool of 3n+5 primes (this is an arbitrary value) */
    m = n*3+5;
    if( mode == 1 )
	m += 5; /* need some more for DSA */
    if( m < 25 )
	m = 25;
    pool = m_alloc_clear( m * sizeof *pool );

    /* permutate over the pool of primes */
    count1=count2=0;
    do {
      next_try:
	if( !perms ) {
	    /* allocate new primes */
	    for(i=0; i < m; i++ ) {
		mpi_free(pool[i]);
		pool[i] = NULL;
	    }
	    /* init m_out_of_n() */
	    perms = m_alloc_clear( m );
	    for(i=0; i < n; i++ ) {
		perms[i] = 1;
		pool[i] = gen_prime( fbits, 0, 0 );
		factors[i] = pool[i];
	    }
	}
	else {
	    m_out_of_n( perms, n, m );
	    for(i=j=0; i < m && j < n ; i++ )
		if( perms[i] ) {
		    if( !pool[i] )
			pool[i] = gen_prime( fbits, 0, 0 );
		    factors[j++] = pool[i];
		}
	    if( i == n ) {
		m_free(perms); perms = NULL;
		progress('!');
		goto next_try;	/* allocate new primes */
	    }
	}

	mpi_set( prime, q );
	mpi_mul_ui( prime, prime, 2 );
	if( mode == 1 )
	    mpi_mul( prime, prime, q_factor );
	for(i=0; i < n; i++ )
	    mpi_mul( prime, prime, factors[i] );
	mpi_add_ui( prime, prime, 1 );
	nprime = mpi_get_nbits(prime);
	if( nprime < pbits ) {
	    if( ++count1 > 20 ) {
		count1 = 0;
		qbits++;
		progress('>');
                mpi_free (q);
		q = gen_prime( qbits, 0, 0 );
		goto next_try;
	    }
	}
	else
	    count1 = 0;
	if( nprime > pbits ) {
	    if( ++count2 > 20 ) {
		count2 = 0;
		qbits--;
		progress('<');
                mpi_free (q);
		q = gen_prime( qbits, 0, 0 );
		goto next_try;
	    }
	}
	else
	    count2 = 0;
    } while( !(nprime == pbits && check_prime( prime, val_2 )) );

    if( DBG_CIPHER ) {
	progress('\n');
	log_mpidump( "prime    : ", prime );
	log_mpidump( "factor  q: ", q );
	if( mode == 1 )
	    log_mpidump( "factor q0: ", q_factor );
	for(i=0; i < n; i++ )
	    log_mpidump( "factor pi: ", factors[i] );
	log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
	if( mode == 1 )
	    fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
	for(i=0; i < n; i++ )
	    fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
	progress('\n');
    }

    if( ret_factors ) { /* caller wants the factors */
	*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
        i = 0;
	if( mode == 1 ) {
	    (*ret_factors)[i++] = mpi_copy( q_factor );
	    for(; i <= n; i++ )
		(*ret_factors)[i] = mpi_copy( factors[i] );
	}
	else {
	    for(; i < n; i++ )
		(*ret_factors)[i] = mpi_copy( factors[i] );
	}
    }

    if( g ) { /* create a generator (start with 3)*/
	MPI tmp   = mpi_alloc( mpi_get_nlimbs(prime) );
	MPI b	  = mpi_alloc( mpi_get_nlimbs(prime) );
	MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );

	if( mode == 1 )
	    BUG(); /* not yet implemented */
	factors[n] = q;
	factors[n+1] = mpi_alloc_set_ui(2);
	mpi_sub_ui( pmin1, prime, 1 );
	mpi_set_ui(g,2);
	do {
	    mpi_add_ui(g, g, 1);
	    if( DBG_CIPHER ) {
		log_debug("checking g: ");
		mpi_print( stderr, g, 1 );
	    }
	    else
		progress('^');
	    for(i=0; i < n+2; i++ ) {
		/*fputc('~', stderr);*/
		mpi_fdiv_q(tmp, pmin1, factors[i] );
		/* (no mpi_pow(), but it is okay to use this with mod prime) */
		mpi_powm(b, g, tmp, prime );
		if( !mpi_cmp_ui(b, 1) )
		    break;
	    }
	    if( DBG_CIPHER )
		progress('\n');
	} while( i < n+2 );
	mpi_free(factors[n+1]);
	mpi_free(tmp);
	mpi_free(b);
	mpi_free(pmin1);
    }
    if( !DBG_CIPHER )
	progress('\n');

    m_free( factors );	/* (factors are shallow copies) */
    for(i=0; i < m; i++ )
	mpi_free( pool[i] );
    m_free( pool );
    m_free(perms);
    mpi_free(val_2);
    mpi_free(q);
    return prime;
}