int receive_and_decrypt(byte * msg){

	int length = readFromPipe(inputChannel , msg); 

	if(length < 0)
	{
		fprintf(stderr , " **** error reading message **** \n\n");
		return -1;
	}	

	if(strncmp(msg , ClientCloseConnection , length) == 0 && length == strlen(ClientCloseConnection))
		return length;
	
	if(encType == PLAIN)
		return length;

	if(encType == RSA64){
		BIGNUM *message = BN_new();	
		message = BN_bin2bn((const unsigned char *) msg, RSA64_BYTE_LENGTH , NULL);
		
		printf("%s\n", BN_bn2hex(message));
		
		rsaEXP(message , &server64Rsa);	//Decrypt with private keyExchange
		
		BN_bn2bin(message , msg);

		BN_free(message);		
		return length;		
	}
	
	if(encType == RSA512){
		BIGNUM *message = BN_new();	
		message = BN_bin2bn((const unsigned char *) msg, RSA512_BYTE_LENGTH , NULL);
		
		printf("%s\n", BN_bn2hex(message));
		
		rsaEXP(message , &server512Rsa);	//Decrypt with private keyExchange

		BN_bn2bin(message , msg);

		BN_free(message);		
		return length;		
	}
	
	if(encType == Cipher_ALL5){
		BIGNUM *tm = BN_new();	
		tm = BN_bin2bn((const unsigned char *) msg, length , NULL);
		printf("ALL5 : %s\n", BN_bn2hex(tm));

		byte message[length - HASH_BYTE_LENGTH];	
		byte hash[HASH_BYTE_LENGTH];

		int recv_length = length;
		
		if(cipherSpec.hash_function == hash_spongeBunny)
		{
		recv_length -= HASH_BYTE_LENGTH;	
		memmove(hash , msg + (sizeof(byte) * recv_length) , sizeof(byte) * HASH_BYTE_LENGTH);	//copy the hash
		memcpy(message , msg , sizeof(byte) * recv_length);	//copy the cihpertext				
		
		ALL5_decrypt(&cipherStruct.all5, message, message, recv_length);	//decrypt
		
		byte rec_hash[HASH_BYTE_LENGTH];
		spongeBunnyComputeHash(message , rec_hash , recv_length);	//compute the hash of the plaintext
		
		if(memcmp(rec_hash, hash, sizeof(byte) * HASH_BYTE_LENGTH) != 0)
		{
			recv_length = 0;
			fprintf(stderr , "Wrong HASH !!!!!!! \n");
		}
		
		tm = BN_bin2bn((const unsigned char *) hash, HASH_BYTE_LENGTH , NULL);
		printf("HASH : %s\n", BN_bn2hex(tm));
		memcpy(msg , message , sizeof(byte) * recv_length);
		
			
		}	//no hash function
		else
			ALL5_decrypt(&cipherStruct.all5, msg, msg, recv_length);	//decrypt	
		
		BN_free(tm);		
		return recv_length;
	}
	
	if(encType == Cipher_MAJ5){
		BIGNUM *tm = BN_new();	
		tm = BN_bin2bn((const unsigned char *) msg, length , NULL);
		printf("MAJ5 : %s\n", BN_bn2hex(tm));
		
		int recv_length = length;
		
		if(cipherSpec.hash_function == hash_spongeBunny)		
		{
		byte message[length - HASH_BYTE_LENGTH];	
		byte hash[HASH_BYTE_LENGTH];
		
		recv_length -= HASH_BYTE_LENGTH;	
		memmove(hash , msg + (sizeof(byte) * recv_length) , sizeof(byte) * HASH_BYTE_LENGTH);	//copy the hash
		memcpy(message , msg , sizeof(byte) * recv_length);	//copy the cihpertext				
		
		MAJ5_decrypt(&cipherStruct.maj5, message, message, recv_length);	//decrypt
		
		byte rec_hash[HASH_BYTE_LENGTH];
		spongeBunnyComputeHash(message , rec_hash , recv_length);	//compute the hash of the plaintext
		
		if(memcmp(rec_hash, hash, sizeof(byte) * HASH_BYTE_LENGTH) != 0)
		{
			recv_length = 0;
			fprintf(stderr , "Wrong HASH !!!!!!! \n");
		}
		
		tm = BN_bin2bn((const unsigned char *) hash, HASH_BYTE_LENGTH , NULL);
		printf("HASH : %s\n", BN_bn2hex(tm));
		memcpy(msg , message , sizeof(byte) * recv_length);
		
		}	//no hash function
		else
			MAJ5_decrypt(&cipherStruct.maj5, msg, msg, recv_length);	//decrypt	
		
		BN_free(tm);		
		return recv_length;
		
	}
	
	if(encType == Cipher_Bunny24){
		
		BIGNUM *tm = BN_new();	
		tm = BN_bin2bn((const unsigned char *) msg, length , NULL);
		printf("BUNNY24 : %s \n", BN_bn2hex(tm));
		
		int recv_length = length - HASH_BYTE_LENGTH;
		
		byte hash[HASH_BYTE_LENGTH];	
		byte mess[recv_length];
		
		memmove(hash , msg + (sizeof(byte) * recv_length) , sizeof(byte) * HASH_BYTE_LENGTH);	//copy the hash					
		memcpy(mess , msg , sizeof(byte) * recv_length);
		
		int message_bit_length = recv_length * 8;
		
		bit  plain_bit_text[message_bit_length];			//plaintext in  bits
		bit  crypt_bit_text[message_bit_length];			//ciphertext in bits
		bit  plain_byte_text[recv_length];
		
		memset(plain_byte_text , 0 , sizeof(byte) * recv_length);

		int i;

		for(i = 0; i < message_bit_length; i++)
			crypt_bit_text[i] = (msg[i / 8] & (1 << i % 8)) ? 1 : 0;		//to bit
			
		bunny24CBC_decrypt(plain_bit_text, crypt_bit_text , init_vector , cipherStruct.key , message_bit_length); // encrypt

		for(i = 0; i < message_bit_length; i++)
			plain_byte_text[i/8] |= (plain_bit_text[i] << (i % 8));		//to byte
			
		strcpy(msg ,plain_byte_text);
		msg[strlen(msg) + 1] = '\0';

		byte rec_hash[HASH_BYTE_LENGTH];
		memset(rec_hash , 0 , sizeof(byte) * HASH_BYTE_LENGTH);
		spongeBunnyComputeHash(msg , rec_hash , strlen(msg) + 1);	//compute the hash of the ciphertext
		
		if(memcmp(rec_hash, hash, sizeof(byte) * HASH_BYTE_LENGTH) != 0)
			fprintf(stderr , "Wrong HASH !!!!!!! \n");	
		
		tm = BN_bin2bn((const unsigned char *) rec_hash , HASH_BYTE_LENGTH , NULL);
		printf("\nHASH : %s\n", BN_bn2hex(tm));

		BN_free(tm);	
		
		return strlen(msg) + 1;
	}
	
}
Example #2
0
void tgl_do_send_create_encr_chat (struct tgl_state *TLS, void *x, unsigned char *random, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
  int user_id = (long)x;
  int i;
  unsigned char random_here[256];
  tglt_secure_random (random_here, 256);
  for (i = 0; i < 256; i++) {
    random[i] ^= random_here[i];
  }
  BIGNUM *a = BN_bin2bn (random, 256, 0);
  ensure_ptr (a);
  BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); 
  ensure_ptr (p);
 
  BIGNUM *g = BN_new ();
  ensure_ptr (g);

  ensure (BN_set_word (g, TLS->encr_root));

  BIGNUM *r = BN_new ();
  ensure_ptr (r);

  ensure (BN_mod_exp (r, g, a, p, TLS->BN_ctx));

  BN_clear_free (a);

  static char g_a[256];
  memset (g_a, 0, 256);

  BN_bn2bin (r, (void *)(g_a + (256 - BN_num_bytes (r))));
  
  int t = lrand48 ();
  while (tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t))) {
    t = lrand48 ();
  }

  //bl_do_encr_chat_init (TLS, t, user_id, (void *)random, (void *)g_a);
  
  int state = sc_waiting;
  bl_do_encr_chat_new (TLS, t, NULL, NULL, &TLS->our_id, &user_id, random, NULL, NULL, &state, NULL, NULL, NULL, NULL, NULL, NULL, TGLPF_CREATE | TGLPF_CREATED);

  
  tgl_peer_t *_E = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t));
  assert (_E);
  struct tgl_secret_chat *E = &_E->encr_chat;
  
  clear_packet ();
  out_int (CODE_messages_request_encryption);
  tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (E->user_id));
  assert (U);
  if (U && U->user.access_hash) {
    out_int (CODE_input_user_foreign);
    out_int (E->user_id);
    out_long (U->user.access_hash);
  } else {
    out_int (CODE_input_user_contact);
    out_int (E->user_id);
  }
  out_int (tgl_get_peer_id (E->id));
  out_cstring (g_a, 256);
  //write_secret_chat_file ();
  
  BN_clear_free (g);
  BN_clear_free (p);
  BN_clear_free (r);

  tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E, callback, callback_extra);
}
static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM *f,*ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
		return -1;
		}

	if (BN_ucmp(rsa->n, rsa->e) <= 0)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
		return -1;
		}

	/* for large moduli, enforce exponent limit */
	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
		{
		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
			{
			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
			return -1;
			}
		}
	
	if ((ctx=BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	f = BN_CTX_get(ctx);
	ret = BN_CTX_get(ctx);
	num=BN_num_bytes(rsa->n);
	buf = OPENSSL_malloc(num);
	if (!f || !ret || !buf)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
		break;
#ifndef OPENSSL_NO_SHA
	case RSA_PKCS1_OAEP_PADDING:
	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
		break;
#endif
	case RSA_SSLV23_PADDING:
		i=RSA_padding_add_SSLv23(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	default:
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,f) == NULL) goto err;
	
	if (BN_ucmp(f, rsa->n) >= 0)
		{
		/* usually the padding functions would catch this */
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
		goto err;
		}

	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
			goto err;

	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
		rsa->_method_mod_n)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(ret);
	i=BN_bn2bin(ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (buf != NULL) 
		{
		OPENSSL_cleanse(buf,num);
		OPENSSL_free(buf);
		}
	return(r);
	}
Example #4
0
int
ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	DSA_SIG *sig;
	const EVP_MD *evp_md = EVP_sha1();
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
	u_int rlen, slen, len, dlen;
	Buffer b;

	if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA &&
	    key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) {
		error("ssh_dss_sign: no DSA key");
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	sig = DSA_do_sign(digest, dlen, key->dsa);
	memset(digest, 'd', sizeof(digest));

	if (sig == NULL) {
		error("ssh_dss_sign: sign failed");
		return -1;
	}

	rlen = BN_num_bytes(sig->r);
	slen = BN_num_bytes(sig->s);
	if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
		error("bad sig size %u %u", rlen, slen);
		DSA_SIG_free(sig);
		return -1;
	}
	memset(sigblob, 0, SIGBLOB_LEN);
	BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
	BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
	DSA_SIG_free(sig);

	if (datafellows & SSH_BUG_SIGBLOB) {
		if (lenp != NULL)
			*lenp = SIGBLOB_LEN;
		if (sigp != NULL) {
			*sigp = xmalloc(SIGBLOB_LEN);
			memcpy(*sigp, sigblob, SIGBLOB_LEN);
		}
	} else {
		/* ietf-drafts */
		buffer_init(&b);
		buffer_put_cstring(&b, "ssh-dss");
		buffer_put_string(&b, sigblob, SIGBLOB_LEN);
		len = buffer_len(&b);
		if (lenp != NULL)
			*lenp = len;
		if (sigp != NULL) {
			*sigp = xmalloc(len);
			memcpy(*sigp, buffer_ptr(&b), len);
		}
		buffer_free(&b);
	}
	return 0;
}
Example #5
0
SESSION *session_init_client (void)
{
	SESSION *session;

	if ((session = (SESSION *) calloc (1, sizeof (SESSION))) == NULL)
		return NULL;

	session->client_OS = 0x00;	/* 0x00 == Windows, 0x01 == Mac OS X */
	memcpy(session->client_id, "\x01\x04\x01\x01", 4);
	session->client_revision = 99999;
	
	/*
	 * Client and server generate 16 random bytes each.
	 */
	RAND_bytes (session->client_random_16, 16);

	if ((session->rsa =
	     RSA_generate_key (1024, 65537, NULL, NULL)) == NULL) {
		DSFYDEBUG ("RSA key generation failed with error %lu\n",
			   ERR_get_error ());
	}
	assert (session->rsa != NULL);

	/*
	 * Create a private and public key.
	 * This, along with key signing, is used to securely
	 * agree on a session key for the Shannon stream cipher.
	 *
	 */
	session->dh = DH_new ();
	session->dh->p = BN_bin2bn (DH_prime, 96, NULL);
	session->dh->g = BN_bin2bn (DH_generator, 1, NULL);
	assert (DH_generate_key (session->dh) == 1);

	BN_bn2bin (session->dh->priv_key, session->my_priv_key);
	BN_bn2bin (session->dh->pub_key, session->my_pub_key);

	/*
	 * Found in Storage.dat (cache) at offset 16.
	 * Automatically generated, but we're lazy.
	 *
	 */
	memcpy (session->cache_hash,
		"\xf4\xc2\xaa\x05\xe8\x25\xa7\xb5\xe4\xe6\x59\x0f\x3d\xd0\xbe\x0a\xef\x20\x51\x95",
		20);
	session->cache_hash[0] = (unsigned char) getpid ();

	session->ap_sock = -1;
	session->username[0] = 0;
	session->server_host[0] = 0;
	session->server_port = 0;

	session->key_recv_IV = 0;
	session->key_send_IV = 0;

	session->user_info.username[0] = 0;
	session->user_info.country[0] = 0;
	session->user_info.server_host[0] = 0;
	session->user_info.server_port = 0;

	return session;
}
Example #6
0
/*
 * convert the RSA public key in the X.509 certificate in the BIO pointed to
 * by "input" to a JSON Web Key object
 */
static apr_byte_t oidc_jwk_rsa_bio_to_jwk(apr_pool_t *pool, BIO *input,
		cjose_jwk_t **jwk, int is_private_key, oidc_jose_error_t *err) {

	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	apr_byte_t rv = FALSE;

	cjose_jwk_rsa_keyspec key_spec;
	memset(&key_spec, 0, sizeof(cjose_jwk_rsa_keyspec));

	if (is_private_key) {
		/* get the private key struct from the BIO */
		if ((pkey = PEM_read_bio_PrivateKey(input, NULL, NULL, NULL)) == NULL) {
			oidc_jose_error_openssl(err, "PEM_read_bio_PrivateKey");
			goto end;
		}
	} else {
		/* read the X.509 struct */
		if ((x509 = PEM_read_bio_X509_AUX(input, NULL, NULL, NULL)) == NULL) {
			oidc_jose_error_openssl(err, "PEM_read_bio_X509_AUX");
			goto end;
		}
		/* get the public key struct from the X.509 struct */
		if ((pkey = X509_get_pubkey(x509)) == NULL) {
			oidc_jose_error_openssl(err, "X509_get_pubkey");
			goto end;
		}
	}

	/* get the RSA key from the public key struct */
	RSA *rsa = EVP_PKEY_get1_RSA(pkey);
	if (rsa == NULL) {
		oidc_jose_error_openssl(err, "EVP_PKEY_get1_RSA");
		goto end;
	}

	const BIGNUM *rsa_n, *rsa_e, *rsa_d;
#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined (LIBRESSL_VERSION_NUMBER)
	RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
#else
	rsa_n = rsa->n;
	rsa_e = rsa->e;
	rsa_d = rsa->d;
#endif

	RSA_free(rsa);

	/* convert the modulus bignum in to a key/len */
	key_spec.nlen = BN_num_bytes(rsa_n);
	key_spec.n = apr_pcalloc(pool, key_spec.nlen);
	BN_bn2bin(rsa_n, key_spec.n);

	/* convert the exponent bignum in to a key/len */
	key_spec.elen = BN_num_bytes(rsa_e);
	key_spec.e = apr_pcalloc(pool, key_spec.elen);
	BN_bn2bin(rsa_e, key_spec.e);

	/* convert the private exponent bignum in to a key/len */
	if (rsa_d != NULL) {
		key_spec.dlen = BN_num_bytes(rsa_d);
		key_spec.d = apr_pcalloc(pool, key_spec.dlen);
		BN_bn2bin(rsa_d, key_spec.d);
	}

	cjose_err cjose_err;
	*jwk = cjose_jwk_create_RSA_spec(&key_spec, &cjose_err);
	if (*jwk == NULL) {
		oidc_jose_error(err, "cjose_jwk_create_RSA_spec failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		goto end;
	}

	char *fingerprint = apr_pcalloc(pool, key_spec.nlen + key_spec.elen);
	memcpy(fingerprint, key_spec.n, key_spec.nlen);
	memcpy(fingerprint + key_spec.nlen, key_spec.e, key_spec.elen);

	if (oidc_jwk_set_or_generate_kid(pool, *jwk, NULL, fingerprint,
			key_spec.nlen + key_spec.elen, err) == FALSE) {
		goto end;
	}

	rv = TRUE;

	end:

	if (pkey)
		EVP_PKEY_free(pkey);
	if (x509)
		X509_free(x509);

	return rv;
}
Example #7
0
BigNumber *cop_convert_bignum(BIGNUM * bn)
{
	BigNumber *r = cop_bn_new_sz((size_t) BN_num_bytes(bn));
	BN_bn2bin(bn, r->number);
	return r;
}
Example #8
0
int MAIN(int argc, char **argv)
	{
	DH *dh=NULL;
	int i,badops=0,text=0;
#ifndef OPENSSL_NO_DSA
	int dsaparam=0;
#endif
	BIO *in=NULL,*out=NULL;
	int informat,outformat,check=0,noout=0,C=0,ret=1;
	char *infile,*outfile,*prog;
	char *inrand=NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif
	int num = 0, g = 0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	infile=NULL;
	outfile=NULL;
	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	prog=argv[0];
	argc--;
	argv++;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-check") == 0)
			check=1;
		else if (strcmp(*argv,"-text") == 0)
			text=1;
#ifndef OPENSSL_NO_DSA
		else if (strcmp(*argv,"-dsaparam") == 0)
			dsaparam=1;
#endif
		else if (strcmp(*argv,"-C") == 0)
			C=1;
		else if (strcmp(*argv,"-noout") == 0)
			noout=1;
		else if (strcmp(*argv,"-2") == 0)
			g=2;
		else if (strcmp(*argv,"-5") == 0)
			g=5;
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			}
		else if (((sscanf(*argv,"%d",&num) == 0) || (num <= 0)))
			goto bad;
		argv++;
		argc--;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] [numbits]\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
		BIO_printf(bio_err," -outform arg  output format - one of DER PEM\n");
		BIO_printf(bio_err," -in arg       input file\n");
		BIO_printf(bio_err," -out arg      output file\n");
#ifndef OPENSSL_NO_DSA
		BIO_printf(bio_err," -dsaparam     read or generate DSA parameters, convert to DH\n");
#endif
		BIO_printf(bio_err," -check        check the DH parameters\n");
		BIO_printf(bio_err," -text         print a text form of the DH parameters\n");
		BIO_printf(bio_err," -C            Output C code\n");
		BIO_printf(bio_err," -2            generate parameters using  2 as the generator value\n");
		BIO_printf(bio_err," -5            generate parameters using  5 as the generator value\n");
		BIO_printf(bio_err," numbits       number of bits in to generate (default 512)\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
#endif
		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err,"               - load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,"               the random number generator\n");
		BIO_printf(bio_err," -noout        no output\n");
		goto end;
		}

	ERR_load_crypto_strings();

#ifndef OPENSSL_NO_ENGINE
        setup_engine(bio_err, engine, 0);
#endif

	if (g && !num)
		num = DEFBITS;

#ifndef OPENSSL_NO_DSA
	if (dsaparam)
		{
		if (g)
			{
			BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
			goto end;
			}
		}
	else
#endif
		{
		/* DH parameters */
		if (num && !g)
			g = 2;
		}

	if(num) {

		BN_GENCB cb;
		BN_GENCB_set(&cb, dh_cb, bio_err);
		if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
			{
			BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
			}
		if (inrand != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				app_RAND_load_files(inrand));

#ifndef OPENSSL_NO_DSA
		if (dsaparam)
			{
			DSA *dsa = DSA_new();
			
			BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
			if(!dsa || !DSA_generate_parameters_ex(dsa, num,
						NULL, 0, NULL, NULL, &cb))
				{
				if(dsa) DSA_free(dsa);
				ERR_print_errors(bio_err);
				goto end;
				}

			dh = DSA_dup_DH(dsa);
			DSA_free(dsa);
			if (dh == NULL)
				{
				ERR_print_errors(bio_err);
				goto end;
				}
			}
		else
#endif
			{
			dh = DH_new();
			BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
			BIO_printf(bio_err,"This is going to take a long time\n");
			if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb))
				{
				ERR_print_errors(bio_err);
				goto end;
				}
			}

		app_RAND_write_file(NULL, bio_err);
	} else {

		in=BIO_new(BIO_s_file());
		if (in == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				goto end;
				}
			}

		if	(informat != FORMAT_ASN1 && informat != FORMAT_PEM)
			{
			BIO_printf(bio_err,"bad input format specified\n");
			goto end;
			}

#ifndef OPENSSL_NO_DSA
		if (dsaparam)
			{
			DSA *dsa;
			
			if (informat == FORMAT_ASN1)
				dsa=d2i_DSAparams_bio(in,NULL);
			else /* informat == FORMAT_PEM */
				dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
			
			if (dsa == NULL)
				{
				BIO_printf(bio_err,"unable to load DSA parameters\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			
			dh = DSA_dup_DH(dsa);
			DSA_free(dsa);
			if (dh == NULL)
				{
				ERR_print_errors(bio_err);
				goto end;
				}
			}
		else
#endif
			{
			if (informat == FORMAT_ASN1)
				dh=d2i_DHparams_bio(in,NULL);
			else /* informat == FORMAT_PEM */
				dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
			
			if (dh == NULL)
				{
				BIO_printf(bio_err,"unable to load DH parameters\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			}
		
		/* dh != NULL */
	}
	
	out=BIO_new(BIO_s_file());
	if (out == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			perror(outfile);
			goto end;
			}
		}


	if (text)
		{
		DHparams_print(out,dh);
		}
	
	if (check)
		{
		if (!DH_check(dh,&i))
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (i & DH_CHECK_P_NOT_PRIME)
			printf("p value is not prime\n");
		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
			printf("p value is not a safe prime\n");
		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
			printf("unable to check the generator value\n");
		if (i & DH_NOT_SUITABLE_GENERATOR)
			printf("the g value is not a generator\n");
		if (i == 0)
			printf("DH parameters appear to be ok.\n");
		}
	if (C)
		{
		unsigned char *data;
		int len,l,bits;

		len=BN_num_bytes(dh->p);
		bits=BN_num_bits(dh->p);
		data=(unsigned char *)OPENSSL_malloc(len);
		if (data == NULL)
			{
			perror("OPENSSL_malloc");
			goto end;
			}
		printf("#ifndef HEADER_DH_H\n"
		       "#include <openssl/dh.h>\n"
		       "#endif\n");
		printf("DH *get_dh%d()\n\t{\n",bits);

		l=BN_bn2bin(dh->p,data);
		printf("\tstatic unsigned char dh%d_p[]={",bits);
		for (i=0; i<l; i++)
			{
			if ((i%12) == 0) printf("\n\t\t");
			printf("0x%02X,",data[i]);
			}
		printf("\n\t\t};\n");

		l=BN_bn2bin(dh->g,data);
		printf("\tstatic unsigned char dh%d_g[]={",bits);
		for (i=0; i<l; i++)
			{
			if ((i%12) == 0) printf("\n\t\t");
			printf("0x%02X,",data[i]);
			}
		printf("\n\t\t};\n");

		printf("\tDH *dh;\n\n");
		printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
		printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
			bits,bits);
		printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
			bits,bits);
		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
		printf("\t\t{ DH_free(dh); return(NULL); }\n");
		if (dh->length)
			printf("\tdh->length = %ld;\n", dh->length);
		printf("\treturn(dh);\n\t}\n");
		OPENSSL_free(data);
		}


	if (!noout)
		{
		if 	(outformat == FORMAT_ASN1)
			i=i2d_DHparams_bio(out,dh);
		else if (outformat == FORMAT_PEM)
			i=PEM_write_bio_DHparams(out,dh);
		else	{
			BIO_printf(bio_err,"bad output format specified for outfile\n");
			goto end;
			}
		if (!i)
			{
			BIO_printf(bio_err,"unable to write DH parameters\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	ret=0;
end:
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (dh != NULL) DH_free(dh);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
int main2()
{


    // Seed RNG


    // Generate Key Pair
    ERR_load_crypto_strings();
    char error[400];

    int modulus_length = 2048; // bits

    unsigned long e = 65537;
    const char* e_hex = "100001";
    RSA *rsa = NULL;
    rsa = RSA_generate_key(modulus_length, e, NULL /*keygen_progress*/, NULL);
    if (rsa == NULL)
    {
        ERR_error_string(ERR_get_error(), error);
        printf("Failed to generate RSA key pair.OpenSSL error:\n %s\n", error);
        return -1;
    }

    unsigned char *n_hex = (unsigned char*)calloc(1, 2*2048/8);
    unsigned char *d_hex = (unsigned char*)calloc(1, 2*2048/8);
    unsigned char *p_hex = (unsigned char*)calloc(1, 2*2048/8);
    unsigned char *q_hex = (unsigned char*)calloc(1, 2*2048/8);
    if (!(  n_hex = (unsigned char*) BN_bn2hex((const BIGNUM*)rsa->n)  ))
    {
        printf("Modulo parsing error\n");
        return -1;
    }
    if (!(  d_hex = (unsigned char*) BN_bn2hex((const BIGNUM*)rsa->d)  ))
    {
        printf("Private exponent parsing error\n");
        return -1;
    }
    if (!(  p_hex = (unsigned char*) BN_bn2hex((const BIGNUM*)rsa->q)  ))
    {
        printf("Private exponent parsing error\n");
        return -1;
    }
    if (!(  q_hex = (unsigned char*) BN_bn2hex((const BIGNUM*)rsa->p)  ))
    {
        printf("Private exponent parsing error\n");
        return -1;
    }
    printf("Public modulus:\n\t%s\n", n_hex);
    printf("Private exponent:\n\t%s\n", d_hex);
    printf("Prime p:\n\t%s\n", p_hex);
    printf("Prime q:\n\t%s\n", q_hex);


    // Import Key Pair
    sc_cardctl_openpgp_keystore_info_t key_info;
    key_info.keytype = SC_OPENPGP_KEY_ENCR;
    key_info.keyformat = SC_OPENPGP_KEYFORMAT_STD;
    
    /* n */
    unsigned char* n_bin = (unsigned char*)calloc(1, modulus_length/8);
    key_info.n_len = BN_bn2bin(rsa->n, n_bin);
    key_info.n = n_bin;
 
    /* e */
    key_info.e = (u8*)calloc(1, 4);   
    hex_to_bin(e_hex, key_info.e, &(key_info.e_len));

    /* p */
    unsigned char* p_bin = (unsigned char*)calloc(1, strlen((const char*)p_hex)/2);
    key_info.p_len = BN_bn2bin(rsa->p, p_bin);
    key_info.p = p_bin;

    /* q */
    unsigned char* q_bin = (unsigned char*)calloc(1, strlen((const char*)q_hex)/2);
    key_info.q_len = BN_bn2bin(rsa->q, q_bin);
    key_info.q = q_bin;

    
    printf("Lengths: n = %lu\ne= %lu\np = %lu\nq = %lu\n",key_info.n_len, key_info.e_len, key_info.p_len, key_info.q_len);
    // List readers
    int r;
    card_t* card;
    reader_list* readerList = (reader_list*)malloc(sizeof(reader_list));
    r = pcsc_detect_readers(readerList);
    if( !r==SC_SUCCESS)
    {
        printf("pcsc_detect_readers: %s\n",sc_strerror(r));
        return -1;
    }

    connect_card(readerList->root->reader, &card);
    card_init(card);

    csVerifyAdminPIN(card, (unsigned char*)"12345678", 8);

    if( (r = pgp_store_key(card, &key_info)) != 0)
        printf("pgp_store_key error: %d\n",r);

    // Cleanups
    free(rsa);
    free(n_bin);
    free(n_hex);
    free(d_hex);

    return 0;
}
static void
eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
				 struct eap_method_ret *ret,
				 const struct wpabuf *reqData,
				 const u8 *payload, size_t payload_len)
{
	BIGNUM *x = NULL, *y = NULL;
	struct crypto_hash *hash;
	u32 cs;
	u16 grp;
	u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
	int offset;

	if (data->state != PWD_Confirm_Req) {
		ret->ignore = TRUE;
		goto fin;
	}

	if (payload_len != SHA256_MAC_LEN) {
		wpa_printf(MSG_INFO,
			   "EAP-pwd: Unexpected Confirm payload length %u (expected %u)",
			   (unsigned int) payload_len, SHA256_MAC_LEN);
		goto fin;
	}

	/*
	 * first build up the ciphersuite which is group | random_function |
	 *	prf
	 */
	grp = htons(data->group_num);
	ptr = (u8 *) &cs;
	os_memcpy(ptr, &grp, sizeof(u16));
	ptr += sizeof(u16);
	*ptr = EAP_PWD_DEFAULT_RAND_FUNC;
	ptr += sizeof(u8);
	*ptr = EAP_PWD_DEFAULT_PRF;

	/* each component of the cruft will be at most as big as the prime */
	if (((cruft = os_malloc(BN_num_bytes(data->grp->prime))) == NULL) ||
	    ((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): confirm allocation "
			   "fail");
		goto fin;
	}

	/*
	 * server's commit is H(k | server_element | server_scalar |
	 *			peer_element | peer_scalar | ciphersuite)
	 */
	hash = eap_pwd_h_init();
	if (hash == NULL)
		goto fin;

	/*
	 * zero the memory each time because this is mod prime math and some
	 * value may start with a few zeros and the previous one did not.
	 */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
	BN_bn2bin(data->k, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* server element: x, y */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->server_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): confirm point "
			   "assignment fail");
		goto fin;
	}
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* server scalar */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->server_scalar);
	BN_bn2bin(data->server_scalar, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));

	/* my element: x, y */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->my_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (server): confirm point "
			   "assignment fail");
		goto fin;
	}

	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* my scalar */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->my_scalar);
	BN_bn2bin(data->my_scalar, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));

	/* the ciphersuite */
	eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));

	/* random function fin */
	eap_pwd_h_final(hash, conf);

	ptr = (u8 *) payload;
	if (os_memcmp_const(conf, ptr, SHA256_MAC_LEN)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm did not verify");
		goto fin;
	}

	wpa_printf(MSG_DEBUG, "EAP-pwd (peer): confirm verified");

	/*
	 * compute confirm:
	 *  H(k | peer_element | peer_scalar | server_element | server_scalar |
	 *    ciphersuite)
	 */
	hash = eap_pwd_h_init();
	if (hash == NULL)
		goto fin;

	/* k */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
	BN_bn2bin(data->k, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* my element */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->my_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm point "
			   "assignment fail");
		goto fin;
	}
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* my scalar */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->my_scalar);
	BN_bn2bin(data->my_scalar, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));

	/* server element: x, y */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->server_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm point "
			   "assignment fail");
		goto fin;
	}
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));

	/* server scalar */
	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->server_scalar);
	BN_bn2bin(data->server_scalar, cruft + offset);
	eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));

	/* the ciphersuite */
	eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));

	/* all done */
	eap_pwd_h_final(hash, conf);

	if (compute_keys(data->grp, data->bnctx, data->k,
			 data->my_scalar, data->server_scalar, conf, ptr,
			 &cs, data->msk, data->emsk, data->session_id) < 0) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute MSK | "
			   "EMSK");
		goto fin;
	}

	data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
	if (data->outbuf == NULL)
		goto fin;

	wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);

fin:
	bin_clear_free(cruft, BN_num_bytes(data->grp->prime));
	BN_clear_free(x);
	BN_clear_free(y);
	if (data->outbuf == NULL) {
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
		eap_pwd_state(data, FAILURE);
	} else {
		eap_pwd_state(data, SUCCESS_ON_FRAG_COMPLETION);
	}
}
static int RSA_eay_public_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM f,ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	BN_init(&f);
	BN_init(&ret);

	if(FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
		goto err;
		}

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	num=BN_num_bytes(rsa->n);
	if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
		break;
#ifndef OPENSSL_NO_SHA
	case RSA_PKCS1_OAEP_PADDING:
	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
		break;
#endif
	case RSA_SSLV23_PADDING:
		i=RSA_padding_add_SSLv23(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	default:
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
	
	if (BN_ucmp(&f, rsa->n) >= 0)
		{	
		/* usually the padding functions would catch this */
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
		goto err;
		}

	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
		{
		BN_MONT_CTX* bn_mont_ctx;
		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
			goto err;
		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
			{
			BN_MONT_CTX_free(bn_mont_ctx);
			goto err;
			}
		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
			{
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
			if (rsa->_method_mod_n == NULL)
				{
				rsa->_method_mod_n = bn_mont_ctx;
				bn_mont_ctx = NULL;
				}
			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
			}
		if (bn_mont_ctx)
			BN_MONT_CTX_free(bn_mont_ctx);
		}
		
	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
		rsa->_method_mod_n)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(&ret);
	i=BN_bn2bin(&ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_clear_free(&f);
	BN_clear_free(&ret);
	if (buf != NULL) 
		{
		OPENSSL_cleanse(buf,num);
		OPENSSL_free(buf);
		}
	return(r);
	}
static void
eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
				struct eap_method_ret *ret,
				const struct wpabuf *reqData,
				const u8 *payload, size_t payload_len)
{
	EC_POINT *K = NULL, *point = NULL;
	BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL;
	u16 offset;
	u8 *ptr, *scalar = NULL, *element = NULL;
	size_t prime_len, order_len;

	if (data->state != PWD_Commit_Req) {
		ret->ignore = TRUE;
		goto fin;
	}

	prime_len = BN_num_bytes(data->grp->prime);
	order_len = BN_num_bytes(data->grp->order);

	if (payload_len != 2 * prime_len + order_len) {
		wpa_printf(MSG_INFO,
			   "EAP-pwd: Unexpected Commit payload length %u (expected %u)",
			   (unsigned int) payload_len,
			   (unsigned int) (2 * prime_len + order_len));
		goto fin;
	}

	if (((data->private_value = BN_new()) == NULL) ||
	    ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((cofactor = BN_new()) == NULL) ||
	    ((data->my_scalar = BN_new()) == NULL) ||
	    ((mask = BN_new()) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail");
		goto fin;
	}

	if (!EC_GROUP_get_cofactor(data->grp->group, cofactor, NULL)) {
		wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor "
			   "for curve");
		goto fin;
	}

	if (BN_rand_range(data->private_value, data->grp->order) != 1 ||
	    BN_rand_range(mask, data->grp->order) != 1 ||
	    BN_add(data->my_scalar, data->private_value, mask) != 1 ||
	    BN_mod(data->my_scalar, data->my_scalar, data->grp->order,
		   data->bnctx) != 1) {
		wpa_printf(MSG_INFO,
			   "EAP-pwd (peer): unable to get randomness");
		goto fin;
	}

	if (!EC_POINT_mul(data->grp->group, data->my_element, NULL,
			  data->grp->pwe, mask, data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): element allocation "
			   "fail");
		eap_pwd_state(data, FAILURE);
		goto fin;
	}

	if (!EC_POINT_invert(data->grp->group, data->my_element, data->bnctx))
	{
		wpa_printf(MSG_INFO, "EAP-PWD (peer): element inversion fail");
		goto fin;
	}
	BN_clear_free(mask);

	if (((x = BN_new()) == NULL) ||
	    ((y = BN_new()) == NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): point allocation fail");
		goto fin;
	}

	/* process the request */
	if (((data->server_scalar = BN_new()) == NULL) ||
	    ((data->k = BN_new()) == NULL) ||
	    ((K = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((point = EC_POINT_new(data->grp->group)) == NULL) ||
	    ((data->server_element = EC_POINT_new(data->grp->group)) == NULL))
	{
		wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation "
			   "fail");
		goto fin;
	}

	/* element, x then y, followed by scalar */
	ptr = (u8 *) payload;
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), x);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->prime), y);
	ptr += BN_num_bytes(data->grp->prime);
	BN_bin2bn(ptr, BN_num_bytes(data->grp->order), data->server_scalar);
	if (!EC_POINT_set_affine_coordinates_GFp(data->grp->group,
						 data->server_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element "
			   "fail");
		goto fin;
	}

	/* check to ensure server's element is not in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, point, NULL,
				  data->server_element, cofactor, NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
				   "server element by order!\n");
			goto fin;
		}
		if (EC_POINT_is_at_infinity(data->grp->group, point)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): server element "
				   "is at infinity!\n");
			goto fin;
		}
	}

	/* compute the shared key, k */
	if ((!EC_POINT_mul(data->grp->group, K, NULL, data->grp->pwe,
			   data->server_scalar, data->bnctx)) ||
	    (!EC_POINT_add(data->grp->group, K, K, data->server_element,
			   data->bnctx)) ||
	    (!EC_POINT_mul(data->grp->group, K, NULL, K, data->private_value,
			   data->bnctx))) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): computing shared key "
			   "fail");
		goto fin;
	}

	/* ensure that the shared key isn't in a small sub-group */
	if (BN_cmp(cofactor, BN_value_one())) {
		if (!EC_POINT_mul(data->grp->group, K, NULL, K, cofactor,
				  NULL)) {
			wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
				   "shared key point by order");
			goto fin;
		}
	}

	/*
	 * This check is strictly speaking just for the case above where
	 * co-factor > 1 but it was suggested that even though this is probably
	 * never going to happen it is a simple and safe check "just to be
	 * sure" so let's be safe.
	 */
	if (EC_POINT_is_at_infinity(data->grp->group, K)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): shared key point is at "
			   "infinity!\n");
		goto fin;
	}

	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, K, data->k,
						 NULL, data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to extract "
			   "shared secret from point");
		goto fin;
	}

	/* now do the response */
	if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
						 data->my_element, x, y,
						 data->bnctx)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): point assignment fail");
		goto fin;
	}

	if (((scalar = os_malloc(BN_num_bytes(data->grp->order))) == NULL) ||
	    ((element = os_malloc(BN_num_bytes(data->grp->prime) * 2)) ==
	     NULL)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): data allocation fail");
		goto fin;
	}

	/*
	 * bignums occupy as little memory as possible so one that is
	 * sufficiently smaller than the prime or order might need pre-pending
	 * with zeros.
	 */
	os_memset(scalar, 0, BN_num_bytes(data->grp->order));
	os_memset(element, 0, BN_num_bytes(data->grp->prime) * 2);
	offset = BN_num_bytes(data->grp->order) -
		BN_num_bytes(data->my_scalar);
	BN_bn2bin(data->my_scalar, scalar + offset);

	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
	BN_bn2bin(x, element + offset);
	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
	BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset);

	data->outbuf = wpabuf_alloc(BN_num_bytes(data->grp->order) +
				    2 * BN_num_bytes(data->grp->prime));
	if (data->outbuf == NULL)
		goto fin;

	/* we send the element as (x,y) follwed by the scalar */
	wpabuf_put_data(data->outbuf, element,
			2 * BN_num_bytes(data->grp->prime));
	wpabuf_put_data(data->outbuf, scalar, BN_num_bytes(data->grp->order));

fin:
	os_free(scalar);
	os_free(element);
	BN_clear_free(x);
	BN_clear_free(y);
	BN_clear_free(cofactor);
	EC_POINT_clear_free(K);
	EC_POINT_clear_free(point);
	if (data->outbuf == NULL)
		eap_pwd_state(data, FAILURE);
	else
		eap_pwd_state(data, PWD_Confirm_Req);
}
Example #13
0
static void bn_to_bin(BIGNUM* bn, unsigned char* bin, int n) {
    memset(bin, 0, n);
    int m = BN_num_bytes(bn);
    BN_bn2bin(bn, bin+n-m);
}
Example #14
0
/* Out: bytes_B, len_B.
 * 
 * On failure, bytes_B will be set to NULL and len_B will be set to 0
 */
struct SRPVerifier *  srp_verifier_new( SRP_HashAlgorithm alg, SRP_NGType ng_type, const char * username,
                                        const unsigned char * bytes_s, int len_s, 
                                        const unsigned char * bytes_v, int len_v,
                                        const unsigned char * bytes_A, int len_A,
                                        const unsigned char ** bytes_B, int * len_B,
                                        const char * n_hex, const char * g_hex )
{
    BIGNUM             *s    = BN_bin2bn(bytes_s, len_s, NULL);
    BIGNUM             *v    = BN_bin2bn(bytes_v, len_v, NULL);
    BIGNUM             *A    = BN_bin2bn(bytes_A, len_A, NULL);
    BIGNUM             *u    = 0;
    BIGNUM             *B    = BN_new();
    BIGNUM             *S    = BN_new();
    BIGNUM             *b    = BN_new();
    BIGNUM             *k    = 0;
    BIGNUM             *tmp1 = BN_new();
    BIGNUM             *tmp2 = BN_new();
    BN_CTX             *ctx  = BN_CTX_new();
    int                 ulen = strlen(username) + 1;
    NGConstant         *ng   = new_ng( ng_type, n_hex, g_hex );
    struct SRPVerifier *ver  = 0;

    *len_B   = 0;
    *bytes_B = 0;
    
    if( !s || !v || !A || !B || !S || !b || !tmp1 || !tmp2 || !ctx || !ng )
       goto cleanup_and_exit;
    
    ver = (struct SRPVerifier *) malloc( sizeof(struct SRPVerifier) );

    if (!ver)
       goto cleanup_and_exit;

    init_random(); /* Only happens once */
    
    ver->username = (char *) malloc( ulen );
    ver->hash_alg = alg;
    ver->ng       = ng;

    if (!ver->username)
    {
       free(ver);
       ver = 0;
       goto cleanup_and_exit;
    }
    
    memcpy( (char*)ver->username, username, ulen );
    
    ver->authenticated = 0;
        
    /* SRP-6a safety check */
    BN_mod(tmp1, A, ng->N, ctx);
    if ( !BN_is_zero(tmp1) )
    {
       BN_rand(b, 256, -1, 0);
       
       k = H_nn(alg, ng->N, ng->g);
       
       /* B = kv + g^b */
       BN_mul(tmp1, k, v, ctx);
       BN_mod_exp(tmp2, ng->g, b, ng->N, ctx);
       BN_add(B, tmp1, tmp2);
       
       u = H_nn(alg, A, B);
       
       /* S = (A *(v^u)) ^ b */
       BN_mod_exp(tmp1, v, u, ng->N, ctx);
       BN_mul(tmp2, A, tmp1, ctx);
       BN_mod_exp(S, tmp2, b, ng->N, ctx);
       
       hash_num(alg, S, ver->session_key);
       
       calculate_M( alg, ng, ver->M, username, s, A, B, ver->session_key );
       calculate_H_AMK( alg, ver->H_AMK, A, ver->M, ver->session_key );
       
       *len_B   = BN_num_bytes(B);
       *bytes_B = malloc( *len_B );
       
       if( !*bytes_B )
       {
          free( (void*) ver->username );
          free( ver );
          ver = 0;
          *len_B = 0;
          goto cleanup_and_exit;
       }
       
       BN_bn2bin( B, (unsigned char *) *bytes_B );
          
       ver->bytes_B = *bytes_B;
    }
    
 cleanup_and_exit:
    BN_free(s);
    BN_free(v);
    BN_free(A);
    if (u) BN_free(u);
    if (k) BN_free(k);
    BN_free(B);
    BN_free(S);
    BN_free(b);
    BN_free(tmp1);
    BN_free(tmp2);
    BN_CTX_free(ctx);
    
    return ver;
}
Example #15
0
TSS_RESULT
make_fake_key(TSS_HCONTEXT hContext, TSS_HKEY *hCAKey, RSA **rsa, int padding)
{
	TSS_RESULT result;
	UINT32 encScheme, size_n, pub_size;
	BYTE n[2048];
	TCPA_PUBKEY pubkey;
	UINT32 blob_size, size;
	BYTE *blob, pub_blob[1024];

	switch (padding) {
		case RSA_PKCS1_PADDING:
			encScheme = TSS_ES_RSAESPKCSV15;
			break;
		case RSA_PKCS1_OAEP_PADDING:
			encScheme = TSS_ES_RSAESOAEP_SHA1_MGF1;
			break;
		case RSA_NO_PADDING:
			encScheme = TSS_ES_NONE;
			break;
		default:
			return TSS_E_INTERNAL_ERROR;
			break;
	}

		//Create CA Key Object
	result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
	    TSS_KEY_TYPE_LEGACY|TSS_KEY_SIZE_2048, hCAKey);
	if (result != TSS_SUCCESS) {
		check("Tspi_Context_CreateObject", result);
		return result;
	}

		// generate a software key to represent the CA's key
	if ((*rsa = RSA_generate_key(2048, 65537, NULL, NULL)) == NULL) {
		ERR_print_errors_fp(stdout);
		return 254; // ?
	}

		// get the pub CA key
	if ((size_n = BN_bn2bin((*rsa)->n, n)) <= 0) {
		fprintf(stderr, "BN_bn2bin failed\n");
		ERR_print_errors_fp(stdout);
		RSA_free(*rsa);
                return 254; // ?
        }

	result = Tspi_GetAttribData(*hCAKey, TSS_TSPATTRIB_KEY_BLOB,
	    TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob);
	if (result != TSS_SUCCESS) {
		check("Tspi_GetAttribData", result);
		return result;
	}

	pub_size = blob_pubkey(pub_blob, 1024, blob, blob_size, n, size_n);

	result = Tspi_SetAttribData(*hCAKey, TSS_TSPATTRIB_KEY_BLOB,
	    TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, pub_size, pub_blob);
	if (result != TSS_SUCCESS) {
		check("Tspi_SetAttribData", result);
		return result;
	}

		// set the CA key's algorithm
	result = Tspi_SetAttribUint32(*hCAKey, TSS_TSPATTRIB_KEY_INFO,
				      TSS_TSPATTRIB_KEYINFO_ALGORITHM,
				      TSS_ALG_RSA);
	if (result != TSS_SUCCESS) {
		check("Tspi_SetAttribUint32", result);
		RSA_free(*rsa);
		return result;
	}

		// set the CA key's number of primes
	result = Tspi_SetAttribUint32(*hCAKey, TSS_TSPATTRIB_RSAKEY_INFO,
				      TSS_TSPATTRIB_KEYINFO_RSA_PRIMES,
				      2);
	if (result != TSS_SUCCESS) {
		check("Tspi_SetAttribUint32", result);
		RSA_free(*rsa);
		return result;
	}

		// set the CA key's encryption scheme
	result = Tspi_SetAttribUint32(*hCAKey, TSS_TSPATTRIB_KEY_INFO,
				      TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
				      encScheme);
	if (result != TSS_SUCCESS) {
		check("Tspi_SetAttribUint32", result);
		RSA_free(*rsa);
		return result;
	}

	return TSS_SUCCESS;
}
Example #16
0
*																			*
****************************************************************************/

/* The keys for testing the RSA, DSA, and Elgamal implementations. The key 
   values may be extracted with the following code pasted into the 
   generateKey() function in ctx_dsa.c/ctx_rsa.c */

#if 0
{
#include <stdio.h>

BYTE buffer[ CRYPT_MAX_PKCSIZE ];
int length, i;

printf( "static const RSA_KEY FAR_BSS rsaTestKey = {\n" );
length = BN_bn2bin( &contextInfoPtr->ctxPKC->rsaParam_n, buffer );
printf( "\t/* n */\n\t%d,", BN_num_bits( &contextInfoPtr->ctxPKC->rsaParam_n ) );
for( i = 0; i < length; i++ )
	{ if( !( i % 8 ) ) printf( "\n\t  " );
	printf( "0x%02X, ", buffer[ i ] ); }
length = BN_bn2bin( &contextInfoPtr->ctxPKC->rsaParam_e, buffer );
printf( "\n\n\t/* e */\n\t%d,", BN_num_bits( &contextInfoPtr->ctxPKC->rsaParam_e ) );
for( i = 0; i < length; i++ )
	{ if( !( i % 8 ) ) printf( "\n\t  " );
	printf( "0x%02X, ", buffer[ i ] ); }
length = BN_bn2bin( &contextInfoPtr->ctxPKC->rsaParam_d, buffer );
printf( "\n\n\t/* d */\n\t%d,", BN_num_bits( &contextInfoPtr->ctxPKC->rsaParam_d ) );
for( i = 0; i < length; i++ )
	{ if( !( i % 8 ) ) printf( "\n\t  " );
	printf( "0x%02X, ", buffer[ i ] ); }
length = BN_bn2bin( &contextInfoPtr->ctxPKC->rsaParam_p, buffer );
int
dsaparam_main(int argc, char **argv)
{
	DSA *dsa = NULL;
	int i, badops = 0, text = 0;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *infile, *outfile, *prog;
	int numbits = -1, num, genkey = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
#ifdef GENCB_TEST
	const char *errstr = NULL;
	int timebomb = 0;
#endif

	if (!load_config(bio_err, NULL))
		goto end;

	infile = NULL;
	outfile = NULL;
	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		}
#endif
#ifdef GENCB_TEST
		else if (strcmp(*argv, "-timebomb") == 0) {
			if (--argc < 1)
				goto bad;
			timebomb = strtonum(*(++argv), 0, INT_MAX, &errstr);
			if (errstr)
				goto bad;
		}
#endif
		else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (sscanf(*argv, "%d", &num) == 1) {
			/* generate a key */
			numbits = num;
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] [bits] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg   input format - DER or PEM\n");
		BIO_printf(bio_err, " -outform arg  output format - DER or PEM\n");
		BIO_printf(bio_err, " -in arg       input file\n");
		BIO_printf(bio_err, " -out arg      output file\n");
		BIO_printf(bio_err, " -text         print as text\n");
		BIO_printf(bio_err, " -C            Output C code\n");
		BIO_printf(bio_err, " -noout        no output\n");
		BIO_printf(bio_err, " -genkey       generate a DSA key\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, " -engine e     use engine e, possibly a hardware device.\n");
#endif
#ifdef GENCB_TEST
		BIO_printf(bio_err, " -timebomb n   interrupt keygen after <n> seconds\n");
#endif
		BIO_printf(bio_err, " number        number of bits to use for generating private key\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (numbits > 0) {
		BN_GENCB cb;
		BN_GENCB_set(&cb, dsa_cb, bio_err);
		dsa = DSA_new();
		if (!dsa) {
			BIO_printf(bio_err, "Error allocating DSA object\n");
			goto end;
		}
		BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
		BIO_printf(bio_err, "This could take some time\n");
#ifdef GENCB_TEST
		if (timebomb > 0) {
			struct sigaction act;
			act.sa_handler = timebomb_sigalarm;
			act.sa_flags = 0;
			BIO_printf(bio_err, "(though I'll stop it if not done within %d secs)\n",
			    timebomb);
			if (sigaction(SIGALRM, &act, NULL) != 0) {
				BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n");
				goto end;
			}
			alarm(timebomb);
		}
#endif
		if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) {
#ifdef GENCB_TEST
			if (stop_keygen_flag) {
				BIO_printf(bio_err, "DSA key generation time-stopped\n");
				/* This is an asked-for behaviour! */
				ret = 0;
				goto end;
			}
#endif
			ERR_print_errors(bio_err);
			BIO_printf(bio_err, "Error, DSA key generation failed\n");
			goto end;
		}
	} else if (informat == FORMAT_ASN1)
		dsa = d2i_DSAparams_bio(in, NULL);
	else if (informat == FORMAT_PEM)
		dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
	else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}
	if (dsa == NULL) {
		BIO_printf(bio_err, "unable to load DSA parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (text) {
		DSAparams_print(out, dsa);
	}
	if (C) {
		unsigned char *data;
		int l, len, bits_p;

		len = BN_num_bytes(dsa->p);
		bits_p = BN_num_bits(dsa->p);
		data = malloc(len + 20);
		if (data == NULL) {
			perror("malloc");
			goto end;
		}
		l = BN_bn2bin(dsa->p, data);
		printf("static unsigned char dsa%d_p[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->q, data);
		printf("static unsigned char dsa%d_q[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->g, data);
		printf("static unsigned char dsa%d_g[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		free(data);
		printf("\n\t};\n\n");

		printf("DSA *get_dsa%d()\n\t{\n", bits_p);
		printf("\tDSA *dsa;\n\n");
		printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
		printf("\tdsa->p = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->q = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->g = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
		    bits_p, bits_p);
		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
		printf("\treturn(dsa);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_DSAparams_bio(out, dsa);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAparams(out, dsa);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write DSA parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		DSA *dsakey;

		if ((dsakey = DSAparams_dup(dsa)) == NULL)
			goto end;
		if (!DSA_generate_key(dsakey)) {
			ERR_print_errors(bio_err);
			DSA_free(dsakey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_DSAPrivateKey_bio(out, dsakey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			DSA_free(dsakey);
			goto end;
		}
		DSA_free(dsakey);
	}
	ret = 0;

end:
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (dsa != NULL)
		DSA_free(dsa);
	
	return (ret);
}
Example #18
0
static unsigned 
rsa_verify(pgp_hash_alg_t type,
	   const uint8_t *hash,
	   size_t hash_length,
	   const pgp_rsa_sig_t *sig,
	   const pgp_rsa_pubkey_t *pubrsa)
{
	const uint8_t	*prefix;
	unsigned       	 n;
	unsigned       	 keysize;
	unsigned	 plen;
	unsigned	 debug_len_decrypted;
	uint8_t   	 sigbuf[NETPGP_BUFSIZ];
	uint8_t   	 hashbuf_from_sig[NETPGP_BUFSIZ];

	plen = 0;
	prefix = (const uint8_t *) "";
	keysize = BN_num_bytes(pubrsa->n);
	/* RSA key can't be bigger than 65535 bits, so... */
	if (keysize > sizeof(hashbuf_from_sig)) {
		(void) fprintf(stderr, "rsa_verify: keysize too big\n");
		return 0;
	}
	if ((unsigned) BN_num_bits(sig->sig) > 8 * sizeof(sigbuf)) {
		(void) fprintf(stderr, "rsa_verify: BN_numbits too big\n");
		return 0;
	}
	BN_bn2bin(sig->sig, sigbuf);

	n = pgp_rsa_public_decrypt(hashbuf_from_sig, sigbuf,
		(unsigned)(BN_num_bits(sig->sig) + 7) / 8, pubrsa);
	debug_len_decrypted = n;

	if (n != keysize) {
		/* obviously, this includes error returns */
		return 0;
	}

	/* XXX: why is there a leading 0? The first byte should be 1... */
	/* XXX: because the decrypt should use keysize and not sigsize? */
	if (hashbuf_from_sig[0] != 0 || hashbuf_from_sig[1] != 1) {
		return 0;
	}

	switch (type) {
	case PGP_HASH_MD5:
		prefix = prefix_md5;
		plen = sizeof(prefix_md5);
		break;
	case PGP_HASH_SHA1:
		prefix = prefix_sha1;
		plen = sizeof(prefix_sha1);
		break;
	case PGP_HASH_SHA256:
		prefix = prefix_sha256;
		plen = sizeof(prefix_sha256);
		break;
	default:
		(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
		return 0;
	}

	if (keysize - plen - hash_length < 10) {
		return 0;
	}

	for (n = 2; n < keysize - plen - hash_length - 1; ++n) {
		if (hashbuf_from_sig[n] != 0xff) {
			return 0;
		}
	}

	if (hashbuf_from_sig[n++] != 0) {
		return 0;
	}

	if (pgp_get_debug_level(__FILE__)) {
		hexdump(stderr, "sig hashbuf", hashbuf_from_sig, debug_len_decrypted);
		hexdump(stderr, "prefix", prefix, plen);
		hexdump(stderr, "sig hash", &hashbuf_from_sig[n + plen], hash_length);
		hexdump(stderr, "input hash", hash, hash_length);
	}
	return (memcmp(&hashbuf_from_sig[n], prefix, plen) == 0 &&
	        memcmp(&hashbuf_from_sig[n + plen], hash, hash_length) == 0);
}
Example #19
0
int MAIN(int argc, char **argv)
{
    DH *dh = NULL;
    int i, badops = 0, text = 0;
    BIO *in = NULL, *out = NULL;
    int informat, outformat, check = 0, noout = 0, C = 0, ret = 1;
    char *infile, *outfile, *prog;
# ifndef OPENSSL_NO_ENGINE
    char *engine;
# endif

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

# ifndef OPENSSL_NO_ENGINE
    engine = NULL;
# endif
    infile = NULL;
    outfile = NULL;
    informat = FORMAT_PEM;
    outformat = FORMAT_PEM;

    prog = argv[0];
    argc--;
    argv++;
    while (argc >= 1) {
        if (sgx_strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-outform") == 0) {
            if (--argc < 1)
                goto bad;
            outformat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (sgx_strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            outfile = *(++argv);
        }
# ifndef OPENSSL_NO_ENGINE
        else if (sgx_strcmp(*argv, "-engine") == 0) {
            if (--argc < 1)
                goto bad;
            engine = *(++argv);
        }
# endif
        else if (sgx_strcmp(*argv, "-check") == 0)
            check = 1;
        else if (sgx_strcmp(*argv, "-text") == 0)
            text = 1;
        else if (sgx_strcmp(*argv, "-C") == 0)
            C = 1;
        else if (sgx_strcmp(*argv, "-noout") == 0)
            noout = 1;
        else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
        BIO_printf(bio_err,
                   " -outform arg  output format - one of DER PEM\n");
        BIO_printf(bio_err, " -in arg       input file\n");
        BIO_printf(bio_err, " -out arg      output file\n");
        BIO_printf(bio_err, " -check        check the DH parameters\n");
        BIO_printf(bio_err,
                   " -text         print a text form of the DH parameters\n");
        BIO_printf(bio_err, " -C            Output C code\n");
        BIO_printf(bio_err, " -noout        no output\n");
# ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err,
                   " -engine e     use engine e, possibly a hardware device.\n");
# endif
        goto end;
    }

    ERR_load_crypto_strings();

# ifndef OPENSSL_NO_ENGINE
    setup_engine(bio_err, engine, 0);
# endif

    in = BIO_new(BIO_s_file());
    out = BIO_new(BIO_s_file());
    if ((in == NULL) || (out == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (infile == NULL)
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
    else {
        if (BIO_read_filename(in, infile) <= 0) {
            perror(infile);
            goto end;
        }
    }
    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
# endif
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            goto end;
        }
    }

    if (informat == FORMAT_ASN1)
        dh = d2i_DHparams_bio(in, NULL);
    else if (informat == FORMAT_PEM)
        dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
    else {
        BIO_printf(bio_err, "bad input format specified\n");
        goto end;
    }
    if (dh == NULL) {
        BIO_printf(bio_err, "unable to load DH parameters\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    if (text) {
        DHparams_print(out, dh);
# ifdef undef
        printf("p=");
        BN_print(stdout, dh->p);
        printf("\ng=");
        BN_print(stdout, dh->g);
        printf("\n");
        if (dh->length != 0)
            printf("recommended private length=%ld\n", dh->length);
# endif
    }

    if (check) {
        if (!DH_check(dh, &i)) {
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i & DH_CHECK_P_NOT_PRIME)
            printf("p value is not prime\n");
        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
            printf("p value is not a safe prime\n");
        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
            printf("unable to check the generator value\n");
        if (i & DH_NOT_SUITABLE_GENERATOR)
            printf("the g value is not a generator\n");
        if (i == 0)
            printf("DH parameters appear to be ok.\n");
    }
    if (C) {
        unsigned char *data;
        int len, l, bits;

        len = BN_num_bytes(dh->p);
        bits = BN_num_bits(dh->p);
        data = (unsigned char *)OPENSSL_malloc(len);
        if (data == NULL) {
            perror("OPENSSL_malloc");
            goto end;
        }
        l = BN_bn2bin(dh->p, data);
        printf("static unsigned char dh%d_p[]={", bits);
        for (i = 0; i < l; i++) {
            if ((i % 12) == 0)
                printf("\n\t");
            printf("0x%02X,", data[i]);
        }
        printf("\n\t};\n");

        l = BN_bn2bin(dh->g, data);
        printf("static unsigned char dh%d_g[]={", bits);
        for (i = 0; i < l; i++) {
            if ((i % 12) == 0)
                printf("\n\t");
            printf("0x%02X,", data[i]);
        }
        printf("\n\t};\n\n");

        printf("DH *get_dh%d()\n\t{\n", bits);
        printf("\tDH *dh;\n\n");
        printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
        printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
               bits, bits);
        printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
               bits, bits);
        printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
        printf("\t\treturn(NULL);\n");
        printf("\treturn(dh);\n\t}\n");
        OPENSSL_free(data);
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_DHparams_bio(out, dh);
        else if (outformat == FORMAT_PEM)
            i = PEM_write_bio_DHparams(out, dh);
        else {
            BIO_printf(bio_err, "bad output format specified for outfile\n");
            goto end;
        }
        if (!i) {
            BIO_printf(bio_err, "unable to write DH parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    ret = 0;
 end:
    if (in != NULL)
        BIO_free(in);
    if (out != NULL)
        BIO_free_all(out);
    if (dh != NULL)
        DH_free(dh);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Example #20
0
int test_builtin(BIO *out)
	{
	EC_builtin_curve *curves = NULL;
	size_t		crv_len = 0, n = 0;
	EC_KEY		*eckey = NULL, *wrong_eckey = NULL;
	EC_GROUP	*group;
	ECDSA_SIG	*ecdsa_sig = NULL;
	unsigned char	digest[20], wrong_digest[20];
	unsigned char	*signature = NULL;
	const unsigned char	*sig_ptr;
	unsigned char	*sig_ptr2;
	unsigned char	*raw_buf = NULL;
	unsigned int	sig_len, degree, r_len, s_len, bn_len, buf_len;
	int		nid, ret =  0;
	
	/* fill digest values with some random data */
	if (!RAND_pseudo_bytes(digest, 20) ||
	    !RAND_pseudo_bytes(wrong_digest, 20))
		{
		BIO_printf(out, "ERROR: unable to get random data\n");
		goto builtin_err;
		}

	/* create and verify a ecdsa signature with every availble curve
	 * (with ) */
	BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
		"with some internal curves:\n");

	/* get a list of all internal curves */
	crv_len = EC_get_builtin_curves(NULL, 0);

	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);

	if (curves == NULL)
		{
		BIO_printf(out, "malloc error\n");
		goto builtin_err;
		}
	
	if (!EC_get_builtin_curves(curves, crv_len))
		{
		BIO_printf(out, "unable to get internal curves\n");
		goto builtin_err;
		}

	/* now create and verify a signature for every curve */
	for (n = 0; n < crv_len; n++)
		{
		unsigned char dirt, offset;

		nid = curves[n].nid;
		if (nid == NID_ipsec4)
			continue;
		/* create new ecdsa key (== EC_KEY) */
		if ((eckey = EC_KEY_new()) == NULL)
			goto builtin_err;
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL)
			goto builtin_err;
		if (EC_KEY_set_group(eckey, group) == 0)
			goto builtin_err;
		EC_GROUP_free(group);
		degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
		if (degree < 160)
			/* drop the curve */ 
			{
			EC_KEY_free(eckey);
			eckey = NULL;
			continue;
			}
		BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
		/* create key */
		if (!EC_KEY_generate_key(eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		/* create second key */
		if ((wrong_eckey = EC_KEY_new()) == NULL)
			goto builtin_err;
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL)
			goto builtin_err;
		if (EC_KEY_set_group(wrong_eckey, group) == 0)
			goto builtin_err;
		EC_GROUP_free(group);
		if (!EC_KEY_generate_key(wrong_eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}

		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* check key */
		if (!EC_KEY_check_key(eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* create signature */
		sig_len = ECDSA_size(eckey);
		if ((signature = OPENSSL_malloc(sig_len)) == NULL)
			goto builtin_err;
                if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* verify signature */
		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* verify signature with the wrong key */
		if (ECDSA_verify(0, digest, 20, signature, sig_len, 
			wrong_eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* wrong digest */
		if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
			eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* wrong length */
		if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
			eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);

		/* Modify a single byte of the signature: to ensure we don't
		 * garble the ASN1 structure, we read the raw signature and
		 * modify a byte in one of the bignums directly. */
		sig_ptr = signature;
		if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}

		/* Store the two BIGNUMs in raw_buf. */
		r_len = BN_num_bytes(ecdsa_sig->r);
		s_len = BN_num_bytes(ecdsa_sig->s);
		bn_len = (degree + 7) / 8;
		if ((r_len > bn_len) || (s_len > bn_len))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		buf_len = 2 * bn_len;
		if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
			goto builtin_err;
		/* Pad the bignums with leading zeroes. */
		memset(raw_buf, 0, buf_len);
		BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
		BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);

		/* Modify a single byte in the buffer. */
		offset = raw_buf[10] % buf_len;
		dirt   = raw_buf[11] ? raw_buf[11] : 1;
		raw_buf[offset] ^= dirt;
		/* Now read the BIGNUMs back in from raw_buf. */
		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
			goto builtin_err;

		sig_ptr2 = signature;
		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		/* Sanity check: undo the modification and verify signature. */
		raw_buf[offset] ^= dirt;
		if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
			(BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
			goto builtin_err;

		sig_ptr2 = signature;
		sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		
		BIO_printf(out, " ok\n");
		/* cleanup */
		/* clean bogus errors */
		ERR_clear_error();
		OPENSSL_free(signature);
		signature = NULL;
		EC_KEY_free(eckey);
		eckey = NULL;
		EC_KEY_free(wrong_eckey);
		wrong_eckey = NULL;
		ECDSA_SIG_free(ecdsa_sig);
		ecdsa_sig = NULL;
		OPENSSL_free(raw_buf);
		raw_buf = NULL;
		}

	ret = 1;	
builtin_err:
	if (eckey)
		EC_KEY_free(eckey);
	if (wrong_eckey)
		EC_KEY_free(wrong_eckey);
	if (ecdsa_sig)
		ECDSA_SIG_free(ecdsa_sig);
	if (signature)
		OPENSSL_free(signature);
	if (raw_buf)
		OPENSSL_free(raw_buf);
	if (curves)
		OPENSSL_free(curves);

	return ret;
	}
Example #21
0
int main(int argc, char *argv[])
{
	int bitlens[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048 };
	BIGNUM *r_hw = BN_new();
	BIGNUM *r_sw = BN_new();
	BIGNUM *a = BN_new();
	BIGNUM *b = BN_new();
	BIGNUM *n = BN_new();
	BigNumber *bn_r;
	BigNumber *bn_a;
	BigNumber *bn_b;
	BigNumber *bn_n;
	int i = 0;
	int j = 0;
	int fail = 0;
	int total = 0;

	BN_CTX *ctx = BN_CTX_new();
	//bn_r = cop_bn_new_sz(256);

	for (j = 0; j < (sizeof(bitlens) / sizeof(int)); j++) {
		for (i = 0; i < NUM_TESTS; i++) {
			//printf("test %d-%d\n", i, j);

			// Generate random parameters
			BN_pseudo_rand(n, bitlens[j], 0, 1);
			BN_pseudo_rand(b, bitlens[j], 0, 0);
			BN_pseudo_rand_range(a, n);

			// Setup bignumbers
			size_t a_sz = BN_num_bytes(a);
			if (a_sz) {
				bn_a = cop_bn_new_sz(BN_num_bytes(a));
				BN_bn2bin(a, bn_a->number);
			} else {
				bn_a = cop_bn_new_int(0);
			}

			bn_b = cop_bn_new_sz(BN_num_bytes(b));
			bn_n = cop_bn_new_sz(BN_num_bytes(n));
			BN_bn2bin(b, bn_b->number);
			BN_bn2bin(n, bn_n->number);

			// Perform tests
			TEST_CASE_ASYM(mod_add, madd);
			TEST_CASE_ASYM(mod_sub, msub);
			TEST_CASE_ASYM(mod_mul, mmul);
			TEST_CASE_ASYM(mod_exp, mex);

			// Free memory
			cop_bn_free(bn_a);
			cop_bn_free(bn_b);
			cop_bn_free(bn_n);
		}
	}

	cop_bn_free(bn_r);
	BN_free(r_hw);
	BN_free(r_sw);
	BN_free(a);
	BN_free(b);
	BN_free(n);
	BN_CTX_free(ctx);

	printf("=== %s: %d/%d failures ===\n", argv[0], fail, total);
	return fail;
}
Example #22
0
/* Un petit mod_exp */
static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			const BIGNUM *m, BN_CTX *ctx)
	{
	/* I need somewhere to store temporary serialised values for
	 * use with the CryptoSwift API calls. A neat cheat - I'll use
	 * BIGNUMs from the BN_CTX but access their arrays directly as
	 * byte arrays <grin>. This way I don't have to clean anything
	 * up. */
	BIGNUM *modulus;
	BIGNUM *exponent;
	BIGNUM *argument;
	BIGNUM *result;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	int to_return, acquired;
 
	modulus = exponent = argument = result = NULL;
	to_return = 0; /* expect failure */
	acquired = 0;
 
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	modulus = BN_CTX_get(ctx);
	exponent = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
	if(!result)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
		!bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_EXP;
	sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
		(unsigned char *)modulus->d);
	sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
	sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
		(unsigned char *)exponent->d);
	sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = BN_num_bytes(m);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(acquired)
		release_context(hac);
	BN_CTX_end(ctx);
	return to_return;
	}
Example #23
0
/*-
 * This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 * Finally an optional KDF is applied.
 */
static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
                            EC_KEY *ecdh,
                            void *(*KDF) (const void *in, size_t inlen,
                                          void *out, size_t *outlen))
{
    BN_CTX *ctx;
    EC_POINT *tmp = NULL;
    BIGNUM *x = NULL, *y = NULL;
    const BIGNUM *priv_key;
    const EC_GROUP *group;
    int ret = -1;
    size_t buflen, len;
    unsigned char *buf = NULL;

    if (outlen > INT_MAX) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of,
                                                                 * anyway */
        return -1;
    }

    if ((ctx = BN_CTX_new()) == NULL)
        goto err;
    BN_CTX_start(ctx);
    x = BN_CTX_get(ctx);
    y = BN_CTX_get(ctx);

    priv_key = EC_KEY_get0_private_key(ecdh);
    if (priv_key == NULL) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE);
        goto err;
    }

    group = EC_KEY_get0_group(ecdh);
    if ((tmp = EC_POINT_new(group)) == NULL) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
        goto err;
    }

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
        NID_X9_62_prime_field) {
        if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
            goto err;
        }
    } else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
            goto err;
        }
    }

    buflen = (EC_GROUP_get_degree(group) + 7) / 8;
    len = BN_num_bytes(x);
    if (len > buflen) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    if ((buf = OPENSSL_malloc(buflen)) == NULL) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    memset(buf, 0, buflen - len);
    if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
        ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
        goto err;
    }

    if (KDF != 0) {
        if (KDF(buf, buflen, out, &outlen) == NULL) {
            ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED);
            goto err;
        }
        ret = outlen;
    } else {
        /* no KDF, just copy as much as we can */
        if (outlen > buflen)
            outlen = buflen;
        memcpy(out, buf, outlen);
        ret = outlen;
    }

 err:
    if (tmp)
        EC_POINT_free(tmp);
    if (ctx)
        BN_CTX_end(ctx);
    if (ctx)
        BN_CTX_free(ctx);
    if (buf)
        OPENSSL_free(buf);
    return (ret);
}
Example #24
0
/* Un petit mod_exp chinois */
static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			const BIGNUM *q, const BIGNUM *dmp1,
			const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
	{
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	BIGNUM *result = NULL;
	BIGNUM *argument = NULL;
	int to_return = 0; /* expect failure */
	int acquired = 0;

	sw_param.up.crt.p.value = NULL;
	sw_param.up.crt.q.value = NULL;
	sw_param.up.crt.dmp1.value = NULL;
	sw_param.up.crt.dmq1.value = NULL;
	sw_param.up.crt.iqmp.value = NULL;
 
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;

	/* Prepare the params */
	argument = BN_new();
	result = BN_new();
	if(!result || !argument)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}


	sw_param.type = SW_ALG_CRT;
	/************************************************************************/
	/* 04/02/2003                                                           */
	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
	/* limitation of cswift with values not a multiple of 32                */
	/************************************************************************/
	if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(	!bn_wexpand(argument, a->top) ||
			!bn_wexpand(result, p->top + q->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}

	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = 2 * BN_num_bytes(p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(sw_param.up.crt.p.value)
		OPENSSL_free(sw_param.up.crt.p.value);
	if(sw_param.up.crt.q.value)
		OPENSSL_free(sw_param.up.crt.q.value);
	if(sw_param.up.crt.dmp1.value)
		OPENSSL_free(sw_param.up.crt.dmp1.value);
	if(sw_param.up.crt.dmq1.value)
		OPENSSL_free(sw_param.up.crt.dmq1.value);
	if(sw_param.up.crt.iqmp.value)
		OPENSSL_free(sw_param.up.crt.iqmp.value);
	if(result)
		BN_free(result);
	if(argument)
		BN_free(argument);
	if(acquired)
		release_context(hac);
	return to_return;
	}
Example #25
0
void tgl_do_send_accept_encr_chat (struct tgl_state *TLS, struct tgl_secret_chat *E, unsigned char *random, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
  int i;
  int ok = 0;
  for (i = 0; i < 64; i++) {
    if (E->key[i]) {
      ok = 1;
      break;
    }
  }
  if (ok) { 
    if (callback) {
      callback (TLS, callback_extra, 1, E);
    }
    return; 
  } // Already generated key for this chat
  assert (E->g_key);
  assert (TLS->BN_ctx);
  unsigned char random_here[256];
  tglt_secure_random (random_here, 256);
  for (i = 0; i < 256; i++) {
    random[i] ^= random_here[i];
  }
  BIGNUM *b = BN_bin2bn (random, 256, 0);
  ensure_ptr (b);
  BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0);
  ensure_ptr (g_a);
  assert (tglmp_check_g_a (TLS, TLS->encr_prime_bn, g_a) >= 0);
  //if (!ctx) {
  //  ctx = BN_CTX_new ();
  //  ensure_ptr (ctx);
  //}
  BIGNUM *p = TLS->encr_prime_bn;
  BIGNUM *r = BN_new ();
  ensure_ptr (r);
  ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx));
  static unsigned char kk[256];
  memset (kk, 0, sizeof (kk));
  BN_bn2bin (r, kk + (256 - BN_num_bytes (r)));
  static unsigned char sha_buffer[20];
  sha1 (kk, 256, sha_buffer);

  long long fingerprint = *(long long *)(sha_buffer + 12);

  //bl_do_encr_chat_set_key (TLS, E, kk, *(long long *)(sha_buffer + 12));
  //bl_do_encr_chat_set_sha (TLS, E, sha_buffer);

  int state = sc_ok;

  bl_do_encr_chat_new (TLS, tgl_get_peer_id (E->id), 
    NULL, NULL, NULL, NULL, 
    kk, NULL, sha_buffer, &state, 
    NULL, NULL, NULL, NULL, NULL, 
    &fingerprint, 
    TGL_FLAGS_UNCHANGED
  );

  clear_packet ();
  out_int (CODE_messages_accept_encryption);
  out_int (CODE_input_encrypted_chat);
  out_int (tgl_get_peer_id (E->id));
  out_long (E->access_hash);
  
  ensure (BN_set_word (g_a, TLS->encr_root));
  ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx));
  static unsigned char buf[256];
  memset (buf, 0, sizeof (buf));
  BN_bn2bin (r, buf + (256 - BN_num_bytes (r)));
  out_cstring ((void *)buf, 256);

  out_long (E->key_fingerprint);
  BN_clear_free (b);
  BN_clear_free (g_a);
  BN_clear_free (r);

  tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_accept_methods, E, callback, callback_extra);
}
Example #26
0
static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *result = NULL;
	DSA_SIG *to_return = NULL;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
	if(!result)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->priv_key->top) ||
			!bn_wexpand(result, dsa->p->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = dlen;
	arg.value = (unsigned char *)dgst;
	res.nbytes = BN_num_bytes(dsa->p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	if((to_return = DSA_SIG_new()) == NULL)
		goto err;
	to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
	to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return to_return;
	}
Example #27
0
size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
                               unsigned char *buf, size_t len, BN_CTX *ctx)
{
    size_t ret;
    BN_CTX *new_ctx = NULL;
    int used_ctx = 0;
    BIGNUM *x, *y;
    size_t field_len, i, skip;

    if ((form != POINT_CONVERSION_COMPRESSED)
            && (form != POINT_CONVERSION_UNCOMPRESSED)
            && (form != POINT_CONVERSION_HYBRID))
    {
        ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
        goto err;
    }

    if (EC_POINT_is_at_infinity(group, point))
    {
        /* encodes to a single 0 octet */
        if (buf != NULL)
        {
            if (len < 1)
            {
                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
                return 0;
            }
            buf[0] = 0;
        }
        return 1;
    }


    /* ret := required output buffer length */
    field_len = BN_num_bytes(&group->field);
    ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;

    /* if 'buf' is NULL, just return required length */
    if (buf != NULL)
    {
        if (len < ret)
        {
            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
            goto err;
        }

        if (ctx == NULL)
        {
            ctx = new_ctx = BN_CTX_new();
            if (ctx == NULL)
                return 0;
        }

        BN_CTX_start(ctx);
        used_ctx = 1;
        x = BN_CTX_get(ctx);
        y = BN_CTX_get(ctx);
        if (y == NULL) goto err;

        if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;

        if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
            buf[0] = form + 1;
        else
            buf[0] = form;

        i = 1;

        skip = field_len - BN_num_bytes(x);
        if (skip > field_len)
        {
            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
            goto err;
        }
        while (skip > 0)
        {
            buf[i++] = 0;
            skip--;
        }
        skip = BN_bn2bin(x, buf + i);
        i += skip;
        if (i != 1 + field_len)
        {
            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
            goto err;
        }

        if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
        {
            skip = field_len - BN_num_bytes(y);
            if (skip > field_len)
            {
                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
                goto err;
            }
            while (skip > 0)
            {
                buf[i++] = 0;
                skip--;
            }
            skip = BN_bn2bin(y, buf + i);
            i += skip;
        }

        if (i != ret)
        {
            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }

    if (used_ctx)
        BN_CTX_end(ctx);
    if (new_ctx != NULL)
        BN_CTX_free(new_ctx);
    return ret;

err:
    if (used_ctx)
        BN_CTX_end(ctx);
    if (new_ctx != NULL)
        BN_CTX_free(new_ctx);
    return 0;
}
Example #28
0
static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
				DSA_SIG *sig, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg[2], res;
	unsigned long sig_result;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *argument = NULL;
	int to_return = -1;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	if(!argument)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->pub_key->top) ||
			!bn_wexpand(argument, 40))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg[0].nbytes = dgst_len;
	arg[0].value = (unsigned char *)dgst;
	arg[1].nbytes = 40;
	arg[1].value = (unsigned char *)argument->d;
	memset(arg[1].value, 0, 40);
	BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
	BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
	res.nbytes = 4; /* unsigned long */
	res.value = (unsigned char *)(&sig_result);
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	to_return = ((sig_result == 0) ? 0 : 1);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return to_return;
	}
/* signing */
static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM *f, *ret, *res;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;
	int local_blinding = 0;
	/* Used only if the blinding structure is shared. A non-NULL unblind
	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
	 * the unblinding factor outside the blinding structure. */
	BIGNUM *unblind = NULL;
	BN_BLINDING *blinding = NULL;

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	f   = BN_CTX_get(ctx);
	ret = BN_CTX_get(ctx);
	num = BN_num_bytes(rsa->n);
	buf = OPENSSL_malloc(num);
	if(!f || !ret || !buf)
		{
		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
		break;
	case RSA_X931_PADDING:
		i=RSA_padding_add_X931(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	case RSA_SSLV23_PADDING:
	default:
		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,f) == NULL) goto err;
	
	if (BN_ucmp(f, rsa->n) >= 0)
		{	
		/* usually the padding functions would catch this */
		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
		goto err;
		}

	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
		{
		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
		if (blinding == NULL)
			{
			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
			goto err;
			}
		}
	
	if (blinding != NULL)
		{
		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL))
			{
			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
			goto err;
		}

	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
		((rsa->p != NULL) &&
		(rsa->q != NULL) &&
		(rsa->dmp1 != NULL) &&
		(rsa->dmq1 != NULL) &&
		(rsa->iqmp != NULL)) )
		{ 
		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
		}
	else
		{
		BIGNUM local_d;
		BIGNUM *d = NULL;
		
		if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
			{
			BN_init(&local_d);
			d = &local_d;
			BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
			}
		else
			d= rsa->d;

		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
			if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
				goto err;

		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
				rsa->_method_mod_n)) goto err;
		}

	if (blinding)
		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
			goto err;

	if (padding == RSA_X931_PADDING)
		{
		BN_sub(f, rsa->n, ret);
		if (BN_cmp(ret, f))
			res = f;
		else
			res = ret;
		}
	else
		res = ret;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(res);
	i=BN_bn2bin(res,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (buf != NULL)
		{
		OPENSSL_cleanse(buf,num);
		OPENSSL_free(buf);
		}
	return(r);
	}
int encrypt_and_send(byte * msg , const int length){
		
	if(encType == PLAIN)	//send plain text
	{
		if(writeInPipe(outputChannel, (byte *) msg , length) < 0)
		{
			fprintf(stderr , " **** Communication phase write error **** \n\n");
			return -1;	
		}	
		return 0;
	}
	
	if(encType == RSA512){
		BIGNUM *message = BN_new();	
		
		byte fullMsg[RSA512_BYTE_LENGTH];
		
		memset(fullMsg , 0 , sizeof(byte) * RSA512_BYTE_LENGTH);
		memcpy(fullMsg , msg , sizeof(byte) * length);
		
		message = BN_bin2bn((const unsigned char *) fullMsg, RSA512_BYTE_LENGTH , NULL);
		
		rsaEXP(message , &client512Rsa);	//Encrypt with server RSA public key
		
		BN_bn2bin(message , fullMsg);

		if(writeInPipe(outputChannel, (byte *) fullMsg , RSA512_BYTE_LENGTH) < 0)
		{
			fprintf(stderr , " **** Communication phase write error **** \n\n");
			return -1;	
		}
		
		printf("RSA512 : %s\n", BN_bn2hex(message));
		BN_free(message);		
		return 0;
	}
	
	if(encType == RSA64){
		BIGNUM *message = BN_new();
		
		byte fullMsg[RSA64_BYTE_LENGTH];
		
		memset(fullMsg , 0 , sizeof(byte) * RSA64_BYTE_LENGTH);
		memcpy(fullMsg , msg , sizeof(byte) * length);
		
		message = BN_bin2bn((const unsigned char *) fullMsg, RSA64_BYTE_LENGTH , NULL);
		
		rsaEXP(message , &client64Rsa);	//Encrypt with server RSA public key
				
		BN_bn2bin(message , fullMsg);

		if(writeInPipe(outputChannel, (byte *) fullMsg , RSA64_BYTE_LENGTH) < 0)
		{
			fprintf(stderr , " **** Communication phase write error **** \n\n");
			return -1;	
		}
		
		printf("RSA64 : %s\n", BN_bn2hex(message));
		BN_free(message);		
		return 0;
	}
	
}