#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/ts.h>
#include <openssl/asn1t.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/aes.h>
#include <openssl/des.h>
#include <openssl/hmac.h>
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/ecdh.h>

#define TLS_MD_MASTER_SECRET_CONST		"master secret"
#define TLS_MD_MASTER_SECRET_CONST_SIZE		13
#define SSL3_RANDOM_SIZE			32
void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen)
{
	int i;
	unsigned char highByte, lowByte;
	for (i = 0; i < sourceLen; i++)
	{
		highByte = source[i] >> 4;
		lowByte = source[i] & 0x0f;
		highByte += 0x30;
		if (highByte > 0x39)
			dest[i * 2] = highByte + 0x07;
		else
			dest[i * 2] = highByte;
		lowByte += 0x30;
		if (lowByte > 0x39)
			dest[i * 2 + 1] = lowByte + 0x07;
		else
			dest[i * 2 + 1] = lowByte;
	}
	return;
}
void HexStrToByte(const char* source, unsigned char* dest, int sourceLen)
{
	int i;
	unsigned char highByte, lowByte;
	for (i = 0; i < sourceLen; i += 2)
	{
		highByte = toupper(source[i]);
		lowByte = toupper(source[i + 1]);
		if (highByte > 0x39)
			highByte -= 0x37;
		else
			highByte -= 0x30;
		if (lowByte > 0x39)
			lowByte -= 0x37;
		else
			lowByte -= 0x30;
		dest[i / 2] = (highByte << 4) | lowByte;
	}
	return;
}

void dump_str(const char* att, char* str, int len)
{
	char dest[8192] = { 0 };
	ByteToHexStr(str, dest, len);
	printf("%s:%s\n\n", att, dest);
}
static int tls1_P_hash(const EVP_MD* md, const unsigned char* sec,
	int sec_len,
	const void* seed1, int seed1_len,
	const void* seed2, int seed2_len,
	const void* seed3, int seed3_len,
	const void* seed4, int seed4_len,
	const void* seed5, int seed5_len,
	unsigned char* out, int olen)
{
	int chunk;
	size_t j;
	EVP_MD_CTX ctx, ctx_tmp;
	EVP_PKEY* mac_key;
	unsigned char A1[EVP_MAX_MD_SIZE];
	size_t A1_len;
	int ret = 0;

	chunk = EVP_MD_size(md);
	OPENSSL_assert(chunk >= 0);

	EVP_MD_CTX_init(&ctx);
	EVP_MD_CTX_init(&ctx_tmp);
	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
	EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
	if (!mac_key)
		goto err;
	if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key))
		goto err;
	if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key))
		goto err;
	if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
		goto err;
	if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
		goto err;
	if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
		goto err;
	if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len))
		goto err;
	if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len))
		goto err;
	if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
		goto err;

	for (;;)
	{
		
		if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key))
			goto err;
		if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key))
			goto err;
		if (!EVP_DigestSignUpdate(&ctx, A1, A1_len))
			goto err;
		if (!EVP_DigestSignUpdate(&ctx_tmp, A1, A1_len))
			goto err;
		if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
			goto err;
		if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
			goto err;
		if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
			goto err;
		if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len))
			goto err;
		if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len))
			goto err;

		if (olen > chunk)
		{
			if (!EVP_DigestSignFinal(&ctx, out, &j))
				goto err;
			out += j;
			olen -= j;
			
			if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len))
				goto err;
		}
		else	
		{
			if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
				goto err;
			memcpy(out, A1, olen);
			break;
		}
	}
	ret = 1;
err:
	EVP_PKEY_free(mac_key);
	EVP_MD_CTX_cleanup(&ctx);
	EVP_MD_CTX_cleanup(&ctx_tmp);
	OPENSSL_cleanse(A1, sizeof(A1));
	return ret;
}
#define TLS1_PRF_DGST_SHIFT 10
#define SSL_HANDSHAKE_MAC_MD5 0x10
#define SSL_HANDSHAKE_MAC_SHA 0x20
#define SSL_HANDSHAKE_MAC_GOST94 0x40
#define SSL_HANDSHAKE_MAC_SHA256 0x80
#define SSL_HANDSHAKE_MAC_SHA384 0x100
#define SSL_MAX_DIGEST 6
#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
#define SSL_MD_NUM_IDX	SSL_MAX_DIGEST 
#define SSL_ENC_DES_IDX		0
#define SSL_ENC_3DES_IDX	1
#define SSL_ENC_RC4_IDX		2
#define SSL_ENC_RC2_IDX		3
#define SSL_ENC_IDEA_IDX	4
#define SSL_ENC_NULL_IDX	5
#define SSL_ENC_AES128_IDX	6
#define SSL_ENC_AES256_IDX	7
#define SSL_ENC_CAMELLIA128_IDX	8
#define SSL_ENC_CAMELLIA256_IDX	9
#define SSL_ENC_GOST89_IDX	10
#define SSL_ENC_SEED_IDX    	11
#define SSL_ENC_AES128GCM_IDX	12
#define SSL_ENC_AES256GCM_IDX	13
#define SSL_ENC_NUM_IDX		14
#define SSL_MD_MD5_IDX	0
#define SSL_MD_SHA1_IDX	1
#define SSL_MD_GOST94_IDX 2
#define SSL_MD_GOST89MAC_IDX 3
#define SSL_MD_SHA256_IDX 4
#define SSL_MD_SHA384_IDX 5
static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = {
	SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
	SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256,
	SSL_HANDSHAKE_MAC_SHA384
};
#define SSL_ENC_NUM_IDX		14
static const EVP_CIPHER* ssl_cipher_methods[SSL_ENC_NUM_IDX] = {
	NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
static const EVP_MD* ssl_digest_methods[SSL_MD_NUM_IDX] = {
	NULL,NULL,NULL,NULL,NULL,NULL
};
static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = {
	0,0,0,0,0,0
};
#define SSL_MAX_MASTER_KEY_LENGTH		48
void ssl_load_ciphers(void)
{
	OpenSSL_add_all_algorithms();
	ssl_cipher_methods[SSL_ENC_DES_IDX] =
		EVP_get_cipherbyname(SN_des_cbc);
	ssl_cipher_methods[SSL_ENC_3DES_IDX] =
		EVP_get_cipherbyname(SN_des_ede3_cbc);
	ssl_cipher_methods[SSL_ENC_RC4_IDX] =
		EVP_get_cipherbyname(SN_rc4);
	ssl_cipher_methods[SSL_ENC_RC2_IDX] =
		EVP_get_cipherbyname(SN_rc2_cbc);
#ifndef OPENSSL_NO_IDEA
	ssl_cipher_methods[SSL_ENC_IDEA_IDX] =
		EVP_get_cipherbyname(SN_idea_cbc);
#else
	ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL;
#endif
	ssl_cipher_methods[SSL_ENC_AES128_IDX] =
		EVP_get_cipherbyname(SN_aes_128_cbc);
	ssl_cipher_methods[SSL_ENC_AES256_IDX] =
		EVP_get_cipherbyname(SN_aes_256_cbc);
	ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] =
		EVP_get_cipherbyname(SN_camellia_128_cbc);
	ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] =
		EVP_get_cipherbyname(SN_camellia_256_cbc);
	ssl_cipher_methods[SSL_ENC_GOST89_IDX] =
		EVP_get_cipherbyname(SN_gost89_cnt);
	ssl_cipher_methods[SSL_ENC_SEED_IDX] =
		EVP_get_cipherbyname(SN_seed_cbc);

	ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] =
		EVP_get_cipherbyname(SN_aes_128_gcm);
	ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] =
		EVP_get_cipherbyname(SN_aes_256_gcm);

	ssl_digest_methods[SSL_MD_MD5_IDX] =
		EVP_get_digestbyname(SN_md5);
	ssl_mac_secret_size[SSL_MD_MD5_IDX] =
		EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
	ssl_digest_methods[SSL_MD_SHA1_IDX] =
		EVP_get_digestbyname(SN_sha1);
	ssl_mac_secret_size[SSL_MD_SHA1_IDX] =
		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]);
	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
	ssl_digest_methods[SSL_MD_GOST94_IDX] =
		EVP_get_digestbyname(SN_id_GostR3411_94);
	if (ssl_digest_methods[SSL_MD_GOST94_IDX])
	{
		ssl_mac_secret_size[SSL_MD_GOST94_IDX] =
			EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]);
		OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0);
	}
	ssl_digest_methods[SSL_MD_GOST89MAC_IDX] =
		EVP_get_digestbyname(SN_id_Gost28147_89_MAC);

	ssl_digest_methods[SSL_MD_SHA256_IDX] =
		EVP_get_digestbyname(SN_sha256);
	ssl_mac_secret_size[SSL_MD_SHA256_IDX] =
		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]);
	ssl_digest_methods[SSL_MD_SHA384_IDX] =
		EVP_get_digestbyname(SN_sha384);
	ssl_mac_secret_size[SSL_MD_SHA384_IDX] =
		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]);
}

int ssl_get_handshake_digest(int idx, long* mask, const EVP_MD** md)
{
	if (idx < 0 || idx >= SSL_MD_NUM_IDX)
	{
		return 0;
	}
	*mask = ssl_handshake_digest_flag[idx];
	if (*mask)
		*md = ssl_digest_methods[idx];
	else
		*md = NULL;
	return 1;
}

static int tls1_PRF(long digest_mask,
	const void* seed1, int seed1_len,
	const void* seed2, int seed2_len,
	const void* seed3, int seed3_len,
	const void* seed4, int seed4_len,
	const void* seed5, int seed5_len,
	const unsigned char* sec, int slen,
	unsigned char* out1,
	unsigned char* out2, int olen)
{
	int len, i, idx, count;
	const unsigned char* S1;
	long m;
	const EVP_MD* md;
	int ret = 0;

	/* Count number of digests and partition sec evenly */
	count = 0;
	for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
		if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
	}
	len = slen / count;
	if (count == 1)
		slen = 0;
	S1 = sec;
	memset(out1, 0, olen);
	for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
		if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) {
			if (!md) {
				SSLerr(SSL_F_TLS1_PRF,
					SSL_R_UNSUPPORTED_DIGEST_TYPE);
				goto err;
			}
			if (!tls1_P_hash(md, S1, len + (slen & 1),
				seed1, seed1_len, seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, seed5_len,
				out2, olen))
				goto err;
			S1 += len;
			for (i = 0; i < olen; i++)
			{
				out1[i] ^= out2[i];
			}
		}
	}
	ret = 1;
err:
	return ret;
}
#define TLS_MD_KEY_EXPANSION_CONST		"key expansion"
#define TLS_MD_KEY_EXPANSION_CONST_SIZE		13
#define TLS_MD_CLIENT_FINISH_CONST		"client finished"
#define TLS_MD_CLIENT_FINISH_CONST_SIZE		15
#define TLS_MD_SERVER_FINISH_CONST		"server finished"
#define TLS_MD_SERVER_FINISH_CONST_SIZE		15
//expansion_key
void expansion_key_main(int arv, char** arvs)
{
	ssl_load_ciphers();
	unsigned char* dhs = arvs[1];
	unsigned char* cs = arvs[2];
	unsigned char* ss = arvs[3];
	unsigned char hb[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char tmp[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char km[176] = { 0 };
	unsigned char kmtmp[176] = { 0 };

	unsigned char crand[64] = { 0 };
	unsigned char srand[64] = { 0 };
	unsigned char dhc[64] = { 0 };
	HexStrToByte(cs, crand, strlen(cs));
	HexStrToByte(ss, srand, strlen(ss));
	HexStrToByte(dhs, dhc, strlen(dhs));

	long digest_mask = 131200;
	tls1_PRF(digest_mask,
		TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
		crand, SSL3_RANDOM_SIZE,
		0, 0,
		srand, SSL3_RANDOM_SIZE,
		0, 0,
		dhc, strlen(dhs) / 2,
		hb, tmp, sizeof tmp);
	dump_str("master", hb, SSL_MAX_MASTER_KEY_LENGTH);
	tls1_PRF(digest_mask,
		TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
		srand, SSL3_RANDOM_SIZE,
		crand, SSL3_RANDOM_SIZE,
		NULL, 0, NULL, 0,
		hb, SSL_MAX_MASTER_KEY_LENGTH,
		km, kmtmp, sizeof kmtmp);
	dump_str("km", km, sizeof km);
}
//calc_dh
void calc_dh_main(int arv, char** arvs)
{
	const char* ps = arvs[1];
	const char* as = "4FE02D3764B5F742645426CA8EC6FC860476AB260BF375DCDD9C7CE5BAC31BF0744E9426620734B20E8D55CA8186E4C8286AFACB3F162612EAB6FEEE4C7BE8BB";

	const char* bv = arvs[2];
	unsigned char Ks[1024] = { 0 };
	int kslen = 0;
	const char* gs = "02";
	BIGNUM a, g, p, B, K;
	BIGNUM* tem;
	BN_CTX* ctx;

	ctx = BN_CTX_new();
	BN_init(&a);
	BN_init(&g);
	BN_init(&p);
	BN_init(&B);
	BN_init(&K);

	tem = &p;
	BN_hex2bn(&tem, ps);
	tem = &g;
	BN_hex2bn(&tem, gs);
	tem = &a;
	BN_hex2bn(&tem, as);
	tem = &B;
	BN_hex2bn(&tem, bv);

	BN_mod_exp(&K, &B, &a, &p, ctx);
	kslen = BN_bn2bin(&K, Ks);
	BN_free(&a);
	BN_free(&g);
	BN_free(&p);
	BN_free(&B);
	BN_free(&K);
	BN_CTX_free(ctx);

	dump_str("Ks", Ks, kslen);
}
//decrypt_data
void main5469(int arv, char** arvs)
{
	ssl_load_ciphers();
	unsigned char o_out2[8192] = { 0 };

	unsigned char* ivs = arvs[1];
	unsigned char ivc[64] = { 0 };
	HexStrToByte(ivs, ivc, strlen(ivs));

	unsigned char* keys = arvs[2];
	unsigned char keyc[64] = { 0 };
	HexStrToByte(keys, keyc, strlen(keys));

	unsigned char* encbufs = arvs[3];
	unsigned char encbuf[8192] = { 0 };
	HexStrToByte(encbufs, encbuf, strlen(encbufs));

	EVP_CIPHER_CTX* ctx1 = EVP_CIPHER_CTX_new();
	int qdas = 0;
	qdas = EVP_CipherInit(ctx1, EVP_aes_256_cbc(), keyc, ivc, 0);

	qdas = EVP_Cipher(ctx1, o_out2, encbuf, strlen(encbufs) / 2);
	//new iv ctx1->iv
	dump_str("N", o_out2, strlen(encbufs) / 2);
	dump_str("NIV", ctx1->iv, 16);
}
//encrypt_data
void encrypt_data_main(int arv, char** arvs)
{
	ssl_load_ciphers();
	unsigned char o_out2[8192] = { 0 };

	unsigned char* ivs = arvs[1];
	unsigned char ivc[64] = { 0 };
	HexStrToByte(ivs, ivc, strlen(ivs));

	unsigned char* keys = arvs[2];
	unsigned char keyc[64] = { 0 };
	HexStrToByte(keys, keyc, strlen(keys));

	unsigned char* encbufs = arvs[3];
	unsigned char encbuf[8192] = { 0 };
	HexStrToByte(encbufs, encbuf, strlen(encbufs));

	EVP_CIPHER_CTX* ctx1 = EVP_CIPHER_CTX_new();
	int qdas = 0;
	qdas = EVP_CipherInit(ctx1, EVP_aes_256_cbc(), keyc, ivc, 1);

	qdas = EVP_Cipher(ctx1, o_out2, encbuf, strlen(encbufs) / 2);
	//new iv ctx1->iv
	dump_str("N", o_out2, strlen(encbufs) / 2);
	dump_str("NIV", ctx1->iv, 16);
}
//client_finished_hash
void client_finished_hash_main(int arv, char** arvs)
{
	ssl_load_ciphers();
	unsigned char o_out2[8192] = { 0 };
	unsigned char hb[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char tmp[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char* encbufs = arvs[1];
	unsigned char encbuf[8192] = { 0 };
	HexStrToByte(encbufs, encbuf, strlen(encbufs));

	

	SHA256(encbuf, strlen(encbufs) / 2, o_out2);

	unsigned char* masterkeys = arvs[2];
	unsigned char masterkey[1024] = { 0 };
	HexStrToByte(masterkeys, masterkey, strlen(masterkeys));

	long digest_mask = 131200;
	tls1_PRF(digest_mask,
		TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
		o_out2, SSL3_RANDOM_SIZE,
		0, 0,
		0, 0,
		0, 0,
		masterkey, strlen(masterkeys) / 2,
		hb, tmp, sizeof tmp);

	dump_str("HASH", hb, 16);
}
//server_finished_hash
void server_finished_hash_main(int arv, char** arvs)
{
	ssl_load_ciphers();
	
	unsigned char o_out2[8192] = { 0 };
	unsigned char hb[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char tmp[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char* encbufs = arvs[1];
	unsigned char encbuf[8192] = { 0 };
	HexStrToByte(encbufs, encbuf, strlen(encbufs));

	unsigned char* masterkeys = arvs[2];
	unsigned char masterkey[1024] = { 0 };
	HexStrToByte(masterkeys, masterkey, strlen(masterkeys));

	SHA256(encbuf, strlen(encbufs) / 2, o_out2);

	long digest_mask = 131200;
	tls1_PRF(digest_mask,
		TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
		o_out2, SSL3_RANDOM_SIZE,
		0, 0,
		0, 0,
		0, 0,
		masterkey, strlen(masterkeys) / 2,
		hb, tmp, sizeof tmp);

	dump_str("HASH", hb, 16);
}
//calc_hmac
void calc_hmac_main(int arv, char** arvs)
{
	ssl_load_ciphers();
	unsigned char o_out2[8192] = { 0 };
	int qdas = 0;
	unsigned char* keys = arvs[1];
	unsigned char key[8192] = { 0 };
	HexStrToByte(keys, key, strlen(keys));

	unsigned char* datas = arvs[2];
	unsigned char data[1024] = { 0 };
	HexStrToByte(datas, data, strlen(datas));

	HMAC(EVP_sha256(), key, strlen(keys) / 2, data, strlen(datas) / 2, o_out2, &qdas);

	dump_str("HMAC", o_out2, qdas);
}
#define EVP_AEAD_TLS1_AAD_LEN 13
int main(int arv, char** arvs)
{
	ssl_load_ciphers();
	EVP_CIPHER_CTX *ctx;
	EVP_CIPHER* c;
	unsigned char enc[128] = { 0 };
	unsigned char key[32] = { 0 };
	unsigned char iv[32] = { 0 };
	unsigned char crand[64] = { 0 };
	unsigned char srand[64] = { 0 };
	unsigned char rsa[64] = { 0 };
	unsigned char hb[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char tmp[SSL_MAX_MASTER_KEY_LENGTH] = { 0 };
	unsigned char km[176] = { 0 };
	unsigned char kmtmp[176] = { 0 };
	unsigned char buf[EVP_AEAD_TLS1_AAD_LEN] = { 0 };
	int len;
	int which = 0x21;
	int ret = 0;
	char type = 0x16;//
	unsigned short version = 0x0303;//固定
	unsigned long seq = 0;//递增
	
	HexStrToByte(arvs[4], enc, strlen(arvs[4]));
	HexStrToByte(arvs[2], crand, strlen(arvs[2]));
	HexStrToByte(arvs[3], srand, strlen(arvs[3]));
	HexStrToByte(arvs[1], rsa, strlen(arvs[1]));
	len = strlen(arvs[4]) / 2;
	long digest_mask = 262400;//131200 262400
	tls1_PRF(digest_mask,
		TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
		crand, SSL3_RANDOM_SIZE,
		0, 0,
		srand, SSL3_RANDOM_SIZE,
		0, 0,
		rsa, strlen(arvs[1]) / 2,
		hb, tmp, sizeof tmp);
	dump_str("master", hb, SSL_MAX_MASTER_KEY_LENGTH);
	tls1_PRF(digest_mask,
		TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
		srand, SSL3_RANDOM_SIZE,
		crand, SSL3_RANDOM_SIZE,
		NULL, 0, NULL, 0,
		hb, SSL_MAX_MASTER_KEY_LENGTH,
		km, kmtmp, sizeof kmtmp);
	dump_str("km", km, sizeof km);
	//c key 32 s key 32
	//c iv 12 s iv 12
	
	
	memcpy(key, km, 32);
	memcpy(iv, km + 32 * 2, 16);
	dump_str("key", key, 32);
	dump_str("iv", iv, 16);
	
	ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
	EVP_CIPHER_CTX_init(ctx);
	c = EVP_get_cipherbyname(SN_aes_256_gcm);
	
	ret = EVP_CipherInit_ex(ctx, c, NULL, key, NULL, (which & SSL3_CC_WRITE));
	if(ret == -1) return 1;
	ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, 4, iv);
	if(ret == -1) return 1;
	dump_str("ctx iv", ctx->iv, 12);
	memcpy(buf, &seq, sizeof(long));
	buf[8] = type;
	buf[9] = (unsigned char)(version >> 8);
	buf[10] = (unsigned char)(version);
	buf[11] = len >> 8;
	buf[12] = len & 0xff;
	dump_str("buf", buf, 13);
	ret = EVP_CIPHER_CTX_ctrl(ctx, 22, 13, buf);
	//printf("EVP_CIPHER_CTX_ctrl %d\r\n", ret);
	if(ret == -1) return 1;
	dump_str("enc", enc, len);
	ret = EVP_Cipher(ctx, enc, enc, len);
	//printf("EVP_Cipher %d\r\n", ret);
	if(ret == -1) return 1;
	dump_str("nors", enc, len);
	dump_str("nor", enc + 8, len - 8);
} 

C Language online compiler

Write, Run & Share C Language code online using OneCompiler's C online compiler for free. It's one of the robust, feature-rich online compilers for C language, running the latest C version which is C18. Getting started with the OneCompiler's C editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'C' and start coding!

Read inputs from stdin

OneCompiler's C online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample C program which takes name as input and print your name with hello.

#include <stdio.h>
int main()
{
    char name[50];
    printf("Enter name:");
    scanf("%s", name);
    printf("Hello %s \n" , name );
    return 0;
    
}

About C

C language is one of the most popular general-purpose programming language developed by Dennis Ritchie at Bell laboratories for UNIX operating system. The initial release of C Language was in the year 1972. Most of the desktop operating systems are written in C Language.

Key features:

  • Structured Programming
  • Popular system programming language
  • UNIX, MySQL and Oracle are completely written in C.
  • Supports variety of platforms
  • Efficient and also handle low-level activities.
  • As fast as assembly language and hence used as system development language.

Syntax help

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition if-else is used.

if(conditional-expression) {
   // code
} else {
   // code
}

You can also use if-else for nested Ifs and if-else-if ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to if-else-if ladder.

switch(conditional-expression) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 // code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
  // code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition) {  
 // code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (condition); 

Arrays

Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.

Syntax

One dimentional Array:

data-type array-name[size];

Two dimensional array:

data-type array-name[size][size];

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

Two types of functions are present in C

  1. Library Functions:

Library functions are the in-built functions which are declared in header files like printf(),scanf(),puts(),gets() etc.,

  1. User defined functions:

User defined functions are the ones which are written by the programmer based on the requirement.

How to declare a Function

return_type function_name(parameters);

How to call a Function

function_name (parameters)

How to define a Function

return_type function_name(parameters) {  
  //code
}