Example #1
0
static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
{
	str ins;
	str keys;
	pv_spec_t *dst;
	pv_value_t val;
	EVP_CIPHER_CTX *de=NULL;
	str etext;

	if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
		LM_ERR("cannot get input value\n");
		return -1;
	}
	if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
		LM_ERR("cannot get key value\n");
		return -1;
	}
	de = EVP_CIPHER_CTX_new();
	if(de==NULL) {
		LM_ERR("cannot get new cipher context\n");
		return -1;
	}
	dst = (pv_spec_t*)outb;

	/* gen key and iv. init the cipher ctx object */
	if (crypto_aes_init((unsigned char *)keys.s, keys.len,
				(unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("couldn't initialize AES cipher\n");
		return -1;
	}

	memset(&val, 0, sizeof(pv_value_t));
	etext.s = pv_get_buffer();
	etext.len = base64_dec((unsigned char *)ins.s, ins.len,
					(unsigned char *)etext.s, pv_get_buffer_size()-1);
	if (etext.len < 0) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("base64 inpuy with encrypted value is too large (need %d)\n",
				-etext.len);
		return -1;
	}
	val.rs.len = etext.len;
	val.rs.s = (char *)crypto_aes_decrypt(de, (unsigned char *)etext.s,
			&val.rs.len);
	if(val.rs.s==NULL) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("AES decryption failed\n");
		return -1;
	}
	LM_DBG("plain result: [%.*s]\n", val.rs.len, val.rs.s);
	val.flags = PV_VAL_STR;
	dst->setf(msg, &dst->pvp, (int)EQ_T, &val);

	free(val.rs.s);
	EVP_CIPHER_CTX_cleanup(de);
	EVP_CIPHER_CTX_free(de);
	return 1;
}
Example #2
0
/**
 * testing function
 */
int crypto_aes_test(void)
{
	/* "opaque" encryption, decryption ctx structures
	 * that libcrypto uses to record status of enc/dec operations */
	EVP_CIPHER_CTX en, de;


	/* The salt paramter is used as a salt in the derivation:
	 * it should point to an 8 byte buffer or NULL if no salt is used. */
	unsigned char salt[] = {1,2,3,4,5,6,7,8};

	unsigned char *key_data;
	int key_data_len, i;
	char *input[] = {"Kamailio - The Open Source SIP Server",
		"Thank you for flying Kamailio!",
		"100 Trying\nYour call is important to us",
		NULL
	};

	/* the key_data for testing */
	key_data = (unsigned char *)"kamailio-sip-server";
	key_data_len = strlen((const char *)key_data);

	/* gen key and iv. init the cipher ctx object */
	if (crypto_aes_init(key_data, key_data_len, salt, &en, &de)) {
		LM_ERR("couldn't initialize AES cipher\n");
		return -1;
	}

	/* encrypt and decrypt each input string and compare with the original */
	for (i = 0; input[i]; i++) {
		char *plaintext;
		unsigned char *ciphertext;
		int olen, len;

		/* The enc/dec functions deal with binary data and not C strings.
		 * strlen() will return length of the string without counting the '\0'
		 * string marker. We always pass in the marker byte to the
		 * encrypt/decrypt functions so that after decryption we end up with
		 * a legal C string */
		olen = len = strlen(input[i])+1;

		ciphertext = crypto_aes_encrypt(&en, (unsigned char *)input[i], &len);
		plaintext = (char *)crypto_aes_decrypt(&de, ciphertext, &len);

		if (strncmp(plaintext, input[i], olen))
			LM_ERR("FAIL: enc/dec failed for \"%s\"\n", input[i]);
		else
			LM_NOTICE("OK: enc/dec ok for \"%s\"\n", plaintext);

		free(ciphertext);
		free(plaintext);
	}

	EVP_CIPHER_CTX_cleanup(&de);
	EVP_CIPHER_CTX_cleanup(&en);

	return 0;
}
Example #3
0
static int w_crypto_aes_encrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
{
	str ins;
	str keys;
	pv_spec_t *dst;
	pv_value_t val;
	EVP_CIPHER_CTX en;
	str etext;

	if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
		LM_ERR("cannot get input value\n");
		return -1;
	}
	if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
		LM_ERR("cannot get key value\n");
		return -1;
	}
	dst = (pv_spec_t*)outb;

	/* gen key and iv. init the cipher ctx object */
	if (crypto_aes_init((unsigned char *)keys.s, keys.len,
				(unsigned char*)((_crypto_salt_param)?_crypto_salt:0), &en, NULL)) {
		LM_ERR("couldn't initialize AES cipher\n");
		return -1;
	}
	etext.len = ins.len;
	etext.s = (char *)crypto_aes_encrypt(&en, (unsigned char *)ins.s, &etext.len);
	if(etext.s==NULL) {
		LM_ERR("AES encryption failed\n");
		return -1;
	}

	memset(&val, 0, sizeof(pv_value_t));
	val.rs.s = pv_get_buffer();
	val.rs.len = base64_enc((unsigned char *)etext.s, etext.len,
					(unsigned char *)val.rs.s, pv_get_buffer_size()-1);
	if (val.rs.len < 0) {
		LM_ERR("base64 output of encrypted value is too large (need %d)\n",
				-val.rs.len);
		goto error;
	}
	LM_DBG("base64 encrypted result: [%.*s]\n", val.rs.len, val.rs.s);
	val.flags = PV_VAL_STR;
	dst->setf(msg, &dst->pvp, (int)EQ_T, &val);

	free(etext.s);
	EVP_CIPHER_CTX_cleanup(&en);
	return 1;

error:
	free(etext.s);
	EVP_CIPHER_CTX_cleanup(&en);
	return -1;
}
Example #4
0
/*****************************************************************************
* 函 数 名  : crypto_encrypt
*
* 功能描述  : 使用指定的密钥和指定的算法对输入的数据加密,输出加密后的数据。
*             当前支持AES-ECB算法。
*
* 输入参数  : data:        待加密数据。
*             len:         待加密数据长度。(byte)
*             algorithm:   所用HASH算法。
*             key:         密钥buffer。
*             klen:        密钥buffer长度。(byte)
*             cipher_len:  加密后的数据的存放buffer的buffer size。(byte)(没有检查)
*
* 输出参数  : cipher_data: 加密后的数据的存放buffer。
*             cipher_len:  加密后的数据的实际长度。(byte)
*
* 返 回 值  : BSP_OK:      加密成功。
*             BSP_ERROR:   加密失败。
*
* 其它说明  : cipher_len为输入/输出参数,传入的cipher_len变量所用内存必须可写回。
*             所以避免直接传入类似sizeof()的函数调用结果。
*
*****************************************************************************/
int crypto_encrypt_o (char *data, int len, CRYPTO_ENCRYPT_ALGORITHM algorithm, char *key, int klen, char *cipher_data, int *cipher_len)
{
    crypto_aes aes_ctx;
    int16 keybits = 0;
    if(data == NULL || key == NULL || cipher_data == NULL || cipher_len == NULL)
    {
        security_print("ERROR crypto_encrypt: param is NULL pointer!\n");
        return BSP_ERROR;
    }

    if(len<=0 || (klen != AES_KEY_LEN && klen != 16))
    {
        security_print("ERROR crypto_encrypt: param is invalid!\n");
        return BSP_ERROR;
    }
    if (klen == 16)
    {
        keybits = 128;/* [false alarm]:误报 */
    }
    else if(klen == AES_KEY_LEN)
    {
        keybits = 256;/* [false alarm]:误报 */
    }
    crypto_aes_init(&aes_ctx,(UINT8*)key,keybits,MODE_ECB,NULL);

    switch(algorithm)
    {
    case CRYPTO_ENCRYPT_ALGORITHM_AES_ECB:
        //if(0 != crypto_aes_encrypt_pad(&aes_ctx,data,len,cipher_data,cipher_len))
        if(0 != crypto_aes_encrypt_block(&aes_ctx,(UINT8*)data,len,(UINT8*)cipher_data,(int32*)cipher_len))
        {
            security_print("ERROR crypto_encrypt: crypto_aes_encrypt_pad failed!\n");
            return BSP_ERROR;
        }
        break;

    default:
        security_print("ERROR crypto_encrypt: unknown algorithm!\n");

        return BSP_ERROR;
    }

    return BSP_OK;
}
Example #5
0
/*****************************************************************************
* 函 数 名  : crypto_decrypt
*
* 功能描述  : 使用指定的密钥和指定的算法对输入的数据解密,输出解密后的数据。
*             当前支持AES-ECB算法。
*
* 输入参数  :
*             cipher_data: 待密的数据的存放buffer。
*             cipher_len:  待解密的数据的实际长度。(byte)
*             algorithm:   所用解密算法,暂只提供AES-ECB。
*             key:         密钥buffer。
*             klen:        密钥buffer长度。(byte)
*             len:  解密后的数据的存放buffer的buffer size。(byte)(没有检查)
*
* 输出参数  :
*             data:        解密后的数据。
*             len:         解密后的数据长度。(byte)
*
* 返 回 值  : BSP_OK:      解密成功。
*             BSP_ERROR:   解密失败。
*
* 其它说明  : len为输入/输出参数,传入的len变量所用内存必须可写回。
*             所以避免直接传入类似sizeof()的函数调用结果。
*
*****************************************************************************/
int crypto_decrypt_o (char *cipher_data,int cipher_len,CRYPTO_ENCRYPT_ALGORITHM algorithm, char *key, int klen, char *data, int *len)
{
    crypto_aes aes_ctx;

    if((cipher_data == NULL) || (cipher_len == 0) || (data == NULL) || (key == NULL))
    {
        security_print("ERROR crypto_decrypt: param is NULL pointer!\n");
        return BSP_ERROR;
    }

    if(cipher_len<=0 || klen != AES_KEY_LEN)
    {
        security_print("ERROR crypto_decrypt: param is invalid!\n");
        return BSP_ERROR;
    }

    crypto_aes_init(&aes_ctx,(UINT8*)key,256,MODE_ECB,NULL);

    switch(algorithm)
    {
    case CRYPTO_ENCRYPT_ALGORITHM_AES_ECB:
        if(0 != crypto_aes_decrypt_block(&aes_ctx, (uint8 *)cipher_data, (int32)cipher_len, (uint8 *)data, (int32 *)len ))
        {
            security_print("ERROR crypto_decrypt: crypto_aes_decrypt_block failed!\n");
            return BSP_ERROR;
        }
        break;

    default:
        security_print("ERROR crypto_decrypt: unknown algorithm!\n");

        return BSP_ERROR;
    }

    return BSP_OK;
}