static int crypto_rfc4309_encrypt(struct aead_request *req)
{
	req = crypto_rfc4309_crypt(req);

	return crypto_aead_encrypt(req);
}
static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes)
{
	struct aesni_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
	be128 buf[8];
	struct lrw_crypt_req req = {
		.tbuf = buf,
		.tbuflen = sizeof(buf),

		.table_ctx = &ctx->lrw_table,
		.crypt_ctx = aes_ctx(ctx->raw_aes_ctx),
		.crypt_fn = lrw_xts_encrypt_callback,
	};
	int ret;

	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;

	kernel_fpu_begin();
	ret = lrw_crypt(desc, dst, src, nbytes, &req);
	kernel_fpu_end();

	return ret;
}

static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes)
{
	struct aesni_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
	be128 buf[8];
	struct lrw_crypt_req req = {
		.tbuf = buf,
		.tbuflen = sizeof(buf),

		.table_ctx = &ctx->lrw_table,
		.crypt_ctx = aes_ctx(ctx->raw_aes_ctx),
		.crypt_fn = lrw_xts_decrypt_callback,
	};
	int ret;

	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;

	kernel_fpu_begin();
	ret = lrw_crypt(desc, dst, src, nbytes, &req);
	kernel_fpu_end();

	return ret;
}

static int xts_aesni_setkey(struct crypto_tfm *tfm, const u8 *key,
			    unsigned int keylen)
{
	struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm);
	u32 *flags = &tfm->crt_flags;
	int err;

	/* key consists of keys of equal size concatenated, therefore
	 * the length must be even
	 */
	if (keylen % 2) {
		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
		return -EINVAL;
	}

	/* first half of xts-key is for crypt */
	err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen / 2);
	if (err)
		return err;

	/* second half of xts-key is for tweak */
	return aes_set_key_common(tfm, ctx->raw_tweak_ctx, key + keylen / 2,
				  keylen / 2);
}


static void aesni_xts_tweak(void *ctx, u8 *out, const u8 *in)
{
	aesni_enc(ctx, out, in);
}

static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes)
{
	struct aesni_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
	be128 buf[8];
	struct xts_crypt_req req = {
		.tbuf = buf,
		.tbuflen = sizeof(buf),

		.tweak_ctx = aes_ctx(ctx->raw_tweak_ctx),
		.tweak_fn = aesni_xts_tweak,
		.crypt_ctx = aes_ctx(ctx->raw_crypt_ctx),
		.crypt_fn = lrw_xts_encrypt_callback,
	};
	int ret;

	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;

	kernel_fpu_begin();
	ret = xts_crypt(desc, dst, src, nbytes, &req);
	kernel_fpu_end();

	return ret;
}

static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
		       struct scatterlist *src, unsigned int nbytes)
{
	struct aesni_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
	be128 buf[8];
	struct xts_crypt_req req = {
		.tbuf = buf,
		.tbuflen = sizeof(buf),

		.tweak_ctx = aes_ctx(ctx->raw_tweak_ctx),
		.tweak_fn = aesni_xts_tweak,
		.crypt_ctx = aes_ctx(ctx->raw_crypt_ctx),
		.crypt_fn = lrw_xts_decrypt_callback,
	};
	int ret;

	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;

	kernel_fpu_begin();
	ret = xts_crypt(desc, dst, src, nbytes, &req);
	kernel_fpu_end();

	return ret;
}

#ifdef CONFIG_X86_64
static int rfc4106_init(struct crypto_tfm *tfm)
{
	struct cryptd_aead *cryptd_tfm;
	struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *)
		PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
	struct crypto_aead *cryptd_child;
	struct aesni_rfc4106_gcm_ctx *child_ctx;
	cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0);
	if (IS_ERR(cryptd_tfm))
		return PTR_ERR(cryptd_tfm);

	cryptd_child = cryptd_aead_child(cryptd_tfm);
	child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child);
	memcpy(child_ctx, ctx, sizeof(*ctx));
	ctx->cryptd_tfm = cryptd_tfm;
	tfm->crt_aead.reqsize = sizeof(struct aead_request)
		+ crypto_aead_reqsize(&cryptd_tfm->base);
	return 0;
}

static void rfc4106_exit(struct crypto_tfm *tfm)
{
	struct aesni_rfc4106_gcm_ctx *ctx =
		(struct aesni_rfc4106_gcm_ctx *)
		PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
	if (!IS_ERR(ctx->cryptd_tfm))
		cryptd_free_aead(ctx->cryptd_tfm);
	return;
}

static void
rfc4106_set_hash_subkey_done(struct crypto_async_request *req, int err)
{
	struct aesni_gcm_set_hash_subkey_result *result = req->data;

	if (err == -EINPROGRESS)
		return;
	result->err = err;
	complete(&result->completion);
}

static int
rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
{
	struct crypto_ablkcipher *ctr_tfm;
	struct ablkcipher_request *req;
	int ret = -EINVAL;
	struct aesni_hash_subkey_req_data *req_data;

	ctr_tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, 0);
	if (IS_ERR(ctr_tfm))
		return PTR_ERR(ctr_tfm);

	crypto_ablkcipher_clear_flags(ctr_tfm, ~0);

	ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len);
	if (ret)
		goto out_free_ablkcipher;

	ret = -ENOMEM;
	req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL);
	if (!req)
		goto out_free_ablkcipher;

	req_data = kmalloc(sizeof(*req_data), GFP_KERNEL);
	if (!req_data)
		goto out_free_request;

	memset(req_data->iv, 0, sizeof(req_data->iv));

	/* Clear the data in the hash sub key container to zero.*/
	/* We want to cipher all zeros to create the hash sub key. */
	memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE);

	init_completion(&req_data->result.completion);
	sg_init_one(&req_data->sg, hash_subkey, RFC4106_HASH_SUBKEY_SIZE);
	ablkcipher_request_set_tfm(req, ctr_tfm);
	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
					CRYPTO_TFM_REQ_MAY_BACKLOG,
					rfc4106_set_hash_subkey_done,
					&req_data->result);

	ablkcipher_request_set_crypt(req, &req_data->sg,
		&req_data->sg, RFC4106_HASH_SUBKEY_SIZE, req_data->iv);

	ret = crypto_ablkcipher_encrypt(req);
	if (ret == -EINPROGRESS || ret == -EBUSY) {
		ret = wait_for_completion_interruptible
			(&req_data->result.completion);
		if (!ret)
			ret = req_data->result.err;
	}
	kfree(req_data);
out_free_request:
	ablkcipher_request_free(req);
out_free_ablkcipher:
	crypto_free_ablkcipher(ctr_tfm);
	return ret;
}

static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
						   unsigned int key_len)
{
	int ret = 0;
	struct crypto_tfm *tfm = crypto_aead_tfm(parent);
	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
	struct aesni_rfc4106_gcm_ctx *child_ctx =
                                 aesni_rfc4106_gcm_ctx_get(cryptd_child);
	u8 *new_key_align, *new_key_mem = NULL;

	if (key_len < 4) {
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}
	/*Account for 4 byte nonce at the end.*/
	key_len -= 4;
	if (key_len != AES_KEYSIZE_128) {
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}

	memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce));
	/*This must be on a 16 byte boundary!*/
	if ((unsigned long)(&(ctx->aes_key_expanded.key_enc[0])) % AESNI_ALIGN)
		return -EINVAL;

	if ((unsigned long)key % AESNI_ALIGN) {
		/*key is not aligned: use an auxuliar aligned pointer*/
		new_key_mem = kmalloc(key_len+AESNI_ALIGN, GFP_KERNEL);
		if (!new_key_mem)
			return -ENOMEM;

		new_key_align = PTR_ALIGN(new_key_mem, AESNI_ALIGN);
		memcpy(new_key_align, key, key_len);
		key = new_key_align;
	}

	if (!irq_fpu_usable())
		ret = crypto_aes_expand_key(&(ctx->aes_key_expanded),
		key, key_len);
	else {
		kernel_fpu_begin();
		ret = aesni_set_key(&(ctx->aes_key_expanded), key, key_len);
		kernel_fpu_end();
	}
	/*This must be on a 16 byte boundary!*/
	if ((unsigned long)(&(ctx->hash_subkey[0])) % AESNI_ALIGN) {
		ret = -EINVAL;
		goto exit;
	}
	ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
	memcpy(child_ctx, ctx, sizeof(*ctx));
exit:
	kfree(new_key_mem);
	return ret;
}

/* This is the Integrity Check Value (aka the authentication tag length and can
 * be 8, 12 or 16 bytes long. */
static int rfc4106_set_authsize(struct crypto_aead *parent,
				unsigned int authsize)
{
	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);

	switch (authsize) {
	case 8:
	case 12:
	case 16:
		break;
	default:
		return -EINVAL;
	}
	crypto_aead_crt(parent)->authsize = authsize;
	crypto_aead_crt(cryptd_child)->authsize = authsize;
	return 0;
}

static int rfc4106_encrypt(struct aead_request *req)
{
	int ret;
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);

	if (!irq_fpu_usable()) {
		struct aead_request *cryptd_req =
			(struct aead_request *) aead_request_ctx(req);
		memcpy(cryptd_req, req, sizeof(*req));
		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
		return crypto_aead_encrypt(cryptd_req);
	} else {
		struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
		kernel_fpu_begin();
		ret = cryptd_child->base.crt_aead.encrypt(req);
		kernel_fpu_end();
		return ret;
	}
}

static int rfc4106_decrypt(struct aead_request *req)
{
	int ret;
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);

	if (!irq_fpu_usable()) {
		struct aead_request *cryptd_req =
			(struct aead_request *) aead_request_ctx(req);
		memcpy(cryptd_req, req, sizeof(*req));
		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
		return crypto_aead_decrypt(cryptd_req);
	} else {
		struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
		kernel_fpu_begin();
		ret = cryptd_child->base.crt_aead.decrypt(req);
		kernel_fpu_end();
		return ret;
	}
}
static int tls_enc_record(struct aead_request *aead_req,
			  struct crypto_aead *aead, char *aad,
			  char *iv, __be64 rcd_sn,
			  struct scatter_walk *in,
			  struct scatter_walk *out, int *in_len)
{
	unsigned char buf[TLS_HEADER_SIZE + TLS_CIPHER_AES_GCM_128_IV_SIZE];
	struct scatterlist sg_in[3];
	struct scatterlist sg_out[3];
	u16 len;
	int rc;

	len = min_t(int, *in_len, ARRAY_SIZE(buf));

	scatterwalk_copychunks(buf, in, len, 0);
	scatterwalk_copychunks(buf, out, len, 1);

	*in_len -= len;
	if (!*in_len)
		return 0;

	scatterwalk_pagedone(in, 0, 1);
	scatterwalk_pagedone(out, 1, 1);

	len = buf[4] | (buf[3] << 8);
	len -= TLS_CIPHER_AES_GCM_128_IV_SIZE;

	tls_make_aad(aad, len - TLS_CIPHER_AES_GCM_128_TAG_SIZE,
		     (char *)&rcd_sn, sizeof(rcd_sn), buf[0]);

	memcpy(iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, buf + TLS_HEADER_SIZE,
	       TLS_CIPHER_AES_GCM_128_IV_SIZE);

	sg_init_table(sg_in, ARRAY_SIZE(sg_in));
	sg_init_table(sg_out, ARRAY_SIZE(sg_out));
	sg_set_buf(sg_in, aad, TLS_AAD_SPACE_SIZE);
	sg_set_buf(sg_out, aad, TLS_AAD_SPACE_SIZE);
	chain_to_walk(sg_in + 1, in);
	chain_to_walk(sg_out + 1, out);

	*in_len -= len;
	if (*in_len < 0) {
		*in_len += TLS_CIPHER_AES_GCM_128_TAG_SIZE;
		/* the input buffer doesn't contain the entire record.
		 * trim len accordingly. The resulting authentication tag
		 * will contain garbage, but we don't care, so we won't
		 * include any of it in the output skb
		 * Note that we assume the output buffer length
		 * is larger then input buffer length + tag size
		 */
		if (*in_len < 0)
			len += *in_len;

		*in_len = 0;
	}

	if (*in_len) {
		scatterwalk_copychunks(NULL, in, len, 2);
		scatterwalk_pagedone(in, 0, 1);
		scatterwalk_copychunks(NULL, out, len, 2);
		scatterwalk_pagedone(out, 1, 1);
	}

	len -= TLS_CIPHER_AES_GCM_128_TAG_SIZE;
	aead_request_set_crypt(aead_req, sg_in, sg_out, len, iv);

	rc = crypto_aead_encrypt(aead_req);

	return rc;
}
Beispiel #4
0
int genKAT(unsigned long long plaintext_length, unsigned long long ad_length)
{
	if((plaintext_length > (1<<31)) || (ad_length> (1<<31)))
		return 1;
	Init();   //For generating plaintext
	unsigned char *key = (unsigned char*)malloc(crypto_aead_KEYBYTES);  
	unsigned char *nonce = (unsigned char*)malloc(crypto_aead_NPUBBYTES);

 	unsigned char *ciphertext;
	unsigned long long ciphertext_length;
	unsigned long long decrypted_length;

	unsigned char *plaintext = (unsigned char*)malloc((size_t)plaintext_length);
	unsigned char *plaintext_decrypted = (unsigned char*)malloc((size_t)plaintext_length);
	plaintext_length = (size_t)plaintext_length;
	if(plaintext==NULL || plaintext_decrypted==NULL)
		return 1;

	unsigned char *associated_data = (unsigned char*)malloc((size_t)ad_length);
	if(associated_data==NULL)
	{
		free(plaintext);
		free(plaintext_decrypted);
		return 1;
	}

	//Plaintext initialization
	unsigned char StateIn[64];
	memset(StateIn,0,64);
	unsigned char StateOut[64];
	int counter= (int)plaintext_length;
	unsigned char *dest_pointer = plaintext;
	while(counter>0)
	{
		FPerm(StateIn,StateOut);
		unsigned to_copy = (counter<64)?counter:64;
		memcpy(dest_pointer,StateOut,to_copy);
		dest_pointer += to_copy;
		(*((unsigned*)StateIn))++;
		counter-= to_copy;
	}

	//AD initialization
	counter= (int)
		ad_length;
	dest_pointer = associated_data;
	while(counter>0)
	{
		FPerm(StateIn,StateOut);
		unsigned to_copy = (counter<64)?counter:64;
		memcpy(dest_pointer,StateOut,to_copy);
		dest_pointer += to_copy;
		(*((unsigned*)StateIn))++;
		counter-= to_copy;
	}

	//Key setting
	FPerm(StateIn,StateOut);
	memcpy(key,StateOut,crypto_aead_KEYBYTES);
	(*((unsigned*)StateIn))++;

	//Nonce setting
	FPerm(StateIn,StateOut);
	memcpy(nonce,StateOut,crypto_aead_NPUBBYTES);
	(*((unsigned*)StateIn))++;

	//Ciphertext memory allocation
	ciphertext = (unsigned char*)malloc((size_t)(plaintext_length+crypto_aead_ABYTES));
	if(ciphertext==NULL)
	{
		free(plaintext);
		free(plaintext_decrypted);
		free(associated_data);
		return 1;
	}

	//Writing input
	FILE *fp=fopen("out.log","w+");
	fprintf(fp, "PLAINTEXT (%llu bytes):\n",plaintext_length);
	for(unsigned i=0; i<plaintext_length; ++i)
	{
		fprintf(fp, "0x%.02x ",plaintext[i]);
		if(i%20==19)
			fprintf(fp, "\n");
	}

	fprintf(fp, "\nASSOCIATED DATA  (%llu bytes):\n", ad_length);
	for(unsigned i=0; i<ad_length; ++i)
	{
		fprintf(fp, "0x%.02x ",associated_data[i]);
		if(i%20==19)
			fprintf(fp, "\n");
	}
	fprintf(fp, "\n");
		fprintf(fp, "\nKEY  (%d bytes):\n", crypto_aead_KEYBYTES);
	for(unsigned i=0; i<crypto_aead_KEYBYTES; ++i)
		fprintf(fp, "0x%.02x ",key[i]);
	fprintf(fp, "\n");
		 

	//Encryption and decryption
#ifdef EXTRANONCE 	//ExtraNonce
	crypto_aead_encrypt_no_nonce(ciphertext,&ciphertext_length,plaintext,plaintext_length,associated_data, ad_length,NULL,nonce,key);

	int result = crypto_aead_decrypt(plaintext_decrypted,&decrypted_length,NULL,ciphertext,ciphertext_length,associated_data, ad_length,nonce,key);
	
#else	   	//Normal nonce
	crypto_aead_encrypt(ciphertext,&ciphertext_length,plaintext,plaintext_length,associated_data, ad_length,NULL,nonce,key);
	int result = crypto_aead_decrypt(plaintext_decrypted,&decrypted_length,NULL,ciphertext,ciphertext_length,associated_data, ad_length,nonce,key);
	
#endif

	if(decrypted_length != plaintext_length)
		printf("Plaintext length mismatch\n");

	//Writing outputs
	fprintf(fp, "\nNONCE  (%d bytes):\n", crypto_aead_NPUBBYTES);
	for(unsigned i=0; i<crypto_aead_NPUBBYTES; ++i)
		fprintf(fp, "0x%.02x ",nonce[i]);
	fprintf(fp, ".\n");
	printf("Decryption result: %d\n",result);

	  
	fprintf(fp, "\nCIPHERTEXT (%llu bytes):\n", ciphertext_length);
	for(unsigned i=0; i<ciphertext_length; ++i)
	{
		fprintf(fp, "0x%.02x ",ciphertext[i]);
		if(i%20==19)
			fprintf(fp, "\n");
		if(i == ciphertext_length - crypto_aead_ABYTES-1)
			fprintf(fp, " || ");
	}
	fprintf(fp, ".\n");

	fprintf(fp, "\nDECRYPTED PLAINTEXT  (%llu bytes):\n", decrypted_length);
	for(unsigned i=0; i<decrypted_length; ++i)
	{
		fprintf(fp, "0x%.02x ",plaintext_decrypted[i]);
		if(i%20==19)
			fprintf(fp, "\n");
	}
	fprintf(fp, ".\n");
	fclose(fp);


	free(plaintext);
	free(ciphertext);
	free(plaintext_decrypted);
	free(associated_data);
		return 0;



}
static int aead_null_givencrypt(struct aead_givcrypt_request *req)
{
	return crypto_aead_encrypt(&req->areq);
}
Beispiel #6
0
static int seqiv_aead_encrypt(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *subreq = aead_request_ctx(req);
	crypto_completion_t compl;
	void *data;
	u8 *info;
	unsigned int ivsize = 8;
	int err;

	if (req->cryptlen < ivsize)
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = req->base.complete;
	data = req->base.data;
	info = req->iv;

	if (req->src != req->dst) {
		SKCIPHER_REQUEST_ON_STACK(nreq, ctx->sknull);

		skcipher_request_set_tfm(nreq, ctx->sknull);
		skcipher_request_set_callback(nreq, req->base.flags,
					      NULL, NULL);
		skcipher_request_set_crypt(nreq, req->src, req->dst,
					   req->assoclen + req->cryptlen,
					   NULL);

		err = crypto_skcipher_encrypt(nreq);
		if (err)
			return err;
	}

	if (unlikely(!IS_ALIGNED((unsigned long)info,
				 crypto_aead_alignmask(geniv) + 1))) {
		info = kmalloc(ivsize, req->base.flags &
				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
								  GFP_ATOMIC);
		if (!info)
			return -ENOMEM;

		memcpy(info, req->iv, ivsize);
		compl = seqiv_aead_encrypt_complete;
		data = req;
	}

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, req->dst, req->dst,
			       req->cryptlen - ivsize, info);
	aead_request_set_ad(subreq, req->assoclen + ivsize);

	crypto_xor(info, ctx->salt, ivsize);
	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);

	err = crypto_aead_encrypt(subreq);
	if (unlikely(info != req->iv))
		seqiv_aead_encrypt_complete2(req, err);
	return err;
}
Beispiel #7
0
int benchmark(unsigned long long plaintext_length, unsigned long long ad_length)
{
	if ((plaintext_length >(1 << 31)) || (ad_length> (1 << 31)))
		return 1;
	Init();   //For generating plaintext
	unsigned char *key = (unsigned char*)malloc(key_bytes);
	unsigned char *nonce = (unsigned char*)malloc(nonce_bytes);

	unsigned char *ciphertext;
	unsigned long long ciphertext_length;
	unsigned long long decrypted_length;

	unsigned char *plaintext = (unsigned char*)malloc((size_t)plaintext_length);
	unsigned char *plaintext_decrypted = (unsigned char*)malloc((size_t)plaintext_length);
	plaintext_length = (size_t)plaintext_length;
	if (plaintext == NULL || plaintext_decrypted == NULL)
		return 1;

	unsigned char *associated_data = (unsigned char*)malloc((size_t)ad_length);
	if (associated_data == NULL)
	{
		free(plaintext);
		free(plaintext_decrypted);
		return 1;
	}

	//Plaintext initialization
	unsigned char StateIn[64];
	memset(StateIn, 0, 64);
	unsigned char StateOut[64];
	int counter = (int)plaintext_length;
	unsigned char *dest_pointer = plaintext;
	while (counter>0)
	{
		FPerm(StateIn, StateOut);
		unsigned to_copy = (counter<64) ? counter : 64;
		memcpy(dest_pointer, StateOut, to_copy);
		dest_pointer += to_copy;
		(*((unsigned*)StateIn))++;
		counter -= to_copy;
	}

	//AD initialization
	counter = (int)
		ad_length;
	dest_pointer = associated_data;
	while (counter>0)
	{
		FPerm(StateIn, StateOut);
		unsigned to_copy = (counter<64) ? counter : 64;
		memcpy(dest_pointer, StateOut, to_copy);
		dest_pointer += to_copy;
		(*((unsigned*)StateIn))++;
		counter -= to_copy;
	}

	//Key setting
	FPerm(StateIn, StateOut);
	memcpy(key, StateOut, key_bytes);
	(*((unsigned*)StateIn))++;

	//Nonce setting
	FPerm(StateIn, StateOut);
	memcpy(nonce, StateOut, nonce_bytes);
	(*((unsigned*)StateIn))++;

	//Ciphertext memory allocation
	ciphertext = (unsigned char*)malloc((size_t)(plaintext_length + tag_bytes));
	if (ciphertext == NULL)
	{
		free(plaintext);
		free(plaintext_decrypted);
		free(associated_data);
		return 1;
	}

	uint64_t start_time, mid_time, end_time;
	uint32_t start_ptr, mid_ptr, end_ptr;

	start_time = __rdtscp(&start_ptr);
#ifdef EXTRANONCE 	//ExtraNonce
	crypto_aead_encrypt_no_nonce(ciphertext, &ciphertext_length, plaintext, plaintext_length, associated_data, ad_length, NULL, nonce, key);
#else
	crypto_aead_encrypt(ciphertext, &ciphertext_length, plaintext, plaintext_length, associated_data, ad_length, NULL, nonce, key);
#endif
	mid_time = __rdtscp(&mid_ptr);
	float speed = (float)(mid_time - start_time) / (plaintext_length + ad_length);
	printf("PAEQ-128: %d bytes encrypted, %2.2f cpb\n", (uint32_t)(plaintext_length + ad_length), speed);
	mid_time = __rdtscp(&mid_ptr);
	int result = crypto_aead_decrypt(plaintext_decrypted, &decrypted_length, NULL, ciphertext, ciphertext_length, associated_data, ad_length, nonce, key);
	end_time = __rdtscp(&end_ptr);
	speed = (float)(end_time - mid_time) / (plaintext_length + ad_length);
	printf("PAEQ-128: %d bytes decrypted, %2.2f cpb\n", (uint32_t)(plaintext_length + ad_length), speed);

	if (decrypted_length != plaintext_length)
		printf("Plaintext length mismatch\n");
	if (result!=0)
		printf("Decryption result: %d\n", result);

	free(ciphertext);
	free(plaintext_decrypted);
	free(associated_data);
	return 0;
}
Beispiel #8
0
int main() {

const unsigned char key[16] = {0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70};
unsigned char nonce[16] = {0x09,0xf9,0x11,0x02,0x9d,0x74,0xe3,0x5b,0xd8,0x41,0x56,0xc5,0x63,0x56,0x88,0xc0};
unsigned char in[4096], out[4096],adata[4096];
unsigned long long tag[16];

//asm volatile ("mcr p15,  0, %0, c15,  c9, 0\n" : : "r" (1));
  int i, j, k, l=100;

//  srand(time(NULL));
  for (i=0; i<16*BLOCKS*l; i++)
    in[i] = (unsigned char)rand();

   uint32_t overhead = rdtsc32();
   overhead = rdtsc32() - overhead;   
  
  
 uint32_t t0,t1;
  
 uint32_t tMin = 0xFFFFFFFF;         /* big number to start */
  
  printf("Cycles for calibrate: %d\n", overhead);

  for (j=0;j<1000;j++) 
      crypto_aead_encrypt(out,tag,in,4096,0,0,0,nonce,key);

  printf("\nEncryption: \nWithout Adata\n");
  

  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,64,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(64))));
  
  
  tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,128,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(128))));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,256,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(256)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,512,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(512)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,1024,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(1024)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,2048,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(2048)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,4096,0,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(4096)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  printf("Cycles for calibrate: %d\n", overhead);

  for (j=0;j<1000;j++) 
      crypto_aead_encrypt(out,tag,in,4096,0,0,0,nonce,key);

  printf("\nEncryption: \nWith Adata\n");
  

  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,64,adata,64,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(64))));
  
  
  tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,128,adata,128,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(128))));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,256,adata,256,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(256)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,512,adata,512,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(512)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,1024,adata,1024,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(1024)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,2048,adata,2048,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(2048)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_encrypt(out,tag,in,4096,adata,4096,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(4096)));
  tMin = 0xFFFFFFFF;         /* big number to start */
  


  printf("\ndecryption: \nWithout Adata\n");
  

  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,64,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(64))));
  
  
  tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,128,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(128))));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,256,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(256)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,512,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(512)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,1024,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(1024)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,2048,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(2048)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,4096,0,0,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(4096)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  

  for (j=0;j<1000;j++) 
      crypto_aead_decrypt(out,tag,0,in,4096,0,0,nonce,key);

  printf("\nDecryption: \nWith Adata\n");
  

  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,64,adata,64,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(64))));
  
  
  tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,128,adata,128,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/(((double)(128))));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,256,adata,256,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(256)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,512,adata,512,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(512)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,1024,adata,1024,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(1024)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,2048,adata,2048,nonce,key);

    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(2048)));
  
    tMin = 0xFFFFFFFF;         /* big number to start */
  
  for (k=0;k < TIMER_SAMPLE_CNT;k++) {
    t0 = rdtsc32();
      crypto_aead_decrypt(out,tag,0,in,4096,adata,4096,nonce,key);



    t1 = rdtsc32();
    if (tMin > t1-t0 - overhead) tMin = t1-t0 - overhead;
  }
  printf("Cycles for AEGIS: %d\n", tMin);
  printf("Cycles per byte: %f\n", tMin/((double)(4096)));
  
  
  
  
  

  
  return 0;
}
Beispiel #9
0
static int echainiv_encrypt(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *subreq = aead_request_ctx(req);
	crypto_completion_t compl;
	void *data;
	u8 *info;
	unsigned int ivsize = crypto_aead_ivsize(geniv);
	int err;

	if (req->cryptlen < ivsize)
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = echainiv_encrypt_complete;
	data = req;
	info = req->iv;

	if (req->src != req->dst) {
		struct blkcipher_desc desc = {
			.tfm = ctx->null,
		};

		err = crypto_blkcipher_encrypt(
			&desc, req->dst, req->src,
			req->assoclen + req->cryptlen);
		if (err)
			return err;
	}

	if (unlikely(!IS_ALIGNED((unsigned long)info,
				 crypto_aead_alignmask(geniv) + 1))) {
		info = kmalloc(ivsize, req->base.flags &
				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
								  GFP_ATOMIC);
		if (!info)
			return -ENOMEM;

		memcpy(info, req->iv, ivsize);
	}

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, req->dst, req->dst,
			       req->cryptlen, info);
	aead_request_set_ad(subreq, req->assoclen);

	crypto_xor(info, ctx->salt, ivsize);
	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
	echainiv_read_iv(info, ivsize);

	err = crypto_aead_encrypt(subreq);
	echainiv_encrypt_complete2(req, err);
	return err;
}

static int echainiv_decrypt(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *subreq = aead_request_ctx(req);
	crypto_completion_t compl;
	void *data;
	unsigned int ivsize = crypto_aead_ivsize(geniv);

	if (req->cryptlen < ivsize)
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = req->base.complete;
	data = req->base.data;

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, req->src, req->dst,
			       req->cryptlen - ivsize, req->iv);
	aead_request_set_ad(subreq, req->assoclen + ivsize);

	scatterwalk_map_and_copy(req->iv, req->src, req->assoclen, ivsize, 0);

	return crypto_aead_decrypt(subreq);
}

static int echainiv_aead_create(struct crypto_template *tmpl,
				struct rtattr **tb)
{
	struct aead_instance *inst;
	struct crypto_aead_spawn *spawn;
	struct aead_alg *alg;
	int err;

	inst = aead_geniv_alloc(tmpl, tb, 0, 0);

	if (IS_ERR(inst))
		return PTR_ERR(inst);

	spawn = aead_instance_ctx(inst);
	alg = crypto_spawn_aead_alg(spawn);

	err = -EINVAL;
	if (inst->alg.ivsize & (sizeof(u32) - 1) ||
	    inst->alg.ivsize > MAX_IV_SIZE)
		goto free_inst;

	inst->alg.encrypt = echainiv_encrypt;
	inst->alg.decrypt = echainiv_decrypt;

	inst->alg.init = aead_init_geniv;
	inst->alg.exit = aead_exit_geniv;

	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
	inst->alg.base.cra_ctxsize += inst->alg.ivsize;

	inst->free = aead_geniv_free;

	err = aead_register_instance(tmpl, inst);
	if (err)
		goto free_inst;

out:
	return err;

free_inst:
	aead_geniv_free(inst);
	goto out;
}

static void echainiv_free(struct crypto_instance *inst)
{
	aead_geniv_free(aead_instance(inst));
}