void generate_keys(char *outfile, FENC_SCHEME_TYPE scheme, char *secret_params, char *public_params)
{
	FENC_ERROR result;
	fenc_context context;
	fenc_group_params group_params;
	fenc_global_params global_params;
	fenc_function_input func_object_input; // could be policy or list
	pairing_t pairing;
	fenc_key key;
	fenc_key key2;
	FILE *fp;
	char c;
	size_t pub_len = 0, sec_len = 0;
	size_t serialized_len = 0;
	uint8 public_params_buf[SIZE];
	uint8 secret_params_buf[SIZE];
	// char session_key[SESSION_KEY_LEN];
	uint8 output_str[SIZE];
	size_t output_str_len = 0;
	// size_t session_key_len;
	
	/* Clear data structures. */
	memset(&context, 0, sizeof(fenc_context));
	memset(&group_params, 0, sizeof(fenc_group_params));
	memset(&global_params, 0, sizeof(fenc_global_params));	
	memset(&public_params_buf, 0, SIZE);
	memset(&secret_params_buf, 0, SIZE);
	memset(output_str, 0, SIZE);
	/* stores user's authorized attributes */
	memset(&func_object_input, 0, sizeof(fenc_function_input));
	/* stores the user's private key */
	memset(&key, 0, sizeof(fenc_key)); 
	memset(&key2, 0, sizeof(fenc_key));

	/* Initialize the library. */
	result = libfenc_init();
	/* Create a Sahai-Waters context. */
	result = libfenc_create_context(&context, scheme);
			
	/* Load group parameters from a file. */
	fp = fopen(PARAM, "r");
	if (fp != NULL) {
		libfenc_load_group_params_from_file(&group_params, fp);
		libfenc_get_pbc_pairing(&group_params, pairing);
	} else {
		perror("Could not open parameters file.\n");
		return;
	}
	fclose(fp);
	
	/* Set up the global parameters. */
	result = context.generate_global_params(&global_params, &group_params);
	report_error("Loading global parameters", result);
	
	result = libfenc_gen_params(&context, &global_params);
	report_error("Generating scheme parameters and secret key", result);
		
	printf("Reading the public parameters file = %s\n", public_params);	
	/* read file */
	fp = fopen(public_params, "r");
	if(fp != NULL) {
		while (TRUE) {
			c = fgetc(fp);
			if(c != EOF) {
				public_params_buf[pub_len] = c;
				pub_len++;
			}
			else {
				break;
			}
		}
	}
	else {
		perror("File does not exist.\n");
		return;
	}
	fclose(fp);

	printf("Reading the secret parameters file = %s\n", secret_params);	
	/* read file */
	fp = fopen(secret_params, "r");
	if(fp != NULL) {
		while (TRUE) {
			c = fgetc(fp);
			if(c != EOF) {
				secret_params_buf[sec_len] = c;
				sec_len++;
			}
			else {
				break;
			}
		}
	}
	else {
		perror("File does not exist.\n");
		return;
	}	
	fclose(fp);
	
	printf("public params input = '%s'\n", public_params_buf);
	printf("secret params input = '%s'\n", secret_params_buf);
	
	/* base-64 decode */
	uint8 *bin_public_buf = NewBase64Decode((const char *) public_params_buf, pub_len, &serialized_len);
	/* Import the parameters from binary buffer: */
	result = libfenc_import_public_params(&context, bin_public_buf, serialized_len);
	report_error("Importing public parameters", result);

	uint8 *bin_secret_buf = NewBase64Decode((const char *) secret_params_buf, sec_len, &serialized_len);
	result = libfenc_import_secret_params(&context, bin_secret_buf, serialized_len, NULL, 0);
	report_error("Importing secret parameters", result);
	
	if(scheme == FENC_SCHEME_LSW) {
		fenc_create_func_input_for_policy(policy_string, &func_object_input);
		debug_print_policy((fenc_attribute_policy *)(func_object_input.scheme_input));
		free(policy_string);
	}
	else if(scheme == FENC_SCHEME_WATERSCP || scheme == FENC_SCHEME_WATERSSIMPLECP) {
		fenc_create_func_input_for_attributes(attribute_string, &func_object_input);
		debug_print_attribute_list((fenc_attribute_list*)(func_object_input.scheme_input));
		free(attribute_string);
	}
		
	result = libfenc_extract_key(&context, &func_object_input, &key);
	report_error("Extracting a decryption key", result);

	uint8 *buffer = malloc(KEYSIZE_MAX);
	memset(buffer, 0, KEYSIZE_MAX);	
	result = libfenc_export_secret_key(&context, &key, buffer, KEYSIZE_MAX, &serialized_len);
	report_error("Exporting key", result);
	
	size_t keyLength;
	char *secret_key_buf = NewBase64Encode(buffer, serialized_len, FALSE, &keyLength);
	// printf("Your secret-key:\t'%s'\nKey-len:\t'%zd'\n", secret_key_buf, serialized_len);	
	
	fp = fopen(outfile, "w");
	if(fp != NULL) {
		fprintf(fp, "%s", secret_key_buf);
	}
	else {
		perror("Error writing private key.");
	}
	fclose(fp);

	/*
	printf("........Confirming contents of exported key......\n");
	printf("Buffer contents:\n");
	print_buffer_as_hex(buffer, serialized_len);

	if(scheme == FENC_SCHEME_LSW) {
		result = libfenc_import_secret_key(&context, &key2, buffer, serialized_len);
		report_error("Import secret key", result);
	
		fenc_key_LSW *myKey2 = (fenc_key_LSW *) key2.scheme_key;
	
		size_t serialized_len2;
		uint8 *buffer2 = malloc(KEYSIZE_MAX);
		memset(buffer2, 0, KEYSIZE_MAX);
		result = libfenc_serialize_key_LSW(myKey2, buffer2, KEYSIZE_MAX, &serialized_len2);		
		report_error("Serialize user's key", result);
	
		printf("Key-len2: '%zu'\n", serialized_len2);
		printf("Buffer contents 2:\n");
		print_buffer_as_hex(buffer2, serialized_len2);
	} */
cleanup:
	fenc_func_input_clear(&func_object_input);
	
	/* Destroy the context. */
	result = libfenc_destroy_context(&context);
	report_error("Destroying context", result);

	/* Shutdown the library. */
	result = libfenc_shutdown();
	report_error("Shutting down library", result);	
		
	/* free buffer */
	free(buffer);
	return;
}
Example #2
0
void abe_encrypt(FENC_SCHEME_TYPE scheme, char *public_params, char *data, char *enc_file, int isXML, char *ext)
{
	FENC_ERROR result;
	fenc_context context;
	fenc_group_params group_params;
	fenc_global_params global_params;
	fenc_ciphertext ciphertext;
	fenc_function_input func_object_input;
	pairing_t pairing;
	FILE *fp;
	char c;
	size_t pub_len = 0;
	size_t serialized_len = 0;
	uint8 public_params_buf[SIZE];
	char session_key[SESSION_KEY_LEN];
	// size_t session_key_len;
	char pol_str[MAX_POLICY_STR];
	int pol_str_len = MAX_POLICY_STR;
	/* Clear data structures. */
	memset(&context, 0, sizeof(fenc_context));
	memset(&group_params, 0, sizeof(fenc_group_params));
	memset(&global_params, 0, sizeof(fenc_global_params));	
	memset(&public_params_buf, 0, SIZE);
	memset(&ciphertext, 0, sizeof(fenc_ciphertext));
	memset(pol_str, 0, pol_str_len);
	
	/* Initialize the library. */
	result = libfenc_init();
	/* Create a Sahai-Waters context. */
	result = libfenc_create_context(&context, scheme);
	
	/* Load group parameters from a file. */
	fp = fopen(PARAM, "r");
	if (fp != NULL) {
		libfenc_load_group_params_from_file(&group_params, fp);
		libfenc_get_pbc_pairing(&group_params, pairing);
	} else {
		perror("Could not open "PARAM" parameters file.\n");
		return;
	}
	fclose(fp);
	
	/* Set up the global parameters. */
	result = context.generate_global_params(&global_params, &group_params);
	report_error("Loading global parameters", result);
	
	result = libfenc_gen_params(&context, &global_params);
	report_error("Generating scheme parameters and secret key", result);
	
	debug("Reading the public parameters file = %s\n", public_params);
	/* read file */
	fp = fopen(public_params, "r");
	if(fp != NULL) {
		while (TRUE) {
			c = fgetc(fp);
			if(c != EOF) {
				public_params_buf[pub_len] = c;
				pub_len++;
			}
			else {
				break;
			}
		}
	}
	else {
		perror("File does not exist.\n");
		return;
	}
	fclose(fp);
		
	if(scheme == FENC_SCHEME_LSW) {
		fenc_create_func_input_for_attributes(attribute_string, &func_object_input);
		debug_print_attribute_list((fenc_attribute_list*)(func_object_input.scheme_input));
		free(attribute_string);
	}
	else if(scheme == FENC_SCHEME_WATERSCP) {
		fenc_create_func_input_for_policy(policy_string, &func_object_input);
		debug_print_policy((fenc_attribute_policy *)(func_object_input.scheme_input));
		free(policy_string);
	}
	
	/* base-64 decode */
	uint8 *bin_public_buf = NewBase64Decode((const char *) public_params_buf, pub_len, &serialized_len);
	// printf("public params binary = '%s'\n", bin_public_buf);
	
	/* Import the parameters from binary buffer: */
	result = libfenc_import_public_params(&context, bin_public_buf, serialized_len);
	// report_error("Importing public parameters", result);
	
	/* key encapsulation to obtain session key from policy */
	result = libfenc_kem_encrypt(&context, &func_object_input, SESSION_KEY_LEN, (uint8 *)session_key, &ciphertext);	
	
	/* generated PSK from policy string */
	debug("Generated session key: ");
	print_buffer_as_hex((uint8 *) session_key, SESSION_KEY_LEN);

	/* encrypted blob that belongs in the <ABED></ABE> tags */
	// print_buffer_as_hex(ciphertext.data, ciphertext.data_len);
		
	/* use the PSK to encrypt using openssl functions here */
	AES_KEY key;
	size_t iv_length;
	uint8 iv[AES_BLOCK_SIZE+1];
	int data_len = (int) ceil((strlen(data) + strlen(MAGIC))/(double)(AES_BLOCK_SIZE)) * AES_BLOCK_SIZE; // round to nearest multiple of 16-bytes
	char aes_ciphertext[data_len], data_magic[data_len];
	
	/* generate a random IV */
	memset(iv, 0, AES_BLOCK_SIZE);
	RAND_bytes((uint8 *) iv, AES_BLOCK_SIZE);
	debug("IV: ");
	print_buffer_as_hex((uint8 *) iv, AES_BLOCK_SIZE);
	char *iv_base64 = NewBase64Encode(iv, AES_BLOCK_SIZE, FALSE, &iv_length);

	memset(aes_ciphertext, 0, data_len);
	AES_set_encrypt_key((uint8 *) session_key, 8*SESSION_KEY_LEN, &key);
	sprintf(data_magic, MAGIC"%s", data);
	debug("\nEncrypting data...\n");
	debug("\tPlaintext is => '%s'.\n", data);
	
	AES_cbc_encrypt((uint8 *)data_magic, (uint8 *) aes_ciphertext, data_len, &key, (uint8 *) iv, AES_ENCRYPT);
	// printf("\tAES Ciphertext base 64: ");
	// print_buffer_as_hex((uint8 *) aes_ciphertext, data_len);
	
	char filename[strlen(enc_file)+1];
	memset(filename, 0, strlen(enc_file));
	uint8 *rand_id[BYTES+1];
	if(isXML) {
		sprintf(filename, "%s.%s.xml", enc_file, ext);
		fp = fopen(filename, "w");
		/* generate the random unique id */
		RAND_bytes((uint8 *) rand_id, BYTES);
		debug("Generated random id: %08x\n", (unsigned int) rand_id[0]);
	}
	else {
		sprintf(filename, "%s.%s", enc_file, ext);
		fp = fopen(filename, "w");
	}
	debug("\tCiphertext stored in '%s'.\n", filename);
	debug("\tABE Ciphertex size is: '%zd'.\n", ciphertext.data_len);
	debug("\tAES Ciphertext size is: '%d'.\n", data_len);

	/* base-64 both ciphertexts and write to the stdout -- in XML? */
	size_t abe_length, aes_length;
	char *ABE_cipher_base64 = NewBase64Encode(ciphertext.data, ciphertext.data_len, FALSE, &abe_length);
	char *AES_cipher_base64 = NewBase64Encode(aes_ciphertext, data_len, FALSE, &aes_length);
	
	/* output ciphertext to disk: either xml or custom format */
	if(isXML) {
		fprintf(fp,"<Encrypted id='");
		fprintf(fp, "%08x", (unsigned int) rand_id[0]);
		fprintf(fp,"'><ABE type='CP'>%s</ABE>", ABE_cipher_base64);
		fprintf(fp,"<IV>%s</IV>", iv_base64);
		fprintf(fp,"<EncryptedData>%s</EncryptedData></Encrypted>", AES_cipher_base64);
		fclose(fp);
	}
	else {
		fprintf(fp, ABE_TOKEN":%s:"ABE_TOKEN_END":", ABE_cipher_base64);
		fprintf(fp, IV_TOKEN":%s:"IV_TOKEN_END":", iv_base64);
		fprintf(fp, AES_TOKEN":%s:"AES_TOKEN_END, AES_cipher_base64);
		fclose(fp);
	}
		
	if(ABE_cipher_base64 != NULL)
		free(ABE_cipher_base64);
	if(ABE_cipher_base64 != NULL)
		free(AES_cipher_base64);
	if(iv_base64 != NULL)
		free(iv_base64);
	
	fenc_func_input_clear(&func_object_input);
	
	/* Shutdown the library. */
	result = libfenc_shutdown();
	report_error("Shutting down library", result);
	return;
}