Пример #1
0
int
PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
    unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int ret = -1;
	int i, j, max = 0;
	char *s = NULL;

	/*
	 * Make sure ctx is properly initialized so that we can always pass
	 * it to PEM_ENCODE_SEAL_CTX_cleanup() in the error path.
	 */
	EVP_EncodeInit(&ctx->encode);
	EVP_MD_CTX_init(&ctx->md);
	EVP_CIPHER_CTX_init(&ctx->cipher);

	for (i = 0; i < npubk; i++) {
		if (pubk[i]->type != EVP_PKEY_RSA) {
			PEMerror(PEM_R_PUBLIC_KEY_NO_RSA);
			goto err;
		}
		j = RSA_size(pubk[i]->pkey.rsa);
		if (j > max)
			max = j;
	}
	s = reallocarray(NULL, max, 2);
	if (s == NULL) {
		PEMerror(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EVP_SignInit(&ctx->md, md_type))
		goto err;

	ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
	if (ret <= 0)
		goto err;

	/* base64 encode the keys */
	for (i = 0; i < npubk; i++) {
		j = EVP_EncodeBlock((unsigned char *)s, ek[i],
		    RSA_size(pubk[i]->pkey.rsa));
		ekl[i] = j;
		memcpy(ek[i], s, j + 1);
	}

	ret = npubk;

	if (0) {
err:
		PEM_ENCODE_SEAL_CTX_cleanup(ctx);
	}
	free(s);
	explicit_bzero(key, sizeof(key));
	return (ret);
}
Пример #2
0
void openssl_evp_asycrypt()
{
	RSA *rkey;
	BIGNUM *bne;
	EVP_PKEY *pubkey[2];
	EVP_CIPHER_CTX ctx1, ctx2;
	int i, ekl[2], len1 = 0, len2 = 0, len3 = 0;
	unsigned char ins[] = "openssl asymmetric encrypt test";
	unsigned char iv[8], pen[MAX1_LEN], *ek[2], sde[MAX1_LEN];

	ek[0] = (unsigned char *)malloc(MAX1_LEN);
	ek[1] = (unsigned char *)malloc(MAX1_LEN);
	memset(pen, 0, MAX1_LEN);
	memset(sde, 0, MAX1_LEN);
	memset(ek[0], 0, MAX1_LEN);
	memset(ek[1], 0, MAX1_LEN);

	bne = BN_new();
	BN_set_word(bne, RSA_3);
	rkey = RSA_new();
	RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL);
	pubkey[0] = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(pubkey[0], rkey);

	EVP_CIPHER_CTX_init(&ctx1);
	EVP_SealInit(&ctx1, EVP_des_ede3_cbc(), ek, ekl, iv, pubkey, 1);
	EVP_SealUpdate(&ctx1, pen, &len1, ins, strlen((char *)ins));
	EVP_SealFinal(&ctx1, pen + len1, &len3);
	len1 += len3;
	printf("\nEVP_ASYEncry(%s) = ", ins);
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", pen[i]);
	printf("\n");
	EVP_CIPHER_CTX_cleanup(&ctx1);

	len3 = 0;
	EVP_CIPHER_CTX_init(&ctx2);
	EVP_OpenInit(&ctx2, EVP_des_ede3_cbc(), ek[0], ekl[0], iv, pubkey[0]);
	EVP_OpenUpdate(&ctx2, sde, &len2, pen, len1);
	EVP_OpenFinal(&ctx2, sde + len2, &len3);
	len2 += len3;
	printf("EVP_ASYDecry(");
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", pen[i]);
	printf(") = %s\n", sde);
	EVP_CIPHER_CTX_cleanup(&ctx2);

	free(ek[0]);
	free(ek[1]);
	EVP_PKEY_free(pubkey[0]);
	BN_free(bne);
}
Пример #3
0
int
PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
    unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int ret = -1;
	int i, j, max = 0;
	char *s = NULL;

	for (i = 0; i < npubk; i++) {
		if (pubk[i]->type != EVP_PKEY_RSA) {
			PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA);
			goto err;
		}
		j = RSA_size(pubk[i]->pkey.rsa);
		if (j > max)
			max = j;
	}
	s = (char *)reallocarray(NULL, max, 2);
	if (s == NULL) {
		PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	EVP_EncodeInit(&ctx->encode);

	EVP_MD_CTX_init(&ctx->md);
	if (!EVP_SignInit(&ctx->md, md_type))
		goto err;

	EVP_CIPHER_CTX_init(&ctx->cipher);
	ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
	if (ret <= 0)
		goto err;

	/* base64 encode the keys */
	for (i = 0; i < npubk; i++) {
		j = EVP_EncodeBlock((unsigned char *)s, ek[i],
		    RSA_size(pubk[i]->pkey.rsa));
		ekl[i] = j;
		memcpy(ek[i], s, j + 1);
	}

	ret = npubk;

err:
	if (s != NULL)
		free(s);
	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
	return (ret);
}
Пример #4
0
/// 计算数字信封,得到加密密钥和初始向量
int do_seal(const EVP_CIPHER * cipher,
			unsigned char * pbuf,int plen,
			unsigned char * ebuf,int * elen,
			unsigned char * iv,
			unsigned char *kbuf,int* klen)
{
	EVP_CIPHER_CTX ectx; 
	EVP_PKEY *pub_key[1];
	unsigned char *ekey[1]; 
	int tmp_len = 0;
	int ret = 0;
	
	RAND_seed("gt alarm system",10);
	pub_key[0] = NULL;
	ekey[0] = kbuf;

	if(!g_pub_key)
		return ERR_ENV_CERT_INVALID;

	EVP_CIPHER_CTX_init(&ectx);//TaoNote: 如果不调用EVP_CIPHER_CTX_init,不影响运算,但有内存泄漏

	do{
		pub_key[0] = g_pub_key;
		if(1 != EVP_SealInit(&ectx,cipher,ekey,klen,iv,pub_key,1)) 
		{ 
			ret = ERR_ENV_ENCRYPT_FAILED;
			break;
		}

		*elen = 0;
		if(1 != EVP_SealUpdate(&ectx, ebuf+*elen,elen,pbuf,plen))
		{
			ret = ERR_ENV_ENCRYPT_FAILED;
			break;  
		}

		if(1 != EVP_SealFinal(&ectx, ebuf + *elen,&tmp_len)) 
		{
			ret = ERR_ENV_ENCRYPT_FAILED;
			break;          
		}

		*elen = *elen + tmp_len; 		
	}while(0);

    EVP_CIPHER_CTX_cleanup(&ectx);

	return ret;
}
Пример #5
0
void openssl_evp_rsacripher()
{
	RSA *rkey;
	BIGNUM *bne;
	EVP_PKEY *pubkey[2];
	const EVP_CIPHER *type;
	EVP_CIPHER_CTX ctx1, ctx2;
	int i, ekl[2], total = 0, len1 = 0, len2 = 0;
	const unsigned char ins[COMM_LEN] = "openssl evp";
	unsigned char outs[LINE_LEN], iv[8], *ek[2], de[LINE_LEN];

	bne = BN_new();
	BN_set_word(bne, RSA_3);
	rkey = RSA_new();
	RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL);
	pubkey[0] = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(pubkey[0], rkey);
	type = EVP_des_cbc();

	ek[0] = malloc(LINE_LEN);
	ek[1] = malloc(LINE_LEN);
	EVP_CIPHER_CTX_init(&ctx1);
	EVP_SealInit(&ctx1, type, ek, ekl, iv, pubkey, 1);
	EVP_SealUpdate(&ctx1, outs, &total, ins, 11);
	EVP_SealFinal(&ctx1, outs + total, &len1);
	total += len1;
	printf("\nEVP_RSASEAL(%s) = ", ins);
	for (i = 0; i < total; i++)
		printf("0x%.02x ", outs[i]);
	EVP_CIPHER_CTX_cleanup(&ctx1);
	
	memset(de, 0, LINE_LEN);
	EVP_CIPHER_CTX_init(&ctx2);
	EVP_OpenInit(&ctx2, EVP_des_cbc(), ek[0], ekl[0], iv, pubkey[0]);
	EVP_OpenUpdate(&ctx2, de, &len2, outs, total);
	EVP_OpenFinal(&ctx2, de + len2, &len1);
	len2 += len1;
	printf("= %s\n", de);
	EVP_CIPHER_CTX_cleanup(&ctx2);

	free(ek[0]);
	free(ek[1]);
	EVP_PKEY_free(pubkey[0]);
	BN_free(bne);
}
Пример #6
0
static int test_EVP_Enveloped(void)
{
    int ret = 0;
    EVP_CIPHER_CTX *ctx = NULL;
    EVP_PKEY *keypair = NULL;
    unsigned char *kek = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    static const unsigned char msg[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int len, kek_len, ciphertext_len, plaintext_len;
    unsigned char ciphertext[32], plaintext[16];
    const EVP_CIPHER *type = EVP_aes_256_cbc();

    if (!TEST_ptr(keypair = load_example_rsa_key())
            || !TEST_ptr(kek = OPENSSL_zalloc(EVP_PKEY_size(keypair)))
            || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())
            || !TEST_true(EVP_SealInit(ctx, type, &kek, &kek_len, iv,
                                       &keypair, 1))
            || !TEST_true(EVP_SealUpdate(ctx, ciphertext, &ciphertext_len,
                                         msg, sizeof(msg)))
            || !TEST_true(EVP_SealFinal(ctx, ciphertext + ciphertext_len,
                                        &len)))
        goto err;

    ciphertext_len += len;

    if (!TEST_true(EVP_OpenInit(ctx, type, kek, kek_len, iv, keypair))
            || !TEST_true(EVP_OpenUpdate(ctx, plaintext, &plaintext_len,
                                         ciphertext, ciphertext_len))
            || !TEST_true(EVP_OpenFinal(ctx, plaintext + plaintext_len, &len)))
        goto err;

    plaintext_len += len;
    if (!TEST_mem_eq(msg, sizeof(msg), plaintext, plaintext_len))
        goto err;

    ret = 1;
err:
    OPENSSL_free(kek);
    EVP_PKEY_free(keypair);
    EVP_CIPHER_CTX_free(ctx);
    return ret;
}
Пример #7
0
bool OTEnvelope::Seal(const OTAsymmetricKey & RecipPubKey, const OTString & theContents)
{
	bool retval = false;
    
	EVP_CIPHER_CTX	ctx;
    
	unsigned char	buffer[4096];
    unsigned char	buffer_out[4096 + EVP_MAX_IV_LENGTH];
    unsigned char	iv[EVP_MAX_IV_LENGTH];
    
	size_t			len = 0;
    int				len_out = 0;

    unsigned char *	ek = NULL;
    int				eklen = 0;
    uint32_t		eklen_n = 0;
	
	
	memset(buffer, 0, 4096);
	memset(buffer_out, 0, 4096 + EVP_MAX_IV_LENGTH);
	memset(iv, 0, EVP_MAX_IV_LENGTH);

	
	OTAsymmetricKey &	publicKey	= (OTAsymmetricKey &)RecipPubKey;
	EVP_PKEY *			pkey		= (EVP_PKEY *)publicKey.GetKey();
	
	if (NULL == pkey)
	{
		OTLog::Error("Null public key in OTEnvelope::Seal\n");
		return false;
	}
	
	// This is where the envelope final contents will be placed.
	m_dataContents.Release();
	
	
	EVP_CIPHER_CTX_init(&ctx);
    ek = (unsigned char*)malloc(EVP_PKEY_size(pkey));
	
	OT_ASSERT(NULL != ek);
	
	memset(ek, 0, EVP_PKEY_size(pkey));
	
    if (!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1))
    {
        OTLog::Error("EVP_SealInit: failed.\n");
		free(ek); ek = NULL;
		return false;
    }
	
    // First we write out the encrypted key length, then the encrypted key,
	// then the iv (the IV length is fixed by the cipher we have chosen).
	
    eklen_n = htonl(eklen);
	
	OTData dataEKSize(&eklen_n, sizeof(eklen_n)); // Encrypted Key size. (EK). Bytes are in network order.
	OTData dataEK(ek, eklen); // Encrypted Key
	OTData dataIV(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc())); // Initialization Vector
	
	// Concatenate (to the envelope result buffer) the three pieces of final data we have so far.
	m_dataContents += dataEKSize;
	m_dataContents += dataEK;
	m_dataContents += dataIV;
	
	// Next we put the plaintext into a data object so we can process it.
	OTData plaintext((const void*)theContents.Get(), theContents.GetLength()+1); // +1 for null terminator
	
    // Now we process the input and write the encrypted data to the
	// output.
	
    while (0 < (len = plaintext.OTfread((char*)buffer, sizeof(buffer))))
    {
        if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len))
        {
            OTLog::Error("EVP_SealUpdate: failed.\n");
			free(ek); ek = NULL;
			return false;
        }
		
		OTData dataSealUpdate(buffer_out, len_out);
		m_dataContents += dataSealUpdate;
	}
	
    if (!EVP_SealFinal(&ctx, buffer_out, &len_out))
    {
        OTLog::Error("EVP_SealFinal: failed.\n");
		free(ek); ek = NULL;
		return false;
    }
	
	OTData dataSealFinal(buffer_out, len_out);
	m_dataContents += dataSealFinal;
	
	retval = true;
	
    free(ek); ek = NULL;
	
    return retval;
}
Пример #8
0
void main_encrypt(void)
{
	unsigned int ebuflen;
        EVP_CIPHER_CTX ectx;
        unsigned char iv[EVP_MAX_IV_LENGTH];
	unsigned char *ekey[1]; 
	int readlen;
	int ekeylen, net_ekeylen; 
	EVP_PKEY *pubKey[1];
	char buf[512];
	char ebuf[512];
	
 	memset(iv, '\0', sizeof(iv));

        pubKey[0] = ReadPublicKey(PUBFILE);

	if(!pubKey)
	{
           fprintf(stderr,"Error: can't load public key");
           exit(1);
        }      

        ekey[0] = malloc(EVP_PKEY_size(pubKey[0]));  
        if (!ekey[0])
	{
	   EVP_PKEY_free(pubKey[0]); 
	   perror("malloc");
	   exit(1);
	}

	EVP_SealInit(&ectx,
                   EVP_des_ede3_cbc(),
		   ekey,
		   &ekeylen,
		   iv,
		   pubKey,
		   1); 

	net_ekeylen = htonl(ekeylen);	
	write(STDOUT, (char*)&net_ekeylen, sizeof(net_ekeylen));
        write(STDOUT, ekey[0], ekeylen);
        write(STDOUT, iv, sizeof(iv));

	while(1)
	{
		readlen = read(STDIN, buf, sizeof(buf));

		if (readlen <= 0)
		{
		   if (readlen < 0)
			perror("read");

		   break;
		}

		EVP_SealUpdate(&ectx, ebuf, &ebuflen, buf, readlen);

		write(STDOUT, ebuf, ebuflen);
	}

        EVP_SealFinal(&ectx, ebuf, &ebuflen);
        
	write(STDOUT, ebuf, ebuflen);

        EVP_PKEY_free(pubKey[0]);
	free(ekey[0]);
}
Пример #9
0
uint8_t* encrypt(const char* keypath, const uint8_t* p, const size_t plen, size_t* clen, uint8_t** iv, size_t* ivlen, uint8_t** ek, size_t* ekl){
    // Context and key
    FILE* ckeyfh;
    EVP_PKEY *ckey=NULL;

    // Return codes and errors
    unsigned long encerr;

    /* The buffer with the ciphertext */
    uint8_t* c;

    /* Variables  related to the symmetric enc of the envelope */
    EVP_CIPHER_CTX *encctx = NULL;
    const EVP_CIPHER* type = EVP_aes_256_cbc(); // Type of encryption
    int outl, outf;
	int eklint;

    /*
     * Open a public key for encryption
     */
    ckeyfh = fopen(keypath,"r");
    if (!ckeyfh)
    {
        fprintf(stderr, "%s: Cannot open key file\n", __func__);
        c = NULL;
        goto exit_encrypt;
    }
    ckey = PEM_read_PUBKEY(ckeyfh, &ckey, NULL, NULL);
    if (!ckey){
        fprintf(stderr,"Cannot read encryption key from file %s\n", keypath);
        fclose(ckeyfh);
        c = NULL;
        goto exit_encrypt;
    }

    /* EVP_Seal* need a CIPHER_CTX */
    encctx = malloc(sizeof(EVP_CIPHER_CTX));
    if (encctx == NULL)
    {
        fprintf(stderr, "%s: Out of memory\n", __func__);
        fclose(ckeyfh);
        EVP_PKEY_free(ckey);
        c = NULL;
        goto exit_encrypt;
    }

    EVP_CIPHER_CTX_init(encctx);
    if (!encctx){
        fprintf(stderr,"Cannot inizialize an encryption context\n");
        c = NULL;
        goto cleanup_encrypt;
    }

    /* Start the encryption process - generate IV and key */
    *ivlen = EVP_CIPHER_iv_length(type);
    *iv = malloc(*ivlen);
    if (iv == NULL)
    {
        fprintf(stderr, "%s: Out of memory allocating of IV\n", __func__);
        c = NULL;
        goto cleanup_encrypt;
    }
    *ek = malloc(EVP_PKEY_size(ckey));
    if (*ek == NULL)
    {
        fprintf(stderr, "%s: Out of memory allocating ek\n", __func__);
        free(iv);
        c = NULL;
        goto cleanup_encrypt;
    }
    c = malloc(plen + EVP_CIPHER_block_size(type));
    if (c == NULL)
    {
        fprintf(stderr, "%s: Out of memory for \n", __func__);
        free(iv);
        free(*ek);
        goto cleanup_encrypt;
    }

    if (EVP_SealInit(encctx, type, ek, &eklint, *iv, &ckey, 1) != 1){
        ERR_load_crypto_strings();
        encerr = ERR_get_error();
        fprintf(stderr,"Encrypt failed\n");
        printf("%s\n", ERR_error_string(encerr, NULL));
        ERR_free_strings();
        free(iv);
        free(*ek);
        free(c);
        c = NULL;
        goto cleanup_encrypt;
    }
	*ekl = eklint;

    /* Encrypt data, then finalize */
    if (EVP_SealUpdate(encctx, c, &outl, p, plen) != 1){
        ERR_load_crypto_strings();
        encerr = ERR_get_error();
        fprintf(stderr,"Encrypt failed\n");
        printf("%s\n", ERR_error_string(encerr, NULL));
        ERR_free_strings();
        free(iv);
        free(*ek);
        free(c);
        c = NULL;
        goto cleanup_encrypt;
    }
    if (EVP_SealFinal(encctx, &c[outl], &outf) != 1){
        ERR_load_crypto_strings();
        encerr = ERR_get_error();
        fprintf(stderr,"Encrypt failed\n");
        printf("%s\n", ERR_error_string(encerr, NULL));
        ERR_free_strings();
        free(c);
        c = NULL;
        outl = outf = 0;
    }

    *clen = outl + outf;

    cleanup_encrypt:
    EVP_CIPHER_CTX_cleanup(encctx);
    free(encctx);
    fclose(ckeyfh);
    EVP_PKEY_free(ckey);

    exit_encrypt:
    return c;
}
Пример #10
0
unsigned char *rsa_encrypt(unsigned char *plaintext, int *len)
{

    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_PKEY *pkey;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    unsigned char *encrypted_key;
    int encrypted_key_length;
    uint32_t eklen_n;

    // Load pem file
    pkey = load_pubkey("public.pem");

    encrypted_key = malloc(EVP_PKEY_size(pkey));
    encrypted_key_length = EVP_PKEY_size(pkey);

    if (!EVP_SealInit(&ctx, EVP_des_ede_cbc(), &encrypted_key, &encrypted_key_length, iv, &pkey, 1))
    {
        fprintf(stderr, "EVP_SealInit: failed.\n");
        goto out_free;
    }

    eklen_n = htonl(encrypted_key_length);

    int size_header = sizeof(eklen_n) + encrypted_key_length +
                      EVP_CIPHER_iv_length(EVP_des_ede_cbc());

    /* max ciphertext len, see man EVP_CIPHER */
    int cipher_len = *len + EVP_CIPHER_CTX_block_size(&ctx) - 1;

    // header(contains iv, encreypted key and encreypted key length) + data
    unsigned char *ciphertext = (unsigned char *)malloc(size_header + cipher_len);

    /* First we write out the encrypted key length, then the encrypted key,
     * then the iv (the IV length is fixed by the cipher we have chosen).
     */
    int pos = 0;
    memcpy(ciphertext + pos, &eklen_n, sizeof(eklen_n));
    pos += sizeof(eklen_n);

    memcpy(ciphertext + pos, encrypted_key, encrypted_key_length);
    pos += encrypted_key_length;

    memcpy(ciphertext + pos, iv, EVP_CIPHER_iv_length(EVP_des_ede_cbc()));
    pos += EVP_CIPHER_iv_length(EVP_des_ede_cbc());

    /* Now we process the plaintext data and write the encrypted data to the
     * ciphertext. cipher_len is filled with the length of ciphertext
     * generated, len is the size of plaintext in bytes
     * Also we have our updated position, we can skip the header via
     * ciphertext + pos */
    if (!EVP_SealUpdate(&ctx, ciphertext + pos, &cipher_len, plaintext, *len))
    {
        fprintf(stderr, "EVP_SealUpdate: failed.\n");
        goto out_free;
    }

    /* update ciphertext with the final remaining bytes */
    if (!EVP_SealFinal(&ctx, ciphertext + pos + cipher_len, &cipher_len))
    {
        fprintf(stderr, "EVP_SealFinal: failed.\n");
        goto out_free;
    }

out_free:
    EVP_PKEY_free(pkey);
    free(encrypted_key);

    EVP_CIPHER_CTX_cleanup(&ctx);
    return ciphertext;

}
Пример #11
0
int main(int argc, char * argv[]) {
  unsigned char st[BUFFER_SIZE];  // sifrovany text
  unsigned char * key;  // klic pro sifrovani
  unsigned char iv[EVP_MAX_IV_LENGTH];  // inicializacni vektor
  unsigned char readBuffer[BUFFER_SIZE];
  const char * filename = argv[1];
  const char * outfilename = argv[3];
  const char * keyfile = argv[2];
	if(argc != 4){
    fprintf(stderr, "Error shoud be: pem soubor_s_daty soubor_s_verejnym_klicem vystupni_soubor \n" );
    exit(1);
  }
  int stLength = 0;
  int tmpLength = 0;
  int readlen = 0;
  int keyLength = 0;
  FILE * fplainin = fopen(filename,"rb");
  FILE * fcyphedout = fopen(outfilename,"w+b");
  EVP_PKEY * pubkey;
  EVP_CIPHER_CTX ctx;
  FILE * fpubkey = fopen(keyfile,"rb");
  pubkey = PEM_read_PUBKEY(fpubkey, NULL, NULL, NULL); //No password protection of the key itself
  fclose(fpubkey);
 // printf("Reading pubkey\n");
  //EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new(pubkey,NULL);
  keyLength = EVP_PKEY_size(pubkey);
  key = (unsigned char*) malloc(keyLength);
  EVP_SealInit(&ctx,
	EVP_des_cbc(),
	&key, &keyLength, iv,
	&pubkey,
	1);
  /*
  printf("Key length: %d\n",keyLength);
  for(int i=0 ; i < keyLength ; i++){
    printf("%x",key[i]);
  }
   printf("\n");
   */
 // printf("Seal Init\n");
  int nid = EVP_CIPHER_CTX_nid(&ctx);
  fwrite(&nid,sizeof(nid),1,fcyphedout);
  writeData(fcyphedout,(void*)iv,EVP_MAX_IV_LENGTH);
  fwrite(&keyLength,sizeof(keyLength),1,fcyphedout);
  writeData(fcyphedout,(void*)key,keyLength);
  printf("NID: %d\n",nid);
  
  while((readlen =fread(readBuffer,1,BUFFER_SIZE,fplainin))!=0){
	  EVP_SealUpdate(&ctx, st,&stLength, readBuffer, readlen);
	  fwrite(st,1,stLength,fcyphedout);
	 // printf("Seal update\n");
  }
  EVP_SealFinal(&ctx, st, &tmpLength);
  //printf("Seal final\n");
  fwrite(st,1,tmpLength,fcyphedout);
  fclose(fplainin);
  fclose(fcyphedout);
  
  /*
	Encrypting end
  */
  //EVP_CIPHER_CTX ctx;
 
  free(key);
 }
Пример #12
0
/*
* RSA public cryptography function.
* Encrypt 'in_len' bytes from 'plaintext' buffer with the public key contained in 'pub_key_file' 
* Parameter 'outlen' is the size of output buffer 
* It returns the envelope which has to be sent to the receiver or NULL if an error occurs.
*/
unsigned char* asym_crypto(unsigned char* plaintext, int in_len, int* out_len, char* pub_key_file){
	EVP_PKEY* pubkey;
	int ret;	
	EVP_CIPHER_CTX* ctx;
	unsigned char* encrypted_key;
	int encrypted_key_len;
	unsigned char* iv;
	int iv_len;
	unsigned char* ciphertext;
	int cipher_len;
	int app;
	unsigned char* output;
	int total_output_size = 0;
		
	if(plaintext == NULL || in_len < 0 || out_len == NULL || pub_key_file == NULL)
		return NULL;
	
	//Reads the receiver's public key for its file
	pubkey = retrieve_pubkey(pub_key_file);
	if(pubkey == NULL)
		return NULL;
	encrypted_key_len = EVP_PKEY_size(pubkey);
	total_output_size += encrypted_key_len;
	iv_len = EVP_CIPHER_iv_length(SYM_CIPHER);
	total_output_size += iv_len;
	//Allocation of encrypted symmetric key and initialization vector
   	encrypted_key = malloc(encrypted_key_len);
   	iv = malloc(iv_len);
	//Seeding the RNG
	RAND_seed(iv, 8);
	
	//Instantiate and initialize the context
	ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
	EVP_CIPHER_CTX_init(ctx);
	ret = EVP_SealInit(ctx, SYM_CIPHER, &encrypted_key, &encrypted_key_len, iv, &pubkey ,1);
	if(ret == 0){
		fprintf(stderr, "Error in SealInit\n");
		goto error;
	}
	
	//Encrypt the input buffer
	cipher_len = in_len + EVP_CIPHER_block_size(SYM_CIPHER);
	ciphertext = malloc(cipher_len);
	cipher_len = 0;
	
	ret = EVP_SealUpdate(ctx, ciphertext, &app, plaintext, in_len);
	cipher_len += app;
	if(ret == 0){
		fprintf(stderr, "Error in SealUpdate\n");
		goto error;
	}
	ret = EVP_SealFinal(ctx, ciphertext + app, &app);
	cipher_len += app;
	if(ret == 0){
		fprintf(stderr, "Error in SealFinal\n");
		goto error;
	}
	total_output_size += cipher_len;
	
	//Concatenates the envelop in the outbuffer with format: <IV><Dim_Key><Ecrypt_KEY><Ciphertext>
	total_output_size += sizeof(int);
	output = malloc(total_output_size);
	app = 0;
	//<IV>
	memcpy(output, iv, iv_len);
	app += iv_len;
	//<Dim_Key>
	memcpy(output + app, &encrypted_key_len, sizeof(int));
	app += sizeof(int);
	//<Ecrypt_KEY>
	memcpy(output + app, encrypted_key, encrypted_key_len);
	app += encrypted_key_len;
	//<Ciphertext>
	memcpy(output + app, ciphertext, cipher_len);
	app += encrypted_key_len;
	
	*out_len = total_output_size;
	
	//Cleanup
	EVP_CIPHER_CTX_cleanup(ctx);
   	free(ctx);
	free(ciphertext);
	free(pubkey);
	free(iv);
	
	return output;
	
error:
	if(ctx != NULL){
		EVP_CIPHER_CTX_cleanup(ctx);
   		free(ctx);
	}
	if(encrypted_key != NULL)
		free(ciphertext);	
	if(pubkey != NULL)
		free(pubkey);
	if(iv != NULL)		
		free(iv);
	if(ciphertext != NULL)
		free(ciphertext);		
	if(output != NULL)
		free(output);
	return NULL;
}
Пример #13
0
/** Encrypt some data.
 *  \param key_count Number of keys in the \a target array.
 *  \param target Array of keys.  Anyone who owns any of these keys will be 
 *         able to decrypt the data.  These keys must include public key data.
 *  \param data Group to encrypt.  Will be replaced by an encrypted group.
 *  \return Nonzero iff the operation succeeded.
 *  \sa gale_crypto_target(), gale_crypto_open() */
int gale_crypto_seal(
	int key_count,const struct gale_group *target,
	struct gale_group *data)
{
	struct gale_fragment frag;
	struct gale_data plain,cipher;
	EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();

	int i,*session_key_length;
	unsigned char **session_key,iv[EVP_MAX_IV_LENGTH];
	struct gale_text *raw_name;
	EVP_PKEY **public_key;
	RSA *rsa;

	int good_count = 0,is_successful = 0;

	plain.p = gale_malloc(gale_group_size(*data) + gale_u32_size());
	plain.l = 0;
	gale_pack_u32(&plain,0); /* version identifier? */
	gale_pack_group(&plain,*data);
	*data = gale_group_empty();

	gale_create_array(raw_name,key_count);
	gale_create_array(public_key,key_count);
	for (i = 0; i < key_count; ++i) public_key[i] = NULL;
	for (i = 0; i < key_count; ++i) {
		public_key[good_count] = EVP_PKEY_new();
		EVP_PKEY_assign_RSA(public_key[good_count],RSA_new());
		rsa = EVP_PKEY_get0_RSA(public_key[good_count]);
		raw_name[good_count] = key_i_swizzle(crypto_i_rsa(
			target[i],rsa));
		if (0 != raw_name[good_count].l
		&&  crypto_i_public_valid(rsa))
			++good_count;
		else
			EVP_PKEY_free(public_key[good_count]);
	}

	gale_create_array(session_key_length,good_count);
	gale_create_array(session_key,good_count);
	for (i = 0; i < good_count; ++i) 
		gale_create_array(session_key[i],EVP_PKEY_size(public_key[i]));

	crypto_i_seed();
	if (!EVP_SealInit(context,EVP_des_ede3_cbc(),
		session_key,session_key_length,iv,public_key,good_count)) {
		crypto_i_error();
		goto cleanup;
	}

	cipher.l = gale_copy_size(sizeof(magic2))
	         + gale_copy_size(EVP_CIPHER_CTX_iv_length(context))
	         + gale_u32_size()
	         + plain.l + EVP_CIPHER_CTX_block_size(context) - 1;
	for (i = 0; i < good_count; ++i)
		cipher.l += gale_text_size(raw_name[i])
		         +  gale_u32_size()
		         +  gale_copy_size(session_key_length[i]);

	cipher.p = gale_malloc(cipher.l);
	cipher.l = 0;

	assert(IV_LEN == EVP_CIPHER_CTX_iv_length(context));
	gale_pack_copy(&cipher,magic2,sizeof(magic2));
	gale_pack_copy(&cipher,iv,IV_LEN);
	gale_pack_u32(&cipher,good_count);
	for (i = 0; i < good_count; ++i) {
		gale_pack_text(&cipher,raw_name[i]);
		gale_pack_u32(&cipher,session_key_length[i]);
		gale_pack_copy(&cipher,session_key[i],session_key_length[i]);
	}

	EVP_SealUpdate(context,cipher.p + cipher.l,&i,plain.p,plain.l);
	cipher.l += i;

	EVP_SealFinal(context,cipher.p + cipher.l,&i);
	cipher.l += i;

	frag.type = frag_data;
	frag.name = G_("security/encryption");
	frag.value.data = cipher;
	gale_group_add(data,frag);

	is_successful = 1;
cleanup:
	for (i = 0; i < good_count; ++i)
		if (NULL != public_key[i]) EVP_PKEY_free(public_key[i]);
	return is_successful;
}