From b758c2eedc69b41ccfb84aba95b8c71786488a45 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Date: Tue, 6 Dec 2011 10:52:48 +0100
Subject: [PATCH 166/291] cryptodev: Added

---
 .../staging/crypto/cryptodev/examples/aes-gcm.c    |   3 -
 .../staging/crypto/cryptodev/examples/aes-sha1.c   | 136 +++++++++++++++++++++
 .../staging/crypto/cryptodev/examples/aes-sha1.h   |  31 +++++
 3 files changed, 167 insertions(+), 3 deletions(-)
 create mode 100644 drivers/staging/crypto/cryptodev/examples/aes-sha1.c
 create mode 100644 drivers/staging/crypto/cryptodev/examples/aes-sha1.h

diff --git a/drivers/staging/crypto/cryptodev/examples/aes-gcm.c b/drivers/staging/crypto/cryptodev/examples/aes-gcm.c
index 8cdd3d24190b..be327a228894 100644
--- a/drivers/staging/crypto/cryptodev/examples/aes-gcm.c
+++ b/drivers/staging/crypto/cryptodev/examples/aes-gcm.c
@@ -12,9 +12,6 @@
 #include <crypto/cryptodev.h>
 #include "aes-gcm.h"
 
-#define	KEY_SIZE	16
-
-
 int aes_gcm_ctx_init(struct cryptodev_ctx* ctx, int cfd, const uint8_t *key, unsigned int key_size)
 {
 #ifdef CIOCGSESSINFO
diff --git a/drivers/staging/crypto/cryptodev/examples/aes-sha1.c b/drivers/staging/crypto/cryptodev/examples/aes-sha1.c
new file mode 100644
index 000000000000..8235918763dc
--- /dev/null
+++ b/drivers/staging/crypto/cryptodev/examples/aes-sha1.c
@@ -0,0 +1,136 @@
+/*
+ * Demo on how to use /dev/crypto device for ciphering.
+ *
+ * Placed under public domain.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <crypto/cryptodev.h>
+#include "aes-sha1.h"
+
+/* This is the TLS version of AES-CBC with HMAC-SHA1. 
+ */
+
+int aes_sha1_ctx_init(struct cryptodev_ctx* ctx, int cfd, 
+	const uint8_t *key, unsigned int key_size,
+	const uint8_t *mac_key, unsigned int mac_key_size)
+{
+#ifdef CIOCGSESSINFO
+	struct session_info_op siop;
+#endif
+
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->cfd = cfd;
+
+	ctx->sess.cipher = CRYPTO_AES_CBC;
+	ctx->sess.keylen = key_size;
+	ctx->sess.key = (void*)key;
+
+	ctx->sess.mac = CRYPTO_SHA1_HMAC;
+	ctx->sess.mackeylen = mac_key_size;
+	ctx->sess.mackey = (void*)mac_key;
+
+	if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return -1;
+	}
+
+#ifdef CIOCGSESSINFO
+	siop.ses = ctx->sess.ses;
+	if (ioctl(ctx->cfd, CIOCGSESSINFO, &siop)) {
+		perror("ioctl(CIOCGSESSINFO)");
+		return -1;
+	}
+	printf("requested cipher CRYPTO_AES_GCM, got %s with driver %s\n",
+			siop.cipher_info.cra_name, siop.cipher_info.cra_driver_name);
+	/*printf("Alignmask is %x\n", (unsigned int)siop.alignmask); */
+	ctx->alignmask = siop.alignmask;
+#endif
+	return 0;
+}
+
+void aes_sha1_ctx_deinit(struct cryptodev_ctx* ctx) 
+{
+	if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) {
+		perror("ioctl(CIOCFSESSION)");
+	}
+}
+
+int
+aes_sha1_encrypt(struct cryptodev_ctx* ctx, const void* iv, 
+	const void* auth, size_t auth_size,
+	void* plaintext, size_t size)
+{
+	struct crypt_auth_op cryp;
+	void* p;
+	
+	/* check plaintext and ciphertext alignment */
+	if (ctx->alignmask) {
+		p = (void*)(((unsigned long)plaintext + ctx->alignmask) & ~ctx->alignmask);
+		if (plaintext != p) {
+			fprintf(stderr, "plaintext is not aligned\n");
+			return -1;
+		}
+	}
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	/* Encrypt data.in to data.encrypted */
+	cryp.ses = ctx->sess.ses;
+	cryp.iv = (void*)iv;
+	cryp.op = COP_ENCRYPT;
+	cryp.auth_len = auth_size;
+	cryp.auth_src = (void*)auth;
+	cryp.len = size;
+	cryp.src = (void*)plaintext;
+	cryp.dst = plaintext;
+	cryp.flags = COP_FLAG_AEAD_TLS_TYPE;
+	if (ioctl(ctx->cfd, CIOCAUTHCRYPT, &cryp)) {
+		perror("ioctl(CIOCAUTHCRYPT)");
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+aes_sha1_decrypt(struct cryptodev_ctx* ctx, const void* iv, 
+	const void* auth, size_t auth_size,
+	void* ciphertext, size_t size)
+{
+	struct crypt_auth_op cryp;
+	void* p;
+	
+	/* check plaintext and ciphertext alignment */
+	if (ctx->alignmask) {
+		p = (void*)(((unsigned long)ciphertext + ctx->alignmask) & ~ctx->alignmask);
+		if (ciphertext != p) {
+			fprintf(stderr, "ciphertext is not aligned\n");
+			return -1;
+		}
+	}
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	/* Encrypt data.in to data.encrypted */
+	cryp.ses = ctx->sess.ses;
+	cryp.iv = (void*)iv;
+	cryp.op = COP_DECRYPT;
+	cryp.auth_len = auth_size;
+	cryp.auth_src = (void*)auth;
+	cryp.len = size;
+	cryp.src = (void*)ciphertext;
+	cryp.dst = ciphertext;
+	cryp.flags = COP_FLAG_AEAD_TLS_TYPE;
+	if (ioctl(ctx->cfd, CIOCAUTHCRYPT, &cryp)) {
+		perror("ioctl(CIOCAUTHCRYPT)");
+		return -1;
+	}
+
+	return 0;
+}
+
diff --git a/drivers/staging/crypto/cryptodev/examples/aes-sha1.h b/drivers/staging/crypto/cryptodev/examples/aes-sha1.h
new file mode 100644
index 000000000000..a07334cf3a4a
--- /dev/null
+++ b/drivers/staging/crypto/cryptodev/examples/aes-sha1.h
@@ -0,0 +1,31 @@
+#ifndef AES_H
+# define AES_H
+
+#include <stdint.h>
+
+struct cryptodev_ctx {
+	int cfd;
+	struct session_op sess;
+	uint16_t alignmask;
+};
+
+#define	AES_BLOCK_SIZE	16
+
+int aes_sha1_ctx_init(struct cryptodev_ctx* ctx, int cfd, 
+	const uint8_t *key, unsigned int key_size,
+	const uint8_t *mac_key, unsigned int mac_key_size);
+void aes_sha1_ctx_deinit();
+
+/* Note that encryption assumes that ciphertext has enough size
+ * for the tag and padding to be appended. 
+ *
+ * Only in-place encryption and decryption are supported.
+ */
+int aes_sha1_encrypt(struct cryptodev_ctx* ctx, const void* iv, 
+	const void* auth, size_t auth_size,
+	void* plaintext, size_t size);
+int aes_sha1_decrypt(struct cryptodev_ctx* ctx, const void* iv, 
+	const void* auth, size_t auth_size,
+	void* ciphertext, size_t size);
+
+#endif
-- 
2.1.0

